Merge pull request #2264 from krille-chan/krille/refactor-user-settings
refactor: Use AppSettings enum based configuration everywhere and fix load from json on web
This commit is contained in:
commit
90ec0013f1
46 changed files with 357 additions and 402 deletions
58
README.md
58
README.md
|
|
@ -48,9 +48,63 @@ Please visit the website for installation instructions:
|
||||||
|
|
||||||
# How to build
|
# How to build
|
||||||
|
|
||||||
Please visit the [Wiki](https://github.com/krille-chan/fluffychat/wiki) for build instructions:
|
1. To build FluffyChat you need [Flutter](https://flutter.dev) and [Rust](https://www.rust-lang.org/tools/install)
|
||||||
|
|
||||||
- https://github.com/krille-chan/fluffychat/wiki/How-To-Build
|
2. Clone the repo:
|
||||||
|
```
|
||||||
|
git clone https://github.com/krille-chan/fluffychat.git
|
||||||
|
cd fluffychat
|
||||||
|
```
|
||||||
|
3. Choose your target platform below and enable support for it.
|
||||||
|
3.1 If you want, enable Googles Firebase Cloud Messaging:
|
||||||
|
|
||||||
|
`git apply ./scripts/enable-android-google-services.patch`
|
||||||
|
|
||||||
|
4. Debug with: `flutter run`
|
||||||
|
|
||||||
|
### Android
|
||||||
|
|
||||||
|
* Build with: `flutter build apk`
|
||||||
|
|
||||||
|
### iOS / iPadOS
|
||||||
|
|
||||||
|
* Have a Mac with Xcode installed, and set up for Xcode-managed app signing
|
||||||
|
* If you want automatic app installation to connected devices, make sure you have Apple Configurator installed, with the Automation Tools (`cfgutil`) enabled
|
||||||
|
* Set a few environment variables
|
||||||
|
* FLUFFYCHAT_NEW_TEAM: the Apple Developer team that your certificates should live under
|
||||||
|
* FLUFFYCHAT_NEW_GROUP: the group you want App IDs and such to live under (ie: com.example.fluffychat)
|
||||||
|
* FLUFFYCHAT_INSTALL_IPA: set to `1` if you want the IPA to be deployed to connected devices after building, otherwise unset
|
||||||
|
* Run `./scripts/build-ios.sh`
|
||||||
|
|
||||||
|
### Web
|
||||||
|
|
||||||
|
* Build with:
|
||||||
|
```bash
|
||||||
|
./scripts/prepare-web.sh # To install Vodozemac
|
||||||
|
flutter build web --release
|
||||||
|
```
|
||||||
|
|
||||||
|
* Optionally configure by serving a `config.json` at the same path as fluffychat.
|
||||||
|
An example can be found at `config.sample.json`. All values there are optional.
|
||||||
|
**Please only the values, you really need**. If you e.g. only want
|
||||||
|
to change the default homeserver, then only modify the `defaultHomeserver` key.
|
||||||
|
|
||||||
|
### Desktop (Linux, Windows, macOS)
|
||||||
|
|
||||||
|
* Enable Desktop support in Flutter: https://flutter.dev/desktop
|
||||||
|
|
||||||
|
#### Install custom dependencies (Linux)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install libjsoncpp1 libsecret-1-dev libsecret-1-0 librhash0 libwebkit2gtk-4.0-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
* Build with one of these:
|
||||||
|
```bash
|
||||||
|
flutter build linux --release
|
||||||
|
flutter build windows --release
|
||||||
|
flutter build macos --release
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
# Special thanks
|
# Special thanks
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,29 @@
|
||||||
{
|
{
|
||||||
"application_name": "FluffyChat",
|
"applicationName": "FluffyChat",
|
||||||
"application_welcome_message": null,
|
"defaultHomeserver": "matrix.org",
|
||||||
"default_homeserver": "matrix.org",
|
"privacyUrl": "https://github.com/krille-chan/fluffychat/blob/main/PRIVACY.md",
|
||||||
"web_base_url": "https://fluffychat.im/web",
|
"audioRecordingNumChannels": 1,
|
||||||
"privacy_url": "https://fluffychat.im/en/privacy.html",
|
"audioRecordingAutoGain": true,
|
||||||
"render_html": false,
|
"audioRecordingEchoCancel": false,
|
||||||
"hide_redacted_events": false,
|
"audioRecordingNoiseSuppress": true,
|
||||||
"hide_unknown_events": false
|
"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
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:fluffychat/config/setting_keys.dart';
|
|
||||||
import 'package:fluffychat/pages/chat/chat_view.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/chat_list_body.dart';
|
||||||
import 'package:fluffychat/pages/chat_list/search_title.dart';
|
import 'package:fluffychat/pages/chat_list/search_title.dart';
|
||||||
|
|
@ -25,7 +24,7 @@ void main() {
|
||||||
() async {
|
() async {
|
||||||
// this random dialog popping up is super hard to cover in tests
|
// this random dialog popping up is super hard to cover in tests
|
||||||
SharedPreferences.setMockInitialValues({
|
SharedPreferences.setMockInitialValues({
|
||||||
SettingKeys.showNoGoogle: false,
|
'chat.fluffy.show_no_google': false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,25 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:matrix/matrix.dart';
|
|
||||||
|
|
||||||
abstract class AppConfig {
|
abstract class AppConfig {
|
||||||
static String _applicationName = 'FluffyChat';
|
// Const and final configuration values (immutable)
|
||||||
|
|
||||||
static String get applicationName => _applicationName;
|
|
||||||
static String? _applicationWelcomeMessage;
|
|
||||||
|
|
||||||
static String? get applicationWelcomeMessage => _applicationWelcomeMessage;
|
|
||||||
static String _defaultHomeserver = 'matrix.org';
|
|
||||||
|
|
||||||
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 Color primaryColor = Color(0xFF5625BA);
|
static const Color primaryColor = Color(0xFF5625BA);
|
||||||
static const Color primaryColorLight = Color(0xFFCCBDEA);
|
static const Color primaryColorLight = Color(0xFFCCBDEA);
|
||||||
static const Color secondaryColor = Color(0xFF41a2bc);
|
static const Color secondaryColor = Color(0xFF41a2bc);
|
||||||
static String _privacyUrl =
|
|
||||||
'https://github.com/krille-chan/fluffychat/blob/main/PRIVACY.md';
|
|
||||||
|
|
||||||
static const Set<String> defaultReactions = {'👍', '❤️', '😂', '😮', '😢'};
|
static const Color chatColor = 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:';
|
||||||
|
static const String pushNotificationsChannelId = 'fluffychat_push';
|
||||||
|
static const String pushNotificationsAppId = 'chat.fluffy.fluffychat';
|
||||||
|
static const double borderRadius = 18.0;
|
||||||
|
static const double columnWidth = 360.0;
|
||||||
|
|
||||||
static String get privacyUrl => _privacyUrl;
|
|
||||||
static const String website = 'https://fluffychat.im';
|
static const String website = 'https://fluffychat.im';
|
||||||
static const String enablePushTutorial =
|
static const String enablePushTutorial =
|
||||||
'https://github.com/krille-chan/fluffychat/wiki/Push-Notifications-without-Google-Services';
|
'https://github.com/krille-chan/fluffychat/wiki/Push-Notifications-without-Google-Services';
|
||||||
|
|
@ -36,80 +29,25 @@ abstract class AppConfig {
|
||||||
'https://github.com/krille-chan/fluffychat/wiki/How-to-Find-Users-in-FluffyChat';
|
'https://github.com/krille-chan/fluffychat/wiki/How-to-Find-Users-in-FluffyChat';
|
||||||
static const String appId = 'im.fluffychat.FluffyChat';
|
static const String appId = 'im.fluffychat.FluffyChat';
|
||||||
static const String appOpenUrlScheme = 'im.fluffychat';
|
static const String appOpenUrlScheme = 'im.fluffychat';
|
||||||
static String _webBaseUrl = 'https://fluffychat.im/web';
|
|
||||||
|
|
||||||
static String get webBaseUrl => _webBaseUrl;
|
|
||||||
static const String sourceCodeUrl =
|
static const String sourceCodeUrl =
|
||||||
'https://github.com/krille-chan/fluffychat';
|
'https://github.com/krille-chan/fluffychat';
|
||||||
static const String supportUrl =
|
static const String supportUrl =
|
||||||
'https://github.com/krille-chan/fluffychat/issues';
|
'https://github.com/krille-chan/fluffychat/issues';
|
||||||
static const String changelogUrl =
|
static const String changelogUrl =
|
||||||
'https://github.com/krille-chan/fluffychat/blob/main/CHANGELOG.md';
|
'https://github.com/krille-chan/fluffychat/blob/main/CHANGELOG.md';
|
||||||
|
|
||||||
|
static const Set<String> defaultReactions = {'👍', '❤️', '😂', '😮', '😢'};
|
||||||
|
|
||||||
static final Uri newIssueUrl = Uri(
|
static final Uri newIssueUrl = Uri(
|
||||||
scheme: 'https',
|
scheme: 'https',
|
||||||
host: 'github.com',
|
host: 'github.com',
|
||||||
path: '/krille-chan/fluffychat/issues/new',
|
path: '/krille-chan/fluffychat/issues/new',
|
||||||
);
|
);
|
||||||
static bool renderHtml = true;
|
|
||||||
static bool hideRedactedEvents = false;
|
|
||||||
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 showPresences = true;
|
|
||||||
static bool displayNavigationRail = false;
|
|
||||||
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:';
|
|
||||||
static const String pushNotificationsChannelId = 'fluffychat_push';
|
|
||||||
static const String pushNotificationsAppId = 'chat.fluffy.fluffychat';
|
|
||||||
static const double borderRadius = 18.0;
|
|
||||||
static const double columnWidth = 360.0;
|
|
||||||
static final Uri homeserverList = Uri(
|
static final Uri homeserverList = Uri(
|
||||||
scheme: 'https',
|
scheme: 'https',
|
||||||
host: 'servers.joinmatrix.org',
|
host: 'servers.joinmatrix.org',
|
||||||
path: 'servers.json',
|
path: 'servers.json',
|
||||||
);
|
);
|
||||||
|
|
||||||
static void loadFromJson(Map<String, dynamic> 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'];
|
|
||||||
}
|
|
||||||
if (json['default_homeserver'] is String) {
|
|
||||||
_defaultHomeserver = json['default_homeserver'];
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
renderHtml = json['render_html'];
|
|
||||||
}
|
|
||||||
if (json['hide_redacted_events'] is bool) {
|
|
||||||
hideRedactedEvents = json['hide_redacted_events'];
|
|
||||||
}
|
|
||||||
if (json['hide_unknown_events'] is bool) {
|
|
||||||
hideUnknownEvents = json['hide_unknown_events'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +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';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
abstract class SettingKeys {
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
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';
|
|
||||||
}
|
|
||||||
|
|
||||||
enum AppSettings<T> {
|
enum AppSettings<T> {
|
||||||
textMessageMaxLength<int>('textMessageMaxLength', 16384),
|
textMessageMaxLength<int>('textMessageMaxLength', 16384),
|
||||||
|
|
@ -44,6 +16,9 @@ enum AppSettings<T> {
|
||||||
audioRecordingNoiseSuppress<bool>('audioRecordingNoiseSuppress', true),
|
audioRecordingNoiseSuppress<bool>('audioRecordingNoiseSuppress', true),
|
||||||
audioRecordingBitRate<int>('audioRecordingBitRate', 64000),
|
audioRecordingBitRate<int>('audioRecordingBitRate', 64000),
|
||||||
audioRecordingSamplingRate<int>('audioRecordingSamplingRate', 44100),
|
audioRecordingSamplingRate<int>('audioRecordingSamplingRate', 44100),
|
||||||
|
showNoGoogle<bool>('chat.fluffy.show_no_google', false),
|
||||||
|
unifiedPushRegistered<bool>('chat.fluffy.unifiedpush.registered', false),
|
||||||
|
unifiedPushEndpoint<String>('chat.fluffy.unifiedpush.endpoint', ''),
|
||||||
pushNotificationsGatewayUrl<String>(
|
pushNotificationsGatewayUrl<String>(
|
||||||
'pushNotificationsGatewayUrl',
|
'pushNotificationsGatewayUrl',
|
||||||
'https://push.fluffychat.im/_matrix/push/v1/notify',
|
'https://push.fluffychat.im/_matrix/push/v1/notify',
|
||||||
|
|
@ -52,6 +27,19 @@ enum AppSettings<T> {
|
||||||
'pushNotificationsPusherFormat',
|
'pushNotificationsPusherFormat',
|
||||||
'event_id_only',
|
'event_id_only',
|
||||||
),
|
),
|
||||||
|
renderHtml<bool>('chat.fluffy.renderHtml', true),
|
||||||
|
fontSizeFactor<double>('chat.fluffy.font_size_factor', 1.0),
|
||||||
|
hideRedactedEvents<bool>('chat.fluffy.hideRedactedEvents', false),
|
||||||
|
hideUnknownEvents<bool>('chat.fluffy.hideUnknownEvents', true),
|
||||||
|
separateChatTypes<bool>('chat.fluffy.separateChatTypes', false),
|
||||||
|
autoplayImages<bool>('chat.fluffy.autoplay_images', true),
|
||||||
|
sendTypingNotifications<bool>('chat.fluffy.send_typing_notifications', true),
|
||||||
|
sendPublicReadReceipts<bool>('chat.fluffy.send_public_read_receipts', true),
|
||||||
|
swipeRightToLeftToReply<bool>('chat.fluffy.swipeRightToLeftToReply', true),
|
||||||
|
sendOnEnter<bool>('chat.fluffy.send_on_enter', false),
|
||||||
|
showPresences<bool>('chat.fluffy.show_presences', true),
|
||||||
|
displayNavigationRail<bool>('chat.fluffy.display_navigation_rail', false),
|
||||||
|
experimentalVoip<bool>('chat.fluffy.experimental_voip', false),
|
||||||
shareKeysWith<String>('chat.fluffy.share_keys_with_2', 'all'),
|
shareKeysWith<String>('chat.fluffy.share_keys_with_2', 'all'),
|
||||||
noEncryptionWarningShown<bool>(
|
noEncryptionWarningShown<bool>(
|
||||||
'chat.fluffy.no_encryption_warning_shown',
|
'chat.fluffy.no_encryption_warning_shown',
|
||||||
|
|
@ -61,40 +49,88 @@ enum AppSettings<T> {
|
||||||
'chat.fluffy.display_chat_details_column',
|
'chat.fluffy.display_chat_details_column',
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
// AppConfig-mirrored settings
|
||||||
|
applicationName<String>('chat.fluffy.application_name', 'FluffyChat'),
|
||||||
|
defaultHomeserver<String>('chat.fluffy.default_homeserver', 'matrix.org'),
|
||||||
|
privacyUrl<String>(
|
||||||
|
'chat.fluffy.privacy_url',
|
||||||
|
'https://github.com/krille-chan/fluffychat/blob/main/PRIVACY.md',
|
||||||
|
),
|
||||||
|
// colorSchemeSeed stored as ARGB int
|
||||||
|
colorSchemeSeedInt<int>(
|
||||||
|
'chat.fluffy.color_scheme_seed',
|
||||||
|
0xFF5625BA,
|
||||||
|
),
|
||||||
enableSoftLogout<bool>('chat.fluffy.enable_soft_logout', false);
|
enableSoftLogout<bool>('chat.fluffy.enable_soft_logout', false);
|
||||||
|
|
||||||
final String key;
|
final String key;
|
||||||
final T defaultValue;
|
final T defaultValue;
|
||||||
|
|
||||||
const AppSettings(this.key, this.defaultValue);
|
const AppSettings(this.key, this.defaultValue);
|
||||||
|
|
||||||
|
static late final SharedPreferences store;
|
||||||
|
|
||||||
|
static Future<SharedPreferences> init({loadWebConfigFile = true}) async {
|
||||||
|
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<String, Object?>;
|
||||||
|
for (final setting in AppSettings.values) {
|
||||||
|
if (store.get(setting.key) != null) continue;
|
||||||
|
final configValue = configJson[setting.key];
|
||||||
|
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> {
|
extension AppSettingsBoolExtension on AppSettings<bool> {
|
||||||
bool getItem(SharedPreferences store) => store.getBool(key) ?? defaultValue;
|
bool get value => AppSettings.store.getBool(key) ?? defaultValue;
|
||||||
|
|
||||||
Future<void> setItem(SharedPreferences store, bool value) =>
|
Future<void> setItem(bool value) => AppSettings.store.setBool(key, value);
|
||||||
store.setBool(key, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppSettingsStringExtension on AppSettings<String> {
|
extension AppSettingsStringExtension on AppSettings<String> {
|
||||||
String getItem(SharedPreferences store) =>
|
String get value => AppSettings.store.getString(key) ?? defaultValue;
|
||||||
store.getString(key) ?? defaultValue;
|
|
||||||
|
|
||||||
Future<void> setItem(SharedPreferences store, String value) =>
|
Future<void> setItem(String value) => AppSettings.store.setString(key, value);
|
||||||
store.setString(key, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppSettingsIntExtension on AppSettings<int> {
|
extension AppSettingsIntExtension on AppSettings<int> {
|
||||||
int getItem(SharedPreferences store) => store.getInt(key) ?? defaultValue;
|
int get value => AppSettings.store.getInt(key) ?? defaultValue;
|
||||||
|
|
||||||
Future<void> setItem(SharedPreferences store, int value) =>
|
Future<void> setItem(int value) => AppSettings.store.setInt(key, value);
|
||||||
store.setInt(key, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AppSettingsDoubleExtension on AppSettings<double> {
|
extension AppSettingsDoubleExtension on AppSettings<double> {
|
||||||
double getItem(SharedPreferences store) =>
|
double get value => AppSettings.store.getDouble(key) ?? defaultValue;
|
||||||
store.getDouble(key) ?? defaultValue;
|
|
||||||
|
|
||||||
Future<void> setItem(SharedPreferences store, double value) =>
|
Future<void> setItem(double value) => AppSettings.store.setDouble(key, value);
|
||||||
store.setDouble(key, value);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'app_config.dart';
|
import 'app_config.dart';
|
||||||
|
|
||||||
abstract class FluffyThemes {
|
abstract class FluffyThemes {
|
||||||
|
|
@ -45,7 +46,7 @@ abstract class FluffyThemes {
|
||||||
]) {
|
]) {
|
||||||
final colorScheme = ColorScheme.fromSeed(
|
final colorScheme = ColorScheme.fromSeed(
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
seedColor: seed ?? AppConfig.colorSchemeSeed ?? AppConfig.primaryColor,
|
seedColor: seed ?? Color(AppSettings.colorSchemeSeedInt.value),
|
||||||
);
|
);
|
||||||
final isColumnMode = FluffyThemes.isColumnMode(context);
|
final isColumnMode = FluffyThemes.isColumnMode(context);
|
||||||
return ThemeData(
|
return ThemeData(
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import 'package:flutter_vodozemac/flutter_vodozemac.dart' as vod;
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
|
||||||
import 'package:fluffychat/utils/client_manager.dart';
|
import 'package:fluffychat/utils/client_manager.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
import 'config/setting_keys.dart';
|
import 'config/setting_keys.dart';
|
||||||
|
|
@ -14,17 +13,17 @@ import 'utils/background_push.dart';
|
||||||
import 'widgets/fluffy_chat_app.dart';
|
import 'widgets/fluffy_chat_app.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
Logs().i('Welcome to ${AppConfig.applicationName} <3');
|
|
||||||
|
|
||||||
// Our background push shared isolate accesses flutter-internal things very early in the startup proccess
|
// Our background push shared isolate accesses flutter-internal things very early in the startup proccess
|
||||||
// To make sure that the parts of flutter needed are started up already, we need to ensure that the
|
// To make sure that the parts of flutter needed are started up already, we need to ensure that the
|
||||||
// widget bindings are initialized already.
|
// widget bindings are initialized already.
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
final store = await AppSettings.init();
|
||||||
|
Logs().i('Welcome to ${AppSettings.applicationName.value} <3');
|
||||||
|
|
||||||
await vod.init(wasmPath: './assets/assets/vodozemac/');
|
await vod.init(wasmPath: './assets/assets/vodozemac/');
|
||||||
|
|
||||||
Logs().nativeColors = !PlatformInfos.isIOS;
|
Logs().nativeColors = !PlatformInfos.isIOS;
|
||||||
final store = await SharedPreferences.getInstance();
|
|
||||||
final clients = await ClientManager.getClients(store: store);
|
final clients = await ClientManager.getClients(store: store);
|
||||||
|
|
||||||
// If the app starts in detached mode, we assume that it is in
|
// If the app starts in detached mode, we assume that it is in
|
||||||
|
|
@ -44,14 +43,14 @@ void main() async {
|
||||||
// To start the flutter engine afterwards we add an custom observer.
|
// To start the flutter engine afterwards we add an custom observer.
|
||||||
WidgetsBinding.instance.addObserver(AppStarter(clients, store));
|
WidgetsBinding.instance.addObserver(AppStarter(clients, store));
|
||||||
Logs().i(
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Started in foreground mode.
|
// Started in foreground mode.
|
||||||
Logs().i(
|
Logs().i(
|
||||||
'${AppConfig.applicationName} started in foreground mode. Rendering GUI...',
|
'${AppSettings.applicationName.value} started in foreground mode. Rendering GUI...',
|
||||||
);
|
);
|
||||||
await startGui(clients, store);
|
await startGui(clients, store);
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +62,7 @@ Future<void> startGui(List<Client> clients, SharedPreferences store) async {
|
||||||
if (PlatformInfos.isMobile) {
|
if (PlatformInfos.isMobile) {
|
||||||
try {
|
try {
|
||||||
pin =
|
pin =
|
||||||
await const FlutterSecureStorage().read(key: SettingKeys.appLockKey);
|
await const FlutterSecureStorage().read(key: 'chat.fluffy.app_lock');
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logs().d('Unable to read PIN from Secure storage', e, s);
|
Logs().d('Unable to read PIN from Secure storage', e, s);
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +91,7 @@ class AppStarter with WidgetsBindingObserver {
|
||||||
if (state == AppLifecycleState.detached) return;
|
if (state == AppLifecycleState.detached) return;
|
||||||
|
|
||||||
Logs().i(
|
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.
|
// Switching to foreground mode needs to reenable send online sync presence.
|
||||||
for (final client in clients) {
|
for (final client in clients) {
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,8 @@ import 'package:go_router/go_router.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'package:universal_html/html.dart' as html;
|
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/setting_keys.dart';
|
||||||
import 'package:fluffychat/config/themes.dart';
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
|
|
@ -224,7 +222,7 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
}
|
}
|
||||||
|
|
||||||
void _loadDraft() async {
|
void _loadDraft() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = Matrix.of(context).store;
|
||||||
final draft = prefs.getString('draft_$roomId');
|
final draft = prefs.getString('draft_$roomId');
|
||||||
if (draft != null && draft.isNotEmpty) {
|
if (draft != null && draft.isNotEmpty) {
|
||||||
sendController.text = draft;
|
sendController.text = draft;
|
||||||
|
|
@ -274,7 +272,7 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
KeyEventResult _customEnterKeyHandling(FocusNode node, KeyEvent evt) {
|
KeyEventResult _customEnterKeyHandling(FocusNode node, KeyEvent evt) {
|
||||||
if (!HardwareKeyboard.instance.isShiftPressed &&
|
if (!HardwareKeyboard.instance.isShiftPressed &&
|
||||||
evt.logicalKey.keyLabel == 'Enter' &&
|
evt.logicalKey.keyLabel == 'Enter' &&
|
||||||
(AppConfig.sendOnEnter ?? !PlatformInfos.isMobile)) {
|
AppSettings.sendOnEnter.value) {
|
||||||
if (evt is KeyDownEvent) {
|
if (evt is KeyDownEvent) {
|
||||||
send();
|
send();
|
||||||
}
|
}
|
||||||
|
|
@ -325,7 +323,7 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
WidgetsBinding.instance.addPostFrameCallback(_shareItems);
|
WidgetsBinding.instance.addPostFrameCallback(_shareItems);
|
||||||
super.initState();
|
super.initState();
|
||||||
_displayChatDetailsColumn = ValueNotifier(
|
_displayChatDetailsColumn = ValueNotifier(
|
||||||
AppSettings.displayChatDetailsColumn.getItem(Matrix.of(context).store),
|
AppSettings.displayChatDetailsColumn.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
sendingClient = Matrix.of(context).client;
|
sendingClient = Matrix.of(context).client;
|
||||||
|
|
@ -365,7 +363,9 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
var readMarkerEventIndex = readMarkerEventId.isEmpty
|
var readMarkerEventIndex = readMarkerEventId.isEmpty
|
||||||
? -1
|
? -1
|
||||||
: timeline!.events
|
: timeline!.events
|
||||||
.filterByVisibleInGui(exceptionEventId: readMarkerEventId)
|
.filterByVisibleInGui(
|
||||||
|
exceptionEventId: readMarkerEventId,
|
||||||
|
)
|
||||||
.indexWhere((e) => e.eventId == readMarkerEventId);
|
.indexWhere((e) => e.eventId == readMarkerEventId);
|
||||||
|
|
||||||
// Read marker is existing but not found in first events. Try a single
|
// Read marker is existing but not found in first events. Try a single
|
||||||
|
|
@ -373,7 +373,9 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
if (readMarkerEventId.isNotEmpty && readMarkerEventIndex == -1) {
|
if (readMarkerEventId.isNotEmpty && readMarkerEventIndex == -1) {
|
||||||
await timeline?.requestHistory(historyCount: _loadHistoryCount);
|
await timeline?.requestHistory(historyCount: _loadHistoryCount);
|
||||||
readMarkerEventIndex = timeline!.events
|
readMarkerEventIndex = timeline!.events
|
||||||
.filterByVisibleInGui(exceptionEventId: readMarkerEventId)
|
.filterByVisibleInGui(
|
||||||
|
exceptionEventId: readMarkerEventId,
|
||||||
|
)
|
||||||
.indexWhere((e) => e.eventId == readMarkerEventId);
|
.indexWhere((e) => e.eventId == readMarkerEventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -492,7 +494,7 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
_setReadMarkerFuture = timeline
|
_setReadMarkerFuture = timeline
|
||||||
.setReadMarker(
|
.setReadMarker(
|
||||||
eventId: eventId,
|
eventId: eventId,
|
||||||
public: AppConfig.sendPublicReadReceipts,
|
public: AppSettings.sendPublicReadReceipts.value,
|
||||||
)
|
)
|
||||||
.then((_) {
|
.then((_) {
|
||||||
_setReadMarkerFuture = null;
|
_setReadMarkerFuture = null;
|
||||||
|
|
@ -542,7 +544,7 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
Future<void> send() async {
|
Future<void> send() async {
|
||||||
if (sendController.text.trim().isEmpty) return;
|
if (sendController.text.trim().isEmpty) return;
|
||||||
_storeInputTimeoutTimer?.cancel();
|
_storeInputTimeoutTimer?.cancel();
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = Matrix.of(context).store;
|
||||||
prefs.remove('draft_$roomId');
|
prefs.remove('draft_$roomId');
|
||||||
var parseCommands = true;
|
var parseCommands = true;
|
||||||
|
|
||||||
|
|
@ -960,7 +962,9 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
final eventIndex = foundEvent == null
|
final eventIndex = foundEvent == null
|
||||||
? -1
|
? -1
|
||||||
: timeline!.events
|
: timeline!.events
|
||||||
.filterByVisibleInGui(exceptionEventId: eventId)
|
.filterByVisibleInGui(
|
||||||
|
exceptionEventId: eventId,
|
||||||
|
)
|
||||||
.indexOf(foundEvent);
|
.indexOf(foundEvent);
|
||||||
|
|
||||||
if (eventIndex == -1) {
|
if (eventIndex == -1) {
|
||||||
|
|
@ -1203,7 +1207,7 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
|
|
||||||
_storeInputTimeoutTimer?.cancel();
|
_storeInputTimeoutTimer?.cancel();
|
||||||
_storeInputTimeoutTimer = Timer(_storeInputTimeout, () async {
|
_storeInputTimeoutTimer = Timer(_storeInputTimeout, () async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = Matrix.of(context).store;
|
||||||
await prefs.setString('draft_$roomId', text);
|
await prefs.setString('draft_$roomId', text);
|
||||||
});
|
});
|
||||||
if (text.endsWith(' ') && Matrix.of(context).hasComplexBundles) {
|
if (text.endsWith(' ') && Matrix.of(context).hasComplexBundles) {
|
||||||
|
|
@ -1220,7 +1224,7 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (AppConfig.sendTypingNotifications) {
|
if (AppSettings.sendTypingNotifications.value) {
|
||||||
typingCoolDown?.cancel();
|
typingCoolDown?.cancel();
|
||||||
typingCoolDown = Timer(const Duration(seconds: 2), () {
|
typingCoolDown = Timer(const Duration(seconds: 2), () {
|
||||||
typingCoolDown = null;
|
typingCoolDown = null;
|
||||||
|
|
@ -1307,7 +1311,6 @@ class ChatController extends State<ChatPageWithRoom>
|
||||||
|
|
||||||
void toggleDisplayChatDetailsColumn() async {
|
void toggleDisplayChatDetailsColumn() async {
|
||||||
await AppSettings.displayChatDetailsColumn.setItem(
|
await AppSettings.displayChatDetailsColumn.setItem(
|
||||||
Matrix.of(context).store,
|
|
||||||
!_displayChatDetailsColumn.value,
|
!_displayChatDetailsColumn.value,
|
||||||
);
|
);
|
||||||
_displayChatDetailsColumn.value = !_displayChatDetailsColumn.value;
|
_displayChatDetailsColumn.value = !_displayChatDetailsColumn.value;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
import 'package:matrix/matrix.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/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/pages/chat/recording_input_row.dart';
|
import 'package:fluffychat/pages/chat/recording_input_row.dart';
|
||||||
import 'package:fluffychat/pages/chat/recording_view_model.dart';
|
import 'package:fluffychat/pages/chat/recording_view_model.dart';
|
||||||
|
|
@ -297,10 +297,11 @@ class ChatInputRow extends StatelessWidget {
|
||||||
maxLines: 8,
|
maxLines: 8,
|
||||||
autofocus: !PlatformInfos.isMobile,
|
autofocus: !PlatformInfos.isMobile,
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
textInputAction: AppConfig.sendOnEnter == true &&
|
textInputAction:
|
||||||
PlatformInfos.isMobile
|
AppSettings.sendOnEnter.value == true &&
|
||||||
? TextInputAction.send
|
PlatformInfos.isMobile
|
||||||
: null,
|
? TextInputAction.send
|
||||||
|
: null,
|
||||||
onSubmitted: controller.onInputBarSubmitted,
|
onSubmitted: controller.onInputBarSubmitted,
|
||||||
onSubmitImage: controller.sendImageFromClipBoard,
|
onSubmitImage: controller.sendImageFromClipBoard,
|
||||||
focusNode: controller.inputFocus,
|
focusNode: controller.inputFocus,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import 'package:badges/badges.dart';
|
||||||
import 'package:desktop_drop/desktop_drop.dart';
|
import 'package:desktop_drop/desktop_drop.dart';
|
||||||
import 'package:matrix/matrix.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/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/pages/chat/chat.dart';
|
import 'package:fluffychat/pages/chat/chat.dart';
|
||||||
|
|
@ -119,7 +119,7 @@ class ChatView extends StatelessWidget {
|
||||||
];
|
];
|
||||||
} else if (!controller.room.isArchived) {
|
} else if (!controller.room.isArchived) {
|
||||||
return [
|
return [
|
||||||
if (AppConfig.experimentalVoip &&
|
if (AppSettings.experimentalVoip.value &&
|
||||||
Matrix.of(context).voipPlugin != null &&
|
Matrix.of(context).voipPlugin != null &&
|
||||||
controller.room.isDirectChat)
|
controller.room.isDirectChat)
|
||||||
IconButton(
|
IconButton(
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:matrix/matrix.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/l10n/l10n.dart';
|
||||||
|
|
||||||
class CuteContent extends StatefulWidget {
|
class CuteContent extends StatefulWidget {
|
||||||
|
|
@ -21,7 +21,7 @@ class _CuteContentState extends State<CuteContent> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
if (AppConfig.autoplayImages && !_isOverlayShown) {
|
if (AppSettings.autoplayImages.value && !_isOverlayShown) {
|
||||||
addOverlay();
|
addOverlay();
|
||||||
}
|
}
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter_linkify/flutter_linkify.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.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/pages/image_viewer/image_viewer.dart';
|
||||||
import 'package:fluffychat/utils/file_description.dart';
|
import 'package:fluffychat/utils/file_description.dart';
|
||||||
import 'package:fluffychat/utils/url_launcher.dart';
|
import 'package:fluffychat/utils/url_launcher.dart';
|
||||||
|
|
@ -139,14 +140,14 @@ class ImageBubble extends StatelessWidget {
|
||||||
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: textColor,
|
color: textColor,
|
||||||
fontSize:
|
fontSize: AppSettings.fontSizeFactor.value *
|
||||||
AppConfig.fontSizeFactor * AppConfig.messageFontSize,
|
AppConfig.messageFontSize,
|
||||||
),
|
),
|
||||||
options: const LinkifyOptions(humanize: false),
|
options: const LinkifyOptions(humanize: false),
|
||||||
linkStyle: TextStyle(
|
linkStyle: TextStyle(
|
||||||
color: linkColor,
|
color: linkColor,
|
||||||
fontSize:
|
fontSize: AppSettings.fontSizeFactor.value *
|
||||||
AppConfig.fontSizeFactor * AppConfig.messageFontSize,
|
AppConfig.messageFontSize,
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
decorationColor: linkColor,
|
decorationColor: linkColor,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:swipe_to_action/swipe_to_action.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/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/pages/chat/events/room_creation_state_event.dart';
|
import 'package:fluffychat/pages/chat/events/room_creation_state_event.dart';
|
||||||
|
|
@ -204,7 +205,7 @@ class Message extends StatelessWidget {
|
||||||
child: Icon(Icons.check_outlined),
|
child: Icon(Icons.check_outlined),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
direction: AppConfig.swipeRightToLeftToReply
|
direction: AppSettings.swipeRightToLeftToReply.value
|
||||||
? SwipeDirection.endToStart
|
? SwipeDirection.endToStart
|
||||||
: SwipeDirection.startToEnd,
|
: SwipeDirection.startToEnd,
|
||||||
onSwipe: (_) => onSwipe(),
|
onSwipe: (_) => onSwipe(),
|
||||||
|
|
@ -243,7 +244,7 @@ class Message extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
event.originServerTs.localizedTime(context),
|
event.originServerTs.localizedTime(context),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12 * AppConfig.fontSizeFactor,
|
fontSize: 12 * AppSettings.fontSizeFactor.value,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: theme.colorScheme.secondary,
|
color: theme.colorScheme.secondary,
|
||||||
),
|
),
|
||||||
|
|
@ -890,7 +891,7 @@ class Message extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
L10n.of(context).readUpToHere,
|
L10n.of(context).readUpToHere,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12 * AppConfig.fontSizeFactor,
|
fontSize: 12 * AppSettings.fontSizeFactor.value,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/pages/chat/events/video_player.dart';
|
import 'package:fluffychat/pages/chat/events/video_player.dart';
|
||||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||||
|
|
@ -105,7 +106,8 @@ class MessageContent extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
|
final fontSize =
|
||||||
|
AppConfig.messageFontSize * AppSettings.fontSizeFactor.value;
|
||||||
final buttonTextColor = textColor;
|
final buttonTextColor = textColor;
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case EventTypes.Message:
|
case EventTypes.Message:
|
||||||
|
|
@ -255,7 +257,7 @@ class MessageContent extends StatelessWidget {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
var html = AppConfig.renderHtml && event.isRichMessage
|
var html = AppSettings.renderHtml.value && event.isRichMessage
|
||||||
? event.formattedText
|
? event.formattedText
|
||||||
: event.body;
|
: event.body;
|
||||||
if (event.messageType == MessageTypes.Emote) {
|
if (event.messageType == MessageTypes.Emote) {
|
||||||
|
|
@ -274,14 +276,14 @@ class MessageContent extends StatelessWidget {
|
||||||
html: html,
|
html: html,
|
||||||
textColor: textColor,
|
textColor: textColor,
|
||||||
room: event.room,
|
room: event.room,
|
||||||
fontSize: AppConfig.fontSizeFactor *
|
fontSize: AppSettings.fontSizeFactor.value *
|
||||||
AppConfig.messageFontSize *
|
AppConfig.messageFontSize *
|
||||||
(bigEmotes ? 5 : 1),
|
(bigEmotes ? 5 : 1),
|
||||||
limitHeight: !selected,
|
limitHeight: !selected,
|
||||||
linkStyle: TextStyle(
|
linkStyle: TextStyle(
|
||||||
color: linkColor,
|
color: linkColor,
|
||||||
fontSize:
|
fontSize: AppSettings.fontSizeFactor.value *
|
||||||
AppConfig.fontSizeFactor * AppConfig.messageFontSize,
|
AppConfig.messageFontSize,
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
decorationColor: linkColor,
|
decorationColor: linkColor,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter_linkify/flutter_linkify.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.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/file_description.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
|
||||||
import 'package:fluffychat/utils/url_launcher.dart';
|
import 'package:fluffychat/utils/url_launcher.dart';
|
||||||
|
|
@ -92,12 +93,14 @@ class MessageDownloadContent extends StatelessWidget {
|
||||||
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: textColor,
|
color: textColor,
|
||||||
fontSize: AppConfig.fontSizeFactor * AppConfig.messageFontSize,
|
fontSize: AppSettings.fontSizeFactor.value *
|
||||||
|
AppConfig.messageFontSize,
|
||||||
),
|
),
|
||||||
options: const LinkifyOptions(humanize: false),
|
options: const LinkifyOptions(humanize: false),
|
||||||
linkStyle: TextStyle(
|
linkStyle: TextStyle(
|
||||||
color: linkColor,
|
color: linkColor,
|
||||||
fontSize: AppConfig.fontSizeFactor * AppConfig.messageFontSize,
|
fontSize: AppSettings.fontSizeFactor.value *
|
||||||
|
AppConfig.messageFontSize,
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
decorationColor: linkColor,
|
decorationColor: linkColor,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||||
import '../../../config/app_config.dart';
|
import '../../../config/app_config.dart';
|
||||||
|
|
@ -30,7 +31,8 @@ class ReplyContent extends StatelessWidget {
|
||||||
final timeline = this.timeline;
|
final timeline = this.timeline;
|
||||||
final displayEvent =
|
final displayEvent =
|
||||||
timeline != null ? replyEvent.getDisplayEvent(timeline) : replyEvent;
|
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
|
final color = theme.brightness == Brightness.dark
|
||||||
? theme.colorScheme.onTertiaryContainer
|
? theme.colorScheme.onTertiaryContainer
|
||||||
: ownMessage
|
: ownMessage
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/config/themes.dart';
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||||
|
|
@ -68,7 +69,7 @@ class StateMessage extends StatelessWidget {
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12 * AppConfig.fontSizeFactor,
|
fontSize: 12 * AppSettings.fontSizeFactor.value,
|
||||||
decoration: event.redacted
|
decoration: event.redacted
|
||||||
? TextDecoration.lineThrough
|
? TextDecoration.lineThrough
|
||||||
: null,
|
: null,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import 'package:flutter_linkify/flutter_linkify.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.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/file_description.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
|
|
@ -136,14 +137,14 @@ class EventVideoPlayer extends StatelessWidget {
|
||||||
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: textColor,
|
color: textColor,
|
||||||
fontSize:
|
fontSize: AppSettings.fontSizeFactor.value *
|
||||||
AppConfig.fontSizeFactor * AppConfig.messageFontSize,
|
AppConfig.messageFontSize,
|
||||||
),
|
),
|
||||||
options: const LinkifyOptions(humanize: false),
|
options: const LinkifyOptions(humanize: false),
|
||||||
linkStyle: TextStyle(
|
linkStyle: TextStyle(
|
||||||
color: linkColor,
|
color: linkColor,
|
||||||
fontSize:
|
fontSize: AppSettings.fontSizeFactor.value *
|
||||||
AppConfig.fontSizeFactor * AppConfig.messageFontSize,
|
AppConfig.messageFontSize,
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
decorationColor: linkColor,
|
decorationColor: linkColor,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -415,8 +415,7 @@ class InputBar extends StatelessWidget {
|
||||||
// it sets the types for the callback incorrectly
|
// it sets the types for the callback incorrectly
|
||||||
onSubmitted!(text);
|
onSubmitted!(text);
|
||||||
},
|
},
|
||||||
maxLength:
|
maxLength: AppSettings.textMessageMaxLength.value,
|
||||||
AppSettings.textMessageMaxLength.getItem(Matrix.of(context).store),
|
|
||||||
decoration: decoration,
|
decoration: decoration,
|
||||||
onChanged: (text) {
|
onChanged: (text) {
|
||||||
// fix for the library for now
|
// fix for the library for now
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
|
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
|
||||||
import 'events/audio_player.dart';
|
import 'events/audio_player.dart';
|
||||||
|
|
||||||
class RecordingViewModel extends StatefulWidget {
|
class RecordingViewModel extends StatefulWidget {
|
||||||
|
|
@ -62,8 +61,6 @@ class RecordingViewModelState extends State<RecordingViewModel> {
|
||||||
}
|
}
|
||||||
if (await AudioRecorder().hasPermission() == false) return;
|
if (await AudioRecorder().hasPermission() == false) return;
|
||||||
|
|
||||||
final store = Matrix.of(context).store;
|
|
||||||
|
|
||||||
final audioRecorder = _audioRecorder ??= AudioRecorder();
|
final audioRecorder = _audioRecorder ??= AudioRecorder();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|
||||||
|
|
@ -93,12 +90,12 @@ class RecordingViewModelState extends State<RecordingViewModel> {
|
||||||
|
|
||||||
await audioRecorder.start(
|
await audioRecorder.start(
|
||||||
RecordConfig(
|
RecordConfig(
|
||||||
bitRate: AppSettings.audioRecordingBitRate.getItem(store),
|
bitRate: AppSettings.audioRecordingBitRate.value,
|
||||||
sampleRate: AppSettings.audioRecordingSamplingRate.getItem(store),
|
sampleRate: AppSettings.audioRecordingSamplingRate.value,
|
||||||
numChannels: AppSettings.audioRecordingNumChannels.getItem(store),
|
numChannels: AppSettings.audioRecordingNumChannels.value,
|
||||||
autoGain: AppSettings.audioRecordingAutoGain.getItem(store),
|
autoGain: AppSettings.audioRecordingAutoGain.value,
|
||||||
echoCancel: AppSettings.audioRecordingEchoCancel.getItem(store),
|
echoCancel: AppSettings.audioRecordingEchoCancel.value,
|
||||||
noiseSuppress: AppSettings.audioRecordingNoiseSuppress.getItem(store),
|
noiseSuppress: AppSettings.audioRecordingNoiseSuppress.value,
|
||||||
encoder: codec,
|
encoder: codec,
|
||||||
),
|
),
|
||||||
path: path ?? '',
|
path: path ?? '',
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import 'package:matrix/matrix.dart' as sdk;
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:receive_sharing_intent/receive_sharing_intent.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/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/pages/chat_list/chat_list_view.dart';
|
import 'package:fluffychat/pages/chat_list/chat_list_view.dart';
|
||||||
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||||
|
|
@ -94,9 +93,7 @@ class ChatListController extends State<ChatList>
|
||||||
|
|
||||||
StreamSubscription? _intentUriStreamSubscription;
|
StreamSubscription? _intentUriStreamSubscription;
|
||||||
|
|
||||||
ActiveFilter activeFilter = AppConfig.separateChatTypes
|
late ActiveFilter activeFilter;
|
||||||
? ActiveFilter.messages
|
|
||||||
: ActiveFilter.allChats;
|
|
||||||
|
|
||||||
String? _activeSpaceId;
|
String? _activeSpaceId;
|
||||||
String? get activeSpaceId => _activeSpaceId;
|
String? get activeSpaceId => _activeSpaceId;
|
||||||
|
|
@ -401,6 +398,9 @@ class ChatListController extends State<ChatList>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
activeFilter = AppSettings.separateChatTypes.value
|
||||||
|
? ActiveFilter.messages
|
||||||
|
: ActiveFilter.allChats;
|
||||||
_initReceiveSharingIntent();
|
_initReceiveSharingIntent();
|
||||||
_activeSpaceId = widget.activeSpace;
|
_activeSpaceId = widget.activeSpace;
|
||||||
|
|
||||||
|
|
@ -713,8 +713,7 @@ class ChatListController extends State<ChatList>
|
||||||
context: context,
|
context: context,
|
||||||
);
|
);
|
||||||
if (result == OkCancelResult.ok) {
|
if (result == OkCancelResult.ok) {
|
||||||
await Matrix.of(context).store.setBool(SettingKeys.showPresences, false);
|
AppSettings.showPresences.setItem(false);
|
||||||
AppConfig.showPresences = false;
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:matrix/matrix.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/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/pages/chat_list/chat_list.dart';
|
import 'package:fluffychat/pages/chat_list/chat_list.dart';
|
||||||
import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
|
import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
|
||||||
|
|
@ -120,7 +120,8 @@ class ChatListViewBody extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
if (!controller.isSearchMode && AppConfig.showPresences)
|
if (!controller.isSearchMode &&
|
||||||
|
AppSettings.showPresences.value)
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onLongPress: () => controller.dismissStatusList(),
|
onLongPress: () => controller.dismissStatusList(),
|
||||||
child: StatusMessageList(
|
child: StatusMessageList(
|
||||||
|
|
@ -155,14 +156,14 @@ class ChatListViewBody extends StatelessWidget {
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
children: [
|
children: [
|
||||||
if (AppConfig.separateChatTypes)
|
if (AppSettings.separateChatTypes.value)
|
||||||
ActiveFilter.messages
|
ActiveFilter.messages
|
||||||
else
|
else
|
||||||
ActiveFilter.allChats,
|
ActiveFilter.allChats,
|
||||||
ActiveFilter.groups,
|
ActiveFilter.groups,
|
||||||
ActiveFilter.unread,
|
ActiveFilter.unread,
|
||||||
if (spaceDelegateCandidates.isNotEmpty &&
|
if (spaceDelegateCandidates.isNotEmpty &&
|
||||||
!AppConfig.displayNavigationRail &&
|
!AppSettings.displayNavigationRail.value &&
|
||||||
!FluffyThemes.isColumnMode(context))
|
!FluffyThemes.isColumnMode(context))
|
||||||
ActiveFilter.spaces,
|
ActiveFilter.spaces,
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:go_router/go_router.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/config/themes.dart';
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/pages/chat_list/chat_list.dart';
|
import 'package:fluffychat/pages/chat_list/chat_list.dart';
|
||||||
|
|
@ -32,7 +32,7 @@ class ChatListView extends StatelessWidget {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
if (FluffyThemes.isColumnMode(context) ||
|
if (FluffyThemes.isColumnMode(context) ||
|
||||||
AppConfig.displayNavigationRail) ...[
|
AppSettings.displayNavigationRail.value) ...[
|
||||||
SpacesNavigationRail(
|
SpacesNavigationRail(
|
||||||
activeSpaceId: controller.activeSpaceId,
|
activeSpaceId: controller.activeSpaceId,
|
||||||
onGoToChats: controller.clearActiveSpace,
|
onGoToChats: controller.clearActiveSpace,
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import 'package:universal_html/html.dart' as html;
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart';
|
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart';
|
||||||
import 'package:fluffychat/utils/file_selector.dart';
|
import 'package:fluffychat/utils/file_selector.dart';
|
||||||
|
|
@ -34,7 +35,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
|
|
||||||
final TextEditingController homeserverController = TextEditingController(
|
final TextEditingController homeserverController = TextEditingController(
|
||||||
text: AppConfig.defaultHomeserver,
|
text: AppSettings.defaultHomeserver.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
String? error;
|
String? error;
|
||||||
|
|
@ -211,7 +212,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
|
||||||
case MoreLoginActions.importBackup:
|
case MoreLoginActions.importBackup:
|
||||||
restoreBackup();
|
restoreBackup();
|
||||||
case MoreLoginActions.privacy:
|
case MoreLoginActions.privacy:
|
||||||
launchUrlString(AppConfig.privacyUrl);
|
launchUrlString(AppSettings.privacyUrl.value);
|
||||||
case MoreLoginActions.about:
|
case MoreLoginActions.about:
|
||||||
PlatformInfos.showDialog(context);
|
PlatformInfos.showDialog(context);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
|
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
|
||||||
import 'package:fluffychat/widgets/layouts/login_scaffold.dart';
|
import 'package:fluffychat/widgets/layouts/login_scaffold.dart';
|
||||||
|
|
@ -155,7 +156,7 @@ class HomeserverPickerView extends StatelessWidget {
|
||||||
AppConfig.borderRadius,
|
AppConfig.borderRadius,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
hintText: AppConfig.defaultHomeserver,
|
hintText: AppSettings.defaultHomeserver.value,
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
color: theme.colorScheme.surfaceTint,
|
color: theme.colorScheme.surfaceTint,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import 'package:go_router/go_router.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/config/themes.dart';
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/fluffy_share.dart';
|
import 'package:fluffychat/utils/fluffy_share.dart';
|
||||||
|
|
@ -244,7 +244,7 @@ class SettingsView extends StatelessWidget {
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.privacy_tip_outlined),
|
leading: const Icon(Icons.privacy_tip_outlined),
|
||||||
title: Text(L10n.of(context).privacy),
|
title: Text(L10n.of(context).privacy),
|
||||||
onTap: () => launchUrlString(AppConfig.privacyUrl),
|
onTap: () => launchUrlString(AppSettings.privacyUrl.value),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.info_outline_rounded),
|
leading: const Icon(Icons.info_outline_rounded),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:go_router/go_router.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/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/config/themes.dart';
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
|
|
@ -34,41 +33,29 @@ class SettingsChatView extends StatelessWidget {
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).formattedMessages,
|
title: L10n.of(context).formattedMessages,
|
||||||
subtitle: L10n.of(context).formattedMessagesDescription,
|
subtitle: L10n.of(context).formattedMessagesDescription,
|
||||||
onChanged: (b) => AppConfig.renderHtml = b,
|
setting: AppSettings.renderHtml,
|
||||||
storeKey: SettingKeys.renderHtml,
|
|
||||||
defaultValue: AppConfig.renderHtml,
|
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).hideRedactedMessages,
|
title: L10n.of(context).hideRedactedMessages,
|
||||||
subtitle: L10n.of(context).hideRedactedMessagesBody,
|
subtitle: L10n.of(context).hideRedactedMessagesBody,
|
||||||
onChanged: (b) => AppConfig.hideRedactedEvents = b,
|
setting: AppSettings.hideRedactedEvents,
|
||||||
storeKey: SettingKeys.hideRedactedEvents,
|
|
||||||
defaultValue: AppConfig.hideRedactedEvents,
|
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).hideInvalidOrUnknownMessageFormats,
|
title: L10n.of(context).hideInvalidOrUnknownMessageFormats,
|
||||||
onChanged: (b) => AppConfig.hideUnknownEvents = b,
|
setting: AppSettings.hideUnknownEvents,
|
||||||
storeKey: SettingKeys.hideUnknownEvents,
|
|
||||||
defaultValue: AppConfig.hideUnknownEvents,
|
|
||||||
),
|
),
|
||||||
if (PlatformInfos.isMobile)
|
if (PlatformInfos.isMobile)
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).autoplayImages,
|
title: L10n.of(context).autoplayImages,
|
||||||
onChanged: (b) => AppConfig.autoplayImages = b,
|
setting: AppSettings.autoplayImages,
|
||||||
storeKey: SettingKeys.autoplayImages,
|
|
||||||
defaultValue: AppConfig.autoplayImages,
|
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).sendOnEnter,
|
title: L10n.of(context).sendOnEnter,
|
||||||
onChanged: (b) => AppConfig.sendOnEnter = b,
|
setting: AppSettings.sendOnEnter,
|
||||||
storeKey: SettingKeys.sendOnEnter,
|
|
||||||
defaultValue: AppConfig.sendOnEnter ?? !PlatformInfos.isMobile,
|
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).swipeRightToLeftToReply,
|
title: L10n.of(context).swipeRightToLeftToReply,
|
||||||
onChanged: (b) => AppConfig.swipeRightToLeftToReply = b,
|
setting: AppSettings.swipeRightToLeftToReply,
|
||||||
storeKey: SettingKeys.swipeRightToLeftToReply,
|
|
||||||
defaultValue: AppConfig.swipeRightToLeftToReply,
|
|
||||||
),
|
),
|
||||||
Divider(color: theme.dividerColor),
|
Divider(color: theme.dividerColor),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
|
@ -102,12 +89,10 @@ class SettingsChatView extends StatelessWidget {
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).experimentalVideoCalls,
|
title: L10n.of(context).experimentalVideoCalls,
|
||||||
onChanged: (b) {
|
onChanged: (b) {
|
||||||
AppConfig.experimentalVoip = b;
|
|
||||||
Matrix.of(context).createVoipPlugin();
|
Matrix.of(context).createVoipPlugin();
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
storeKey: SettingKeys.experimentalVoip,
|
setting: AppSettings.experimentalVoip,
|
||||||
defaultValue: AppConfig.experimentalVoip,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,6 @@ class SettingsSecurityController extends State<SettingsSecurity> {
|
||||||
void changeShareKeysWith(ShareKeysWith? shareKeysWith) async {
|
void changeShareKeysWith(ShareKeysWith? shareKeysWith) async {
|
||||||
if (shareKeysWith == null) return;
|
if (shareKeysWith == null) return;
|
||||||
AppSettings.shareKeysWith.setItem(
|
AppSettings.shareKeysWith.setItem(
|
||||||
Matrix.of(context).store,
|
|
||||||
shareKeysWith.name,
|
shareKeysWith.name,
|
||||||
);
|
);
|
||||||
Matrix.of(context).client.shareKeysWith = shareKeysWith;
|
Matrix.of(context).client.shareKeysWith = shareKeysWith;
|
||||||
|
|
|
||||||
|
|
@ -63,16 +63,12 @@ class SettingsSecurityView extends StatelessWidget {
|
||||||
title: L10n.of(context).sendTypingNotifications,
|
title: L10n.of(context).sendTypingNotifications,
|
||||||
subtitle:
|
subtitle:
|
||||||
L10n.of(context).sendTypingNotificationsDescription,
|
L10n.of(context).sendTypingNotificationsDescription,
|
||||||
onChanged: (b) => AppConfig.sendTypingNotifications = b,
|
setting: AppSettings.sendTypingNotifications,
|
||||||
storeKey: SettingKeys.sendTypingNotifications,
|
|
||||||
defaultValue: AppConfig.sendTypingNotifications,
|
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).sendReadReceipts,
|
title: L10n.of(context).sendReadReceipts,
|
||||||
subtitle: L10n.of(context).sendReadReceiptsDescription,
|
subtitle: L10n.of(context).sendReadReceiptsDescription,
|
||||||
onChanged: (b) => AppConfig.sendPublicReadReceipts = b,
|
setting: AppSettings.sendPublicReadReceipts,
|
||||||
storeKey: SettingKeys.sendPublicReadReceipts,
|
|
||||||
defaultValue: AppConfig.sendPublicReadReceipts,
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
trailing: const Icon(Icons.chevron_right_outlined),
|
trailing: const Icon(Icons.chevron_right_outlined),
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ class SettingsStyle extends StatefulWidget {
|
||||||
|
|
||||||
class SettingsStyleController extends State<SettingsStyle> {
|
class SettingsStyleController extends State<SettingsStyle> {
|
||||||
void setChatColor(Color? color) async {
|
void setChatColor(Color? color) async {
|
||||||
AppConfig.colorSchemeSeed = color;
|
AppSettings.colorSchemeSeedInt.setItem(
|
||||||
|
color?.toARGB32() ?? AppSettings.colorSchemeSeedInt.defaultValue,
|
||||||
|
);
|
||||||
ThemeController.of(context).setPrimaryColor(color);
|
ThemeController.of(context).setPrimaryColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,11 +158,7 @@ class SettingsStyleController extends State<SettingsStyle> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeFontSizeFactor(double d) {
|
void changeFontSizeFactor(double d) {
|
||||||
setState(() => AppConfig.fontSizeFactor = d);
|
AppSettings.fontSizeFactor.setItem(d);
|
||||||
Matrix.of(context).store.setString(
|
|
||||||
SettingKeys.fontSizeFactor,
|
|
||||||
AppConfig.fontSizeFactor.toString(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ class SettingsStyleView extends StatelessWidget {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: theme.onBubbleColor,
|
color: theme.onBubbleColor,
|
||||||
fontSize: AppConfig.messageFontSize *
|
fontSize: AppConfig.messageFontSize *
|
||||||
AppConfig.fontSizeFactor,
|
AppSettings.fontSizeFactor.value,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -263,7 +263,7 @@ class SettingsStyleView extends StatelessWidget {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: theme.colorScheme.onSurface,
|
color: theme.colorScheme.onSurface,
|
||||||
fontSize: AppConfig.messageFontSize *
|
fontSize: AppConfig.messageFontSize *
|
||||||
AppConfig.fontSizeFactor,
|
AppSettings.fontSizeFactor.value,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -325,13 +325,15 @@ class SettingsStyleView extends StatelessWidget {
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(L10n.of(context).fontSize),
|
title: Text(L10n.of(context).fontSize),
|
||||||
trailing: Text('× ${AppConfig.fontSizeFactor}'),
|
trailing: Text(
|
||||||
|
'× ${AppSettings.fontSizeFactor.value}',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Slider.adaptive(
|
Slider.adaptive(
|
||||||
min: 0.5,
|
min: 0.5,
|
||||||
max: 2.5,
|
max: 2.5,
|
||||||
divisions: 20,
|
divisions: 20,
|
||||||
value: AppConfig.fontSizeFactor,
|
value: AppSettings.fontSizeFactor.value,
|
||||||
semanticFormatterCallback: (d) => d.toString(),
|
semanticFormatterCallback: (d) => d.toString(),
|
||||||
onChanged: controller.changeFontSizeFactor,
|
onChanged: controller.changeFontSizeFactor,
|
||||||
),
|
),
|
||||||
|
|
@ -349,21 +351,15 @@ class SettingsStyleView extends StatelessWidget {
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).presencesToggle,
|
title: L10n.of(context).presencesToggle,
|
||||||
onChanged: (b) => AppConfig.showPresences = b,
|
setting: AppSettings.showPresences,
|
||||||
storeKey: SettingKeys.showPresences,
|
|
||||||
defaultValue: AppConfig.showPresences,
|
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).separateChatTypes,
|
title: L10n.of(context).separateChatTypes,
|
||||||
onChanged: (b) => AppConfig.separateChatTypes = b,
|
setting: AppSettings.separateChatTypes,
|
||||||
storeKey: SettingKeys.separateChatTypes,
|
|
||||||
defaultValue: AppConfig.separateChatTypes,
|
|
||||||
),
|
),
|
||||||
SettingsSwitchListTile.adaptive(
|
SettingsSwitchListTile.adaptive(
|
||||||
title: L10n.of(context).displayNavigationRail,
|
title: L10n.of(context).displayNavigationRail,
|
||||||
onChanged: (b) => AppConfig.displayNavigationRail = b,
|
setting: AppSettings.displayNavigationRail,
|
||||||
storeKey: SettingKeys.displayNavigationRail,
|
|
||||||
defaultValue: AppConfig.displayNavigationRail,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -217,8 +217,7 @@ class BackgroundPush {
|
||||||
currentPushers.first.lang == 'en' &&
|
currentPushers.first.lang == 'en' &&
|
||||||
currentPushers.first.data.url.toString() == gatewayUrl &&
|
currentPushers.first.data.url.toString() == gatewayUrl &&
|
||||||
currentPushers.first.data.format ==
|
currentPushers.first.data.format ==
|
||||||
AppSettings.pushNotificationsPusherFormat
|
AppSettings.pushNotificationsPusherFormat.value &&
|
||||||
.getItem(matrix!.store) &&
|
|
||||||
mapEquals(
|
mapEquals(
|
||||||
currentPushers.single.data.additionalProperties,
|
currentPushers.single.data.additionalProperties,
|
||||||
{"data_message": pusherDataMessageFormat},
|
{"data_message": pusherDataMessageFormat},
|
||||||
|
|
@ -258,8 +257,7 @@ class BackgroundPush {
|
||||||
lang: 'en',
|
lang: 'en',
|
||||||
data: PusherData(
|
data: PusherData(
|
||||||
url: Uri.parse(gatewayUrl!),
|
url: Uri.parse(gatewayUrl!),
|
||||||
format: AppSettings.pushNotificationsPusherFormat
|
format: AppSettings.pushNotificationsPusherFormat.value,
|
||||||
.getItem(matrix!.store),
|
|
||||||
additionalProperties: {"data_message": pusherDataMessageFormat},
|
additionalProperties: {"data_message": pusherDataMessageFormat},
|
||||||
),
|
),
|
||||||
kind: 'http',
|
kind: 'http',
|
||||||
|
|
@ -325,7 +323,7 @@ class BackgroundPush {
|
||||||
if (matrix == null) {
|
if (matrix == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((matrix?.store.getBool(SettingKeys.showNoGoogle) ?? false) == true) {
|
if (!AppSettings.showNoGoogle.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await loadLocale();
|
await loadLocale();
|
||||||
|
|
@ -356,8 +354,7 @@ class BackgroundPush {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await setupPusher(
|
await setupPusher(
|
||||||
gatewayUrl:
|
gatewayUrl: AppSettings.pushNotificationsGatewayUrl.value,
|
||||||
AppSettings.pushNotificationsGatewayUrl.getItem(matrix!.store),
|
|
||||||
token: _fcmToken,
|
token: _fcmToken,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -414,18 +411,18 @@ class BackgroundPush {
|
||||||
oldTokens: oldTokens,
|
oldTokens: oldTokens,
|
||||||
useDeviceSpecificAppId: true,
|
useDeviceSpecificAppId: true,
|
||||||
);
|
);
|
||||||
await matrix?.store.setString(SettingKeys.unifiedPushEndpoint, newEndpoint);
|
await AppSettings.unifiedPushEndpoint.setItem(newEndpoint);
|
||||||
await matrix?.store.setBool(SettingKeys.unifiedPushRegistered, true);
|
await AppSettings.unifiedPushRegistered.setItem(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _upUnregistered(String i) async {
|
Future<void> _upUnregistered(String i) async {
|
||||||
upAction = true;
|
upAction = true;
|
||||||
Logs().i('[Push] Removing UnifiedPush endpoint...');
|
Logs().i('[Push] Removing UnifiedPush endpoint...');
|
||||||
final oldEndpoint =
|
final oldEndpoint = AppSettings.unifiedPushEndpoint.value;
|
||||||
matrix?.store.getString(SettingKeys.unifiedPushEndpoint);
|
await AppSettings.unifiedPushEndpoint
|
||||||
await matrix?.store.setBool(SettingKeys.unifiedPushRegistered, false);
|
.setItem(AppSettings.unifiedPushEndpoint.defaultValue);
|
||||||
await matrix?.store.remove(SettingKeys.unifiedPushEndpoint);
|
await AppSettings.unifiedPushRegistered.setItem(false);
|
||||||
if (oldEndpoint?.isNotEmpty ?? false) {
|
if (oldEndpoint.isNotEmpty) {
|
||||||
// remove the old pusher
|
// remove the old pusher
|
||||||
await setupPusher(
|
await setupPusher(
|
||||||
oldTokens: {oldEndpoint},
|
oldTokens: {oldEndpoint},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import 'package:matrix/matrix.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
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/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/custom_http_client.dart';
|
import 'package:fluffychat/utils/custom_http_client.dart';
|
||||||
|
|
@ -101,8 +100,8 @@ abstract class ClientManager {
|
||||||
String clientName,
|
String clientName,
|
||||||
SharedPreferences store,
|
SharedPreferences store,
|
||||||
) async {
|
) async {
|
||||||
final shareKeysWith = AppSettings.shareKeysWith.getItem(store);
|
final shareKeysWith = AppSettings.shareKeysWith.value;
|
||||||
final enableSoftLogout = AppSettings.enableSoftLogout.getItem(store);
|
final enableSoftLogout = AppSettings.enableSoftLogout.value;
|
||||||
|
|
||||||
return Client(
|
return Client(
|
||||||
clientName,
|
clientName,
|
||||||
|
|
@ -147,7 +146,7 @@ abstract class ClientManager {
|
||||||
await NotificationsClient().notify(
|
await NotificationsClient().notify(
|
||||||
title,
|
title,
|
||||||
body: body,
|
body: body,
|
||||||
appName: AppConfig.applicationName,
|
appName: AppSettings.applicationName.value,
|
||||||
hints: [
|
hints: [
|
||||||
NotificationHint.soundName('message-new-instant'),
|
NotificationHint.soundName('message-new-instant'),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/client_manager.dart';
|
import 'package:fluffychat/utils/client_manager.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
|
|
@ -57,13 +58,13 @@ extension InitWithRestoreExtension on Client {
|
||||||
? const FlutterSecureStorage()
|
? const FlutterSecureStorage()
|
||||||
: null;
|
: null;
|
||||||
await storage?.delete(
|
await storage?.delete(
|
||||||
key: '${AppConfig.applicationName}_session_backup_$clientName',
|
key: '${AppSettings.applicationName.value}_session_backup_$clientName',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initWithRestore({void Function()? onMigration}) async {
|
Future<void> initWithRestore({void Function()? onMigration}) async {
|
||||||
final storageKey =
|
final storageKey =
|
||||||
'${AppConfig.applicationName}_session_backup_$clientName';
|
'${AppSettings.applicationName.value}_session_backup_$clientName';
|
||||||
final storage = PlatformInfos.isMobile || PlatformInfos.isLinux
|
final storage = PlatformInfos.isMobile || PlatformInfos.isLinux
|
||||||
? const FlutterSecureStorage()
|
? const FlutterSecureStorage()
|
||||||
: null;
|
: null;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import '../../config/app_config.dart';
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
|
|
||||||
extension VisibleInGuiExtension on List<Event> {
|
extension VisibleInGuiExtension on List<Event> {
|
||||||
List<Event> filterByVisibleInGui({String? exceptionEventId}) => where(
|
List<Event> filterByVisibleInGui({
|
||||||
|
String? exceptionEventId,
|
||||||
|
}) =>
|
||||||
|
where(
|
||||||
(event) => event.isVisibleInGui || event.eventId == exceptionEventId,
|
(event) => event.isVisibleInGui || event.eventId == exceptionEventId,
|
||||||
).toList();
|
).toList();
|
||||||
}
|
}
|
||||||
|
|
@ -19,9 +22,9 @@ extension IsStateExtension on Event {
|
||||||
// if a reaction has been redacted we also want it to be hidden in the timeline
|
// if a reaction has been redacted we also want it to be hidden in the timeline
|
||||||
!{EventTypes.Reaction, EventTypes.Redaction}.contains(type) &&
|
!{EventTypes.Reaction, EventTypes.Redaction}.contains(type) &&
|
||||||
// if we enabled to hide all redacted events, don't show those
|
// 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
|
// if we enabled to hide all unknown events, don't show those
|
||||||
(!AppConfig.hideUnknownEvents || isEventTypeKnown);
|
(!AppSettings.hideUnknownEvents.value || isEventTypeKnown);
|
||||||
|
|
||||||
bool get isState => !{
|
bool get isState => !{
|
||||||
EventTypes.Message,
|
EventTypes.Message,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
import 'package:fluffychat/config/setting_keys.dart';
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
|
|
@ -52,8 +51,7 @@ Future<String?> getDatabaseCipher() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _sendNoEncryptionWarning(Object exception) async {
|
void _sendNoEncryptionWarning(Object exception) async {
|
||||||
final store = await SharedPreferences.getInstance();
|
final isStored = AppSettings.noEncryptionWarningShown.value;
|
||||||
final isStored = AppSettings.noEncryptionWarningShown.getItem(store);
|
|
||||||
|
|
||||||
if (isStored == true) return;
|
if (isStored == true) return;
|
||||||
|
|
||||||
|
|
@ -63,5 +61,5 @@ void _sendNoEncryptionWarning(Object exception) async {
|
||||||
exception.toString(),
|
exception.toString(),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppSettings.noEncryptionWarningShown.setItem(store, true);
|
await AppSettings.noEncryptionWarningShown.setItem(true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:flutter_vodozemac/flutter_vodozemac.dart' as vod;
|
import 'package:flutter_vodozemac/flutter_vodozemac.dart' as vod;
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/client_download_content_extension.dart';
|
import 'package:fluffychat/utils/client_download_content_extension.dart';
|
||||||
|
|
@ -59,7 +58,7 @@ void notificationTapBackground(
|
||||||
await vod.init();
|
await vod.init();
|
||||||
_vodInitialized = true;
|
_vodInitialized = true;
|
||||||
}
|
}
|
||||||
final store = await SharedPreferences.getInstance();
|
final store = await AppSettings.init();
|
||||||
final client = (await ClientManager.getClients(
|
final client = (await ClientManager.getClients(
|
||||||
initialize: false,
|
initialize: false,
|
||||||
store: store,
|
store: store,
|
||||||
|
|
@ -71,10 +70,6 @@ void notificationTapBackground(
|
||||||
waitUntilLoadCompletedLoaded: false,
|
waitUntilLoadCompletedLoaded: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
AppConfig.sendPublicReadReceipts =
|
|
||||||
store.getBool(SettingKeys.sendPublicReadReceipts) ??
|
|
||||||
AppConfig.sendPublicReadReceipts;
|
|
||||||
|
|
||||||
if (!client.isLogged()) {
|
if (!client.isLogged()) {
|
||||||
throw Exception('Notification tab in background but not logged in!');
|
throw Exception('Notification tab in background but not logged in!');
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +140,7 @@ Future<void> notificationTap(
|
||||||
await room.setReadMarker(
|
await room.setReadMarker(
|
||||||
payload.eventId ?? room.lastEvent!.eventId,
|
payload.eventId ?? room.lastEvent!.eventId,
|
||||||
mRead: payload.eventId ?? room.lastEvent!.eventId,
|
mRead: payload.eventId ?? room.lastEvent!.eventId,
|
||||||
public: AppConfig.sendPublicReadReceipts,
|
public: AppSettings.sendPublicReadReceipts.value,
|
||||||
);
|
);
|
||||||
case FluffyChatNotificationActions.reply:
|
case FluffyChatNotificationActions.reply:
|
||||||
final input = notificationResponse.input;
|
final input = notificationResponse.input;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import 'package:go_router/go_router.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import '../config/app_config.dart';
|
import '../config/app_config.dart';
|
||||||
|
|
||||||
|
|
@ -36,7 +37,7 @@ abstract class PlatformInfos {
|
||||||
static bool get platformCanRecord => (isMobile || isMacOS);
|
static bool get platformCanRecord => (isMobile || isMacOS);
|
||||||
|
|
||||||
static String get clientName =>
|
static String get clientName =>
|
||||||
'${AppConfig.applicationName} ${isWeb ? 'web' : Platform.operatingSystem}${kReleaseMode ? '' : 'Debug'}';
|
'${AppSettings.applicationName.value} ${isWeb ? 'web' : Platform.operatingSystem}${kReleaseMode ? '' : 'Debug'}';
|
||||||
|
|
||||||
static Future<String> getVersion() async {
|
static Future<String> getVersion() async {
|
||||||
var version = kIsWeb ? 'Web' : 'Unknown';
|
var version = kIsWeb ? 'Web' : 'Unknown';
|
||||||
|
|
@ -88,7 +89,7 @@ abstract class PlatformInfos {
|
||||||
height: 64,
|
height: 64,
|
||||||
filterQuality: FilterQuality.medium,
|
filterQuality: FilterQuality.medium,
|
||||||
),
|
),
|
||||||
applicationName: AppConfig.applicationName,
|
applicationName: AppSettings.applicationName.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ import 'package:collection/collection.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:flutter_shortcuts_new/flutter_shortcuts_new.dart';
|
import 'package:flutter_shortcuts_new/flutter_shortcuts_new.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/client_download_content_extension.dart';
|
import 'package:fluffychat/utils/client_download_content_extension.dart';
|
||||||
import 'package:fluffychat/utils/client_manager.dart';
|
import 'package:fluffychat/utils/client_manager.dart';
|
||||||
|
|
@ -50,7 +50,7 @@ Future<void> pushHelper(
|
||||||
l10n.incomingMessages,
|
l10n.incomingMessages,
|
||||||
number: notification.counts?.unread,
|
number: notification.counts?.unread,
|
||||||
ticker: l10n.unreadChatsInApp(
|
ticker: l10n.unreadChatsInApp(
|
||||||
AppConfig.applicationName,
|
AppSettings.applicationName.value,
|
||||||
(notification.counts?.unread ?? 0).toString(),
|
(notification.counts?.unread ?? 0).toString(),
|
||||||
),
|
),
|
||||||
importance: Importance.high,
|
importance: Importance.high,
|
||||||
|
|
@ -85,7 +85,7 @@ Future<void> _tryPushHelper(
|
||||||
|
|
||||||
client ??= (await ClientManager.getClients(
|
client ??= (await ClientManager.getClients(
|
||||||
initialize: false,
|
initialize: false,
|
||||||
store: await SharedPreferences.getInstance(),
|
store: await AppSettings.init(),
|
||||||
))
|
))
|
||||||
.first;
|
.first;
|
||||||
final event = await client.getEventByPushNotification(
|
final event = await client.getEventByPushNotification(
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/setting_keys.dart';
|
|
||||||
import 'package:fluffychat/widgets/lock_screen.dart';
|
import 'package:fluffychat/widgets/lock_screen.dart';
|
||||||
|
|
||||||
class AppLockWidget extends StatefulWidget {
|
class AppLockWidget extends StatefulWidget {
|
||||||
|
|
@ -65,7 +64,7 @@ class AppLock extends State<AppLockWidget> with WidgetsBindingObserver {
|
||||||
|
|
||||||
Future<void> changePincode(String? pincode) async {
|
Future<void> changePincode(String? pincode) async {
|
||||||
await const FlutterSecureStorage().write(
|
await const FlutterSecureStorage().write(
|
||||||
key: SettingKeys.appLockKey,
|
key: 'chat.fluffy.app_lock',
|
||||||
value: pincode,
|
value: pincode,
|
||||||
);
|
);
|
||||||
_pincode = pincode;
|
_pincode = pincode;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class _ConfigViewerState extends State<ConfigViewer> {
|
||||||
String initialValue,
|
String initialValue,
|
||||||
) async {
|
) async {
|
||||||
if (appSetting is AppSettings<bool>) {
|
if (appSetting is AppSettings<bool>) {
|
||||||
await appSetting.setItem(store, !(initialValue == 'true'));
|
await appSetting.setItem(!(initialValue == 'true'));
|
||||||
setState(() {});
|
setState(() {});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -35,13 +35,13 @@ class _ConfigViewerState extends State<ConfigViewer> {
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
|
|
||||||
if (appSetting is AppSettings<String>) {
|
if (appSetting is AppSettings<String>) {
|
||||||
await appSetting.setItem(store, value);
|
await appSetting.setItem(value);
|
||||||
}
|
}
|
||||||
if (appSetting is AppSettings<int>) {
|
if (appSetting is AppSettings<int>) {
|
||||||
await appSetting.setItem(store, int.parse(value));
|
await appSetting.setItem(int.parse(value));
|
||||||
}
|
}
|
||||||
if (appSetting is AppSettings<double>) {
|
if (appSetting is AppSettings<double>) {
|
||||||
await appSetting.setItem(store, double.parse(value));
|
await appSetting.setItem(double.parse(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|
@ -78,16 +78,16 @@ class _ConfigViewerState extends State<ConfigViewer> {
|
||||||
final appSetting = AppSettings.values[i];
|
final appSetting = AppSettings.values[i];
|
||||||
var value = '';
|
var value = '';
|
||||||
if (appSetting is AppSettings<String>) {
|
if (appSetting is AppSettings<String>) {
|
||||||
value = appSetting.getItem(store);
|
value = appSetting.value;
|
||||||
}
|
}
|
||||||
if (appSetting is AppSettings<int>) {
|
if (appSetting is AppSettings<int>) {
|
||||||
value = appSetting.getItem(store).toString();
|
value = appSetting.value.toString();
|
||||||
}
|
}
|
||||||
if (appSetting is AppSettings<bool>) {
|
if (appSetting is AppSettings<bool>) {
|
||||||
value = appSetting.getItem(store).toString();
|
value = appSetting.value.toString();
|
||||||
}
|
}
|
||||||
if (appSetting is AppSettings<double>) {
|
if (appSetting is AppSettings<double>) {
|
||||||
value = appSetting.getItem(store).toString();
|
value = appSetting.value.toString();
|
||||||
}
|
}
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(appSetting.name),
|
title: Text(appSetting.name),
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ import 'package:matrix/matrix.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/routes.dart';
|
import 'package:fluffychat/config/routes.dart';
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/config/themes.dart';
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/widgets/app_lock.dart';
|
import 'package:fluffychat/widgets/app_lock.dart';
|
||||||
import 'package:fluffychat/widgets/theme_builder.dart';
|
import 'package:fluffychat/widgets/theme_builder.dart';
|
||||||
import '../config/app_config.dart';
|
|
||||||
import '../utils/custom_scroll_behaviour.dart';
|
import '../utils/custom_scroll_behaviour.dart';
|
||||||
import 'matrix.dart';
|
import 'matrix.dart';
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ class FluffyChatApp extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ThemeBuilder(
|
return ThemeBuilder(
|
||||||
builder: (context, themeMode, primaryColor) => MaterialApp.router(
|
builder: (context, themeMode, primaryColor) => MaterialApp.router(
|
||||||
title: AppConfig.applicationName,
|
title: AppSettings.applicationName.value,
|
||||||
themeMode: themeMode,
|
themeMode: themeMode,
|
||||||
theme: FluffyThemes.buildTheme(context, Brightness.light, primaryColor),
|
theme: FluffyThemes.buildTheme(context, Brightness.light, primaryColor),
|
||||||
darkTheme:
|
darkTheme:
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/config/app_config.dart';
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
import 'package:fluffychat/config/themes.dart';
|
import 'package:fluffychat/config/themes.dart';
|
||||||
import 'package:fluffychat/l10n/l10n.dart';
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
import 'package:fluffychat/utils/platform_infos.dart';
|
||||||
|
|
@ -107,7 +108,7 @@ class _PrivacyButtons extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => launchUrlString(AppConfig.privacyUrl),
|
onPressed: () => launchUrlString(AppSettings.privacyUrl.value),
|
||||||
child: Text(
|
child: Text(
|
||||||
L10n.of(context).privacy,
|
L10n.of(context).privacy,
|
||||||
style: shadowTextStyle,
|
style: shadowTextStyle,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import 'package:image/image.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
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/l10n/l10n.dart';
|
||||||
import 'package:fluffychat/utils/client_download_content_extension.dart';
|
import 'package:fluffychat/utils/client_download_content_extension.dart';
|
||||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||||
|
|
@ -114,7 +114,7 @@ extension LocalNotificationsExtension on MatrixState {
|
||||||
title,
|
title,
|
||||||
body: body,
|
body: body,
|
||||||
replacesId: linuxNotificationIds[roomId] ?? 0,
|
replacesId: linuxNotificationIds[roomId] ?? 0,
|
||||||
appName: AppConfig.applicationName,
|
appName: AppSettings.applicationName.value,
|
||||||
appIcon: 'fluffychat',
|
appIcon: 'fluffychat',
|
||||||
actions: [
|
actions: [
|
||||||
NotificationAction(
|
NotificationAction(
|
||||||
|
|
@ -139,7 +139,7 @@ extension LocalNotificationsExtension on MatrixState {
|
||||||
event.room.setReadMarker(
|
event.room.setReadMarker(
|
||||||
event.eventId,
|
event.eventId,
|
||||||
mRead: event.eventId,
|
mRead: event.eventId,
|
||||||
public: AppConfig.sendPublicReadReceipts,
|
public: AppSettings.sendPublicReadReceipts.value,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case DesktopNotificationActions.openChat:
|
case DesktopNotificationActions.openChat:
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:desktop_notifications/desktop_notifications.dart';
|
import 'package:desktop_notifications/desktop_notifications.dart';
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:just_audio/just_audio.dart';
|
import 'package:just_audio/just_audio.dart';
|
||||||
|
|
@ -27,7 +26,6 @@ import 'package:fluffychat/utils/voip_plugin.dart';
|
||||||
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.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/fluffy_chat_app.dart';
|
||||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||||
import '../config/app_config.dart';
|
|
||||||
import '../config/setting_keys.dart';
|
import '../config/setting_keys.dart';
|
||||||
import '../pages/key_verification/key_verification_dialog.dart';
|
import '../pages/key_verification/key_verification_dialog.dart';
|
||||||
import '../utils/account_bundles.dart';
|
import '../utils/account_bundles.dart';
|
||||||
|
|
@ -155,7 +153,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||||
}
|
}
|
||||||
final candidate =
|
final candidate =
|
||||||
_loginClientCandidate ??= await ClientManager.createClient(
|
_loginClientCandidate ??= await ClientManager.createClient(
|
||||||
'${AppConfig.applicationName}-${DateTime.now().millisecondsSinceEpoch}',
|
'${AppSettings.applicationName.value}-${DateTime.now().millisecondsSinceEpoch}',
|
||||||
store,
|
store,
|
||||||
)
|
)
|
||||||
..onLoginStateChanged
|
..onLoginStateChanged
|
||||||
|
|
@ -221,24 +219,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||||
super.initState();
|
super.initState();
|
||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
initMatrix();
|
initMatrix();
|
||||||
if (PlatformInfos.isWeb) {
|
|
||||||
initConfig().then((_) => initSettings());
|
|
||||||
} else {
|
|
||||||
initSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> 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) {
|
void _registerSubs(String name) {
|
||||||
|
|
@ -358,7 +338,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (result == OkCancelResult.cancel) {
|
if (result == OkCancelResult.cancel) {
|
||||||
await store.setBool(SettingKeys.showNoGoogle, true);
|
await AppSettings.showNoGoogle.setItem(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -368,7 +348,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
void createVoipPlugin() async {
|
void createVoipPlugin() async {
|
||||||
if (store.getBool(SettingKeys.experimentalVoip) == false) {
|
if (AppSettings.experimentalVoip.value) {
|
||||||
voipPlugin = null;
|
voipPlugin = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -390,55 +370,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initSettings() {
|
|
||||||
AppConfig.fontSizeFactor =
|
|
||||||
double.tryParse(store.getString(SettingKeys.fontSizeFactor) ?? '') ??
|
|
||||||
AppConfig.fontSizeFactor;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'matrix.dart';
|
import 'package:fluffychat/config/setting_keys.dart';
|
||||||
|
|
||||||
class SettingsSwitchListTile extends StatefulWidget {
|
class SettingsSwitchListTile extends StatefulWidget {
|
||||||
final bool defaultValue;
|
final AppSettings<bool> setting;
|
||||||
final String storeKey;
|
|
||||||
final String title;
|
final String title;
|
||||||
final String? subtitle;
|
final String? subtitle;
|
||||||
final Function(bool)? onChanged;
|
final Function(bool)? onChanged;
|
||||||
|
|
||||||
const SettingsSwitchListTile.adaptive({
|
const SettingsSwitchListTile.adaptive({
|
||||||
super.key,
|
super.key,
|
||||||
this.defaultValue = false,
|
required this.setting,
|
||||||
required this.storeKey,
|
|
||||||
required this.title,
|
required this.title,
|
||||||
this.subtitle,
|
this.subtitle,
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
|
|
@ -27,13 +25,12 @@ class SettingsSwitchListTileState extends State<SettingsSwitchListTile> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final subtitle = widget.subtitle;
|
final subtitle = widget.subtitle;
|
||||||
return SwitchListTile.adaptive(
|
return SwitchListTile.adaptive(
|
||||||
value: Matrix.of(context).store.getBool(widget.storeKey) ??
|
value: widget.setting.value,
|
||||||
widget.defaultValue,
|
|
||||||
title: Text(widget.title),
|
title: Text(widget.title),
|
||||||
subtitle: subtitle == null ? null : Text(subtitle),
|
subtitle: subtitle == null ? null : Text(subtitle),
|
||||||
onChanged: (bool newValue) async {
|
onChanged: (bool newValue) async {
|
||||||
widget.onChanged?.call(newValue);
|
widget.onChanged?.call(newValue);
|
||||||
await Matrix.of(context).store.setBool(widget.storeKey, newValue);
|
await widget.setting.setItem(newValue);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue