Post tags

This commit is contained in:
2025-06-27 02:31:21 +08:00
parent 0361f031db
commit 4deff5a920
7 changed files with 114 additions and 118 deletions

View File

@ -103,30 +103,32 @@ class PostComposeScreen extends HookConsumerWidget {
originalPost: originalPost,
forwardedPost: effectiveForwardedPost,
repliedPost: effectiveRepliedPost,
postType: 0, // Regular post type
),
[originalPost, effectiveForwardedPost, effectiveRepliedPost],
);
// Add a listener to the entire state to trigger rebuilds
final stateNotifier = useMemoized(
() => Listenable.merge([
state.titleController,
state.descriptionController,
state.contentController,
state.visibility,
state.attachments,
state.attachmentProgress,
state.currentPublisher,
state.submitting,
]),
[state]);
() => Listenable.merge([
state.titleController,
state.descriptionController,
state.contentController,
state.visibility,
state.attachments,
state.attachmentProgress,
state.currentPublisher,
state.submitting,
]),
[state],
);
useListenable(stateNotifier);
// Start auto-save when component mounts
useEffect(() {
if (originalPost == null) {
// Only auto-save for new posts, not edits
state.startAutoSave(ref, postType: 0);
state.startAutoSave(ref);
}
return () => state.stopAutoSave();
}, [state]);
@ -165,13 +167,18 @@ class PostComposeScreen extends HookConsumerWidget {
final drafts = ref.read(composeStorageNotifierProvider);
if (drafts.isNotEmpty) {
final mostRecentDraft = drafts.values.reduce(
(a, b) => (a.updatedAt ?? DateTime(0)).isAfter(b.updatedAt ?? DateTime(0)) ? a : b,
(a, b) =>
(a.updatedAt ?? DateTime(0)).isAfter(b.updatedAt ?? DateTime(0))
? a
: b,
);
// Only load if the draft has meaningful content
if (mostRecentDraft.content?.isNotEmpty == true || mostRecentDraft.title?.isNotEmpty == true) {
if (mostRecentDraft.content?.isNotEmpty == true ||
mostRecentDraft.title?.isNotEmpty == true) {
state.titleController.text = mostRecentDraft.title ?? '';
state.descriptionController.text = mostRecentDraft.description ?? '';
state.descriptionController.text =
mostRecentDraft.description ?? '';
state.contentController.text = mostRecentDraft.content ?? '';
state.visibility.value = mostRecentDraft.visibility;
}
@ -298,7 +305,8 @@ class PostComposeScreen extends HookConsumerWidget {
state.titleController.text = draft.title ?? '';
state.descriptionController.text =
draft.description ?? '';
state.contentController.text = draft.content ?? '';
state.contentController.text =
draft.content ?? '';
state.visibility.value = draft.visibility;
}
},
@ -322,14 +330,13 @@ class PostComposeScreen extends HookConsumerWidget {
state.submitting.value
? null
: () => ComposeLogic.performAction(
ref,
state,
context,
originalPost: originalPost,
repliedPost: repliedPost,
forwardedPost: forwardedPost,
postType: 0, // Regular post type
),
ref,
state,
context,
originalPost: originalPost,
repliedPost: repliedPost,
forwardedPost: forwardedPost,
),
icon:
state.submitting.value
? SizedBox(
@ -341,9 +348,7 @@ class PostComposeScreen extends HookConsumerWidget {
),
).center()
: Icon(
originalPost != null
? Symbols.edit
: Symbols.upload,
originalPost != null ? Symbols.edit : Symbols.upload,
),
),
const Gap(8),
@ -405,7 +410,6 @@ class PostComposeScreen extends HookConsumerWidget {
originalPost: originalPost,
repliedPost: repliedPost,
forwardedPost: forwardedPost,
postType: 0, // Regular post type
),
child: TextField(
controller: state.contentController,

View File

@ -60,7 +60,10 @@ class ArticleComposeScreen extends HookConsumerWidget {
final publishers = ref.watch(publishersManagedProvider);
final state = useMemoized(
() => ComposeLogic.createState(originalPost: originalPost),
() => ComposeLogic.createState(
originalPost: originalPost,
postType: 1, // Article type
),
[originalPost],
);
@ -70,7 +73,7 @@ class ArticleComposeScreen extends HookConsumerWidget {
if (originalPost == null) {
// Only auto-save for new articles, not edits
autoSaveTimer = Timer.periodic(const Duration(seconds: 3), (_) {
ComposeLogic.saveDraftWithoutUpload(ref, state, postType: 1);
ComposeLogic.saveDraftWithoutUpload(ref, state);
});
}
return () {
@ -78,7 +81,7 @@ class ArticleComposeScreen extends HookConsumerWidget {
state.stopAutoSave();
// Save final draft before disposing
if (originalPost == null) {
ComposeLogic.saveDraftWithoutUpload(ref, state, postType: 1);
ComposeLogic.saveDraftWithoutUpload(ref, state);
}
ComposeLogic.dispose(state);
autoSaveTimer?.cancel();
@ -362,7 +365,7 @@ class ArticleComposeScreen extends HookConsumerWidget {
return PopScope(
onPopInvoked: (_) {
if (originalPost == null) {
ComposeLogic.saveDraftWithoutUpload(ref, state, postType: 1);
ComposeLogic.saveDraftWithoutUpload(ref, state);
}
},
child: AppScaffold(
@ -410,7 +413,7 @@ class ArticleComposeScreen extends HookConsumerWidget {
),
IconButton(
icon: const Icon(Symbols.save),
onPressed: () => ComposeLogic.saveDraft(ref, state, postType: 1),
onPressed: () => ComposeLogic.saveDraft(ref, state),
tooltip: 'saveDraft'.tr(),
),
IconButton(
@ -437,7 +440,6 @@ class ArticleComposeScreen extends HookConsumerWidget {
state,
context,
originalPost: originalPost,
postType: 1, // Article type
),
icon:
submitting
@ -530,18 +532,17 @@ class ArticleComposeScreen extends HookConsumerWidget {
if (isPaste && isModifierPressed) {
ComposeLogic.handlePaste(state);
} else if (isSave && isModifierPressed) {
ComposeLogic.saveDraft(ref, state, postType: 1);
ComposeLogic.saveDraft(ref, state);
ComposeLogic.saveDraft(ref, state);
} else if (isSubmit && isModifierPressed && !state.submitting.value) {
ComposeLogic.performAction(
ref,
state,
context,
originalPost: originalPost,
postType: 1, // Article type
);
}
}
// Helper method to save article draft
}