From 015b6ad10c009bd2ee6a723a24a63b94fe95af7e Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 13 Feb 2024 17:00:47 -0800 Subject: [PATCH] Fix Lazy Loading for Themes --- lib/main.dart | 19 ++++--- lib/main_test.dart | 2 +- lib/settings.dart | 11 ++-- lib/themes/opaque.dart | 57 +++++++++++---------- lib/views/globalsettingsappearanceview.dart | 6 +-- lib/views/splashView.dart | 2 + lib/widgets/filebubble.dart | 33 ++++++------ test/buttontextfield_test.dart | 3 +- test/cwtchlabel_test.dart | 3 +- test/profileimage_test.dart | 3 +- test/textfield_test.dart | 3 +- 11 files changed, 74 insertions(+), 68 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index f3d888a0..72c8e724 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -35,7 +35,7 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:intl/intl.dart' as intl; -var globalSettings = Settings(Locale("en", ''), CwtchDark()); +var globalSettings = Settings(Locale("en", '')); var globalErrorHandler = ErrorHandler(); var globalTorStatus = TorStatus(); var globalAppState = AppState(); @@ -80,7 +80,7 @@ class FlwtchState extends State with WindowListener { @override initState() { print("initState() started, setting up handlers"); - globalSettings = Settings(Locale("en", ''), CwtchDark()); + globalSettings = Settings(Locale("en", '')); globalErrorHandler = ErrorHandler(); globalTorStatus = TorStatus(); globalAppState = AppState(); @@ -109,9 +109,11 @@ class FlwtchState extends State with WindowListener { } print("initState: invoking cwtch.Start()"); // Cwtch.start can take time, we don't want it blocking first splash screen draw, so postpone a smidge to let splash render - Future.delayed(const Duration(milliseconds: 50), () async { - await cwtch.Start(); - LoadThemes(await cwtch.getCwtchDir()); + + cwtch.Start().then((vale) { + cwtch.getCwtchDir().then((dir) { + globalSettings.themeloader.LoadThemes(dir); + }); }); print("initState: starting connectivityListener"); if (EnvironmentConfig.TEST_MODE == false) { @@ -161,6 +163,7 @@ class FlwtchState extends State with WindowListener { @override Widget build(BuildContext context) { globalSettings.initPackageInfo(); + return MultiProvider( providers: [ getFlwtchStateProvider(), @@ -172,10 +175,6 @@ class FlwtchState extends State with WindowListener { getServerListStateProvider(), ], builder: (context, widget) { - // in test mode...rebuild everything every second...if cwtch isn't loaded... - if (EnvironmentConfig.TEST_MODE && cwtch.IsLoaded() == false) { - Timer t = new Timer.periodic(Duration(seconds: 1), (Timer t) => setState(() {})); - } return Consumer2( builder: (context, settings, appState, child) => MaterialApp( key: Key('app'), @@ -193,7 +192,7 @@ class FlwtchState extends State with WindowListener { title: 'Cwtch', showSemanticsDebugger: settings.useSemanticDebugger, theme: mkThemeData(settings), - home: (!appState.cwtchInit || appState.modalState != ModalState.none) || !cwtch.IsLoaded() ? SplashView() : ProfileMgrView(), + home: (!appState.cwtchInit || appState.modalState != ModalState.none) ? SplashView() : ProfileMgrView(), ), ); }, diff --git a/lib/main_test.dart b/lib/main_test.dart index a6abe145..537f96e4 100644 --- a/lib/main_test.dart +++ b/lib/main_test.dart @@ -17,7 +17,7 @@ import "package:flutter_driver/driver_extension.dart"; import 'package:flutter_test/flutter_test.dart'; import 'package:glob/glob.dart'; -var globalSettings = Settings(Locale("en", ''), CwtchDark()); +var globalSettings = Settings(Locale("en", '')); var globalErrorHandler = ErrorHandler(); Future main() async { diff --git a/lib/settings.dart b/lib/settings.dart index 786171ac..db286c60 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -42,7 +42,6 @@ enum NotificationContent { class Settings extends ChangeNotifier { Locale locale; late PackageInfo packageInfo; - OpaqueThemeType theme; bool _themeImages = false; // explicitly set experiments to false until told otherwise... @@ -70,6 +69,8 @@ class Settings extends ChangeNotifier { bool _useSemanticDebugger = false; double _fontScaling = 1.0; + ThemeLoader themeloader = ThemeLoader(); + String get torCacheDir => _torCacheDir; // Whether to show the profiling interface, not saved @@ -88,8 +89,12 @@ class Settings extends ChangeNotifier { bool get useSemanticDebugger => _useSemanticDebugger; + String? _themeId; + String? _mode; + OpaqueThemeType get theme => themeloader.getTheme(_themeId, _mode); void setTheme(String themeId, String mode) { - theme = getTheme(themeId, mode); + _themeId = themeId; + _mode = mode; notifyListeners(); } @@ -464,7 +469,7 @@ class Settings extends ChangeNotifier { } /// Construct a default settings object. - Settings(this.locale, this.theme); + Settings(this.locale); String _blodeuweddPath = ""; String get blodeuweddPath => _blodeuweddPath; diff --git a/lib/themes/opaque.dart b/lib/themes/opaque.dart index bab22160..95c314f8 100644 --- a/lib/themes/opaque.dart +++ b/lib/themes/opaque.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'dart:ui'; import 'dart:core'; +import 'package:cwtch/config.dart'; import 'package:cwtch/themes/cwtch.dart'; import 'package:cwtch/themes/yamltheme.dart'; import 'package:flutter/material.dart'; @@ -21,36 +22,40 @@ final TextStyle defaultTextStyle = TextStyle(fontFamily: "Inter", fontWeight: Fo final TextStyle defaultTextButtonStyle = defaultTextStyle.copyWith(fontWeight: FontWeight.bold); final TextStyle defaultDropDownMenuItemTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: 16); -Map> themes = Map(); +class ThemeLoader extends ChangeNotifier { + Map> themes = Map(); -LoadThemes(String cwtchDir) async { - themes = await loadBuiltinThemes(); - final customThemes = await loadCustomThemes(path.join(cwtchDir, custom_themes_subdir)); - themes.addAll(customThemes); -} - -OpaqueThemeType getTheme(String themeId, String mode) { - if (themeId == "") { - themeId = cwtch_theme; - } - if (themeId == mode_light) { - themeId = cwtch_theme; - mode = mode_light; - } - if (themeId == mode_dark) { - themeId = cwtch_theme; - mode = mode_dark; + LoadThemes(String cwtchDir) async { + loadBuiltinThemes().then((dir) { + themes.addAll(dir); + notifyListeners(); + loadCustomThemes(path.join(cwtchDir, custom_themes_subdir)).then((customThemes) { + themes.addAll(customThemes); + notifyListeners(); + }); + }); } - var theme = themes[themeId]?[mode] ?? themes[themeId]?[flipMode(mode)]; - return theme ?? CwtchDark(); -} - -String flipMode(String mode) { - if (mode == mode_dark) { - return mode_light; + OpaqueThemeType getTheme(String? themeId, String? mode) { + if (themeId == null) { + themeId = cwtch_theme; + } + if (themeId == mode_light) { + mode = mode_light; + } + if (themeId == mode_dark) { + mode = mode_dark; + } + var theme = themes[themeId]?[mode] ?? themes[themeId]?[flipMode(mode ?? mode_dark)]; + return theme ?? CwtchDark(); + } + + String flipMode(String mode) { + if (mode == mode_dark) { + return mode_light; + } + return mode_dark; } - return mode_dark; } Color lighten(Color color, [double amount = 0.15]) { diff --git a/lib/views/globalsettingsappearanceview.dart b/lib/views/globalsettingsappearanceview.dart index cf31d9e0..416d6bab 100644 --- a/lib/views/globalsettingsappearanceview.dart +++ b/lib/views/globalsettingsappearanceview.dart @@ -99,7 +99,7 @@ class _GlobalSettingsAppearanceViewState extends State>((String themeId) { + items: settings.themeloader.themes.keys.map>((String themeId) { return DropdownMenuItem( value: themeId, child: Text(getThemeName(context, themeId), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")), @@ -372,7 +372,7 @@ class _GlobalSettingsAppearanceViewState extends State { @override Widget build(BuildContext context) { + EnvironmentConfig.debugLog("building splash screen..."); var cwtch = Provider.of(context, listen: false).cwtch; if (!cwtch.isL10nInit()) { if (AppLocalizations.of(context) != null && AppLocalizations.of(context)!.newMessageNotificationSimple.isNotEmpty) { diff --git a/lib/widgets/filebubble.dart b/lib/widgets/filebubble.dart index df27041d..ef76dc19 100644 --- a/lib/widgets/filebubble.dart +++ b/lib/widgets/filebubble.dart @@ -100,23 +100,22 @@ class FileBubbleState extends State { if (downloadComplete && path != null) { if (isImagePreview) { if (myFile == null || myFile?.path != path) { - setState(() { - myFile = new File(path!); - // reset - if (myFile?.existsSync() == false) { - myFile = null; - Provider.of(context).downloadReset(widget.fileKey()); - Provider.of(context).attributes["filepath"] = null; - Provider.of(context).attributes["file-downloaded"] = "false"; - Provider.of(context).attributes["file-missing"] = "true"; - Provider.of(context).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-downloaded", "false"); - Provider.of(context).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "filepath", ""); - Provider.of(context).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "true"); - } else { - Provider.of(context).attributes["file-missing"] = "false"; - Provider.of(context).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "false"); - } - }); + myFile = new File(path!); + // reset + if (myFile?.existsSync() == false) { + myFile = null; + //Provider.of(context, listen: false).downloadReset(widget.fileKey()); + Provider.of(context, listen: false).attributes["filepath"] = null; + Provider.of(context, listen: false).attributes["file-downloaded"] = "false"; + Provider.of(context, listen: false).attributes["file-missing"] = "true"; + Provider.of(context, listen: false).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-downloaded", "false"); + Provider.of(context, listen: false).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "filepath", ""); + Provider.of(context, listen: false).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "true"); + } else { + Provider.of(context, listen: false).attributes["file-missing"] = "false"; + Provider.of(context, listen: false).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "false"); + setState(() {}); + } } } } diff --git a/test/buttontextfield_test.dart b/test/buttontextfield_test.dart index 95c2d65a..eb603162 100644 --- a/test/buttontextfield_test.dart +++ b/test/buttontextfield_test.dart @@ -15,8 +15,7 @@ import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -var settingsEnglishDark = Settings(Locale("en", ''), CwtchDark()); -var settingsEnglishLight = Settings(Locale("en", ''), CwtchLight()); +var settingsEnglishDark = Settings(Locale("en", ''),); ChangeNotifierProvider getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark); void main() { diff --git a/test/cwtchlabel_test.dart b/test/cwtchlabel_test.dart index 63ad75b7..52eeebfb 100644 --- a/test/cwtchlabel_test.dart +++ b/test/cwtchlabel_test.dart @@ -15,8 +15,7 @@ import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -var settingsEnglishDark = Settings(Locale("en", ''), CwtchDark()); -var settingsEnglishLight = Settings(Locale("en", ''), CwtchLight()); +var settingsEnglishDark = Settings(Locale("en", '')); ChangeNotifierProvider getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark); void main() { diff --git a/test/profileimage_test.dart b/test/profileimage_test.dart index 239aa5aa..93dcf068 100644 --- a/test/profileimage_test.dart +++ b/test/profileimage_test.dart @@ -15,8 +15,7 @@ import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -var settingsEnglishDark = Settings(Locale("en", ''), CwtchDark()); -var settingsEnglishLight = Settings(Locale("en", ''), CwtchLight()); +var settingsEnglishDark = Settings(Locale("en", '')); ChangeNotifierProvider getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark); String file(String slug) { diff --git a/test/textfield_test.dart b/test/textfield_test.dart index 27ea0f3e..514b4bb3 100644 --- a/test/textfield_test.dart +++ b/test/textfield_test.dart @@ -15,8 +15,7 @@ import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -var settingsEnglishDark = Settings(Locale("en", ''), CwtchDark()); -var settingsEnglishLight = Settings(Locale("en", ''), CwtchLight()); +var settingsEnglishDark = Settings(Locale("en", '')); ChangeNotifierProvider getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark); String file(String slug) {