From dcd4587525a67646ffac81588b211527d658bdcf Mon Sep 17 00:00:00 2001 From: tusooa Date: Fri, 10 Mar 2023 12:10:39 -0500 Subject: [PATCH] Add minimal draft management tool --- src/boot/routes.js | 2 + src/components/draft/draft.js | 42 +++++++++ src/components/draft/draft.vue | 35 ++++++++ src/components/drafts/drafts.js | 17 ++++ src/components/drafts/drafts.vue | 24 +++++ src/components/nav_panel/nav_panel.js | 6 +- src/components/navigation/navigation.js | 5 ++ .../post_status_form/post_status_form.js | 90 ++++++++++--------- src/i18n/en.json | 7 +- src/modules/drafts.js | 3 + 10 files changed, 186 insertions(+), 45 deletions(-) create mode 100644 src/components/draft/draft.js create mode 100644 src/components/draft/draft.vue create mode 100644 src/components/drafts/drafts.js create mode 100644 src/components/drafts/drafts.vue diff --git a/src/boot/routes.js b/src/boot/routes.js index 2dc900e7..f6117adb 100644 --- a/src/boot/routes.js +++ b/src/boot/routes.js @@ -25,6 +25,7 @@ import ListsTimeline from 'components/lists_timeline/lists_timeline.vue' import ListsEdit from 'components/lists_edit/lists_edit.vue' import NavPanel from 'src/components/nav_panel/nav_panel.vue' import AnnouncementsPage from 'components/announcements_page/announcements_page.vue' +import Drafts from 'components/drafts/drafts.vue' export default (store) => { const validateAuthenticatedRoute = (to, from, next) => { @@ -78,6 +79,7 @@ export default (store) => { { name: 'who-to-follow', path: '/who-to-follow', component: WhoToFollow, beforeEnter: validateAuthenticatedRoute }, { name: 'about', path: '/about', component: About }, { name: 'announcements', path: '/announcements', component: AnnouncementsPage }, + { name: 'drafts', path: '/drafts', component: Drafts }, { name: 'user-profile', path: '/users/:name', component: UserProfile }, { name: 'legacy-user-profile', path: '/:name', component: UserProfile }, { name: 'lists', path: '/lists', component: Lists }, diff --git a/src/components/draft/draft.js b/src/components/draft/draft.js new file mode 100644 index 00000000..1914024f --- /dev/null +++ b/src/components/draft/draft.js @@ -0,0 +1,42 @@ +import PostStatusForm from 'src/components/post_status_form/post_status_form.vue' + +const Draft = { + components: { + PostStatusForm + }, + props: { + draft: { + type: Object, + required: true + } + }, + data () { + return { + editing: false + } + }, + computed: { + relAttrs () { + if (this.draft.type === 'edit') { + return { statusId: this.draft.refId } + } else if (this.draft.type === 'reply') { + return { replyTo: this.draft.refId } + } else { + return {} + } + }, + postStatusFormProps () { + return { + draftId: this.draft.id, + ...this.relAttrs + } + } + }, + methods: { + toggleEditing () { + this.editing = !this.editing + } + } +} + +export default Draft diff --git a/src/components/draft/draft.vue b/src/components/draft/draft.vue new file mode 100644 index 00000000..5114da70 --- /dev/null +++ b/src/components/draft/draft.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/drafts/drafts.js b/src/components/drafts/drafts.js new file mode 100644 index 00000000..6703a48e --- /dev/null +++ b/src/components/drafts/drafts.js @@ -0,0 +1,17 @@ +import Draft from 'src/components/draft/draft.vue' +import List from 'src/components/list/list.vue' + +const Drafts = { + components: { + Draft, + List + }, + computed: { + drafts () { + console.debug('available drafts:', this.$store.getters.draftsArray) + return this.$store.getters.draftsArray + } + } +} + +export default Drafts diff --git a/src/components/drafts/drafts.vue b/src/components/drafts/drafts.vue new file mode 100644 index 00000000..e64a506e --- /dev/null +++ b/src/components/drafts/drafts.vue @@ -0,0 +1,24 @@ + + + diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js index 8c9c3b11..f8d551c7 100644 --- a/src/components/nav_panel/nav_panel.js +++ b/src/components/nav_panel/nav_panel.js @@ -19,7 +19,8 @@ import { faInfoCircle, faStream, faList, - faBullhorn + faBullhorn, + faFilePen } from '@fortawesome/free-solid-svg-icons' library.add( @@ -34,7 +35,8 @@ library.add( faInfoCircle, faStream, faList, - faBullhorn + faBullhorn, + faFilePen ) const NavPanel = { props: ['forceExpand', 'forceEditMode'], diff --git a/src/components/navigation/navigation.js b/src/components/navigation/navigation.js index face430e..41685cda 100644 --- a/src/components/navigation/navigation.js +++ b/src/components/navigation/navigation.js @@ -78,6 +78,11 @@ export const ROOT_ITEMS = { label: 'nav.announcements', badgeGetter: 'unreadAnnouncementCount', criteria: ['announcements'] + }, + drafts: { + route: 'drafts', + icon: 'file-pen', + label: 'nav.drafts' } } diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 322ab0e9..7b6bc293 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -137,58 +137,47 @@ const PostStatusForm = { const [statusType, refId] = typeAndRefId({ replyTo: this.replyTo, statusId: this.statusId }) - if (statusType === 'reply') { - const currentUser = this.$store.state.users.currentUser - statusText = buildMentionsString({ user: this.repliedUser, attentions: this.attentions }, currentUser) - } + let statusParams = this.getDraft(statusType, refId) - const scope = ((this.copyMessageScope && scopeCopy) || this.copyMessageScope === 'direct') - ? this.copyMessageScope - : this.$store.state.users.currentUser.default_scope + if (!statusParams) { + if (statusType === 'reply') { + const currentUser = this.$store.state.users.currentUser + statusText = buildMentionsString({ user: this.repliedUser, attentions: this.attentions }, currentUser) + } - const { postContentType: contentType, sensitiveByDefault } = this.$store.getters.mergedConfig + const scope = ((this.copyMessageScope && scopeCopy) || this.copyMessageScope === 'direct') + ? this.copyMessageScope + : this.$store.state.users.currentUser.default_scope - let statusParams = { - type: statusType, - refId, - spoilerText: this.subject || '', - status: statusText, - nsfw: !!sensitiveByDefault, - files: [], - poll: {}, - mediaDescriptions: {}, - visibility: scope, - contentType - } + const { postContentType: contentType, sensitiveByDefault } = this.$store.getters.mergedConfig - if (statusType === 'edit') { - const statusContentType = this.statusContentType || contentType statusParams = { type: statusType, refId, spoilerText: this.subject || '', - status: this.statusText || '', - nsfw: this.statusIsSensitive || !!sensitiveByDefault, - files: this.statusFiles || [], - poll: this.statusPoll || {}, - mediaDescriptions: this.statusMediaDescriptions || {}, - visibility: this.statusScope || scope, - contentType: statusContentType + status: statusText, + nsfw: !!sensitiveByDefault, + files: [], + poll: {}, + mediaDescriptions: {}, + visibility: scope, + contentType } - } - console.debug('type and ref:', [statusType, refId]) - - const maybeDraft = this.$store.state.drafts.drafts[this.draftId] - if (this.draftId && maybeDraft) { - console.debug('current draft:', maybeDraft) - statusParams = maybeDraft - } else { - const existingDrafts = this.$store.getters.draftsByTypeAndRefId(statusType, refId) - - console.debug('existing drafts:', existingDrafts) - if (existingDrafts.length) { - statusParams = existingDrafts[0] + if (statusType === 'edit') { + const statusContentType = this.statusContentType || contentType + statusParams = { + type: statusType, + refId, + spoilerText: this.subject || '', + status: this.statusText || '', + nsfw: this.statusIsSensitive || !!sensitiveByDefault, + files: this.statusFiles || [], + poll: this.statusPoll || {}, + mediaDescriptions: this.statusMediaDescriptions || {}, + visibility: this.statusScope || scope, + contentType: statusContentType + } } } @@ -683,6 +672,23 @@ const PostStatusForm = { } }) } + }, + getDraft (statusType, refId) { + console.debug('type and ref:', [statusType, refId]) + + const maybeDraft = this.$store.state.drafts.drafts[this.draftId] + if (this.draftId && maybeDraft) { + console.debug('current draft:', maybeDraft) + return maybeDraft + } else { + const existingDrafts = this.$store.getters.draftsByTypeAndRefId(statusType, refId) + + console.debug('existing drafts:', existingDrafts) + if (existingDrafts.length) { + return existingDrafts[0] + } + } + // No draft available, fall back } } } diff --git a/src/i18n/en.json b/src/i18n/en.json index b051f088..330d1f4b 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -189,7 +189,8 @@ "mobile_notifications": "Open notifications", "mobile_notifications": "Open notifications (there are unread ones)", "mobile_notifications_close": "Close notifications", - "announcements": "Announcements" + "announcements": "Announcements", + "drafts": "Drafts" }, "notifications": { "broken_favorite": "Unknown status, searching for it…", @@ -1154,5 +1155,9 @@ }, "unicode_domain_indicator": { "tooltip": "This domain contains non-ascii characters." + }, + "drafts": { + "drafts": "Drafts", + "continue": "Continue editing" } } diff --git a/src/modules/drafts.js b/src/modules/drafts.js index 465c9aad..81199c62 100644 --- a/src/modules/drafts.js +++ b/src/modules/drafts.js @@ -22,6 +22,9 @@ export const getters = { return (type, refId) => { return Object.values(state.drafts).filter(draft => draft.type === type && draft.refId === refId) } + }, + draftsArray (state) { + return Object.values(state.drafts) } }