Added example project

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2024-09-18 10:39:46 +02:00
parent af6194608d
commit e6b2442eea
15 changed files with 536 additions and 2 deletions
+7
View File
@@ -0,0 +1,7 @@
enum Feature {
logging(true),
;
final bool enabledAtStartup;
const Feature(this.enabledAtStartup);
}
@@ -0,0 +1,89 @@
import "package:arcane_framework/arcane_framework.dart";
class DebugAuthInterface implements ArcaneAuthInterface {
DebugAuthInterface._internal();
static final ArcaneAuthInterface _instance = DebugAuthInterface._internal();
static ArcaneAuthInterface get I => _instance;
@override
Future<bool> get isSignedIn => Future.value(_isSignedIn);
bool _isSignedIn = false;
@override
Future<String?> get accessToken => isSignedIn.then(
(loggedIn) => loggedIn ? "access_token" : null,
);
@override
Future<String?> get refreshToken => isSignedIn.then(
(loggedIn) => loggedIn ? "refresh_token" : null,
);
@override
Future<Result<void, String>> logout() async {
Arcane.log("Logging out");
_isSignedIn = false;
return Result.ok(null);
}
@override
Future<Result<void, String>> loginWithEmailAndPassword({
required String email,
required String password,
}) async {
final bool alreadyLoggedIn = await isSignedIn;
if (alreadyLoggedIn) return Result.ok(null);
Arcane.log("Logging in as $email");
_isSignedIn = true;
return Result.ok(null);
}
@override
Future<Result<String, String>> resendVerificationCode(String email) async {
Arcane.log("Re-sending verification code to $email");
return Result.ok("Code sent");
}
@override
Future<Result<SignUpStep, String>> signup({
required String password,
required String email,
}) async {
Arcane.log("Creating account for $email with password $password");
return Result.ok(SignUpStep.confirmSignUp);
}
@override
Future<Result<bool, String>> confirmSignup({
required String username,
required String confirmationCode,
}) async {
Arcane.log(
"Confirming registration for $username with code $confirmationCode",
);
return Result.ok(true);
}
@override
Future<Result<bool, String>> resetPassword({
required String email,
String? newPassword,
String? code,
}) async {
Arcane.log("Resetting password for $email");
return Result.ok(true);
}
@override
Future<void> init() async {
Arcane.log("Debug auth interface initialized.");
return;
}
}
@@ -0,0 +1,27 @@
import "package:arcane_framework/arcane_framework.dart";
import "package:example/config.dart";
import "package:flutter/foundation.dart";
class DebugPrint implements LoggingInterface {
DebugPrint._internal();
static final DebugPrint _instance = DebugPrint._internal();
static DebugPrint get I => _instance;
@override
bool get initialized => true;
@override
void log(
String message, {
Map<String, dynamic>? metadata,
Level? level = Level.debug,
StackTrace? stackTrace,
}) {
if (Feature.logging.disabled) return;
debugPrint("[${level!.name}] $message ($metadata)");
}
@override
Future<LoggingInterface?> init() async => I;
}
+133
View File
@@ -0,0 +1,133 @@
import "package:arcane_framework/arcane_framework.dart";
import "package:example/config.dart";
import "package:example/interfaces/debug_auth_interface.dart";
import "package:example/interfaces/debug_print_interface.dart";
import "package:example/services/demo_service.dart";
import "package:example/theme/theme.dart";
import "package:flutter/material.dart";
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
for (final Feature feature in Feature.values) {
if (feature.enabledAtStartup) Arcane.features.enableFeature(feature);
}
await Future.wait([
Arcane.logger.registerInterfaces([
DebugPrint.I,
]),
IdService.I.init(),
]);
Arcane.logger.addPersistentMetadata({
"session_id": IdService.I.sessionId.value,
});
await Arcane.auth.registerInterface(DebugAuthInterface.I);
Arcane.theme
..setDarkTheme(darkTheme)
..setLightTheme(lightTheme);
Arcane.log(
"Initialization complete.",
level: Level.info,
module: "main",
method: "main",
metadata: {
"ready": "true",
},
);
runApp(const MainApp());
}
class MainApp extends StatefulWidget {
const MainApp({super.key});
@override
State<MainApp> createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
@override
Widget build(BuildContext context) {
return ArcaneApp(
services: [
IdService.I,
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: Arcane.theme.light,
darkTheme: Arcane.theme.dark,
themeMode: Arcane.theme.currentMode,
home: Scaffold(
appBar: AppBar(
title: const Text("Arcane Framework Example"),
actions: [
IconButton(
icon: const Icon(Icons.contrast),
onPressed: () {
Arcane.theme.switchTheme();
setState(() {});
},
),
],
),
body: const HomeScreen(),
),
),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
final bool isSignedIn = Arcane.auth.isSignedIn.value;
return Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Authentication status: ${Arcane.auth.status.name}",
),
if (isSignedIn)
ElevatedButton(
child: const Text("Sign out"),
onPressed: () async {
await Arcane.auth.logOut(
onLoggedOut: () async {
setState(() {});
},
);
},
),
if (!isSignedIn)
ElevatedButton(
child: const Text("Sign in"),
onPressed: () async {
await Arcane.auth.loginWithEmailAndPassword(
email: "email",
password: "password",
onLoggedIn: () async {
setState(() {});
},
);
},
),
],
),
),
);
}
}
+33
View File
@@ -0,0 +1,33 @@
import "package:arcane_framework/arcane_framework.dart";
import "package:flutter/foundation.dart";
import "package:uuid/uuid.dart";
class IdService extends ArcaneService {
static final IdService _instance = IdService._internal();
static IdService get I => _instance;
IdService._internal();
bool _initialized = false;
bool get initialized => I._initialized;
String? _sessionId;
ValueListenable<String?> get sessionId =>
ValueNotifier<String?>(I._sessionId);
String get newId => uuid.v7();
/// The `Uuid` instance used for generating unique IDs.
static const Uuid uuid = Uuid();
Future<void> init() async {
Arcane.log(
"Initializing ID Service",
level: Level.debug,
);
I._sessionId = uuid.v7();
I._initialized = true;
notifyListeners();
}
}
+4
View File
@@ -0,0 +1,4 @@
import "package:flutter/material.dart";
final ThemeData darkTheme = ThemeData.dark();
final ThemeData lightTheme = ThemeData.light();