Re-implement status detail
This commit is contained in:
parent
88575a0a47
commit
c9d43714e9
|
@ -14,7 +14,9 @@
|
|||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<div class="detail">detail</div>
|
||||
<el-aside class="detail" v-if="detail">
|
||||
<Detail />
|
||||
</el-aside>
|
||||
<modals></modals>
|
||||
<receive-drop v-show="droppableVisible"></receive-drop>
|
||||
</template>
|
||||
|
@ -29,7 +31,7 @@ import HeaderMenu from './TimelineSpace/HeaderMenu.vue'
|
|||
import Contents from './TimelineSpace/Contents.vue'
|
||||
import Compose from './TimelineSpace/Compose.vue'
|
||||
import Modals from './TimelineSpace/Modals.vue'
|
||||
import SideBar from './TimelineSpace/Contents/SideBar.vue'
|
||||
import Detail from './TimelineSpace/Detail.vue'
|
||||
import Mousetrap from 'mousetrap'
|
||||
import ReceiveDrop from './TimelineSpace/ReceiveDrop.vue'
|
||||
import { AccountLoadError } from '@/errors/load'
|
||||
|
@ -45,7 +47,7 @@ import { ACTION_TYPES as NEW_TOOT_ACTION } from '@/store/TimelineSpace/Modals/Ne
|
|||
|
||||
export default defineComponent({
|
||||
name: 'timeline-space',
|
||||
components: { SideMenu, HeaderMenu, Modals, Contents, ReceiveDrop, Compose, SideBar },
|
||||
components: { SideMenu, HeaderMenu, Modals, Contents, ReceiveDrop, Compose, Detail },
|
||||
setup() {
|
||||
const space = 'TimelineSpace'
|
||||
const store = useStore()
|
||||
|
@ -57,9 +59,7 @@ export default defineComponent({
|
|||
const contentsRef = ref<HTMLElement | null>(null)
|
||||
|
||||
const loading = computed(() => store.state.TimelineSpace.loading)
|
||||
const collapse = computed(() => store.state.TimelineSpace.SideMenu.collapse)
|
||||
// const modalOpened = computed(() => store.getters[`TimelineSpace/Modals/modalOpened`])
|
||||
// const shortcutEnabled = computed(() => !modalOpened.value)
|
||||
const detail = computed(() => route.query.detail?.toString() === 'true')
|
||||
|
||||
onMounted(async () => {
|
||||
store.dispatch(`TimelineSpace/Contents/SideBar/${SIDEBAR_ACTION.CLOSE}`)
|
||||
|
@ -167,10 +167,10 @@ export default defineComponent({
|
|||
|
||||
return {
|
||||
loading,
|
||||
collapse,
|
||||
droppableVisible,
|
||||
composeResized,
|
||||
contentsRef
|
||||
contentsRef,
|
||||
detail
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -183,6 +183,7 @@ export default defineComponent({
|
|||
|
||||
.header {
|
||||
padding: 0;
|
||||
height: auto;
|
||||
border-bottom: 1px solid var(--theme-border-color);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
<template>
|
||||
<el-container>
|
||||
<el-header class="header-wrapper">
|
||||
<div class="header">
|
||||
<div>
|
||||
<el-button class="header-action" link @click="back">
|
||||
<font-awesome-icon icon="chevron-left" />
|
||||
Back
|
||||
</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button class="header-action" link @click="close">
|
||||
<font-awesome-icon icon="xmark" />
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main class="main">
|
||||
<Status v-if="target() === 'status'" />
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import Status from './Detail/Status.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Detail',
|
||||
components: { Status },
|
||||
setup() {
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const close = () => {
|
||||
router.push({
|
||||
query: {}
|
||||
})
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
router.back()
|
||||
}
|
||||
|
||||
const target = () => {
|
||||
if (route.query.status_id?.toString()) {
|
||||
return 'status'
|
||||
} else if (route.query.account_id?.toString()) {
|
||||
return 'account'
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
close,
|
||||
back,
|
||||
target
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.header-wrapper {
|
||||
height: auto;
|
||||
border-bottom: 1px solid var(--theme-border-color);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px 0;
|
||||
line-height: 32px;
|
||||
|
||||
.header-action {
|
||||
color: var(--theme-secondary-color);
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,131 @@
|
|||
<template>
|
||||
<div class="status-detail">
|
||||
<div class="ancestors" v-for="mes in ancestors" :key="mes.id">
|
||||
<Toot
|
||||
v-if="account.account && account.server"
|
||||
:message="mes"
|
||||
:overlaid="modalOpened"
|
||||
:account="account.account"
|
||||
:server="account.server"
|
||||
@update="updateStatus"
|
||||
/>
|
||||
</div>
|
||||
<div class="original-status">
|
||||
<Toot
|
||||
v-if="status !== null && account.account && account.server"
|
||||
:message="status"
|
||||
:overlaid="modalOpened"
|
||||
:account="account.account"
|
||||
:server="account.server"
|
||||
@update="updateStatus"
|
||||
/>
|
||||
</div>
|
||||
<div class="descendants" v-for="mes in descendants" :key="mes.id">
|
||||
<Toot
|
||||
v-if="account.account && account.server"
|
||||
:message="mes"
|
||||
:overlaid="modalOpened"
|
||||
:account="account.account"
|
||||
:server="account.server"
|
||||
@update="updateStatus"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, onMounted, computed, reactive, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import generator, { MegalodonInterface, Entity } from 'megalodon'
|
||||
import Toot from '@/components/organisms/Toot.vue'
|
||||
import { useStore } from '@/store'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
import { LocalAccount } from '~/src/types/localAccount'
|
||||
import { LocalServer } from '~/src/types/localServer'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Status',
|
||||
components: { Toot },
|
||||
setup() {
|
||||
const win = (window as any) as MyWindow
|
||||
const store = useStore()
|
||||
const route = useRoute()
|
||||
|
||||
const client = ref<MegalodonInterface | null>(null)
|
||||
const id = computed(() => parseInt(route.params.id as string))
|
||||
const statusId = computed(() => route.query.status_id?.toString())
|
||||
const userAgent = computed(() => store.state.App.userAgent)
|
||||
const status = ref<Entity.Status | null>(null)
|
||||
const ancestors = ref<Array<Entity.Status>>([])
|
||||
const descendants = ref<Array<Entity.Status>>([])
|
||||
const account = reactive<{ account: LocalAccount | null; server: LocalServer | null }>({
|
||||
account: null,
|
||||
server: null
|
||||
})
|
||||
const modalOpened = computed(() => store.getters[`TimelineSpace/Modals/modalOpened`])
|
||||
|
||||
onMounted(async () => {
|
||||
const [a, s]: [LocalAccount, LocalServer] = await win.ipcRenderer.invoke('get-local-account', id.value)
|
||||
account.account = a
|
||||
account.server = s
|
||||
const c = generator(s.sns, s.baseURL, a.accessToken, userAgent.value)
|
||||
client.value = c
|
||||
|
||||
if (statusId.value) {
|
||||
const s = await c.getStatus(statusId.value)
|
||||
status.value = s.data
|
||||
const res = await c.getStatusContext(statusId.value)
|
||||
ancestors.value = res.data.ancestors
|
||||
descendants.value = res.data.descendants
|
||||
}
|
||||
})
|
||||
watch(statusId, async current => {
|
||||
if (client.value && current) {
|
||||
const s = await client.value.getStatus(current)
|
||||
status.value = s.data
|
||||
const res = await client.value.getStatusContext(current)
|
||||
ancestors.value = res.data.ancestors
|
||||
descendants.value = res.data.descendants
|
||||
}
|
||||
})
|
||||
|
||||
const update = (target: Entity.Status, s: Entity.Status) => {
|
||||
if (target.id === s.id) {
|
||||
return s
|
||||
} else if (target.reblog !== null && target.reblog.id == s.id) {
|
||||
return Object.assign(target, { reblog: s })
|
||||
} else {
|
||||
return target
|
||||
}
|
||||
}
|
||||
|
||||
const updateStatus = (s: Entity.Status) => {
|
||||
if (status.value) {
|
||||
status.value = update(status.value, s)
|
||||
}
|
||||
ancestors.value = ancestors.value.map(anc => update(anc, s))
|
||||
descendants.value = descendants.value.map(des => update(des, s))
|
||||
}
|
||||
|
||||
return {
|
||||
account,
|
||||
status,
|
||||
ancestors,
|
||||
descendants,
|
||||
updateStatus,
|
||||
modalOpened
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.status-detail {
|
||||
.original-status {
|
||||
.status {
|
||||
background-color: var(--theme-selected-background-color);
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -483,9 +483,7 @@ export default defineComponent({
|
|||
})
|
||||
}
|
||||
const openDetail = (message: Entity.Status) => {
|
||||
store.dispatch(`TimelineSpace/Contents/SideBar/${SIDEBAR_ACTION.OPEN_TOOT_COMPONENT}`)
|
||||
store.dispatch(`TimelineSpace/Contents/SideBar/TootDetail/${DETAIL_ACTION.CHANGE_TOOT}`, message)
|
||||
store.commit(`TimelineSpace/Contents/SideBar/${SIDEBAR_MUTATION.CHANGE_OPEN_SIDEBAR}`, true)
|
||||
router.push({ query: { detail: 'true', status_id: message.id } })
|
||||
}
|
||||
const openBrowser = (message: Entity.Status) => {
|
||||
;(window as any).shell.openExternal(message.url)
|
||||
|
|
Loading…
Reference in New Issue