Fixes the notifier for feature flags and updates the example

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2025-05-13 14:31:21 +02:00
parent e6646d308c
commit 515c7fb5b1
2 changed files with 138 additions and 119 deletions
+126 -111
View File
@@ -147,42 +147,47 @@ class _ArcaneLoggingExampleState extends State<ArcaneLoggingExample> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: SizedBox(
height: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Logging",
style: Theme.of(context).textTheme.headlineSmall,
return ValueListenableBuilder(
valueListenable: Arcane.features.notifier,
builder: (context, enabledFeatures, _) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: SizedBox(
height: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Logging",
style: Theme.of(context).textTheme.headlineSmall,
),
if (latestLogs.isEmpty)
Text(
"Log messages will appear here",
style: Theme.of(context).textTheme.labelSmall?.copyWith(
fontStyle: FontStyle.italic,
),
),
if (Feature.logging.disabled)
Text(
"Logging feature is disabled.",
style: Theme.of(context).textTheme.labelSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
Expanded(
child: ListView.builder(
itemCount: latestLogs.length,
itemBuilder: (context, index) {
return Text(latestLogs[index]);
},
),
),
],
),
if (latestLogs.isEmpty)
Text(
"Log messages will appear here",
style: Theme.of(context).textTheme.labelSmall?.copyWith(
fontStyle: FontStyle.italic,
),
),
if (Feature.logging.disabled)
Text(
"Logging feature is disabled.",
style: Theme.of(context).textTheme.labelSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
Expanded(
child: ListView.builder(
itemCount: latestLogs.length,
itemBuilder: (context, index) {
return Text(latestLogs[index]);
},
),
),
],
),
),
),
);
},
);
}
}
@@ -200,47 +205,52 @@ class ArcaneAuthExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ValueListenableBuilder(
valueListenable: Arcane.auth.isSignedIn,
builder: (context, isSignedIn, _) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"Authentication",
style: Theme.of(context).textTheme.headlineSmall,
),
ElevatedButton(
onPressed: Feature.authentication.enabled
? () async {
if (isSignedIn) {
await Arcane.auth.logOut();
} else {
await Arcane.auth.login<Credentials>(
input: (
email: "email",
password: "password",
),
);
}
}
: null,
child: Text(
isSignedIn ? "Sign out" : "Sign in",
),
),
Center(
child: Text("Status: ${Arcane.auth.status.name}"),
),
],
);
},
),
),
return ValueListenableBuilder(
valueListenable: Arcane.features.notifier,
builder: (context, enabledFeatures, _) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ValueListenableBuilder(
valueListenable: Arcane.auth.isSignedIn,
builder: (context, isSignedIn, _) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"Authentication",
style: Theme.of(context).textTheme.headlineSmall,
),
ElevatedButton(
onPressed: Feature.authentication.enabled
? () async {
if (isSignedIn) {
await Arcane.auth.logOut();
} else {
await Arcane.auth.login<Credentials>(
input: (
email: "email",
password: "password",
),
);
}
}
: null,
child: Text(
isSignedIn ? "Sign out" : "Sign in",
),
),
Center(
child: Text("Status: ${Arcane.auth.status.name}"),
),
],
);
},
),
),
);
},
);
}
}
@@ -414,42 +424,47 @@ class ArcaneFeatureFlagsExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"Feature Flags",
style: Theme.of(context).textTheme.headlineSmall,
return ValueListenableBuilder(
valueListenable: Arcane.features.notifier,
builder: (context, enabledFeatures, _) {
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"Feature Flags",
style: Theme.of(context).textTheme.headlineSmall,
),
Expanded(
child: ListView.builder(
itemCount: Feature.values.length,
itemBuilder: (context, i) {
final Feature feature = Feature.values[i];
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(feature.name),
Switch(
value: feature.enabled,
onChanged: (_) {
feature.enabled
? feature.disable()
: feature.enable();
},
),
],
);
},
),
),
],
),
Expanded(
child: ListView.builder(
itemCount: Feature.values.length,
itemBuilder: (context, i) {
final Feature feature = Feature.values[i];
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(feature.name),
Switch(
value: feature.enabled,
onChanged: (_) {
feature.enabled
? feature.disable()
: feature.enable();
},
),
],
);
},
),
),
],
),
),
),
);
},
);
}
}
@@ -70,8 +70,7 @@ class ArcaneFeatureFlags extends ArcaneService {
if (_enabledFeatures.contains(feature)) return I;
_enabledFeatures.add(feature);
_notifier.value.add(feature);
_notifier.value = [..._enabledFeatures, feature];
if (Arcane.logger.initialized) {
Arcane.logger.log(
@@ -100,8 +99,7 @@ class ArcaneFeatureFlags extends ArcaneService {
if (!I._initialized) _init();
if (!_enabledFeatures.contains(feature)) return I;
_enabledFeatures.remove(feature);
_notifier.value.remove(feature);
_notifier.value = [..._enabledFeatures]..removeWhere((i) => i == feature);
if (Arcane.logger.initialized) {
Arcane.logger.log(
@@ -123,8 +121,9 @@ class ArcaneFeatureFlags extends ArcaneService {
/// It is called automatically when enabling or disabling features if they haven't
/// already been initialized.
void _init() {
_enabledFeatures.clear();
_notifier.value.clear();
_notifier.value = [];
notifier.addListener(_listener);
I._initialized = true;
notifyListeners();
@@ -135,10 +134,15 @@ class ArcaneFeatureFlags extends ArcaneService {
/// This method clears all enabled features, resets notification values,
/// marks the flags as uninitialized, and notifies listeners of the changes.
void reset() {
_enabledFeatures.clear();
_notifier.value.clear();
_notifier.value = [];
I._initialized = false;
notifyListeners();
}
void _listener() {
_enabledFeatures
..clear()
..addAll(notifier.value);
}
}