♻️ Refactored the post compose sheet
This commit is contained in:
@@ -7,8 +7,13 @@ import 'package:island/models/post.dart';
|
||||
import 'package:island/screens/posts/compose.dart';
|
||||
import 'package:island/services/compose_storage_db.dart';
|
||||
import 'package:island/services/event_bus.dart';
|
||||
import 'package:island/services/responsive.dart';
|
||||
import 'package:island/widgets/content/sheet.dart';
|
||||
import 'package:island/widgets/post/compose_card.dart';
|
||||
import 'package:island/widgets/post/compose_settings_sheet.dart';
|
||||
import 'package:island/widgets/post/compose_shared.dart';
|
||||
import 'package:island/widgets/post/compose_state_utils.dart';
|
||||
import 'package:island/widgets/post/compose_submit_utils.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
/// A dialog that wraps PostComposeCard for easy use in dialogs.
|
||||
/// This provides a convenient way to show the compose interface in a modal dialog.
|
||||
@@ -29,16 +34,15 @@ class PostComposeDialog extends HookConsumerWidget {
|
||||
SnPost? originalPost,
|
||||
PostComposeInitialState? initialState,
|
||||
}) {
|
||||
return showDialog<bool>(
|
||||
return showModalBottomSheet<bool>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
useRootNavigator: true,
|
||||
builder:
|
||||
(context) => Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: PostComposeDialog(
|
||||
originalPost: originalPost,
|
||||
initialState: initialState,
|
||||
),
|
||||
(context) => PostComposeDialog(
|
||||
originalPost: originalPost,
|
||||
initialState: initialState,
|
||||
isBottomSheet: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -48,7 +52,41 @@ class PostComposeDialog extends HookConsumerWidget {
|
||||
final drafts = ref.watch(composeStorageNotifierProvider);
|
||||
final restoredInitialState = useState<PostComposeInitialState?>(null);
|
||||
final prompted = useState(false);
|
||||
final isWide = isWideScreen(context);
|
||||
|
||||
final repliedPost = initialState?.replyingTo ?? originalPost?.repliedPost;
|
||||
final forwardedPost =
|
||||
initialState?.forwardingTo ?? originalPost?.forwardedPost;
|
||||
|
||||
// Create compose state
|
||||
final state = useMemoized(
|
||||
() => ComposeLogic.createState(
|
||||
originalPost: originalPost,
|
||||
forwardedPost: forwardedPost,
|
||||
repliedPost: repliedPost,
|
||||
postType: 0,
|
||||
),
|
||||
[originalPost, forwardedPost, repliedPost],
|
||||
);
|
||||
|
||||
// Add a listener to the entire state to trigger rebuilds
|
||||
final stateNotifier = useMemoized(
|
||||
() => Listenable.merge([
|
||||
state.titleController,
|
||||
state.descriptionController,
|
||||
state.contentController,
|
||||
state.visibility,
|
||||
state.attachments,
|
||||
state.attachmentProgress,
|
||||
state.currentPublisher,
|
||||
state.submitting,
|
||||
]),
|
||||
[state],
|
||||
);
|
||||
useListenable(stateNotifier);
|
||||
|
||||
// Use shared state management utilities
|
||||
ComposeStateUtils.usePublisherInitialization(ref, state);
|
||||
ComposeStateUtils.useInitialStateLoader(state, initialState);
|
||||
|
||||
useEffect(() {
|
||||
if (!prompted.value &&
|
||||
@@ -64,24 +102,69 @@ class PostComposeDialog extends HookConsumerWidget {
|
||||
return null;
|
||||
}, [drafts, prompted.value]);
|
||||
|
||||
return Dialog(
|
||||
insetPadding: isWide ? const EdgeInsets.all(16) : EdgeInsets.zero,
|
||||
child: ConstrainedBox(
|
||||
constraints:
|
||||
isWide
|
||||
? const BoxConstraints(maxWidth: 600)
|
||||
: const BoxConstraints.expand(),
|
||||
child: PostComposeCard(
|
||||
originalPost: originalPost,
|
||||
initialState: restoredInitialState.value ?? initialState,
|
||||
onCancel: () => Navigator.of(context).pop(),
|
||||
onSubmit: () {
|
||||
// Fire event to notify listeners that a post was created
|
||||
eventBus.fire(PostCreatedEvent());
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
isDialog: true,
|
||||
),
|
||||
// Helper methods for actions
|
||||
void showSettingsSheet() {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
useRootNavigator: true,
|
||||
builder: (context) => ComposeSettingsSheet(state: state),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> performSubmit() async {
|
||||
await ComposeSubmitUtils.performSubmit(
|
||||
ref,
|
||||
state,
|
||||
context,
|
||||
originalPost: originalPost,
|
||||
repliedPost: repliedPost,
|
||||
forwardedPost: forwardedPost,
|
||||
onSuccess: () {
|
||||
// Fire event to notify listeners that a post was created
|
||||
eventBus.fire(PostCreatedEvent());
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
final actions = [
|
||||
IconButton(
|
||||
icon: const Icon(Symbols.settings),
|
||||
onPressed: showSettingsSheet,
|
||||
tooltip: 'postSettings'.tr(),
|
||||
),
|
||||
IconButton(
|
||||
onPressed:
|
||||
(state.submitting.value || state.currentPublisher.value == null)
|
||||
? null
|
||||
: performSubmit,
|
||||
icon:
|
||||
state.submitting.value
|
||||
? SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: const CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: Icon(originalPost != null ? Symbols.edit : Symbols.upload),
|
||||
tooltip: originalPost != null ? 'postUpdate'.tr() : 'postPublish'.tr(),
|
||||
),
|
||||
];
|
||||
|
||||
return SheetScaffold(
|
||||
titleText: 'postCompose'.tr(),
|
||||
actions: actions,
|
||||
child: PostComposeCard(
|
||||
originalPost: originalPost,
|
||||
initialState: restoredInitialState.value ?? initialState,
|
||||
onCancel: () => Navigator.of(context).pop(),
|
||||
onSubmit: () {
|
||||
// Fire event to notify listeners that a post was created
|
||||
eventBus.fire(PostCreatedEvent());
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
isContained: true,
|
||||
showHeader: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user