From 1a5c1b20e545935c9412e40b2bd53e7b9a1abb4c Mon Sep 17 00:00:00 2001 From: kushalm Date: Sat, 16 Sep 2023 20:17:16 +0400 Subject: [PATCH] feat: Add Mirai Switch --- .../assets/json/home_screen.json | 31 +++ .../assets/json/switch_example.json | 49 +++++ packages/mirai/lib/src/framework/mirai.dart | 2 + .../cubit/mirai_switch_cubit.dart | 13 ++ .../cubit/mirai_switch_state.dart | 18 ++ .../parsers/mirai_switch/mirai_switch.dart | 15 ++ .../mirai_switch/mirai_switch.freezed.dart | 182 ++++++++++++++++++ .../parsers/mirai_switch/mirai_switch.g.dart | 19 ++ .../mirai_switch/mirai_switch_parser.dart | 37 ++++ packages/mirai/lib/src/utils/widget_type.dart | 3 + 10 files changed, 369 insertions(+) create mode 100644 examples/mirai_gallery/assets/json/switch_example.json create mode 100644 packages/mirai/lib/src/parsers/mirai_switch/cubit/mirai_switch_cubit.dart create mode 100644 packages/mirai/lib/src/parsers/mirai_switch/cubit/mirai_switch_state.dart create mode 100644 packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.dart create mode 100644 packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.freezed.dart create mode 100644 packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.g.dart create mode 100644 packages/mirai/lib/src/parsers/mirai_switch/mirai_switch_parser.dart diff --git a/examples/mirai_gallery/assets/json/home_screen.json b/examples/mirai_gallery/assets/json/home_screen.json index 1eb21465..87d9b74c 100644 --- a/examples/mirai_gallery/assets/json/home_screen.json +++ b/examples/mirai_gallery/assets/json/home_screen.json @@ -956,6 +956,37 @@ "assetPath": "assets/json/web_view_example.json" } } + }, + { + "type": "listTile", + "leading": { + "type": "icon", + "iconType": "cupertino", + "icon": "textbox" + }, + "title": { + "type": "text", + "data": "Mirai Switch", + "style": { + "fontSize": 21 + } + }, + "subtitle": { + "type": "text", + "data": "Text button displays an ink splash on press but does not lift", + "style": { + "fontSize": 12 + } + }, + "isThreeLine": true, + "onTap": { + "actionType": "navigate", + "navigationStyle": "push", + "widgetJson": { + "type": "exampleScreen", + "assetPath": "assets/json/switch_example.json" + } + } } ] } diff --git a/examples/mirai_gallery/assets/json/switch_example.json b/examples/mirai_gallery/assets/json/switch_example.json new file mode 100644 index 00000000..b4fbe561 --- /dev/null +++ b/examples/mirai_gallery/assets/json/switch_example.json @@ -0,0 +1,49 @@ +{ + "type": "scaffold", + "appBar": { + "type": "appBar", + "title": { + "type": "text", + "data": "Mirai Switch" + } + }, + "body": { + "type": "row", + "mainAxisAlignment": "center", + "crossAxisAlignment": "center", + "children": [ + { + "type": "column", + "mainAxisAlignment": "center", + "crossAxisAlignment": "center", + "children": [ + { + "type": "row", + "mainAxisAlignment": "center", + "crossAxisAlignment": "center", + "children": [ + { + "type": "switchButton", + "initialValue": true, + "onChanged": {} + }, + { + "type": "sizedBox", + "width": 20 + }, + { + "type": "switchButton", + "initialValue": false, + "onChanged": {} + } + ] + }, + { + "type": "sizedBox", + "height": 12 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/mirai/lib/src/framework/mirai.dart b/packages/mirai/lib/src/framework/mirai.dart index 58d02b37..ad5fb5d9 100644 --- a/packages/mirai/lib/src/framework/mirai.dart +++ b/packages/mirai/lib/src/framework/mirai.dart @@ -15,6 +15,7 @@ import 'package:mirai/src/parsers/mirai_check_box_widget/mirai_check_box_widget_ import 'package:mirai/src/parsers/mirai_form/mirai_form_parser.dart'; import 'package:mirai/src/parsers/mirai_form_field/mirai_form_field_parser.dart'; import 'package:mirai/src/parsers/mirai_fractionally_sized_box/mirai_fractionally_sized_box_parser.dart'; +import 'package:mirai/src/parsers/mirai_switch/mirai_switch_parser.dart'; import 'package:mirai/src/parsers/mirai_tab/mirai_tab_parser.dart'; import 'package:mirai/src/parsers/parsers.dart'; import 'package:mirai/src/utils/log.dart'; @@ -65,6 +66,7 @@ class Mirai { const MiraiExpandedParser(), const MiraiFlexibleParser(), const MiraiSafeAreaParser(), + const MiraiSwitchParser(), ]; static final _actionParsers = [ diff --git a/packages/mirai/lib/src/parsers/mirai_switch/cubit/mirai_switch_cubit.dart b/packages/mirai/lib/src/parsers/mirai_switch/cubit/mirai_switch_cubit.dart new file mode 100644 index 00000000..fc25063a --- /dev/null +++ b/packages/mirai/lib/src/parsers/mirai_switch/cubit/mirai_switch_cubit.dart @@ -0,0 +1,13 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +part 'mirai_switch_state.dart'; + +class MiraiSwitchCubit extends Cubit { + MiraiSwitchCubit({required bool value}) + : super(MiraiSwitchState(isSelected: value)); + + void changeValue(bool value) { + emit(state.copyWith(isSelected: value)); + } +} diff --git a/packages/mirai/lib/src/parsers/mirai_switch/cubit/mirai_switch_state.dart b/packages/mirai/lib/src/parsers/mirai_switch/cubit/mirai_switch_state.dart new file mode 100644 index 00000000..e44bfd39 --- /dev/null +++ b/packages/mirai/lib/src/parsers/mirai_switch/cubit/mirai_switch_state.dart @@ -0,0 +1,18 @@ +part of 'mirai_switch_cubit.dart'; + +@immutable +final class MiraiSwitchState { + const MiraiSwitchState({ + this.isSelected = false, + }); + + final bool isSelected; + + MiraiSwitchState copyWith({ + bool? isSelected, + }) { + return MiraiSwitchState( + isSelected: isSelected ?? this.isSelected, + ); + } +} diff --git a/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.dart b/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.dart new file mode 100644 index 00000000..09b4cc62 --- /dev/null +++ b/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.dart @@ -0,0 +1,15 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'mirai_switch.freezed.dart'; +part 'mirai_switch.g.dart'; + +@freezed +class MiraiSwitch with _$MiraiSwitch { + const factory MiraiSwitch({ + @Default(false) initialValue, + Map? onChanged, + }) = _MiraiSwitch; + + factory MiraiSwitch.fromJson(Map json) => + _$MiraiSwitchFromJson(json); +} diff --git a/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.freezed.dart b/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.freezed.dart new file mode 100644 index 00000000..2c6e2933 --- /dev/null +++ b/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.freezed.dart @@ -0,0 +1,182 @@ +// 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 'mirai_switch.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +MiraiSwitch _$MiraiSwitchFromJson(Map json) { + return _MiraiSwitch.fromJson(json); +} + +/// @nodoc +mixin _$MiraiSwitch { + dynamic get initialValue => throw _privateConstructorUsedError; + Map? get onChanged => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $MiraiSwitchCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $MiraiSwitchCopyWith<$Res> { + factory $MiraiSwitchCopyWith( + MiraiSwitch value, $Res Function(MiraiSwitch) then) = + _$MiraiSwitchCopyWithImpl<$Res, MiraiSwitch>; + @useResult + $Res call({dynamic initialValue, Map? onChanged}); +} + +/// @nodoc +class _$MiraiSwitchCopyWithImpl<$Res, $Val extends MiraiSwitch> + implements $MiraiSwitchCopyWith<$Res> { + _$MiraiSwitchCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? initialValue = freezed, + Object? onChanged = freezed, + }) { + return _then(_value.copyWith( + initialValue: freezed == initialValue + ? _value.initialValue + : initialValue // ignore: cast_nullable_to_non_nullable + as dynamic, + onChanged: freezed == onChanged + ? _value.onChanged + : onChanged // ignore: cast_nullable_to_non_nullable + as Map?, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_MiraiSwitchCopyWith<$Res> + implements $MiraiSwitchCopyWith<$Res> { + factory _$$_MiraiSwitchCopyWith( + _$_MiraiSwitch value, $Res Function(_$_MiraiSwitch) then) = + __$$_MiraiSwitchCopyWithImpl<$Res>; + @override + @useResult + $Res call({dynamic initialValue, Map? onChanged}); +} + +/// @nodoc +class __$$_MiraiSwitchCopyWithImpl<$Res> + extends _$MiraiSwitchCopyWithImpl<$Res, _$_MiraiSwitch> + implements _$$_MiraiSwitchCopyWith<$Res> { + __$$_MiraiSwitchCopyWithImpl( + _$_MiraiSwitch _value, $Res Function(_$_MiraiSwitch) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? initialValue = freezed, + Object? onChanged = freezed, + }) { + return _then(_$_MiraiSwitch( + initialValue: + freezed == initialValue ? _value.initialValue! : initialValue, + onChanged: freezed == onChanged + ? _value._onChanged + : onChanged // ignore: cast_nullable_to_non_nullable + as Map?, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$_MiraiSwitch implements _MiraiSwitch { + const _$_MiraiSwitch( + {this.initialValue = false, final Map? onChanged}) + : _onChanged = onChanged; + + factory _$_MiraiSwitch.fromJson(Map json) => + _$$_MiraiSwitchFromJson(json); + + @override + @JsonKey() + final dynamic initialValue; + final Map? _onChanged; + @override + Map? get onChanged { + final value = _onChanged; + if (value == null) return null; + if (_onChanged is EqualUnmodifiableMapView) return _onChanged; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + @override + String toString() { + return 'MiraiSwitch(initialValue: $initialValue, onChanged: $onChanged)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_MiraiSwitch && + const DeepCollectionEquality() + .equals(other.initialValue, initialValue) && + const DeepCollectionEquality() + .equals(other._onChanged, _onChanged)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(initialValue), + const DeepCollectionEquality().hash(_onChanged)); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_MiraiSwitchCopyWith<_$_MiraiSwitch> get copyWith => + __$$_MiraiSwitchCopyWithImpl<_$_MiraiSwitch>(this, _$identity); + + @override + Map toJson() { + return _$$_MiraiSwitchToJson( + this, + ); + } +} + +abstract class _MiraiSwitch implements MiraiSwitch { + const factory _MiraiSwitch( + {final dynamic initialValue, + final Map? onChanged}) = _$_MiraiSwitch; + + factory _MiraiSwitch.fromJson(Map json) = + _$_MiraiSwitch.fromJson; + + @override + dynamic get initialValue; + @override + Map? get onChanged; + @override + @JsonKey(ignore: true) + _$$_MiraiSwitchCopyWith<_$_MiraiSwitch> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.g.dart b/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.g.dart new file mode 100644 index 00000000..14f56977 --- /dev/null +++ b/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'mirai_switch.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_MiraiSwitch _$$_MiraiSwitchFromJson(Map json) => + _$_MiraiSwitch( + initialValue: json['initialValue'] ?? false, + onChanged: json['onChanged'] as Map?, + ); + +Map _$$_MiraiSwitchToJson(_$_MiraiSwitch instance) => + { + 'initialValue': instance.initialValue, + 'onChanged': instance.onChanged, + }; diff --git a/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch_parser.dart b/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch_parser.dart new file mode 100644 index 00000000..ee0f4351 --- /dev/null +++ b/packages/mirai/lib/src/parsers/mirai_switch/mirai_switch_parser.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:mirai/src/framework/framework.dart'; +import 'package:mirai/src/parsers/mirai_switch/cubit/mirai_switch_cubit.dart'; +import 'package:mirai/src/parsers/mirai_switch/mirai_switch.dart'; +import 'package:mirai/src/utils/widget_type.dart'; + +class MiraiSwitchParser extends MiraiParser { + const MiraiSwitchParser(); + + @override + MiraiSwitch getModel(Map json) => MiraiSwitch.fromJson(json); + + @override + String get type => WidgetType.switchButton.name; + + @override + Widget parse(BuildContext context, MiraiSwitch model) { + return BlocProvider( + create: (context) => MiraiSwitchCubit(value: model.initialValue ?? false), + child: BlocSelector( + selector: (state) => state.isSelected, + builder: (context, isSelected) { + return Switch( + value: isSelected, + onChanged: (bool value) { + context.read().changeValue(value); + if (model.onChanged != null) { + Mirai.onCallFromJson(model.onChanged, context); + } + }, + ); + }, + ), + ); + } +} diff --git a/packages/mirai/lib/src/utils/widget_type.dart b/packages/mirai/lib/src/utils/widget_type.dart index ec5e7f72..33ddbf91 100644 --- a/packages/mirai/lib/src/utils/widget_type.dart +++ b/packages/mirai/lib/src/utils/widget_type.dart @@ -36,4 +36,7 @@ enum WidgetType { expanded, flexible, safeArea, + + /// cant use switch here because it is a keyword + switchButton, }