From f08c9903b47b09f86a8312c1a0bc5b6951dd4b7c Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 27 Jul 2024 01:39:20 +0800 Subject: [PATCH] :sparkles: Bootstrapper --- lib/bootstrapper.dart | 149 +++++++++++++++++++++++++++++++++++ lib/main.dart | 24 +----- lib/providers/websocket.dart | 2 +- lib/services.dart | 2 +- lib/translations/en_us.dart | 6 ++ lib/translations/zh_cn.dart | 6 ++ pubspec.yaml | 2 +- 7 files changed, 168 insertions(+), 23 deletions(-) create mode 100644 lib/bootstrapper.dart diff --git a/lib/bootstrapper.dart b/lib/bootstrapper.dart new file mode 100644 index 0000000..41c2ee8 --- /dev/null +++ b/lib/bootstrapper.dart @@ -0,0 +1,149 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:solian/exts.dart'; +import 'package:solian/providers/auth.dart'; +import 'package:solian/providers/content/channel.dart'; +import 'package:solian/providers/relation.dart'; +import 'package:solian/providers/websocket.dart'; +import 'package:solian/services.dart'; + +class BootstrapperShell extends StatefulWidget { + final Widget child; + + const BootstrapperShell({super.key, required this.child}); + + @override + State createState() => _BootstrapperShellState(); +} + +class _BootstrapperShellState extends State { + bool _isBusy = true; + bool _isErrored = false; + String? _subtitle; + + Color get _unFocusColor => + Theme.of(context).colorScheme.onSurface.withOpacity(0.75); + + int _periodCursor = 0; + + late final List<({String label, Future Function() action})> _periods = [ + ( + label: 'bsCheckingServer', + action: () async { + final client = ServiceFinder.configureClient('dealer'); + final resp = await client.get('/.well-known'); + if (resp.statusCode != 200) { + setState(() { + _isErrored = true; + _subtitle = 'bsCheckingServerFail'.tr; + }); + } + }, + ), + ( + label: 'bsAuthorizing', + action: () async { + final AuthProvider auth = Get.find(); + await auth.refreshAuthorizeStatus(); + if (auth.isAuthorized.isTrue) { + await auth.refreshUserProfile(); + } + }, + ), + ( + label: 'bsEstablishingConn', + action: () async { + final AuthProvider auth = Get.find(); + if (auth.isAuthorized.isTrue) { + await Get.find().connect(); + } + }, + ), + ( + label: 'bsPreparingData', + action: () async { + final AuthProvider auth = Get.find(); + if (auth.isAuthorized.isTrue) { + await Future.wait([ + Get.find().refreshAvailableChannel(), + Get.find().refreshFriendList(), + ]); + } + }, + ), + ( + label: 'bsRegisteringPushNotify', + action: () async { + final AuthProvider auth = Get.find(); + if (auth.isAuthorized.isTrue) { + try { + Get.find().registerPushNotifications(); + } catch (err) { + context.showSnackbar( + 'pushNotifyRegisterFailed'.trParams({'reason': err.toString()}), + ); + } + } + }, + ), + ]; + + Future _runPeriods() async { + for (var idx = 0; idx < _periods.length; idx++) { + await _periods[idx].action(); + setState(() => _periodCursor++); + } + setState(() => _isBusy = false); + } + + @override + void initState() { + super.initState(); + _runPeriods(); + } + + @override + Widget build(BuildContext context) { + if (_isBusy || _isErrored) { + return Material( + color: Theme.of(context).colorScheme.surface, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + SizedBox( + height: 280, + child: Align( + alignment: Alignment.bottomCenter, + child: Image.asset('assets/logo.png', width: 80, height: 80), + ), + ), + Column( + children: [ + if (_isErrored) + const Icon(Icons.cancel, size: 24) + else + const SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator(strokeWidth: 3), + ), + const SizedBox(height: 12), + Text( + _subtitle ?? + '${_periods[_periodCursor].label.tr} (${_periodCursor + 1}/${_periods.length})', + style: TextStyle( + fontSize: 13, + color: _unFocusColor, + ), + ), + ], + ) + ], + ), + ); + } + + return widget.child; + } +} diff --git a/lib/main.dart b/lib/main.dart index 2186cd0..c9220bf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,7 +5,7 @@ import 'package:get/get.dart'; import 'package:media_kit/media_kit.dart'; import 'package:protocol_handler/protocol_handler.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; -import 'package:solian/exts.dart'; +import 'package:solian/bootstrapper.dart'; import 'package:solian/firebase_options.dart'; import 'package:solian/platform.dart'; import 'package:solian/providers/websocket.dart'; @@ -87,7 +87,9 @@ class SolianApp extends StatelessWidget { builder: (context, child) { return SystemShell( child: ScaffoldMessenger( - child: child ?? const SizedBox(), + child: BootstrapperShell( + child: child ?? const SizedBox(), + ), ), ); }, @@ -104,23 +106,5 @@ class SolianApp extends StatelessWidget { Get.lazyPut(() => ChannelProvider()); Get.lazyPut(() => RealmProvider()); Get.lazyPut(() => ChatCallProvider()); - - final AuthProvider auth = Get.find(); - - auth.refreshAuthorizeStatus().then((_) { - if (auth.isAuthorized.isFalse) return; - - Get.find().connect(); - Get.find().refreshAvailableChannel(); - Get.find().refreshFriendList(); - - try { - Get.find().registerPushNotifications(); - } catch (err) { - context.showSnackbar( - 'pushNotifyRegisterFailed'.trParams({'reason': err.toString()}), - ); - } - }); } } diff --git a/lib/providers/websocket.dart b/lib/providers/websocket.dart index 6b1c57a..91ca987 100644 --- a/lib/providers/websocket.dart +++ b/lib/providers/websocket.dart @@ -42,7 +42,7 @@ class WebSocketProvider extends GetxController { super.onInit(); } - void connect({noRetry = false}) async { + Future connect({noRetry = false}) async { if (isConnected.value) { return; } else { diff --git a/lib/services.dart b/lib/services.dart index 92a94fa..42253c0 100644 --- a/lib/services.dart +++ b/lib/services.dart @@ -15,7 +15,7 @@ abstract class ServiceFinder { } else if (serviceName == 'passport') { return '$passportUrl$append'; } - return '$dealerUrl/srv/$serviceName$append'; + return '$dealerUrl/cgi/$serviceName$append'; } static GetConnect configureClient(String serviceName, diff --git a/lib/translations/en_us.dart b/lib/translations/en_us.dart index 9400582..4f84f36 100644 --- a/lib/translations/en_us.dart +++ b/lib/translations/en_us.dart @@ -276,4 +276,10 @@ const messagesEnglish = { 'accountStatusNegative': 'Negative', 'accountStatusNeutral': 'Neutral', 'accountStatusPositive': 'Positive', + 'bsCheckingServer': 'Checking Server Status', + 'bsCheckingServerFail': 'Unable connect to server, check your network connection or follow our service maintenance status', + 'bsAuthorizing': 'Authorizing', + 'bsEstablishingConn': 'Establishing Connection', + 'bsPreparingData': 'Preparing User Data', + 'bsRegisteringPushNotify': 'Enabling Push Notifications', }; diff --git a/lib/translations/zh_cn.dart b/lib/translations/zh_cn.dart index e930c2c..69cf180 100644 --- a/lib/translations/zh_cn.dart +++ b/lib/translations/zh_cn.dart @@ -255,4 +255,10 @@ const simplifiedChineseMessages = { 'accountStatusNegative': '负面', 'accountStatusNeutral': '中性', 'accountStatusPositive': '积极', + 'bsCheckingServer': '检查服务器状态中', + 'bsCheckingServerFail': '无法连接至服务器,请检查你的网络状态或我们服务维护状态', + 'bsAuthorizing': '正在授权中', + 'bsEstablishingConn': '部署连接中', + 'bsPreparingData': '正在准备用户资料', + 'bsRegisteringPushNotify': '正在启用推送通知', }; diff --git a/pubspec.yaml b/pubspec.yaml index 38bb85e..290b9c7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: solian description: "The Solar Network App" publish_to: "none" -version: 1.1.0+1 +version: 1.1.0+46 environment: sdk: ">=3.3.4 <4.0.0"