forked from firka/firka
1369 lines
36 KiB
Dart
1369 lines
36 KiB
Dart
import 'dart:collection';
|
|
import 'dart:core';
|
|
import 'dart:io';
|
|
|
|
import 'package:firka/data/models/app_settings_model.dart';
|
|
import 'package:firka/services/live_activity_service.dart';
|
|
import 'package:firka/l10n/app_localizations.dart';
|
|
import 'package:firka/ui/shared/firka_icon.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:isar_community/isar.dart';
|
|
import 'package:majesticons_flutter/majesticons_flutter.dart';
|
|
|
|
import 'package:firka/app/app_state.dart';
|
|
import 'package:firka/app/initialization.dart';
|
|
import 'package:firka/app/initialization_screen.dart';
|
|
import 'package:firka/services/wear_sync_cache.dart';
|
|
import 'package:firka/services/watch_sync_helper.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
const bellRing = 1001;
|
|
const rounding1 = 1002;
|
|
const rounding2 = 1003;
|
|
const rounding3 = 1004;
|
|
const rounding4 = 1005;
|
|
const classAvgOnGraph = 1006;
|
|
const leftHandedMode = 1007;
|
|
const language = 1008;
|
|
const appIcon = 1009;
|
|
const childProtection = 1010;
|
|
const betaWarning = 1011;
|
|
const ttToastLessonNo = 1012;
|
|
const ttToastTestsAndHw = 1013;
|
|
const ttToastBreaks = 1014;
|
|
const statsForNerds = 1015;
|
|
const developerOptsEnabled = 1016;
|
|
const themeBrightness = 1017;
|
|
const ttToastSubstitution = 1018;
|
|
const liveActivityEnabled = 1019;
|
|
const liveActivityPrivacyEverDeclined = 1020;
|
|
const morningNotificationEnabled = 1021;
|
|
const morningNotificationTime = 1022;
|
|
const ttToastABTimetable = 1023;
|
|
const wearOsSupport = 1024;
|
|
|
|
bool always() {
|
|
return true;
|
|
}
|
|
|
|
bool never() {
|
|
return false;
|
|
}
|
|
|
|
bool isDeveloper() {
|
|
return isDebug() ||
|
|
initData.settings.group("settings").boolean("developer_enabled");
|
|
}
|
|
|
|
bool isAndroid() {
|
|
return Platform.isAndroid;
|
|
}
|
|
|
|
bool isIOS() {
|
|
return Platform.isIOS;
|
|
}
|
|
|
|
bool isLiveActivityEnabled() {
|
|
return Platform.isIOS &&
|
|
initData.settings
|
|
.group("settings")
|
|
.subGroup("notifications")
|
|
.boolean("live_activity_enabled");
|
|
}
|
|
|
|
bool isMorningNotificationEnabled() {
|
|
return Platform.isIOS &&
|
|
initData.settings
|
|
.group("settings")
|
|
.subGroup("notifications")
|
|
.boolean("morning_notification_enabled");
|
|
}
|
|
|
|
bool isWearOsSupportEnabled() {
|
|
return Platform.isAndroid &&
|
|
initData.settings
|
|
.group("settings")
|
|
.subGroup("wear")
|
|
.boolean("wear_os_support");
|
|
}
|
|
|
|
bool isDebug() {
|
|
return kDebugMode;
|
|
}
|
|
|
|
bool isDebugIOS() {
|
|
return kDebugMode && Platform.isIOS;
|
|
}
|
|
|
|
class SettingsStore {
|
|
LinkedHashMap<String, SettingsItem> items = LinkedHashMap.of({});
|
|
|
|
Map<String, String> appIcons = {};
|
|
|
|
SettingsStore(AppLocalizations l10n) {
|
|
items["settings"] = SettingsGroup(
|
|
0,
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_a, always),
|
|
"settings_header": SettingsHeader(0, l10n.s_settings, always),
|
|
"settings_padding": SettingsPadding(0, 20, always),
|
|
"application": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.settingsCogSolid,
|
|
l10n.s_a,
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_settings, always),
|
|
"settings_header": SettingsHeader(0, l10n.s_ag, always),
|
|
"settings_padding": SettingsPadding(0, 23, always),
|
|
"bell_delay": SettingsDouble(
|
|
bellRing,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.bellSolid,
|
|
l10n.s_ag_bell_delay,
|
|
0,
|
|
0,
|
|
120,
|
|
0,
|
|
always,
|
|
),
|
|
"rounding": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.ruler2Solid,
|
|
l10n.s_ag_rounding,
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_ag_rounding, always),
|
|
"1": SettingsDouble(
|
|
rounding1,
|
|
null,
|
|
null,
|
|
l10n.s_ag_r1,
|
|
0.1,
|
|
0.5,
|
|
0.99,
|
|
2,
|
|
always,
|
|
),
|
|
"2": SettingsDouble(
|
|
rounding2,
|
|
null,
|
|
null,
|
|
l10n.s_ag_r2,
|
|
0.1,
|
|
0.5,
|
|
0.99,
|
|
2,
|
|
always,
|
|
),
|
|
"3": SettingsDouble(
|
|
rounding3,
|
|
null,
|
|
null,
|
|
l10n.s_ag_r3,
|
|
0.1,
|
|
0.5,
|
|
0.99,
|
|
2,
|
|
always,
|
|
),
|
|
"4": SettingsDouble(
|
|
rounding4,
|
|
null,
|
|
null,
|
|
l10n.s_ag_r4,
|
|
0.1,
|
|
0.5,
|
|
0.99,
|
|
2,
|
|
always,
|
|
),
|
|
}),
|
|
always,
|
|
null,
|
|
),
|
|
"class_avg_on_graph": SettingsBoolean(
|
|
classAvgOnGraph,
|
|
null,
|
|
null,
|
|
l10n.s_ag_class_avg_on_graph,
|
|
true,
|
|
never,
|
|
),
|
|
"navbar": SettingsSubGroup(
|
|
0,
|
|
null, // TODO: icon
|
|
null,
|
|
l10n.s_ag_navbar,
|
|
LinkedHashMap.of({}),
|
|
never,
|
|
null,
|
|
),
|
|
"left_handed_mode": SettingsBoolean(
|
|
leftHandedMode,
|
|
null,
|
|
null,
|
|
l10n.s_ag_left_handed_mode,
|
|
false,
|
|
never,
|
|
),
|
|
"live_activity_privacy_ever_declined": SettingsBoolean(
|
|
liveActivityPrivacyEverDeclined,
|
|
null,
|
|
null,
|
|
"Privacy Ever Declined",
|
|
false,
|
|
never,
|
|
),
|
|
"language_header": SettingsHeaderSmall(
|
|
0,
|
|
l10n.s_ag_language_header,
|
|
always,
|
|
),
|
|
"language": SettingsItemsRadio(
|
|
language,
|
|
null,
|
|
null,
|
|
[
|
|
l10n.s_ag_language_auto,
|
|
l10n.s_ag_language_hu,
|
|
l10n.s_ag_language_en,
|
|
l10n.s_ag_language_de,
|
|
],
|
|
0,
|
|
always,
|
|
() async {
|
|
await initLang(initData);
|
|
initData.settings = SettingsStore(initData.l10n);
|
|
await initData.settings.load(initData.isar.appSettingsModels);
|
|
|
|
initData.themeCubit?.refresh();
|
|
runApp(InitializationScreen());
|
|
},
|
|
),
|
|
}),
|
|
always,
|
|
null,
|
|
),
|
|
"customization": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.flower2Solid,
|
|
l10n.s_c,
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_settings, always),
|
|
"settings_header": SettingsHeader(0, l10n.s_customization, always),
|
|
"icon_header": SettingsHeaderSmall(0, l10n.s_c_icon_header, always),
|
|
"icon_header_preview_padding": SettingsPadding(0, 16, always),
|
|
"icon_preview": SettingsAppIconPreview(0, always),
|
|
"icon_picker": SettingsSubGroup(
|
|
0,
|
|
null,
|
|
null,
|
|
l10n.s_c_replace_icon,
|
|
LinkedHashMap.of({
|
|
"icon_header": SettingsHeader(0, l10n.s_ci_icon_header, always),
|
|
"warning_header": SettingsHeader(
|
|
0,
|
|
l10n.s_ci_warning_header,
|
|
isDebug,
|
|
),
|
|
"icon_subtitle": SettingsSubtitle(
|
|
0,
|
|
l10n.s_ci_icon_subtitle,
|
|
always,
|
|
),
|
|
"settings_padding": SettingsPadding(0, 24, always),
|
|
"icon_preview": SettingsAppIconPreview(0, always),
|
|
"settings_padding2": SettingsPadding(0, 24, always),
|
|
"child_protection": SettingsBoolean(
|
|
childProtection,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.shieldSolid,
|
|
l10n.s_ci_child_protection,
|
|
true,
|
|
never,
|
|
),
|
|
"icon_picker": SettingsAppIconPicker(0, "original", {
|
|
l10n.s_ci_icon_g1: ["original", "proto", "pride"],
|
|
l10n.s_ci_icon_g2: ["pixel", "galaxy", "cactus"],
|
|
l10n.s_ci_icon_g3: ["old", "refilc", "filc", "szivacs"],
|
|
l10n.s_ci_icon_g4: [
|
|
"modern",
|
|
"cc",
|
|
"paper",
|
|
"filco",
|
|
"o1g",
|
|
"pear",
|
|
"half_firka_2",
|
|
"nuke",
|
|
"refulc",
|
|
],
|
|
l10n.s_ci_icon_g5: [
|
|
"kreta",
|
|
"cc",
|
|
"repont",
|
|
"void_icon",
|
|
"pixelized",
|
|
"mkkp",
|
|
"fidesz",
|
|
"tisza",
|
|
],
|
|
l10n.s_ci_icon_g6: ["xmas1", "xmas2", "xmas3"],
|
|
l10n.s_ci_icon_g7: [
|
|
"lgbtq",
|
|
"lgbtqp",
|
|
"trans",
|
|
"enby",
|
|
"ace",
|
|
"gay",
|
|
"lesb",
|
|
"bi",
|
|
],
|
|
l10n.s_ci_icon_g8: [
|
|
"lgbtq_f",
|
|
"lgbtqp_f",
|
|
"trans_f",
|
|
"enby_f",
|
|
"ace_f",
|
|
"gay_f",
|
|
"lesb_f",
|
|
"bi_f",
|
|
],
|
|
}, always),
|
|
}),
|
|
isAndroid,
|
|
null,
|
|
),
|
|
"icon_theme_padding": SettingsPadding(0, 16, always),
|
|
"theme_header": SettingsHeaderSmall(
|
|
0,
|
|
l10n.s_c_theme_header,
|
|
always,
|
|
),
|
|
"theme": SettingsItemsRadio(
|
|
themeBrightness,
|
|
null,
|
|
null,
|
|
[l10n.s_c_theme_auto, l10n.s_c_theme_light, l10n.s_c_theme_dark],
|
|
0,
|
|
always,
|
|
() async {
|
|
initTheme(initData);
|
|
},
|
|
),
|
|
}),
|
|
always,
|
|
null,
|
|
),
|
|
"wear": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.clockSolid,
|
|
l10n.s_wear,
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_settings, always),
|
|
"settings_header": SettingsHeader(0, l10n.s_wear, always),
|
|
"settings_padding": SettingsPadding(0, 23, always),
|
|
"wear_os_support": SettingsBoolean(
|
|
wearOsSupport,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.clockSolid,
|
|
l10n.s_wear_os_support,
|
|
false,
|
|
always,
|
|
() async {
|
|
if (!Platform.isAndroid) return;
|
|
final enabled = isWearOsSupportEnabled();
|
|
if (enabled && initDone) {
|
|
final payload = await buildWearSyncPayload(initData.client);
|
|
if (payload != null) {
|
|
final path = await getWearSyncCachePath();
|
|
await writeWearSyncCache(path, payload);
|
|
await WatchSyncHelper.startWearSyncService(path);
|
|
}
|
|
} else {
|
|
await WatchSyncHelper.stopWearSyncService();
|
|
}
|
|
},
|
|
),
|
|
}),
|
|
isAndroid,
|
|
null,
|
|
),
|
|
"notifications": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.bellSolid,
|
|
l10n.s_n,
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_settings, always),
|
|
"settings_header": SettingsHeader(0, l10n.s_n, always),
|
|
"settings_padding": SettingsPadding(0, 23, always),
|
|
"morning_notification_enabled": SettingsBoolean(
|
|
morningNotificationEnabled,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.bellSolid,
|
|
l10n.s_n_morning,
|
|
true,
|
|
always,
|
|
() async {
|
|
final setting =
|
|
initData.settings
|
|
.group("settings")
|
|
.subGroup(
|
|
"notifications",
|
|
)["morning_notification_enabled"]
|
|
as SettingsBoolean;
|
|
|
|
LiveActivityService.onMorningNotificationEnabledChanged(
|
|
setting.value,
|
|
);
|
|
},
|
|
),
|
|
"morning_notification_time": SettingsDouble(
|
|
morningNotificationTime,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.clockSolid,
|
|
l10n.s_n_morning_time,
|
|
30, // minValue
|
|
120, // defaultValue
|
|
240, // maxValue
|
|
0, // precision (0 = whole numbers)
|
|
isMorningNotificationEnabled,
|
|
step: 15,
|
|
), // 15 minute steps
|
|
"live_activity_enabled": SettingsBoolean(
|
|
liveActivityEnabled,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.clockSolid,
|
|
l10n.s_n_live_activity,
|
|
false,
|
|
always,
|
|
() async {
|
|
final globalSetting =
|
|
initData.settings
|
|
.group("settings")
|
|
.subGroup("notifications")["live_activity_enabled"]
|
|
as SettingsBoolean;
|
|
|
|
final enabled = globalSetting.value;
|
|
|
|
await LiveActivityService.handleEnabledChange(
|
|
enabled,
|
|
isManual: true,
|
|
);
|
|
|
|
await LiveActivityService.syncGlobalSettingWithCurrentUser();
|
|
},
|
|
),
|
|
"test_notification": SettingsButton(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.bellSolid,
|
|
l10n.s_n_test,
|
|
isDebugIOS,
|
|
() async {
|
|
await LiveActivityService.sendTestNotification();
|
|
},
|
|
),
|
|
}),
|
|
isIOS,
|
|
null,
|
|
),
|
|
"extras": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.lightningBoltSolid,
|
|
"Extrák",
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_settings, always),
|
|
}),
|
|
never,
|
|
null,
|
|
),
|
|
"settings_other_padding": SettingsPadding(0, 20, never),
|
|
"settings_other_header": SettingsHeaderSmall(0, "Egyéb", never),
|
|
|
|
"developer": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticonsLocal,
|
|
"wrenchSolid",
|
|
'Developer',
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_settings, always),
|
|
"stats_for_nerds": SettingsBoolean(
|
|
statsForNerds,
|
|
FirkaIconType.majesticonsLocal,
|
|
"wrenchSolid",
|
|
l10n.s_stats_for_nerds,
|
|
false,
|
|
always,
|
|
),
|
|
"logs": SettingsLogs(0, always),
|
|
}),
|
|
isDeveloper,
|
|
null,
|
|
),
|
|
|
|
// misc
|
|
"beta_warning": SettingsBoolean(
|
|
betaWarning,
|
|
null,
|
|
null,
|
|
"Beta warning",
|
|
false,
|
|
never,
|
|
),
|
|
"timetable_toast": SettingsSubGroup(
|
|
0,
|
|
null,
|
|
null,
|
|
l10n.tt_settings_toast,
|
|
LinkedHashMap.of({
|
|
"header": SettingsMediumHeader(0, l10n.tt_settings_toast, always),
|
|
"padding": SettingsPadding(0, 16, always),
|
|
"lesson_no": SettingsBoolean(
|
|
ttToastLessonNo,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.clockSolid,
|
|
l10n.tt_settings_toast_lesson_nos,
|
|
true,
|
|
always,
|
|
),
|
|
"tests_and_homework": SettingsBoolean(
|
|
ttToastTestsAndHw,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.editPen4Solid,
|
|
l10n.tt_settings_toast_lesson_tests,
|
|
true,
|
|
always,
|
|
),
|
|
"substitution": SettingsBoolean(
|
|
ttToastSubstitution,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.usersSolid,
|
|
l10n.tt_settings_toast_lesson_substitution,
|
|
true,
|
|
always,
|
|
),
|
|
"breaks": SettingsBoolean(
|
|
ttToastBreaks,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.viewRowsLine,
|
|
l10n.tt_settings_toast_lesson_breaks,
|
|
true,
|
|
always,
|
|
),
|
|
"ab_timetable": SettingsBoolean(
|
|
ttToastABTimetable,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.calendarSolid,
|
|
l10n.tt_settings_toast_lesson_ab_timetable,
|
|
true,
|
|
always,
|
|
),
|
|
}),
|
|
never,
|
|
null,
|
|
),
|
|
"settings_about_padding": SettingsPadding(0, 20, always),
|
|
"settings_about_header": SettingsHeaderSmall(0, "Névjegy", always),
|
|
"discord_button": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.chatSolid,
|
|
"Discord",
|
|
LinkedHashMap.of({}),
|
|
always,
|
|
"discord",
|
|
),
|
|
"privacy_policy_button": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.lockSolid,
|
|
l10n.privacyLabel,
|
|
LinkedHashMap.of({}),
|
|
always,
|
|
"privacy",
|
|
),
|
|
"license_page": SettingsSubGroup(
|
|
0,
|
|
FirkaIconType.majesticons,
|
|
Majesticon.awardSolid,
|
|
l10n.licensesLabel,
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_settings, always),
|
|
"header": SettingsMediumHeader(0, l10n.licensesLabel, always),
|
|
"licenses_header": SettingsHeaderSmall(
|
|
0,
|
|
l10n.licenseDescription,
|
|
always,
|
|
),
|
|
"show_license": ShowLicensePage(),
|
|
}),
|
|
always,
|
|
null,
|
|
),
|
|
"developer_enabled": SettingsBoolean(
|
|
developerOptsEnabled,
|
|
null,
|
|
null,
|
|
"Developer",
|
|
false,
|
|
never,
|
|
),
|
|
}),
|
|
always,
|
|
);
|
|
items["profile_settings"] = SettingsGroup(
|
|
0,
|
|
LinkedHashMap.of({
|
|
"back": SettingsBackHeader(0, l10n.s_your_account, always),
|
|
"e_kreta_accounts": SettingsHeaderSmall(0, l10n.s_acc_kreta, always),
|
|
"e_padding": SettingsPadding(0, 8, always),
|
|
"e_kreta_account_picker": SettingsKretenAccountPicker(0, always),
|
|
}),
|
|
never,
|
|
);
|
|
appIcons = {
|
|
"ace": l10n.ic_ace,
|
|
"ace_f": l10n.ic_ace_f,
|
|
"bi": l10n.ic_bi,
|
|
"bi_f": l10n.ic_bi_f,
|
|
"cactus": l10n.ic_cactus,
|
|
"cc": l10n.ic_cc,
|
|
"enby": l10n.ic_enby,
|
|
"enby_f": l10n.ic_enby_f,
|
|
"fidesz": l10n.ic_fidesz,
|
|
"filc": l10n.ic_filc,
|
|
"filco": l10n.ic_filco,
|
|
"galaxy": l10n.ic_galaxy,
|
|
"gay": l10n.ic_gay,
|
|
"gay_f": l10n.ic_gay_f,
|
|
"half_firka_2": l10n.ic_half_firka_2,
|
|
"kreta": l10n.ic_kreta,
|
|
"lesb": l10n.ic_lesb,
|
|
"lesb_f": l10n.ic_lesb_f,
|
|
"lgbtq": l10n.ic_lgbtq,
|
|
"lgbtq_f": l10n.ic_lgbtq_f,
|
|
"lgbtqp": l10n.ic_lgbtqp,
|
|
"lgbtqp_f": l10n.ic_lgbtqp_f,
|
|
"mkkp": l10n.ic_mkkp,
|
|
"nuke": l10n.ic_nuke,
|
|
"modern": l10n.ic_modern,
|
|
"o1g": l10n.ic_o1g,
|
|
"old": l10n.ic_old,
|
|
"original": l10n.ic_original,
|
|
"paper": l10n.ic_paper,
|
|
"pear": l10n.ic_pear,
|
|
"pixel": l10n.ic_pixel,
|
|
"pixelized": l10n.ic_pixelized,
|
|
"pride": l10n.ic_pride,
|
|
"proto": l10n.ic_proto,
|
|
"refilc": l10n.ic_refilc,
|
|
"refulc": l10n.ic_refulc,
|
|
"repont": l10n.ic_repont,
|
|
"szivacs": l10n.ic_szivacs,
|
|
"tisza": l10n.ic_tisza,
|
|
"trans": l10n.ic_trans,
|
|
"trans_f": l10n.ic_trans_f,
|
|
"void_icon": l10n.ic_void_icon,
|
|
"xmas1": l10n.ic_xmas1,
|
|
"xmas2": l10n.ic_xmas2,
|
|
"xmas3": l10n.ic_xmas3,
|
|
};
|
|
|
|
if (Platform.isIOS) {
|
|
final bellDelaySetting =
|
|
group("settings").subGroup("application")["bell_delay"]
|
|
as SettingsDouble;
|
|
bellDelaySetting.postUpdate = () async {
|
|
LiveActivityService.onBellDelayChanged(bellDelaySetting.value);
|
|
};
|
|
|
|
final morningNotificationTimeSetting =
|
|
group(
|
|
"settings",
|
|
).subGroup("notifications")["morning_notification_time"]
|
|
as SettingsDouble;
|
|
morningNotificationTimeSetting.postUpdate = () async {
|
|
LiveActivityService.onMorningNotificationTimeChanged(
|
|
morningNotificationTimeSetting.value,
|
|
);
|
|
};
|
|
}
|
|
}
|
|
|
|
LinkedHashMap<String, SettingsItem> group(String key) {
|
|
return (items[key] as SettingsGroup).children;
|
|
}
|
|
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
|
for (var item in items.values) {
|
|
await item.save(model);
|
|
}
|
|
|
|
initData.settingsCubit?.notifyChanged();
|
|
}
|
|
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
|
for (var item in items.values) {
|
|
await item.load(model);
|
|
}
|
|
}
|
|
}
|
|
|
|
extension SettingExt on LinkedHashMap<String, SettingsItem> {
|
|
LinkedHashMap<String, SettingsItem> group(String key) {
|
|
return (this[key] as SettingsGroup).children;
|
|
}
|
|
|
|
LinkedHashMap<String, SettingsItem> subGroup(String key) {
|
|
return (this[key] as SettingsSubGroup).children;
|
|
}
|
|
|
|
String string(String key) {
|
|
return (this[key] as SettingsString).value;
|
|
}
|
|
|
|
void setString(String key, String value) {
|
|
(this[key] as SettingsString).value = value;
|
|
}
|
|
|
|
String iconString(String key) {
|
|
return (this[key] as SettingsAppIconPicker).icon;
|
|
}
|
|
|
|
void setIconString(String key, String value) {
|
|
(this[key] as SettingsAppIconPicker).icon = value;
|
|
}
|
|
|
|
double dbl(String key) {
|
|
return (this[key] as SettingsDouble).value;
|
|
}
|
|
|
|
void setDbl(String key, double value) {
|
|
(this[key] as SettingsDouble).value = value;
|
|
}
|
|
|
|
bool boolean(String key) {
|
|
return (this[key] as SettingsBoolean).value;
|
|
}
|
|
|
|
void setBoolean(String key, bool value) {
|
|
(this[key] as SettingsBoolean).value = value;
|
|
}
|
|
}
|
|
|
|
class SettingsItem {
|
|
Id key;
|
|
FirkaIconType? iconType;
|
|
Object? iconData;
|
|
bool Function() visibilityProvider;
|
|
Future<void> Function() postUpdate = () async {};
|
|
|
|
SettingsItem(this.key, this.iconType, this.iconData, this.visibilityProvider);
|
|
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class SettingsGroup implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
LinkedHashMap<String, SettingsItem> children;
|
|
|
|
SettingsGroup(this.key, this.children, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
|
for (var item in children.values) {
|
|
await item.load(model);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
|
for (var item in children.values) {
|
|
await item.save(model);
|
|
}
|
|
|
|
initData.settingsCubit?.notifyChanged();
|
|
}
|
|
}
|
|
|
|
class SettingsSubGroup implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
LinkedHashMap<String, SettingsItem> children;
|
|
String? redirectTo;
|
|
|
|
SettingsSubGroup(
|
|
this.key,
|
|
this.iconType,
|
|
this.iconData,
|
|
this.title,
|
|
this.children,
|
|
this.visibilityProvider,
|
|
this.redirectTo,
|
|
);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
|
for (var item in children.values) {
|
|
await item.load(model);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
|
for (var item in children.values) {
|
|
await item.save(model);
|
|
}
|
|
|
|
initData.settingsCubit?.notifyChanged();
|
|
}
|
|
}
|
|
|
|
class SettingsPadding implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
double padding;
|
|
|
|
SettingsPadding(this.key, this.padding, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class SettingsBackHeader implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
|
|
SettingsBackHeader(this.key, this.title, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class SettingsHeader implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
|
|
SettingsHeader(this.key, this.title, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class SettingsMediumHeader implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
|
|
SettingsMediumHeader(this.key, this.title, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class SettingsHeaderSmall implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
|
|
SettingsHeaderSmall(this.key, this.title, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class ShowLicensePage implements SettingsItem {
|
|
@override
|
|
Id key = 0;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider = always;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
|
|
ShowLicensePage();
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class SettingsSubtitle implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
|
|
SettingsSubtitle(this.key, this.title, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class SettingsAppIconPreview implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title = "";
|
|
|
|
SettingsAppIconPreview(this.key, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class SettingsKretenAccountPicker implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title = "";
|
|
String icon = "";
|
|
int accountIndex = 0;
|
|
|
|
SettingsKretenAccountPicker(this.key, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
|
var v = await model.get(key);
|
|
if (v == null || v.valueIndex == null) {
|
|
accountIndex = 0;
|
|
} else {
|
|
accountIndex = v.valueIndex!;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
|
var v = AppSettingsModel();
|
|
v.id = key;
|
|
v.valueIndex = accountIndex;
|
|
|
|
await model.put(v);
|
|
|
|
initData.settingsCubit?.notifyChanged();
|
|
}
|
|
}
|
|
|
|
class SettingsLogs implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title = "";
|
|
String icon = "";
|
|
|
|
SettingsLogs(this.key, this.visibilityProvider);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|
|
|
|
class SettingsAppIconPicker implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title = "";
|
|
String icon = "";
|
|
String defaultValue;
|
|
Map<String, List<String>> iconGroups;
|
|
|
|
SettingsAppIconPicker(
|
|
this.key,
|
|
this.defaultValue,
|
|
this.iconGroups,
|
|
this.visibilityProvider,
|
|
);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
|
var v = await model.get(key);
|
|
if (v == null || v.valueString == null) {
|
|
icon = defaultValue;
|
|
} else {
|
|
icon = v.valueString!;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
|
var v = AppSettingsModel();
|
|
v.id = key;
|
|
v.valueString = icon;
|
|
|
|
await model.put(v);
|
|
|
|
initData.settingsCubit?.notifyChanged();
|
|
}
|
|
}
|
|
|
|
class SettingsBoolean implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
bool value = false;
|
|
bool defaultValue;
|
|
|
|
SettingsBoolean(
|
|
this.key,
|
|
this.iconType,
|
|
this.iconData,
|
|
this.title,
|
|
this.defaultValue,
|
|
this.visibilityProvider, [
|
|
Future<void> Function()? postUpdateFn,
|
|
]) {
|
|
if (postUpdateFn != null) {
|
|
postUpdate = postUpdateFn;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
|
var v = await model.get(key);
|
|
if (v == null || v.valueBool == null) {
|
|
value = defaultValue;
|
|
} else {
|
|
value = v.valueBool!;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
|
var v = AppSettingsModel();
|
|
v.id = key;
|
|
v.valueBool = value;
|
|
|
|
await model.put(v);
|
|
|
|
initData.settingsCubit?.notifyChanged();
|
|
}
|
|
}
|
|
|
|
class SettingsItemsRadio implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate;
|
|
List<String> values;
|
|
int activeIndex = 0;
|
|
int defaultIndex;
|
|
|
|
SettingsItemsRadio(
|
|
this.key,
|
|
this.iconType,
|
|
this.iconData,
|
|
this.values,
|
|
this.defaultIndex,
|
|
this.visibilityProvider,
|
|
this.postUpdate,
|
|
);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
|
var v = await model.get(key);
|
|
if (v == null || v.valueIndex == null) {
|
|
activeIndex = defaultIndex;
|
|
} else {
|
|
activeIndex = v.valueIndex!;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
|
var v = AppSettingsModel();
|
|
v.id = key;
|
|
v.valueIndex = activeIndex;
|
|
|
|
await model.put(v);
|
|
|
|
initData.settingsCubit?.notifyChanged();
|
|
}
|
|
}
|
|
|
|
class SettingsDouble implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
double value = 0;
|
|
double minValue = 0.0;
|
|
double defaultValue;
|
|
double maxValue = 0.0;
|
|
int precision;
|
|
double? step;
|
|
|
|
SettingsDouble(
|
|
this.key,
|
|
this.iconType,
|
|
this.iconData,
|
|
this.title,
|
|
this.minValue,
|
|
this.defaultValue,
|
|
this.maxValue,
|
|
this.precision,
|
|
this.visibilityProvider, {
|
|
this.step,
|
|
});
|
|
|
|
double toRoundedDouble() {
|
|
return double.parse(toRoundedString());
|
|
}
|
|
|
|
String toRoundedString() {
|
|
return precision == 0
|
|
? value.toString().split(".")[0]
|
|
: value.toStringAsPrecision(precision) == "0.0"
|
|
? "0"
|
|
: value.toStringAsPrecision(precision);
|
|
}
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
|
var v = await model.get(key);
|
|
if (v == null || v.valueDouble == null) {
|
|
value = defaultValue;
|
|
} else {
|
|
value = v.valueDouble!;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
|
var v = AppSettingsModel();
|
|
v.id = key;
|
|
v.valueDouble = value;
|
|
|
|
await model.put(v);
|
|
|
|
initData.settingsCubit?.notifyChanged();
|
|
}
|
|
}
|
|
|
|
class SettingsString implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
String value = "";
|
|
String defaultValue;
|
|
|
|
SettingsString(
|
|
this.key,
|
|
this.iconType,
|
|
this.iconData,
|
|
this.title,
|
|
this.defaultValue,
|
|
this.visibilityProvider,
|
|
);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {
|
|
var v = await model.get(key);
|
|
if (v == null || v.valueString == null) {
|
|
value = defaultValue;
|
|
} else {
|
|
value = v.valueString!;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {
|
|
var v = AppSettingsModel();
|
|
v.id = key;
|
|
v.valueString = value;
|
|
|
|
await model.put(v);
|
|
|
|
initData.settingsCubit?.notifyChanged();
|
|
}
|
|
}
|
|
|
|
class SettingsButton implements SettingsItem {
|
|
@override
|
|
Id key;
|
|
@override
|
|
FirkaIconType? iconType;
|
|
@override
|
|
Object? iconData;
|
|
@override
|
|
bool Function() visibilityProvider;
|
|
@override
|
|
Future<void> Function() postUpdate = () async {};
|
|
String title;
|
|
Future<void> Function() onTap;
|
|
|
|
SettingsButton(
|
|
this.key,
|
|
this.iconType,
|
|
this.iconData,
|
|
this.title,
|
|
this.visibilityProvider,
|
|
this.onTap,
|
|
);
|
|
|
|
@override
|
|
Future<void> load(IsarCollection<AppSettingsModel> model) async {}
|
|
|
|
@override
|
|
Future<void> save(IsarCollection<AppSettingsModel> model) async {}
|
|
}
|