mirror of
https://github.com/hanskokx/arcane_framework.git
synced 2026-05-14 02:19:08 +02:00
@@ -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;
|
||||
}
|
||||
@@ -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(() {});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import "package:flutter/material.dart";
|
||||
|
||||
final ThemeData darkTheme = ThemeData.dark();
|
||||
final ThemeData lightTheme = ThemeData.light();
|
||||
Reference in New Issue
Block a user