♻️ Dialog based editor for normal post

This commit is contained in:
2025-09-29 01:16:32 +08:00
parent 56fb5451cd
commit de9e235d0c
5 changed files with 290 additions and 124 deletions

View File

@@ -12,8 +12,14 @@ import 'package:styled_widget/styled_widget.dart';
class ComposeToolbar extends HookConsumerWidget {
final ComposeState state;
final SnPost? originalPost;
final bool isCompact;
const ComposeToolbar({super.key, required this.state, this.originalPost});
const ComposeToolbar({
super.key,
required this.state,
this.originalPost,
this.isCompact = false,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -74,6 +80,160 @@ class ComposeToolbar extends HookConsumerWidget {
final colorScheme = Theme.of(context).colorScheme;
if (isCompact) {
return Container(
color: Theme.of(context).colorScheme.surfaceContainerLow,
padding: EdgeInsets.symmetric(horizontal: 8),
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 560),
child: Row(
children: [
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
IconButton(
onPressed: pickPhotoMedia,
tooltip: 'addPhoto'.tr(),
icon: const Icon(Symbols.add_a_photo),
color: colorScheme.primary,
visualDensity: const VisualDensity(
horizontal: -4,
vertical: -2,
),
),
IconButton(
onPressed: pickVideoMedia,
tooltip: 'addVideo'.tr(),
icon: const Icon(Symbols.videocam),
color: colorScheme.primary,
visualDensity: const VisualDensity(
horizontal: -4,
vertical: -2,
),
),
IconButton(
onPressed: addAudio,
tooltip: 'addAudio'.tr(),
icon: const Icon(Symbols.mic),
color: colorScheme.primary,
visualDensity: const VisualDensity(
horizontal: -4,
vertical: -2,
),
),
IconButton(
onPressed: pickGeneralFile,
tooltip: 'uploadFile'.tr(),
icon: const Icon(Symbols.file_upload),
color: colorScheme.primary,
visualDensity: const VisualDensity(
horizontal: -4,
vertical: -2,
),
),
IconButton(
onPressed: linkAttachment,
icon: const Icon(Symbols.attach_file),
tooltip: 'linkAttachment'.tr(),
color: colorScheme.primary,
visualDensity: const VisualDensity(
horizontal: -4,
vertical: -2,
),
),
// Poll button with visual state when a poll is linked
ListenableBuilder(
listenable: state.pollId,
builder: (context, _) {
return IconButton(
onPressed: pickPoll,
icon: const Icon(Symbols.how_to_vote),
tooltip: 'poll'.tr(),
color: colorScheme.primary,
visualDensity: const VisualDensity(
horizontal: -4,
vertical: -2,
),
style: ButtonStyle(
backgroundColor: WidgetStatePropertyAll(
state.pollId.value != null
? colorScheme.primary.withOpacity(0.15)
: null,
),
),
);
},
),
// Embed button with visual state when embed is present
ListenableBuilder(
listenable: state.embedView,
builder: (context, _) {
return IconButton(
onPressed: showEmbedSheet,
icon: const Icon(Symbols.iframe),
tooltip: 'embedView'.tr(),
color: colorScheme.primary,
visualDensity: const VisualDensity(
horizontal: -4,
vertical: -2,
),
style: ButtonStyle(
backgroundColor: WidgetStatePropertyAll(
state.embedView.value != null
? colorScheme.primary.withOpacity(0.15)
: null,
),
),
);
},
),
],
),
),
),
if (originalPost == null && state.isEmpty)
IconButton(
icon: const Icon(Symbols.draft, size: 20),
color: colorScheme.primary,
onPressed: showDraftManager,
tooltip: 'drafts'.tr(),
visualDensity: const VisualDensity(
horizontal: -4,
vertical: -4,
),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(
minWidth: 32,
minHeight: 32,
),
)
else if (originalPost == null)
IconButton(
icon: const Icon(Symbols.save, size: 20),
color: colorScheme.primary,
onPressed: saveDraft,
onLongPress: showDraftManager,
tooltip: 'saveDraft'.tr(),
visualDensity: const VisualDensity(
horizontal: -4,
vertical: -4,
),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(
minWidth: 32,
minHeight: 32,
),
),
],
).padding(horizontal: 8, vertical: 4),
),
),
);
}
return Material(
elevation: 4,
color: Theme.of(context).colorScheme.surfaceContainerLow,