mirror of
https://github.com/hanskokx/arcane_framework.git
synced 2026-05-14 02:19:08 +02:00
+20
@@ -30,3 +30,23 @@ build/
|
|||||||
|
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
.flutter-plugins-dependencies
|
.flutter-plugins-dependencies
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
**/.dart_tool/
|
||||||
|
**/.flutter-plugins
|
||||||
|
**/.flutter-plugins-dependencies
|
||||||
|
**/.pub-cache/
|
||||||
|
**/.pub/
|
||||||
|
**/build/
|
||||||
|
|
||||||
|
# Symbolication related
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Obfuscation related
|
||||||
|
app.*.map.json
|
||||||
|
|
||||||
|
# Android Studio will place build artifacts here
|
||||||
|
**/android/app/debug
|
||||||
|
**/android/app/profile
|
||||||
|
**/android/app/release
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
|
||||||
|
## 1.0.3+1
|
||||||
|
|
||||||
|
* Added example project
|
||||||
|
|
||||||
## 1.0.3
|
## 1.0.3
|
||||||
|
|
||||||
* Added the ability to switch back to the normal environment from the debug environment in ArcaneEnvironment
|
* Added the ability to switch back to the normal environment from the debug environment in ArcaneEnvironment
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
migrate_working_dir/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
/build/
|
||||||
|
|
||||||
|
# Symbolication related
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Obfuscation related
|
||||||
|
app.*.map.json
|
||||||
|
|
||||||
|
# Android Studio will place build artifacts here
|
||||||
|
/android/app/debug
|
||||||
|
/android/app/profile
|
||||||
|
/android/app/release
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: "2663184aa79047d0a33a14a3b607954f8fdd8730"
|
||||||
|
channel: "stable"
|
||||||
|
|
||||||
|
project_type: app
|
||||||
|
|
||||||
|
# Tracks metadata for the flutter migrate command
|
||||||
|
migration:
|
||||||
|
platforms:
|
||||||
|
- platform: root
|
||||||
|
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
|
||||||
|
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
|
||||||
|
- platform: web
|
||||||
|
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
|
||||||
|
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
|
||||||
|
|
||||||
|
# User provided section
|
||||||
|
|
||||||
|
# List of Local paths (relative to this file) that should be
|
||||||
|
# ignored by the migrate tool.
|
||||||
|
#
|
||||||
|
# Files that are not part of the templates will be ignored by default.
|
||||||
|
unmanaged_files:
|
||||||
|
- 'lib/main.dart'
|
||||||
|
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# example
|
||||||
|
|
||||||
|
A new Flutter project.
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
analyzer:
|
||||||
|
errors:
|
||||||
|
# treat missing required parameters as an error (not a hint)
|
||||||
|
missing_required_param: error
|
||||||
|
# treat missing returns as an error (not a hint)
|
||||||
|
missing_return: error
|
||||||
|
invalid_annotation_target: ignore
|
||||||
|
language:
|
||||||
|
strict-casts: true
|
||||||
|
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
always_declare_return_types: true
|
||||||
|
always_put_required_named_parameters_first: true
|
||||||
|
annotate_overrides: true
|
||||||
|
avoid_annotating_with_dynamic: true
|
||||||
|
avoid_dynamic_calls: true
|
||||||
|
avoid_escaping_inner_quotes: true
|
||||||
|
avoid_function_literals_in_foreach_calls: true
|
||||||
|
avoid_null_checks_in_equality_operators: true
|
||||||
|
avoid_print: true
|
||||||
|
avoid_relative_lib_imports: true
|
||||||
|
avoid_setters_without_getters: true
|
||||||
|
avoid_shadowing_type_parameters: true
|
||||||
|
avoid_single_cascade_in_expression_statements: true
|
||||||
|
avoid_unnecessary_containers: true
|
||||||
|
avoid_unused_constructor_parameters: true
|
||||||
|
avoid_void_async: true
|
||||||
|
camel_case_extensions: true
|
||||||
|
camel_case_types: true
|
||||||
|
cancel_subscriptions: true
|
||||||
|
close_sinks: true
|
||||||
|
collection_methods_unrelated_type: true
|
||||||
|
constant_identifier_names: true
|
||||||
|
control_flow_in_finally: true
|
||||||
|
depend_on_referenced_packages: true
|
||||||
|
directives_ordering: true
|
||||||
|
empty_constructor_bodies: true
|
||||||
|
empty_statements: true
|
||||||
|
eol_at_end_of_file: true
|
||||||
|
exhaustive_cases: true
|
||||||
|
file_names: true
|
||||||
|
flutter_style_todos: true
|
||||||
|
hash_and_equals: true
|
||||||
|
implementation_imports: true
|
||||||
|
implicit_call_tearoffs: true
|
||||||
|
leading_newlines_in_multiline_strings: true
|
||||||
|
missing_whitespace_between_adjacent_strings: true
|
||||||
|
no_adjacent_strings_in_list: true
|
||||||
|
no_duplicate_case_values: true
|
||||||
|
no_leading_underscores_for_library_prefixes: true
|
||||||
|
no_leading_underscores_for_local_identifiers: true
|
||||||
|
no_logic_in_create_state: true
|
||||||
|
no_runtimeType_toString: true
|
||||||
|
non_constant_identifier_names: true
|
||||||
|
null_check_on_nullable_type_parameter: true
|
||||||
|
null_closures: true
|
||||||
|
only_throw_errors: true
|
||||||
|
package_prefixed_library_names: true
|
||||||
|
prefer_adjacent_string_concatenation: true
|
||||||
|
prefer_asserts_in_initializer_lists: true
|
||||||
|
prefer_collection_literals: true
|
||||||
|
prefer_conditional_assignment: true
|
||||||
|
prefer_const_constructors_in_immutables: true
|
||||||
|
prefer_const_constructors: true
|
||||||
|
prefer_const_declarations: true
|
||||||
|
prefer_const_literals_to_create_immutables: true
|
||||||
|
prefer_constructors_over_static_methods: true
|
||||||
|
prefer_contains: true
|
||||||
|
prefer_double_quotes: true
|
||||||
|
prefer_final_fields: true
|
||||||
|
prefer_final_in_for_each: true
|
||||||
|
prefer_final_locals: true
|
||||||
|
prefer_for_elements_to_map_fromIterable: true
|
||||||
|
prefer_function_declarations_over_variables: true
|
||||||
|
prefer_generic_function_type_aliases: true
|
||||||
|
prefer_if_null_operators: true
|
||||||
|
prefer_initializing_formals: true
|
||||||
|
prefer_inlined_adds: true
|
||||||
|
prefer_interpolation_to_compose_strings: true
|
||||||
|
prefer_is_empty: true
|
||||||
|
prefer_is_not_empty: true
|
||||||
|
prefer_is_not_operator: true
|
||||||
|
prefer_iterable_whereType: true
|
||||||
|
prefer_null_aware_operators: true
|
||||||
|
prefer_spread_collections: true
|
||||||
|
prefer_typing_uninitialized_variables: true
|
||||||
|
provide_deprecation_message: true
|
||||||
|
recursive_getters: true
|
||||||
|
require_trailing_commas: true
|
||||||
|
sized_box_for_whitespace: true
|
||||||
|
sized_box_shrink_expand: true
|
||||||
|
slash_for_doc_comments: true
|
||||||
|
sort_child_properties_last: true
|
||||||
|
sort_pub_dependencies: true
|
||||||
|
type_init_formals: true
|
||||||
|
type_literal_in_constant_pattern: true
|
||||||
|
unawaited_futures: true
|
||||||
|
unnecessary_await_in_return: true
|
||||||
|
unnecessary_brace_in_string_interps: true
|
||||||
|
unnecessary_const: true
|
||||||
|
unnecessary_constructor_name: true
|
||||||
|
unnecessary_getters_setters: true
|
||||||
|
unnecessary_late: true
|
||||||
|
unnecessary_new: true
|
||||||
|
unnecessary_null_aware_assignments: true
|
||||||
|
unnecessary_null_in_if_null_operators: true
|
||||||
|
unnecessary_nullable_for_final_variable_declarations: true
|
||||||
|
unnecessary_overrides: true
|
||||||
|
unnecessary_parenthesis: true
|
||||||
|
unnecessary_statements: true
|
||||||
|
use_build_context_synchronously: true
|
||||||
|
use_colored_box: true
|
||||||
|
use_key_in_widget_constructors: true
|
||||||
|
valid_regexps: true
|
||||||
@@ -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();
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
name: example
|
||||||
|
description: "A new Flutter project."
|
||||||
|
publish_to: "none"
|
||||||
|
version: 0.1.0
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ^3.5.3
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
arcane_framework:
|
||||||
|
path: "../"
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
uuid: ^4.5.0
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_lints: ^4.0.0
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
uses-material-design: true
|
||||||
@@ -38,6 +38,7 @@ class ArcaneReactiveTheme extends ArcaneService {
|
|||||||
/// Returns the current light theme `ThemeData`.
|
/// Returns the current light theme `ThemeData`.
|
||||||
ThemeData get light => _lightTheme;
|
ThemeData get light => _lightTheme;
|
||||||
|
|
||||||
|
/// A listenable that notifies listeners when the syste theme mode changes.
|
||||||
ValueListenable<ThemeMode> get systemTheme =>
|
ValueListenable<ThemeMode> get systemTheme =>
|
||||||
ValueNotifier<ThemeMode>(_isDark ? ThemeMode.dark : ThemeMode.light);
|
ValueNotifier<ThemeMode>(_isDark ? ThemeMode.dark : ThemeMode.light);
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
name: arcane_framework
|
name: arcane_framework
|
||||||
description: "Agnostic Reusable Component Architecture for New Ecosystems"
|
description: "Agnostic Reusable Component Architecture for New Ecosystems: a modern framework for bootstrapping new applications"
|
||||||
version: 1.0.3
|
version: 1.0.3+1
|
||||||
repository: https://github.com/hanskokx/arcane_framework
|
repository: https://github.com/hanskokx/arcane_framework
|
||||||
issue_tracker: https://github.com/hanskokx/arcane_framework/issues
|
issue_tracker: https://github.com/hanskokx/arcane_framework/issues
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user