From a7d4975e182d38641f987df2d291be2182874cf4 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 26 Apr 2025 17:55:32 +0800 Subject: [PATCH] :sparkles: Post editing --- lib/screens/posts/compose.dart | 16 ++++--- lib/widgets/post/post_item.dart | 76 +++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/lib/screens/posts/compose.dart b/lib/screens/posts/compose.dart index 96ff36a..7ac71b4 100644 --- a/lib/screens/posts/compose.dart +++ b/lib/screens/posts/compose.dart @@ -185,8 +185,8 @@ class PostComposeScreen extends HookConsumerWidget { ); final client = ref.watch(apiClientProvider); - await client.post( - '/posts', + await client.request( + originalPost == null ? '/posts' : '/posts/${originalPost!.id}', data: { 'content': contentController.text, 'attachments': @@ -195,7 +195,10 @@ class PostComposeScreen extends HookConsumerWidget { .map((e) => e.data.id) .toList(), }, - options: Options(headers: {'X-Pub': currentPublisher.value?.name}), + options: Options( + headers: {'X-Pub': currentPublisher.value?.name}, + method: originalPost == null ? 'POST' : 'PATCH', + ), ); if (context.mounted) { context.maybePop(true); @@ -223,6 +226,8 @@ class PostComposeScreen extends HookConsumerWidget { strokeWidth: 2.5, ), ).center() + : originalPost != null + ? const Icon(LucideIcons.edit) : const Icon(LucideIcons.upload), ), const Gap(8), @@ -357,7 +362,8 @@ class _AttachmentPreview extends StatelessWidget { @override Widget build(BuildContext context) { return AspectRatio( - aspectRatio: 1, + aspectRatio: + (item.isOnCloud ? (item.data.fileMeta?['ratio'] ?? 1) : 1).toDouble(), child: ClipRRect( borderRadius: BorderRadius.circular(8), child: Stack( @@ -485,7 +491,7 @@ class _AttachmentPreview extends StatelessWidget { color: Colors.black.withOpacity(0.5), padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: - (item is SnCloudFile) + (item.isOnCloud) ? Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/widgets/post/post_item.dart b/lib/widgets/post/post_item.dart index d9a1212..e14d1fd 100644 --- a/lib/widgets/post/post_item.dart +++ b/lib/widgets/post/post_item.dart @@ -1,10 +1,12 @@ import 'package:auto_route/auto_route.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:island/models/post.dart'; import 'package:island/route.gr.dart'; import 'package:island/widgets/content/cloud_file_collection.dart'; import 'package:island/widgets/content/cloud_files.dart'; import 'package:island/widgets/content/markdown.dart'; +import 'package:lucide_icons/lucide_icons.dart'; import 'package:styled_widget/styled_widget.dart'; class PostItem extends StatelessWidget { @@ -23,39 +25,59 @@ class PostItem extends StatelessWidget { final renderingPadding = padding ?? EdgeInsets.symmetric(horizontal: 12, vertical: 16); - return Padding( - padding: renderingPadding, - child: Column( - spacing: 8, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 12, - children: [ - ProfilePictureWidget(item: item.publisher.picture), - Expanded( - child: GestureDetector( - child: Column( + return CupertinoContextMenu.builder( + actions: [ + CupertinoContextMenuAction( + trailingIcon: LucideIcons.edit, + onPressed: () { + context.router.push(PostEditRoute(id: item.id)); + }, + child: Text('Edit'), + ), + ], + builder: (context, animation) { + return Material( + color: Theme.of(context).colorScheme.surface, + child: SingleChildScrollView( + physics: const NeverScrollableScrollPhysics(), + child: Padding( + padding: renderingPadding, + child: Column( + spacing: 8, + children: [ + Row( + mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, + spacing: 12, children: [ - Text(item.publisher.nick).bold(), - if (item.content.isNotEmpty) - MarkdownTextContent(content: item.content), + ProfilePictureWidget(item: item.publisher.picture), + Expanded( + child: GestureDetector( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(item.publisher.nick).bold(), + if (item.content.isNotEmpty) + MarkdownTextContent(content: item.content), + ], + ), + onTap: () { + if (isOpenable) { + context.router.push(PostDetailRoute(id: item.id)); + } + }, + ), + ), ], ), - onTap: () { - if (isOpenable) { - context.router.push(PostDetailRoute(id: item.id)); - } - }, - ), + if (item.attachments.isNotEmpty) + CloudFileList(files: item.attachments), + ], ), - ], + ), ), - if (item.attachments.isNotEmpty) - CloudFileList(files: item.attachments), - ], - ), + ); + }, ); } }