diff --git a/packages/stac/lib/src/framework/stac.dart b/packages/stac/lib/src/framework/stac.dart index 6bd5cbf7..26ef7d2a 100644 --- a/packages/stac/lib/src/framework/stac.dart +++ b/packages/stac/lib/src/framework/stac.dart @@ -121,6 +121,8 @@ class Stac { const StacFormValidateParser(), const StacSnackBarParser(), const StacSetValueActionParser(), + const StacMultiActionParser(), + const StacDelayActionParser(), ]; static Future initialize({ diff --git a/packages/stac/lib/src/parsers/actions/actions.dart b/packages/stac/lib/src/parsers/actions/actions.dart index 288fc73e..654f714d 100644 --- a/packages/stac/lib/src/parsers/actions/actions.dart +++ b/packages/stac/lib/src/parsers/actions/actions.dart @@ -7,3 +7,5 @@ export 'package:stac/src/parsers/actions/stac_network_request/stac_network_reque export 'package:stac/src/parsers/actions/stac_none_action/stac_none_action_parser.dart'; export 'package:stac/src/parsers/actions/stac_set_value/stac_set_value_action_parser.dart'; export 'package:stac/src/parsers/actions/stac_snack_bar/stac_snack_bar.dart'; +export 'package:stac/src/parsers/actions/stac_multi_action/stac_multi_action.dart'; +export 'package:stac/src/parsers/actions/stac_delay_action/stac_delay_action.dart'; diff --git a/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action.dart b/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action.dart new file mode 100644 index 00000000..cc4294ac --- /dev/null +++ b/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action.dart @@ -0,0 +1,16 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +export 'stac_delay_action_parser.dart'; + +part 'stac_delay_action.freezed.dart'; +part 'stac_delay_action.g.dart'; + +@freezed +abstract class StacDelayAction with _$StacDelayAction { + const factory StacDelayAction({ + @Default(1000) int milliseconds, + }) = _StacDelayAction; + + factory StacDelayAction.fromJson(Map json) => + _$StacDelayActionFromJson(json); +} diff --git a/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action.freezed.dart b/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action.freezed.dart new file mode 100644 index 00000000..295f691b --- /dev/null +++ b/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action.freezed.dart @@ -0,0 +1,163 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'stac_delay_action.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$StacDelayAction { + int get milliseconds; + + /// Create a copy of StacDelayAction + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $StacDelayActionCopyWith get copyWith => + _$StacDelayActionCopyWithImpl( + this as StacDelayAction, _$identity); + + /// Serializes this StacDelayAction to a JSON map. + Map toJson(); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is StacDelayAction && + (identical(other.milliseconds, milliseconds) || + other.milliseconds == milliseconds)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, milliseconds); + + @override + String toString() { + return 'StacDelayAction(milliseconds: $milliseconds)'; + } +} + +/// @nodoc +abstract mixin class $StacDelayActionCopyWith<$Res> { + factory $StacDelayActionCopyWith( + StacDelayAction value, $Res Function(StacDelayAction) _then) = + _$StacDelayActionCopyWithImpl; + @useResult + $Res call({int milliseconds}); +} + +/// @nodoc +class _$StacDelayActionCopyWithImpl<$Res> + implements $StacDelayActionCopyWith<$Res> { + _$StacDelayActionCopyWithImpl(this._self, this._then); + + final StacDelayAction _self; + final $Res Function(StacDelayAction) _then; + + /// Create a copy of StacDelayAction + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? milliseconds = null, + }) { + return _then(_self.copyWith( + milliseconds: null == milliseconds + ? _self.milliseconds + : milliseconds // ignore: cast_nullable_to_non_nullable + as int, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _StacDelayAction implements StacDelayAction { + const _StacDelayAction({this.milliseconds = 1000}); + factory _StacDelayAction.fromJson(Map json) => + _$StacDelayActionFromJson(json); + + @override + @JsonKey() + final int milliseconds; + + /// Create a copy of StacDelayAction + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$StacDelayActionCopyWith<_StacDelayAction> get copyWith => + __$StacDelayActionCopyWithImpl<_StacDelayAction>(this, _$identity); + + @override + Map toJson() { + return _$StacDelayActionToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _StacDelayAction && + (identical(other.milliseconds, milliseconds) || + other.milliseconds == milliseconds)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, milliseconds); + + @override + String toString() { + return 'StacDelayAction(milliseconds: $milliseconds)'; + } +} + +/// @nodoc +abstract mixin class _$StacDelayActionCopyWith<$Res> + implements $StacDelayActionCopyWith<$Res> { + factory _$StacDelayActionCopyWith( + _StacDelayAction value, $Res Function(_StacDelayAction) _then) = + __$StacDelayActionCopyWithImpl; + @override + @useResult + $Res call({int milliseconds}); +} + +/// @nodoc +class __$StacDelayActionCopyWithImpl<$Res> + implements _$StacDelayActionCopyWith<$Res> { + __$StacDelayActionCopyWithImpl(this._self, this._then); + + final _StacDelayAction _self; + final $Res Function(_StacDelayAction) _then; + + /// Create a copy of StacDelayAction + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? milliseconds = null, + }) { + return _then(_StacDelayAction( + milliseconds: null == milliseconds + ? _self.milliseconds + : milliseconds // ignore: cast_nullable_to_non_nullable + as int, + )); + } +} + +// dart format on diff --git a/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action.g.dart b/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action.g.dart new file mode 100644 index 00000000..42556656 --- /dev/null +++ b/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'stac_delay_action.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_StacDelayAction _$StacDelayActionFromJson(Map json) => + _StacDelayAction( + milliseconds: (json['milliseconds'] as num?)?.toInt() ?? 1000, + ); + +Map _$StacDelayActionToJson(_StacDelayAction instance) => + { + 'milliseconds': instance.milliseconds, + }; diff --git a/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action_parser.dart b/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action_parser.dart new file mode 100644 index 00000000..88f611ca --- /dev/null +++ b/packages/stac/lib/src/parsers/actions/stac_delay_action/stac_delay_action_parser.dart @@ -0,0 +1,22 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:stac/src/parsers/actions/stac_delay_action/stac_delay_action.dart'; +import 'package:stac/src/utils/action_type.dart'; +import 'package:stac_framework/stac_framework.dart'; + +class StacDelayActionParser extends StacActionParser { + const StacDelayActionParser(); + + @override + String get actionType => ActionType.delay.name; + + @override + StacDelayAction getModel(Map json) => + StacDelayAction.fromJson(json); + + @override + FutureOr onCall(BuildContext context, StacDelayAction model) { + return Future.delayed(Duration(milliseconds: model.milliseconds)); + } +} diff --git a/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action.dart b/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action.dart new file mode 100644 index 00000000..024743d4 --- /dev/null +++ b/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action.dart @@ -0,0 +1,17 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +export 'stac_multi_action_parser.dart'; + +part 'stac_multi_action.freezed.dart'; +part 'stac_multi_action.g.dart'; + +@freezed +abstract class StacMultiAction with _$StacMultiAction { + const factory StacMultiAction({ + required List?>? actions, + @Default(false) bool sync, + }) = _StacMultiAction; + + factory StacMultiAction.fromJson(Map json) => + _$StacMultiActionFromJson(json); +} diff --git a/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action.freezed.dart b/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action.freezed.dart new file mode 100644 index 00000000..c3536752 --- /dev/null +++ b/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action.freezed.dart @@ -0,0 +1,188 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'stac_multi_action.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$StacMultiAction { + List?>? get actions; + bool get sync; + + /// Create a copy of StacMultiAction + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $StacMultiActionCopyWith get copyWith => + _$StacMultiActionCopyWithImpl( + this as StacMultiAction, _$identity); + + /// Serializes this StacMultiAction to a JSON map. + Map toJson(); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is StacMultiAction && + const DeepCollectionEquality().equals(other.actions, actions) && + (identical(other.sync, sync) || other.sync == sync)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, const DeepCollectionEquality().hash(actions), sync); + + @override + String toString() { + return 'StacMultiAction(actions: $actions, sync: $sync)'; + } +} + +/// @nodoc +abstract mixin class $StacMultiActionCopyWith<$Res> { + factory $StacMultiActionCopyWith( + StacMultiAction value, $Res Function(StacMultiAction) _then) = + _$StacMultiActionCopyWithImpl; + @useResult + $Res call({List?>? actions, bool sync}); +} + +/// @nodoc +class _$StacMultiActionCopyWithImpl<$Res> + implements $StacMultiActionCopyWith<$Res> { + _$StacMultiActionCopyWithImpl(this._self, this._then); + + final StacMultiAction _self; + final $Res Function(StacMultiAction) _then; + + /// Create a copy of StacMultiAction + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? actions = freezed, + Object? sync = null, + }) { + return _then(_self.copyWith( + actions: freezed == actions + ? _self.actions + : actions // ignore: cast_nullable_to_non_nullable + as List?>?, + sync: null == sync + ? _self.sync + : sync // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _StacMultiAction implements StacMultiAction { + const _StacMultiAction( + {required final List?>? actions, this.sync = false}) + : _actions = actions; + factory _StacMultiAction.fromJson(Map json) => + _$StacMultiActionFromJson(json); + + final List?>? _actions; + @override + List?>? get actions { + final value = _actions; + if (value == null) return null; + if (_actions is EqualUnmodifiableListView) return _actions; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); + } + + @override + @JsonKey() + final bool sync; + + /// Create a copy of StacMultiAction + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$StacMultiActionCopyWith<_StacMultiAction> get copyWith => + __$StacMultiActionCopyWithImpl<_StacMultiAction>(this, _$identity); + + @override + Map toJson() { + return _$StacMultiActionToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _StacMultiAction && + const DeepCollectionEquality().equals(other._actions, _actions) && + (identical(other.sync, sync) || other.sync == sync)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, const DeepCollectionEquality().hash(_actions), sync); + + @override + String toString() { + return 'StacMultiAction(actions: $actions, sync: $sync)'; + } +} + +/// @nodoc +abstract mixin class _$StacMultiActionCopyWith<$Res> + implements $StacMultiActionCopyWith<$Res> { + factory _$StacMultiActionCopyWith( + _StacMultiAction value, $Res Function(_StacMultiAction) _then) = + __$StacMultiActionCopyWithImpl; + @override + @useResult + $Res call({List?>? actions, bool sync}); +} + +/// @nodoc +class __$StacMultiActionCopyWithImpl<$Res> + implements _$StacMultiActionCopyWith<$Res> { + __$StacMultiActionCopyWithImpl(this._self, this._then); + + final _StacMultiAction _self; + final $Res Function(_StacMultiAction) _then; + + /// Create a copy of StacMultiAction + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? actions = freezed, + Object? sync = null, + }) { + return _then(_StacMultiAction( + actions: freezed == actions + ? _self._actions + : actions // ignore: cast_nullable_to_non_nullable + as List?>?, + sync: null == sync + ? _self.sync + : sync // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +// dart format on diff --git a/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action.g.dart b/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action.g.dart new file mode 100644 index 00000000..d6d7c97f --- /dev/null +++ b/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'stac_multi_action.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_StacMultiAction _$StacMultiActionFromJson(Map json) => + _StacMultiAction( + actions: (json['actions'] as List?) + ?.map((e) => e as Map?) + .toList(), + sync: json['sync'] as bool? ?? false, + ); + +Map _$StacMultiActionToJson(_StacMultiAction instance) => + { + 'actions': instance.actions, + 'sync': instance.sync, + }; diff --git a/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action_parser.dart b/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action_parser.dart new file mode 100644 index 00000000..7070cc6b --- /dev/null +++ b/packages/stac/lib/src/parsers/actions/stac_multi_action/stac_multi_action_parser.dart @@ -0,0 +1,28 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:stac/src/parsers/actions/stac_multi_action/stac_multi_action.dart'; +import 'package:stac/src/utils/action_type.dart'; +import 'package:stac/src/framework/framework.dart'; +import 'package:stac_framework/stac_framework.dart'; + +class StacMultiActionParser extends StacActionParser { + const StacMultiActionParser(); + + @override + String get actionType => ActionType.multiAction.name; + + @override + StacMultiAction getModel(Map json) => + StacMultiAction.fromJson(json); + + @override + FutureOr onCall(BuildContext context, StacMultiAction model) async { + final actions = model.actions ?? []; + for (var json in actions) { + model.sync + ? await Stac.onCallFromJson(json, context) + : Stac.onCallFromJson(json, context); + } + } +} diff --git a/packages/stac/lib/src/utils/action_type.dart b/packages/stac/lib/src/utils/action_type.dart index 9d66cd03..bca0211f 100644 --- a/packages/stac/lib/src/utils/action_type.dart +++ b/packages/stac/lib/src/utils/action_type.dart @@ -8,4 +8,6 @@ enum ActionType { validateForm, showSnackBar, setValue, + multiAction, + delay, } diff --git a/website/docs/actions/delay_action.md b/website/docs/actions/delay_action.md new file mode 100644 index 00000000..d8601576 --- /dev/null +++ b/website/docs/actions/delay_action.md @@ -0,0 +1,19 @@ +# Delay Action + +The `StacDelayAction` allows you to do nothing for a specified duration. + +## Delay Action Properties + +| Property | Type | Description | +| --- |-------------------|---------------------------------------------------| +| milliseconds | `int` | The amount of time (in milliseconds) we want to wait for | + +## Delay Action JSON + +```json +{ + "actionType": "delay", + "milliseconds": 1000 +}, + +``` \ No newline at end of file diff --git a/website/docs/actions/multi_action.md b/website/docs/actions/multi_action.md new file mode 100644 index 00000000..d34340bb --- /dev/null +++ b/website/docs/actions/multi_action.md @@ -0,0 +1,78 @@ +# Multi Action + +The `StacMultiAction` allows you to execute multiple actions with ease. + +## Multi Action Properties + +| Property | Type | Description | +| --- |-------------------|---------------------------------------------------| +| actions | `List?>?` | The list of actions to be performed | +| sync | `bool` | Whether to execute the actions in syncronous or parallel. Defaults to `false`. | + +## Multi Action JSON + +This example will allow you to show a snackbar through `StacShowSnackBarAction`, execute a network request through `StacNetworkRequest` and show another snackbar right after. + +```json +{ + "actionType": "multiAction", + "sync": true, + "actions": [ + { + "actionType": "showSnackBar", + "content": { + "type": "text", + "data": "Executing request..." + }, + "action": { + "label": "Done", + "textColor": "#73C2FB", + "onPressed": {} + }, + "behavior": "floating" + }, + { + "actionType": "networkRequest", + "url": "https://example.com/api", + "method": "get", + "queryParameters": { + "page": 1 + }, + "headers": { + "Authorization": "Bearer token" + }, + "contentType": "application/json", + "body": { + "data": "example" + }, + "results": [ + { + "statusCode": 200, + "action": { + "actionType": "none" + } + }, + { + "statusCode": 404, + "action": { + "actionType": "none" + } + } + ] + }, + { + "actionType": "showSnackBar", + "content": { + "type": "text", + "data": "Request executed" + }, + "action": { + "label": "Done", + "textColor": "#73C2FB", + "onPressed": {} + }, + "behavior": "floating" + } + ] +} +``` \ No newline at end of file