💄 Optimize the article editor

This commit is contained in:
2026-01-17 14:50:16 +08:00
parent 09767e113f
commit c5d667ecf3
3 changed files with 99 additions and 86 deletions

View File

@@ -201,6 +201,7 @@ class ArticleComposeScreen extends HookConsumerWidget {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: colorScheme.surface,
border: Border.all(color: colorScheme.outline.withOpacity(0.3)), border: Border.all(color: colorScheme.outline.withOpacity(0.3)),
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
), ),
@@ -225,19 +226,14 @@ class ArticleComposeScreen extends HookConsumerWidget {
], ],
), ),
), ),
Expanded( Expanded(child: widgetItem),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: widgetItem,
),
),
], ],
), ),
); );
} }
Widget buildEditorPane() { Widget buildEditorPane() {
return Center( final editorContent = Center(
child: ConstrainedBox( child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 560), constraints: const BoxConstraints(maxWidth: 560),
child: Column( child: Column(
@@ -267,6 +263,20 @@ class ArticleComposeScreen extends HookConsumerWidget {
), ),
), ),
); );
// Add background color for mobile editor pane
if (!isWideScreen(context)) {
return Container(
decoration: BoxDecoration(
color: colorScheme.surface,
borderRadius: BorderRadius.circular(8),
),
margin: const EdgeInsets.symmetric(vertical: 8),
child: editorContent,
);
}
return editorContent;
} }
return PopScope( return PopScope(
@@ -325,7 +335,9 @@ class ArticleComposeScreen extends HookConsumerWidget {
Tooltip( Tooltip(
message: 'togglePreview'.tr(), message: 'togglePreview'.tr(),
child: IconButton( child: IconButton(
icon: Icon(showPreview.value ? Symbols.edit : Symbols.preview), icon: Icon(
showPreview.value ? Symbols.preview_off : Symbols.preview,
),
onPressed: () => showPreview.value = !showPreview.value, onPressed: () => showPreview.value = !showPreview.value,
), ),
), ),
@@ -395,12 +407,25 @@ class ArticleComposeScreen extends HookConsumerWidget {
switchOutCurve: Curves.easeOutCubic, switchOutCurve: Curves.easeOutCubic,
transitionBuilder: transitionBuilder:
(Widget child, Animation<double> animation) { (Widget child, Animation<double> animation) {
return FadeTransition( final isWide = isWideScreen(context);
opacity: animation, if (isWide) {
child: SlideTransition( // Desktop: scale animation
return ScaleTransition(
scale: Tween<double>(begin: 0.95, end: 1.0)
.animate(
CurvedAnimation(
parent: animation,
curve: Curves.easeOutCubic,
),
),
child: child,
);
} else {
// Mobile: horizontal slide animation
return SlideTransition(
position: position:
Tween<Offset>( Tween<Offset>(
begin: const Offset(0, 0.05), begin: const Offset(0.05, 0),
end: Offset.zero, end: Offset.zero,
).animate( ).animate(
CurvedAnimation( CurvedAnimation(
@@ -409,8 +434,8 @@ class ArticleComposeScreen extends HookConsumerWidget {
), ),
), ),
child: child, child: child,
),
); );
}
}, },
child: isWideScreen(context) child: isWideScreen(context)
? Row( ? Row(

View File

@@ -44,7 +44,7 @@ class ResponsiveSidebar extends HookConsumerWidget {
showDrawer.value = true; showDrawer.value = true;
animationController.forward(); animationController.forward();
} else if (!showSidebar.value && showDrawer.value) { } else if (!showSidebar.value && showDrawer.value) {
showDrawer.value = false; // Don't set showDrawer.value = false here - let animation complete first
animationController.reverse(); animationController.reverse();
} }
} else { } else {

View File

@@ -121,8 +121,7 @@ class PostComposeCard extends HookConsumerWidget {
content: composeState.contentController.text, content: composeState.contentController.text,
visibility: composeState.visibility.value, visibility: composeState.visibility.value,
type: composeState.postType, type: composeState.postType,
attachments: attachments: composeState.attachments.value
composeState.attachments.value
.where((e) => e.isOnCloud) .where((e) => e.isOnCloud)
.map((e) => e.data as SnCloudFile) .map((e) => e.data as SnCloudFile)
.toList(), .toList(),
@@ -221,8 +220,7 @@ class PostComposeCard extends HookConsumerWidget {
composeState.currentPublisher.value == null) composeState.currentPublisher.value == null)
? null ? null
: performSubmit, : performSubmit,
icon: icon: composeState.submitting.value
composeState.submitting.value
? SizedBox( ? SizedBox(
width: 24, width: 24,
height: 24, height: 24,
@@ -235,8 +233,7 @@ class PostComposeCard extends HookConsumerWidget {
? Symbols.edit ? Symbols.edit
: Symbols.upload, : Symbols.upload,
), ),
tooltip: tooltip: originalPost != null
originalPost != null
? 'postUpdate'.tr() ? 'postUpdate'.tr()
: 'postPublish'.tr(), : 'postPublish'.tr(),
visualDensity: const VisualDensity( visualDensity: const VisualDensity(
@@ -268,12 +265,9 @@ class PostComposeCard extends HookConsumerWidget {
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
useRootNavigator: true, useRootNavigator: true,
builder: builder: (context) => SheetScaffold(
(context) => SheetScaffold(
titleText: 'Post Preview', titleText: 'Post Preview',
child: SingleChildScrollView( child: SingleChildScrollView(child: PostItem(item: post)),
child: PostItem(item: post),
),
), ),
); );
}, },
@@ -283,8 +277,7 @@ class PostComposeCard extends HookConsumerWidget {
Expanded( Expanded(
child: KeyboardListener( child: KeyboardListener(
focusNode: FocusNode(), focusNode: FocusNode(),
onKeyEvent: onKeyEvent: (event) => ComposeLogic.handleKeyPress(
(event) => ComposeLogic.handleKeyPress(
event, event,
composeState, composeState,
ref, ref,
@@ -304,8 +297,7 @@ class PostComposeCard extends HookConsumerWidget {
// Publisher profile picture // Publisher profile picture
GestureDetector( GestureDetector(
child: ProfilePictureWidget( child: ProfilePictureWidget(
fileId: fileId: composeState
composeState
.currentPublisher .currentPublisher
.value .value
?.picture ?.picture
@@ -326,8 +318,8 @@ class PostComposeCard extends HookConsumerWidget {
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
useRootNavigator: true, useRootNavigator: true,
builder: builder: (context) =>
(context) => const NewPublisherScreen(), const NewPublisherScreen(),
).then((value) { ).then((value) {
if (value != null) { if (value != null) {
composeState.currentPublisher.value = composeState.currentPublisher.value =
@@ -370,8 +362,7 @@ class PostComposeCard extends HookConsumerWidget {
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
useRootNavigator: true, useRootNavigator: true,
builder: builder: (context) =>
(context) =>
const NewPublisherScreen(), const NewPublisherScreen(),
).then((value) { ).then((value) {
if (value != null) { if (value != null) {
@@ -388,8 +379,8 @@ class PostComposeCard extends HookConsumerWidget {
isScrollControlled: true, isScrollControlled: true,
useRootNavigator: true, useRootNavigator: true,
context: context, context: context,
builder: builder: (context) =>
(context) => const PublisherModal(), const PublisherModal(),
).then((value) { ).then((value) {
if (value != null) { if (value != null) {
composeState.currentPublisher.value = composeState.currentPublisher.value =
@@ -415,9 +406,7 @@ class PostComposeCard extends HookConsumerWidget {
), ),
// Bottom toolbar // Bottom toolbar
SizedBox( ClipRRect(
height: 65,
child: ClipRRect(
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(8), bottomLeft: Radius.circular(8),
bottomRight: Radius.circular(8), bottomRight: Radius.circular(8),
@@ -429,7 +418,6 @@ class PostComposeCard extends HookConsumerWidget {
useSafeArea: isContained, useSafeArea: isContained,
), ),
), ),
),
], ],
), ),
), ),