refs #3771 Attach media files

This commit is contained in:
AkiraFukushima 2023-01-21 22:08:16 +09:00
parent 135ed92b56
commit a7d80c9d68
No known key found for this signature in database
GPG Key ID: B6E51BAC4DE1A957
1 changed files with 106 additions and 5 deletions

View File

@ -2,11 +2,18 @@
<div class="compose">
<el-form :model="form" class="compose-form">
<el-input v-model="form.status" type="textarea" :autosize="{ minRows: 2 }" :placeholder="$t('modals.new_toot.status')" />
<div class="preview" ref="previewRef">
<div class="image-wrapper" v-for="media in attachments" :key="media.id">
<img :src="media.preview_url" class="preview-image" />
<el-button class="remove-image" link @click="removeAttachment(media)"><font-awesome-icon icon="circle-xmark" /></el-button>
</div>
</div>
<div class="form-footer">
<el-button-group class="tool-buttons">
<el-button link size="default">
<el-button link size="default" @click="selectImage">
<font-awesome-icon icon="camera" />
</el-button>
<input name="image" type="file" class="image-input" ref="imageRef" @change="onChangeImage" />
<el-button link size="default" disabled>
<font-awesome-icon icon="square-poll-horizontal" />
</el-button>
@ -19,7 +26,7 @@
</el-button-group>
<div class="actions-group">
<span>500</span>
<el-button type="primary" @click="post"> {{ $t('modals.new_toot.toot') }} </el-button>
<el-button type="primary" @click="post" :loading="loading"> {{ $t('modals.new_toot.toot') }} </el-button>
</div>
</div>
</el-form>
@ -29,7 +36,7 @@
<script lang="ts">
import { defineComponent, reactive, computed, ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import generator, { MegalodonInterface } from 'megalodon'
import generator, { Entity, MegalodonInterface } from 'megalodon'
import { useStore } from '@/store'
import { MyWindow } from '~/src/types/global'
import { LocalAccount } from '~/src/types/localAccount'
@ -49,6 +56,9 @@ export default defineComponent({
const form = reactive({
status: ''
})
const imageRef = ref<any>(null)
const attachments = ref<Array<Entity.Attachment | Entity.AsyncAttachment>>([])
const loading = ref<boolean>(false)
onMounted(async () => {
const [a, s]: [LocalAccount, LocalServer] = await win.ipcRenderer.invoke('get-local-account', id.value)
@ -60,21 +70,69 @@ export default defineComponent({
if (!client.value) {
return
}
let options = {}
try {
await client.value.postStatus(form.status)
loading.value = true
if (attachments.value.length > 0) {
options = Object.assign(options, {
media_ids: attachments.value.map(m => m.id)
})
}
await client.value.postStatus(form.status, options)
clear()
} catch (err) {
console.error(err)
} finally {
loading.value = false
}
}
const clear = () => {
form.status = ''
attachments.value = []
}
const selectImage = () => {
imageRef?.value?.click()
}
const onChangeImage = async (e: Event) => {
const target = e.target as HTMLInputElement
const file = target.files?.item(0)
if (file === null || file === undefined) {
return
}
await uploadImage(file)
}
const uploadImage = async (file: File) => {
if (!client.value) {
return
}
try {
loading.value = true
const res = await client.value.uploadMedia(file)
attachments.value = [...attachments.value, res.data]
} catch (err) {
console.error(err)
} finally {
loading.value = false
}
}
const removeAttachment = async (attachment: Entity.Attachment | Entity.AsyncAttachment) => {
attachments.value = attachments.value.filter(e => e.id !== attachment.id)
}
return {
form,
post
post,
imageRef,
selectImage,
onChangeImage,
loading,
attachments,
removeAttachment
}
}
})
@ -96,6 +154,45 @@ export default defineComponent({
box-shadow: 0 0 0 1px var(--theme-border-color, var(--theme-border-color)) inset;
}
.preview {
box-sizing: border-box;
display: flex;
flex-flow: row wrap;
.image-wrapper {
position: relative;
display: flex;
min-width: 10%;
height: 80px;
margin: 4px;
.preview-image {
width: 80px;
height: 80px;
object-fit: cover;
border: 0;
border-radius: 8px;
}
.remove-image {
position: absolute;
top: 2px;
left: 2px;
padding: 0;
cursor: pointer;
font-size: 1.5rem;
.fa-icon {
font-size: 0.9rem;
width: auto;
height: 1em;
max-width: 100%;
max-height: 100%;
}
}
}
}
.form-footer {
display: flex;
justify-content: space-between;
@ -106,6 +203,10 @@ export default defineComponent({
button {
margin-right: 8px;
}
.image-input {
display: none;
}
}
.actions-group {