Compare commits

..

4 commits

Author SHA1 Message Date
Henry Jameson
d679642a19 Merge branch 'drafts-improvements' into shigusegubu-themes3 2024-12-30 03:10:42 +02:00
Henry Jameson
68e8a24f18 a bit clearer draft editing flow, partially divorced menu-item from list-item 2024-12-30 03:10:11 +02:00
Henry Jameson
8657c820bd include attachments in draft 2024-12-30 02:07:49 +02:00
Henry Jameson
cc922029fb resize button to compensate for added width of dropdown 2024-12-30 01:22:17 +02:00
8 changed files with 121 additions and 31 deletions

View file

@ -390,6 +390,20 @@ nav {
}
}
.menu-item {
line-height: var(--__line-height);
font-family: inherit;
font-weight: 400;
font-size: 100%;
cursor: pointer;
a,
button:not(.button-default) {
color: var(--text);
font-size: 100%;
}
}
.menu-item,
.list-item {
display: block;
@ -397,10 +411,6 @@ nav {
border: none;
outline: none;
text-align: initial;
font-size: inherit;
font-family: inherit;
font-weight: 400;
cursor: pointer;
color: inherit;
clear: both;
position: relative;
@ -410,7 +420,6 @@ nav {
border-width: 0;
border-top-width: 1px;
width: 100%;
line-height: var(--__line-height);
padding: var(--__vertical-gap) var(--__horizontal-gap);
background: transparent;
@ -450,10 +459,8 @@ nav {
border: none;
outline: none;
display: inline;
font-size: 100%;
font-family: inherit;
line-height: unset;
color: var(--text);
}
&:first-child {

View file

@ -2,13 +2,16 @@ import PostStatusForm from 'src/components/post_status_form/post_status_form.vue
import EditStatusForm from 'src/components/edit_status_form/edit_status_form.vue'
import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
import StatusContent from 'src/components/status_content/status_content.vue'
import Gallery from 'src/components/gallery/gallery.vue'
import { cloneDeep } from 'lodash'
const Draft = {
components: {
PostStatusForm,
EditStatusForm,
ConfirmModal,
StatusContent
StatusContent,
Gallery
},
props: {
draft: {
@ -18,6 +21,7 @@ const Draft = {
},
data () {
return {
referenceDraft: cloneDeep(this.draft),
editing: false,
showingConfirmDialog: false
}
@ -32,6 +36,11 @@ const Draft = {
return {}
}
},
safeToSave () {
return this.draft.status ||
this.draft.files?.length ||
this.draft.hasPoll
},
postStatusFormProps () {
return {
draftId: this.draft.id,
@ -40,6 +49,28 @@ const Draft = {
},
refStatus () {
return this.draft.refId ? this.$store.state.statuses.allStatusesObject[this.draft.refId] : undefined
},
localCollapseSubjectDefault () {
return this.$store.getters.mergedConfig.collapseMessageWithSubject
},
nsfwClickthrough () {
if (!this.draft.nsfw) {
return false
}
if (this.draft.summary && this.localCollapseSubjectDefault) {
return false
}
return true
}
},
watch: {
editing (newVal) {
if (newVal) return
if (this.safeToSave) {
this.$store.dispatch('addOrSaveDraft', { draft: this.draft })
} else {
this.$store.dispatch('addOrSaveDraft', { draft: this.referenceDraft })
}
}
},
methods: {

View file

@ -26,15 +26,30 @@
:compact="true"
/>
</div>
<p>{{ draft.status }}</p>
<div class="status-preview">
<p>{{ draft.status }}</p>
<gallery
v-if="draft.files?.length !== 0"
class="attachments media-body"
:compact="true"
:nsfw="nsfwClickthrough"
:attachments="draft.files"
:limit="1"
size="small"
@play="$emit('mediaplay', attachment.id)"
@pause="$emit('mediapause', attachment.id)"
/>
</div>
</div>
<div v-if="editing">
<PostStatusForm
v-if="draft.type !== 'edit'"
:disable-draft="true"
v-bind="postStatusFormProps"
/>
<EditStatusForm
v-else
:disable-draft="true"
:params="postStatusFormProps"
/>
</div>
@ -53,11 +68,10 @@
<div class="actions">
<button
class="btn button-default"
:class="{ toggled: editing }"
:aria-expanded="editing"
@click.prevent.stop="toggleEditing"
>
{{ $t('drafts.continue') }}
{{ editing ? $t('drafts.save') : $t('drafts.continue') }}
</button>
<button
class="btn button-default"
@ -73,11 +87,32 @@
<style lang="scss">
.Draft {
position: relative;
line-height: 1.1;
font-size: initial;
a {
color: var(--link);
}
.status-content {
padding: 0.5em;
margin: 0.5em 0;
}
.status-preview {
display: grid;
grid-template-columns: 1fr 10em;
grid-gap: 0.5em;
max-width: 100%;
p {
word-wrap: break-word;
white-space: normal;
overflow-x: hidden;
}
}
.actions {
display: flex;
flex-direction: row;
@ -87,7 +122,6 @@
flex: 1;
margin-left: 1em;
margin-right: 1em;
max-width: 10em;
}
}
}

View file

@ -16,6 +16,7 @@
>
<template #item="{ item: draft }">
<Draft
class="draft"
:draft="draft"
/>
</template>
@ -26,3 +27,9 @@
</template>
<script src="./drafts.js"></script>
<style lang="scss">
.draft {
margin: 1em 0;
}
</style>

View file

@ -118,7 +118,8 @@ const PostStatusForm = {
'resize',
'mediaplay',
'mediapause',
'can-close'
'can-close',
'update'
],
components: {
MediaUpload,
@ -218,7 +219,7 @@ const PostStatusForm = {
emojiInputShown: false,
idempotencyKey: '',
saveInhibited: true,
savable: false
saveable: false
}
},
computed: {
@ -343,7 +344,7 @@ const PostStatusForm = {
return this.$store.getters.mergedConfig.autoSaveDraft
},
autoSaveState () {
if (this.savable) {
if (this.saveable) {
return this.$t('post_status.auto_save_saving')
} else if (this.newStatus.id) {
return this.$t('post_status.auto_save_saved')
@ -363,7 +364,7 @@ const PostStatusForm = {
this.statusChanged()
}
},
savable (val) {
saveable (val) {
// https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#usage_notes
// MDN says we'd better add the beforeunload event listener only when needed, and remove it when it's no longer needed
if (val) {
@ -382,7 +383,7 @@ const PostStatusForm = {
this.autoPreview()
this.updateIdempotencyKey()
this.debouncedMaybeAutoSaveDraft()
this.savable = true
this.saveable = true
this.saveInhibited = false
},
clearStatus () {
@ -411,7 +412,7 @@ const PostStatusForm = {
el.style.height = undefined
this.error = null
if (this.preview) this.previewStatus()
this.savable = false
this.saveable = false
},
async postStatus (event, newStatus, opts = {}) {
if (this.posting && !this.optimisticPosting) { return }
@ -754,13 +755,13 @@ const PostStatusForm = {
if (this.newStatus.id !== id) {
this.newStatus.id = id
}
this.savable = false
this.saveable = false
})
} else if (this.newStatus.id) {
// There is a draft, but there is nothing in it, clear it
return this.abandonDraft()
.then(() => {
this.savable = false
this.saveable = false
})
}
}
@ -788,7 +789,7 @@ const PostStatusForm = {
// No draft available, fall back
},
requestClose () {
if (!this.savable) {
if (!this.saveable) {
this.$emit('can-close')
} else {
this.$refs.draftCloser.requestClose()

View file

@ -5,14 +5,31 @@
margin-bottom: 0.5em;
}
.more-post-actions {
height: 100%;
.btn {
height: 100%;
}
}
.form-bottom {
display: flex;
justify-content: space-between;
padding: 0.5em;
height: 2.5em;
.post-button {
.post-button-group {
width: 10em;
display: flex;
.post-button {
flex: 1 0 auto;
}
.more-post-actions {
flex: 0 0 auto;
}
}
p {
@ -22,14 +39,6 @@
}
}
.more-post-actions {
height: 100%;
.btn {
height: 100%;
}
}
.form-bottom-left {
display: flex;
flex: 1;

View file

@ -302,7 +302,7 @@
<FAIcon icon="poll-h" />
</button>
</div>
<div class="btn-group">
<div class="btn-group post-button-group">
<button
class="btn button-default post-button"
:disabled="isOverLengthLimit || posting || uploadingFiles || disableSubmit"

View file

@ -1515,6 +1515,7 @@
"drafts": "Drafts",
"no_drafts": "You have no drafts",
"continue": "Continue composing",
"save": "Save without posting",
"abandon": "Abandon draft",
"abandon_confirm_title": "Abandon confirmation",
"abandon_confirm": "Do you really want to abandon this draft?",