feat:improve logic
This commit is contained in:
1 parent
a78a87e46b
commit
dca69d095a
4 files changed
+105
-8
No files matched your search
@@ -19,6 +19,7 @@ class AppStrings {
|
|||||||
static const qrScanSuccess = '二维码解析成功';
|
static const qrScanSuccess = '二维码解析成功';
|
||||||
static const qrScanFailed = '未能识别二维码,请手动粘贴内容';
|
static const qrScanFailed = '未能识别二维码,请手动粘贴内容';
|
||||||
static const qrScanError = '解析失败';
|
static const qrScanError = '解析失败';
|
||||||
|
static const forcePreviewApi = '强制使用 Preview API';
|
||||||
static const loginFailed = '登录失败';
|
static const loginFailed = '登录失败';
|
||||||
static const requestFailed = '请求失败';
|
static const requestFailed = '请求失败';
|
||||||
static const settingsTooltip = '设置';
|
static const settingsTooltip = '设置';
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
final _apiService = ApiService();
|
final _apiService = ApiService();
|
||||||
String _qrCode = '';
|
String _qrCode = '';
|
||||||
bool _loading = false;
|
bool _loading = false;
|
||||||
|
bool _forcePreviewApi = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
@@ -115,6 +116,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
userId: result.userId,
|
userId: result.userId,
|
||||||
token: result.token,
|
token: result.token,
|
||||||
cookies: result.cookies,
|
cookies: result.cookies,
|
||||||
|
forcePreviewApi: _forcePreviewApi,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -317,6 +319,15 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
CheckboxListTile(
|
||||||
|
value: _forcePreviewApi,
|
||||||
|
onChanged: (v) => setState(() => _forcePreviewApi = v ?? false),
|
||||||
|
title: const Text(AppStrings.forcePreviewApi),
|
||||||
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
dense: true,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ class HomePage extends StatefulWidget {
|
|||||||
final int userId;
|
final int userId;
|
||||||
final String token;
|
final String token;
|
||||||
final String? cookies;
|
final String? cookies;
|
||||||
|
final bool forcePreviewApi;
|
||||||
|
|
||||||
const HomePage({
|
const HomePage({
|
||||||
super.key,
|
super.key,
|
||||||
required this.userId,
|
required this.userId,
|
||||||
required this.token,
|
required this.token,
|
||||||
this.cookies,
|
this.cookies,
|
||||||
|
this.forcePreviewApi = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -34,6 +36,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
String? _error;
|
String? _error;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
bool _loggingOut = false;
|
bool _loggingOut = false;
|
||||||
|
String? _sessionCookies;
|
||||||
|
|
||||||
static const _tabTitles = [
|
static const _tabTitles = [
|
||||||
AppStrings.tabHome,
|
AppStrings.tabHome,
|
||||||
@@ -76,10 +79,12 @@ class _HomePageState extends State<HomePage> {
|
|||||||
token: widget.token,
|
token: widget.token,
|
||||||
);
|
);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
_sessionCookies = service.cookies;
|
||||||
setState(() => _preview = preview);
|
setState(() => _preview = preview);
|
||||||
|
|
||||||
// isLogin == true => 已有人登录, 不再走完整登录, 直接展示 preview 概要
|
// isLogin == true => 已有人登录, 不再走完整登录, 直接展示 preview 概要
|
||||||
if (preview.isLogin) {
|
// forcePreviewApi => 跳过 UserLoginApi, 仅展示 preview + Login 按钮
|
||||||
|
if (preview.isLogin || widget.forcePreviewApi) {
|
||||||
setState(() => _loading = false);
|
setState(() => _loading = false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -89,10 +94,55 @@ class _HomePageState extends State<HomePage> {
|
|||||||
token: widget.token,
|
token: widget.token,
|
||||||
);
|
);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
_sessionCookies = service.cookies;
|
||||||
setState(() => _login = login);
|
setState(() => _login = login);
|
||||||
|
|
||||||
final userData = await service.getUserDataTyped(widget.userId);
|
final userData = await service.getUserDataTyped(widget.userId);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
_sessionCookies = service.cookies;
|
||||||
|
setState(() {
|
||||||
|
_userData = userData;
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
} on TitleApiException catch (e) {
|
||||||
|
if (!mounted) return;
|
||||||
|
setState(() {
|
||||||
|
_error = e.message;
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (!mounted) return;
|
||||||
|
setState(() {
|
||||||
|
_error = e.toString();
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _performLogin() async {
|
||||||
|
if (!TitleServerConfigHolder().isConfigured) return;
|
||||||
|
setState(() {
|
||||||
|
_loading = true;
|
||||||
|
_error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
final service = TitleApiService(
|
||||||
|
TitleServerConfigHolder().config!,
|
||||||
|
cookies: _sessionCookies ?? widget.cookies,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final login = await service.userLoginFull(
|
||||||
|
userId: widget.userId,
|
||||||
|
token: widget.token,
|
||||||
|
);
|
||||||
|
if (!mounted) return;
|
||||||
|
_sessionCookies = service.cookies;
|
||||||
|
setState(() => _login = login);
|
||||||
|
|
||||||
|
final userData = await service.getUserDataTyped(widget.userId);
|
||||||
|
if (!mounted) return;
|
||||||
|
_sessionCookies = service.cookies;
|
||||||
setState(() {
|
setState(() {
|
||||||
_userData = userData;
|
_userData = userData;
|
||||||
_loading = false;
|
_loading = false;
|
||||||
@@ -118,7 +168,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
if (!TitleServerConfigHolder().isConfigured) return;
|
if (!TitleServerConfigHolder().isConfigured) return;
|
||||||
final service = TitleApiService(
|
final service = TitleApiService(
|
||||||
TitleServerConfigHolder().config!,
|
TitleServerConfigHolder().config!,
|
||||||
cookies: widget.cookies,
|
cookies: _sessionCookies ?? widget.cookies,
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
await service.userLogout(
|
await service.userLogout(
|
||||||
@@ -171,7 +221,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
_buildBody(theme),
|
_buildBody(theme),
|
||||||
TicketPage(
|
TicketPage(
|
||||||
userId: widget.userId,
|
userId: widget.userId,
|
||||||
cookies: widget.cookies,
|
cookies: _sessionCookies ?? widget.cookies,
|
||||||
loginDateTime: _login?.loginDateTime,
|
loginDateTime: _login?.loginDateTime,
|
||||||
playerRating: _userData?.playerRating ?? _preview?.playerRating ?? 0,
|
playerRating: _userData?.playerRating ?? _preview?.playerRating ?? 0,
|
||||||
onLogoutRequested: _login != null ? _logoutSession : null,
|
onLogoutRequested: _login != null ? _logoutSession : null,
|
||||||
@@ -268,8 +318,13 @@ class _HomePageState extends State<HomePage> {
|
|||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preview.isLogin && userData == null) {
|
if ((preview.isLogin || (widget.forcePreviewApi && _login == null)) && userData == null) {
|
||||||
return _buildPreviewOnly(theme, preview);
|
return _buildPreviewOnly(
|
||||||
|
theme,
|
||||||
|
preview,
|
||||||
|
showLoginButton: widget.forcePreviewApi && _login == null,
|
||||||
|
onLoginPressed: _performLogin,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userData != null) {
|
if (userData != null) {
|
||||||
@@ -279,7 +334,12 @@ class _HomePageState extends State<HomePage> {
|
|||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPreviewOnly(ThemeData theme, UserPreviewDataBean preview) {
|
Widget _buildPreviewOnly(
|
||||||
|
ThemeData theme,
|
||||||
|
UserPreviewDataBean preview, {
|
||||||
|
bool showLoginButton = false,
|
||||||
|
VoidCallback? onLoginPressed,
|
||||||
|
}) {
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
@@ -295,12 +355,35 @@ class _HomePageState extends State<HomePage> {
|
|||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
AppStrings.inheritedAccountNotice,
|
showLoginButton ? 'Preview API 模式,点击下方按钮登录。' : AppStrings.inheritedAccountNotice,
|
||||||
style: theme.textTheme.bodySmall?.copyWith(
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
color: theme.colorScheme.onTertiaryContainer,
|
color: theme.colorScheme.onTertiaryContainer,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (showLoginButton) ...[
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: FilledButton.icon(
|
||||||
|
onPressed: _loading ? null : onLoginPressed,
|
||||||
|
icon: _loading
|
||||||
|
? const SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
|
)
|
||||||
|
: const Icon(Icons.login, size: 20),
|
||||||
|
label: Text(_loading ? AppStrings.loggingIn : AppStrings.login),
|
||||||
|
style: FilledButton.styleFrom(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
_ProfileFromPreviewCard(theme: theme, preview: preview),
|
_ProfileFromPreviewCard(theme: theme, preview: preview),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ class TitleApiService {
|
|||||||
final TitleServerConfig _config;
|
final TitleServerConfig _config;
|
||||||
String? _cookies;
|
String? _cookies;
|
||||||
|
|
||||||
TitleApiService(this._config, {this._cookies});
|
TitleApiService(this._config, {String? cookies}) : _cookies = cookies;
|
||||||
|
|
||||||
|
String? get cookies => _cookies;
|
||||||
|
|
||||||
Uint8List _aesEncrypt(Uint8List plaintext) {
|
Uint8List _aesEncrypt(Uint8List plaintext) {
|
||||||
final cipher = PaddedBlockCipherImpl(
|
final cipher = PaddedBlockCipherImpl(
|
||||||
|
|||||||
Reference in new issue
Block a user