diff --git a/lib/posts/widgets/compose/compose_toolbar.dart b/lib/posts/widgets/compose/compose_toolbar.dart index 95f39d75f..82d78efde 100644 --- a/lib/posts/widgets/compose/compose_toolbar.dart +++ b/lib/posts/widgets/compose/compose_toolbar.dart @@ -10,6 +10,8 @@ import 'package:island/posts/widgets/compose/draft_manager.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:solar_network_sdk/solar_network_sdk.dart'; +import 'package:island/stickers/widgets/stickers/sticker_picker.dart'; +import 'package:flutter/services.dart'; class ComposeToolbar extends HookConsumerWidget { final ComposeState state; @@ -105,6 +107,32 @@ class ComposeToolbar extends HookConsumerWidget { ); } + void pickSticker() async { + final renderBox = context.findRenderObject() as RenderBox?; + final offset = renderBox?.localToGlobal(Offset.zero) ?? Offset.zero; + await showStickerPickerPopover( + context, + offset, + alignment: Alignment.bottomCenter, + onPick: (placeholder) { + final controller = state.contentController; + final text = controller.text; + final selection = controller.selection + final newText = text.replaceRange( + selection.start, + selection.end, + '$placeholder', + ); + controller.text = newText; + controller.selection = TextSelection.fromPosition( + TextPosition(offset: selection.start + placeholder.length + 2), + ); + HapticFeedback.selectionClick(); + }, + ); +} + + void showDraftManager() { showModalBottomSheet( context: context, @@ -123,7 +151,7 @@ class ComposeToolbar extends HookConsumerWidget { state.visibility.value = draft.visibility; state.attachments.value = draft.attachments .map((e) => UniversalFile.fromAttachment(e)) - .toList(); + .toList(); } }, ), @@ -142,6 +170,7 @@ class ComposeToolbar extends HookConsumerWidget { return Material( elevation: 8, color: Theme.of(context).colorScheme.surfaceContainer, + child: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 560), @@ -239,13 +268,32 @@ class ComposeToolbar extends HookConsumerWidget { }, ), // 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(), + + IconButton( + onPressed: pickSticker, + icon: const Icon(Symbols.sticky_note_2), + tooltip: 'stickers'.tr(), + color: colorScheme.primary, + ), + + ListenableBuilder( + listenable: state.embedView, + builder: (context, _) { + return IconButton( + onPressed: showEmbedSheet, + icon: const Icon(Symbols.iframe), + tooltip: 'embedView'.tr(), + color: colorScheme.primary, + style: ButtonStyle( + backgroundColor: WidgetStatePropertyAll( + state.embedView.value != null + ? colorScheme.primary.withOpacity(0.15) + : null, + ), + ), + ); + }, + ), color: colorScheme.primary, style: ButtonStyle( backgroundColor: WidgetStatePropertyAll(