mirror of
https://github.com/hanskokx/arcane_framework.git
synced 2026-05-14 02:19:08 +02:00
Updated example to add a services example
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
+114
-9
@@ -5,6 +5,7 @@ import "package:example/config.dart";
|
|||||||
import "package:example/interfaces/debug_auth_interface.dart";
|
import "package:example/interfaces/debug_auth_interface.dart";
|
||||||
import "package:example/interfaces/debug_print_interface.dart";
|
import "package:example/interfaces/debug_print_interface.dart";
|
||||||
import "package:example/services/demo_service.dart";
|
import "package:example/services/demo_service.dart";
|
||||||
|
import "package:example/services/favorite_color_service.dart";
|
||||||
import "package:example/theme/theme.dart";
|
import "package:example/theme/theme.dart";
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
@@ -81,8 +82,9 @@ class HomeScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _HomeScreenState extends State<HomeScreen> {
|
class _HomeScreenState extends State<HomeScreen> {
|
||||||
late final StreamSubscription<String> _subscription;
|
late final StreamSubscription<String> _subscription;
|
||||||
|
late final StreamSubscription<Color> _serviceSubscription;
|
||||||
final List<String> latestLogs = [];
|
final List<String> latestLogs = [];
|
||||||
final List<Color> themeColors = [
|
static const List<MaterialColor> colors = [
|
||||||
Colors.red,
|
Colors.red,
|
||||||
Colors.orange,
|
Colors.orange,
|
||||||
Colors.yellow,
|
Colors.yellow,
|
||||||
@@ -94,7 +96,6 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final bool isSignedIn = Arcane.auth.isSignedIn.value;
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -192,7 +193,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
const Text("Color"),
|
const Text("Color"),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.separated(
|
child: ListView.separated(
|
||||||
itemCount: themeColors.length,
|
itemCount: colors.length,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
separatorBuilder: (_, __) =>
|
separatorBuilder: (_, __) =>
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
@@ -204,7 +205,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
Arcane.theme.setDarkTheme(
|
Arcane.theme.setDarkTheme(
|
||||||
ThemeData(
|
ThemeData(
|
||||||
brightness: Brightness.dark,
|
brightness: Brightness.dark,
|
||||||
colorSchemeSeed: themeColors[index],
|
colorSchemeSeed: colors[index],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (Arcane
|
} else if (Arcane
|
||||||
@@ -213,17 +214,17 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
Arcane.theme.setLightTheme(
|
Arcane.theme.setLightTheme(
|
||||||
ThemeData(
|
ThemeData(
|
||||||
brightness: Brightness.light,
|
brightness: Brightness.light,
|
||||||
colorSchemeSeed: themeColors[index],
|
colorSchemeSeed: colors[index],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Arcane.log(
|
Arcane.log(
|
||||||
"Setting ${Arcane.theme.currentThemeMode.name} theme color to ${themeColors[index]}",
|
"Setting ${Arcane.theme.currentThemeMode.name} theme color to ${colors[index]}",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
color: themeColors[index],
|
color: colors[index],
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
),
|
),
|
||||||
@@ -259,7 +260,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: Feature.authentication.enabled
|
onPressed: Feature.authentication.enabled
|
||||||
? () async {
|
? () async {
|
||||||
if (isSignedIn) {
|
if (Arcane.auth.isSignedIn.value) {
|
||||||
await Arcane.auth.logOut(
|
await Arcane.auth.logOut(
|
||||||
onLoggedOut: () async {
|
onLoggedOut: () async {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@@ -278,7 +279,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: Text(isSignedIn ? "Sign out" : "Sign in"),
|
child: Text(
|
||||||
|
Arcane.auth.isSignedIn.value ? "Sign out" : "Sign in",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Center(
|
Center(
|
||||||
child: Text("Status: ${Arcane.auth.status.name}"),
|
child: Text("Status: ${Arcane.auth.status.name}"),
|
||||||
@@ -377,6 +380,108 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Services
|
||||||
|
Card(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Services",
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall,
|
||||||
|
),
|
||||||
|
ValueListenableBuilder(
|
||||||
|
valueListenable:
|
||||||
|
ArcaneService.ofType<FavoriteColorService>(
|
||||||
|
context,
|
||||||
|
)?.notifier ??
|
||||||
|
ValueNotifier(null),
|
||||||
|
builder: (context, color, _) {
|
||||||
|
return Text(
|
||||||
|
color != null
|
||||||
|
? "Favorite color: ${color.name}"
|
||||||
|
: "",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: ArcaneServiceProvider.serviceOfType<
|
||||||
|
FavoriteColorService>(context) ==
|
||||||
|
null
|
||||||
|
? () {
|
||||||
|
ArcaneServiceProvider.of(context).addService(
|
||||||
|
FavoriteColorService.I,
|
||||||
|
);
|
||||||
|
Arcane.log(
|
||||||
|
"Service registered.",
|
||||||
|
metadata: {
|
||||||
|
"service": "FavoriteColorService",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
: () {
|
||||||
|
ArcaneServiceProvider.of(context)
|
||||||
|
.removeService<FavoriteColorService>();
|
||||||
|
Arcane.log(
|
||||||
|
"Service removed.",
|
||||||
|
metadata: {
|
||||||
|
"service": "FavoriteColorService",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
'${ArcaneServiceProvider.serviceOfType<FavoriteColorService>(context) == null ? 'Register' : 'Remove'} service',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
const Text("Color"),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.separated(
|
||||||
|
itemCount: colors.length,
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
separatorBuilder: (_, __) =>
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
ArcaneService.ofType<
|
||||||
|
FavoriteColorService>(
|
||||||
|
context,
|
||||||
|
)?.setMyFavoriteColor(colors[index]);
|
||||||
|
Arcane.log(
|
||||||
|
"Set a color in FavoriteColorService",
|
||||||
|
metadata: {
|
||||||
|
"color": colors[index].name,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
color: colors[index],
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"Service is ${ArcaneService.ofType<FavoriteColorService>(context) != null ? "" : "not "}registered",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import "package:arcane_framework/arcane_framework.dart";
|
||||||
|
import "package:flutter/material.dart";
|
||||||
|
|
||||||
|
class FavoriteColorService extends ArcaneService {
|
||||||
|
static final FavoriteColorService _instance =
|
||||||
|
FavoriteColorService._internal();
|
||||||
|
|
||||||
|
static FavoriteColorService get I => _instance;
|
||||||
|
|
||||||
|
FavoriteColorService._internal();
|
||||||
|
|
||||||
|
MaterialColor? get myFavoriteColor => _notifier.value;
|
||||||
|
|
||||||
|
final ValueNotifier<MaterialColor?> _notifier =
|
||||||
|
ValueNotifier<MaterialColor?>(null);
|
||||||
|
|
||||||
|
ValueNotifier<MaterialColor?> get notifier => _notifier;
|
||||||
|
|
||||||
|
void setMyFavoriteColor(MaterialColor? newValue) {
|
||||||
|
if (_notifier.value != newValue) {
|
||||||
|
_notifier.value = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ColorName on MaterialColor {
|
||||||
|
String get name {
|
||||||
|
final double red = double.parse(r.toStringAsFixed(4));
|
||||||
|
final double green = double.parse(g.toStringAsFixed(4));
|
||||||
|
final double blue = double.parse(b.toStringAsFixed(4));
|
||||||
|
if (red == 0.9569 && green == 0.2627 && blue == 0.2118) return "red";
|
||||||
|
if (red == 1 && green == 0.5961 && blue == 0) return "orange";
|
||||||
|
if (red == 1 && green == 0.9216 && blue == 0.2314) return "yellow";
|
||||||
|
if (red == 0.2980 && green == 0.6863 && blue == 0.3137) return "green";
|
||||||
|
if (red == 0.1294 && green == 0.5882 && blue == 0.9529) return "blue";
|
||||||
|
if (red == 0.6118 && green == 0.1529 && blue == 0.6902) return "indigo";
|
||||||
|
if (red == 0.4039 && green == 0.2275 && blue == 0.7176) return "violet";
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -194,7 +194,7 @@ void main() {
|
|||||||
services: testServices,
|
services: testServices,
|
||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final service = ArcaneService.of<MockArcaneService>(context);
|
final service = ArcaneService.ofType<MockArcaneService>(context);
|
||||||
expect(service, isNotNull);
|
expect(service, isNotNull);
|
||||||
expect(service, isA<MockArcaneService>());
|
expect(service, isA<MockArcaneService>());
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
@@ -212,11 +212,12 @@ void main() {
|
|||||||
child: Builder(
|
child: Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final service =
|
final service =
|
||||||
ArcaneService.requiredOf<MockArcaneService>(context);
|
ArcaneService.requiredOfType<MockArcaneService>(context);
|
||||||
expect(service, isA<MockArcaneService>());
|
expect(service, isA<MockArcaneService>());
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() => ArcaneService.requiredOf<UnregisteredService>(context),
|
() =>
|
||||||
|
ArcaneService.requiredOfType<UnregisteredService>(context),
|
||||||
throwsA(isA<AssertionError>()),
|
throwsA(isA<AssertionError>()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user