diff --git a/mobile/lib/services/user_remote_flag_service.dart b/mobile/lib/services/user_remote_flag_service.dart index 42bc45a60d..40d1b63b3f 100644 --- a/mobile/lib/services/user_remote_flag_service.dart +++ b/mobile/lib/services/user_remote_flag_service.dart @@ -17,7 +17,6 @@ class UserRemoteFlagService { final SharedPreferences _prefs; static const String recoveryVerificationFlag = "recoveryKeyVerified"; - static const String mapEnabled = "mapEnabled"; static const String mlEnabled = "faceSearchEnabled"; static const String videoStreamingEnabled = "videoStreamingEnabled"; static const String needRecoveryKeyVerification = @@ -44,9 +43,7 @@ class UserRemoteFlagService { bool getCachedBoolValue(String key) { bool defaultValue = false; - if (key == mapEnabled) { - defaultValue = flagService.mapEnabled; - } else if (key == mlEnabled) { + if (key == mlEnabled) { defaultValue = flagService.hasGrantedMLConsent; } return _prefs.getBool(key) ?? defaultValue; diff --git a/mobile/lib/ui/map/enable_map.dart b/mobile/lib/ui/map/enable_map.dart index 335b362ae1..553e13dae4 100644 --- a/mobile/lib/ui/map/enable_map.dart +++ b/mobile/lib/ui/map/enable_map.dart @@ -2,15 +2,13 @@ import "package:flutter/cupertino.dart"; import "package:photos/generated/l10n.dart"; import 'package:photos/models/button_result.dart'; import "package:photos/service_locator.dart"; -import "package:photos/services/user_remote_flag_service.dart"; import "package:photos/ui/components/buttons/button_widget.dart"; import "package:photos/ui/components/dialog_widget.dart"; import "package:photos/ui/components/models/button_type.dart"; import "package:photos/utils/toast_util.dart"; Future requestForMapEnable(BuildContext context) async { - const String flagName = UserRemoteFlagService.mapEnabled; - if (userRemoteFlagService.getCachedBoolValue(flagName)) { + if (flagService.mapEnabled) { return true; } @@ -26,10 +24,7 @@ Future requestForMapEnable(BuildContext context) async { labelText: S.of(context).enableMaps, isInAlert: true, onTap: () async { - await userRemoteFlagService.setBoolValue( - flagName, - true, - ); + await flagService.setMapEnabled(true); }, ), ButtonWidget( @@ -52,5 +47,5 @@ Future requestForMapEnable(BuildContext context) async { //For debugging. void disableMap() { - userRemoteFlagService.setBoolValue(UserRemoteFlagService.mapEnabled, false); + flagService.setMapEnabled(false); } diff --git a/mobile/lib/ui/settings/advanced_settings_screen.dart b/mobile/lib/ui/settings/advanced_settings_screen.dart index 0da7aab7ca..461131a503 100644 --- a/mobile/lib/ui/settings/advanced_settings_screen.dart +++ b/mobile/lib/ui/settings/advanced_settings_screen.dart @@ -3,7 +3,6 @@ import "package:photos/core/error-reporting/super_logging.dart"; import "package:photos/generated/l10n.dart"; import "package:photos/service_locator.dart"; import "package:photos/services/preview_video_store.dart"; -import "package:photos/services/user_remote_flag_service.dart"; import 'package:photos/theme/ente_theme.dart'; import 'package:photos/ui/components/buttons/icon_button_widget.dart'; import 'package:photos/ui/components/captioned_text_widget.dart'; @@ -101,19 +100,10 @@ class AdvancedSettingsScreen extends StatelessWidget { singleBorderRadius: 8, alignCaptionedTextToLeft: true, trailingWidget: ToggleSwitchWidget( - value: () => userRemoteFlagService.getCachedBoolValue( - UserRemoteFlagService.mapEnabled, - ), + value: () => flagService.mapEnabled, onChanged: () async { - final isEnabled = - userRemoteFlagService.getCachedBoolValue( - UserRemoteFlagService.mapEnabled, - ); - - await userRemoteFlagService.setBoolValue( - UserRemoteFlagService.mapEnabled, - !isEnabled, - ); + final isEnabled = flagService.mapEnabled; + await flagService.setMapEnabled(!isEnabled); }, ), ), diff --git a/mobile/lib/ui/viewer/file_details/location_tags_widget.dart b/mobile/lib/ui/viewer/file_details/location_tags_widget.dart index fd85ef491b..b526643f1a 100644 --- a/mobile/lib/ui/viewer/file_details/location_tags_widget.dart +++ b/mobile/lib/ui/viewer/file_details/location_tags_widget.dart @@ -11,7 +11,6 @@ import "package:photos/generated/l10n.dart"; import "package:photos/models/file/file.dart"; import "package:photos/service_locator.dart"; import "package:photos/services/search_service.dart"; -import "package:photos/services/user_remote_flag_service.dart"; import "package:photos/states/location_screen_state.dart"; import "package:photos/theme/ente_theme.dart"; import "package:photos/ui/components/buttons/chip_button_widget.dart"; @@ -183,8 +182,7 @@ class _InfoMapState extends State { @override void initState() { super.initState(); - _hasEnabledMap = userRemoteFlagService - .getCachedBoolValue(UserRemoteFlagService.mapEnabled); + _hasEnabledMap = flagService.mapEnabled; _fileLat = widget.file.location!.latitude!; _fileLng = widget.file.location!.longitude!; diff --git a/mobile/plugins/ente_feature_flag/lib/src/model.dart b/mobile/plugins/ente_feature_flag/lib/src/model.dart index 412ef11a39..5635df17a2 100644 --- a/mobile/plugins/ente_feature_flag/lib/src/model.dart +++ b/mobile/plugins/ente_feature_flag/lib/src/model.dart @@ -26,6 +26,31 @@ class RemoteFlags { required this.castUrl, }); + // CopyWith + RemoteFlags copyWith({ + bool? enableStripe, + bool? disableCFWorker, + bool? mapEnabled, + bool? faceSearchEnabled, + bool? recoveryKeyVerified, + bool? internalUser, + bool? betaUser, + bool? enableMobMultiPart, + String? castUrl, + }) { + return RemoteFlags( + enableStripe: enableStripe ?? this.enableStripe, + disableCFWorker: disableCFWorker ?? this.disableCFWorker, + mapEnabled: mapEnabled ?? this.mapEnabled, + faceSearchEnabled: faceSearchEnabled ?? this.faceSearchEnabled, + recoveryKeyVerified: recoveryKeyVerified ?? this.recoveryKeyVerified, + internalUser: internalUser ?? this.internalUser, + betaUser: betaUser ?? this.betaUser, + enableMobMultiPart: enableMobMultiPart ?? this.enableMobMultiPart, + castUrl: castUrl ?? this.castUrl, + ); + } + static RemoteFlags defaultValue = RemoteFlags( enableStripe: Platform.isAndroid, disableCFWorker: false, diff --git a/mobile/plugins/ente_feature_flag/lib/src/service.dart b/mobile/plugins/ente_feature_flag/lib/src/service.dart index 0bbcdda9ed..0b011f01eb 100644 --- a/mobile/plugins/ente_feature_flag/lib/src/service.dart +++ b/mobile/plugins/ente_feature_flag/lib/src/service.dart @@ -38,6 +38,28 @@ class FlagService { } } + bool get disableCFWorker => flags.disableCFWorker; + + bool get internalUser => flags.internalUser || kDebugMode; + + bool get betaUser => flags.betaUser; + + bool get internalOrBetaUser => internalUser || betaUser; + + bool get enableStripe => Platform.isIOS ? false : flags.enableStripe; + + bool get mapEnabled => flags.mapEnabled; + + bool get isBetaUser => internalUser || flags.betaUser; + + bool get recoveryKeyVerified => flags.recoveryKeyVerified; + + bool get hasGrantedMLConsent => flags.faceSearchEnabled; + + bool get enableMobMultiPart => flags.enableMobMultiPart || internalUser; + + String get castUrl => flags.castUrl; + Completer? _fetchCompleter; Future _fetch() async { if (_fetchCompleter != null) { @@ -65,25 +87,32 @@ class FlagService { } } - bool get disableCFWorker => flags.disableCFWorker; + Future _updateKeyValue(String key, String value) async { + try { + final response = await _enteDio.post( + "/remote-store/update", + data: { + "key": key, + "value": value, + }, + ); + if (response.statusCode != HttpStatus.ok) { + throw Exception("Unexpected state"); + } + } catch (e) { + debugPrint("Failed to set flag for $key $e"); + rethrow; + } + } - bool get internalUser => flags.internalUser || kDebugMode; + Future setMapEnabled(bool isEnabled) async { + await _updateKeyValue("mapEnabled", isEnabled.toString()); + _updateFlags(flags.copyWith(mapEnabled: isEnabled)); + } - bool get betaUser => flags.betaUser; - - bool get internalOrBetaUser => internalUser || betaUser; - - bool get enableStripe => Platform.isIOS ? false : flags.enableStripe; - - bool get mapEnabled => flags.mapEnabled; - - bool get isBetaUser => internalUser || flags.betaUser; - - bool get recoveryKeyVerified => flags.recoveryKeyVerified; - - bool get hasGrantedMLConsent => flags.faceSearchEnabled; - - bool get enableMobMultiPart => flags.enableMobMultiPart || internalUser; - - String get castUrl => flags.castUrl; + void _updateFlags(RemoteFlags flags) { + _flags = flags; + _prefs.setString("remote_flags", flags.toJson()); + _fetch().ignore(); + } }