@@ -13,42 +13,47 @@ import 'models/settings_service.dart';
1313import 'routes/app_routes.dart' ;
1414import 'services/auth_state.dart' ;
1515import 'utils/talker.dart' ;
16+ import 'widgets/app_alert_dialog.dart' ;
1617
1718void main () async {
1819 WidgetsFlutterBinding .ensureInitialized ();
1920 MediaKit .ensureInitialized ();
20-
21- final isDesktop = ! kIsWeb && (Platform .isWindows || Platform .isMacOS || Platform .isLinux);
21+
22+ final isDesktop =
23+ ! kIsWeb && (Platform .isWindows || Platform .isMacOS || Platform .isLinux);
2224 final startupRecovery = await _performStartupRecovery (isDesktop: isDesktop);
2325 await SettingsService .instance.init ();
24-
26+
2527 if (isDesktop) {
2628 await windowManager.ensureInitialized ();
2729 }
28-
30+
2931 final prefs = await SharedPreferences .getInstance ();
30-
32+
3133 if (isDesktop) {
3234 const defaultSize = Size (1280 , 800 );
3335 const minSize = Size (400 , 700 );
3436 final savedWidth = prefs.getDouble ('window_width' );
3537 final savedHeight = prefs.getDouble ('window_height' );
3638 final savedX = prefs.getDouble ('window_x' );
3739 final savedY = prefs.getDouble ('window_y' );
38- final windowOpacity = SettingsService .instance.getValue <double >('windowOpacity' , 1.0 );
39-
40+ final windowOpacity = SettingsService .instance.getValue <double >(
41+ 'windowOpacity' ,
42+ 1.0 ,
43+ );
44+
4045 final initialSize = (savedWidth != null && savedHeight != null )
4146 ? Size (savedWidth, savedHeight)
4247 : defaultSize;
43-
48+
4449 WindowOptions windowOptions = WindowOptions (
4550 size: initialSize,
4651 center: savedX == null || savedY == null ,
4752 backgroundColor: Colors .transparent,
4853 skipTaskbar: false ,
4954 titleBarStyle: TitleBarStyle .hidden,
5055 );
51-
56+
5257 windowManager.waitUntilReadyToShow (windowOptions, () async {
5358 if (Platform .isLinux) {
5459 final env = Platform .environment;
@@ -60,21 +65,21 @@ void main() async {
6065 if (savedX != null && savedY != null ) {
6166 await windowManager.setPosition (Offset (savedX, savedY));
6267 }
63-
68+
6469 await windowManager.setMinimumSize (minSize);
6570 await windowManager.setOpacity (windowOpacity);
6671 await windowManager.show ();
6772 await windowManager.focus ();
6873 });
6974 }
70-
75+
7176 final isFirstLaunch = prefs.getBool ('isFirstLaunch' ) ?? true ;
72-
77+
7378 talker.info ('TouchFish Client started!' );
7479 AuthState .instance.init ().catchError ((e) {
7580 talker.error ('AuthState.init error' , e);
7681 });
77-
82+
7883 runApp (
7984 TouchFishApp (
8085 isFirstLaunch: isFirstLaunch,
@@ -123,7 +128,9 @@ Future<bool> _repairSharedPreferencesFileIfCorrupted() async {
123128 }
124129
125130 await preferencesFile.writeAsString ('{}' , flush: true );
126- talker.warning ('Shared preferences file had an invalid root JSON value and was reset.' );
131+ talker.warning (
132+ 'Shared preferences file had an invalid root JSON value and was reset.' ,
133+ );
127134 return true ;
128135 } on FormatException catch (error, stackTrace) {
129136 try {
@@ -133,14 +140,26 @@ Future<bool> _repairSharedPreferencesFileIfCorrupted() async {
133140 );
134141 await preferencesFile.writeAsString ('{}' , flush: true );
135142 } catch (writeError, writeStackTrace) {
136- talker.error ('Failed to rewrite corrupted shared preferences file.' , writeError, writeStackTrace);
143+ talker.error (
144+ 'Failed to rewrite corrupted shared preferences file.' ,
145+ writeError,
146+ writeStackTrace,
147+ );
137148 return false ;
138149 }
139150
140- talker.error ('Shared preferences JSON parse failed and the file was reset.' , error, stackTrace);
151+ talker.error (
152+ 'Shared preferences JSON parse failed and the file was reset.' ,
153+ error,
154+ stackTrace,
155+ );
141156 return true ;
142157 } catch (error, stackTrace) {
143- talker.error ('Failed while checking shared preferences file integrity.' , error, stackTrace);
158+ talker.error (
159+ 'Failed while checking shared preferences file integrity.' ,
160+ error,
161+ stackTrace,
162+ );
144163 return false ;
145164 }
146165}
@@ -175,20 +194,17 @@ Future<bool> _resetWindowPositionIfFarOutsideScreen(
175194 screenWidth * 3 ,
176195 screenHeight * 3 ,
177196 );
178- final windowBounds = Rect .fromLTWH (
179- savedX,
180- savedY,
181- savedWidth,
182- savedHeight,
183- );
197+ final windowBounds = Rect .fromLTWH (savedX, savedY, savedWidth, savedHeight);
184198
185199 if (windowBounds.overlaps (allowedBounds)) {
186200 return false ;
187201 }
188202
189203 await prefs.remove ('window_x' );
190204 await prefs.remove ('window_y' );
191- talker.warning ('Saved window position was far outside the current screen bounds and was reset.' );
205+ talker.warning (
206+ 'Saved window position was far outside the current screen bounds and was reset.' ,
207+ );
192208 return true ;
193209}
194210
@@ -205,7 +221,7 @@ class _StartupRecoveryResult {
205221class TouchFishApp extends StatefulWidget {
206222 final bool isFirstLaunch;
207223 final bool didResetLocalSettings;
208-
224+
209225 const TouchFishApp ({
210226 super .key,
211227 required this .isFirstLaunch,
@@ -218,7 +234,9 @@ class TouchFishApp extends StatefulWidget {
218234
219235class _TouchFishAppState extends State <TouchFishApp > {
220236 final _appState = AppState .instance;
221- late final _router = AppRoutes .createRouter (isFirstLaunch: widget.isFirstLaunch);
237+ late final _router = AppRoutes .createRouter (
238+ isFirstLaunch: widget.isFirstLaunch,
239+ );
222240 bool _didShowStartupResetNotice = false ;
223241
224242 void _showStartupResetNoticeIfNeeded (BuildContext context) {
@@ -233,19 +251,10 @@ class _TouchFishAppState extends State<TouchFishApp> {
233251 final l10n = AppLocalizations .of (context);
234252 if (l10n == null ) return ;
235253
236- showDialog <void >(
237- context: context,
238- builder: (dialogContext) {
239- return AlertDialog (
240- content: Text (l10n.settingsCorruptedResetNotice),
241- actions: [
242- TextButton (
243- onPressed: () => Navigator .of (dialogContext).pop (),
244- child: Text (MaterialLocalizations .of (dialogContext).okButtonLabel),
245- ),
246- ],
247- );
248- },
254+ showTouchFishInfoDialog <void >(
255+ context,
256+ message: l10n.settingsCorruptedResetNotice,
257+ icon: Icons .settings_suggest_rounded,
249258 );
250259 });
251260 }
@@ -272,7 +281,8 @@ class _TouchFishAppState extends State<TouchFishApp> {
272281 }
273282 final cardOpacity = _appState.cardOpacity;
274283 final backgroundImagePath = _appState.backgroundImagePath;
275- final hasBackgroundImage = backgroundImagePath != null && backgroundImagePath.isNotEmpty;
284+ final hasBackgroundImage =
285+ backgroundImagePath != null && backgroundImagePath.isNotEmpty;
276286
277287 return MaterialApp .router (
278288 routerConfig: _router,
@@ -284,16 +294,15 @@ class _TouchFishAppState extends State<TouchFishApp> {
284294 GlobalWidgetsLocalizations .delegate,
285295 GlobalCupertinoLocalizations .delegate,
286296 ],
287- supportedLocales: const [
288- Locale ('en' ),
289- Locale ('zh' ),
290- ],
297+ supportedLocales: const [Locale ('en' ), Locale ('zh' )],
291298 locale: _appState.locale,
292299 theme: ThemeData (
293300 colorScheme: lightColorScheme,
294301 useMaterial3: true ,
295302 fontFamily: _appState.fontFamily,
296- scaffoldBackgroundColor: hasBackgroundImage ? Colors .transparent : null ,
303+ scaffoldBackgroundColor: hasBackgroundImage
304+ ? Colors .transparent
305+ : null ,
297306 cardTheme: CardThemeData (
298307 color: lightColorScheme.surfaceContainer.withOpacity (cardOpacity),
299308 elevation: cardOpacity < 1 ? 0 : null ,
@@ -303,7 +312,9 @@ class _TouchFishAppState extends State<TouchFishApp> {
303312 colorScheme: darkColorScheme,
304313 useMaterial3: true ,
305314 fontFamily: _appState.fontFamily,
306- scaffoldBackgroundColor: hasBackgroundImage ? Colors .transparent : null ,
315+ scaffoldBackgroundColor: hasBackgroundImage
316+ ? Colors .transparent
317+ : null ,
307318 cardTheme: CardThemeData (
308319 color: darkColorScheme.surfaceContainer.withOpacity (cardOpacity),
309320 elevation: cardOpacity < 1 ? 0 : null ,
@@ -318,7 +329,9 @@ class _TouchFishAppState extends State<TouchFishApp> {
318329 child: Container (
319330 decoration: BoxDecoration (
320331 backgroundBlendMode: BlendMode .darken,
321- color: Theme .of (context).colorScheme.surface.withOpacity (0.85 ),
332+ color: Theme .of (
333+ context,
334+ ).colorScheme.surface.withOpacity (0.85 ),
322335 image: DecorationImage (
323336 opacity: 0.2 ,
324337 image: FileImage (File (backgroundImagePath)),
@@ -336,14 +349,29 @@ class _TouchFishAppState extends State<TouchFishApp> {
336349 );
337350 }
338351
339- ColorScheme _applyCustomColors (ColorScheme scheme, Map <String , int > customColors) {
352+ ColorScheme _applyCustomColors (
353+ ColorScheme scheme,
354+ Map <String , int > customColors,
355+ ) {
340356 return scheme.copyWith (
341- primary: customColors['primary' ] != null ? Color (customColors['primary' ]! ) : null ,
342- secondary: customColors['secondary' ] != null ? Color (customColors['secondary' ]! ) : null ,
343- tertiary: customColors['tertiary' ] != null ? Color (customColors['tertiary' ]! ) : null ,
344- surface: customColors['surface' ] != null ? Color (customColors['surface' ]! ) : null ,
345- background: customColors['background' ] != null ? Color (customColors['background' ]! ) : null ,
346- error: customColors['error' ] != null ? Color (customColors['error' ]! ) : null ,
357+ primary: customColors['primary' ] != null
358+ ? Color (customColors['primary' ]! )
359+ : null ,
360+ secondary: customColors['secondary' ] != null
361+ ? Color (customColors['secondary' ]! )
362+ : null ,
363+ tertiary: customColors['tertiary' ] != null
364+ ? Color (customColors['tertiary' ]! )
365+ : null ,
366+ surface: customColors['surface' ] != null
367+ ? Color (customColors['surface' ]! )
368+ : null ,
369+ background: customColors['background' ] != null
370+ ? Color (customColors['background' ]! )
371+ : null ,
372+ error: customColors['error' ] != null
373+ ? Color (customColors['error' ]! )
374+ : null ,
347375 );
348376 }
349377}
0 commit comments