Merge pull request #4098 from h3poteto/iss-4085

refs #4085 Show reply target message on compose
This commit is contained in:
AkiraFukushima 2023-02-08 23:15:32 +09:00 committed by GitHub
commit e42ad4dc3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 141 additions and 15 deletions

View File

@ -1,5 +1,6 @@
<template>
<div class="compose">
<Quote v-if="inReplyTo" :message="inReplyTo" @close="clearReply" />
<el-form :model="form" class="compose-form">
<el-input v-model="form.spoiler" class="spoiler" :placeholder="$t('modals.new_toot.cw')" v-if="cw" />
<el-input
@ -115,6 +116,7 @@ import { LocalServer } from '~/src/types/localServer'
import visibilityList from '~/src/constants/visibility'
import { MUTATION_TYPES } from '@/store/TimelineSpace/Compose'
import ReceiveDrop from './ReceiveDrop.vue'
import Quote from './Compose/Quote.vue'
type Expire = {
label: string
@ -123,7 +125,7 @@ type Expire = {
export default defineComponent({
name: 'Compose',
components: { Picker, ReceiveDrop },
components: { Picker, ReceiveDrop, Quote },
setup() {
const route = useRoute()
const store = useStore()
@ -248,7 +250,7 @@ export default defineComponent({
watch(inReplyTo, current => {
if (current) {
form.status = `@${current.acct} `
form.status = `@${current.account.acct} `
}
})
@ -411,6 +413,10 @@ export default defineComponent({
e.preventDefault()
}
const clearReply = () => {
store.commit(`${space}/${MUTATION_TYPES.CLEAR_REPLY_TO_ID}`)
}
return {
form,
post,
@ -434,7 +440,9 @@ export default defineComponent({
expiresList,
addPollOption,
removePollOption,
droppableVisible
droppableVisible,
inReplyTo,
clearReply
}
}
})

View File

@ -0,0 +1,125 @@
<template>
<div class="quote">
<div class="icon">
<FailoverImg :src="message.account.avatar" />
</div>
<div class="status">
<div class="header">
<div class="user">
<span class="display-name"><bdi v-html="username(message.account)"></bdi></span>
<span class="acct">{{ accountName(message.account) }}</span>
</div>
<div class="close">
<el-button link>
<font-awesome-icon icon="xmark" @click="close" />
</el-button>
</div>
</div>
<div class="body">
<div class="spoiler" v-html="emojiText(message.spoiler_text, message.emojis)"></div>
<div class="content" v-html="emojiText(message.content, message.emojis)"></div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, computed, PropType } from 'vue'
import { Entity } from 'megalodon'
import DisplayStyle from '~/src/constants/displayStyle'
import FailoverImg from '@/components/atoms/FailoverImg.vue'
import emojify from '@/utils/emojify'
import { useStore } from '@/store'
export default defineComponent({
name: 'Quote',
components: {
FailoverImg
},
props: {
message: {
type: Object as PropType<Entity.Status>,
required: true
}
},
emits: ['close'],
setup(_props, ctx) {
const store = useStore()
const displayNameStyle = computed(() => store.state.App.displayNameStyle)
const username = (account: Entity.Account) => {
switch (displayNameStyle.value) {
case DisplayStyle.DisplayNameAndUsername.value:
if (account.display_name !== '') {
return emojify(account.display_name, account.emojis)
} else {
return account.acct
}
case DisplayStyle.DisplayName.value:
if (account.display_name !== '') {
return emojify(account.display_name, account.emojis)
} else {
return account.acct
}
default:
return account.acct
}
}
const accountName = (account: Entity.Account) => {
switch (displayNameStyle.value) {
case DisplayStyle.DisplayNameAndUsername.value:
return `@${account.acct}`
case DisplayStyle.DisplayName.value:
default:
return ''
}
}
const emojiText = (content: string, emojis: Array<Entity.Emoji>) => {
return emojify(content, emojis)
}
const close = () => {
ctx.emit('close', null)
}
return {
username,
accountName,
emojiText,
close
}
}
})
</script>
<style lang="scss" scoped>
.quote {
display: flex;
border-radius: 4px;
overflow: hidden;
border: 1px solid var(--theme-border-color);
font-size: var(--base-font-size);
background-color: var(--theme-selected-background-color);
margin-bottom: 8px;
.icon {
img {
width: 40px;
height: 40px;
min-width: 40px;
min-height: 40px;
margin: 10px;
border-radius: 4px;
}
}
.status {
width: calc(100% - 40px);
.header {
display: flex;
justify-content: space-between;
}
}
}
</style>

View File

@ -41,7 +41,7 @@ export default defineComponent({
})
</script>
<style lang="scss">
<style lang="scss" scoped>
.quote {
display: flex;
border-radius: 4px;

View File

@ -504,10 +504,7 @@ export default defineComponent({
}
}
const openReply = () => {
store.commit(`TimelineSpace/Compose/${COMPOSE_MUTATION.SET_REPLY_TO_ID}`, {
acct: originalMessage.value.account.acct,
id: originalMessage.value.id
})
store.commit(`TimelineSpace/Compose/${COMPOSE_MUTATION.SET_REPLY_TO_ID}`, originalMessage.value)
}
const openDetail = (message: Entity.Status | null) => {
if (message) {

View File

@ -1,13 +1,9 @@
import { Module, MutationTree } from 'vuex'
import { RootState } from '@/store'
export type ReplyTo = {
acct: string
id: string
}
import { Entity } from 'megalodon'
export type ComposeState = {
inReplyTo: ReplyTo | null
inReplyTo: Entity.Status | null
}
const state = (): ComposeState => ({
@ -20,7 +16,7 @@ export const MUTATION_TYPES = {
}
const mutations: MutationTree<ComposeState> = {
[MUTATION_TYPES.SET_REPLY_TO_ID]: (state, inReplyTo: ReplyTo) => {
[MUTATION_TYPES.SET_REPLY_TO_ID]: (state, inReplyTo: Entity.Status) => {
state.inReplyTo = inReplyTo
},
[MUTATION_TYPES.CLEAR_REPLY_TO_ID]: state => {