diff --git a/lib/controllers/post_write_controller.dart b/lib/controllers/post_write_controller.dart index 84a3e8a..450cf67 100644 --- a/lib/controllers/post_write_controller.dart +++ b/lib/controllers/post_write_controller.dart @@ -220,6 +220,7 @@ class PostWriteController extends ChangeNotifier { contentController.text = post.body['content'] ?? ''; aliasController.text = post.alias ?? ''; rewardController.text = post.body['reward']?.toString() ?? ''; + videoAttachment = post.preload?.video; publishedAt = post.publishedAt; publishedUntil = post.publishedUntil; visibleUsers = List.from(post.visibleUsersList ?? [], growable: true); diff --git a/lib/screens/post/post_editor.dart b/lib/screens/post/post_editor.dart index ad81937..89eca9f 100644 --- a/lib/screens/post/post_editor.dart +++ b/lib/screens/post/post_editor.dart @@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_context_menu/flutter_context_menu.dart'; import 'package:gap/gap.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:material_symbols_icons/symbols.dart'; @@ -14,11 +15,14 @@ import 'package:responsive_framework/responsive_framework.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:surface/controllers/post_write_controller.dart'; import 'package:surface/providers/config.dart'; +import 'package:surface/providers/sn_attachment.dart'; import 'package:surface/providers/sn_network.dart'; import 'package:surface/types/attachment.dart'; import 'package:surface/types/post.dart'; import 'package:surface/widgets/account/account_image.dart'; import 'package:surface/widgets/attachment/attachment_item.dart'; +import 'package:surface/widgets/attachment/pending_attachment_alt.dart'; +import 'package:surface/widgets/attachment/pending_attachment_boost.dart'; import 'package:surface/widgets/loading_indicator.dart'; import 'package:surface/widgets/markdown_content.dart'; import 'package:surface/widgets/navigation/app_scaffold.dart'; @@ -716,6 +720,74 @@ class _PostVideoEditor extends StatelessWidget { controller.setVideoAttachment(video); } + void _setAlt(BuildContext context) async { + if (controller.videoAttachment == null) return; + + final result = await showDialog( + context: context, + builder: (context) => PendingAttachmentAltDialog(media: PostWriteMedia(controller.videoAttachment)), + ); + if (result == null) return; + + controller.setVideoAttachment(result); + } + + Future _createBoost(BuildContext context) async { + if (controller.videoAttachment == null) return; + + final result = await showDialog( + context: context, + builder: (context) => PendingAttachmentBoostDialog(media: PostWriteMedia(controller.videoAttachment)), + ); + if (result == null) return; + + final newAttach = controller.videoAttachment!.copyWith( + boosts: [...controller.videoAttachment!.boosts, result], + ); + + controller.setVideoAttachment(newAttach); + } + + void _setThumbnail(BuildContext context) async { + if (controller.videoAttachment == null) return; + + final thumbnail = await showDialog( + context: context, + builder: (context) => AttachmentInputDialog( + title: 'attachmentSetThumbnail'.tr(), + pool: 'interactive', + analyzeNow: true, + ), + ); + if (thumbnail == null) return; + if (!context.mounted) return; + + try { + final attach = context.read(); + final newAttach = await attach.updateOne( + controller.videoAttachment!, + thumbnailId: thumbnail.id, + ); + controller.setVideoAttachment(newAttach); + } catch (err) { + if (!context.mounted) return; + context.showErrorDialog(err); + } + } + + Future _deleteAttachment(BuildContext context) async { + if (controller.videoAttachment == null) return; + + try { + final sn = context.read(); + await sn.client.delete('/cgi/uc/attachments/${controller.videoAttachment!.id}'); + controller.setVideoAttachment(null); + } catch (err) { + if (!context.mounted) return; + context.showErrorDialog(err); + } + } + @override Widget build(BuildContext context) { return Column( @@ -772,35 +844,78 @@ class _PostVideoEditor extends StatelessWidget { borderRadius: BorderRadius.circular(16), border: Border.all(color: Theme.of(context).dividerColor), ), - child: InkWell( - borderRadius: BorderRadius.circular(16), - child: AspectRatio( - aspectRatio: 16 / 9, - child: controller.videoAttachment == null - ? Center( - child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.add), - const Gap(4), - Text('postVideoUpload'.tr()), - ], - ), - ) - : ClipRRect( - borderRadius: BorderRadius.circular(16), - child: AttachmentItem( - data: controller.videoAttachment!, - heroTag: const Uuid().v4(), - ), - ), + child: ContextMenuRegion( + contextMenu: ContextMenu( + entries: [ + MenuItem( + label: 'attachmentSetAlt'.tr(), + icon: Symbols.description, + onSelected: () { + _setAlt(context); + }, + ), + MenuItem( + label: 'attachmentBoost'.tr(), + icon: Symbols.bolt, + onSelected: () { + _createBoost(context); + }, + ), + MenuItem( + label: 'attachmentSetThumbnail'.tr(), + icon: Symbols.image, + onSelected: () { + _setThumbnail(context); + }, + ), + MenuItem( + label: 'attachmentCopyRandomId'.tr(), + icon: Symbols.content_copy, + onSelected: () { + Clipboard.setData(ClipboardData(text: controller.videoAttachment!.rid)); + }, + ), + MenuItem( + label: 'delete'.tr(), + icon: Symbols.delete, + onSelected: () => _deleteAttachment(context), + ), + MenuItem( + label: 'unlink'.tr(), + icon: Symbols.link_off, + onSelected: () { + controller.setVideoAttachment(null); + }, + ), + ], + ), + child: InkWell( + borderRadius: BorderRadius.circular(16), + onTap: controller.videoAttachment != null ? () => _selectVideo(context) : null, + child: AspectRatio( + aspectRatio: 16 / 9, + child: controller.videoAttachment == null + ? Center( + child: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.add), + const Gap(4), + Text('postVideoUpload'.tr()), + ], + ), + ) + : ClipRRect( + borderRadius: BorderRadius.circular(16), + child: AttachmentItem( + data: controller.videoAttachment!, + heroTag: const Uuid().v4(), + ), + ), + ), ), - onTap: () { - if (controller.videoAttachment != null) return; - _selectVideo(context); - }, ), ), ],