Compare commits
3 Commits
Author | SHA1 | Date |
---|---|---|
Dan Ballard | f88ec4f34e | |
Dan Ballard | cf4011779f | |
Sarah Jamie Lewis | d4f4e45bf0 |
|
@ -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<Flwtch> 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<Flwtch> 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<Flwtch> with WindowListener {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
globalSettings.initPackageInfo();
|
||||
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
getFlwtchStateProvider(),
|
||||
|
@ -172,10 +175,6 @@ class FlwtchState extends State<Flwtch> 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<Settings, AppState>(
|
||||
builder: (context, settings, appState, child) => MaterialApp(
|
||||
key: Key('app'),
|
||||
|
@ -193,7 +192,7 @@ class FlwtchState extends State<Flwtch> 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(),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
@ -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<void> main() async {
|
||||
|
|
|
@ -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,13 @@ class Settings extends ChangeNotifier {
|
|||
|
||||
bool get useSemanticDebugger => _useSemanticDebugger;
|
||||
|
||||
String? _themeId;
|
||||
String? get themeId => _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 +470,7 @@ class Settings extends ChangeNotifier {
|
|||
}
|
||||
|
||||
/// Construct a default settings object.
|
||||
Settings(this.locale, this.theme);
|
||||
Settings(this.locale);
|
||||
|
||||
String _blodeuweddPath = "";
|
||||
String get blodeuweddPath => _blodeuweddPath;
|
||||
|
@ -478,7 +484,7 @@ class Settings extends ChangeNotifier {
|
|||
dynamic asJson() {
|
||||
return {
|
||||
"Locale": this.locale.toString(),
|
||||
"Theme": theme.theme,
|
||||
"Theme": _themeId,
|
||||
"ThemeMode": theme.mode,
|
||||
"ThemeImages": _themeImages,
|
||||
"PreviousPid": -1,
|
||||
|
|
|
@ -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<String, Map<String, OpaqueThemeType>> themes = Map();
|
||||
class ThemeLoader extends ChangeNotifier {
|
||||
Map<String, Map<String, OpaqueThemeType>> 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]) {
|
||||
|
|
|
@ -132,7 +132,7 @@ class YmlTheme extends OpaqueThemeType {
|
|||
val = yml["themes"][mode]["theme"][val] ?? val;
|
||||
}
|
||||
if (!(val is int)) {
|
||||
val = yml["themes"][mode]?["colors"][val] ?? val;
|
||||
val = yml["themes"][mode]?["colors"]?[val] ?? val;
|
||||
}
|
||||
if (!(val is int)) {
|
||||
val = yml["colors"]?[val];
|
||||
|
|
|
@ -92,17 +92,17 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
|
|||
child: DropdownButton<String>(
|
||||
key: Key("DropdownTheme"),
|
||||
isExpanded: true,
|
||||
value: Provider.of<Settings>(context).theme.theme,
|
||||
value: Provider.of<Settings>(context).themeId,
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
settings.setTheme(newValue!, settings.theme.mode);
|
||||
saveSettings(context);
|
||||
});
|
||||
},
|
||||
items: themes.keys.map<DropdownMenuItem<String>>((String themeId) {
|
||||
items: settings.themeloader.themes.keys.map<DropdownMenuItem<String>>((String themeId) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: themeId,
|
||||
child: Text(getThemeName(context, themeId), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")),
|
||||
child: Text(getThemeName(context, settings, themeId), style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), //"ddi_$themeId", key: Key("ddi_$themeId")),
|
||||
);
|
||||
}).toList())),
|
||||
leading: Icon(Icons.palette, color: settings.current().mainTextColor),
|
||||
|
@ -330,7 +330,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
|
|||
}
|
||||
|
||||
/// Since we don't seem to able to dynamically pull translations, this function maps themes to their names
|
||||
String getThemeName(context, String theme) {
|
||||
String getThemeName(context, Settings settings, String theme) {
|
||||
switch (theme) {
|
||||
case cwtch_theme:
|
||||
return AppLocalizations.of(context)!.themeNameCwtch;
|
||||
|
@ -353,7 +353,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
|
|||
case "juniper":
|
||||
return "Juniper"; // Juniper is a noun, and doesn't get subject to translation...
|
||||
}
|
||||
return theme;
|
||||
return settings.themeloader.themes[theme]?[settings.theme.mode]?.theme ?? theme;
|
||||
}
|
||||
|
||||
void importThemeCheck(BuildContext context, Settings settings, String themesDir, String newThemeDirectory) async {
|
||||
|
@ -372,7 +372,7 @@ class _GlobalSettingsAppearanceViewState extends State<GlobalSettingsAppearanceV
|
|||
|
||||
Directory targetDir = Directory(path.join(themesDir, themeName));
|
||||
// check if exists
|
||||
if (themes.containsKey(themeName) || targetDir.existsSync()) {
|
||||
if (settings.themeloader.themes.containsKey(themeName) || targetDir.existsSync()) {
|
||||
_modalConfirmOverwriteCustomTheme(srcDir, targetDir, themesDir, themeName, settings);
|
||||
} else {
|
||||
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);
|
||||
if (data != null) {
|
||||
themes[themeName] = data;
|
||||
settings.themeloader.themes[themeName] = data;
|
||||
}
|
||||
|
||||
if (settings.current().theme == themeName) {
|
||||
|
|
|
@ -259,7 +259,7 @@ class _MessageViewState extends State<MessageView> {
|
|||
actions: appBarButtons,
|
||||
),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 182.0),
|
||||
padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 164.0),
|
||||
child: MessageList(
|
||||
scrollListener,
|
||||
)),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cwtch/config.dart';
|
||||
import 'package:cwtch/models/appstate.dart';
|
||||
import 'package:cwtch/themes/opaque.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
@ -16,6 +17,7 @@ class SplashView extends StatefulWidget {
|
|||
class _SplashViewState extends State<SplashView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
EnvironmentConfig.debugLog("building splash screen...");
|
||||
var cwtch = Provider.of<FlwtchState>(context, listen: false).cwtch;
|
||||
if (!cwtch.isL10nInit()) {
|
||||
if (AppLocalizations.of(context) != null && AppLocalizations.of(context)!.newMessageNotificationSimple.isNotEmpty) {
|
||||
|
|
|
@ -100,23 +100,22 @@ class FileBubbleState extends State<FileBubble> {
|
|||
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<ProfileInfoState>(context).downloadReset(widget.fileKey());
|
||||
Provider.of<MessageMetadata>(context).attributes["filepath"] = null;
|
||||
Provider.of<MessageMetadata>(context).attributes["file-downloaded"] = "false";
|
||||
Provider.of<MessageMetadata>(context).attributes["file-missing"] = "true";
|
||||
Provider.of<FlwtchState>(context).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, "filepath", "");
|
||||
Provider.of<FlwtchState>(context).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "true");
|
||||
} else {
|
||||
Provider.of<MessageMetadata>(context).attributes["file-missing"] = "false";
|
||||
Provider.of<FlwtchState>(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<ProfileInfoState>(context, listen: false).downloadReset(widget.fileKey());
|
||||
Provider.of<MessageMetadata>(context, listen: false).attributes["filepath"] = null;
|
||||
Provider.of<MessageMetadata>(context, listen: false).attributes["file-downloaded"] = "false";
|
||||
Provider.of<MessageMetadata>(context, listen: false).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, listen: false).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");
|
||||
} else {
|
||||
Provider.of<MessageMetadata>(context, listen: false).attributes["file-missing"] = "false";
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetMessageAttribute(metadata.profileOnion, metadata.conversationIdentifier, 0, metadata.messageID, "file-missing", "false");
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,10 @@ class _MessageListState extends State<MessageList> {
|
|||
image: AssetImage("assets/core/negative_heart_512px.png"),
|
||||
colorFilter: ColorFilter.mode(Provider.of<Settings>(context).theme.hilightElementColor.withOpacity(0.15), BlendMode.srcIn))),
|
||||
// Don't load messages for syncing server...
|
||||
child: loadMessages
|
||||
child:
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 20.0),
|
||||
child: loadMessages
|
||||
? ScrollablePositionedList.builder(
|
||||
itemPositionsListener: widget.scrollListener,
|
||||
itemScrollController: Provider.of<ContactInfoState>(outerContext).messageScrollController,
|
||||
|
@ -152,7 +155,7 @@ class _MessageListState extends State<MessageList> {
|
|||
);
|
||||
},
|
||||
)
|
||||
: null))
|
||||
: null)))
|
||||
])));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
|
||||
|
||||
void main() {
|
||||
|
|
|
@ -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<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
|
||||
|
||||
void main() {
|
||||
|
|
|
@ -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<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
|
||||
|
||||
String file(String slug) {
|
||||
|
|
|
@ -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<Settings> getSettingsEnglishDark() => ChangeNotifierProvider.value(value: settingsEnglishDark);
|
||||
|
||||
String file(String slug) {
|
||||
|
|
Loading…
Reference in New Issue