@@ -5,25 +5,41 @@ import 'package:shared_preferences/shared_preferences.dart';
55import 'package:tattoo/services/feature_flag/feature_flag_service.dart' ;
66import 'package:tattoo/services/firebase_service.dart' ;
77
8+ enum FeatureFlagSource {
9+ local,
10+ remote,
11+ override,
12+ forced,
13+ }
14+
815/// The model for a UI-consumable feature flag.
916class FeatureFlag {
1017 final String key;
1118 final dynamic defaultValue;
1219 final dynamic overrideValue;
1320 final List <dynamic >? options;
1421 final bool isForced;
22+ final bool isRemote;
1523
1624 const FeatureFlag ({
1725 required this .key,
1826 required this .defaultValue,
1927 this .overrideValue,
2028 this .options,
2129 this .isForced = false ,
30+ this .isRemote = false ,
2231 });
2332
2433 dynamic get value => overrideValue ?? defaultValue;
2534 Type get type => defaultValue.runtimeType;
2635
36+ FeatureFlagSource get source {
37+ if (isForced) return FeatureFlagSource .forced;
38+ if (overrideValue != null ) return FeatureFlagSource .override;
39+ if (isRemote) return FeatureFlagSource .remote;
40+ return FeatureFlagSource .local;
41+ }
42+
2743 // Type-safe getters
2844 bool get asBool => value as bool ;
2945 int get asInt => value as int ;
@@ -42,15 +58,17 @@ final featureFlagRepositoryProvider = Provider<FeatureFlagRepository>((ref) {
4258class FeatureFlagRepository {
4359 final FeatureFlagService _service;
4460 final SharedPreferencesAsync _prefs;
45- Map <String , dynamic >? _defaultsCache;
61+ Map <String , FeatureFlagData >? _defaultsCache;
4662
4763 FeatureFlagRepository ({
4864 required FeatureFlagService service,
4965 required SharedPreferencesAsync prefs,
5066 }) : _service = service,
5167 _prefs = prefs;
5268
53- Future <Map <String , dynamic >> _getDefaults ({bool forceRefresh = false }) async {
69+ Future <Map <String , FeatureFlagData >> _getDefaults ({
70+ bool forceRefresh = false ,
71+ }) async {
5472 if (forceRefresh) _defaultsCache = null ;
5573 return _defaultsCache ?? = await _service.fetchDefaultFlags ();
5674 }
@@ -59,7 +77,8 @@ class FeatureFlagRepository {
5977 final defaults = await _getDefaults (forceRefresh: forceRefresh);
6078 final list = < FeatureFlag > [];
6179
62- final forceOverrideString = defaults['_force_override_flags' ] as String ? ;
80+ final forceOverrideString =
81+ defaults['_force_override_flags' ]? .value as String ? ;
6382 final forceOverrides =
6483 forceOverrideString
6584 ? .split (',' )
@@ -72,7 +91,8 @@ class FeatureFlagRepository {
7291 final key = entry.key;
7392 if (key == '_force_override_flags' ) continue ;
7493
75- dynamic defVal = entry.value;
94+ dynamic defVal = entry.value.value;
95+ final isRemote = entry.value.isRemote;
7696 List <dynamic >? options;
7797
7898 if (defVal is Map <String , dynamic > &&
@@ -106,6 +126,7 @@ class FeatureFlagRepository {
106126 overrideValue: overrideVal,
107127 options: options,
108128 isForced: isForced,
129+ isRemote: isRemote,
109130 ),
110131 );
111132 }
0 commit comments