diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index f4bfeaf5c..f7db1049a 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -17,7 +17,6 @@
-
@@ -161,16 +160,6 @@
android:foregroundServiceType="camera|microphone|mediaProjection">
-
-
-
-
-
-
diff --git a/config.sample.json b/config.sample.json
index 03ac42a6a..ad34192a1 100644
--- a/config.sample.json
+++ b/config.sample.json
@@ -1,10 +1,29 @@
{
- "application_name": "PangeaChat",
- "application_welcome_message": null,
- "default_homeserver": "matrix.pangea.chat",
- "web_base_url": "https://web.pangea.chat",
- "privacy_url": "https://pangea.chat/privacy",
- "render_html": false,
- "hide_redacted_events": false,
- "hide_unknown_events": false
+ "applicationName": "PangeaChat",
+ "defaultHomeserver": "matrix.pangea.chat",
+ "privacyUrl": "https://pangea.chat/privacy",
+ "audioRecordingNumChannels": 1,
+ "audioRecordingAutoGain": true,
+ "audioRecordingEchoCancel": false,
+ "audioRecordingNoiseSuppress": true,
+ "audioRecordingBitRate": 64000,
+ "audioRecordingSamplingRate": 44100,
+ "renderHtml": true,
+ "fontSizeFactor": 1,
+ "hideRedactedEvents": false,
+ "hideUnknownEvents": true,
+ "separateChatTypes": false,
+ "autoplayImages": true,
+ "sendTypingNotifications": true,
+ "sendPublicReadReceipts": true,
+ "swipeRightToLeftToReply": true,
+ "sendOnEnter": false,
+ "showPresences": true,
+ "displayNavigationRail": false,
+ "experimentalVoip": false,
+ "shareKeysWith": "all",
+ "noEncryptionWarningShown": false,
+ "displayChatDetailsColumn": false,
+ "colorSchemeSeedInt": 4283835834,
+ "enableSoftLogout": false
}
\ No newline at end of file
diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart
index 4b49aac6b..3a0139365 100644
--- a/integration_test/app_test.dart
+++ b/integration_test/app_test.dart
@@ -1,4 +1,3 @@
-import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/pages/chat/chat_view.dart';
import 'package:fluffychat/pages/chat_list/chat_list_body.dart';
import 'package:fluffychat/pages/chat_list/search_title.dart';
@@ -25,7 +24,7 @@ void main() {
() async {
// this random dialog popping up is super hard to cover in tests
SharedPreferences.setMockInitialValues({
- SettingKeys.showNoGoogle: false,
+ 'chat.fluffy.show_no_google': false,
});
},
);
diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart
index f566ed862..099555dfb 100644
--- a/lib/config/app_config.dart
+++ b/lib/config/app_config.dart
@@ -2,97 +2,41 @@ import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/pangea/common/config/environment.dart';
abstract class AppConfig {
// #Pangea
- // static String _applicationName = 'FluffyChat';
- static String _applicationName = 'Pangea Chat';
+ static String get defaultHomeserver => Environment.synapseURL;
+ // Pangea#
+ // Const and final configuration values (immutable)
// #Pangea
-
- static String get applicationName => _applicationName;
- static String? _applicationWelcomeMessage;
-
- static String? get applicationWelcomeMessage => _applicationWelcomeMessage;
- // #Pangea
- // static String _defaultHomeserver = 'matrix.org';
- static String get _defaultHomeserver => Environment.synapseURL;
+ // static const Color primaryColor = Color(0xFF5625BA);
+ // static const Color primaryColorLight = Color(0xFFCCBDEA);
+ // static const Color secondaryColor = Color(0xFF41a2bc);
+ static const Color primaryColor = Color(0xFF8560E0);
+ static const Color primaryColorLight = Color(0xFFDBC9FF);
+ static const Color secondaryColor = Color.fromARGB(255, 253, 191, 1);
// Pangea#
- static String get defaultHomeserver => _defaultHomeserver;
- static double fontSizeFactor = 1;
static const Color chatColor = primaryColor;
- static Color? colorSchemeSeed = primaryColor;
static const double messageFontSize = 16.0;
static const bool allowOtherHomeservers = true;
static const bool enableRegistration = true;
+ static const bool hideTypingUsernames = false;
+
+ static const String inviteLinkPrefix = 'https://matrix.to/#/';
+ static const String deepLinkPrefix = 'im.fluffychat://chat/';
+ static const String schemePrefix = 'matrix:';
// #Pangea
- static const double toolbarMaxHeight = 250.0;
- static const double toolbarMinHeight = 150.0;
- static const double toolbarMinWidth = 350.0;
- static const double toolbarMenuHeight = 50.0;
- static const double defaultHeaderHeight = 56.0;
- static const double toolbarButtonsHeight = 50.0;
- static const double toolbarSpacing = 8.0;
- static const double toolbarIconSize = 24.0;
- static const double readingAssistanceInputBarHeight = 175.0;
- static const double reactionsPickerHeight = 48.0;
- static const double chatInputRowOverlayPadding = 8.0;
- static const double selectModeInputBarHeight = 0;
- // reactionsPickerHeight + (chatInputRowOverlayPadding * 2) + toolbarSpacing;
- static const double practiceModeInputBarHeight =
- readingAssistanceInputBarHeight +
- toolbarButtonsHeight +
- (chatInputRowOverlayPadding * 2) +
- toolbarSpacing;
+ // static const String pushNotificationsChannelId = 'fluffychat_push';
+ // static const String pushNotificationsAppId = 'chat.fluffy.fluffychat';
+ static const String pushNotificationsChannelId = 'pangeachat_push';
+ static const String pushNotificationsAppId = 'com.talktolearn.chat';
+ // Pangea#
+ static const double borderRadius = 18.0;
+ static const double columnWidth = 360.0;
- static TextStyle messageTextStyle(
- Event? event,
- Color textColor,
- ) {
- final fontSize = messageFontSize * fontSizeFactor;
- final bigEmotes = event != null &&
- event.onlyEmotes &&
- event.numberEmotes > 0 &&
- event.numberEmotes <= 3;
-
- return TextStyle(
- color: textColor,
- fontSize: bigEmotes ? fontSize * 5 : fontSize,
- decoration:
- (event?.redacted ?? false) ? TextDecoration.lineThrough : null,
- height: 1.3,
- );
- }
-
- // static const Color primaryColor = Color(0xFF5625BA);
- // static const Color primaryColorLight = Color(0xFFCCBDEA);
- static const Color primaryColor = Color(0xFF8560E0);
- static const Color primaryColorLight = Color(0xFFDBC9FF);
- // static const Color secondaryColor = Color(0xFF41a2bc);
- static const Color secondaryColor = Color.fromARGB(255, 253, 191, 1);
- static const Color activeToggleColor = Color(0xFF33D057);
- static const Color success = Color(0xFF33D057);
- static const Color warning = Color.fromARGB(255, 210, 124, 12);
- static const Color gold = Color.fromARGB(255, 253, 191, 1);
- static const Color silver = Color.fromARGB(255, 192, 192, 192);
- static const Color bronze = Color.fromARGB(255, 205, 127, 50);
- static const Color goldLight = Color.fromARGB(255, 254, 223, 73);
-
- static const Color yellowLight = Color.fromARGB(255, 247, 218, 120);
- static const Color yellowDark = Color.fromARGB(255, 253, 191, 1);
-
- static const Color error = Colors.red;
- static const int overlayAnimationDuration = 250;
- static const int roomCreationTimeoutSeconds = 15;
- // static String _privacyUrl =
- // 'https://gitlab.com/famedly/fluffychat/-/blob/main/PRIVACY.md';
- static String _privacyUrl = "https://www.pangeachat.com/privacy";
- //Pangea#
-
- static const Set defaultReactions = {'👍', '❤️', '😂', '😮', '😢'};
-
- static String get privacyUrl => _privacyUrl;
// #Pangea
// static const String website = 'https://fluffychat.im';
static const String website = "https://pangea.chat/";
@@ -108,9 +52,7 @@ abstract class AppConfig {
// static const String appOpenUrlScheme = 'im.fluffychat';
static const String appOpenUrlScheme = 'matrix.pangea.chat';
// Pangea#
- static String _webBaseUrl = 'https://fluffychat.im/web';
- static String get webBaseUrl => _webBaseUrl;
static const String sourceCodeUrl =
'https://github.com/krille-chan/fluffychat';
// #Pangea
@@ -118,126 +60,81 @@ abstract class AppConfig {
// 'https://github.com/krille-chan/fluffychat/issues';
// static const String changelogUrl =
// 'https://github.com/krille-chan/fluffychat/blob/main/CHANGELOG.md';
+ // static const String donationUrl = 'https://ko-fi.com/krille';
static const String supportUrl = 'https://www.pangeachat.com/faqs';
static const String termsOfServiceUrl =
'https://www.pangeachat.com/terms-of-service';
// Pangea#
+
+ static const Set defaultReactions = {'👍', '❤️', '😂', '😮', '😢'};
+
static final Uri newIssueUrl = Uri(
scheme: 'https',
host: 'github.com',
path: '/krille-chan/fluffychat/issues/new',
);
- // #Pangea
- static const bool enableSentry = true;
- static const String sentryDns =
- 'https://8591d0d863b646feb4f3dda7e5dcab38@o256755.ingest.sentry.io/5243143';
- // Pangea#
- static bool renderHtml = true;
- // #Pangea
- // static bool hideRedactedEvents = false;
- static bool hideRedactedEvents = true;
- // Pangea#
- static bool hideUnknownEvents = true;
- static bool separateChatTypes = false;
- static bool autoplayImages = true;
- static bool sendTypingNotifications = true;
- static bool sendPublicReadReceipts = true;
- static bool swipeRightToLeftToReply = true;
- static bool? sendOnEnter;
- static bool useActivityImageAsChatBackground = true;
- static bool showPresences = true;
- // #Pangea
- // static bool displayNavigationRail = false;
- static bool displayNavigationRail = true;
- // Pangea#
- static bool experimentalVoip = false;
- static const bool hideTypingUsernames = false;
- static const String inviteLinkPrefix = 'https://matrix.to/#/';
- static const String deepLinkPrefix = 'im.fluffychat://chat/';
- static const String schemePrefix = 'matrix:';
- // #Pangea
- // static const String pushNotificationsChannelId = 'fluffychat_push';
- // static const String pushNotificationsAppId = 'chat.fluffy.fluffychat';
- static const String pushNotificationsChannelId = 'pangeachat_push';
- static const String pushNotificationsAppId = 'com.talktolearn.chat';
- // Pangea#
- static const double borderRadius = 18.0;
- static const double columnWidth = 360.0;
+
static final Uri homeserverList = Uri(
scheme: 'https',
host: 'servers.joinmatrix.org',
path: 'servers.json',
);
+
+ static final Uri privacyUrl = Uri(
+ scheme: 'https',
+ host: 'github.com',
+ path: '/krille-chan/fluffychat/blob/main/PRIVACY.md',
+ );
+
// #Pangea
- static String googlePlayMangementUrl =
- "https://play.google.com/store/account/subscriptions";
- static String googlePlayHistoryUrl =
- "https://play.google.com/store/account/orderhistory";
+ static String assetsBaseURL =
+ "https://pangea-chat-client-assets.s3.us-east-1.amazonaws.com";
+ static String androidUpdateURL =
+ "https://play.google.com/store/apps/details?id=com.talktolearn.chat";
+ static String iosUpdateURL = "itms-apps://itunes.apple.com/app/id1445118630";
static String googlePlayPaymentMethodUrl =
"https://play.google.com/store/paymentmethods";
static String appleMangementUrl =
"https://apps.apple.com/account/subscriptions";
- static String stripePerMonth =
- "https://buy.stripe.com/test_bIY6ssd8z5Uz8ec8ww";
- static String iosPromoCode =
- "https://apps.apple.com/redeem?ctx=offercodes&id=1445118630&code=";
- static String androidUpdateURL =
- "https://play.google.com/store/apps/details?id=com.talktolearn.chat";
- static String iosUpdateURL = "itms-apps://itunes.apple.com/app/id1445118630";
-
- static String windowsTTSDownloadInstructions =
- "https://support.microsoft.com/en-us/topic/download-languages-and-voices-for-immersive-reader-read-mode-and-read-aloud-4c83a8d8-7486-42f7-8e46-2b0fdf753130";
- static String androidTTSDownloadInstructions =
- "https://support.google.com/accessibility/android/answer/6006983?hl=en";
- static String assetsBaseURL =
- "https://pangea-chat-client-assets.s3.us-east-1.amazonaws.com";
-
+ static String googlePlayMangementUrl =
+ "https://play.google.com/store/account/subscriptions";
+ static String googlePlayHistoryUrl =
+ "https://play.google.com/store/account/orderhistory";
+ static bool useActivityImageAsChatBackground = true;
+ static const int overlayAnimationDuration = 250;
+ static double volume = 1.0;
+ static const Color gold = Color.fromARGB(255, 253, 191, 1);
+ static const Color goldLight = Color.fromARGB(255, 254, 223, 73);
+ static const Color success = Color(0xFF33D057);
+ static const Color error = Colors.red;
+ static const Color warning = Color.fromARGB(255, 210, 124, 12);
+ static const Color activeToggleColor = Color(0xFF33D057);
+ static const Color yellowLight = Color.fromARGB(255, 247, 218, 120);
+ static const Color yellowDark = Color.fromARGB(255, 253, 191, 1);
+ static const double toolbarMaxHeight = 250.0;
+ static const double toolbarMinWidth = 350.0;
+ static const double toolbarMinHeight = 150.0;
+ static const double toolbarMenuHeight = 50.0;
+ static const double readingAssistanceInputBarHeight = 175.0;
static String errorSubscriptionId = "pangea_subscription_error";
- static double volume = 1.0;
- static bool showedActivityMenu = false;
- // Pangea#
+ static TextStyle messageTextStyle(
+ Event? event,
+ Color textColor,
+ ) {
+ final fontSize = messageFontSize * AppSettings.fontSizeFactor.value;
+ final bigEmotes = event != null &&
+ event.onlyEmotes &&
+ event.numberEmotes > 0 &&
+ event.numberEmotes <= 3;
- static void loadFromJson(Map json) {
- if (json['chat_color'] != null) {
- try {
- colorSchemeSeed = Color(json['chat_color']);
- } catch (e) {
- Logs().w(
- 'Invalid color in config.json! Please make sure to define the color in this format: "0xffdd0000"',
- e,
- );
- }
- }
- if (json['application_name'] is String) {
- _applicationName = json['application_name'];
- }
- if (json['application_welcome_message'] is String) {
- _applicationWelcomeMessage = json['application_welcome_message'];
- }
- // #Pangea
- // if (json['default_homeserver'] is String) {
- // _defaultHomeserver = json['default_homeserver'];
- // }
- // Pangea#
- if (json['privacy_url'] is String) {
- _privacyUrl = json['privacy_url'];
- }
- if (json['web_base_url'] is String) {
- _webBaseUrl = json['web_base_url'];
- }
- if (json['render_html'] is bool) {
- // #Pangea
- // this is interfering with our PangeaRichText functionality, removing it for now
- renderHtml = false;
- // renderHtml = json['render_html'];
- // Pangea#
- }
- if (json['hide_redacted_events'] is bool) {
- hideRedactedEvents = json['hide_redacted_events'];
- }
- if (json['hide_unknown_events'] is bool) {
- hideUnknownEvents = json['hide_unknown_events'];
- }
+ return TextStyle(
+ color: textColor,
+ fontSize: bigEmotes ? fontSize * 5 : fontSize,
+ decoration:
+ (event?.redacted ?? false) ? TextDecoration.lineThrough : null,
+ height: 1.3,
+ );
}
+ // Pangea#
}
diff --git a/lib/config/routes.dart b/lib/config/routes.dart
index 032bf08e5..ed8c53afa 100644
--- a/lib/config/routes.dart
+++ b/lib/config/routes.dart
@@ -260,6 +260,7 @@ abstract class AppRoutes {
// ? TwoColumnLayout(
// mainView: ChatList(
// activeChat: state.pathParameters['roomid'],
+ // activeSpace: state.uri.queryParameters['spaceId'],
// displayNavigationRail:
// state.path?.startsWith('/rooms/settings') != true,
// ),
@@ -292,7 +293,10 @@ abstract class AppRoutes {
// Pangea#
: ChatList(
activeChat: state.pathParameters['roomid'],
- activeSpaceId: state.pathParameters['spaceid'],
+ // #Pangea
+ // activeSpace: state.uri.queryParameters['spaceId'],
+ activeSpace: state.pathParameters['spaceid'],
+ // Pangea#
),
),
routes: [
diff --git a/lib/config/setting_keys.dart b/lib/config/setting_keys.dart
index 9d7f5e756..08f4fefc9 100644
--- a/lib/config/setting_keys.dart
+++ b/lib/config/setting_keys.dart
@@ -1,45 +1,12 @@
+import 'dart:convert';
+
+import 'package:flutter/foundation.dart';
+
+import 'package:http/http.dart' as http;
+import 'package:matrix/matrix_api_lite/utils/logs.dart';
import 'package:shared_preferences/shared_preferences.dart';
-abstract class SettingKeys {
- static const String renderHtml = 'chat.fluffy.renderHtml';
- static const String hideRedactedEvents = 'chat.fluffy.hideRedactedEvents';
- static const String hideUnknownEvents = 'chat.fluffy.hideUnknownEvents';
- static const String hideUnimportantStateEvents =
- 'chat.fluffy.hideUnimportantStateEvents';
- static const String separateChatTypes = 'chat.fluffy.separateChatTypes';
- static const String sentry = 'sentry';
- static const String theme = 'theme';
- static const String amoledEnabled = 'amoled_enabled';
- static const String codeLanguage = 'code_language';
- static const String showNoGoogle = 'chat.fluffy.show_no_google';
- static const String fontSizeFactor = 'chat.fluffy.font_size_factor';
- static const String showNoPid = 'chat.fluffy.show_no_pid';
- static const String databasePassword = 'database-password';
- static const String appLockKey = 'chat.fluffy.app_lock';
- static const String unifiedPushRegistered =
- 'chat.fluffy.unifiedpush.registered';
- static const String unifiedPushEndpoint = 'chat.fluffy.unifiedpush.endpoint';
- static const String ownStatusMessage = 'chat.fluffy.status_msg';
- static const String dontAskForBootstrapKey =
- 'chat.fluffychat.dont_ask_bootstrap';
- static const String autoplayImages = 'chat.fluffy.autoplay_images';
- static const String sendTypingNotifications =
- 'chat.fluffy.send_typing_notifications';
- static const String sendPublicReadReceipts =
- 'chat.fluffy.send_public_read_receipts';
- static const String sendOnEnter = 'chat.fluffy.send_on_enter';
- static const String swipeRightToLeftToReply =
- 'chat.fluffy.swipeRightToLeftToReply';
- static const String experimentalVoip = 'chat.fluffy.experimental_voip';
- static const String showPresences = 'chat.fluffy.show_presences';
- static const String displayNavigationRail =
- 'chat.fluffy.display_navigation_rail';
- // #Pangea
- static const String volume = 'pangea.volume';
- static const String showedActivityMenu =
- 'pangea.showed_activity_menu_tutorial';
- // Pangea#
-}
+import 'package:fluffychat/utils/platform_infos.dart';
enum AppSettings {
textMessageMaxLength('textMessageMaxLength', 16384),
@@ -52,6 +19,9 @@ enum AppSettings {
// audioRecordingSamplingRate('audioRecordingSamplingRate', 44100),
audioRecordingSamplingRate('audioRecordingSamplingRate', 22050),
// Pangea#
+ showNoGoogle('chat.fluffy.show_no_google', false),
+ unifiedPushRegistered('chat.fluffy.unifiedpush.registered', false),
+ unifiedPushEndpoint('chat.fluffy.unifiedpush.endpoint', ''),
pushNotificationsGatewayUrl(
'pushNotificationsGatewayUrl',
// #Pangea
@@ -65,6 +35,19 @@ enum AppSettings {
// 'event_id_only',
// ),
// Pangea#
+ renderHtml('chat.fluffy.renderHtml', true),
+ fontSizeFactor('chat.fluffy.font_size_factor', 1.0),
+ hideRedactedEvents('chat.fluffy.hideRedactedEvents', false),
+ hideUnknownEvents('chat.fluffy.hideUnknownEvents', true),
+ separateChatTypes('chat.fluffy.separateChatTypes', false),
+ autoplayImages('chat.fluffy.autoplay_images', true),
+ sendTypingNotifications('chat.fluffy.send_typing_notifications', true),
+ sendPublicReadReceipts('chat.fluffy.send_public_read_receipts', true),
+ swipeRightToLeftToReply('chat.fluffy.swipeRightToLeftToReply', true),
+ sendOnEnter('chat.fluffy.send_on_enter', false),
+ showPresences('chat.fluffy.show_presences', true),
+ displayNavigationRail('chat.fluffy.display_navigation_rail', false),
+ experimentalVoip('chat.fluffy.experimental_voip', false),
shareKeysWith('chat.fluffy.share_keys_with_2', 'all'),
noEncryptionWarningShown(
'chat.fluffy.no_encryption_warning_shown',
@@ -74,40 +57,95 @@ enum AppSettings {
'chat.fluffy.display_chat_details_column',
false,
),
+ // AppConfig-mirrored settings
+ // #Pangea
+ // applicationName('chat.fluffy.application_name', 'FluffyChat'),
+ // defaultHomeserver('chat.fluffy.default_homeserver', 'matrix.org'),
+ applicationName('chat.fluffy.application_name', 'Pangea Chat'),
+ // Pangea#
+ // colorSchemeSeed stored as ARGB int
+ colorSchemeSeedInt(
+ 'chat.fluffy.color_scheme_seed',
+ // #Pangea
+ // 0xFF5625BA,
+ 0xFF8560E0,
+ // Pangea#
+ ),
+ // #Pangea
+ volume('pangea.value', 1.0),
+ // Pangea#
enableSoftLogout('chat.fluffy.enable_soft_logout', false);
final String key;
final T defaultValue;
const AppSettings(this.key, this.defaultValue);
+
+ static SharedPreferences get store => _store!;
+ static SharedPreferences? _store;
+
+ static Future init({loadWebConfigFile = true}) async {
+ if (AppSettings._store != null) return AppSettings.store;
+
+ final store = AppSettings._store = await SharedPreferences.getInstance();
+
+ if (store.getBool(AppSettings.sendOnEnter.key) == null) {
+ await store.setBool(AppSettings.sendOnEnter.key, !PlatformInfos.isMobile);
+ }
+ if (kIsWeb && loadWebConfigFile) {
+ try {
+ final configJsonString =
+ utf8.decode((await http.get(Uri.parse('config.json'))).bodyBytes);
+ final configJson =
+ json.decode(configJsonString) as Map;
+ for (final setting in AppSettings.values) {
+ if (store.get(setting.key) != null) continue;
+ final configValue = configJson[setting.name];
+ if (configValue == null) continue;
+ if (configValue is bool) {
+ await store.setBool(setting.key, configValue);
+ }
+ if (configValue is String) {
+ await store.setString(setting.key, configValue);
+ }
+ if (configValue is int) {
+ await store.setInt(setting.key, configValue);
+ }
+ if (configValue is double) {
+ await store.setDouble(setting.key, configValue);
+ }
+ }
+ } on FormatException catch (_) {
+ Logs().v('[ConfigLoader] config.json not found');
+ } catch (e) {
+ Logs().v('[ConfigLoader] config.json not found', e);
+ }
+ }
+
+ return store;
+ }
}
extension AppSettingsBoolExtension on AppSettings {
- bool getItem(SharedPreferences store) => store.getBool(key) ?? defaultValue;
+ bool get value => AppSettings.store.getBool(key) ?? defaultValue;
- Future setItem(SharedPreferences store, bool value) =>
- store.setBool(key, value);
+ Future setItem(bool value) => AppSettings.store.setBool(key, value);
}
extension AppSettingsStringExtension on AppSettings {
- String getItem(SharedPreferences store) =>
- store.getString(key) ?? defaultValue;
+ String get value => AppSettings.store.getString(key) ?? defaultValue;
- Future setItem(SharedPreferences store, String value) =>
- store.setString(key, value);
+ Future setItem(String value) => AppSettings.store.setString(key, value);
}
extension AppSettingsIntExtension on AppSettings {
- int getItem(SharedPreferences store) => store.getInt(key) ?? defaultValue;
+ int get value => AppSettings.store.getInt(key) ?? defaultValue;
- Future setItem(SharedPreferences store, int value) =>
- store.setInt(key, value);
+ Future setItem(int value) => AppSettings.store.setInt(key, value);
}
extension AppSettingsDoubleExtension on AppSettings {
- double getItem(SharedPreferences store) =>
- store.getDouble(key) ?? defaultValue;
+ double get value => AppSettings.store.getDouble(key) ?? defaultValue;
- Future setItem(SharedPreferences store, double value) =>
- store.setDouble(key, value);
+ Future setItem(double value) => AppSettings.store.setDouble(key, value);
}
diff --git a/lib/config/themes.dart b/lib/config/themes.dart
index 762f1f073..71247db2b 100644
--- a/lib/config/themes.dart
+++ b/lib/config/themes.dart
@@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'app_config.dart';
abstract class FluffyThemes {
@@ -49,11 +50,7 @@ abstract class FluffyThemes {
]) {
final colorScheme = ColorScheme.fromSeed(
brightness: brightness,
- seedColor: seed ??
- AppConfig.colorSchemeSeed ??
- Theme.of(context).colorScheme.primary,
- // primary: AppConfig.primaryColor,
- // secondary: AppConfig.gold,
+ seedColor: seed ?? Color(AppSettings.colorSchemeSeedInt.value),
);
final isColumnMode = FluffyThemes.isColumnMode(context);
return ThemeData(
diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb
index 2cc4e5ba1..d9340409b 100644
--- a/lib/l10n/intl_en.arb
+++ b/lib/l10n/intl_en.arb
@@ -3379,6 +3379,39 @@
"longPressToRecordVoiceMessage": "Long press to record voice message.",
"pause": "Pause",
"resume": "Resume",
+ "newSubSpace": "New sub space",
+ "moveToDifferentSpace": "Move to different space",
+ "moveUp": "Move up",
+ "moveDown": "Move down",
+ "removeFromSpaceDescription": "The chat will be removed from the space but still appear in your chat list.",
+ "countChats": "{chats} chats",
+ "@countChats": {
+ "type": "String",
+ "placeholders": {
+ "chats": {
+ "type": "int"
+ }
+ }
+ },
+ "spaceMemberOf": "Space member of {spaces}",
+ "@spaceMemberOf": {
+ "type": "String",
+ "placeholders": {
+ "spaces": {
+ "type": "String"
+ }
+ }
+ },
+ "spaceMemberOfCanKnock": "Space member of {spaces} can knock",
+ "@spaceMemberOfCanKnock": {
+ "type": "String",
+ "placeholders": {
+ "spaces": {
+ "type": "String"
+ }
+ }
+ },
+ "donate": "Donate",
"ignore": "Block",
"ignoredUsers": "Blocked users",
"writeAMessageLangCodes": "Type in {l1} or {l2}...",
@@ -3947,6 +3980,9 @@
"grammarCopyPOSpropn": "Proper Noun",
"grammarCopyPOSnoun": "Noun",
"grammarCopyPOSintj": "Interjection",
+ "grammarCopyPOSidiom": "Idiom",
+ "grammarCopyPOSphrasalv": "Phrasal Verb",
+ "grammarCopyPOScompn": "Compound",
"grammarCopyPOSx": "Other",
"grammarCopyGENDERfem": "Feminine",
"grammarCopyPERSON2": "Second Person",
diff --git a/lib/main.dart b/lib/main.dart
index ac55d22a4..58b72f4d3 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -9,7 +9,6 @@ import 'package:matrix/matrix.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
-import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pangea/common/config/environment.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/common/utils/firebase_analytics.dart';
@@ -22,8 +21,6 @@ import 'utils/background_push.dart';
import 'widgets/fluffy_chat_app.dart';
void main() async {
- Logs().i('Welcome to ${AppConfig.applicationName} <3');
-
// #Pangea
try {
await dotenv.load(fileName: ".env");
@@ -55,12 +52,14 @@ void main() async {
// widget bindings are initialized already.
WidgetsFlutterBinding.ensureInitialized();
+ final store = await AppSettings.init();
+ Logs().i('Welcome to ${AppSettings.applicationName.value} <3');
+
// #Pangea
// await vod.init(wasmPath: './assets/assets/vodozemac/');
// Pangea#
Logs().nativeColors = !PlatformInfos.isIOS;
- final store = await SharedPreferences.getInstance();
final clients = await ClientManager.getClients(store: store);
// If the app starts in detached mode, we assume that it is in
@@ -80,14 +79,14 @@ void main() async {
// To start the flutter engine afterwards we add an custom observer.
WidgetsBinding.instance.addObserver(AppStarter(clients, store));
Logs().i(
- '${AppConfig.applicationName} started in background-fetch mode. No GUI will be created unless the app is no longer detached.',
+ '${AppSettings.applicationName.value} started in background-fetch mode. No GUI will be created unless the app is no longer detached.',
);
return;
}
// Started in foreground mode.
Logs().i(
- '${AppConfig.applicationName} started in foreground mode. Rendering GUI...',
+ '${AppSettings.applicationName.value} started in foreground mode. Rendering GUI...',
);
await startGui(clients, store);
}
@@ -99,7 +98,7 @@ Future startGui(List clients, SharedPreferences store) async {
if (PlatformInfos.isMobile) {
try {
pin =
- await const FlutterSecureStorage().read(key: SettingKeys.appLockKey);
+ await const FlutterSecureStorage().read(key: 'chat.fluffy.app_lock');
} catch (e, s) {
Logs().d('Unable to read PIN from Secure storage', e, s);
}
@@ -152,7 +151,7 @@ class AppStarter with WidgetsBindingObserver {
if (state == AppLifecycleState.detached) return;
Logs().i(
- '${AppConfig.applicationName} switches from the detached background-fetch mode to ${state.name} mode. Rendering GUI...',
+ '${AppSettings.applicationName.value} switches from the detached background-fetch mode to ${state.name} mode. Rendering GUI...',
);
// Switching to foreground mode needs to reenable send online sync presence.
for (final client in clients) {
diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart
index 298df8b0d..69e97a59a 100644
--- a/lib/pages/chat/chat.dart
+++ b/lib/pages/chat/chat.dart
@@ -15,10 +15,8 @@ import 'package:matrix/matrix.dart';
import 'package:path_provider/path_provider.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
-import 'package:shared_preferences/shared_preferences.dart';
import 'package:universal_html/html.dart' as html;
-import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
@@ -341,7 +339,7 @@ class ChatController extends State
}
void _loadDraft() async {
- final prefs = await SharedPreferences.getInstance();
+ final prefs = Matrix.of(context).store;
final draft = prefs.getString('draft_$roomId');
if (draft != null && draft.isNotEmpty) {
// #Pangea
@@ -394,7 +392,7 @@ class ChatController extends State
KeyEventResult _customEnterKeyHandling(FocusNode node, KeyEvent evt) {
if (!HardwareKeyboard.instance.isShiftPressed &&
evt.logicalKey.keyLabel == 'Enter' &&
- (AppConfig.sendOnEnter ?? !PlatformInfos.isMobile)) {
+ AppSettings.sendOnEnter.value) {
if (evt is KeyDownEvent) {
// #Pangea
// send();
@@ -450,7 +448,7 @@ class ChatController extends State
WidgetsBinding.instance.addPostFrameCallback(_shareItems);
super.initState();
_displayChatDetailsColumn = ValueNotifier(
- AppSettings.displayChatDetailsColumn.getItem(Matrix.of(context).store),
+ AppSettings.displayChatDetailsColumn.value,
);
sendingClient = Matrix.of(context).client;
@@ -588,7 +586,9 @@ class ChatController extends State
var readMarkerEventIndex = readMarkerEventId.isEmpty
? -1
: timeline!.events
- .filterByVisibleInGui(exceptionEventId: readMarkerEventId)
+ .filterByVisibleInGui(
+ exceptionEventId: readMarkerEventId,
+ )
.indexWhere((e) => e.eventId == readMarkerEventId);
// Read marker is existing but not found in first events. Try a single
@@ -596,7 +596,9 @@ class ChatController extends State
if (readMarkerEventId.isNotEmpty && readMarkerEventIndex == -1) {
await timeline?.requestHistory(historyCount: _loadHistoryCount);
readMarkerEventIndex = timeline!.events
- .filterByVisibleInGui(exceptionEventId: readMarkerEventId)
+ .filterByVisibleInGui(
+ exceptionEventId: readMarkerEventId,
+ )
.indexWhere((e) => e.eventId == readMarkerEventId);
}
@@ -772,7 +774,7 @@ class ChatController extends State
_setReadMarkerFuture = timeline
.setReadMarker(
eventId: eventId,
- public: AppConfig.sendPublicReadReceipts,
+ public: AppSettings.sendPublicReadReceipts.value,
)
.then((_) {
_setReadMarkerFuture = null;
@@ -938,7 +940,7 @@ class ChatController extends State
// if (sendController.text.trim().isEmpty) return;
// Pangea#
_storeInputTimeoutTimer?.cancel();
- final prefs = await SharedPreferences.getInstance();
+ final prefs = Matrix.of(context).store;
prefs.remove('draft_$roomId');
var parseCommands = true;
@@ -1564,7 +1566,9 @@ class ChatController extends State
final eventIndex = foundEvent == null
? -1
: timeline!.events
- .filterByVisibleInGui(exceptionEventId: eventId)
+ .filterByVisibleInGui(
+ exceptionEventId: eventId,
+ )
.indexOf(foundEvent);
if (eventIndex == -1) {
@@ -1884,7 +1888,7 @@ class ChatController extends State
_storeInputTimeoutTimer?.cancel();
_storeInputTimeoutTimer = Timer(_storeInputTimeout, () async {
- final prefs = await SharedPreferences.getInstance();
+ final prefs = Matrix.of(context).store;
await prefs.setString('draft_$roomId', text);
});
// #Pangea
@@ -1903,7 +1907,7 @@ class ChatController extends State
// }
// }
// Pangea#
- if (AppConfig.sendTypingNotifications) {
+ if (AppSettings.sendTypingNotifications.value) {
typingCoolDown?.cancel();
typingCoolDown = Timer(const Duration(seconds: 2), () {
typingCoolDown = null;
@@ -2392,12 +2396,8 @@ class ChatController extends State
inputFocus.unfocus();
activityController.toggleShowDropdown();
- if (!AppConfig.showedActivityMenu) {
- AppConfig.showedActivityMenu = true;
- Matrix.of(context).store.setBool(
- SettingKeys.showedActivityMenu,
- AppConfig.showedActivityMenu,
- );
+ if (!InstructionsEnum.showedActivityMenu.isToggledOff) {
+ InstructionsEnum.showedActivityMenu.setToggledOff(true);
}
}
@@ -2462,7 +2462,6 @@ class ChatController extends State
void toggleDisplayChatDetailsColumn() async {
await AppSettings.displayChatDetailsColumn.setItem(
- Matrix.of(context).store,
!_displayChatDetailsColumn.value,
);
_displayChatDetailsColumn.value = !_displayChatDetailsColumn.value;
diff --git a/lib/pages/chat/chat_input_row.dart b/lib/pages/chat/chat_input_row.dart
index 8bdef7d09..dc375f0cb 100644
--- a/lib/pages/chat/chat_input_row.dart
+++ b/lib/pages/chat/chat_input_row.dart
@@ -1,5 +1,9 @@
+// import 'package:flutter/material.dart';
+
// import 'package:animations/animations.dart';
-// import 'package:fluffychat/config/app_config.dart';
+// import 'package:matrix/matrix.dart';
+
+// import 'package:fluffychat/config/setting_keys.dart';
// import 'package:fluffychat/l10n/l10n.dart';
// import 'package:fluffychat/pages/chat/recording_input_row.dart';
// import 'package:fluffychat/pages/chat/recording_view_model.dart';
@@ -7,9 +11,6 @@
// import 'package:fluffychat/utils/platform_infos.dart';
// import 'package:fluffychat/widgets/avatar.dart';
// import 'package:fluffychat/widgets/matrix.dart';
-// import 'package:flutter/material.dart';
-// import 'package:matrix/matrix.dart';
-
// import '../../config/themes.dart';
// import 'chat.dart';
// import 'input_bar.dart';
@@ -296,10 +297,11 @@
// maxLines: 8,
// autofocus: !PlatformInfos.isMobile,
// keyboardType: TextInputType.multiline,
-// textInputAction: AppConfig.sendOnEnter == true &&
-// PlatformInfos.isMobile
-// ? TextInputAction.send
-// : null,
+// textInputAction:
+// AppSettings.sendOnEnter.value == true &&
+// PlatformInfos.isMobile
+// ? TextInputAction.send
+// : null,
// onSubmitted: controller.onInputBarSubmitted,
// onSubmitImage: controller.sendImageFromClipBoard,
// focusNode: controller.inputFocus,
diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart
index 7d4311624..5ea673739 100644
--- a/lib/pages/chat/chat_view.dart
+++ b/lib/pages/chat/chat_view.dart
@@ -130,7 +130,7 @@ class ChatView extends StatelessWidget {
// ];
// } else if (!controller.room.isArchived) {
// return [
- // if (AppConfig.experimentalVoip &&
+ // if (AppSettings.experimentalVoip.value &&
// Matrix.of(context).voipPlugin != null &&
// controller.room.isDirectChat)
// IconButton(
diff --git a/lib/pages/chat/encryption_button.dart b/lib/pages/chat/encryption_button.dart
index 3bc556b4a..a18e10609 100644
--- a/lib/pages/chat/encryption_button.dart
+++ b/lib/pages/chat/encryption_button.dart
@@ -21,6 +21,7 @@ class EncryptionButton extends StatelessWidget {
.stream
.where((s) => s.deviceLists != null),
builder: (context, snapshot) {
+ final shouldBeEncrypted = room.joinRules != JoinRules.public;
return FutureBuilder(
future: room.encrypted
? room.calcEncryptionHealthState()
@@ -46,9 +47,13 @@ class EncryptionButton extends StatelessWidget {
),
),
child: Icon(
- room.encrypted ? Icons.lock_outlined : Icons.lock_open_outlined,
+ room.encrypted
+ ? Icons.lock_outlined
+ : Icons.no_encryption_outlined,
size: 20,
- color: theme.colorScheme.onSurface,
+ color: (shouldBeEncrypted && !room.encrypted)
+ ? theme.colorScheme.error
+ : theme.colorScheme.onSurface,
),
),
onPressed: () => context.go('/rooms/${room.id}/encryption'),
diff --git a/lib/pages/chat/events/cute_events.dart b/lib/pages/chat/events/cute_events.dart
index bb675e641..9d43021dc 100644
--- a/lib/pages/chat/events/cute_events.dart
+++ b/lib/pages/chat/events/cute_events.dart
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
-import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
class CuteContent extends StatefulWidget {
@@ -21,7 +21,7 @@ class _CuteContentState extends State {
@override
void initState() {
- if (AppConfig.autoplayImages && !_isOverlayShown) {
+ if (AppSettings.autoplayImages.value && !_isOverlayShown) {
addOverlay();
}
super.initState();
diff --git a/lib/pages/chat/events/image_bubble.dart b/lib/pages/chat/events/image_bubble.dart
index f056366b1..e93cb9f54 100644
--- a/lib/pages/chat/events/image_bubble.dart
+++ b/lib/pages/chat/events/image_bubble.dart
@@ -5,6 +5,7 @@ import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/pages/image_viewer/image_viewer.dart';
import 'package:fluffychat/utils/file_description.dart';
import 'package:fluffychat/utils/url_launcher.dart';
@@ -162,14 +163,14 @@ class ImageBubble extends StatelessWidget {
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
style: TextStyle(
color: textColor,
- fontSize:
- AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
),
options: const LinkifyOptions(humanize: false),
linkStyle: TextStyle(
color: linkColor,
- fontSize:
- AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
decoration: TextDecoration.underline,
decorationColor: linkColor,
),
diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart
index ff7a0f942..0f240f108 100644
--- a/lib/pages/chat/events/message.dart
+++ b/lib/pages/chat/events/message.dart
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:swipe_to_action/swipe_to_action.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
@@ -308,7 +309,7 @@ class Message extends StatelessWidget {
child: Icon(Icons.check_outlined),
),
),
- direction: AppConfig.swipeRightToLeftToReply
+ direction: AppSettings.swipeRightToLeftToReply.value
? SwipeDirection.endToStart
: SwipeDirection.startToEnd,
onSwipe: (_) => onSwipe(),
@@ -350,7 +351,7 @@ class Message extends StatelessWidget {
child: Text(
event.originServerTs.localizedTime(context),
style: TextStyle(
- fontSize: 12 * AppConfig.fontSizeFactor,
+ fontSize: 12 * AppSettings.fontSizeFactor.value,
fontWeight: FontWeight.bold,
color: theme.colorScheme.secondary,
),
@@ -1137,7 +1138,7 @@ class Message extends StatelessWidget {
child: Text(
L10n.of(context).readUpToHere,
style: TextStyle(
- fontSize: 12 * AppConfig.fontSizeFactor,
+ fontSize: 12 * AppSettings.fontSizeFactor.value,
),
),
),
diff --git a/lib/pages/chat/events/message_content.dart b/lib/pages/chat/events/message_content.dart
index bcd3debff..d8d0eb6df 100644
--- a/lib/pages/chat/events/message_content.dart
+++ b/lib/pages/chat/events/message_content.dart
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pages/chat/events/video_player.dart';
@@ -146,7 +147,8 @@ class MessageContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
- final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
+ final fontSize =
+ AppConfig.messageFontSize * AppSettings.fontSizeFactor.value;
final buttonTextColor = textColor;
switch (event.type) {
case EventTypes.Message:
@@ -306,7 +308,7 @@ class MessageContent extends StatelessWidget {
},
);
}
- var html = AppConfig.renderHtml && event.isRichMessage
+ var html = AppSettings.renderHtml.value && event.isRichMessage
? event.formattedText
: event.body;
if (event.messageType == MessageTypes.Emote) {
@@ -325,14 +327,14 @@ class MessageContent extends StatelessWidget {
html: html,
textColor: textColor,
room: event.room,
- fontSize: AppConfig.fontSizeFactor *
+ fontSize: AppSettings.fontSizeFactor.value *
AppConfig.messageFontSize *
(bigEmotes ? 5 : 1),
limitHeight: !selected,
linkStyle: TextStyle(
color: linkColor,
- fontSize:
- AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
decoration: TextDecoration.underline,
decorationColor: linkColor,
),
diff --git a/lib/pages/chat/events/message_download_content.dart b/lib/pages/chat/events/message_download_content.dart
index f1b517d14..18b5c0b07 100644
--- a/lib/pages/chat/events/message_download_content.dart
+++ b/lib/pages/chat/events/message_download_content.dart
@@ -4,6 +4,7 @@ import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/file_description.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
import 'package:fluffychat/utils/url_launcher.dart';
@@ -92,12 +93,14 @@ class MessageDownloadContent extends StatelessWidget {
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
style: TextStyle(
color: textColor,
- fontSize: AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
),
options: const LinkifyOptions(humanize: false),
linkStyle: TextStyle(
color: linkColor,
- fontSize: AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
decoration: TextDecoration.underline,
decorationColor: linkColor,
),
diff --git a/lib/pages/chat/events/reply_content.dart b/lib/pages/chat/events/reply_content.dart
index 859d59243..e3c7f9484 100644
--- a/lib/pages/chat/events/reply_content.dart
+++ b/lib/pages/chat/events/reply_content.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import '../../../config/app_config.dart';
@@ -30,7 +31,8 @@ class ReplyContent extends StatelessWidget {
final timeline = this.timeline;
final displayEvent =
timeline != null ? replyEvent.getDisplayEvent(timeline) : replyEvent;
- final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
+ final fontSize =
+ AppConfig.messageFontSize * AppSettings.fontSizeFactor.value;
final color = theme.brightness == Brightness.dark
// Pangea#
? ownMessage
diff --git a/lib/pages/chat/events/state_message.dart b/lib/pages/chat/events/state_message.dart
index b1d0dec8a..eaebc828e 100644
--- a/lib/pages/chat/events/state_message.dart
+++ b/lib/pages/chat/events/state_message.dart
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
@@ -79,7 +80,7 @@ class StateMessage extends StatelessWidget {
),
textAlign: TextAlign.center,
style: TextStyle(
- fontSize: 12 * AppConfig.fontSizeFactor,
+ fontSize: 12 * AppSettings.fontSizeFactor.value,
decoration: event.redacted
? TextDecoration.lineThrough
: null,
diff --git a/lib/pages/chat/events/video_player.dart b/lib/pages/chat/events/video_player.dart
index 1940abc33..d78230b1f 100644
--- a/lib/pages/chat/events/video_player.dart
+++ b/lib/pages/chat/events/video_player.dart
@@ -6,6 +6,7 @@ import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/file_description.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
import 'package:fluffychat/utils/platform_infos.dart';
@@ -148,14 +149,14 @@ class EventVideoPlayer extends StatelessWidget {
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
style: TextStyle(
color: textColor,
- fontSize:
- AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
),
options: const LinkifyOptions(humanize: false),
linkStyle: TextStyle(
color: linkColor,
- fontSize:
- AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
decoration: TextDecoration.underline,
decorationColor: linkColor,
),
diff --git a/lib/pages/chat/recording_view_model.dart b/lib/pages/chat/recording_view_model.dart
index c65e81246..53ce6b993 100644
--- a/lib/pages/chat/recording_view_model.dart
+++ b/lib/pages/chat/recording_view_model.dart
@@ -15,7 +15,6 @@ import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
-import 'package:fluffychat/widgets/matrix.dart';
import 'events/audio_player.dart';
// #Pangea
@@ -72,8 +71,6 @@ class RecordingViewModelState extends State {
}
if (await AudioRecorder().hasPermission() == false) return;
- final store = Matrix.of(context).store;
-
final audioRecorder = _audioRecorder ??= AudioRecorder();
setState(() {});
@@ -109,12 +106,12 @@ class RecordingViewModelState extends State {
await audioRecorder.start(
RecordConfig(
- bitRate: AppSettings.audioRecordingBitRate.getItem(store),
- sampleRate: AppSettings.audioRecordingSamplingRate.getItem(store),
- numChannels: AppSettings.audioRecordingNumChannels.getItem(store),
- autoGain: AppSettings.audioRecordingAutoGain.getItem(store),
- echoCancel: AppSettings.audioRecordingEchoCancel.getItem(store),
- noiseSuppress: AppSettings.audioRecordingNoiseSuppress.getItem(store),
+ bitRate: AppSettings.audioRecordingBitRate.value,
+ sampleRate: AppSettings.audioRecordingSamplingRate.value,
+ numChannels: AppSettings.audioRecordingNumChannels.value,
+ autoGain: AppSettings.audioRecordingAutoGain.value,
+ echoCancel: AppSettings.audioRecordingEchoCancel.value,
+ noiseSuppress: AppSettings.audioRecordingNoiseSuppress.value,
encoder: codec,
),
path: path ?? '',
diff --git a/lib/pages/chat_access_settings/chat_access_settings_controller.dart b/lib/pages/chat_access_settings/chat_access_settings_controller.dart
index 9c3a48b86..0c170a1bf 100644
--- a/lib/pages/chat_access_settings/chat_access_settings_controller.dart
+++ b/lib/pages/chat_access_settings/chat_access_settings_controller.dart
@@ -27,6 +27,16 @@ class ChatAccessSettingsController extends State {
bool historyVisibilityLoading = false;
bool guestAccessLoading = false;
Room get room => Matrix.of(context).client.getRoomById(widget.roomId)!;
+ Set get knownSpaceParents => {
+ ...room.client.rooms.where(
+ (space) =>
+ space.isSpace &&
+ space.spaceChildren.any((child) => child.roomId == room.id),
+ ),
+ ...room.spaceParents
+ .map((parent) => room.client.getRoomById(parent.roomId ?? ''))
+ .whereType(),
+ };
String get roomVersion =>
room
@@ -45,11 +55,13 @@ class ChatAccessSettingsController extends State {
// Knock is only supported for rooms up from version 7:
if (roomVersionInt != null && roomVersionInt <= 6) {
joinRules.remove(JoinRules.knock);
+ joinRules.remove(JoinRules.knockRestricted);
}
- // Not yet supported in FluffyChat:
- joinRules.remove(JoinRules.restricted);
- joinRules.remove(JoinRules.knockRestricted);
+ if (knownSpaceParents.isEmpty) {
+ joinRules.remove(JoinRules.restricted);
+ joinRules.remove(JoinRules.knockRestricted);
+ }
// If an unsupported join rule is the current join rule, display it:
final currentJoinRule = room.joinRules;
@@ -69,7 +81,13 @@ class ChatAccessSettingsController extends State {
try {
// #Pangea
- // await room.setJoinRules(newJoinRules);
+ // await room.setJoinRules(
+ // newJoinRules,
+ // allowConditionRoomId: {JoinRules.restricted, JoinRules.knockRestricted}
+ // .contains(newJoinRules)
+ // ? knownSpaceParents.first.id
+ // : null,
+ // );
await room.pangeaSetJoinRules(
newJoinRules.toString().replaceAll('JoinRules.', ''),
);
diff --git a/lib/pages/chat_access_settings/chat_access_settings_page.dart b/lib/pages/chat_access_settings/chat_access_settings_page.dart
index 5f679cffb..616d13934 100644
--- a/lib/pages/chat_access_settings/chat_access_settings_page.dart
+++ b/lib/pages/chat_access_settings/chat_access_settings_page.dart
@@ -88,7 +88,10 @@ class ChatAccessSettingsPageView extends StatelessWidget {
enabled: !controller.joinRulesLoading &&
room.canChangeJoinRules,
title: Text(
- joinRule.localizedString(L10n.of(context)),
+ joinRule.localizedString(
+ L10n.of(context),
+ controller.knownSpaceParents,
+ ),
),
value: joinRule,
),
@@ -280,7 +283,7 @@ class _AliasListTile extends StatelessWidget {
}
extension JoinRulesDisplayString on JoinRules {
- String localizedString(L10n l10n) {
+ String localizedString(L10n l10n, Set spaceParents) {
switch (this) {
case JoinRules.public:
return l10n.anyoneCanJoin;
@@ -291,9 +294,17 @@ extension JoinRulesDisplayString on JoinRules {
case JoinRules.private:
return l10n.noOneCanJoin;
case JoinRules.restricted:
- return l10n.restricted;
+ return l10n.spaceMemberOf(
+ spaceParents
+ .map((space) => space.getLocalizedDisplayname(MatrixLocals(l10n)))
+ .join(', '),
+ );
case JoinRules.knockRestricted:
- return l10n.knockRestricted;
+ return l10n.spaceMemberOfCanKnock(
+ spaceParents
+ .map((space) => space.getLocalizedDisplayname(MatrixLocals(l10n)))
+ .join(', '),
+ );
}
}
}
diff --git a/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart b/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart
index f6adffd58..754178c25 100644
--- a/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart
+++ b/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart
@@ -9,6 +9,7 @@ import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_encryption_settings/chat_encryption_settings.dart';
import 'package:fluffychat/utils/beautify_string_extension.dart';
+import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
class ChatEncryptionSettingsView extends StatelessWidget {
@@ -58,7 +59,6 @@ class ChatEncryptionSettingsView extends StatelessWidget {
size: 128,
color: theme.colorScheme.onInverseSurface,
),
- const Divider(),
if (room.isDirectChat)
Padding(
padding: const EdgeInsets.all(16.0),
@@ -107,72 +107,73 @@ class ChatEncryptionSettingsView extends StatelessWidget {
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: deviceKeys.length,
- itemBuilder: (BuildContext context, int i) =>
- SwitchListTile(
- value: !deviceKeys[i].blocked,
- activeThumbColor: deviceKeys[i].verified
- ? Colors.green
- : Colors.orange,
- onChanged: (_) =>
- controller.toggleDeviceKey(deviceKeys[i]),
- title: Row(
- children: [
- Icon(
- deviceKeys[i].verified
- ? Icons.verified_outlined
- : deviceKeys[i].blocked
- ? Icons.block_outlined
- : Icons.info_outlined,
- color: deviceKeys[i].verified
- ? Colors.green
- : deviceKeys[i].blocked
- ? Colors.red
- : Colors.orange,
- size: 20,
- ),
- const SizedBox(width: 4),
- Text(
- deviceKeys[i].deviceId ??
- L10n.of(context).unknownDevice,
- ),
- const SizedBox(width: 4),
- Flexible(
- fit: FlexFit.loose,
- child: Material(
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(
- AppConfig.borderRadius,
+ itemBuilder: (BuildContext context, int i) => Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ if (i == 0 ||
+ deviceKeys[i].userId !=
+ deviceKeys[i - 1].userId) ...[
+ const Divider(),
+ FutureBuilder(
+ future: room.client
+ .getUserProfile(deviceKeys[i].userId),
+ builder: (context, snapshot) {
+ final displayname =
+ snapshot.data?.displayname ??
+ deviceKeys[i].userId.localpart ??
+ deviceKeys[i].userId;
+ return ListTile(
+ leading: Avatar(
+ name: displayname,
+ mxContent: snapshot.data?.avatarUrl,
),
- side: BorderSide(
- color: theme.colorScheme.primary,
- ),
- ),
- color: theme.colorScheme.primaryContainer,
- child: Padding(
- padding: const EdgeInsets.all(4.0),
- child: Text(
- deviceKeys[i].userId,
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- style: TextStyle(
- color: theme.colorScheme.primary,
- fontSize: 12,
- fontStyle: FontStyle.italic,
- ),
- ),
- ),
- ),
+ title: Text(displayname),
+ subtitle: Text(deviceKeys[i].userId),
+ );
+ },
),
],
- ),
- subtitle: Text(
- deviceKeys[i].ed25519Key?.beautified ??
- L10n.of(context).unknownEncryptionAlgorithm,
- style: TextStyle(
- fontFamily: 'RobotoMono',
- color: theme.colorScheme.secondary,
+ SwitchListTile(
+ value: !deviceKeys[i].blocked,
+ activeThumbColor: deviceKeys[i].verified
+ ? Colors.green
+ : Colors.orange,
+ onChanged: (_) =>
+ controller.toggleDeviceKey(deviceKeys[i]),
+ title: Row(
+ children: [
+ Text(
+ deviceKeys[i].verified
+ ? L10n.of(context).verified
+ : deviceKeys[i].blocked
+ ? L10n.of(context).blocked
+ : L10n.of(context).unverified,
+ style: TextStyle(
+ color: deviceKeys[i].verified
+ ? Colors.green
+ : deviceKeys[i].blocked
+ ? Colors.red
+ : Colors.orange,
+ ),
+ ),
+ const Text(' | ID: '),
+ Text(
+ deviceKeys[i].deviceId ??
+ L10n.of(context).unknownDevice,
+ ),
+ ],
+ ),
+ subtitle: Text(
+ deviceKeys[i].ed25519Key?.beautified ??
+ L10n.of(context).unknownEncryptionAlgorithm,
+ style: TextStyle(
+ fontFamily: 'RobotoMono',
+ color: theme.colorScheme.secondary,
+ fontSize: 11,
+ ),
+ ),
),
- ),
+ ],
),
);
},
diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart
index f7c9e16d4..1da716a2d 100644
--- a/lib/pages/chat_list/chat_list.dart
+++ b/lib/pages/chat_list/chat_list.dart
@@ -11,7 +11,6 @@ import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
-import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_list/chat_list_view.dart';
import 'package:fluffychat/pangea/chat_list/utils/app_version_util.dart';
@@ -83,17 +82,13 @@ extension LocalizedActiveFilter on ActiveFilter {
class ChatList extends StatefulWidget {
static BuildContext? contextForVoip;
final String? activeChat;
- // #Pangea
- final String? activeSpaceId;
- // Pangea#
+ final String? activeSpace;
final bool displayNavigationRail;
const ChatList({
super.key,
required this.activeChat,
- // #Pangea
- this.activeSpaceId,
- // Pangea#
+ this.activeSpace,
this.displayNavigationRail = false,
});
@@ -111,15 +106,10 @@ class ChatListController extends State
// StreamSubscription? _intentUriStreamSubscription;
// Pangea#
- // #Pangea
- // ActiveFilter activeFilter = AppConfig.separateChatTypes
- // ? ActiveFilter.messages
- // : ActiveFilter.allChats;
- ActiveFilter activeFilter = ActiveFilter.allChats;
- // Pangea#
+ late ActiveFilter activeFilter;
// #Pangea
- String? get activeSpaceId => widget.activeSpaceId;
+ String? get activeSpaceId => widget.activeSpace;
// String? _activeSpaceId;
// String? get activeSpaceId => _activeSpaceId;
@@ -535,7 +525,16 @@ class ChatListController extends State
@override
void initState() {
+ // #Pangea
+ // activeFilter = AppSettings.separateChatTypes.value
+ // ? ActiveFilter.messages
+ // : ActiveFilter.allChats;
+ activeFilter = ActiveFilter.allChats;
+ // Pangea#
_initReceiveSharingIntent();
+ // #Pangea
+ // _activeSpaceId = widget.activeSpace;
+ // Pangea#
scrollController.addListener(_onScroll);
_waitForFirstSync();
@@ -993,8 +992,7 @@ class ChatListController extends State
context: context,
);
if (result == OkCancelResult.ok) {
- await Matrix.of(context).store.setBool(SettingKeys.showPresences, false);
- AppConfig.showPresences = false;
+ AppSettings.showPresences.setItem(false);
setState(() {});
}
}
diff --git a/lib/pages/chat_list/chat_list_body.dart b/lib/pages/chat_list/chat_list_body.dart
index 705197545..cee769511 100644
--- a/lib/pages/chat_list/chat_list_body.dart
+++ b/lib/pages/chat_list/chat_list_body.dart
@@ -42,10 +42,7 @@ class ChatListViewBody extends StatelessWidget {
// spaceId: activeSpace,
// onBack: controller.clearActiveSpace,
// onChatTab: (room) => controller.onChatTap(room),
- // onChatContext: (room, context) =>
- // controller.chatContextAction(room, context),
// activeChat: controller.activeChat,
- // toParentSpace: controller.setActiveSpace,
// );
return CourseChats(
activeSpace,
@@ -108,8 +105,8 @@ class ChatListViewBody extends StatelessWidget {
// ),
// PublicRoomsHorizontalList(publicRooms: publicRooms),
// SearchTitle(
- // title: L10n.of(context).publicSpaces,
- // icon: const Icon(Icons.workspaces_outlined),
+ // title: L10n.of(context).publicSpaces,
+ // icon: const Icon(Icons.workspaces_outlined),
// ),
// PublicRoomsHorizontalList(publicRooms: publicSpaces),
// SearchTitle(
@@ -127,27 +124,28 @@ class ChatListViewBody extends StatelessWidget {
// curve: FluffyThemes.animationCurve,
// child: userSearchResult == null
// ? null
- // : ListView.builder(
- // scrollDirection: Axis.horizontal,
- // itemCount: userSearchResult.results.length,
- // itemBuilder: (context, i) => _SearchItem(
- // title:
- // userSearchResult.results[i].displayName ??
- // userSearchResult
- // .results[i].userId.localpart ??
- // L10n.of(context).unknownDevice,
- // avatar: userSearchResult.results[i].avatarUrl,
- // onPressed: () => UserDialog.show(
- // context: context,
- // profile: userSearchResult.results[i],
- // ),
- // ),
- // ),
- // ),
- // Pangea#
+ // : ListView.builder(
+ // scrollDirection: Axis.horizontal,
+ // itemCount: userSearchResult.results.length,
+ // itemBuilder: (context, i) => _SearchItem(
+ // title:
+ // userSearchResult.results[i].displayName ??
+ // userSearchResult
+ // .results[i].userId.localpart ??
+ // L10n.of(context).unknownDevice,
+ // avatar: userSearchResult.results[i].avatarUrl,
+ // onPressed: () => UserDialog.show(
+ // context: context,
+ // profile: userSearchResult.results[i],
+ // ),
+ // ),
+ // ),
+ // ),
+ // Pangea#
],
// #Pangea
- // if (!controller.isSearchMode && AppConfig.showPresences)
+ // if (!controller.isSearchMode &&
+ // AppSettings.showPresences.value)
// GestureDetector(
// onLongPress: () => controller.dismissStatusList(),
// child: StatusMessageList(
@@ -184,14 +182,14 @@ class ChatListViewBody extends StatelessWidget {
// shrinkWrap: true,
// scrollDirection: Axis.horizontal,
// children: [
- // if (AppConfig.separateChatTypes)
+ // if (AppSettings.separateChatTypes.value)
// ActiveFilter.messages
// else
// ActiveFilter.allChats,
// ActiveFilter.groups,
// ActiveFilter.unread,
// if (spaceDelegateCandidates.isNotEmpty &&
- // !AppConfig.displayNavigationRail &&
+ // !AppSettings.displayNavigationRail.value &&
// !FluffyThemes.isColumnMode(context))
// ActiveFilter.spaces,
// ]
@@ -217,24 +215,6 @@ class ChatListViewBody extends StatelessWidget {
// title: L10n.of(context).chats,
// icon: const Icon(Icons.forum_outlined),
// ),
- if (controller.isSearchMode &&
- rooms
- .where(
- (room) => room
- .getLocalizedDisplayname(
- MatrixLocals(L10n.of(context)),
- )
- .toLowerCase()
- .contains(filter),
- )
- .isEmpty)
- Padding(
- padding: const EdgeInsetsGeometry.all(16.0),
- child: Text(
- L10n.of(context).emptyChatSearch,
- textAlign: TextAlign.center,
- ),
- ),
// if (client.prevBatch != null &&
// rooms.isEmpty &&
// !controller.isSearchMode) ...[
@@ -268,7 +248,7 @@ class ChatListViewBody extends StatelessWidget {
// padding: const EdgeInsets.all(16.0),
// child: Text(
// client.rooms.isEmpty
- // ? L10n.of(context).noChatsFoundHereYet
+ // ? L10n.of(context).noChatsFoundHere
// : L10n.of(context).noMoreChatsFound,
// textAlign: TextAlign.center,
// style: TextStyle(
@@ -280,6 +260,24 @@ class ChatListViewBody extends StatelessWidget {
// ],
// ),
// ],
+ if (controller.isSearchMode &&
+ rooms
+ .where(
+ (room) => room
+ .getLocalizedDisplayname(
+ MatrixLocals(L10n.of(context)),
+ )
+ .toLowerCase()
+ .contains(filter),
+ )
+ .isEmpty)
+ Padding(
+ padding: const EdgeInsetsGeometry.all(16.0),
+ child: Text(
+ L10n.of(context).emptyChatSearch,
+ textAlign: TextAlign.center,
+ ),
+ ),
// Pangea#
],
),
diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart
index 8853e9d7a..346870b00 100644
--- a/lib/pages/chat_list/chat_list_item.dart
+++ b/lib/pages/chat_list/chat_list_item.dart
@@ -4,6 +4,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
+import 'package:fluffychat/pages/chat_list/unread_bubble.dart';
import 'package:fluffychat/pangea/chat_list/utils/get_chat_list_item_subtitle.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
@@ -54,11 +55,6 @@ class ChatListItem extends StatelessWidget {
final unread = room.isUnread;
final directChatMatrixId = room.directChatMatrixID;
final isDirectChat = directChatMatrixId != null;
- final unreadBubbleSize = unread || room.hasNewMessages
- ? room.notificationCount > 0
- ? 20.0
- : 14.0
- : 0.0;
final hasNotifications = room.notificationCount > 0;
final backgroundColor =
activeChat ? theme.colorScheme.secondaryContainer : null;
@@ -248,7 +244,7 @@ class ChatListItem extends StatelessWidget {
children: [
if (typingText.isEmpty &&
ownMessage &&
- room.lastEvent!.status.isSending) ...[
+ room.lastEvent?.status.isSending == true) ...[
const SizedBox(
width: 16,
height: 16,
@@ -272,13 +268,11 @@ class ChatListItem extends StatelessWidget {
Expanded(
child: room.isSpace && room.membership == Membership.join
? Text(
- L10n.of(context).countChatsAndCountParticipants(
- // #Pangea
- // room.spaceChildren.length,
- room.spaceChildCount,
- // Pangea#
- (room.summary.mJoinedMemberCount ?? 1),
- ),
+ // #Pangea
+ // L10n.of(context)
+ // .countChats(room.spaceChildren.length),
+ L10n.of(context).countChats(room.spaceChildCount),
+ // Pangea#
style: TextStyle(color: theme.colorScheme.outline),
)
: typingText.isNotEmpty
@@ -367,41 +361,7 @@ class ChatListItem extends StatelessWidget {
),
),
const SizedBox(width: 8),
- AnimatedContainer(
- duration: FluffyThemes.animationDuration,
- curve: FluffyThemes.animationCurve,
- alignment: Alignment.center,
- padding: const EdgeInsets.symmetric(horizontal: 7),
- height: unreadBubbleSize,
- width: !hasNotifications && !unread && !room.hasNewMessages
- ? 0
- : (unreadBubbleSize - 9) *
- room.notificationCount.toString().length +
- 9,
- decoration: BoxDecoration(
- color: room.highlightCount > 0
- ? theme.colorScheme.error
- : hasNotifications || room.markedUnread
- ? theme.colorScheme.primary
- : theme.colorScheme.primaryContainer,
- borderRadius: BorderRadius.circular(7),
- ),
- child: hasNotifications
- ? Text(
- room.notificationCount.toString(),
- style: TextStyle(
- color: room.highlightCount > 0
- ? theme.colorScheme.onError
- : hasNotifications
- ? theme.colorScheme.onPrimary
- : theme.colorScheme.onPrimaryContainer,
- fontSize: 13,
- fontWeight: FontWeight.w500,
- ),
- textAlign: TextAlign.center,
- )
- : const SizedBox.shrink(),
- ),
+ UnreadBubble(room: room),
],
),
onTap: onTap,
diff --git a/lib/pages/chat_list/chat_list_view.dart b/lib/pages/chat_list/chat_list_view.dart
index 6bf986215..ef756dc45 100644
--- a/lib/pages/chat_list/chat_list_view.dart
+++ b/lib/pages/chat_list/chat_list_view.dart
@@ -30,7 +30,7 @@ class ChatListView extends StatelessWidget {
children: [
// #Pangea
// if (FluffyThemes.isColumnMode(context) ||
- // AppConfig.displayNavigationRail) ...[
+ // AppSettings.displayNavigationRail.value) ...[
// SpacesNavigationRail(
// activeSpaceId: controller.activeSpaceId,
// onGoToChats: controller.clearActiveSpace,
diff --git a/lib/pages/chat_list/client_chooser_button.dart b/lib/pages/chat_list/client_chooser_button.dart
index 643a6055c..83276dfeb 100644
--- a/lib/pages/chat_list/client_chooser_button.dart
+++ b/lib/pages/chat_list/client_chooser_button.dart
@@ -1,9 +1,10 @@
-// #Pangea
// import 'package:flutter/material.dart';
// import 'package:go_router/go_router.dart';
// import 'package:matrix/matrix.dart';
+// import 'package:url_launcher/url_launcher_string.dart';
+// import 'package:fluffychat/config/app_config.dart';
// import 'package:fluffychat/config/themes.dart';
// import 'package:fluffychat/l10n/l10n.dart';
// import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
@@ -68,6 +69,17 @@
// ],
// ),
// ),
+// if (Matrix.of(context).backgroundPush?.firebaseEnabled != true)
+// PopupMenuItem(
+// value: SettingsAction.support,
+// child: Row(
+// children: [
+// const Icon(Icons.favorite, color: Colors.red),
+// const SizedBox(width: 18),
+// Text(L10n.of(context).donate),
+// ],
+// ),
+// ),
// PopupMenuItem(
// value: SettingsAction.settings,
// child: Row(
@@ -208,6 +220,9 @@
// case SettingsAction.invite:
// FluffyShare.shareInviteLink(context);
// break;
+// case SettingsAction.support:
+// launchUrlString(AppConfig.donationUrl);
+// break;
// case SettingsAction.settings:
// context.go('/rooms/settings');
// break;
@@ -227,7 +242,7 @@
// newGroup,
// setStatus,
// invite,
+// support,
// settings,
// archive,
// }
-// Pangea#
diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart
index 33ea75344..a16220c4e 100644
--- a/lib/pages/chat_list/space_view.dart
+++ b/lib/pages/chat_list/space_view.dart
@@ -1,3 +1,5 @@
+import 'dart:convert';
+
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
@@ -8,26 +10,35 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
-import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
-import 'package:fluffychat/pages/chat_list/search_title.dart';
+import 'package:fluffychat/pages/chat_list/unread_bubble.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
+import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/stream_extension.dart';
+import 'package:fluffychat/utils/string_color.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/public_room_dialog.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
+import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/matrix.dart';
enum AddRoomType { chat, subspace }
+enum SpaceChildAction { edit, moveToSpace, removeFromSpace }
+
+enum SpaceActions {
+ settings,
+ invite,
+ members,
+ leave,
+}
+
class SpaceView extends StatefulWidget {
final String spaceId;
final void Function() onBack;
- final void Function(String spaceId) toParentSpace;
final void Function(Room room) onChatTab;
- final void Function(Room room, BuildContext context) onChatContext;
final String? activeChat;
const SpaceView({
@@ -35,8 +46,6 @@ class SpaceView extends StatefulWidget {
required this.onBack,
required this.onChatTab,
required this.activeChat,
- required this.toParentSpace,
- required this.onChatContext,
super.key,
});
@@ -58,9 +67,28 @@ class _SpaceViewState extends State {
}
void _loadHierarchy() async {
- final room = Matrix.of(context).client.getRoomById(widget.spaceId);
+ final matrix = Matrix.of(context);
+ final room = matrix.client.getRoomById(widget.spaceId);
if (room == null) return;
+ final cacheKey = 'spaces_history_cache${room.id}';
+ if (_discoveredChildren.isEmpty) {
+ final cachedChildren = matrix.store.getStringList(cacheKey);
+ if (cachedChildren != null) {
+ try {
+ _discoveredChildren.addAll(
+ cachedChildren.map(
+ (jsonString) =>
+ SpaceRoomsChunk$2.fromJson(jsonDecode(jsonString)),
+ ),
+ );
+ } catch (e, s) {
+ Logs().e('Unable to json decode spaces hierarchy cache!', e, s);
+ matrix.store.remove(cacheKey);
+ }
+ }
+ }
+
setState(() {
_isLoading = true;
});
@@ -74,16 +102,25 @@ class _SpaceViewState extends State {
);
if (!mounted) return;
setState(() {
+ if (_nextBatch == null) _discoveredChildren.clear();
_nextBatch = hierarchy.nextBatch;
if (hierarchy.nextBatch == null) {
_noMoreRooms = true;
}
_discoveredChildren.addAll(
- hierarchy.rooms
- .where((c) => room.client.getRoomById(c.roomId) == null),
+ hierarchy.rooms.where((room) => room.roomId != widget.spaceId),
);
_isLoading = false;
});
+
+ if (_nextBatch == null) {
+ matrix.store.setStringList(
+ cacheKey,
+ _discoveredChildren
+ .map((child) => jsonEncode(child.toJson()))
+ .toList(),
+ );
+ }
} catch (e, s) {
Logs().w('Unable to load hierarchy', e, s);
if (!mounted) return;
@@ -111,9 +148,7 @@ class _SpaceViewState extends State {
),
);
if (mounted && joined == true) {
- setState(() {
- _discoveredChildren.remove(item);
- });
+ setState(() {});
}
}
@@ -129,6 +164,10 @@ class _SpaceViewState extends State {
await space?.postLoad();
context.push('/rooms/${widget.spaceId}/invite');
break;
+ case SpaceActions.members:
+ await space?.postLoad();
+ context.push('/rooms/${widget.spaceId}/details/members');
+ break;
case SpaceActions.leave:
final confirmed = await showOkCancelAlertDialog(
context: context,
@@ -151,27 +190,11 @@ class _SpaceViewState extends State {
}
}
- void _addChatOrSubspace() async {
- final roomType = await showModalActionPopup(
- context: context,
- title: L10n.of(context).addChatOrSubSpace,
- actions: [
- AdaptiveModalAction(
- value: AddRoomType.subspace,
- label: L10n.of(context).createNewSpace,
- ),
- AdaptiveModalAction(
- value: AddRoomType.chat,
- label: L10n.of(context).createGroup,
- ),
- ],
- );
- if (roomType == null) return;
-
+ void _addChatOrSubspace(AddRoomType roomType) async {
final names = await showTextInputDialog(
context: context,
title: roomType == AddRoomType.subspace
- ? L10n.of(context).createNewSpace
+ ? L10n.of(context).newSubSpace
: L10n.of(context).createGroup,
hintText: roomType == AddRoomType.subspace
? L10n.of(context).spaceName
@@ -196,29 +219,169 @@ class _SpaceViewState extends State {
late final String roomId;
final activeSpace = client.getRoomById(widget.spaceId)!;
await activeSpace.postLoad();
+ final isPublicSpace = activeSpace.joinRules == JoinRules.public;
if (roomType == AddRoomType.subspace) {
roomId = await client.createSpace(
name: names,
- visibility: activeSpace.joinRules == JoinRules.public
- ? sdk.Visibility.public
- : sdk.Visibility.private,
+ visibility:
+ isPublicSpace ? sdk.Visibility.public : sdk.Visibility.private,
);
} else {
roomId = await client.createGroupChat(
+ enableEncryption: !isPublicSpace,
groupName: names,
- preset: activeSpace.joinRules == JoinRules.public
+ preset: isPublicSpace
? CreateRoomPreset.publicChat
: CreateRoomPreset.privateChat,
- visibility: activeSpace.joinRules == JoinRules.public
- ? sdk.Visibility.public
- : sdk.Visibility.private,
+ visibility:
+ isPublicSpace ? sdk.Visibility.public : sdk.Visibility.private,
+ initialState: isPublicSpace
+ ? null
+ : [
+ StateEvent(
+ content: {
+ 'join_rule': 'restricted',
+ 'allow': [
+ {
+ 'room_id': widget.spaceId,
+ 'type': 'm.room_membership',
+ },
+ ],
+ },
+ type: EventTypes.RoomJoinRules,
+ ),
+ ],
);
}
await activeSpace.setSpaceChild(roomId);
},
);
if (result.error != null) return;
+ setState(() {
+ _nextBatch = null;
+ _discoveredChildren.clear();
+ });
+ _loadHierarchy();
+ }
+
+ void _showSpaceChildEditMenu(BuildContext posContext, String roomId) async {
+ final overlay =
+ Overlay.of(posContext).context.findRenderObject() as RenderBox;
+
+ final button = posContext.findRenderObject() as RenderBox;
+
+ final position = RelativeRect.fromRect(
+ Rect.fromPoints(
+ button.localToGlobal(const Offset(0, -65), ancestor: overlay),
+ button.localToGlobal(
+ button.size.bottomRight(Offset.zero) + const Offset(-50, 0),
+ ancestor: overlay,
+ ),
+ ),
+ Offset.zero & overlay.size,
+ );
+
+ final action = await showMenu(
+ context: posContext,
+ position: position,
+ items: [
+ PopupMenuItem(
+ value: SpaceChildAction.moveToSpace,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Icon(Icons.move_down_outlined),
+ const SizedBox(width: 12),
+ Text(L10n.of(context).moveToDifferentSpace),
+ ],
+ ),
+ ),
+ PopupMenuItem(
+ value: SpaceChildAction.edit,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Icon(Icons.edit_outlined),
+ const SizedBox(width: 12),
+ Text(L10n.of(context).edit),
+ ],
+ ),
+ ),
+ PopupMenuItem(
+ value: SpaceChildAction.removeFromSpace,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Icon(Icons.group_remove_outlined),
+ const SizedBox(width: 12),
+ Text(L10n.of(context).removeFromSpace),
+ ],
+ ),
+ ),
+ ],
+ );
+ if (action == null) return;
+ if (!mounted) return;
+ final space = Matrix.of(context).client.getRoomById(widget.spaceId);
+ if (space == null) return;
+ switch (action) {
+ case SpaceChildAction.edit:
+ context.push('/rooms/${widget.spaceId}/details');
+ case SpaceChildAction.moveToSpace:
+ final spacesWithPowerLevels = space.client.rooms
+ .where(
+ (room) =>
+ room.isSpace &&
+ room.canChangeStateEvent(EventTypes.SpaceChild) &&
+ room.id != widget.spaceId,
+ )
+ .toList();
+ final newSpace = await showModalActionPopup(
+ context: context,
+ title: L10n.of(context).space,
+ actions: spacesWithPowerLevels
+ .map(
+ (space) => AdaptiveModalAction(
+ value: space,
+ label: space
+ .getLocalizedDisplayname(MatrixLocals(L10n.of(context))),
+ ),
+ )
+ .toList(),
+ );
+ if (newSpace == null) return;
+ final result = await showFutureLoadingDialog(
+ context: context,
+ future: () async {
+ await newSpace.setSpaceChild(newSpace.id);
+ await space.removeSpaceChild(roomId);
+ },
+ );
+ if (result.isError) return;
+ if (!mounted) return;
+ _nextBatch = null;
+ _loadHierarchy();
+ return;
+
+ case SpaceChildAction.removeFromSpace:
+ final consent = await showOkCancelAlertDialog(
+ context: context,
+ title: L10n.of(context).removeFromSpace,
+ message: L10n.of(context).removeFromSpaceDescription,
+ );
+ if (consent != OkCancelResult.ok) return;
+ if (!mounted) return;
+ final result = await showFutureLoadingDialog(
+ context: context,
+ future: () => space.removeSpaceChild(roomId),
+ );
+ if (result.isError) return;
+ if (!mounted) return;
+ _nextBatch = null;
+ _loadHierarchy();
+ return;
+ }
}
@override
@@ -228,6 +391,11 @@ class _SpaceViewState extends State {
final room = Matrix.of(context).client.getRoomById(widget.spaceId);
final displayname =
room?.getLocalizedDisplayname() ?? L10n.of(context).nothingFound;
+ const avatarSize = Avatar.defaultSize / 1.5;
+ final isAdmin = room?.canChangeStateEvent(
+ EventTypes.SpaceChild,
+ ) ==
+ true;
return Scaffold(
appBar: AppBar(
leading: FluffyThemes.isColumnMode(context)
@@ -242,6 +410,7 @@ class _SpaceViewState extends State {
title: ListTile(
contentPadding: EdgeInsets.zero,
leading: Avatar(
+ size: avatarSize,
mxContent: room?.avatar,
name: displayname,
border: BorderSide(width: 1, color: theme.dividerColor),
@@ -252,18 +421,38 @@ class _SpaceViewState extends State {
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
- subtitle: room == null
- ? null
- : Text(
- L10n.of(context).countChatsAndCountParticipants(
- room.spaceChildren.length,
- room.summary.mJoinedMemberCount ?? 1,
- ),
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- ),
),
actions: [
+ if (isAdmin)
+ PopupMenuButton(
+ icon: const Icon(Icons.add_outlined),
+ onSelected: _addChatOrSubspace,
+ tooltip: L10n.of(context).addChatOrSubSpace,
+ itemBuilder: (context) => [
+ PopupMenuItem(
+ value: AddRoomType.chat,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Icon(Icons.group_add_outlined),
+ const SizedBox(width: 12),
+ Text(L10n.of(context).newGroup),
+ ],
+ ),
+ ),
+ PopupMenuItem(
+ value: AddRoomType.subspace,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Icon(Icons.workspaces_outlined),
+ const SizedBox(width: 12),
+ Text(L10n.of(context).newSubSpace),
+ ],
+ ),
+ ),
+ ],
+ ),
PopupMenuButton(
useRootNavigator: true,
onSelected: _onSpaceAction,
@@ -290,6 +479,21 @@ class _SpaceViewState extends State {
],
),
),
+ PopupMenuItem(
+ value: SpaceActions.members,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const Icon(Icons.group_outlined),
+ const SizedBox(width: 12),
+ Text(
+ L10n.of(context).countParticipants(
+ room?.summary.mJoinedMemberCount ?? 1,
+ ),
+ ),
+ ],
+ ),
+ ),
PopupMenuItem(
value: SpaceActions.leave,
child: Row(
@@ -305,16 +509,6 @@ class _SpaceViewState extends State {
),
],
),
- floatingActionButton: room?.canChangeStateEvent(
- EventTypes.SpaceChild,
- ) ==
- true
- ? FloatingActionButton.extended(
- onPressed: _addChatOrSubspace,
- label: Text(L10n.of(context).group),
- icon: const Icon(Icons.group_add_outlined),
- )
- : null,
body: room == null
? const Center(
child: Icon(
@@ -327,29 +521,11 @@ class _SpaceViewState extends State {
.where((s) => s.hasRoomUpdate)
.rateLimit(const Duration(seconds: 1)),
builder: (context, snapshot) {
- final childrenIds = room.spaceChildren
- .map((c) => c.roomId)
- .whereType()
- .toSet();
-
- final joinedRooms = room.client.rooms
- .where((room) => childrenIds.remove(room.id))
- .toList();
-
- final joinedParents = room.spaceParents
- .map((parent) {
- final roomId = parent.roomId;
- if (roomId == null) return null;
- return room.client.getRoomById(roomId);
- })
- .whereType()
- .toList();
final filter = _filterController.text.trim().toLowerCase();
return CustomScrollView(
slivers: [
SliverAppBar(
floating: true,
- toolbarHeight: 72,
scrolledUnderElevation: 0,
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
@@ -359,11 +535,6 @@ class _SpaceViewState extends State {
textInputAction: TextInputAction.search,
decoration: InputDecoration(
filled: true,
- fillColor: theme.colorScheme.secondaryContainer,
- border: OutlineInputBorder(
- borderSide: BorderSide.none,
- borderRadius: BorderRadius.circular(99),
- ),
contentPadding: EdgeInsets.zero,
hintText: L10n.of(context).search,
hintStyle: TextStyle(
@@ -382,83 +553,11 @@ class _SpaceViewState extends State {
),
),
SliverList.builder(
- itemCount: joinedParents.length,
+ itemCount: _discoveredChildren.length + 1,
itemBuilder: (context, i) {
- final displayname =
- joinedParents[i].getLocalizedDisplayname();
- return Padding(
- padding: const EdgeInsets.symmetric(
- horizontal: 8,
- vertical: 1,
- ),
- child: Material(
- borderRadius:
- BorderRadius.circular(AppConfig.borderRadius),
- clipBehavior: Clip.hardEdge,
- child: ListTile(
- minVerticalPadding: 0,
- leading: Icon(
- Icons.adaptive.arrow_back_outlined,
- size: 16,
- ),
- title: Row(
- children: [
- Avatar(
- mxContent: joinedParents[i].avatar,
- name: displayname,
- size: Avatar.defaultSize / 2,
- borderRadius: BorderRadius.circular(
- AppConfig.borderRadius / 4,
- ),
- ),
- const SizedBox(width: 8),
- Expanded(child: Text(displayname)),
- ],
- ),
- onTap: () =>
- widget.toParentSpace(joinedParents[i].id),
- ),
- ),
- );
- },
- ),
- SliverList.builder(
- itemCount: joinedRooms.length,
- itemBuilder: (context, i) {
- final joinedRoom = joinedRooms[i];
- return ChatListItem(
- joinedRoom,
- filter: filter,
- onTap: () => widget.onChatTab(joinedRoom),
- onLongPress: (context) => widget.onChatContext(
- joinedRoom,
- context,
- ),
- activeChat: widget.activeChat == joinedRoom.id,
- );
- },
- ),
- SliverList.builder(
- itemCount: _discoveredChildren.length + 2,
- itemBuilder: (context, i) {
- if (i == 0) {
- return SearchTitle(
- title: L10n.of(context).discover,
- icon: const Icon(Icons.explore_outlined),
- );
- }
- i--;
if (i == _discoveredChildren.length) {
if (_noMoreRooms) {
- return Padding(
- padding: const EdgeInsets.all(12.0),
- child: Center(
- child: Text(
- L10n.of(context).noMoreChatsFound,
- style: const TextStyle(fontSize: 13),
- ),
- ),
- );
+ return const SizedBox.shrink();
}
return Padding(
padding: const EdgeInsets.symmetric(
@@ -468,11 +567,7 @@ class _SpaceViewState extends State {
child: TextButton(
onPressed: _isLoading ? null : _loadHierarchy,
child: _isLoading
- ? LinearProgressIndicator(
- borderRadius: BorderRadius.circular(
- AppConfig.borderRadius,
- ),
- )
+ ? const CircularProgressIndicator.adaptive()
: Text(L10n.of(context).loadMore),
),
);
@@ -484,6 +579,10 @@ class _SpaceViewState extends State {
if (!displayname.toLowerCase().contains(filter)) {
return const SizedBox.shrink();
}
+ var joinedRoom = room.client.getRoomById(item.roomId);
+ if (joinedRoom?.membership == Membership.leave) {
+ joinedRoom = null;
+ }
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8,
@@ -493,51 +592,83 @@ class _SpaceViewState extends State {
borderRadius:
BorderRadius.circular(AppConfig.borderRadius),
clipBehavior: Clip.hardEdge,
- child: ListTile(
- visualDensity:
- const VisualDensity(vertical: -0.5),
- contentPadding:
- const EdgeInsets.symmetric(horizontal: 8),
- onTap: () => _joinChildRoom(item),
- leading: Avatar(
- mxContent: item.avatarUrl,
- name: displayname,
- borderRadius: item.roomType == 'm.space'
- ? BorderRadius.circular(
- AppConfig.borderRadius / 2,
- )
+ color: joinedRoom != null &&
+ widget.activeChat == joinedRoom.id
+ ? theme.colorScheme.secondaryContainer
+ : Colors.transparent,
+ child: HoverBuilder(
+ builder: (context, hovered) => ListTile(
+ visualDensity:
+ const VisualDensity(vertical: -0.5),
+ contentPadding:
+ const EdgeInsets.symmetric(horizontal: 8),
+ onTap: joinedRoom != null
+ ? () => widget.onChatTab(joinedRoom!)
+ : () => _joinChildRoom(item),
+ onLongPress: isAdmin
+ ? () => _showSpaceChildEditMenu(
+ context,
+ item.roomId,
+ )
: null,
- ),
- title: Row(
- children: [
- Expanded(
- child: Text(
- displayname,
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
+ leading: hovered && isAdmin
+ ? SizedBox.square(
+ dimension: avatarSize,
+ child: IconButton(
+ splashRadius: avatarSize,
+ iconSize: 14,
+ style: IconButton.styleFrom(
+ foregroundColor: theme.colorScheme
+ .onTertiaryContainer,
+ backgroundColor: theme
+ .colorScheme.tertiaryContainer,
+ ),
+ onPressed: () =>
+ _showSpaceChildEditMenu(
+ context,
+ item.roomId,
+ ),
+ icon: const Icon(Icons.edit_outlined),
+ ),
+ )
+ : Avatar(
+ size: avatarSize,
+ mxContent: item.avatarUrl,
+ name: '#',
+ backgroundColor:
+ theme.colorScheme.surfaceContainer,
+ textColor: item.name?.darkColor ??
+ theme.colorScheme.onSurface,
+ border: item.roomType == 'm.space'
+ ? BorderSide(
+ color: theme.colorScheme
+ .surfaceContainerHighest,
+ )
+ : null,
+ borderRadius: item.roomType == 'm.space'
+ ? BorderRadius.circular(
+ AppConfig.borderRadius / 4,
+ )
+ : null,
+ ),
+ title: Row(
+ children: [
+ Expanded(
+ child: Opacity(
+ opacity: joinedRoom == null ? 0.5 : 1,
+ child: Text(
+ displayname,
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ ),
+ ),
),
- ),
- Text(
- item.numJoinedMembers.toString(),
- style: TextStyle(
- fontSize: 13,
- color: theme.textTheme.bodyMedium!.color,
- ),
- ),
- const SizedBox(width: 4),
- const Icon(
- Icons.people_outlined,
- size: 14,
- ),
- ],
- ),
- subtitle: Text(
- item.topic ??
- L10n.of(context).countParticipants(
- item.numJoinedMembers,
- ),
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
+ if (joinedRoom != null)
+ UnreadBubble(room: joinedRoom)
+ else
+ const Icon(Icons.chevron_right_outlined),
+ ],
+ ),
),
),
),
@@ -552,9 +683,3 @@ class _SpaceViewState extends State {
);
}
}
-
-enum SpaceActions {
- settings,
- invite,
- leave,
-}
diff --git a/lib/pages/chat_list/unread_bubble.dart b/lib/pages/chat_list/unread_bubble.dart
new file mode 100644
index 000000000..964094f97
--- /dev/null
+++ b/lib/pages/chat_list/unread_bubble.dart
@@ -0,0 +1,56 @@
+import 'package:flutter/material.dart';
+
+import 'package:matrix/matrix.dart';
+
+import 'package:fluffychat/config/themes.dart';
+
+class UnreadBubble extends StatelessWidget {
+ final Room room;
+ const UnreadBubble({required this.room, super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ final unread = room.isUnread;
+ final hasNotifications = room.notificationCount > 0;
+ final unreadBubbleSize = unread || room.hasNewMessages
+ ? room.notificationCount > 0
+ ? 20.0
+ : 14.0
+ : 0.0;
+ return AnimatedContainer(
+ duration: FluffyThemes.animationDuration,
+ curve: FluffyThemes.animationCurve,
+ alignment: Alignment.center,
+ padding: const EdgeInsets.symmetric(horizontal: 7),
+ height: unreadBubbleSize,
+ width: !hasNotifications && !unread && !room.hasNewMessages
+ ? 0
+ : (unreadBubbleSize - 9) * room.notificationCount.toString().length +
+ 9,
+ decoration: BoxDecoration(
+ color: room.highlightCount > 0
+ ? theme.colorScheme.error
+ : hasNotifications || room.markedUnread
+ ? theme.colorScheme.primary
+ : theme.colorScheme.primaryContainer,
+ borderRadius: BorderRadius.circular(7),
+ ),
+ child: hasNotifications
+ ? Text(
+ room.notificationCount.toString(),
+ style: TextStyle(
+ color: room.highlightCount > 0
+ ? theme.colorScheme.onError
+ : hasNotifications
+ ? theme.colorScheme.onPrimary
+ : theme.colorScheme.onPrimaryContainer,
+ fontSize: 13,
+ fontWeight: FontWeight.w500,
+ ),
+ textAlign: TextAlign.center,
+ )
+ : const SizedBox.shrink(),
+ );
+ }
+}
diff --git a/lib/pages/homeserver_picker/homeserver_picker.dart b/lib/pages/homeserver_picker/homeserver_picker.dart
index b17a3bc06..1e8d015bf 100644
--- a/lib/pages/homeserver_picker/homeserver_picker.dart
+++ b/lib/pages/homeserver_picker/homeserver_picker.dart
@@ -8,7 +8,7 @@ import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:universal_html/html.dart' as html;
-import 'package:url_launcher/url_launcher_string.dart';
+import 'package:url_launcher/url_launcher.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
@@ -34,7 +34,10 @@ class HomeserverPickerController extends State {
bool isLoading = false;
final TextEditingController homeserverController = TextEditingController(
+ // #Pangea
+ // text: AppSettings.defaultHomeserver.value,
text: AppConfig.defaultHomeserver,
+ // Pangea#
);
String? error;
@@ -211,7 +214,7 @@ class HomeserverPickerController extends State {
case MoreLoginActions.importBackup:
restoreBackup();
case MoreLoginActions.privacy:
- launchUrlString(AppConfig.privacyUrl);
+ launchUrl(AppConfig.privacyUrl);
case MoreLoginActions.about:
PlatformInfos.showDialog(context);
}
diff --git a/lib/pages/settings/settings_view.dart b/lib/pages/settings/settings_view.dart
index 874e7ebe3..4a7f90bc0 100644
--- a/lib/pages/settings/settings_view.dart
+++ b/lib/pages/settings/settings_view.dart
@@ -148,7 +148,9 @@ class SettingsView extends StatelessWidget {
displayname,
maxLines: 1,
overflow: TextOverflow.ellipsis,
- style: const TextStyle(fontSize: 18),
+ style: const TextStyle(
+ fontSize: 18,
+ ),
),
),
TextButton.icon(
@@ -380,7 +382,7 @@ class SettingsView extends StatelessWidget {
// ListTile(
// leading: const Icon(Icons.privacy_tip_outlined),
// title: Text(L10n.of(context).privacy),
- // onTap: () => launchUrlString(AppConfig.privacyUrl),
+ // onTap: () => launchUrl(AppConfig.privacyUrl),
// ),
// ListTile(
// leading: const Icon(Icons.info_outline_rounded),
diff --git a/lib/pages/settings_chat/settings_chat_view.dart b/lib/pages/settings_chat/settings_chat_view.dart
index 1b41f51d9..0d635c0fd 100644
--- a/lib/pages/settings_chat/settings_chat_view.dart
+++ b/lib/pages/settings_chat/settings_chat_view.dart
@@ -4,7 +4,6 @@ import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
-import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:fluffychat/widgets/settings_switch_list_tile.dart';
import 'settings_chat.dart';
@@ -32,46 +31,33 @@ class SettingsChatView extends StatelessWidget {
// SettingsSwitchListTile.adaptive(
// title: L10n.of(context).formattedMessages,
// subtitle: L10n.of(context).formattedMessagesDescription,
- // onChanged: (b) => AppConfig.renderHtml = b,
- // storeKey: SettingKeys.renderHtml,
- // defaultValue: AppConfig.renderHtml,
+ // setting: AppSettings.renderHtml,
// ),
// Pangea#
SettingsSwitchListTile.adaptive(
title: L10n.of(context).hideRedactedMessages,
subtitle: L10n.of(context).hideRedactedMessagesBody,
- onChanged: (b) => AppConfig.hideRedactedEvents = b,
- storeKey: SettingKeys.hideRedactedEvents,
- defaultValue: AppConfig.hideRedactedEvents,
+ setting: AppSettings.hideRedactedEvents,
),
SettingsSwitchListTile.adaptive(
title: L10n.of(context).hideInvalidOrUnknownMessageFormats,
- onChanged: (b) => AppConfig.hideUnknownEvents = b,
- storeKey: SettingKeys.hideUnknownEvents,
- defaultValue: AppConfig.hideUnknownEvents,
+ setting: AppSettings.hideUnknownEvents,
),
// #Pangea
// if (PlatformInfos.isMobile)
// SettingsSwitchListTile.adaptive(
// title: L10n.of(context).autoplayImages,
- // onChanged: (b) => AppConfig.autoplayImages = b,
- // storeKey: SettingKeys.autoplayImages,
- // defaultValue: AppConfig.autoplayImages,
+ // setting: AppSettings.autoplayImages,
// ),
// Pangea#
SettingsSwitchListTile.adaptive(
title: L10n.of(context).sendOnEnter,
- onChanged: (b) => AppConfig.sendOnEnter = b,
- storeKey: SettingKeys.sendOnEnter,
- defaultValue: AppConfig.sendOnEnter ?? !PlatformInfos.isMobile,
+ setting: AppSettings.sendOnEnter,
),
SettingsSwitchListTile.adaptive(
title: L10n.of(context).swipeRightToLeftToReply,
- onChanged: (b) => AppConfig.swipeRightToLeftToReply = b,
- storeKey: SettingKeys.swipeRightToLeftToReply,
- defaultValue: AppConfig.swipeRightToLeftToReply,
+ setting: AppSettings.swipeRightToLeftToReply,
),
-
// #Pangea
SwitchListTile.adaptive(
value: AppConfig.useActivityImageAsChatBackground,
@@ -110,12 +96,10 @@ class SettingsChatView extends StatelessWidget {
// SettingsSwitchListTile.adaptive(
// title: L10n.of(context).experimentalVideoCalls,
// onChanged: (b) {
- // AppConfig.experimentalVoip = b;
// Matrix.of(context).createVoipPlugin();
// return;
// },
- // storeKey: SettingKeys.experimentalVoip,
- // defaultValue: AppConfig.experimentalVoip,
+ // setting: AppSettings.experimentalVoip,
// ),
// Pangea#
],
diff --git a/lib/pages/settings_notifications/settings_notifications.dart b/lib/pages/settings_notifications/settings_notifications.dart
index b0974940c..162cc881e 100644
--- a/lib/pages/settings_notifications/settings_notifications.dart
+++ b/lib/pages/settings_notifications/settings_notifications.dart
@@ -201,10 +201,7 @@ class SettingsNotificationsController extends State {
void updateVolume(double value) {
volumeNotifier.value = value;
AppConfig.volume = value;
- Matrix.of(context).store.setDouble(
- SettingKeys.volume,
- value,
- );
+ AppSettings.volume.setItem(value);
}
Future requestNotificationPermission() async {
diff --git a/lib/pages/settings_security/settings_security.dart b/lib/pages/settings_security/settings_security.dart
index e55d4c3c2..c84a144cb 100644
--- a/lib/pages/settings_security/settings_security.dart
+++ b/lib/pages/settings_security/settings_security.dart
@@ -156,7 +156,6 @@ class SettingsSecurityController extends State {
void changeShareKeysWith(ShareKeysWith? shareKeysWith) async {
if (shareKeysWith == null) return;
AppSettings.shareKeysWith.setItem(
- Matrix.of(context).store,
shareKeysWith.name,
);
Matrix.of(context).client.shareKeysWith = shareKeysWith;
diff --git a/lib/pages/settings_security/settings_security_view.dart b/lib/pages/settings_security/settings_security_view.dart
index b181c9915..039fd97eb 100644
--- a/lib/pages/settings_security/settings_security_view.dart
+++ b/lib/pages/settings_security/settings_security_view.dart
@@ -63,16 +63,12 @@ class SettingsSecurityView extends StatelessWidget {
title: L10n.of(context).sendTypingNotifications,
subtitle:
L10n.of(context).sendTypingNotificationsDescription,
- onChanged: (b) => AppConfig.sendTypingNotifications = b,
- storeKey: SettingKeys.sendTypingNotifications,
- defaultValue: AppConfig.sendTypingNotifications,
+ setting: AppSettings.sendTypingNotifications,
),
SettingsSwitchListTile.adaptive(
title: L10n.of(context).sendReadReceipts,
subtitle: L10n.of(context).sendReadReceiptsDescription,
- onChanged: (b) => AppConfig.sendPublicReadReceipts = b,
- storeKey: SettingKeys.sendPublicReadReceipts,
- defaultValue: AppConfig.sendPublicReadReceipts,
+ setting: AppSettings.sendPublicReadReceipts,
),
ListTile(
trailing: const Icon(Icons.chevron_right_outlined),
diff --git a/lib/pages/settings_style/settings_style.dart b/lib/pages/settings_style/settings_style.dart
index 5a0092a9a..968759ad4 100644
--- a/lib/pages/settings_style/settings_style.dart
+++ b/lib/pages/settings_style/settings_style.dart
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/config/app_config.dart';
-import 'package:fluffychat/pangea/user/style_settings_repo.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/account_config.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
@@ -18,7 +18,9 @@ class SettingsStyle extends StatefulWidget {
class SettingsStyleController extends State {
void setChatColor(Color? color) async {
- AppConfig.colorSchemeSeed = color;
+ AppSettings.colorSchemeSeedInt.setItem(
+ color?.toARGB32() ?? AppSettings.colorSchemeSeedInt.defaultValue,
+ );
ThemeController.of(context).setPrimaryColor(color);
}
@@ -156,17 +158,7 @@ class SettingsStyleController extends State {
}
void changeFontSizeFactor(double d) {
- setState(() => AppConfig.fontSizeFactor = d);
- // #Pangea
- // Matrix.of(context).store.setString(
- // SettingKeys.fontSizeFactor,
- // AppConfig.fontSizeFactor.toString(),
- // );
- StyleSettingsRepo.setFontSizeFactor(
- Matrix.of(context).client.userID!,
- AppConfig.fontSizeFactor,
- );
- // Pangea#
+ AppSettings.fontSizeFactor.setItem(d);
}
@override
diff --git a/lib/pages/settings_style/settings_style_view.dart b/lib/pages/settings_style/settings_style_view.dart
index 6bf3b2a79..aa32e6828 100644
--- a/lib/pages/settings_style/settings_style_view.dart
+++ b/lib/pages/settings_style/settings_style_view.dart
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:matrix/matrix.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/events/state_message.dart';
@@ -228,7 +229,7 @@ class SettingsStyleView extends StatelessWidget {
style: TextStyle(
color: theme.onBubbleColor,
fontSize: AppConfig.messageFontSize *
- AppConfig.fontSizeFactor,
+ AppSettings.fontSizeFactor.value,
),
),
),
@@ -261,7 +262,7 @@ class SettingsStyleView extends StatelessWidget {
style: TextStyle(
color: theme.colorScheme.onSurface,
fontSize: AppConfig.messageFontSize *
- AppConfig.fontSizeFactor,
+ AppSettings.fontSizeFactor.value,
),
),
),
@@ -323,13 +324,15 @@ class SettingsStyleView extends StatelessWidget {
),
ListTile(
title: Text(L10n.of(context).fontSize),
- trailing: Text('× ${AppConfig.fontSizeFactor}'),
+ trailing: Text(
+ '× ${AppSettings.fontSizeFactor.value}',
+ ),
),
Slider.adaptive(
min: 0.5,
max: 2.5,
divisions: 20,
- value: AppConfig.fontSizeFactor,
+ value: AppSettings.fontSizeFactor.value,
semanticFormatterCallback: (d) => d.toString(),
onChanged: controller.changeFontSizeFactor,
),
@@ -348,21 +351,15 @@ class SettingsStyleView extends StatelessWidget {
// ),
// SettingsSwitchListTile.adaptive(
// title: L10n.of(context).presencesToggle,
- // onChanged: (b) => AppConfig.showPresences = b,
- // storeKey: SettingKeys.showPresences,
- // defaultValue: AppConfig.showPresences,
+ // setting: AppSettings.showPresences,
// ),
// SettingsSwitchListTile.adaptive(
// title: L10n.of(context).separateChatTypes,
- // onChanged: (b) => AppConfig.separateChatTypes = b,
- // storeKey: SettingKeys.separateChatTypes,
- // defaultValue: AppConfig.separateChatTypes,
+ // setting: AppSettings.separateChatTypes,
// ),
// SettingsSwitchListTile.adaptive(
// title: L10n.of(context).displayNavigationRail,
- // onChanged: (b) => AppConfig.displayNavigationRail = b,
- // storeKey: SettingKeys.displayNavigationRail,
- // defaultValue: AppConfig.displayNavigationRail,
+ // setting: AppSettings.displayNavigationRail,
// ),
// Pangea#
],
diff --git a/lib/pangea/activity_sessions/activity_session_chat/activity_chat_extension.dart b/lib/pangea/activity_sessions/activity_session_chat/activity_chat_extension.dart
index 582fddb85..fa917769a 100644
--- a/lib/pangea/activity_sessions/activity_session_chat/activity_chat_extension.dart
+++ b/lib/pangea/activity_sessions/activity_session_chat/activity_chat_extension.dart
@@ -1,7 +1,6 @@
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
-import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
@@ -10,7 +9,7 @@ import 'package:fluffychat/widgets/matrix.dart';
extension ActivityMenuLogic on ChatController {
bool get shouldShowActivityInstructions {
- if (AppConfig.showedActivityMenu ||
+ if (InstructionsEnum.showedActivityMenu.isToggledOff ||
InstructionsEnum.activityStatsMenu.isToggledOff ||
MatrixState.pAnyState.isOverlayOpen(RegExp(r"^word-zoom-card-.*$")) ||
timeline == null ||
diff --git a/lib/pangea/activity_sessions/activity_session_chat/activity_roles_event_widget.dart b/lib/pangea/activity_sessions/activity_session_chat/activity_roles_event_widget.dart
index a6e3f3fd9..6a52cfc37 100644
--- a/lib/pangea/activity_sessions/activity_session_chat/activity_roles_event_widget.dart
+++ b/lib/pangea/activity_sessions/activity_session_chat/activity_roles_event_widget.dart
@@ -4,6 +4,7 @@ import 'package:collection/collection.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/activity_sessions/activity_role_model.dart';
@@ -72,7 +73,7 @@ class ActivityRolesEvent extends StatelessWidget {
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
- fontSize: 12 * AppConfig.fontSizeFactor,
+ fontSize: 12 * AppSettings.fontSizeFactor.value,
decoration:
event.redacted ? TextDecoration.lineThrough : null,
),
diff --git a/lib/pangea/analytics_details_popup/lemma_use_example_messages.dart b/lib/pangea/analytics_details_popup/lemma_use_example_messages.dart
index 86dbc3364..cb59a93fb 100644
--- a/lib/pangea/analytics_details_popup/lemma_use_example_messages.dart
+++ b/lib/pangea/analytics_details_popup/lemma_use_example_messages.dart
@@ -6,6 +6,7 @@ import 'package:collection/collection.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_use_model.dart';
import 'package:fluffychat/pangea/analytics_misc/construct_use_type_enum.dart';
import 'package:fluffychat/pangea/analytics_misc/constructs_model.dart';
@@ -118,7 +119,7 @@ class LemmaUseExampleMessages extends StatelessWidget {
text: TextSpan(
style: TextStyle(
color: Theme.of(context).colorScheme.onPrimaryFixed,
- fontSize: AppConfig.fontSizeFactor *
+ fontSize: AppSettings.fontSizeFactor.value *
AppConfig.messageFontSize,
),
children: example.textSpans,
diff --git a/lib/pangea/analytics_downloads/analytics_dowload_dialog.dart b/lib/pangea/analytics_downloads/analytics_dowload_dialog.dart
index ea0739580..da4a96c4b 100644
--- a/lib/pangea/analytics_downloads/analytics_dowload_dialog.dart
+++ b/lib/pangea/analytics_downloads/analytics_dowload_dialog.dart
@@ -7,6 +7,7 @@ import 'package:intl/intl.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/analytics_downloads/analytics_summary_enum.dart';
@@ -426,7 +427,8 @@ class AnalyticsDownloadDialogState extends State {
Text(
L10n.of(context).fileType,
style: TextStyle(
- fontSize: AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
),
),
Padding(
diff --git a/lib/pangea/analytics_misc/text_loading_shimmer.dart b/lib/pangea/analytics_misc/text_loading_shimmer.dart
index f22a87062..1b2232e6a 100644
--- a/lib/pangea/analytics_misc/text_loading_shimmer.dart
+++ b/lib/pangea/analytics_misc/text_loading_shimmer.dart
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
class TextLoadingShimmer extends StatelessWidget {
final double width;
@@ -24,8 +25,8 @@ class TextLoadingShimmer extends StatelessWidget {
borderRadius: BorderRadius.circular(4.0),
color: Theme.of(context).colorScheme.primary,
),
- height:
- height ?? (AppConfig.messageFontSize * AppConfig.fontSizeFactor),
+ height: height ??
+ (AppConfig.messageFontSize * AppSettings.fontSizeFactor.value),
width: width,
),
);
diff --git a/lib/pangea/analytics_practice/analytics_practice_view.dart b/lib/pangea/analytics_practice/analytics_practice_view.dart
index 9ada4f9d2..a38c7525f 100644
--- a/lib/pangea/analytics_practice/analytics_practice_view.dart
+++ b/lib/pangea/analytics_practice/analytics_practice_view.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/analytics_details_popup/morph_meaning_widget.dart';
@@ -270,7 +271,8 @@ class _ExampleMessageWidget extends StatelessWidget {
text: TextSpan(
style: TextStyle(
color: Theme.of(context).colorScheme.onPrimaryFixed,
- fontSize: AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
),
children: snapshot.data!,
),
@@ -464,8 +466,8 @@ class _ErrorBlankWidgetState extends State<_ErrorBlankWidget> {
text: TextSpan(
style: TextStyle(
color: Theme.of(context).colorScheme.onPrimaryFixed,
- fontSize:
- AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
),
children: [
if (trimmedBefore) const TextSpan(text: '…'),
@@ -491,7 +493,7 @@ class _ErrorBlankWidgetState extends State<_ErrorBlankWidget> {
translation,
style: TextStyle(
color: Theme.of(context).colorScheme.onPrimaryFixed,
- fontSize: AppConfig.fontSizeFactor *
+ fontSize: AppSettings.fontSizeFactor.value *
AppConfig.messageFontSize,
fontStyle: FontStyle.italic,
),
diff --git a/lib/pangea/bot/utils/bot_style.dart b/lib/pangea/bot/utils/bot_style.dart
index 8007660cf..8c344887a 100644
--- a/lib/pangea/bot/utils/bot_style.dart
+++ b/lib/pangea/bot/utils/bot_style.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
class BotStyle {
@@ -16,7 +17,7 @@ class BotStyle {
final TextStyle botStyle = TextStyle(
fontWeight: bold ? FontWeight.w700 : null,
fontSize: AppConfig.messageFontSize *
- AppConfig.fontSizeFactor *
+ AppSettings.fontSizeFactor.value *
(big == true ? 1.2 : 1),
fontStyle: italics ? FontStyle.italic : null,
color: setColor ? Theme.of(context).colorScheme.primary : null,
diff --git a/lib/pangea/chat/widgets/pangea_chat_input_row.dart b/lib/pangea/chat/widgets/pangea_chat_input_row.dart
index 4606d39bd..62231dfe7 100644
--- a/lib/pangea/chat/widgets/pangea_chat_input_row.dart
+++ b/lib/pangea/chat/widgets/pangea_chat_input_row.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:animations/animations.dart';
-import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
@@ -201,10 +201,11 @@ class PangeaChatInputRow extends StatelessWidget {
maxLines: 8,
autofocus: !PlatformInfos.isMobile,
keyboardType: TextInputType.multiline,
- textInputAction: AppConfig.sendOnEnter == true &&
- PlatformInfos.isMobile
- ? TextInputAction.send
- : null,
+ textInputAction:
+ AppSettings.sendOnEnter.value == true &&
+ PlatformInfos.isMobile
+ ? TextInputAction.send
+ : null,
onSubmitted: (_) => controller.onInputBarSubmitted(),
onSubmitImage: controller.sendImageFromClipBoard,
focusNode: controller.inputFocus,
diff --git a/lib/pangea/chat_list/utils/get_chat_list_item_subtitle.dart b/lib/pangea/chat_list/utils/get_chat_list_item_subtitle.dart
index 3b86069b6..c4440ac5a 100644
--- a/lib/pangea/chat_list/utils/get_chat_list_item_subtitle.dart
+++ b/lib/pangea/chat_list/utils/get_chat_list_item_subtitle.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
-import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
import 'package:fluffychat/pangea/course_chats/open_roles_indicator.dart';
@@ -25,7 +25,9 @@ class ChatListItemSubtitle extends StatelessWidget {
!event.redacted &&
event.type == EventTypes.Message &&
event.messageType == MessageTypes.Text &&
- !(AppConfig.renderHtml && !event.redacted && event.isRichMessage);
+ !(AppSettings.renderHtml.value &&
+ !event.redacted &&
+ event.isRichMessage);
}
Future _getPangeaMessageEvent(
diff --git a/lib/pangea/common/controllers/pangea_controller.dart b/lib/pangea/common/controllers/pangea_controller.dart
index 71a4a5987..0d5fbcdac 100644
--- a/lib/pangea/common/controllers/pangea_controller.dart
+++ b/lib/pangea/common/controllers/pangea_controller.dart
@@ -6,7 +6,6 @@ import 'package:get_storage/get_storage.dart';
import 'package:matrix/matrix.dart';
import 'package:provider/provider.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
-import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
@@ -67,7 +66,7 @@ class PangeaController {
subscriptionController.reinitialize();
StyleSettingsRepo.settings(userID!).then((settings) {
- AppConfig.fontSizeFactor = settings.fontSizeFactor;
+ AppSettings.fontSizeFactor.setItem(settings.fontSizeFactor);
AppConfig.useActivityImageAsChatBackground =
settings.useActivityImageBackground;
});
@@ -136,18 +135,6 @@ class PangeaController {
futures.add(GetStorage(key).erase());
}
- if (AppConfig.showedActivityMenu) {
- futures.add(
- SharedPreferences.getInstance().then((prefs) async {
- AppConfig.showedActivityMenu = false;
- prefs.setBool(
- SettingKeys.showedActivityMenu,
- AppConfig.showedActivityMenu,
- );
- }),
- );
- }
-
await Future.wait(futures);
}
diff --git a/lib/pangea/instructions/instructions_enum.dart b/lib/pangea/instructions/instructions_enum.dart
index a3cecfcdc..10f058054 100644
--- a/lib/pangea/instructions/instructions_enum.dart
+++ b/lib/pangea/instructions/instructions_enum.dart
@@ -35,6 +35,7 @@ enum InstructionsEnum {
dismissSupportChat,
shimmerNewToken,
shimmerTranslation,
+ showedActivityMenu,
}
extension InstructionsEnumExtension on InstructionsEnum {
@@ -69,6 +70,7 @@ extension InstructionsEnumExtension on InstructionsEnum {
case InstructionsEnum.dismissSupportChat:
case InstructionsEnum.shimmerNewToken:
case InstructionsEnum.shimmerTranslation:
+ case InstructionsEnum.showedActivityMenu:
ErrorHandler.logError(
e: Exception("No title for this instruction"),
m: 'InstructionsEnumExtension.title',
@@ -133,6 +135,7 @@ extension InstructionsEnumExtension on InstructionsEnum {
case InstructionsEnum.dismissSupportChat:
case InstructionsEnum.shimmerNewToken:
case InstructionsEnum.shimmerTranslation:
+ case InstructionsEnum.showedActivityMenu:
return "";
case InstructionsEnum.disableLanguageTools:
return l10n.disableLanguageToolsDesc;
diff --git a/lib/pangea/login/pages/login_or_signup_view.dart b/lib/pangea/login/pages/login_or_signup_view.dart
index b0b8086c4..d4b078e1e 100644
--- a/lib/pangea/login/pages/login_or_signup_view.dart
+++ b/lib/pangea/login/pages/login_or_signup_view.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
-import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/common/config/environment.dart';
import 'package:fluffychat/pangea/common/widgets/pangea_logo_svg.dart';
@@ -78,7 +78,7 @@ class LoginOrSignupViewState extends State {
forceColor: theme.colorScheme.onSurface,
),
Text(
- AppConfig.applicationName,
+ AppSettings.applicationName.value,
style: theme.textTheme.headlineSmall
?.copyWith(fontWeight: FontWeight.bold),
),
diff --git a/lib/pangea/login/pages/pangea_login_scaffold.dart b/lib/pangea/login/pages/pangea_login_scaffold.dart
index af1fc603a..31c32efd4 100644
--- a/lib/pangea/login/pages/pangea_login_scaffold.dart
+++ b/lib/pangea/login/pages/pangea_login_scaffold.dart
@@ -2,7 +2,7 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
-import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
@@ -84,7 +84,7 @@ class PangeaLoginScaffold extends StatelessWidget {
),
if (showAppName)
Text(
- AppConfig.applicationName,
+ AppSettings.applicationName.value,
style: Theme.of(context).textTheme.displaySmall,
),
const SizedBox(height: 12),
diff --git a/lib/pangea/space_analytics/download_space_analytics_dialog.dart b/lib/pangea/space_analytics/download_space_analytics_dialog.dart
index 5a783a918..cae1175f3 100644
--- a/lib/pangea/space_analytics/download_space_analytics_dialog.dart
+++ b/lib/pangea/space_analytics/download_space_analytics_dialog.dart
@@ -6,6 +6,7 @@ import 'package:excel/excel.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/analytics_downloads/space_analytics_summary_enum.dart';
@@ -289,7 +290,8 @@ class DownloadAnalyticsDialogState extends State {
Text(
L10n.of(context).fileType,
style: TextStyle(
- fontSize: AppConfig.fontSizeFactor * AppConfig.messageFontSize,
+ fontSize: AppSettings.fontSizeFactor.value *
+ AppConfig.messageFontSize,
),
),
Padding(
diff --git a/lib/pangea/spaces/space_navigation_column.dart b/lib/pangea/spaces/space_navigation_column.dart
index b6d630870..9cac6b7c6 100644
--- a/lib/pangea/spaces/space_navigation_column.dart
+++ b/lib/pangea/spaces/space_navigation_column.dart
@@ -183,7 +183,7 @@ class _MainView extends StatelessWidget {
if (path == null) {
return ChatList(
activeChat: state.pathParameters['roomid'],
- activeSpaceId: state.pathParameters['spaceid'],
+ activeSpace: state.pathParameters['spaceid'],
);
}
@@ -220,7 +220,7 @@ class _MainView extends StatelessWidget {
return ChatList(
activeChat: state.pathParameters['roomid'],
- activeSpaceId: state.pathParameters['spaceid'],
+ activeSpace: state.pathParameters['spaceid'],
);
}
}
diff --git a/lib/pangea/toolbar/layout/message_selection_positioner.dart b/lib/pangea/toolbar/layout/message_selection_positioner.dart
index 5d9f2fe16..fc8a90463 100644
--- a/lib/pangea/toolbar/layout/message_selection_positioner.dart
+++ b/lib/pangea/toolbar/layout/message_selection_positioner.dart
@@ -154,7 +154,7 @@ class MessageSelectionPositionerState extends State
widget.event.senderId == widget.event.room.client.userID;
bool get showDetails =>
- AppSettings.displayChatDetailsColumn.getItem(Matrix.of(context).store) &&
+ AppSettings.displayChatDetailsColumn.value &&
FluffyThemes.isThreeColumnMode(context) &&
widget.chatController.room.membership == Membership.join;
diff --git a/lib/pangea/toolbar/message_practice/message_audio_card.dart b/lib/pangea/toolbar/message_practice/message_audio_card.dart
index 6a3661b61..cfc0bc204 100644
--- a/lib/pangea/toolbar/message_practice/message_audio_card.dart
+++ b/lib/pangea/toolbar/message_practice/message_audio_card.dart
@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/pages/chat/events/audio_player.dart';
import 'package:fluffychat/pangea/analytics_misc/text_loading_shimmer.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
@@ -79,8 +80,8 @@ class MessageAudioCardState extends State {
senderId: widget.messageEvent.senderId,
matrixFile: audioFile,
color: Theme.of(context).colorScheme.onPrimaryContainer,
- fontSize:
- AppConfig.messageFontSize * AppConfig.fontSizeFactor,
+ fontSize: AppConfig.messageFontSize *
+ AppSettings.fontSizeFactor.value,
linkColor: Theme.of(context).brightness == Brightness.light
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onPrimary,
diff --git a/lib/utils/background_push.dart b/lib/utils/background_push.dart
index 2bec4ecf2..31fd338ba 100644
--- a/lib/utils/background_push.dart
+++ b/lib/utils/background_push.dart
@@ -69,6 +69,7 @@ class BackgroundPush {
}
final pendingTests = >{};
+ bool firebaseEnabled = false;
//final firebase = FcmSharedIsolate();
@@ -77,6 +78,7 @@ class BackgroundPush {
bool upAction = false;
void _init() async {
+ //firebaseEnabled = true;
try {
// #Pangea
// Handle notifications when app is opened from terminated/background state
@@ -346,8 +348,7 @@ class BackgroundPush {
currentPushers.first.data.url.toString() == gatewayUrl &&
currentPushers.first.data.format ==
// #Pangea
- // AppSettings.pushNotificationsPusherFormat
- // .getItem(matrix!.store) &&
+ // AppSettings.pushNotificationsPusherFormat.value &&
null &&
// Pangea#
mapEquals(
@@ -393,8 +394,7 @@ class BackgroundPush {
data: PusherData(
url: Uri.parse(gatewayUrl!),
// #Pangea
- // format: AppSettings.pushNotificationsPusherFormat
- // .getItem(matrix!.store),
+ // format: AppSettings.pushNotificationsPusherFormat.value,
// Pangea#
additionalProperties: {"data_message": pusherDataMessageFormat},
),
@@ -468,7 +468,7 @@ class BackgroundPush {
if (matrix == null) {
return;
}
- if ((matrix?.store.getBool(SettingKeys.showNoGoogle) ?? false) == true) {
+ if (!AppSettings.showNoGoogle.value) {
return;
}
await loadLocale();
@@ -499,15 +499,19 @@ class BackgroundPush {
}
}
await setupPusher(
- gatewayUrl:
- AppSettings.pushNotificationsGatewayUrl.getItem(matrix!.store),
+ gatewayUrl: AppSettings.pushNotificationsGatewayUrl.value,
token: _fcmToken,
);
}
Future setupUp() async {
- await UnifiedPushUi(matrix!.context, ["default"], UPFunctions())
- .registerAppWithDialog();
+ await UnifiedPushUi(
+ context: matrix!.context,
+ instances: ["default"],
+ unifiedPushFunctions: UPFunctions(),
+ showNoDistribDialog: false,
+ onNoDistribDialogDismissed: () {}, // TODO: Implement me
+ ).registerAppWithDialog();
}
Future _newUpEndpoint(PushEndpoint newPushEndpoint, String i) async {
@@ -552,18 +556,18 @@ class BackgroundPush {
oldTokens: oldTokens,
useDeviceSpecificAppId: true,
);
- await matrix?.store.setString(SettingKeys.unifiedPushEndpoint, newEndpoint);
- await matrix?.store.setBool(SettingKeys.unifiedPushRegistered, true);
+ await AppSettings.unifiedPushEndpoint.setItem(newEndpoint);
+ await AppSettings.unifiedPushRegistered.setItem(true);
}
Future _upUnregistered(String i) async {
upAction = true;
Logs().i('[Push] Removing UnifiedPush endpoint...');
- final oldEndpoint =
- matrix?.store.getString(SettingKeys.unifiedPushEndpoint);
- await matrix?.store.setBool(SettingKeys.unifiedPushRegistered, false);
- await matrix?.store.remove(SettingKeys.unifiedPushEndpoint);
- if (oldEndpoint?.isNotEmpty ?? false) {
+ final oldEndpoint = AppSettings.unifiedPushEndpoint.value;
+ await AppSettings.unifiedPushEndpoint
+ .setItem(AppSettings.unifiedPushEndpoint.defaultValue);
+ await AppSettings.unifiedPushRegistered.setItem(false);
+ if (oldEndpoint.isNotEmpty) {
// remove the old pusher
await setupPusher(
oldTokens: {oldEndpoint},
diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart
index f498ddf8d..f4872c60c 100644
--- a/lib/utils/client_manager.dart
+++ b/lib/utils/client_manager.dart
@@ -11,7 +11,6 @@ import 'package:matrix/matrix.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:universal_html/html.dart' as html;
-import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
@@ -109,8 +108,8 @@ abstract class ClientManager {
String clientName,
SharedPreferences store,
) async {
- final shareKeysWith = AppSettings.shareKeysWith.getItem(store);
- final enableSoftLogout = AppSettings.enableSoftLogout.getItem(store);
+ final shareKeysWith = AppSettings.shareKeysWith.value;
+ final enableSoftLogout = AppSettings.enableSoftLogout.value;
return Client(
clientName,
@@ -185,7 +184,7 @@ abstract class ClientManager {
await NotificationsClient().notify(
title,
body: body,
- appName: AppConfig.applicationName,
+ appName: AppSettings.applicationName.value,
hints: [
NotificationHint.soundName('message-new-instant'),
],
diff --git a/lib/utils/init_with_restore.dart b/lib/utils/init_with_restore.dart
index 523b22f9e..feb95e003 100644
--- a/lib/utils/init_with_restore.dart
+++ b/lib/utils/init_with_restore.dart
@@ -5,6 +5,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/platform_infos.dart';
@@ -57,13 +58,13 @@ extension InitWithRestoreExtension on Client {
? const FlutterSecureStorage()
: null;
await storage?.delete(
- key: '${AppConfig.applicationName}_session_backup_$clientName',
+ key: '${AppSettings.applicationName.value}_session_backup_$clientName',
);
}
Future initWithRestore({void Function()? onMigration}) async {
final storageKey =
- '${AppConfig.applicationName}_session_backup_$clientName';
+ '${AppSettings.applicationName.value}_session_backup_$clientName';
final storage = PlatformInfos.isMobile || PlatformInfos.isLinux
? const FlutterSecureStorage()
: null;
diff --git a/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart b/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart
index e5f07543b..4df40fc0c 100644
--- a/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart
+++ b/lib/utils/matrix_sdk_extensions/filtered_timeline_extension.dart
@@ -1,13 +1,16 @@
import 'package:matrix/matrix.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart';
-import '../../config/app_config.dart';
extension VisibleInGuiExtension on List {
- List filterByVisibleInGui({String? exceptionEventId}) => where(
+ List filterByVisibleInGui({
+ String? exceptionEventId,
+ }) =>
+ where(
// #Pangea
// (event) => event.isVisibleInGui || event.eventId == exceptionEventId,
(event) =>
@@ -28,18 +31,16 @@ extension IsStateExtension on Event {
// if a reaction has been redacted we also want it to be hidden in the timeline
!{EventTypes.Reaction, EventTypes.Redaction}.contains(type) &&
// if we enabled to hide all redacted events, don't show those
- (!AppConfig.hideRedactedEvents || !redacted) &&
+ (!AppSettings.hideRedactedEvents.value || !redacted) &&
// if we enabled to hide all unknown events, don't show those
// #Pangea
- // (!AppConfig.hideUnknownEvents || isEventTypeKnown);
- (!AppConfig.hideUnknownEvents || pangeaIsEventTypeKnown) &&
- (!isState || importantStateEvents.contains(type)) &&
+ // (!AppSettings.hideUnknownEvents.value || isEventTypeKnown);
+ (!AppSettings.hideUnknownEvents.value || pangeaIsEventTypeKnown) &&
content.tryGet(ModelKey.transcription) == null &&
- // if sending of transcription fails,
- // don't show it as a errored audio event in timeline.
((unsigned?['extra_content']
as Map?)?[ModelKey.transcription] ==
- null);
+ null) &&
+ (!isState || importantStateEvents.contains(type));
// Pangea#
bool get isState => !{
@@ -74,6 +75,7 @@ extension IsStateExtension on Event {
PangeaEventTypes.activityRole,
].contains(type);
+ // we're filtering out some state events that we don't want to render
static const Set importantStateEvents = {
EventTypes.Encryption,
EventTypes.RoomCreate,
diff --git a/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/cipher.dart b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/cipher.dart
index 4c3296c86..70f8d8072 100644
--- a/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/cipher.dart
+++ b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/cipher.dart
@@ -6,7 +6,6 @@ import 'package:flutter/services.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:matrix/matrix.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
-import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluffychat/config/setting_keys.dart';
@@ -89,8 +88,7 @@ Future getDatabaseCipher() async {
}
void _sendNoEncryptionWarning(Object exception) async {
- final store = await SharedPreferences.getInstance();
- final isStored = AppSettings.noEncryptionWarningShown.getItem(store);
+ final isStored = AppSettings.noEncryptionWarningShown.value;
if (isStored == true) return;
@@ -108,5 +106,5 @@ void _sendNoEncryptionWarning(Object exception) async {
// );
// Pangea#
- await AppSettings.noEncryptionWarningShown.setItem(store, true);
+ await AppSettings.noEncryptionWarningShown.setItem(true);
}
diff --git a/lib/utils/notification_background_handler.dart b/lib/utils/notification_background_handler.dart
index 531d7e19d..aa8ea17dd 100644
--- a/lib/utils/notification_background_handler.dart
+++ b/lib/utils/notification_background_handler.dart
@@ -6,7 +6,6 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_vodozemac/flutter_vodozemac.dart' as vod;
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
-import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/client_download_content_extension.dart';
@@ -59,7 +58,7 @@ void notificationTapBackground(
await vod.init();
_vodInitialized = true;
}
- final store = await SharedPreferences.getInstance();
+ final store = await AppSettings.init();
final client = (await ClientManager.getClients(
initialize: false,
store: store,
@@ -71,10 +70,6 @@ void notificationTapBackground(
waitUntilLoadCompletedLoaded: false,
);
- AppConfig.sendPublicReadReceipts =
- store.getBool(SettingKeys.sendPublicReadReceipts) ??
- AppConfig.sendPublicReadReceipts;
-
if (!client.isLogged()) {
throw Exception('Notification tab in background but not logged in!');
}
@@ -145,7 +140,7 @@ Future notificationTap(
await room.setReadMarker(
payload.eventId ?? room.lastEvent!.eventId,
mRead: payload.eventId ?? room.lastEvent!.eventId,
- public: AppConfig.sendPublicReadReceipts,
+ public: AppSettings.sendPublicReadReceipts.value,
);
case FluffyChatNotificationActions.reply:
final input = notificationResponse.input;
diff --git a/lib/utils/platform_infos.dart b/lib/utils/platform_infos.dart
index 4913c1fe5..e80af37e6 100644
--- a/lib/utils/platform_infos.dart
+++ b/lib/utils/platform_infos.dart
@@ -8,6 +8,7 @@ import 'package:package_info_plus/package_info_plus.dart';
import 'package:universal_html/html.dart' as html;
import 'package:url_launcher/url_launcher_string.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import '../config/app_config.dart';
@@ -46,7 +47,7 @@ abstract class PlatformInfos {
// Pangea#
static String get clientName =>
- '${AppConfig.applicationName} ${isWeb ? 'web' : Platform.operatingSystem}${kReleaseMode ? '' : 'Debug'}';
+ '${AppSettings.applicationName.value} ${isWeb ? 'web' : Platform.operatingSystem}${kReleaseMode ? '' : 'Debug'}';
static Future getVersion() async {
var version = kIsWeb ? 'Web' : 'Unknown';
@@ -101,7 +102,7 @@ abstract class PlatformInfos {
height: 64,
filterQuality: FilterQuality.medium,
),
- applicationName: AppConfig.applicationName,
+ applicationName: AppSettings.applicationName.value,
);
}
diff --git a/lib/utils/push_helper.dart b/lib/utils/push_helper.dart
index 8854eb629..82f49441a 100644
--- a/lib/utils/push_helper.dart
+++ b/lib/utils/push_helper.dart
@@ -8,9 +8,9 @@ import 'package:collection/collection.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_shortcuts_new/flutter_shortcuts_new.dart';
import 'package:matrix/matrix.dart';
-import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/utils/client_download_content_extension.dart';
@@ -60,7 +60,7 @@ Future pushHelper(
l10n.incomingMessages,
number: notification.counts?.unread,
ticker: l10n.unreadChatsInApp(
- AppConfig.applicationName,
+ AppSettings.applicationName.value,
(notification.counts?.unread ?? 0).toString(),
),
importance: Importance.high,
@@ -98,7 +98,7 @@ Future _tryPushHelper(
client ??= (await ClientManager.getClients(
initialize: false,
- store: await SharedPreferences.getInstance(),
+ store: await AppSettings.init(),
))
.first;
final event = await client.getEventByPushNotification(
@@ -300,25 +300,27 @@ Future _tryPushHelper(
importance: Importance.high,
priority: Priority.max,
groupKey: event.room.spaceParents.firstOrNull?.roomId ?? 'rooms',
- actions: [
- AndroidNotificationAction(
- FluffyChatNotificationActions.reply.name,
- l10n.reply,
- inputs: [
- AndroidNotificationActionInput(
- label: l10n.writeAMessage,
- ),
- ],
- cancelNotification: false,
- allowGeneratedReplies: true,
- semanticAction: SemanticAction.reply,
- ),
- AndroidNotificationAction(
- FluffyChatNotificationActions.markAsRead.name,
- l10n.markAsRead,
- semanticAction: SemanticAction.markAsRead,
- ),
- ],
+ actions: event.type == EventTypes.RoomMember
+ ? null
+ : [
+ AndroidNotificationAction(
+ FluffyChatNotificationActions.reply.name,
+ l10n.reply,
+ inputs: [
+ AndroidNotificationActionInput(
+ label: l10n.writeAMessage,
+ ),
+ ],
+ cancelNotification: false,
+ allowGeneratedReplies: true,
+ semanticAction: SemanticAction.reply,
+ ),
+ AndroidNotificationAction(
+ FluffyChatNotificationActions.markAsRead.name,
+ l10n.markAsRead,
+ semanticAction: SemanticAction.markAsRead,
+ ),
+ ],
);
const iOSPlatformChannelSpecifics = DarwinNotificationDetails();
final platformChannelSpecifics = NotificationDetails(
diff --git a/lib/widgets/adaptive_dialogs/public_room_dialog.dart b/lib/widgets/adaptive_dialogs/public_room_dialog.dart
index 09e125613..6b11d45c9 100644
--- a/lib/widgets/adaptive_dialogs/public_room_dialog.dart
+++ b/lib/widgets/adaptive_dialogs/public_room_dialog.dart
@@ -30,7 +30,9 @@ class PublicRoomDialog extends StatelessWidget {
final result = await showFutureLoadingDialog(
context: context,
future: () async {
- if (chunk != null && client.getRoomById(chunk.roomId) != null) {
+ if (chunk != null &&
+ client.getRoomById(chunk.roomId) != null &&
+ client.getRoomById(chunk.roomId)?.membership != Membership.leave) {
return chunk.roomId;
}
final roomId = chunk != null && knock
@@ -64,6 +66,8 @@ class PublicRoomDialog extends StatelessWidget {
if (chunk?.roomType != 'm.space' &&
!client.getRoomById(result.result!)!.isSpace) {
context.go('/rooms/$roomId');
+ } else {
+ context.go('/rooms?spaceId=$roomId');
}
return;
}
diff --git a/lib/widgets/adaptive_dialogs/show_text_input_dialog.dart b/lib/widgets/adaptive_dialogs/show_text_input_dialog.dart
index cba2d7247..475e3bd81 100644
--- a/lib/widgets/adaptive_dialogs/show_text_input_dialog.dart
+++ b/lib/widgets/adaptive_dialogs/show_text_input_dialog.dart
@@ -89,7 +89,6 @@ Future showTextInputDialog({
// Pangea#
maxLength: maxLength,
keyboardType: keyboardType,
- obscureText: obscureText,
);
},
),
diff --git a/lib/widgets/app_lock.dart b/lib/widgets/app_lock.dart
index d337358d7..c4682d9f4 100644
--- a/lib/widgets/app_lock.dart
+++ b/lib/widgets/app_lock.dart
@@ -4,7 +4,6 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:matrix/matrix.dart';
import 'package:provider/provider.dart';
-import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/widgets/lock_screen.dart';
class AppLockWidget extends StatefulWidget {
@@ -65,7 +64,7 @@ class AppLock extends State with WidgetsBindingObserver {
Future changePincode(String? pincode) async {
await const FlutterSecureStorage().write(
- key: SettingKeys.appLockKey,
+ key: 'chat.fluffy.app_lock',
value: pincode,
);
_pincode = pincode;
diff --git a/lib/widgets/avatar.dart b/lib/widgets/avatar.dart
index 4355f53db..995a15b9a 100644
--- a/lib/widgets/avatar.dart
+++ b/lib/widgets/avatar.dart
@@ -21,6 +21,8 @@ class Avatar extends StatelessWidget {
final BorderRadius? borderRadius;
final IconData? icon;
final BorderSide? border;
+ final Color? backgroundColor;
+ final Color? textColor;
// #Pangea
final bool useRive;
final bool showPresence;
@@ -42,6 +44,8 @@ class Avatar extends StatelessWidget {
this.borderRadius,
this.border,
this.icon,
+ this.backgroundColor,
+ this.textColor,
// #Pangea
this.useRive = false,
this.showPresence = true,
@@ -80,7 +84,6 @@ class Avatar extends StatelessWidget {
side: border ?? BorderSide.none,
),
clipBehavior: Clip.antiAlias,
- // #Pangea
// child: MxcImage(
child: (userId ?? presenceUserId) == BotName.byEnvironment
? BotFace(
@@ -88,6 +91,7 @@ class Avatar extends StatelessWidget {
expression: BotExpression.idle,
useRive: useRive,
)
+ // #Pangea
: !(mxContent.toString().startsWith('mxc://'))
? ImageByUrl(
imageUrl: mxContent,
@@ -101,6 +105,7 @@ class Avatar extends StatelessWidget {
),
borderRadius: borderRadius,
)
+ // Pangea#
: MxcImage(
// Pangea#
client: client,
@@ -114,7 +119,8 @@ class Avatar extends StatelessWidget {
placeholder: (_) => noPic
? Container(
decoration: BoxDecoration(
- color: name?.lightColorAvatar,
+ color:
+ backgroundColor ?? name?.lightColorAvatar,
),
alignment: Alignment.center,
child: Text(
@@ -122,7 +128,7 @@ class Avatar extends StatelessWidget {
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'RobotoMono',
- color: Colors.white,
+ color: textColor ?? Colors.white,
fontWeight: FontWeight.bold,
fontSize: (size / 2.5).roundToDouble(),
),
diff --git a/lib/widgets/config_viewer.dart b/lib/widgets/config_viewer.dart
index adfb34407..b0537317c 100644
--- a/lib/widgets/config_viewer.dart
+++ b/lib/widgets/config_viewer.dart
@@ -21,7 +21,7 @@ class _ConfigViewerState extends State {
String initialValue,
) async {
if (appSetting is AppSettings) {
- await appSetting.setItem(store, !(initialValue == 'true'));
+ await appSetting.setItem(!(initialValue == 'true'));
setState(() {});
return;
}
@@ -35,13 +35,13 @@ class _ConfigViewerState extends State {
if (value == null) return;
if (appSetting is AppSettings) {
- await appSetting.setItem(store, value);
+ await appSetting.setItem(value);
}
if (appSetting is AppSettings) {
- await appSetting.setItem(store, int.parse(value));
+ await appSetting.setItem(int.parse(value));
}
if (appSetting is AppSettings) {
- await appSetting.setItem(store, double.parse(value));
+ await appSetting.setItem(double.parse(value));
}
setState(() {});
@@ -78,16 +78,16 @@ class _ConfigViewerState extends State {
final appSetting = AppSettings.values[i];
var value = '';
if (appSetting is AppSettings) {
- value = appSetting.getItem(store);
+ value = appSetting.value;
}
if (appSetting is AppSettings) {
- value = appSetting.getItem(store).toString();
+ value = appSetting.value.toString();
}
if (appSetting is AppSettings) {
- value = appSetting.getItem(store).toString();
+ value = appSetting.value.toString();
}
if (appSetting is AppSettings) {
- value = appSetting.getItem(store).toString();
+ value = appSetting.value.toString();
}
return ListTile(
title: Text(appSetting.name),
diff --git a/lib/widgets/fluffy_chat_app.dart b/lib/widgets/fluffy_chat_app.dart
index aa773d5d5..c89916511 100644
--- a/lib/widgets/fluffy_chat_app.dart
+++ b/lib/widgets/fluffy_chat_app.dart
@@ -8,13 +8,13 @@ import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluffychat/config/routes.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/common/utils/firebase_analytics.dart';
import 'package:fluffychat/pangea/languages/locale_provider.dart';
import 'package:fluffychat/widgets/app_lock.dart';
import 'package:fluffychat/widgets/theme_builder.dart';
-import '../config/app_config.dart';
import '../utils/custom_scroll_behaviour.dart';
import 'matrix.dart';
@@ -53,7 +53,7 @@ class FluffyChatApp extends StatelessWidget {
Widget build(BuildContext context) {
return ThemeBuilder(
builder: (context, themeMode, primaryColor) => MaterialApp.router(
- title: AppConfig.applicationName,
+ title: AppSettings.applicationName.value,
themeMode: themeMode,
theme: FluffyThemes.buildTheme(context, Brightness.light, primaryColor),
darkTheme:
diff --git a/lib/widgets/layouts/login_scaffold.dart b/lib/widgets/layouts/login_scaffold.dart
index 963315e5e..9060eace4 100644
--- a/lib/widgets/layouts/login_scaffold.dart
+++ b/lib/widgets/layouts/login_scaffold.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
+import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:fluffychat/config/app_config.dart';
@@ -132,7 +133,7 @@ class _PrivacyButtons extends StatelessWidget {
),
),
TextButton(
- onPressed: () => launchUrlString(AppConfig.privacyUrl),
+ onPressed: () => launchUrl(AppConfig.privacyUrl),
child: Text(
L10n.of(context).privacy,
style: shadowTextStyle,
diff --git a/lib/widgets/local_notifications_extension.dart b/lib/widgets/local_notifications_extension.dart
index 3036a92d2..87e17f40d 100644
--- a/lib/widgets/local_notifications_extension.dart
+++ b/lib/widgets/local_notifications_extension.dart
@@ -11,6 +11,7 @@ import 'package:permission_handler/permission_handler.dart';
import 'package:universal_html/html.dart' as html;
import 'package:fluffychat/config/app_config.dart';
+import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/utils/client_download_content_extension.dart';
@@ -122,7 +123,7 @@ extension LocalNotificationsExtension on MatrixState {
title,
body: body,
replacesId: linuxNotificationIds[roomId] ?? 0,
- appName: AppConfig.applicationName,
+ appName: AppSettings.applicationName.value,
appIcon: 'fluffychat',
actions: [
NotificationAction(
@@ -147,7 +148,7 @@ extension LocalNotificationsExtension on MatrixState {
event.room.setReadMarker(
event.eventId,
mRead: event.eventId,
- public: AppConfig.sendPublicReadReceipts,
+ public: AppSettings.sendPublicReadReceipts.value,
);
break;
case DesktopNotificationActions.openChat:
diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart
index 96698dec2..3c07dfdc4 100644
--- a/lib/widgets/matrix.dart
+++ b/lib/widgets/matrix.dart
@@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
import 'package:app_links/app_links.dart';
import 'package:collection/collection.dart';
import 'package:desktop_notifications/desktop_notifications.dart';
-import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:just_audio/just_audio.dart';
@@ -19,13 +18,13 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:universal_html/html.dart' as html;
import 'package:url_launcher/url_launcher_string.dart';
+import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/analytics_data/analytics_data_service.dart';
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/common/utils/any_state_holder.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/languages/locale_provider.dart';
-import 'package:fluffychat/pangea/user/style_settings_repo.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart';
import 'package:fluffychat/utils/platform_infos.dart';
@@ -34,7 +33,6 @@ import 'package:fluffychat/utils/voip_plugin.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/fluffy_chat_app.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
-import '../config/app_config.dart';
import '../config/setting_keys.dart';
import '../pages/key_verification/key_verification_dialog.dart';
import '../utils/account_bundles.dart';
@@ -192,7 +190,7 @@ class MatrixState extends State with WidgetsBindingObserver {
}
final candidate =
_loginClientCandidate ??= await ClientManager.createClient(
- '${AppConfig.applicationName}-${DateTime.now().millisecondsSinceEpoch}',
+ '${AppSettings.applicationName.value}-${DateTime.now().millisecondsSinceEpoch}',
store,
)
..onLoginStateChanged
@@ -283,11 +281,6 @@ class MatrixState extends State with WidgetsBindingObserver {
super.initState();
WidgetsBinding.instance.addObserver(this);
initMatrix();
- if (PlatformInfos.isWeb) {
- initConfig().then((_) => initSettings());
- } else {
- initSettings();
- }
// #Pangea
Sentry.configureScope(
(scope) => scope.setUser(
@@ -369,19 +362,6 @@ class MatrixState extends State with WidgetsBindingObserver {
}
// Pangea#
- Future initConfig() async {
- try {
- final configJsonString =
- utf8.decode((await http.get(Uri.parse('config.json'))).bodyBytes);
- final configJson = json.decode(configJsonString);
- AppConfig.loadFromJson(configJson);
- } on FormatException catch (_) {
- Logs().v('[ConfigLoader] config.json not found');
- } catch (e) {
- Logs().v('[ConfigLoader] config.json not found', e);
- }
- }
-
void _registerSubs(String name) {
final c = getClientByName(name);
if (c == null) {
@@ -528,7 +508,7 @@ class MatrixState extends State with WidgetsBindingObserver {
);
}
if (result == OkCancelResult.cancel) {
- await store.setBool(SettingKeys.showNoGoogle, true);
+ await AppSettings.showNoGoogle.setItem(true);
}
},
);
@@ -538,7 +518,7 @@ class MatrixState extends State with WidgetsBindingObserver {
}
void createVoipPlugin() async {
- if (store.getBool(SettingKeys.experimentalVoip) == false) {
+ if (AppSettings.experimentalVoip.value) {
voipPlugin = null;
return;
}
@@ -560,72 +540,6 @@ class MatrixState extends State with WidgetsBindingObserver {
}
}
- void initSettings() {
- // #Pangea
- // AppConfig.fontSizeFactor =
- // double.tryParse(store.getString(SettingKeys.fontSizeFactor) ?? '') ??
- // AppConfig.fontSizeFactor;
- if (client.isLogged()) {
- StyleSettingsRepo.settings(client.userID!).then((settings) {
- AppConfig.fontSizeFactor = settings.fontSizeFactor;
- AppConfig.useActivityImageAsChatBackground =
- settings.useActivityImageBackground;
- });
- }
- // Pangea#
-
- AppConfig.renderHtml =
- store.getBool(SettingKeys.renderHtml) ?? AppConfig.renderHtml;
-
- AppConfig.swipeRightToLeftToReply =
- store.getBool(SettingKeys.swipeRightToLeftToReply) ??
- AppConfig.swipeRightToLeftToReply;
-
- AppConfig.hideRedactedEvents =
- store.getBool(SettingKeys.hideRedactedEvents) ??
- AppConfig.hideRedactedEvents;
-
- AppConfig.hideUnknownEvents =
- store.getBool(SettingKeys.hideUnknownEvents) ??
- AppConfig.hideUnknownEvents;
-
- AppConfig.separateChatTypes =
- store.getBool(SettingKeys.separateChatTypes) ??
- AppConfig.separateChatTypes;
-
- AppConfig.autoplayImages =
- store.getBool(SettingKeys.autoplayImages) ?? AppConfig.autoplayImages;
-
- AppConfig.sendTypingNotifications =
- store.getBool(SettingKeys.sendTypingNotifications) ??
- AppConfig.sendTypingNotifications;
-
- AppConfig.sendPublicReadReceipts =
- store.getBool(SettingKeys.sendPublicReadReceipts) ??
- AppConfig.sendPublicReadReceipts;
-
- AppConfig.sendOnEnter =
- store.getBool(SettingKeys.sendOnEnter) ?? AppConfig.sendOnEnter;
-
- AppConfig.experimentalVoip = store.getBool(SettingKeys.experimentalVoip) ??
- AppConfig.experimentalVoip;
-
- AppConfig.showPresences =
- store.getBool(SettingKeys.showPresences) ?? AppConfig.showPresences;
-
- AppConfig.displayNavigationRail =
- store.getBool(SettingKeys.displayNavigationRail) ??
- AppConfig.displayNavigationRail;
-
- // #Pangea
- AppConfig.volume = store.getDouble(SettingKeys.volume) ?? AppConfig.volume;
-
- AppConfig.showedActivityMenu =
- store.getBool(SettingKeys.showedActivityMenu) ??
- AppConfig.showedActivityMenu;
- // Pangea#
- }
-
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
diff --git a/lib/widgets/navigation_rail.dart b/lib/widgets/navigation_rail.dart
index 3fc977dee..fc2ee8381 100644
--- a/lib/widgets/navigation_rail.dart
+++ b/lib/widgets/navigation_rail.dart
@@ -73,15 +73,8 @@ class SpacesNavigationRail extends StatelessWidget {
.where((s) => s.hasRoomUpdate)
.rateLimit(const Duration(seconds: 1)),
builder: (context, _) {
- final allSpaces = client.rooms.where((room) => room.isSpace);
- final rootSpaces = allSpaces
- .where(
- (space) => !allSpaces.any(
- (parentSpace) => parentSpace.spaceChildren
- .any((child) => child.roomId == space.id),
- ),
- )
- .toList();
+ final allSpaces =
+ client.rooms.where((room) => room.isSpace).toList();
// #Pangea
// return SizedBox(
@@ -99,8 +92,8 @@ class SpacesNavigationRail extends StatelessWidget {
child: ListView.builder(
scrollDirection: Axis.vertical,
// #Pangea
- // itemCount: rootSpaces.length + 2,
- itemCount: rootSpaces.length + 3,
+ // itemCount: allSpaces.length + 2,
+ itemCount: allSpaces.length + 3,
// Pangea#
itemBuilder: (context, i) {
// #Pangea
@@ -189,7 +182,7 @@ class SpacesNavigationRail extends StatelessWidget {
);
}
i--;
- if (i == rootSpaces.length) {
+ if (i == allSpaces.length) {
return NaviRailItem(
// #Pangea
// isSelected: false,
@@ -226,9 +219,9 @@ class SpacesNavigationRail extends StatelessWidget {
// Pangea#
);
}
- final space = rootSpaces[i];
+ final space = allSpaces[i];
final displayname =
- rootSpaces[i].getLocalizedDisplayname(
+ allSpaces[i].getLocalizedDisplayname(
MatrixLocals(L10n.of(context)),
);
final spaceChildrenIds =
@@ -239,10 +232,10 @@ class SpacesNavigationRail extends StatelessWidget {
// #Pangea
backgroundColor: Colors.transparent,
borderRadius: BorderRadius.circular(0),
- // onTap: () => onGoToSpaceId(rootSpaces[i].id),
+ // onTap: () => onGoToSpaceId(allSpaces[i].id),
onTap: () {
collapse();
- final room = client.getRoomById(rootSpaces[i].id);
+ final room = client.getRoomById(allSpaces[i].id);
if (room != null) {
chatListHandleSpaceTap(
context,
@@ -250,7 +243,7 @@ class SpacesNavigationRail extends StatelessWidget {
);
} else {
context.go(
- "/rooms/spaces/${rootSpaces[i].id}/details",
+ "/rooms/spaces/${allSpaces[i].id}/details",
);
}
},
@@ -259,7 +252,7 @@ class SpacesNavigationRail extends StatelessWidget {
spaceChildrenIds.contains(room.id),
// #Pangea
// icon: Avatar(
- // mxContent: rootSpaces[i].avatar,
+ // mxContent: allSpaces[i].avatar,
// name: displayname,
// border: BorderSide(
// width: 1,
@@ -271,7 +264,7 @@ class SpacesNavigationRail extends StatelessWidget {
// ),
icon: b.Badge(
showBadge:
- rootSpaces[i].membership == Membership.invite,
+ allSpaces[i].membership == Membership.invite,
badgeStyle: b.BadgeStyle(
badgeColor: Theme.of(context).colorScheme.error,
elevation: 4,
@@ -290,7 +283,7 @@ class SpacesNavigationRail extends StatelessWidget {
child: ClipPath(
clipper: MapClipper(),
child: Avatar(
- mxContent: rootSpaces[i].avatar,
+ mxContent: allSpaces[i].avatar,
name: displayname,
border: BorderSide(
width: 1,
diff --git a/lib/widgets/settings_switch_list_tile.dart b/lib/widgets/settings_switch_list_tile.dart
index f49b97598..f625f9e64 100644
--- a/lib/widgets/settings_switch_list_tile.dart
+++ b/lib/widgets/settings_switch_list_tile.dart
@@ -1,18 +1,16 @@
import 'package:flutter/material.dart';
-import 'matrix.dart';
+import 'package:fluffychat/config/setting_keys.dart';
class SettingsSwitchListTile extends StatefulWidget {
- final bool defaultValue;
- final String storeKey;
+ final AppSettings setting;
final String title;
final String? subtitle;
final Function(bool)? onChanged;
const SettingsSwitchListTile.adaptive({
super.key,
- this.defaultValue = false,
- required this.storeKey,
+ required this.setting,
required this.title,
this.subtitle,
this.onChanged,
@@ -27,13 +25,12 @@ class SettingsSwitchListTileState extends State {
Widget build(BuildContext context) {
final subtitle = widget.subtitle;
return SwitchListTile.adaptive(
- value: Matrix.of(context).store.getBool(widget.storeKey) ??
- widget.defaultValue,
+ value: widget.setting.value,
title: Text(widget.title),
subtitle: subtitle == null ? null : Text(subtitle),
onChanged: (bool newValue) async {
widget.onChanged?.call(newValue);
- await Matrix.of(context).store.setBool(widget.storeKey, newValue);
+ await widget.setting.setItem(newValue);
setState(() {});
},
);
diff --git a/macos/Podfile.lock b/macos/Podfile.lock
index 80bbc5087..8507a72ef 100644
--- a/macos/Podfile.lock
+++ b/macos/Podfile.lock
@@ -42,6 +42,8 @@ PODS:
- FlutterMacOS
- record_macos (1.1.0):
- FlutterMacOS
+ - screen_retriever_macos (0.0.1):
+ - FlutterMacOS
- share_plus (0.0.1):
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
@@ -64,7 +66,12 @@ PODS:
- FlutterMacOS
- wakelock_plus (0.0.1):
- FlutterMacOS
+ - webcrypto (0.1.1):
+ - Flutter
+ - FlutterMacOS
- WebRTC-SDK (137.7151.04)
+ - window_manager (0.5.0):
+ - FlutterMacOS
- window_to_front (0.0.1):
- FlutterMacOS
@@ -89,6 +96,7 @@ DEPENDENCIES:
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- record_macos (from `Flutter/ephemeral/.symlinks/plugins/record_macos/macos`)
+ - screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`)
- share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqlcipher_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlcipher_flutter_libs/macos`)
@@ -96,6 +104,8 @@ DEPENDENCIES:
- video_compress (from `Flutter/ephemeral/.symlinks/plugins/video_compress/macos`)
- video_player_avfoundation (from `Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin`)
- wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`)
+ - webcrypto (from `Flutter/ephemeral/.symlinks/plugins/webcrypto/darwin`)
+ - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`)
- window_to_front (from `Flutter/ephemeral/.symlinks/plugins/window_to_front/macos`)
SPEC REPOS:
@@ -144,6 +154,8 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
record_macos:
:path: Flutter/ephemeral/.symlinks/plugins/record_macos/macos
+ screen_retriever_macos:
+ :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos
share_plus:
:path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos
shared_preferences_foundation:
@@ -158,6 +170,10 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/video_player_avfoundation/darwin
wakelock_plus:
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos
+ webcrypto:
+ :path: Flutter/ephemeral/.symlinks/plugins/webcrypto/darwin
+ window_manager:
+ :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos
window_to_front:
:path: Flutter/ephemeral/.symlinks/plugins/window_to_front/macos
@@ -182,6 +198,7 @@ SPEC CHECKSUMS:
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
record_macos: 43194b6c06ca6f8fa132e2acea72b202b92a0f5b
+ screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f
share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
SQLCipher: eb79c64049cb002b4e9fcb30edb7979bf4706dfc
@@ -190,7 +207,9 @@ SPEC CHECKSUMS:
video_compress: 752b161da855df2492dd1a8fa899743cc8fe9534
video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
wakelock_plus: 917609be14d812ddd9e9528876538b2263aaa03b
+ webcrypto: a5f5eb3e375cf0a99993e207e97cdcab5c94ce2e
WebRTC-SDK: 40d4f5ba05cadff14e4db5614aec402a633f007e
+ window_manager: b729e31d38fb04905235df9ea896128991cad99e
window_to_front: 9e76fd432e36700a197dac86a0011e49c89abe0a
PODFILE CHECKSUM: d0975b16fbdecb73b109d8fbc88aa77ffe4c7a8d
diff --git a/pubspec.lock b/pubspec.lock
index 6aacdbe86..a4e899775 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -45,10 +45,10 @@ packages:
dependency: "direct main"
description:
name: animations
- sha256: d3d6dcfb218225bbe68e87ccf6378bbb2e32a94900722c5f81611dad089911cb
+ sha256: a8031b276f0a7986ac907195f10ca7cd04ecf2a8a566bd6dbe03018a9b02b427
url: "https://pub.dev"
source: hosted
- version: "2.0.11"
+ version: "2.1.0"
ansicolor:
dependency: transitive
description:
@@ -1342,14 +1342,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.7"
- js_interop:
- dependency: transitive
- description:
- name: js_interop
- sha256: "7ec859c296958ccea34dc770504bd3ff4ae52fdd9e7eeb2bacc7081ad476a1f5"
- url: "https://pub.dev"
- source: hosted
- version: "0.0.1"
json_annotation:
dependency: transitive
description:
@@ -1516,7 +1508,7 @@ packages:
path: "/Users/ggurdin/pangea/matrix-dart-sdk"
relative: false
source: path
- version: "2.0.1"
+ version: "3.0.0"
meta:
dependency: transitive
description:
@@ -2558,10 +2550,10 @@ packages:
dependency: "direct main"
description:
name: unifiedpush_ui
- sha256: cf86f0214f37debd41f25c0425c8489df85e27f9f8784fed571eb7a86d39ba11
+ sha256: "1b36b2aa0bc6b61577e2661c1183bd3442969ecf77b4c78174796d324f66dd1d"
url: "https://pub.dev"
source: hosted
- version: "0.1.0"
+ version: "0.2.0"
universal_html:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 45c4afcfe..82607023c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -12,7 +12,7 @@ environment:
sdk: ">=3.0.0 <4.0.0"
dependencies:
- animations: ^2.0.11
+ animations: ^2.1.0
app_links: ^6.4.1
archive: ^4.0.7
async: ^2.11.0
@@ -91,7 +91,7 @@ dependencies:
swipe_to_action: ^0.3.0
tor_detector_web: ^1.1.0
unifiedpush: ^6.2.0
- unifiedpush_ui: ^0.1.0
+ unifiedpush_ui: ^0.2.0
universal_html: ^2.2.4
url_launcher: ^6.3.2
video_compress: ^3.1.4