TF-3977 Separate settings keys for easier in conflict

This commit is contained in:
dab246
2025-09-09 11:12:57 +07:00
committed by Dat H. Pham
parent 7fdfb97fc5
commit 5a88f3c36f
27 changed files with 290 additions and 206 deletions
@@ -0,0 +1,14 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/default_preferences_config.dart';
class DefaultPreferencesConfigConverter
implements JsonConverter<DefaultPreferencesConfig, Map<String, dynamic>> {
const DefaultPreferencesConfigConverter();
@override
DefaultPreferencesConfig fromJson(Map<String, dynamic> json) =>
DefaultPreferencesConfig(json);
@override
Map<String, dynamic> toJson(DefaultPreferencesConfig config) => config.data;
}
@@ -1,50 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_setting.dart';
part 'preferences_root.g.dart';
@JsonSerializable(explicitToJson: true)
class PreferencesRoot with EquatableMixin {
final PreferencesSetting setting;
PreferencesRoot({required this.setting});
factory PreferencesRoot.initial() {
return PreferencesRoot(
setting: PreferencesSetting.initial(),
);
}
factory PreferencesRoot.fromJson(Map<String, dynamic> json) =>
_$PreferencesRootFromJson(json);
Map<String, dynamic> toJson() => _$PreferencesRootToJson(this);
@override
List<Object?> get props => [setting];
}
extension PreferencesRootExtension on PreferencesRoot {
PreferencesRoot copyWith({PreferencesSetting? setting}) {
return PreferencesRoot(
setting: setting ?? this.setting,
);
}
PreferencesRoot updateThreadDetail(bool enabled) {
return copyWith(setting: setting.updateThreadDetail(enabled));
}
PreferencesRoot updateSpamReport({
bool? isEnabled,
int? lastTimeDismissedMilliseconds,
}) {
return copyWith(
setting: setting.updateSpamReport(
isEnabled: isEnabled,
lastTimeDismissedMilliseconds: lastTimeDismissedMilliseconds,
),
);
}
}
@@ -1,61 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/spam_report_config.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/thread_detail_config.dart';
part 'preferences_setting.g.dart';
@JsonSerializable(explicitToJson: true)
class PreferencesSetting with EquatableMixin {
final ThreadDetailConfig threadDetail;
final SpamReportConfig spamReport;
PreferencesSetting({
required this.threadDetail,
required this.spamReport,
});
factory PreferencesSetting.initial() {
return PreferencesSetting(
threadDetail: ThreadDetailConfig.initial(),
spamReport: SpamReportConfig.initial(),
);
}
factory PreferencesSetting.fromJson(Map<String, dynamic> json) =>
_$PreferencesSettingFromJson(json);
Map<String, dynamic> toJson() => _$PreferencesSettingToJson(this);
@override
List<Object?> get props => [threadDetail, spamReport];
}
extension PreferencesSettingExtension on PreferencesSetting {
PreferencesSetting copyWith({
ThreadDetailConfig? threadDetail,
SpamReportConfig? spamReport,
}) {
return PreferencesSetting(
threadDetail: threadDetail ?? this.threadDetail,
spamReport: spamReport ?? this.spamReport,
);
}
PreferencesSetting updateThreadDetail(bool enabled) {
return copyWith(threadDetail: threadDetail.copyWith(isEnabled: enabled));
}
PreferencesSetting updateSpamReport({
bool? isEnabled,
int? lastTimeDismissedMilliseconds,
}) {
return copyWith(
spamReport: spamReport.copyWith(
isEnabled: isEnabled ?? spamReport.isEnabled,
lastTimeDismissedMilliseconds: lastTimeDismissedMilliseconds ??
spamReport.lastTimeDismissedMilliseconds,
),
);
}
}
@@ -1,47 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/spam_report_state.dart';
part 'spam_report_config.g.dart';
@JsonSerializable()
class SpamReportConfig with EquatableMixin {
final bool isEnabled;
final int lastTimeDismissedMilliseconds;
SpamReportConfig({
this.isEnabled = true,
this.lastTimeDismissedMilliseconds = 0,
});
factory SpamReportConfig.initial() {
return SpamReportConfig(
isEnabled: true,
lastTimeDismissedMilliseconds: 0,
);
}
factory SpamReportConfig.fromJson(Map<String, dynamic> json) =>
_$SpamReportConfigFromJson(json);
Map<String, dynamic> toJson() => _$SpamReportConfigToJson(this);
@override
List<Object> get props => [isEnabled, lastTimeDismissedMilliseconds];
}
extension SpamReportConfigExtension on SpamReportConfig {
SpamReportConfig copyWith({
bool? isEnabled,
int? lastTimeDismissedMilliseconds,
}) {
return SpamReportConfig(
isEnabled: isEnabled ?? this.isEnabled,
lastTimeDismissedMilliseconds:
lastTimeDismissedMilliseconds ?? this.lastTimeDismissedMilliseconds,
);
}
SpamReportState get spamReportState =>
isEnabled ? SpamReportState.enabled : SpamReportState.disabled;
}
@@ -1,33 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'thread_detail_config.g.dart';
@JsonSerializable()
class ThreadDetailConfig with EquatableMixin {
final bool isEnabled;
ThreadDetailConfig({this.isEnabled = false});
factory ThreadDetailConfig.initial() {
return ThreadDetailConfig(
isEnabled: false,
);
}
factory ThreadDetailConfig.fromJson(Map<String, dynamic> json) =>
_$ThreadDetailConfigFromJson(json);
Map<String, dynamic> toJson() => _$ThreadDetailConfigToJson(this);
@override
List<Object> get props => [isEnabled];
}
extension ThreadDetailConfigExtension on ThreadDetailConfig {
ThreadDetailConfig copyWith({bool? isEnabled}) {
return ThreadDetailConfig(
isEnabled: isEnabled ?? this.isEnabled,
);
}
}
@@ -1,7 +1,7 @@
import 'package:server_settings/server_settings/tmail_server_settings.dart';
import 'package:server_settings/server_settings/tmail_server_settings_extension.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_setting.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_setting.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
enum PreferencesOptionType {
@@ -63,9 +63,9 @@ enum PreferencesOptionType {
case PreferencesOptionType.senderPriority:
return settingOption?.isDisplaySenderPriority ?? false;
case PreferencesOptionType.thread:
return preferencesSetting.threadDetail.isEnabled;
return preferencesSetting.threadConfig.isEnabled;
case PreferencesOptionType.spamReport:
return preferencesSetting.spamReport.isEnabled;
return preferencesSetting.spamReportConfig.isEnabled;
}
}
}
@@ -1,16 +1,21 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:server_settings/server_settings/tmail_server_settings.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/loader_status.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_config.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_setting.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/spam_report_config.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/thread_detail_config.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/get_local_settings_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/state/update_local_settings_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/get_local_settings_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/update_local_settings_interactor.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/manage_account_dashboard_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_root.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences_option_type.dart';
import 'package:tmail_ui_user/features/server_settings/domain/state/get_server_setting_state.dart';
import 'package:tmail_ui_user/features/server_settings/domain/state/update_server_setting_state.dart';
@@ -33,7 +38,10 @@ class PreferencesController extends BaseController {
final UpdateLocalSettingsInteractor _updateLocalSettingsInteractor;
final settingOption = Rxn<TMailServerSettingOptions>();
final localSettings = Rxn<PreferencesRoot>();
final localSettings = Rx<PreferencesSetting>(PreferencesSetting.initial());
AppLifecycleListener? _appLifecycleListener;
LoaderStatus _localSettingLoaderStatus = LoaderStatus.idle;
bool get isLoading => viewState.value.fold(
(failure) => false,
@@ -45,6 +53,15 @@ class PreferencesController extends BaseController {
void onInit() {
super.onInit();
_getSettingOption();
_appLifecycleListener ??= AppLifecycleListener(
onResume: () {
if (_localSettingLoaderStatus == LoaderStatus.loading) {
return;
}
consumeState(_getLocalSettingInteractor.execute());
},
);
}
@override
@@ -54,9 +71,12 @@ class PreferencesController extends BaseController {
} else if (success is UpdateServerSettingSuccess) {
_updateSettingOptionValue(newSettingOption: success.settingOption);
} else if (success is GetLocalSettingsSuccess) {
_updateLocalSettingOptionValue(success.preferencesRoot);
_localSettingLoaderStatus = LoaderStatus.completed;
_updateLocalSettingOptionValue(success.preferencesSetting);
} else if (success is UpdateLocalSettingsSuccess) {
_updateLocalSettingOptionValue(success.preferencesRoot);
_updateLocalSettingOptionValue(success.preferencesSetting);
} else if (success is GettingLocalSettingsState) {
_localSettingLoaderStatus = LoaderStatus.loading;
} else {
super.handleSuccessViewState(success);
}
@@ -66,6 +86,8 @@ class PreferencesController extends BaseController {
void handleFailureViewState(Failure failure) {
if (failure is GetServerSettingFailure) {
_updateSettingOptionValue(newSettingOption: null);
} else if (failure is GetLocalSettingsFailure) {
_localSettingLoaderStatus = LoaderStatus.completed;
} else if (failure is UpdateServerSettingFailure) {
_handleUpdateServerSettingFailure();
} else {
@@ -73,6 +95,12 @@ class PreferencesController extends BaseController {
}
}
@override
void handleErrorViewState(Object error, StackTrace stackTrace) {
super.handleErrorViewState(error, stackTrace);
_localSettingLoaderStatus = LoaderStatus.completed;
}
void _handleUpdateServerSettingFailure() {
if (currentOverlayContext != null && currentContext != null) {
appToast.showToastErrorMessage(
@@ -85,8 +113,8 @@ class PreferencesController extends BaseController {
settingOption.value = newSettingOption;
}
void _updateLocalSettingOptionValue(PreferencesRoot preferencesRoot) {
localSettings.value = preferencesRoot;
void _updateLocalSettingOptionValue(PreferencesSetting preferencesSetting) {
localSettings.value = preferencesSetting;
}
void _getSettingOption() {
@@ -114,24 +142,20 @@ class PreferencesController extends BaseController {
PreferencesOptionType optionType,
bool isEnabled,
) {
PreferencesRoot? preferencesRoot;
PreferencesConfig? config;
switch(optionType) {
case PreferencesOptionType.thread:
preferencesRoot = localSettings.value?.updateThreadDetail(
!isEnabled,
);
config = ThreadDetailConfig(isEnabled: !isEnabled);
break;
case PreferencesOptionType.spamReport:
preferencesRoot = localSettings.value?.updateSpamReport(
isEnabled: !isEnabled,
);
config = SpamReportConfig(isEnabled: !isEnabled);
break;
default:
break;
}
if (preferencesRoot != null) {
consumeState(_updateLocalSettingsInteractor.execute(preferencesRoot));
if (config != null) {
consumeState(_updateLocalSettingsInteractor.execute(config));
}
}
@@ -171,4 +195,11 @@ class PreferencesController extends BaseController {
);
}
}
@override
void onClose() {
_appLifecycleListener?.dispose();
super.onClose();
}
}
@@ -59,7 +59,8 @@ class PreferencesView extends GetWidget<PreferencesController> with AppLoaderMix
final settingOption = controller.settingOption.value;
final localSettingOption = controller.localSettings.value;
if (settingOption == null && localSettingOption == null) {
if (settingOption == null &&
localSettingOption.configs.isEmpty) {
return const SizedBox.shrink();
}
@@ -68,7 +69,7 @@ class PreferencesView extends GetWidget<PreferencesController> with AppLoaderMix
...PreferencesOptionType.values.where(
(optionType) => !optionType.isLocal,
),
if (localSettingOption != null)
if (localSettingOption.configs.isNotEmpty)
...PreferencesOptionType.values.where(
(optionType) => optionType.isLocal,
),
@@ -81,7 +82,7 @@ class PreferencesView extends GetWidget<PreferencesController> with AppLoaderMix
return PreferencesOptionItem(
imagePaths: controller.imagePaths,
settingOption: settingOption,
preferencesSetting: localSettingOption!.setting,
preferencesSetting: localSettingOption,
optionType: availableSettingOptions[index],
onTapPreferencesOptionAction: controller.updateStateSettingOption,
);
@@ -4,9 +4,7 @@ import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:server_settings/server_settings/tmail_server_settings.dart';
import 'package:tmail_ui_user/features/base/widget/default_switch_icon_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/local_setting_options.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/setting_option_type.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences/preferences_setting.dart';
import 'package:tmail_ui_user/features/manage_account/domain/model/preferences/preferences_setting.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/preferences_option_type.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';