Skip to content

Commit cda0e7e

Browse files
committed
feat: 自动重试网络+网络指示器
1 parent 22caeaa commit cda0e7e

10 files changed

Lines changed: 438 additions & 40 deletions

lib/l10n/app_en.arb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,10 @@
338338
"networkStatusDisconnected": "Disconnected from Internet",
339339
"networkStatusDisconnectedDesc": "You are disconnected from the internet and can only connect to local network servers",
340340
"networkStatusCheckingConnection": "Checking network connection...",
341+
"connectionBannerConnecting": "Connecting",
342+
"connectionBannerDisconnected": "Disconnected",
343+
"connectionBannerConnected": "Connected",
344+
"connectionBannerTapToRetry": "Tap to retry",
341345

342346
"messageActions": "Message Actions",
343347
"messageActionReply": "Reply",

lib/l10n/app_localizations.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,30 @@ abstract class AppLocalizations {
16041604
/// **'Checking network connection...'**
16051605
String get networkStatusCheckingConnection;
16061606

1607+
/// No description provided for @connectionBannerConnecting.
1608+
///
1609+
/// In en, this message translates to:
1610+
/// **'Connecting'**
1611+
String get connectionBannerConnecting;
1612+
1613+
/// No description provided for @connectionBannerDisconnected.
1614+
///
1615+
/// In en, this message translates to:
1616+
/// **'Disconnected'**
1617+
String get connectionBannerDisconnected;
1618+
1619+
/// No description provided for @connectionBannerConnected.
1620+
///
1621+
/// In en, this message translates to:
1622+
/// **'Connected'**
1623+
String get connectionBannerConnected;
1624+
1625+
/// No description provided for @connectionBannerTapToRetry.
1626+
///
1627+
/// In en, this message translates to:
1628+
/// **'Tap to retry'**
1629+
String get connectionBannerTapToRetry;
1630+
16071631
/// No description provided for @messageActions.
16081632
///
16091633
/// In en, this message translates to:

lib/l10n/app_localizations_en.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,18 @@ class AppLocalizationsEn extends AppLocalizations {
809809
String get networkStatusCheckingConnection =>
810810
'Checking network connection...';
811811

812+
@override
813+
String get connectionBannerConnecting => 'Connecting';
814+
815+
@override
816+
String get connectionBannerDisconnected => 'Disconnected';
817+
818+
@override
819+
String get connectionBannerConnected => 'Connected';
820+
821+
@override
822+
String get connectionBannerTapToRetry => 'Tap to retry';
823+
812824
@override
813825
String get messageActions => 'Message Actions';
814826

lib/l10n/app_localizations_zh.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,18 @@ class AppLocalizationsZh extends AppLocalizations {
776776
@override
777777
String get networkStatusCheckingConnection => '正在检查网络连接...';
778778

779+
@override
780+
String get connectionBannerConnecting => '正在连接';
781+
782+
@override
783+
String get connectionBannerDisconnected => '已断开';
784+
785+
@override
786+
String get connectionBannerConnected => '已连接';
787+
788+
@override
789+
String get connectionBannerTapToRetry => '点击重试';
790+
779791
@override
780792
String get messageActions => '消息操作';
781793

lib/l10n/app_zh.arb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@
324324
"networkStatusDisconnected": "已断开互联网连接",
325325
"networkStatusDisconnectedDesc": "您已断开互联网连接,仅能连接内网服务器",
326326
"networkStatusCheckingConnection": "正在检查网络连接...",
327+
"connectionBannerConnecting": "正在连接",
328+
"connectionBannerDisconnected": "已断开",
329+
"connectionBannerConnected": "已连接",
330+
"connectionBannerTapToRetry": "点击重试",
327331

328332
"messageActions": "消息操作",
329333
"messageActionReply": "回复",

lib/main.dart

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ import 'models/app_state.dart';
1414
import 'models/settings_service.dart';
1515
import 'routes/app_routes.dart';
1616
import 'services/auth_state.dart';
17+
import 'services/server_connection_status_service.dart';
1718
import 'utils/talker.dart';
1819
import 'widgets/app_alert_dialog.dart';
20+
import 'widgets/custom_title_bar.dart';
21+
import 'widgets/server_connection_banner.dart';
1922

2023
void main() async {
2124
WidgetsFlutterBinding.ensureInitialized();
@@ -397,6 +400,75 @@ class _TouchFishAppState extends State<TouchFishApp> {
397400
);
398401
}
399402

403+
Widget _buildServerConnectionOverlay(BuildContext context, Widget child) {
404+
final hasDesktopWindowFrame =
405+
!kIsWeb && (Platform.isWindows || Platform.isMacOS || Platform.isLinux);
406+
407+
return ListenableBuilder(
408+
listenable: ServerConnectionStatusService.instance,
409+
builder: (context, _) {
410+
final service = ServerConnectionStatusService.instance;
411+
412+
return Stack(
413+
children: [
414+
child,
415+
SafeArea(
416+
child: Align(
417+
alignment: Alignment.topCenter,
418+
child: Padding(
419+
padding: EdgeInsets.fromLTRB(
420+
16,
421+
(hasDesktopWindowFrame ? CustomTitleBar.height : 0) + 12,
422+
16,
423+
12,
424+
),
425+
child: AnimatedSwitcher(
426+
duration: const Duration(milliseconds: 220),
427+
switchInCurve: Curves.easeOutCubic,
428+
switchOutCurve: Curves.easeInCubic,
429+
transitionBuilder: (child, animation) {
430+
final curved = CurvedAnimation(
431+
parent: animation,
432+
curve: Curves.easeOutCubic,
433+
reverseCurve: Curves.easeInCubic,
434+
);
435+
return FadeTransition(
436+
opacity: curved,
437+
child: SlideTransition(
438+
position: Tween<Offset>(
439+
begin: const Offset(0, -0.2),
440+
end: Offset.zero,
441+
).animate(curved),
442+
child: child,
443+
),
444+
);
445+
},
446+
child: service.isVisible
447+
? ServerConnectionBanner(
448+
key: ValueKey(service.phase),
449+
phase: service.phase,
450+
onTap:
451+
service.phase ==
452+
ServerConnectionBannerPhase.disconnected
453+
? () {
454+
unawaited(
455+
ServerConnectionStatusService.instance
456+
.retryConnection(),
457+
);
458+
}
459+
: null,
460+
)
461+
: const SizedBox.shrink(key: ValueKey('hidden')),
462+
),
463+
),
464+
),
465+
),
466+
],
467+
);
468+
},
469+
);
470+
}
471+
400472
@override
401473
Widget build(BuildContext context) {
402474
return ListenableBuilder(
@@ -465,7 +537,10 @@ class _TouchFishAppState extends State<TouchFishApp> {
465537
themeMode: _appState.themeMode,
466538
builder: (context, child) {
467539
_showStartupResetNoticeIfNeeded(context);
468-
final content = child ?? const SizedBox.shrink();
540+
final content = _buildServerConnectionOverlay(
541+
context,
542+
child ?? const SizedBox.shrink(),
543+
);
469544
if (hasBackgroundImage && !kIsWeb) {
470545
return _buildSavedSessionRestoreOverlay(
471546
context,

0 commit comments

Comments
 (0)