diff --git a/.gitattributes b/.gitattributes
index dfe0770424..a12925e59a 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,3 @@
# Auto detect text files and perform LF normalization
-* text=auto
+/extensions/_DocsExtension/**/*.kt text eol=lf
+* text=auto
\ No newline at end of file
diff --git a/README.md b/README.md
index 1d0a958b4e..d1f4505db7 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ For detailed setup instructions, visit the [Installation Guide](https://docs.typ
### Sponsors
-
+
Thanks to the following sponsors for supporting this project. Without their support, this project would not be possible. If you are using Typewriter for your server, and are making money from it, please consider [sponsoring](https://github.com/sponsors/gabber235) the project.
diff --git a/app/build.yaml b/app/build.yaml
new file mode 100644
index 0000000000..34d8f8d279
--- /dev/null
+++ b/app/build.yaml
@@ -0,0 +1,23 @@
+targets:
+ $default:
+ builders:
+ json_serializable:
+ options:
+ # Options configure how source code is generated for every
+ # `@JsonSerializable`-annotated class in the package.
+ #
+ # The default value for each is listed.
+ any_map: false
+ checked: false
+ constructor: ""
+ create_factory: true
+ create_field_map: false
+ create_json_keys: false
+ create_per_field_to_json: false
+ create_to_json: true
+ disallow_unrecognized_keys: false
+ explicit_to_json: true
+ field_rename: none
+ generic_argument_factories: false
+ ignore_unannotated: false
+ include_if_null: true
diff --git a/app/lib/app_router.dart b/app/lib/app_router.dart
index 0a1ec7401e..9374d47ed9 100644
--- a/app/lib/app_router.dart
+++ b/app/lib/app_router.dart
@@ -2,6 +2,7 @@ import "dart:async";
import "package:auto_route/auto_route.dart";
import "package:flutter/material.dart";
+import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:riverpod_annotation/riverpod_annotation.dart";
import "package:typewriter/guard/connected_guard.dart";
import "package:typewriter/models/page.dart";
@@ -85,7 +86,7 @@ class InvalidatorNavigatorObserver extends NavigatorObserver {
/// Provides the current route data for the given [name].
@Riverpod(keepAlive: true)
-RouteData? currentRouteData(CurrentRouteDataRef ref, String path) {
+RouteData? currentRouteData(Ref ref, String path) {
final router = ref.watch(appRouter);
return _fetchCurrentRouteData(path, router);
}
diff --git a/app/lib/app_router.g.dart b/app/lib/app_router.g.dart
index 52abcd35c5..ad6c5192a6 100644
--- a/app/lib/app_router.g.dart
+++ b/app/lib/app_router.g.dart
@@ -6,7 +6,7 @@ part of 'app_router.dart';
// RiverpodGenerator
// **************************************************************************
-String _$currentRouteDataHash() => r'85f6e480f36835de3b5fb961a26cce4215ee98aa';
+String _$currentRouteDataHash() => r'bc5d43d37915bc2ee1b3bd06af8a8f9f45cdb5ac';
/// Copied from Dart SDK
class _SystemHash {
@@ -154,6 +154,8 @@ class CurrentRouteDataProvider extends Provider {
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin CurrentRouteDataRef on ProviderRef {
/// The parameter `path` of this provider.
String get path;
@@ -167,4 +169,4 @@ class _CurrentRouteDataProviderElement extends ProviderElement
String get path => (origin as CurrentRouteDataProvider).path;
}
// ignore_for_file: type=lint
-// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
diff --git a/app/lib/hooks/delayed_execution.dart b/app/lib/hooks/delayed_execution.dart
index 079204192f..73b923e524 100644
--- a/app/lib/hooks/delayed_execution.dart
+++ b/app/lib/hooks/delayed_execution.dart
@@ -17,7 +17,8 @@ class _DelayedExecutionHook extends Hook {
_DelayedExecutionHookState createState() => _DelayedExecutionHookState();
}
-class _DelayedExecutionHookState extends HookState {
+class _DelayedExecutionHookState
+ extends HookState {
void _run() {
WidgetsBinding.instance.addPostFrameCallback((_) => hook.function());
}
diff --git a/app/lib/hooks/staggered_animation_controllers.dart b/app/lib/hooks/staggered_animation_controllers.dart
new file mode 100644
index 0000000000..2d45ed1cb6
--- /dev/null
+++ b/app/lib/hooks/staggered_animation_controllers.dart
@@ -0,0 +1,110 @@
+import "dart:async";
+
+import "package:flutter/material.dart";
+import "package:flutter_hooks/flutter_hooks.dart";
+
+/// Run multiple animation staggered from each other.
+List useStaggeredAnimationControllers({
+ required int count,
+ required Duration duration,
+ required Duration interval,
+ required TickerProvider vsync,
+ bool autoPlay = true,
+}) {
+ return use(
+ _StaggeredAnimationControllersHook(
+ count,
+ duration,
+ interval,
+ vsync,
+ autoPlay: autoPlay,
+ ),
+ );
+}
+
+class _StaggeredAnimationControllersHook
+ extends Hook> {
+ const _StaggeredAnimationControllersHook(
+ this.count,
+ this.duration,
+ this.interval,
+ this.vsync, {
+ required this.autoPlay,
+ });
+
+ final int count;
+ final Duration duration;
+ final Duration interval;
+ final bool autoPlay;
+ final TickerProvider vsync;
+
+ @override
+ _StaggeredAnimationControllersHookState createState() =>
+ _StaggeredAnimationControllersHookState();
+}
+
+class _StaggeredAnimationControllersHookState extends HookState<
+ List, _StaggeredAnimationControllersHook> {
+ List controllers = [];
+ Timer? timer;
+ int index = 0;
+
+ void _animate() {
+ if (!hook.autoPlay) {
+ return;
+ }
+ if (timer != null) {
+ return;
+ }
+ if (index >= hook.count) {
+ return;
+ }
+ timer = Timer.periodic(hook.interval, (timer) {
+ controllers[index].forward();
+ index = index + 1;
+ if (index >= hook.count) {
+ timer.cancel();
+ this.timer = null;
+ }
+ });
+ }
+
+ void _updateControllers() {
+ while (controllers.length > hook.count) {
+ controllers.removeLast();
+ }
+
+ while (controllers.length < hook.count) {
+ controllers.add(
+ AnimationController(
+ duration: hook.duration,
+ vsync: hook.vsync,
+ ),
+ );
+
+ if (index >= controllers.length) {
+ index = controllers.length - 1;
+ }
+ }
+ }
+
+ @override
+ void initHook() {
+ _updateControllers();
+ _animate();
+ super.initHook();
+ }
+
+ @override
+ List build(BuildContext context) {
+ _updateControllers();
+ _animate();
+ return controllers;
+ }
+
+ @override
+ void dispose() {
+ timer?.cancel();
+ super.dispose();
+ }
+}
diff --git a/app/lib/models/communicator.dart b/app/lib/models/communicator.dart
index e204f72975..23d35675cb 100644
--- a/app/lib/models/communicator.dart
+++ b/app/lib/models/communicator.dart
@@ -41,7 +41,7 @@ final socketProvider = StateNotifierProvider(
class SocketNotifier extends StateNotifier {
SocketNotifier(this.ref) : super(null);
- final StateNotifierProviderRef ref;
+ final Ref ref;
bool _disposed = false;
/// When a socket gets disconnected, we want to try to reconnect it.
@@ -235,13 +235,13 @@ class SocketNotifier extends StateNotifier {
}
@Riverpod(keepAlive: true)
-Communicator communicator(CommunicatorRef ref) => Communicator(ref);
+Communicator communicator(Ref ref) => Communicator(ref);
@immutable
class Communicator {
const Communicator(this.ref);
- final CommunicatorRef ref;
+ final Ref ref;
Future fetchBook() async {
final socket = ref.read(socketProvider);
diff --git a/app/lib/models/communicator.g.dart b/app/lib/models/communicator.g.dart
index 86a703df5c..99af6daf55 100644
--- a/app/lib/models/communicator.g.dart
+++ b/app/lib/models/communicator.g.dart
@@ -22,7 +22,7 @@ Map _$$ResponseImplToJson(_$ResponseImpl instance) =>
// RiverpodGenerator
// **************************************************************************
-String _$communicatorHash() => r'9085b5b631ddf5d09d571a34e6d1de239259e08f';
+String _$communicatorHash() => r'31ea59bcbb12c56d2ec15a773434802d1e663753';
/// See also [communicator].
@ProviderFor(communicator)
@@ -35,6 +35,8 @@ final communicatorProvider = Provider.internal(
allTransitiveDependencies: null,
);
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
typedef CommunicatorRef = ProviderRef;
// ignore_for_file: type=lint
-// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
diff --git a/app/lib/models/entry.dart b/app/lib/models/entry.dart
index 36adf4794e..0c9e0711e6 100644
--- a/app/lib/models/entry.dart
+++ b/app/lib/models/entry.dart
@@ -1,6 +1,7 @@
import "dart:convert";
import "package:collection/collection.dart";
+import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:riverpod_annotation/riverpod_annotation.dart";
import "package:typewriter/models/entry_blueprint.dart";
import "package:typewriter/models/page.dart";
@@ -11,7 +12,7 @@ part "entry.g.dart";
@riverpod
EntryDefinition? entryDefinition(
- EntryDefinitionRef ref,
+ Ref ref,
String entryId,
) {
final page = ref.watch(entryPageProvider(entryId));
@@ -32,21 +33,30 @@ EntryDefinition? entryDefinition(
}
@riverpod
-String? entryName(EntryNameRef ref, String entryId) {
+String? entryName(Ref ref, String entryId) {
final entry = ref.watch(globalEntryProvider(entryId));
return entry?.formattedName;
}
@riverpod
-String? entryBlueprintId(EntryBlueprintIdRef ref, String entryId) {
+String? entryBlueprintId(Ref ref, String entryId) {
final entry = ref.watch(globalEntryProvider(entryId));
return entry?.blueprintId;
}
@riverpod
-bool isEntryDeprecated(IsEntryDeprecatedRef ref, String entryId) {
- final entryTags = ref.watch(entryTagsProvider(entryId));
- return entryTags.contains("deprecated");
+DeprecatedModifier? entryDeprecated(Ref ref, String entryId) {
+ final blueprintId = ref.watch(entryBlueprintIdProvider(entryId));
+ if (blueprintId == null) return null;
+ final blueprint = ref.watch(entryBlueprintProvider(blueprintId));
+ if (blueprint == null) return null;
+ return blueprint.modifiers.whereType().firstOrNull;
+}
+
+@riverpod
+bool isEntryDeprecated(Ref ref, String entryId) {
+ final deprecated = ref.watch(entryDeprecatedProvider(entryId));
+ return deprecated != null;
}
class EntryDefinition {
@@ -74,15 +84,28 @@ class Entry {
Entry.fromBlueprint({
required String id,
required EntryBlueprint blueprint,
- }) : data = {
+ DataBlueprint? genericBlueprint,
+ }) : assert(
+ blueprint.isGeneric == (genericBlueprint != null),
+ blueprint.isGeneric
+ ? "Blueprint is generic but no generic blueprint was provided"
+ : "Blueprint is not generic but a generic blueprint was provided",
+ ),
+ assert(
+ blueprint.allowsGeneric(genericBlueprint),
+ "Generic blueprint given is not allowed for this blueprint, blueprint: ${blueprint.id}, allowed: ${blueprint.genericConstraints}, genericBlueprint: $genericBlueprint",
+ ),
+ data = {
...blueprint.dataBlueprint.defaultValue(),
"id": id,
"name": "new_${blueprint.name}",
"type": blueprint.id,
+ "_genericBlueprint": genericBlueprint?.toJson(),
};
factory Entry.fromJson(Map json) => Entry(json);
final Map data;
+ DataBlueprint? _genericBlueprint;
Map toJson() => data;
@@ -102,6 +125,21 @@ class Entry {
throw Exception("Could not find blueprint id or type in entry data");
}
+ /// Returns the generic blueprint of the entry.
+ DataBlueprint? get genericBlueprint {
+ if (_genericBlueprint != null) return _genericBlueprint;
+ final genericBlueprint = data["_genericBlueprint"];
+ if (genericBlueprint == null) return null;
+
+ if (genericBlueprint is! Map) {
+ throw Exception("Generic blueprint is not a map");
+ }
+
+ final blueprint = DataBlueprint.fromJson(genericBlueprint);
+ _genericBlueprint = blueprint;
+ return blueprint;
+ }
+
/// Returns the values in [map] that match [path].
///
/// The path is a string representation of keys and indices to access the values in [map].
diff --git a/app/lib/models/entry.g.dart b/app/lib/models/entry.g.dart
index 2753e66cd7..fa8b8b7785 100644
--- a/app/lib/models/entry.g.dart
+++ b/app/lib/models/entry.g.dart
@@ -6,7 +6,7 @@ part of 'entry.dart';
// RiverpodGenerator
// **************************************************************************
-String _$entryDefinitionHash() => r'48daba0fcb38d6f4c72fe2fe06680bed39074626';
+String _$entryDefinitionHash() => r'3db66db468e0d5ba6bc0041201174dfd2189955e';
/// Copied from Dart SDK
class _SystemHash {
@@ -142,6 +142,8 @@ class EntryDefinitionProvider extends AutoDisposeProvider {
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin EntryDefinitionRef on AutoDisposeProviderRef {
/// The parameter `entryId` of this provider.
String get entryId;
@@ -156,7 +158,7 @@ class _EntryDefinitionProviderElement
String get entryId => (origin as EntryDefinitionProvider).entryId;
}
-String _$entryNameHash() => r'7e19e3e55767e19fe015a69c99f4af9173872ef2';
+String _$entryNameHash() => r'c24fb19c761064f9dfb5cf881d78a213d5bee5de';
/// See also [entryName].
@ProviderFor(entryName)
@@ -270,6 +272,8 @@ class EntryNameProvider extends AutoDisposeProvider {
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin EntryNameRef on AutoDisposeProviderRef {
/// The parameter `entryId` of this provider.
String get entryId;
@@ -283,7 +287,7 @@ class _EntryNameProviderElement extends AutoDisposeProviderElement
String get entryId => (origin as EntryNameProvider).entryId;
}
-String _$entryBlueprintIdHash() => r'5cac165b3797bad6ce6518cd948251f1107d7a2d';
+String _$entryBlueprintIdHash() => r'7706260dfec68caabf7d9ae4c7d151548d3abef8';
/// See also [entryBlueprintId].
@ProviderFor(entryBlueprintId)
@@ -398,6 +402,8 @@ class EntryBlueprintIdProvider extends AutoDisposeProvider {
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin EntryBlueprintIdRef on AutoDisposeProviderRef {
/// The parameter `entryId` of this provider.
String get entryId;
@@ -411,7 +417,138 @@ class _EntryBlueprintIdProviderElement
String get entryId => (origin as EntryBlueprintIdProvider).entryId;
}
-String _$isEntryDeprecatedHash() => r'f7417cbbc63faac9f66342e4170f30e7466c646a';
+String _$entryDeprecatedHash() => r'379035c4bf36de1185ce43187253b02ea579eaa9';
+
+/// See also [entryDeprecated].
+@ProviderFor(entryDeprecated)
+const entryDeprecatedProvider = EntryDeprecatedFamily();
+
+/// See also [entryDeprecated].
+class EntryDeprecatedFamily extends Family {
+ /// See also [entryDeprecated].
+ const EntryDeprecatedFamily();
+
+ /// See also [entryDeprecated].
+ EntryDeprecatedProvider call(
+ String entryId,
+ ) {
+ return EntryDeprecatedProvider(
+ entryId,
+ );
+ }
+
+ @override
+ EntryDeprecatedProvider getProviderOverride(
+ covariant EntryDeprecatedProvider provider,
+ ) {
+ return call(
+ provider.entryId,
+ );
+ }
+
+ static const Iterable? _dependencies = null;
+
+ @override
+ Iterable? get dependencies => _dependencies;
+
+ static const Iterable? _allTransitiveDependencies = null;
+
+ @override
+ Iterable? get allTransitiveDependencies =>
+ _allTransitiveDependencies;
+
+ @override
+ String? get name => r'entryDeprecatedProvider';
+}
+
+/// See also [entryDeprecated].
+class EntryDeprecatedProvider extends AutoDisposeProvider {
+ /// See also [entryDeprecated].
+ EntryDeprecatedProvider(
+ String entryId,
+ ) : this._internal(
+ (ref) => entryDeprecated(
+ ref as EntryDeprecatedRef,
+ entryId,
+ ),
+ from: entryDeprecatedProvider,
+ name: r'entryDeprecatedProvider',
+ debugGetCreateSourceHash:
+ const bool.fromEnvironment('dart.vm.product')
+ ? null
+ : _$entryDeprecatedHash,
+ dependencies: EntryDeprecatedFamily._dependencies,
+ allTransitiveDependencies:
+ EntryDeprecatedFamily._allTransitiveDependencies,
+ entryId: entryId,
+ );
+
+ EntryDeprecatedProvider._internal(
+ super._createNotifier, {
+ required super.name,
+ required super.dependencies,
+ required super.allTransitiveDependencies,
+ required super.debugGetCreateSourceHash,
+ required super.from,
+ required this.entryId,
+ }) : super.internal();
+
+ final String entryId;
+
+ @override
+ Override overrideWith(
+ DeprecatedModifier? Function(EntryDeprecatedRef provider) create,
+ ) {
+ return ProviderOverride(
+ origin: this,
+ override: EntryDeprecatedProvider._internal(
+ (ref) => create(ref as EntryDeprecatedRef),
+ from: from,
+ name: null,
+ dependencies: null,
+ allTransitiveDependencies: null,
+ debugGetCreateSourceHash: null,
+ entryId: entryId,
+ ),
+ );
+ }
+
+ @override
+ AutoDisposeProviderElement createElement() {
+ return _EntryDeprecatedProviderElement(this);
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return other is EntryDeprecatedProvider && other.entryId == entryId;
+ }
+
+ @override
+ int get hashCode {
+ var hash = _SystemHash.combine(0, runtimeType.hashCode);
+ hash = _SystemHash.combine(hash, entryId.hashCode);
+
+ return _SystemHash.finish(hash);
+ }
+}
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+mixin EntryDeprecatedRef on AutoDisposeProviderRef {
+ /// The parameter `entryId` of this provider.
+ String get entryId;
+}
+
+class _EntryDeprecatedProviderElement
+ extends AutoDisposeProviderElement
+ with EntryDeprecatedRef {
+ _EntryDeprecatedProviderElement(super.provider);
+
+ @override
+ String get entryId => (origin as EntryDeprecatedProvider).entryId;
+}
+
+String _$isEntryDeprecatedHash() => r'e763f6414bab29d177973400fed8321d8e68b1c7';
/// See also [isEntryDeprecated].
@ProviderFor(isEntryDeprecated)
@@ -526,6 +663,8 @@ class IsEntryDeprecatedProvider extends AutoDisposeProvider {
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin IsEntryDeprecatedRef on AutoDisposeProviderRef {
/// The parameter `entryId` of this provider.
String get entryId;
@@ -539,4 +678,4 @@ class _IsEntryDeprecatedProviderElement extends AutoDisposeProviderElement
String get entryId => (origin as IsEntryDeprecatedProvider).entryId;
}
// ignore_for_file: type=lint
-// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
diff --git a/app/lib/models/entry_blueprint.dart b/app/lib/models/entry_blueprint.dart
index edebdc5e7a..cf196f036d 100644
--- a/app/lib/models/entry_blueprint.dart
+++ b/app/lib/models/entry_blueprint.dart
@@ -2,11 +2,13 @@ import "package:collection/collection.dart";
import "package:flutter/foundation.dart";
import "package:flutter/material.dart";
import "package:freezed_annotation/freezed_annotation.dart";
+import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:riverpod_annotation/riverpod_annotation.dart";
import "package:typewriter/models/entry.dart";
import "package:typewriter/models/extension.dart";
import "package:typewriter/models/page.dart";
import "package:typewriter/utils/color_converter.dart";
+import "package:typewriter/utils/extensions.dart";
import "package:typewriter/utils/icons.dart";
import "package:url_launcher/url_launcher_string.dart";
@@ -17,25 +19,25 @@ part "entry_blueprint.g.dart";
/// A generated provider to fetch and cache a list of all the [EntryBlueprint]s.
@riverpod
-List entryBlueprints(EntryBlueprintsRef ref) =>
+List entryBlueprints(Ref ref) =>
ref.watch(extensionsProvider).expand((e) => e.entries).toList();
/// A generated provider to fetch and cache a specific [EntryBlueprint] by its [blueprintId].
@riverpod
-EntryBlueprint? entryBlueprint(EntryBlueprintRef ref, String blueprintId) => ref
+EntryBlueprint? entryBlueprint(Ref ref, String blueprintId) => ref
.watch(entryBlueprintsProvider)
.firstWhereOrNull((e) => e.id == blueprintId);
@riverpod
List entryBlueprintTags(
- EntryBlueprintTagsRef ref,
+ Ref ref,
String blueprintId,
) =>
ref.watch(entryBlueprintProvider(blueprintId))?.tags ?? [];
@riverpod
List entryTags(
- EntryTagsRef ref,
+ Ref ref,
String entryId,
) {
final blueprintId = ref.watch(entryBlueprintIdProvider(entryId));
@@ -45,7 +47,7 @@ List entryTags(
@riverpod
PageType entryBlueprintPageType(
- EntryBlueprintPageTypeRef ref,
+ Ref ref,
String blueprintId,
) {
final blueprint = ref.watch(entryBlueprintProvider(blueprintId));
@@ -56,7 +58,7 @@ PageType entryBlueprintPageType(
/// Gets all the modifiers with a given name.
@riverpod
Map fieldModifiers(
- FieldModifiersRef ref,
+ Ref ref,
String blueprintId,
String modifierName,
) {
@@ -69,7 +71,7 @@ Map fieldModifiers(
/// Gets all the paths from fields with a given modifier.
@riverpod
List modifierPaths(
- ModifierPathsRef ref,
+ Ref ref,
String blueprintId,
String modifierName, [
String? data,
@@ -91,9 +93,12 @@ class EntryBlueprint with _$EntryBlueprint {
required String description,
required String extension,
required ObjectBlueprint dataBlueprint,
- @Default([]) List tags,
@ColorConverter() @Default(Colors.grey) Color color,
@Default(TWIcons.help) String icon,
+ @Default([]) List tags,
+ @Default(null) List? genericConstraints,
+ @Default(null) DataBlueprint? variableDataBlueprint,
+ @Default([]) List modifiers,
}) = _EntryBlueprint;
factory EntryBlueprint.fromJson(Map json) =>
@@ -177,11 +182,37 @@ class Modifier with _$Modifier {
_$ModifierFromJson(json);
}
+@Freezed(unionKey: "kind")
+class EntryModifier with _$EntryModifier {
+ const factory EntryModifier() = _EmptyModifier;
+
+ const factory EntryModifier.deprecated({
+ @Default("") String reason,
+ }) = DeprecatedModifier;
+
+ factory EntryModifier.fromJson(Map json) =>
+ _$EntryModifierFromJson(json);
+}
+
const wikiBaseUrl = kDebugMode
? "http://localhost:3000/TypeWriter"
: "https://gabber235.github.io/TypeWriter";
extension EntryBlueprintExt on EntryBlueprint {
+ bool get isGeneric => genericConstraints != null;
+
+ bool allowsGeneric(DataBlueprint? genericBlueprint) {
+ final blueprints = genericConstraints;
+ if (blueprints == null) return true;
+ if (genericBlueprint == null) return false;
+ // If the blueprints is empty, all blueprints are allowed.
+ if (blueprints.isEmpty) return true;
+ for (final blueprint in blueprints) {
+ if (blueprint.matches(genericBlueprint)) return true;
+ }
+ return blueprints.any((e) => e.matches(genericBlueprint));
+ }
+
Map fieldsWithModifier(String name) =>
_fieldsWithModifier(name, "", dataBlueprint);
@@ -195,25 +226,28 @@ extension EntryBlueprintExt on EntryBlueprint {
if (blueprint.hasModifier(name)) path: blueprint.getModifier(name)!,
};
- final separator = path.isEmpty ? "" : ".";
if (blueprint is ObjectBlueprint) {
for (final field in blueprint.fields.entries) {
fields.addAll(
_fieldsWithModifier(
name,
- "$path$separator${field.key}",
+ path.join(field.key),
field.value,
),
);
}
} else if (blueprint is ListBlueprint) {
fields.addAll(
- _fieldsWithModifier(name, "$path$separator*", blueprint.type),
+ _fieldsWithModifier(name, path.join("*"), blueprint.type),
);
} else if (blueprint is MapBlueprint) {
- fields.addAll(
- _fieldsWithModifier(name, "$path$separator*", blueprint.value),
- );
+ fields
+ ..addAll(
+ _fieldsWithModifier(name, path, blueprint.key),
+ )
+ ..addAll(
+ _fieldsWithModifier(name, path.join("*"), blueprint.value),
+ );
}
return fields;
@@ -263,11 +297,10 @@ extension EntryBlueprintExt on EntryBlueprint {
}
final _customEditorCustomLayout = [
- "optional",
"item",
"skin",
"color",
- "closedRange",
+ "var",
];
/// Since freezed does not support methods on data models, we have to create a separate extension class.
@@ -344,10 +377,6 @@ extension DataBlueprintExtension on DataBlueprint {
if (this is MapBlueprint) {
return true;
}
- if (this is PrimitiveBlueprint &&
- (this as PrimitiveBlueprint).type == PrimitiveType.boolean) {
- return true;
- }
return false;
}
@@ -363,6 +392,49 @@ extension DataBlueprintExtension on DataBlueprint {
final modifier = getModifier(name);
return modifier?.data as T?;
}
+
+ bool matches(DataBlueprint other) {
+ if (this is PrimitiveBlueprint && other is PrimitiveBlueprint) {
+ return other.type == (this as PrimitiveBlueprint).type;
+ }
+ if (this is EnumBlueprint && other is EnumBlueprint) {
+ return listEquals(other.values, (this as EnumBlueprint).values);
+ }
+ if (this is ListBlueprint && other is ListBlueprint) {
+ return other.type.matches((this as ListBlueprint).type);
+ }
+ if (this is MapBlueprint && other is MapBlueprint) {
+ return other.key.matches((this as MapBlueprint).key) &&
+ other.value.matches((this as MapBlueprint).value);
+ }
+ if (this is ObjectBlueprint && other is ObjectBlueprint) {
+ final obj = this as ObjectBlueprint;
+ if (obj.fields.length != other.fields.length) return false;
+ if (!setEquals(obj.fields.keys.toSet(), other.fields.keys.toSet())) {
+ return false;
+ }
+ for (final key in obj.fields.keys) {
+ if (!other.fields.containsKey(key)) return false;
+ if (!obj.fields[key]!.matches(other.fields[key]!)) return false;
+ }
+ return true;
+ }
+ if (this is AlgebraicBlueprint && other is AlgebraicBlueprint) {
+ final alg = this as AlgebraicBlueprint;
+ if (alg.cases.length != other.cases.length) return false;
+ if (alg.cases.keys.toSet() != other.cases.keys.toSet()) return false;
+ for (final key in alg.cases.keys) {
+ if (!other.cases.containsKey(key)) return false;
+ if (!alg.cases[key]!.matches(other.cases[key]!)) return false;
+ }
+ return true;
+ }
+ if (this is CustomBlueprint && other is CustomBlueprint) {
+ return other.editor == (this as CustomBlueprint).editor &&
+ other.shape.matches((this as CustomBlueprint).shape);
+ }
+ return false;
+ }
}
/// A data model that represents a primitive field type.
diff --git a/app/lib/models/entry_blueprint.freezed.dart b/app/lib/models/entry_blueprint.freezed.dart
index 5cca3dd812..7fb223d827 100644
--- a/app/lib/models/entry_blueprint.freezed.dart
+++ b/app/lib/models/entry_blueprint.freezed.dart
@@ -25,10 +25,15 @@ mixin _$EntryBlueprint {
String get description => throw _privateConstructorUsedError;
String get extension => throw _privateConstructorUsedError;
ObjectBlueprint get dataBlueprint => throw _privateConstructorUsedError;
- List get tags => throw _privateConstructorUsedError;
@ColorConverter()
Color get color => throw _privateConstructorUsedError;
String get icon => throw _privateConstructorUsedError;
+ List get tags => throw _privateConstructorUsedError;
+ List? get genericConstraints =>
+ throw _privateConstructorUsedError;
+ DataBlueprint? get variableDataBlueprint =>
+ throw _privateConstructorUsedError;
+ List get modifiers => throw _privateConstructorUsedError;
/// Serializes this EntryBlueprint to a JSON map.
Map toJson() => throw _privateConstructorUsedError;
@@ -52,9 +57,14 @@ abstract class $EntryBlueprintCopyWith<$Res> {
String description,
String extension,
ObjectBlueprint dataBlueprint,
- List tags,
@ColorConverter() Color color,
- String icon});
+ String icon,
+ List tags,
+ List? genericConstraints,
+ DataBlueprint? variableDataBlueprint,
+ List modifiers});
+
+ $DataBlueprintCopyWith<$Res>? get variableDataBlueprint;
}
/// @nodoc
@@ -77,9 +87,12 @@ class _$EntryBlueprintCopyWithImpl<$Res, $Val extends EntryBlueprint>
Object? description = null,
Object? extension = null,
Object? dataBlueprint = freezed,
- Object? tags = null,
Object? color = null,
Object? icon = null,
+ Object? tags = null,
+ Object? genericConstraints = freezed,
+ Object? variableDataBlueprint = freezed,
+ Object? modifiers = null,
}) {
return _then(_value.copyWith(
id: null == id
@@ -102,10 +115,6 @@ class _$EntryBlueprintCopyWithImpl<$Res, $Val extends EntryBlueprint>
? _value.dataBlueprint
: dataBlueprint // ignore: cast_nullable_to_non_nullable
as ObjectBlueprint,
- tags: null == tags
- ? _value.tags
- : tags // ignore: cast_nullable_to_non_nullable
- as List,
color: null == color
? _value.color
: color // ignore: cast_nullable_to_non_nullable
@@ -114,8 +123,38 @@ class _$EntryBlueprintCopyWithImpl<$Res, $Val extends EntryBlueprint>
? _value.icon
: icon // ignore: cast_nullable_to_non_nullable
as String,
+ tags: null == tags
+ ? _value.tags
+ : tags // ignore: cast_nullable_to_non_nullable
+ as List,
+ genericConstraints: freezed == genericConstraints
+ ? _value.genericConstraints
+ : genericConstraints // ignore: cast_nullable_to_non_nullable
+ as List?,
+ variableDataBlueprint: freezed == variableDataBlueprint
+ ? _value.variableDataBlueprint
+ : variableDataBlueprint // ignore: cast_nullable_to_non_nullable
+ as DataBlueprint?,
+ modifiers: null == modifiers
+ ? _value.modifiers
+ : modifiers // ignore: cast_nullable_to_non_nullable
+ as List,
) as $Val);
}
+
+ /// Create a copy of EntryBlueprint
+ /// with the given fields replaced by the non-null parameter values.
+ @override
+ @pragma('vm:prefer-inline')
+ $DataBlueprintCopyWith<$Res>? get variableDataBlueprint {
+ if (_value.variableDataBlueprint == null) {
+ return null;
+ }
+
+ return $DataBlueprintCopyWith<$Res>(_value.variableDataBlueprint!, (value) {
+ return _then(_value.copyWith(variableDataBlueprint: value) as $Val);
+ });
+ }
}
/// @nodoc
@@ -132,9 +171,15 @@ abstract class _$$EntryBlueprintImplCopyWith<$Res>
String description,
String extension,
ObjectBlueprint dataBlueprint,
- List tags,
@ColorConverter() Color color,
- String icon});
+ String icon,
+ List tags,
+ List? genericConstraints,
+ DataBlueprint? variableDataBlueprint,
+ List modifiers});
+
+ @override
+ $DataBlueprintCopyWith<$Res>? get variableDataBlueprint;
}
/// @nodoc
@@ -155,9 +200,12 @@ class __$$EntryBlueprintImplCopyWithImpl<$Res>
Object? description = null,
Object? extension = null,
Object? dataBlueprint = freezed,
- Object? tags = null,
Object? color = null,
Object? icon = null,
+ Object? tags = null,
+ Object? genericConstraints = freezed,
+ Object? variableDataBlueprint = freezed,
+ Object? modifiers = null,
}) {
return _then(_$EntryBlueprintImpl(
id: null == id
@@ -180,10 +228,6 @@ class __$$EntryBlueprintImplCopyWithImpl<$Res>
? _value.dataBlueprint
: dataBlueprint // ignore: cast_nullable_to_non_nullable
as ObjectBlueprint,
- tags: null == tags
- ? _value._tags
- : tags // ignore: cast_nullable_to_non_nullable
- as List,
color: null == color
? _value.color
: color // ignore: cast_nullable_to_non_nullable
@@ -192,6 +236,22 @@ class __$$EntryBlueprintImplCopyWithImpl<$Res>
? _value.icon
: icon // ignore: cast_nullable_to_non_nullable
as String,
+ tags: null == tags
+ ? _value._tags
+ : tags // ignore: cast_nullable_to_non_nullable
+ as List,
+ genericConstraints: freezed == genericConstraints
+ ? _value._genericConstraints
+ : genericConstraints // ignore: cast_nullable_to_non_nullable
+ as List?,
+ variableDataBlueprint: freezed == variableDataBlueprint
+ ? _value.variableDataBlueprint
+ : variableDataBlueprint // ignore: cast_nullable_to_non_nullable
+ as DataBlueprint?,
+ modifiers: null == modifiers
+ ? _value._modifiers
+ : modifiers // ignore: cast_nullable_to_non_nullable
+ as List,
));
}
}
@@ -207,10 +267,15 @@ class _$EntryBlueprintImpl
required this.description,
required this.extension,
required this.dataBlueprint,
- final List tags = const [],
@ColorConverter() this.color = Colors.grey,
- this.icon = TWIcons.help})
- : _tags = tags;
+ this.icon = TWIcons.help,
+ final List tags = const [],
+ final List? genericConstraints = null,
+ this.variableDataBlueprint = null,
+ final List modifiers = const []})
+ : _tags = tags,
+ _genericConstraints = genericConstraints,
+ _modifiers = modifiers;
factory _$EntryBlueprintImpl.fromJson(Map json) =>
_$$EntryBlueprintImplFromJson(json);
@@ -225,6 +290,13 @@ class _$EntryBlueprintImpl
final String extension;
@override
final ObjectBlueprint dataBlueprint;
+ @override
+ @JsonKey()
+ @ColorConverter()
+ final Color color;
+ @override
+ @JsonKey()
+ final String icon;
final List _tags;
@override
@JsonKey()
@@ -234,17 +306,33 @@ class _$EntryBlueprintImpl
return EqualUnmodifiableListView(_tags);
}
+ final List? _genericConstraints;
@override
@JsonKey()
- @ColorConverter()
- final Color color;
+ List? get genericConstraints {
+ final value = _genericConstraints;
+ if (value == null) return null;
+ if (_genericConstraints is EqualUnmodifiableListView)
+ return _genericConstraints;
+ // ignore: implicit_dynamic_type
+ return EqualUnmodifiableListView(value);
+ }
+
@override
@JsonKey()
- final String icon;
+ final DataBlueprint? variableDataBlueprint;
+ final List _modifiers;
+ @override
+ @JsonKey()
+ List get modifiers {
+ if (_modifiers is EqualUnmodifiableListView) return _modifiers;
+ // ignore: implicit_dynamic_type
+ return EqualUnmodifiableListView(_modifiers);
+ }
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
- return 'EntryBlueprint(id: $id, name: $name, description: $description, extension: $extension, dataBlueprint: $dataBlueprint, tags: $tags, color: $color, icon: $icon)';
+ return 'EntryBlueprint(id: $id, name: $name, description: $description, extension: $extension, dataBlueprint: $dataBlueprint, color: $color, icon: $icon, tags: $tags, genericConstraints: $genericConstraints, variableDataBlueprint: $variableDataBlueprint, modifiers: $modifiers)';
}
@override
@@ -257,9 +345,12 @@ class _$EntryBlueprintImpl
..add(DiagnosticsProperty('description', description))
..add(DiagnosticsProperty('extension', extension))
..add(DiagnosticsProperty('dataBlueprint', dataBlueprint))
- ..add(DiagnosticsProperty('tags', tags))
..add(DiagnosticsProperty('color', color))
- ..add(DiagnosticsProperty('icon', icon));
+ ..add(DiagnosticsProperty('icon', icon))
+ ..add(DiagnosticsProperty('tags', tags))
+ ..add(DiagnosticsProperty('genericConstraints', genericConstraints))
+ ..add(DiagnosticsProperty('variableDataBlueprint', variableDataBlueprint))
+ ..add(DiagnosticsProperty('modifiers', modifiers));
}
@override
@@ -275,9 +366,15 @@ class _$EntryBlueprintImpl
other.extension == extension) &&
const DeepCollectionEquality()
.equals(other.dataBlueprint, dataBlueprint) &&
- const DeepCollectionEquality().equals(other._tags, _tags) &&
(identical(other.color, color) || other.color == color) &&
- (identical(other.icon, icon) || other.icon == icon));
+ (identical(other.icon, icon) || other.icon == icon) &&
+ const DeepCollectionEquality().equals(other._tags, _tags) &&
+ const DeepCollectionEquality()
+ .equals(other._genericConstraints, _genericConstraints) &&
+ (identical(other.variableDataBlueprint, variableDataBlueprint) ||
+ other.variableDataBlueprint == variableDataBlueprint) &&
+ const DeepCollectionEquality()
+ .equals(other._modifiers, _modifiers));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -289,9 +386,12 @@ class _$EntryBlueprintImpl
description,
extension,
const DeepCollectionEquality().hash(dataBlueprint),
- const DeepCollectionEquality().hash(_tags),
color,
- icon);
+ icon,
+ const DeepCollectionEquality().hash(_tags),
+ const DeepCollectionEquality().hash(_genericConstraints),
+ variableDataBlueprint,
+ const DeepCollectionEquality().hash(_modifiers));
/// Create a copy of EntryBlueprint
/// with the given fields replaced by the non-null parameter values.
@@ -317,9 +417,12 @@ abstract class _EntryBlueprint implements EntryBlueprint {
required final String description,
required final String extension,
required final ObjectBlueprint dataBlueprint,
- final List tags,
@ColorConverter() final Color color,
- final String icon}) = _$EntryBlueprintImpl;
+ final String icon,
+ final List tags,
+ final List? genericConstraints,
+ final DataBlueprint? variableDataBlueprint,
+ final List modifiers}) = _$EntryBlueprintImpl;
factory _EntryBlueprint.fromJson(Map json) =
_$EntryBlueprintImpl.fromJson;
@@ -335,12 +438,18 @@ abstract class _EntryBlueprint implements EntryBlueprint {
@override
ObjectBlueprint get dataBlueprint;
@override
- List get tags;
- @override
@ColorConverter()
Color get color;
@override
String get icon;
+ @override
+ List get tags;
+ @override
+ List? get genericConstraints;
+ @override
+ DataBlueprint? get variableDataBlueprint;
+ @override
+ List get modifiers;
/// Create a copy of EntryBlueprint
/// with the given fields replaced by the non-null parameter values.
@@ -3662,3 +3771,383 @@ abstract class _Modifier implements Modifier {
_$$ModifierImplCopyWith<_$ModifierImpl> get copyWith =>
throw _privateConstructorUsedError;
}
+
+EntryModifier _$EntryModifierFromJson(Map json) {
+ switch (json['kind']) {
+ case 'default':
+ return _EmptyModifier.fromJson(json);
+ case 'deprecated':
+ return DeprecatedModifier.fromJson(json);
+
+ default:
+ throw CheckedFromJsonException(json, 'kind', 'EntryModifier',
+ 'Invalid union type "${json['kind']}"!');
+ }
+}
+
+/// @nodoc
+mixin _$EntryModifier {
+ @optionalTypeArgs
+ TResult when(
+ TResult Function() $default, {
+ required TResult Function(String reason) deprecated,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult? whenOrNull(
+ TResult? Function()? $default, {
+ TResult? Function(String reason)? deprecated,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult maybeWhen(
+ TResult Function()? $default, {
+ TResult Function(String reason)? deprecated,
+ required TResult orElse(),
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult map(
+ TResult Function(_EmptyModifier value) $default, {
+ required TResult Function(DeprecatedModifier value) deprecated,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult? mapOrNull(
+ TResult? Function(_EmptyModifier value)? $default, {
+ TResult? Function(DeprecatedModifier value)? deprecated,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult maybeMap(
+ TResult Function(_EmptyModifier value)? $default, {
+ TResult Function(DeprecatedModifier value)? deprecated,
+ required TResult orElse(),
+ }) =>
+ throw _privateConstructorUsedError;
+
+ /// Serializes this EntryModifier to a JSON map.
+ Map toJson() => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $EntryModifierCopyWith<$Res> {
+ factory $EntryModifierCopyWith(
+ EntryModifier value, $Res Function(EntryModifier) then) =
+ _$EntryModifierCopyWithImpl<$Res, EntryModifier>;
+}
+
+/// @nodoc
+class _$EntryModifierCopyWithImpl<$Res, $Val extends EntryModifier>
+ implements $EntryModifierCopyWith<$Res> {
+ _$EntryModifierCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ /// Create a copy of EntryModifier
+ /// with the given fields replaced by the non-null parameter values.
+}
+
+/// @nodoc
+abstract class _$$EmptyModifierImplCopyWith<$Res> {
+ factory _$$EmptyModifierImplCopyWith(
+ _$EmptyModifierImpl value, $Res Function(_$EmptyModifierImpl) then) =
+ __$$EmptyModifierImplCopyWithImpl<$Res>;
+}
+
+/// @nodoc
+class __$$EmptyModifierImplCopyWithImpl<$Res>
+ extends _$EntryModifierCopyWithImpl<$Res, _$EmptyModifierImpl>
+ implements _$$EmptyModifierImplCopyWith<$Res> {
+ __$$EmptyModifierImplCopyWithImpl(
+ _$EmptyModifierImpl _value, $Res Function(_$EmptyModifierImpl) _then)
+ : super(_value, _then);
+
+ /// Create a copy of EntryModifier
+ /// with the given fields replaced by the non-null parameter values.
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$EmptyModifierImpl
+ with DiagnosticableTreeMixin
+ implements _EmptyModifier {
+ const _$EmptyModifierImpl({final String? $type}) : $type = $type ?? 'default';
+
+ factory _$EmptyModifierImpl.fromJson(Map json) =>
+ _$$EmptyModifierImplFromJson(json);
+
+ @JsonKey(name: 'kind')
+ final String $type;
+
+ @override
+ String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
+ return 'EntryModifier()';
+ }
+
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties.add(DiagnosticsProperty('type', 'EntryModifier'));
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType && other is _$EmptyModifierImpl);
+ }
+
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ @override
+ int get hashCode => runtimeType.hashCode;
+
+ @override
+ @optionalTypeArgs
+ TResult when(
+ TResult Function() $default, {
+ required TResult Function(String reason) deprecated,
+ }) {
+ return $default();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? whenOrNull(
+ TResult? Function()? $default, {
+ TResult? Function(String reason)? deprecated,
+ }) {
+ return $default?.call();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen(
+ TResult Function()? $default, {
+ TResult Function(String reason)? deprecated,
+ required TResult orElse(),
+ }) {
+ if ($default != null) {
+ return $default();
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map(
+ TResult Function(_EmptyModifier value) $default, {
+ required TResult Function(DeprecatedModifier value) deprecated,
+ }) {
+ return $default(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? mapOrNull(
+ TResult? Function(_EmptyModifier value)? $default, {
+ TResult? Function(DeprecatedModifier value)? deprecated,
+ }) {
+ return $default?.call(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap(
+ TResult Function(_EmptyModifier value)? $default, {
+ TResult Function(DeprecatedModifier value)? deprecated,
+ required TResult orElse(),
+ }) {
+ if ($default != null) {
+ return $default(this);
+ }
+ return orElse();
+ }
+
+ @override
+ Map toJson() {
+ return _$$EmptyModifierImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class _EmptyModifier implements EntryModifier {
+ const factory _EmptyModifier() = _$EmptyModifierImpl;
+
+ factory _EmptyModifier.fromJson(Map json) =
+ _$EmptyModifierImpl.fromJson;
+}
+
+/// @nodoc
+abstract class _$$DeprecatedModifierImplCopyWith<$Res> {
+ factory _$$DeprecatedModifierImplCopyWith(_$DeprecatedModifierImpl value,
+ $Res Function(_$DeprecatedModifierImpl) then) =
+ __$$DeprecatedModifierImplCopyWithImpl<$Res>;
+ @useResult
+ $Res call({String reason});
+}
+
+/// @nodoc
+class __$$DeprecatedModifierImplCopyWithImpl<$Res>
+ extends _$EntryModifierCopyWithImpl<$Res, _$DeprecatedModifierImpl>
+ implements _$$DeprecatedModifierImplCopyWith<$Res> {
+ __$$DeprecatedModifierImplCopyWithImpl(_$DeprecatedModifierImpl _value,
+ $Res Function(_$DeprecatedModifierImpl) _then)
+ : super(_value, _then);
+
+ /// Create a copy of EntryModifier
+ /// with the given fields replaced by the non-null parameter values.
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? reason = null,
+ }) {
+ return _then(_$DeprecatedModifierImpl(
+ reason: null == reason
+ ? _value.reason
+ : reason // ignore: cast_nullable_to_non_nullable
+ as String,
+ ));
+ }
+}
+
+/// @nodoc
+@JsonSerializable()
+class _$DeprecatedModifierImpl
+ with DiagnosticableTreeMixin
+ implements DeprecatedModifier {
+ const _$DeprecatedModifierImpl({this.reason = "", final String? $type})
+ : $type = $type ?? 'deprecated';
+
+ factory _$DeprecatedModifierImpl.fromJson(Map json) =>
+ _$$DeprecatedModifierImplFromJson(json);
+
+ @override
+ @JsonKey()
+ final String reason;
+
+ @JsonKey(name: 'kind')
+ final String $type;
+
+ @override
+ String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
+ return 'EntryModifier.deprecated(reason: $reason)';
+ }
+
+ @override
+ void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+ super.debugFillProperties(properties);
+ properties
+ ..add(DiagnosticsProperty('type', 'EntryModifier.deprecated'))
+ ..add(DiagnosticsProperty('reason', reason));
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$DeprecatedModifierImpl &&
+ (identical(other.reason, reason) || other.reason == reason));
+ }
+
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ @override
+ int get hashCode => Object.hash(runtimeType, reason);
+
+ /// Create a copy of EntryModifier
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$DeprecatedModifierImplCopyWith<_$DeprecatedModifierImpl> get copyWith =>
+ __$$DeprecatedModifierImplCopyWithImpl<_$DeprecatedModifierImpl>(
+ this, _$identity);
+
+ @override
+ @optionalTypeArgs
+ TResult when(
+ TResult Function() $default, {
+ required TResult Function(String reason) deprecated,
+ }) {
+ return deprecated(reason);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? whenOrNull(
+ TResult? Function()? $default, {
+ TResult? Function(String reason)? deprecated,
+ }) {
+ return deprecated?.call(reason);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen(
+ TResult Function()? $default, {
+ TResult Function(String reason)? deprecated,
+ required TResult orElse(),
+ }) {
+ if (deprecated != null) {
+ return deprecated(reason);
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map(
+ TResult Function(_EmptyModifier value) $default, {
+ required TResult Function(DeprecatedModifier value) deprecated,
+ }) {
+ return deprecated(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? mapOrNull(
+ TResult? Function(_EmptyModifier value)? $default, {
+ TResult? Function(DeprecatedModifier value)? deprecated,
+ }) {
+ return deprecated?.call(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap(
+ TResult Function(_EmptyModifier value)? $default, {
+ TResult Function(DeprecatedModifier value)? deprecated,
+ required TResult orElse(),
+ }) {
+ if (deprecated != null) {
+ return deprecated(this);
+ }
+ return orElse();
+ }
+
+ @override
+ Map toJson() {
+ return _$$DeprecatedModifierImplToJson(
+ this,
+ );
+ }
+}
+
+abstract class DeprecatedModifier implements EntryModifier {
+ const factory DeprecatedModifier({final String reason}) =
+ _$DeprecatedModifierImpl;
+
+ factory DeprecatedModifier.fromJson(Map json) =
+ _$DeprecatedModifierImpl.fromJson;
+
+ String get reason;
+
+ /// Create a copy of EntryModifier
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ _$$DeprecatedModifierImplCopyWith<_$DeprecatedModifierImpl> get copyWith =>
+ throw _privateConstructorUsedError;
+}
diff --git a/app/lib/models/entry_blueprint.g.dart b/app/lib/models/entry_blueprint.g.dart
index 88ee88ad42..d55405c523 100644
--- a/app/lib/models/entry_blueprint.g.dart
+++ b/app/lib/models/entry_blueprint.g.dart
@@ -14,13 +14,25 @@ _$EntryBlueprintImpl _$$EntryBlueprintImplFromJson(Map json) =>
extension: json['extension'] as String,
dataBlueprint: ObjectBlueprint.fromJson(
json['dataBlueprint'] as Map),
- tags:
- (json['tags'] as List?)?.map((e) => e as String).toList() ??
- const [],
color: json['color'] == null
? Colors.grey
: const ColorConverter().fromJson(json['color'] as String),
icon: json['icon'] as String? ?? TWIcons.help,
+ tags:
+ (json['tags'] as List?)?.map((e) => e as String).toList() ??
+ const [],
+ genericConstraints: (json['genericConstraints'] as List?)
+ ?.map((e) => DataBlueprint.fromJson(e as Map))
+ .toList() ??
+ null,
+ variableDataBlueprint: json['variableDataBlueprint'] == null
+ ? null
+ : DataBlueprint.fromJson(
+ json['variableDataBlueprint'] as Map),
+ modifiers: (json['modifiers'] as List?)
+ ?.map((e) => EntryModifier.fromJson(e as Map))
+ .toList() ??
+ const [],
);
Map _$$EntryBlueprintImplToJson(
@@ -30,10 +42,14 @@ Map _$$EntryBlueprintImplToJson(
'name': instance.name,
'description': instance.description,
'extension': instance.extension,
- 'dataBlueprint': instance.dataBlueprint,
- 'tags': instance.tags,
+ 'dataBlueprint': instance.dataBlueprint.toJson(),
'color': const ColorConverter().toJson(instance.color),
'icon': instance.icon,
+ 'tags': instance.tags,
+ 'genericConstraints':
+ instance.genericConstraints?.map((e) => e.toJson()).toList(),
+ 'variableDataBlueprint': instance.variableDataBlueprint?.toJson(),
+ 'modifiers': instance.modifiers.map((e) => e.toJson()).toList(),
};
_$DataBlueprintTypeImpl _$$DataBlueprintTypeImplFromJson(
@@ -51,7 +67,7 @@ Map _$$DataBlueprintTypeImplToJson(
_$DataBlueprintTypeImpl instance) =>
{
'default': instance.internalDefaultValue,
- 'modifiers': instance.modifiers,
+ 'modifiers': instance.modifiers.map((e) => e.toJson()).toList(),
'kind': instance.$type,
};
@@ -72,7 +88,7 @@ Map _$$PrimitiveBlueprintImplToJson(
{
'type': _$PrimitiveTypeEnumMap[instance.type]!,
'default': instance.internalDefaultValue,
- 'modifiers': instance.modifiers,
+ 'modifiers': instance.modifiers.map((e) => e.toJson()).toList(),
'kind': instance.$type,
};
@@ -99,7 +115,7 @@ Map _$$EnumBlueprintImplToJson(_$EnumBlueprintImpl instance) =>
{
'values': instance.values,
'default': instance.internalDefaultValue,
- 'modifiers': instance.modifiers,
+ 'modifiers': instance.modifiers.map((e) => e.toJson()).toList(),
'kind': instance.$type,
};
@@ -116,9 +132,9 @@ _$ListBlueprintImpl _$$ListBlueprintImplFromJson(Map json) =>
Map _$$ListBlueprintImplToJson(_$ListBlueprintImpl instance) =>
{
- 'type': instance.type,
+ 'type': instance.type.toJson(),
'default': instance.internalDefaultValue,
- 'modifiers': instance.modifiers,
+ 'modifiers': instance.modifiers.map((e) => e.toJson()).toList(),
'kind': instance.$type,
};
@@ -136,10 +152,10 @@ _$MapBlueprintImpl _$$MapBlueprintImplFromJson(Map json) =>
Map _$$MapBlueprintImplToJson(_$MapBlueprintImpl instance) =>
{
- 'key': instance.key,
- 'value': instance.value,
+ 'key': instance.key.toJson(),
+ 'value': instance.value.toJson(),
'default': instance.internalDefaultValue,
- 'modifiers': instance.modifiers,
+ 'modifiers': instance.modifiers.map((e) => e.toJson()).toList(),
'kind': instance.$type,
};
@@ -161,9 +177,9 @@ _$ObjectBlueprintImpl _$$ObjectBlueprintImplFromJson(
Map _$$ObjectBlueprintImplToJson(
_$ObjectBlueprintImpl instance) =>
{
- 'fields': instance.fields,
+ 'fields': instance.fields.map((k, e) => MapEntry(k, e.toJson())),
'default': instance.internalDefaultValue,
- 'modifiers': instance.modifiers,
+ 'modifiers': instance.modifiers.map((e) => e.toJson()).toList(),
'kind': instance.$type,
};
@@ -185,9 +201,9 @@ _$AlgebraicBlueprintImpl _$$AlgebraicBlueprintImplFromJson(
Map _$$AlgebraicBlueprintImplToJson(
_$AlgebraicBlueprintImpl instance) =>
{
- 'cases': instance.cases,
+ 'cases': instance.cases.map((k, e) => MapEntry(k, e.toJson())),
'default': instance.internalDefaultValue,
- 'modifiers': instance.modifiers,
+ 'modifiers': instance.modifiers.map((e) => e.toJson()).toList(),
'kind': instance.$type,
};
@@ -208,9 +224,9 @@ Map _$$CustomBlueprintImplToJson(
_$CustomBlueprintImpl instance) =>
{
'editor': instance.editor,
- 'shape': instance.shape,
+ 'shape': instance.shape.toJson(),
'default': instance.internalDefaultValue,
- 'modifiers': instance.modifiers,
+ 'modifiers': instance.modifiers.map((e) => e.toJson()).toList(),
'kind': instance.$type,
};
@@ -226,11 +242,35 @@ Map _$$ModifierImplToJson(_$ModifierImpl instance) =>
'data': instance.data,
};
+_$EmptyModifierImpl _$$EmptyModifierImplFromJson(Map json) =>
+ _$EmptyModifierImpl(
+ $type: json['kind'] as String?,
+ );
+
+Map _$$EmptyModifierImplToJson(_$EmptyModifierImpl instance) =>
+ {
+ 'kind': instance.$type,
+ };
+
+_$DeprecatedModifierImpl _$$DeprecatedModifierImplFromJson(
+ Map json) =>
+ _$DeprecatedModifierImpl(
+ reason: json['reason'] as String? ?? "",
+ $type: json['kind'] as String?,
+ );
+
+Map _$$DeprecatedModifierImplToJson(
+ _$DeprecatedModifierImpl instance) =>
+ {
+ 'reason': instance.reason,
+ 'kind': instance.$type,
+ };
+
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
-String _$entryBlueprintsHash() => r'f0fa147f0decf8c831c0f3aa4d33530002a2b51b';
+String _$entryBlueprintsHash() => r'7c332657f0558d980c13827627ce297ca4263865';
/// A generated provider to fetch and cache a list of all the [EntryBlueprint]s.
///
@@ -247,8 +287,10 @@ final entryBlueprintsProvider =
allTransitiveDependencies: null,
);
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
typedef EntryBlueprintsRef = AutoDisposeProviderRef>;
-String _$entryBlueprintHash() => r'6823811ab4f61b543b7b06c4069f224179cec055';
+String _$entryBlueprintHash() => r'7db7dd388f5998fccd421ff822e75b951c8047b0';
/// Copied from Dart SDK
class _SystemHash {
@@ -396,6 +438,8 @@ class EntryBlueprintProvider extends AutoDisposeProvider {
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin EntryBlueprintRef on AutoDisposeProviderRef {
/// The parameter `blueprintId` of this provider.
String get blueprintId;
@@ -410,7 +454,7 @@ class _EntryBlueprintProviderElement
}
String _$entryBlueprintTagsHash() =>
- r'dc8074c390aabc3d6ff2b7778ee679d343c8ddac';
+ r'd4fb86b5fc8d9a206c4140b770b50d799923565c';
/// See also [entryBlueprintTags].
@ProviderFor(entryBlueprintTags)
@@ -526,6 +570,8 @@ class EntryBlueprintTagsProvider extends AutoDisposeProvider> {
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin EntryBlueprintTagsRef on AutoDisposeProviderRef> {
/// The parameter `blueprintId` of this provider.
String get blueprintId;
@@ -540,7 +586,7 @@ class _EntryBlueprintTagsProviderElement
String get blueprintId => (origin as EntryBlueprintTagsProvider).blueprintId;
}
-String _$entryTagsHash() => r'26e764a45dae73ed8e21ac9affbe0c3c524e59ef';
+String _$entryTagsHash() => r'8e3671fafea112b0c5718862f6cac60872444179';
/// See also [entryTags].
@ProviderFor(entryTags)
@@ -654,6 +700,8 @@ class EntryTagsProvider extends AutoDisposeProvider> {
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin EntryTagsRef on AutoDisposeProviderRef> {
/// The parameter `entryId` of this provider.
String get entryId;
@@ -668,7 +716,7 @@ class _EntryTagsProviderElement extends AutoDisposeProviderElement>
}
String _$entryBlueprintPageTypeHash() =>
- r'7ea4a3693045d74a338e7a2fe7de83c915b23137';
+ r'de37953ce77af7052651105704e4f829f4753e71';
/// See also [entryBlueprintPageType].
@ProviderFor(entryBlueprintPageType)
@@ -784,6 +832,8 @@ class EntryBlueprintPageTypeProvider extends AutoDisposeProvider {
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin EntryBlueprintPageTypeRef on AutoDisposeProviderRef {
/// The parameter `blueprintId` of this provider.
String get blueprintId;
@@ -799,7 +849,7 @@ class _EntryBlueprintPageTypeProviderElement
(origin as EntryBlueprintPageTypeProvider).blueprintId;
}
-String _$fieldModifiersHash() => r'356ae9f89ffe0ab87b1d27055284326ee202e770';
+String _$fieldModifiersHash() => r'3568ba69f15d904253ba445e8f5b7740823d8246';
/// Gets all the modifiers with a given name.
///
@@ -939,6 +989,8 @@ class FieldModifiersProvider
}
}
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
mixin FieldModifiersRef on AutoDisposeProviderRef