Add minimal draft management tool
This commit is contained in:
parent
d4444cd0b1
commit
dcd4587525
|
@ -25,6 +25,7 @@ import ListsTimeline from 'components/lists_timeline/lists_timeline.vue'
|
||||||
import ListsEdit from 'components/lists_edit/lists_edit.vue'
|
import ListsEdit from 'components/lists_edit/lists_edit.vue'
|
||||||
import NavPanel from 'src/components/nav_panel/nav_panel.vue'
|
import NavPanel from 'src/components/nav_panel/nav_panel.vue'
|
||||||
import AnnouncementsPage from 'components/announcements_page/announcements_page.vue'
|
import AnnouncementsPage from 'components/announcements_page/announcements_page.vue'
|
||||||
|
import Drafts from 'components/drafts/drafts.vue'
|
||||||
|
|
||||||
export default (store) => {
|
export default (store) => {
|
||||||
const validateAuthenticatedRoute = (to, from, next) => {
|
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: 'who-to-follow', path: '/who-to-follow', component: WhoToFollow, beforeEnter: validateAuthenticatedRoute },
|
||||||
{ name: 'about', path: '/about', component: About },
|
{ name: 'about', path: '/about', component: About },
|
||||||
{ name: 'announcements', path: '/announcements', component: AnnouncementsPage },
|
{ name: 'announcements', path: '/announcements', component: AnnouncementsPage },
|
||||||
|
{ name: 'drafts', path: '/drafts', component: Drafts },
|
||||||
{ name: 'user-profile', path: '/users/:name', component: UserProfile },
|
{ name: 'user-profile', path: '/users/:name', component: UserProfile },
|
||||||
{ name: 'legacy-user-profile', path: '/:name', component: UserProfile },
|
{ name: 'legacy-user-profile', path: '/:name', component: UserProfile },
|
||||||
{ name: 'lists', path: '/lists', component: Lists },
|
{ name: 'lists', path: '/lists', component: Lists },
|
||||||
|
|
|
@ -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
|
|
@ -0,0 +1,35 @@
|
||||||
|
<template>
|
||||||
|
<article class="Draft">
|
||||||
|
<div>
|
||||||
|
{{ draft.id }}
|
||||||
|
</div>
|
||||||
|
<div v-if="draft.inReplyToStatusId">
|
||||||
|
{{ draft.inReplyToStatusId }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="draft-content"
|
||||||
|
>
|
||||||
|
{{ draft.status }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
class="btn button-default"
|
||||||
|
:aria-expanded="editing"
|
||||||
|
@click.prevent.stop="toggleEditing"
|
||||||
|
>
|
||||||
|
{{ $t('drafts.continue') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div v-if="editing">
|
||||||
|
<PostStatusForm v-bind="postStatusFormProps" />
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./draft.js"></script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.Draft {
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -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
|
|
@ -0,0 +1,24 @@
|
||||||
|
<template>
|
||||||
|
<div class="Drafts">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<div class="title">
|
||||||
|
{{ $t('drafts.drafts') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<List
|
||||||
|
:items="drafts"
|
||||||
|
>
|
||||||
|
<template #item="{ item: draft }">
|
||||||
|
<Draft
|
||||||
|
:draft="draft"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./drafts.js"></script>
|
|
@ -19,7 +19,8 @@ import {
|
||||||
faInfoCircle,
|
faInfoCircle,
|
||||||
faStream,
|
faStream,
|
||||||
faList,
|
faList,
|
||||||
faBullhorn
|
faBullhorn,
|
||||||
|
faFilePen
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
|
@ -34,7 +35,8 @@ library.add(
|
||||||
faInfoCircle,
|
faInfoCircle,
|
||||||
faStream,
|
faStream,
|
||||||
faList,
|
faList,
|
||||||
faBullhorn
|
faBullhorn,
|
||||||
|
faFilePen
|
||||||
)
|
)
|
||||||
const NavPanel = {
|
const NavPanel = {
|
||||||
props: ['forceExpand', 'forceEditMode'],
|
props: ['forceExpand', 'forceEditMode'],
|
||||||
|
|
|
@ -78,6 +78,11 @@ export const ROOT_ITEMS = {
|
||||||
label: 'nav.announcements',
|
label: 'nav.announcements',
|
||||||
badgeGetter: 'unreadAnnouncementCount',
|
badgeGetter: 'unreadAnnouncementCount',
|
||||||
criteria: ['announcements']
|
criteria: ['announcements']
|
||||||
|
},
|
||||||
|
drafts: {
|
||||||
|
route: 'drafts',
|
||||||
|
icon: 'file-pen',
|
||||||
|
label: 'nav.drafts'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,58 +137,47 @@ const PostStatusForm = {
|
||||||
|
|
||||||
const [statusType, refId] = typeAndRefId({ replyTo: this.replyTo, statusId: this.statusId })
|
const [statusType, refId] = typeAndRefId({ replyTo: this.replyTo, statusId: this.statusId })
|
||||||
|
|
||||||
if (statusType === 'reply') {
|
let statusParams = this.getDraft(statusType, refId)
|
||||||
const currentUser = this.$store.state.users.currentUser
|
|
||||||
statusText = buildMentionsString({ user: this.repliedUser, attentions: this.attentions }, currentUser)
|
|
||||||
}
|
|
||||||
|
|
||||||
const scope = ((this.copyMessageScope && scopeCopy) || this.copyMessageScope === 'direct')
|
if (!statusParams) {
|
||||||
? this.copyMessageScope
|
if (statusType === 'reply') {
|
||||||
: this.$store.state.users.currentUser.default_scope
|
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 = {
|
const { postContentType: contentType, sensitiveByDefault } = this.$store.getters.mergedConfig
|
||||||
type: statusType,
|
|
||||||
refId,
|
|
||||||
spoilerText: this.subject || '',
|
|
||||||
status: statusText,
|
|
||||||
nsfw: !!sensitiveByDefault,
|
|
||||||
files: [],
|
|
||||||
poll: {},
|
|
||||||
mediaDescriptions: {},
|
|
||||||
visibility: scope,
|
|
||||||
contentType
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusType === 'edit') {
|
|
||||||
const statusContentType = this.statusContentType || contentType
|
|
||||||
statusParams = {
|
statusParams = {
|
||||||
type: statusType,
|
type: statusType,
|
||||||
refId,
|
refId,
|
||||||
spoilerText: this.subject || '',
|
spoilerText: this.subject || '',
|
||||||
status: this.statusText || '',
|
status: statusText,
|
||||||
nsfw: this.statusIsSensitive || !!sensitiveByDefault,
|
nsfw: !!sensitiveByDefault,
|
||||||
files: this.statusFiles || [],
|
files: [],
|
||||||
poll: this.statusPoll || {},
|
poll: {},
|
||||||
mediaDescriptions: this.statusMediaDescriptions || {},
|
mediaDescriptions: {},
|
||||||
visibility: this.statusScope || scope,
|
visibility: scope,
|
||||||
contentType: statusContentType
|
contentType
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
console.debug('type and ref:', [statusType, refId])
|
if (statusType === 'edit') {
|
||||||
|
const statusContentType = this.statusContentType || contentType
|
||||||
const maybeDraft = this.$store.state.drafts.drafts[this.draftId]
|
statusParams = {
|
||||||
if (this.draftId && maybeDraft) {
|
type: statusType,
|
||||||
console.debug('current draft:', maybeDraft)
|
refId,
|
||||||
statusParams = maybeDraft
|
spoilerText: this.subject || '',
|
||||||
} else {
|
status: this.statusText || '',
|
||||||
const existingDrafts = this.$store.getters.draftsByTypeAndRefId(statusType, refId)
|
nsfw: this.statusIsSensitive || !!sensitiveByDefault,
|
||||||
|
files: this.statusFiles || [],
|
||||||
console.debug('existing drafts:', existingDrafts)
|
poll: this.statusPoll || {},
|
||||||
if (existingDrafts.length) {
|
mediaDescriptions: this.statusMediaDescriptions || {},
|
||||||
statusParams = existingDrafts[0]
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,8 @@
|
||||||
"mobile_notifications": "Open notifications",
|
"mobile_notifications": "Open notifications",
|
||||||
"mobile_notifications": "Open notifications (there are unread ones)",
|
"mobile_notifications": "Open notifications (there are unread ones)",
|
||||||
"mobile_notifications_close": "Close notifications",
|
"mobile_notifications_close": "Close notifications",
|
||||||
"announcements": "Announcements"
|
"announcements": "Announcements",
|
||||||
|
"drafts": "Drafts"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"broken_favorite": "Unknown status, searching for it…",
|
"broken_favorite": "Unknown status, searching for it…",
|
||||||
|
@ -1154,5 +1155,9 @@
|
||||||
},
|
},
|
||||||
"unicode_domain_indicator": {
|
"unicode_domain_indicator": {
|
||||||
"tooltip": "This domain contains non-ascii characters."
|
"tooltip": "This domain contains non-ascii characters."
|
||||||
|
},
|
||||||
|
"drafts": {
|
||||||
|
"drafts": "Drafts",
|
||||||
|
"continue": "Continue editing"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@ export const getters = {
|
||||||
return (type, refId) => {
|
return (type, refId) => {
|
||||||
return Object.values(state.drafts).filter(draft => draft.type === type && draft.refId === refId)
|
return Object.values(state.drafts).filter(draft => draft.type === type && draft.refId === refId)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
draftsArray (state) {
|
||||||
|
return Object.values(state.drafts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue