Initial commit
This commit is contained in:
264
lib/config/setting_keys.dart
Normal file
264
lib/config/setting_keys.dart
Normal file
@@ -0,0 +1,264 @@
|
||||
// SPDX-FileCopyrightText: 2019-Present Christian Kußowski
|
||||
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:async/async.dart';
|
||||
import 'package:tatchat/utils/platform_infos.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:managed_configurations/managed_configurations.dart';
|
||||
import 'package:matrix/matrix_api_lite/utils/logs.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
enum AppSettings<T> {
|
||||
textMessageMaxLength<int>('textMessageMaxLength', 16384),
|
||||
|
||||
/// Max lines for unselected HTML/text bubbles; 0 = unlimited (no fade).
|
||||
messagePreviewMaxLines<int>('chat.fluffy.message_preview_max_lines', 50),
|
||||
audioRecordingNumChannels<int>('audioRecordingNumChannels', 1),
|
||||
audioRecordingAutoGain<bool>('audioRecordingAutoGain', true),
|
||||
audioRecordingEchoCancel<bool>('audioRecordingEchoCancel', false),
|
||||
audioRecordingNoiseSuppress<bool>('audioRecordingNoiseSuppress', true),
|
||||
audioRecordingBitRate<int>('audioRecordingBitRate', 64000),
|
||||
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',
|
||||
'https://push.fluffychat.im/_matrix/push/v1/notify',
|
||||
),
|
||||
pushNotificationsPusherFormat<String>(
|
||||
'pushNotificationsPusherFormat',
|
||||
'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),
|
||||
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),
|
||||
displayNavigationRail<bool>('chat.fluffy.display_navigation_rail', false),
|
||||
shareKeysWith<String>('chat.fluffy.share_keys_with_2', 'all'),
|
||||
noEncryptionWarningShown<bool>(
|
||||
'chat.fluffy.no_encryption_warning_shown',
|
||||
false,
|
||||
),
|
||||
displayChatDetailsColumn('chat.fluffy.display_chat_details_column', false),
|
||||
// AppConfig-mirrored settings
|
||||
applicationName<String>('chat.fluffy.application_name', 'TatuChat'),
|
||||
defaultHomeserver<String>(
|
||||
'chat.fluffy.default_homeserver',
|
||||
'https://matrix.weltonmoura.com.br',
|
||||
),
|
||||
// colorSchemeSeed stored as ARGB int
|
||||
colorSchemeSeedInt<int>('chat.fluffy.color_scheme_seed', 0xFF00D084),
|
||||
emojiSuggestionLocale<String>('emoji_suggestion_locale', ''),
|
||||
enableSoftLogout<bool>('chat.fluffy.enable_soft_logout', true),
|
||||
enableMatrixNativeOIDC<bool>('chat.fluffy.enable_matrix_native_oidc', true),
|
||||
presetHomeserver<String>(
|
||||
'chat.fluffy.preset_homeserver',
|
||||
'https://matrix.weltonmoura.com.br',
|
||||
),
|
||||
welcomeText<String>('chat.fluffy.welcome_text', ''),
|
||||
website<String>('chat.fluffy.website_url', 'https://fluffychat.im'),
|
||||
logoUrl<String>(
|
||||
'chat.fluffy.logo_url',
|
||||
'https://fluffychat.im/assets/favicon.png',
|
||||
),
|
||||
privacyPolicy<String>(
|
||||
'chat.fluffy.privacy_policy_url',
|
||||
'https://fluffychat.im/privacy',
|
||||
),
|
||||
tos<String>('chat.fluffy.tos_url', 'https://fluffychat.im/tos'),
|
||||
sendTimelineEventTimeout<int>('chat.fluffy.send_timeline_event_timeout', 15),
|
||||
webNotificationSound<bool>('chat.fluffy.web_notification_sound', true),
|
||||
chatFilter<String>('chat.fluffy.chat_filter', 'allChats'),
|
||||
hideRoomsInSpaces<bool>('chat.fluffy.hideRoomsInSpaces', false),
|
||||
showThumbnailsInTimeline<bool>('chat.fluffy.showThumbnailsInTimeline', true),
|
||||
doubleTapToReact<bool>('chat.fluffy.double_tap_to_react', false),
|
||||
doubleTapReaction<String>('chat.fluffy.double_tap_reaction', '❤️'),
|
||||
benchmarksInLogs<bool>('chat.fluffy.benchmarks_in_logs', false),
|
||||
autoSendErrorReports<bool?>('chat.fluffy.auto_send_eror_reports', null),
|
||||
knownErrorHashes<List<String>>('chat.fluffy.known_crash_hashes', []),
|
||||
customLiveKitInstance<String>('chat.fluffy.custom_live_kit_instance', '');
|
||||
|
||||
final String key;
|
||||
final T _defaultValue;
|
||||
|
||||
const AppSettings(this.key, this._defaultValue);
|
||||
|
||||
static SharedPreferences get store => _store!;
|
||||
static SharedPreferences? _store;
|
||||
|
||||
static Map<String, Object?>? _platformConfiguration;
|
||||
|
||||
T get defaultValue {
|
||||
final platformConfig = _platformConfiguration?[name];
|
||||
if (platformConfig is T) return platformConfig;
|
||||
return _defaultValue;
|
||||
}
|
||||
|
||||
static Future<void> reset({bool loadWebConfigFile = true}) async {
|
||||
await AppSettings._store!.clear();
|
||||
await init(loadWebConfigFile: loadWebConfigFile);
|
||||
}
|
||||
|
||||
static Future<SharedPreferences> init({bool loadWebConfigFile = true}) async {
|
||||
if (AppSettings._store != null) return AppSettings.store;
|
||||
|
||||
final store = AppSettings._store = await SharedPreferences.getInstance();
|
||||
|
||||
// Migrate wrong datatype for fontSizeFactor
|
||||
final fontSizeFactorString = Result(
|
||||
() => store.getString(AppSettings.fontSizeFactor.key),
|
||||
).asValue?.value;
|
||||
if (fontSizeFactorString != null) {
|
||||
Logs().i('Migrate wrong datatype for fontSizeFactor!');
|
||||
await store.remove(AppSettings.fontSizeFactor.key);
|
||||
final fontSizeFactor = double.tryParse(fontSizeFactorString);
|
||||
if (fontSizeFactor != null) {
|
||||
await store.setDouble(AppSettings.fontSizeFactor.key, fontSizeFactor);
|
||||
}
|
||||
}
|
||||
|
||||
if (store.getBool(AppSettings.sendOnEnter.key) == null) {
|
||||
await store.setBool(AppSettings.sendOnEnter.key, !PlatformInfos.isMobile);
|
||||
}
|
||||
if (store.getBool(AppSettings.doubleTapToReact.key) == null) {
|
||||
await store.setBool(
|
||||
AppSettings.doubleTapToReact.key,
|
||||
PlatformInfos.isMobile,
|
||||
);
|
||||
}
|
||||
|
||||
// Load configuration from config.json file or MDM:
|
||||
if (PlatformInfos.isMobile) {
|
||||
_platformConfiguration =
|
||||
await ManagedConfigurations().getManagedConfigurations;
|
||||
} else if (kIsWeb && loadWebConfigFile) {
|
||||
try {
|
||||
final configJsonString = utf8.decode(
|
||||
(await http.get(Uri.parse('config.json'))).bodyBytes,
|
||||
);
|
||||
_platformConfiguration =
|
||||
json.decode(configJsonString) as Map<String, Object?>;
|
||||
} on FormatException catch (_) {
|
||||
Logs().v('[ConfigLoader] config.json not found');
|
||||
} catch (e) {
|
||||
Logs().v('[ConfigLoader] config.json not found', e);
|
||||
}
|
||||
}
|
||||
|
||||
return store;
|
||||
}
|
||||
}
|
||||
|
||||
extension AppSettingsBoolNExtension on AppSettings<bool?> {
|
||||
bool? get value {
|
||||
final value = Result(() => AppSettings.store.getBool(key));
|
||||
final error = value.asError;
|
||||
if (error != null) {
|
||||
Logs().e(
|
||||
'Unable to fetch $key from storage. Removing entry...',
|
||||
error.error,
|
||||
error.stackTrace,
|
||||
);
|
||||
}
|
||||
return value.asValue?.value;
|
||||
}
|
||||
|
||||
Future<void> setItem(bool value) => AppSettings.store.setBool(key, value);
|
||||
}
|
||||
|
||||
extension AppSettingsBoolExtension on AppSettings<bool> {
|
||||
bool get value {
|
||||
final value = Result(() => AppSettings.store.getBool(key));
|
||||
final error = value.asError;
|
||||
if (error != null) {
|
||||
Logs().e(
|
||||
'Unable to fetch $key from storage. Removing entry...',
|
||||
error.error,
|
||||
error.stackTrace,
|
||||
);
|
||||
}
|
||||
return value.asValue?.value ?? defaultValue;
|
||||
}
|
||||
|
||||
Future<void> setItem(bool value) => AppSettings.store.setBool(key, value);
|
||||
}
|
||||
|
||||
extension AppSettingsStringExtension on AppSettings<String> {
|
||||
String get value {
|
||||
final value = Result(() => AppSettings.store.getString(key));
|
||||
final error = value.asError;
|
||||
if (error != null) {
|
||||
Logs().e(
|
||||
'Unable to fetch $key from storage. Removing entry...',
|
||||
error.error,
|
||||
error.stackTrace,
|
||||
);
|
||||
}
|
||||
return value.asValue?.value ?? defaultValue;
|
||||
}
|
||||
|
||||
Future<void> setItem(String value) => AppSettings.store.setString(key, value);
|
||||
}
|
||||
|
||||
extension AppSettingsIntExtension on AppSettings<int> {
|
||||
int get value {
|
||||
final value = Result(() => AppSettings.store.getInt(key));
|
||||
final error = value.asError;
|
||||
if (error != null) {
|
||||
Logs().e(
|
||||
'Unable to fetch $key from storage. Removing entry...',
|
||||
error.error,
|
||||
error.stackTrace,
|
||||
);
|
||||
}
|
||||
return value.asValue?.value ?? defaultValue;
|
||||
}
|
||||
|
||||
Future<void> setItem(int value) => AppSettings.store.setInt(key, value);
|
||||
}
|
||||
|
||||
extension AppSettingsDoubleExtension on AppSettings<double> {
|
||||
double get value {
|
||||
final value = Result(() => AppSettings.store.getDouble(key));
|
||||
final error = value.asError;
|
||||
if (error != null) {
|
||||
Logs().e(
|
||||
'Unable to fetch $key from storage. Removing entry...',
|
||||
error.error,
|
||||
error.stackTrace,
|
||||
);
|
||||
}
|
||||
return value.asValue?.value ?? defaultValue;
|
||||
}
|
||||
|
||||
Future<void> setItem(double value) => AppSettings.store.setDouble(key, value);
|
||||
}
|
||||
|
||||
extension AppSettingsStringListExtension on AppSettings<List<String>> {
|
||||
List<String> get value {
|
||||
final value = Result(() => AppSettings.store.getStringList(key));
|
||||
final error = value.asError;
|
||||
if (error != null) {
|
||||
Logs().e(
|
||||
'Unable to fetch $key from storage. Removing entry...',
|
||||
error.error,
|
||||
error.stackTrace,
|
||||
);
|
||||
}
|
||||
return value.asValue?.value ?? defaultValue;
|
||||
}
|
||||
|
||||
Future<void> setItem(List<String> value) =>
|
||||
AppSettings.store.setStringList(key, value);
|
||||
}
|
||||
Reference in New Issue
Block a user