♻️ Refactor snackbar
This commit is contained in:
@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/file.dart';
|
||||
@ -22,6 +23,23 @@ import 'package:island/widgets/post/draft_manager.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
part 'compose.freezed.dart';
|
||||
part 'compose.g.dart';
|
||||
|
||||
@freezed
|
||||
sealed class PostComposeInitialState with _$PostComposeInitialState {
|
||||
const factory PostComposeInitialState({
|
||||
String? title,
|
||||
String? description,
|
||||
String? content,
|
||||
@Default([]) List<UniversalFile> attachments,
|
||||
int? visibility,
|
||||
}) = _PostComposeInitialState;
|
||||
|
||||
factory PostComposeInitialState.fromJson(Map<String, dynamic> json) =>
|
||||
_$PostComposeInitialStateFromJson(json);
|
||||
}
|
||||
|
||||
@RoutePage()
|
||||
class PostEditScreen extends HookConsumerWidget {
|
||||
final String id;
|
||||
@ -54,12 +72,14 @@ class PostComposeScreen extends HookConsumerWidget {
|
||||
final SnPost? repliedPost;
|
||||
final SnPost? forwardedPost;
|
||||
final int? type;
|
||||
final PostComposeInitialState? initialState;
|
||||
const PostComposeScreen({
|
||||
super.key,
|
||||
this.originalPost,
|
||||
this.repliedPost,
|
||||
this.forwardedPost,
|
||||
@QueryParam('type') this.type,
|
||||
this.initialState,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -107,11 +127,28 @@ class PostComposeScreen extends HookConsumerWidget {
|
||||
return null;
|
||||
}, [publishers]);
|
||||
|
||||
// Load draft if available (only for new posts)
|
||||
// Load initial state if provided (for sharing functionality)
|
||||
useEffect(() {
|
||||
if (initialState != null) {
|
||||
state.titleController.text = initialState!.title ?? '';
|
||||
state.descriptionController.text = initialState!.description ?? '';
|
||||
state.contentController.text = initialState!.content ?? '';
|
||||
if (initialState!.visibility != null) {
|
||||
state.visibility.value = initialState!.visibility!;
|
||||
}
|
||||
if (initialState!.attachments.isNotEmpty) {
|
||||
state.attachments.value = List.from(initialState!.attachments);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}, [initialState]);
|
||||
|
||||
// Load draft if available (only for new posts without initial state)
|
||||
useEffect(() {
|
||||
if (originalPost == null &&
|
||||
effectiveForwardedPost == null &&
|
||||
effectiveRepliedPost == null) {
|
||||
effectiveRepliedPost == null &&
|
||||
initialState == null) {
|
||||
// Try to load the most recent draft
|
||||
final drafts = ref.read(composeStorageNotifierProvider);
|
||||
if (drafts.isNotEmpty) {
|
||||
|
166
lib/screens/posts/compose.freezed.dart
Normal file
166
lib/screens/posts/compose.freezed.dart
Normal file
@ -0,0 +1,166 @@
|
||||
// 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 'compose.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$PostComposeInitialState {
|
||||
|
||||
String? get title; String? get description; String? get content; List<UniversalFile> get attachments; int? get visibility;
|
||||
/// Create a copy of PostComposeInitialState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$PostComposeInitialStateCopyWith<PostComposeInitialState> get copyWith => _$PostComposeInitialStateCopyWithImpl<PostComposeInitialState>(this as PostComposeInitialState, _$identity);
|
||||
|
||||
/// Serializes this PostComposeInitialState to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is PostComposeInitialState&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.content, content) || other.content == content)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.visibility, visibility) || other.visibility == visibility));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,description,content,const DeepCollectionEquality().hash(attachments),visibility);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PostComposeInitialState(title: $title, description: $description, content: $content, attachments: $attachments, visibility: $visibility)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $PostComposeInitialStateCopyWith<$Res> {
|
||||
factory $PostComposeInitialStateCopyWith(PostComposeInitialState value, $Res Function(PostComposeInitialState) _then) = _$PostComposeInitialStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String? title, String? description, String? content, List<UniversalFile> attachments, int? visibility
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$PostComposeInitialStateCopyWithImpl<$Res>
|
||||
implements $PostComposeInitialStateCopyWith<$Res> {
|
||||
_$PostComposeInitialStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final PostComposeInitialState _self;
|
||||
final $Res Function(PostComposeInitialState) _then;
|
||||
|
||||
/// Create a copy of PostComposeInitialState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? title = freezed,Object? description = freezed,Object? content = freezed,Object? attachments = null,Object? visibility = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String?,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
||||
as String?,attachments: null == attachments ? _self.attachments : attachments // ignore: cast_nullable_to_non_nullable
|
||||
as List<UniversalFile>,visibility: freezed == visibility ? _self.visibility : visibility // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _PostComposeInitialState implements PostComposeInitialState {
|
||||
const _PostComposeInitialState({this.title, this.description, this.content, final List<UniversalFile> attachments = const [], this.visibility}): _attachments = attachments;
|
||||
factory _PostComposeInitialState.fromJson(Map<String, dynamic> json) => _$PostComposeInitialStateFromJson(json);
|
||||
|
||||
@override final String? title;
|
||||
@override final String? description;
|
||||
@override final String? content;
|
||||
final List<UniversalFile> _attachments;
|
||||
@override@JsonKey() List<UniversalFile> get attachments {
|
||||
if (_attachments is EqualUnmodifiableListView) return _attachments;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_attachments);
|
||||
}
|
||||
|
||||
@override final int? visibility;
|
||||
|
||||
/// Create a copy of PostComposeInitialState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$PostComposeInitialStateCopyWith<_PostComposeInitialState> get copyWith => __$PostComposeInitialStateCopyWithImpl<_PostComposeInitialState>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$PostComposeInitialStateToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PostComposeInitialState&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.content, content) || other.content == content)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.visibility, visibility) || other.visibility == visibility));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,description,content,const DeepCollectionEquality().hash(_attachments),visibility);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PostComposeInitialState(title: $title, description: $description, content: $content, attachments: $attachments, visibility: $visibility)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$PostComposeInitialStateCopyWith<$Res> implements $PostComposeInitialStateCopyWith<$Res> {
|
||||
factory _$PostComposeInitialStateCopyWith(_PostComposeInitialState value, $Res Function(_PostComposeInitialState) _then) = __$PostComposeInitialStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String? title, String? description, String? content, List<UniversalFile> attachments, int? visibility
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$PostComposeInitialStateCopyWithImpl<$Res>
|
||||
implements _$PostComposeInitialStateCopyWith<$Res> {
|
||||
__$PostComposeInitialStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _PostComposeInitialState _self;
|
||||
final $Res Function(_PostComposeInitialState) _then;
|
||||
|
||||
/// Create a copy of PostComposeInitialState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? title = freezed,Object? description = freezed,Object? content = freezed,Object? attachments = null,Object? visibility = freezed,}) {
|
||||
return _then(_PostComposeInitialState(
|
||||
title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String?,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
||||
as String?,attachments: null == attachments ? _self._attachments : attachments // ignore: cast_nullable_to_non_nullable
|
||||
as List<UniversalFile>,visibility: freezed == visibility ? _self.visibility : visibility // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
31
lib/screens/posts/compose.g.dart
Normal file
31
lib/screens/posts/compose.g.dart
Normal file
@ -0,0 +1,31 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'compose.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_PostComposeInitialState _$PostComposeInitialStateFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _PostComposeInitialState(
|
||||
title: json['title'] as String?,
|
||||
description: json['description'] as String?,
|
||||
content: json['content'] as String?,
|
||||
attachments:
|
||||
(json['attachments'] as List<dynamic>?)
|
||||
?.map((e) => UniversalFile.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
const [],
|
||||
visibility: (json['visibility'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$PostComposeInitialStateToJson(
|
||||
_PostComposeInitialState instance,
|
||||
) => <String, dynamic>{
|
||||
'title': instance.title,
|
||||
'description': instance.description,
|
||||
'content': instance.content,
|
||||
'attachments': instance.attachments.map((e) => e.toJson()).toList(),
|
||||
'visibility': instance.visibility,
|
||||
};
|
Reference in New Issue
Block a user