Add dive functionality

This commit is contained in:
Tusooa Zhu 2021-08-07 14:11:34 -04:00
parent f0c717ce5f
commit 93bcee9516
No known key found for this signature in database
GPG key ID: 7B467EDE43A08224
5 changed files with 80 additions and 14 deletions

View file

@ -5,12 +5,14 @@ import ThreadTree from '../thread_tree/thread_tree.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAngleDoubleDown,
faAngleDoubleLeft
faAngleDoubleLeft,
faChevronLeft
} from '@fortawesome/free-solid-svg-icons'
library.add(
faAngleDoubleDown,
faAngleDoubleLeft
faAngleDoubleLeft,
faChevronLeft
)
// const debug = console.log
@ -53,7 +55,7 @@ const conversation = {
expanded: false,
threadDisplayStatusObject: {}, // id => 'showing' | 'hidden'
statusContentPropertiesObject: {},
diveRoot: null
diveHistory: []
}
},
props: [
@ -120,6 +122,14 @@ const conversation = {
return sortAndFilterConversation(conversation, this.status)
},
conversationDive () {
},
statusMap () {
return this.conversation.reduce((res, s) => {
res[s.id] = s
return res
}, {})
},
threadTree () {
const reverseLookupTable = this.conversation.reduce((table, status, index) => {
table[status.id] = index
@ -208,16 +218,19 @@ const conversation = {
return topLevel
},
showingTopLevel () {
if (this.diveRoot) {
return [this.conversation.filter(k => this.diveRoot === k.id)[0]]
if (this.canDive && this.diveRoot) {
return [this.statusMap[this.diveRoot]]
}
return this.topLevel
},
diveRoot () {
return this.diveHistory[this.diveHistory.length - 1]
},
diveDepth () {
return this.diveRoot ? this.depths[this.diveRoot] : 0
return this.canDive && this.diveRoot ? this.depths[this.diveRoot] : 0
},
diveMode () {
return !!this.diveRoot
return this.canDive && !!this.diveRoot
},
replies () {
let i = 1
@ -252,7 +265,7 @@ const conversation = {
if (this.threadDisplayStatusObject[id]) {
return this.threadDisplayStatusObject[id]
}
if (depth <= this.maxDepthToShowByDefault) {
if ((depth - this.diveDepth) <= this.maxDepthToShowByDefault) {
return 'showing'
} else {
return 'hidden'
@ -281,6 +294,9 @@ const conversation = {
a[id] = props
return a
}, {})
},
canDive () {
return this.isTreeView && this.isExpanded
}
},
components: {
@ -310,6 +326,25 @@ const conversation = {
}
},
methods: {
conversationFetched () {
if (!this.isExpanded) {
return
}
if (!this._diven) {
if (!this.threadDisplayStatus[this.statusId]) {
return
}
this._diven = true
const parentOrSelf = this.parentOrSelf(this.originalStatusId)
console.log(
'this.threadDisplayStatus ', this.threadDisplayStatus,
'this.statusId', this.statusId)
if (this.threadDisplayStatus[this.statusId] === 'hidden') {
this.diveIntoStatus(parentOrSelf)
}
}
},
fetchConversation () {
if (this.status) {
this.$store.state.api.backendInteractor.fetchConversation({ id: this.statusId })
@ -318,6 +353,7 @@ const conversation = {
this.$store.dispatch('addNewStatuses', { statuses: descendants })
this.setHighlight(this.originalStatusId)
})
.then(this.conversationFetched)
} else {
this.$store.state.api.backendInteractor.fetchStatus({ id: this.statusId })
.then((status) => {
@ -385,10 +421,23 @@ const conversation = {
this.setStatusContentProperty(id, name, !this.statusContentProperties[id][name])
},
diveIntoStatus (id) {
this.diveRoot = id
this.diveHistory = [...this.diveHistory, id]
},
diveBack () {
this.diveHistory = [...this.diveHistory.slice(0, this.diveHistory.length - 1)]
},
undive () {
this.diveRoot = null
this.diveHistory = []
},
statusById (id) {
return this.statusMap[id]
},
parentOf (id) {
const { in_reply_to_status_id: parentId } = this.statusById(id)
return parentId
},
parentOrSelf (id) {
return this.parentOf(id) || id
}
}
}

View file

@ -31,6 +31,19 @@
<FAIcon icon="angle-double-left" />
</i18n>
</div>
<div
v-if="diveMode"
class="conversation-undive-box"
>
<i18n
path="status.return_to_last_showing"
tag="button"
class="button-unstyled -link"
@click.prevent="diveBack"
>
<FAIcon icon="chevron-left" />
</i18n>
</div>
<div v-if="isTreeView">
<thread-tree
v-for="status in showingTopLevel"
@ -60,7 +73,7 @@
:status-content-properties="statusContentProperties"
:set-status-content-property="setStatusContentProperty"
:toggle-status-content-property="toggleStatusContentProperty"
:dive="diveIntoStatus"
:dive="canDive ? diveIntoStatus : undefined"
/>
</div>
<div v-if="isLinearView">

View file

@ -220,7 +220,7 @@
/>
</button>
<button
v-if="inThreadForest && replies && replies.length"
v-if="inThreadForest && replies && replies.length && toggleThreadDisplay"
class="button-unstyled"
:title="threadShowing ? $t('status.thread_hide') : $t('status.thread_show')"
:aria-expanded="threadShowing ? 'true' : 'false'"

View file

@ -1,6 +1,7 @@
import Status from '../status/status.vue'
const debug = console.log
// const debug = console.log
const debug = () => {}
const ThreadTree = {
components: {

View file

@ -74,7 +74,10 @@
class="button-unstyled -link thread-tree-show-replies-button"
@click.prevent="showThreadRecursively(status.id)"
>
<FAIcon place="icon" icon="angle-double-down" />
<FAIcon
place="icon"
icon="angle-double-down"
/>
<span place="text">
{{ $tc('status.thread_show_full', totalReplyCount[status.id], { numStatus: totalReplyCount[status.id], depth: totalReplyDepth[status.id] }) }}
</span>