Fix Lazy Loading for Themes

This commit is contained in:
Sarah Jamie Lewis 2024-02-13 17:00:47 -08:00
parent ea213080b1
commit 015b6ad10c
Signed by: sarah
GPG Key ID: F27FD21A270837EF
11 changed files with 74 additions and 68 deletions

View File

@ -35,7 +35,7 @@ import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:intl/intl.dart' as intl; import 'package:intl/intl.dart' as intl;
var globalSettings = Settings(Locale("en", ''), CwtchDark()); var globalSettings = Settings(Locale("en", ''));
var globalErrorHandler = ErrorHandler(); var globalErrorHandler = ErrorHandler();
var globalTorStatus = TorStatus(); var globalTorStatus = TorStatus();
var globalAppState = AppState(); var globalAppState = AppState();
@ -80,7 +80,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
@override @override
initState() { initState() {
print("initState() started, setting up handlers"); print("initState() started, setting up handlers");
globalSettings = Settings(Locale("en", ''), CwtchDark()); globalSettings = Settings(Locale("en", ''));
globalErrorHandler = ErrorHandler(); globalErrorHandler = ErrorHandler();
globalTorStatus = TorStatus(); globalTorStatus = TorStatus();
globalAppState = AppState(); globalAppState = AppState();
@ -109,9 +109,11 @@ class FlwtchState extends State<Flwtch> with WindowListener {
} }
print("initState: invoking cwtch.Start()"); 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 // 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(); cwtch.Start().then((vale) {
LoadThemes(await cwtch.getCwtchDir()); cwtch.getCwtchDir().then((dir) {
globalSettings.themeloader.LoadThemes(dir);
});
}); });
print("initState: starting connectivityListener"); print("initState: starting connectivityListener");
if (EnvironmentConfig.TEST_MODE == false) { if (EnvironmentConfig.TEST_MODE == false) {
@ -161,6 +163,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
globalSettings.initPackageInfo(); globalSettings.initPackageInfo();
return MultiProvider( return MultiProvider(
providers: [ providers: [
getFlwtchStateProvider(), getFlwtchStateProvider(),
@ -172,10 +175,6 @@ class FlwtchState extends State<Flwtch> with WindowListener {
getServerListStateProvider(), getServerListStateProvider(),
], ],
builder: (context, widget) { 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<Settings, AppState>( return Consumer2<Settings, AppState>(
builder: (context, settings, appState, child) => MaterialApp( builder: (context, settings, appState, child) => MaterialApp(
key: Key('app'), key: Key('app'),
@ -193,7 +192,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
title: 'Cwtch', title: 'Cwtch',
showSemanticsDebugger: settings.useSemanticDebugger, showSemanticsDebugger: settings.useSemanticDebugger,
theme: mkThemeData(settings), theme: mkThemeData(settings),
home: (!appState.cwtchInit || appState.modalState != ModalState.none) || !cwtch.IsLoaded() ? SplashView() : ProfileMgrView(), home: (!appState.cwtchInit || appState.modalState != ModalState.none) ? SplashView() : ProfileMgrView(),
), ),
); );
}, },

View File

@ -17,7 +17,7 @@ import "package:flutter_driver/driver_extension.dart";
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:glob/glob.dart'; import 'package:glob/glob.dart';
var globalSettings = Settings(Locale("en", ''), CwtchDark()); var globalSettings = Settings(Locale("en", ''));
var globalErrorHandler = ErrorHandler(); var globalErrorHandler = ErrorHandler();
Future<void> main() async { Future<void> main() async {

View File

@ -42,7 +42,6 @@ enum NotificationContent {
class Settings extends ChangeNotifier { class Settings extends ChangeNotifier {
Locale locale; Locale locale;
late PackageInfo packageInfo; late PackageInfo packageInfo;
OpaqueThemeType theme;
bool _themeImages = false; bool _themeImages = false;
// explicitly set experiments to false until told otherwise... // explicitly set experiments to false until told otherwise...
@ -70,6 +69,8 @@ class Settings extends ChangeNotifier {
bool _useSemanticDebugger = false; bool _useSemanticDebugger = false;
double _fontScaling = 1.0; double _fontScaling = 1.0;
ThemeLoader themeloader = ThemeLoader();
String get torCacheDir => _torCacheDir; String get torCacheDir => _torCacheDir;
// Whether to show the profiling interface, not saved // Whether to show the profiling interface, not saved
@ -88,8 +89,12 @@ class Settings extends ChangeNotifier {
bool get useSemanticDebugger => _useSemanticDebugger; bool get useSemanticDebugger => _useSemanticDebugger;
String? _themeId;
String? _mode;
OpaqueThemeType get theme => themeloader.getTheme(_themeId, _mode);
void setTheme(String themeId, String mode) { void setTheme(String themeId, String mode) {
theme = getTheme(themeId, mode); _themeId = themeId;
_mode = mode;
notifyListeners(); notifyListeners();
} }
@ -464,7 +469,7 @@ class Settings extends ChangeNotifier {
} }
/// Construct a default settings object. /// Construct a default settings object.
Settings(this.locale, this.theme); Settings(this.locale);
String _blodeuweddPath = ""; String _blodeuweddPath = "";
String get blodeuweddPath => _blodeuweddPath; String get blodeuweddPath => _blodeuweddPath;

View File

@ -2,6 +2,7 @@ import 'dart:io';
import 'dart:ui'; import 'dart:ui';
import 'dart:core'; import 'dart:core';
import 'package:cwtch/config.dart';
import 'package:cwtch/themes/cwtch.dart'; import 'package:cwtch/themes/cwtch.dart';
import 'package:cwtch/themes/yamltheme.dart'; import 'package:cwtch/themes/yamltheme.dart';
import 'package:flutter/material.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 defaultTextButtonStyle = defaultTextStyle.copyWith(fontWeight: FontWeight.bold);
final TextStyle defaultDropDownMenuItemTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: 16); final TextStyle defaultDropDownMenuItemTextStyle = TextStyle(fontFamily: "Inter", fontWeight: FontWeight.bold, fontSize: 16);
Map<String, Map<String, OpaqueThemeType>> themes = Map(); class ThemeLoader extends ChangeNotifier {
Map<String, Map<String, OpaqueThemeType>> themes = Map();
LoadThemes(String cwtchDir) async { LoadThemes(String cwtchDir) async {
themes = await loadBuiltinThemes(); loadBuiltinThemes().then((dir) {
final customThemes = await loadCustomThemes(path.join(cwtchDir, custom_themes_subdir)); themes.addAll(dir);
themes.addAll(customThemes); notifyListeners();
} loadCustomThemes(path.join(cwtchDir, custom_themes_subdir)).then((customThemes) {
themes.addAll(customThemes);
OpaqueThemeType getTheme(String themeId, String mode) { notifyListeners();
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;
} }
var theme = themes[themeId]?[mode] ?? themes[themeId]?[flipMode(mode)]; OpaqueThemeType getTheme(String? themeId, String? mode) {
return theme ?? CwtchDark(); if (themeId == null) {
} themeId = cwtch_theme;
}
String flipMode(String mode) { if (themeId == mode_light) {
if (mode == mode_dark) { mode = mode_light;
return 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]) { Color lighten(Color color, [double amount = 0.15]) {

View File

@ -99,7 +99,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
saveSettings(context); saveSettings(context);
}); });
}, },
items: themes.keys.map<DropdownMenuItem<String>>((String themeId) { items: settings.themeloader.themes.keys.map<DropdownMenuItem<String>>((String themeId) {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(
value: themeId, value: themeId,
child: Text(getThemeName(context, themeId), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")), child: Text(getThemeName(context, themeId), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")),
@ -372,7 +372,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
Directory targetDir = Directory(path.join(themesDir, themeName)); Directory targetDir = Directory(path.join(themesDir, themeName));
// check if exists // check if exists
if (themes.containsKey(themeName) || targetDir.existsSync()) { if (settings.themeloader.themes.containsKey(themeName) || targetDir.existsSync()) {
_modalConfirmOverwriteCustomTheme(srcDir, targetDir, themesDir, themeName, settings); _modalConfirmOverwriteCustomTheme(srcDir, targetDir, themesDir, themeName, settings);
} else { } else {
importTheme(srcDir, targetDir, themesDir, themeName, settings); importTheme(srcDir, targetDir, themesDir, themeName, settings);
@ -393,7 +393,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
var data = await loadFileYamlTheme(path.join(targetDir.path, "theme.yml"), targetDir.path); var data = await loadFileYamlTheme(path.join(targetDir.path, "theme.yml"), targetDir.path);
if (data != null) { if (data != null) {
themes[themeName] = data; settings.themeloader.themes[themeName] = data;
} }
if (settings.current().theme == themeName) { if (settings.current().theme == themeName) {

View File

@ -1,3 +1,4 @@
import 'package:cwtch/config.dart';
import 'package:cwtch/models/appstate.dart'; import 'package:cwtch/models/appstate.dart';
import 'package:cwtch/themes/opaque.dart'; import 'package:cwtch/themes/opaque.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -16,6 +17,7 @@ class SplashView extends StatefulWidget {
class _SplashViewState extends State<SplashView> { class _SplashViewState extends State<SplashView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
EnvironmentConfig.debugLog("building splash screen...");
var cwtch = Provider.of<FlwtchState>(context, listen: false).cwtch; var cwtch = Provider.of<FlwtchState>(context, listen: false).cwtch;
if (!cwtch.isL10nInit()) { if (!cwtch.isL10nInit()) {
if (AppLocalizations.of(context) != null && AppLocalizations.of(context)!.newMessageNotificationSimple.isNotEmpty) { if (AppLocalizations.of(context) != null && AppLocalizations.of(context)!.newMessageNotificationSimple.isNotEmpty) {

View File

@ -100,23 +100,22 @@ class FileBubbleState extends State<FileBubble> {
if (downloadComplete && path != null) { if (downloadComplete && path != null) {
if (isImagePreview) { if (isImagePreview) {
if (myFile == null || myFile?.path != path) { if (myFile == null || myFile?.path != path) {
setState(() { myFile = new File(path!);
myFile = new File(path!); // reset
// reset if (myFile?.existsSync() == false) {
if (myFile?.existsSync() == false) { myFile = null;
myFile = null; //Provider.of<ProfileInfoState>(context, listen: false).downloadReset(widget.fileKey());
Provider.of<ProfileInfoState>(context).downloadReset(widget.fileKey()); Provider.of<MessageMetadata>(context, listen: false).attributes["filepath"] = null;
Provider.of<MessageMetadata>(context).attributes["filepath"] = null; Provider.of<MessageMetadata>(context, listen: false).attributes["file-downloaded"] = "false";
Provider.of<MessageMetadata>(context).attributes["file-downloaded"] = "false"; Provider.of<MessageMetadata>(context, listen: false).attributes["file-missing"] = "true";
Provider.of<MessageMetadata>(context).attributes["file-missing"] = "true"; Provider.of<FlwtchState>(context, listen: false).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-downloaded", "false");
Provider.of<FlwtchState>(context).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-downloaded", "false"); Provider.of<FlwtchState>(context, listen: false).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "filepath", "");
Provider.of<FlwtchState>(context).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "filepath", ""); Provider.of<FlwtchState>(context, listen: false).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "true");
Provider.of<FlwtchState>(context).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "true"); } else {
} else { Provider.of<MessageMetadata>(context, listen: false).attributes["file-missing"] = "false";
Provider.of<MessageMetadata>(context).attributes["file-missing"] = "false"; Provider.of<FlwtchState>(context, listen: false).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "false");
Provider.of<FlwtchState>(context).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "false"); setState(() {});
} }
});
} }
} }
} }

View File

@ -15,8 +15,7 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
var settingsEnglishDark = Settings(Locale("en", ''), CwtchDark()); var settingsEnglishDark = Settings(Locale("en", ''),);
var settingsEnglishLight = Settings(Locale("en", ''), CwtchLight());
ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark); ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
void main() { void main() {

View File

@ -15,8 +15,7 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
var settingsEnglishDark = Settings(Locale("en", ''), CwtchDark()); var settingsEnglishDark = Settings(Locale("en", ''));
var settingsEnglishLight = Settings(Locale("en", ''), CwtchLight());
ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark); ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
void main() { void main() {

View File

@ -15,8 +15,7 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
var settingsEnglishDark = Settings(Locale("en", ''), CwtchDark()); var settingsEnglishDark = Settings(Locale("en", ''));
var settingsEnglishLight = Settings(Locale("en", ''), CwtchLight());
ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark); ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
String file(String slug) { String file(String slug) {

View File

@ -15,8 +15,7 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
var settingsEnglishDark = Settings(Locale("en", ''), CwtchDark()); var settingsEnglishDark = Settings(Locale("en", ''));
var settingsEnglishLight = Settings(Locale("en", ''), CwtchLight());
ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark); ChangeNotifierProvider<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
String file(String slug) { String file(String slug) {