Add dive functionality

This commit is contained in:
Tusooa Zhu 2021-08-07 14:11:34 -04:00
parent 31c4300456
commit d15d24c11c
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 { library } from '@fortawesome/fontawesome-svg-core'
import { import {
faAngleDoubleDown, faAngleDoubleDown,
faAngleDoubleLeft faAngleDoubleLeft,
faChevronLeft
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
library.add( library.add(
faAngleDoubleDown, faAngleDoubleDown,
faAngleDoubleLeft faAngleDoubleLeft,
faChevronLeft
) )
// const debug = console.log // const debug = console.log
@ -53,7 +55,7 @@ const conversation = {
expanded: false, expanded: false,
threadDisplayStatusObject: {}, // id => 'showing' | 'hidden' threadDisplayStatusObject: {}, // id => 'showing' | 'hidden'
statusContentPropertiesObject: {}, statusContentPropertiesObject: {},
diveRoot: null diveHistory: []
} }
}, },
props: [ props: [
@ -120,6 +122,14 @@ const conversation = {
return sortAndFilterConversation(conversation, this.status) return sortAndFilterConversation(conversation, this.status)
}, },
conversationDive () {
},
statusMap () {
return this.conversation.reduce((res, s) => {
res[s.id] = s
return res
}, {})
},
threadTree () { threadTree () {
const reverseLookupTable = this.conversation.reduce((table, status, index) => { const reverseLookupTable = this.conversation.reduce((table, status, index) => {
table[status.id] = index table[status.id] = index
@ -208,16 +218,19 @@ const conversation = {
return topLevel return topLevel
}, },
showingTopLevel () { showingTopLevel () {
if (this.diveRoot) { if (this.canDive && this.diveRoot) {
return [this.conversation.filter(k => this.diveRoot === k.id)[0]] return [this.statusMap[this.diveRoot]]
} }
return this.topLevel return this.topLevel
}, },
diveRoot () {
return this.diveHistory[this.diveHistory.length - 1]
},
diveDepth () { diveDepth () {
return this.diveRoot ? this.depths[this.diveRoot] : 0 return this.canDive && this.diveRoot ? this.depths[this.diveRoot] : 0
}, },
diveMode () { diveMode () {
return !!this.diveRoot return this.canDive && !!this.diveRoot
}, },
replies () { replies () {
let i = 1 let i = 1
@ -252,7 +265,7 @@ const conversation = {
if (this.threadDisplayStatusObject[id]) { if (this.threadDisplayStatusObject[id]) {
return this.threadDisplayStatusObject[id] return this.threadDisplayStatusObject[id]
} }
if (depth <= this.maxDepthToShowByDefault) { if ((depth - this.diveDepth) <= this.maxDepthToShowByDefault) {
return 'showing' return 'showing'
} else { } else {
return 'hidden' return 'hidden'
@ -281,6 +294,9 @@ const conversation = {
a[id] = props a[id] = props
return a return a
}, {}) }, {})
},
canDive () {
return this.isTreeView && this.isExpanded
} }
}, },
components: { components: {
@ -310,6 +326,25 @@ const conversation = {
} }
}, },
methods: { 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 () { fetchConversation () {
if (this.status) { if (this.status) {
this.$store.state.api.backendInteractor.fetchConversation({ id: this.statusId }) this.$store.state.api.backendInteractor.fetchConversation({ id: this.statusId })
@ -318,6 +353,7 @@ const conversation = {
this.$store.dispatch('addNewStatuses', { statuses: descendants }) this.$store.dispatch('addNewStatuses', { statuses: descendants })
this.setHighlight(this.originalStatusId) this.setHighlight(this.originalStatusId)
}) })
.then(this.conversationFetched)
} else { } else {
this.$store.state.api.backendInteractor.fetchStatus({ id: this.statusId }) this.$store.state.api.backendInteractor.fetchStatus({ id: this.statusId })
.then((status) => { .then((status) => {
@ -385,10 +421,23 @@ const conversation = {
this.setStatusContentProperty(id, name, !this.statusContentProperties[id][name]) this.setStatusContentProperty(id, name, !this.statusContentProperties[id][name])
}, },
diveIntoStatus (id) { diveIntoStatus (id) {
this.diveRoot = id this.diveHistory = [...this.diveHistory, id]
},
diveBack () {
this.diveHistory = [...this.diveHistory.slice(0, this.diveHistory.length - 1)]
}, },
undive () { 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" /> <FAIcon icon="angle-double-left" />
</i18n> </i18n>
</div> </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"> <div v-if="isTreeView">
<thread-tree <thread-tree
v-for="status in showingTopLevel" v-for="status in showingTopLevel"
@ -60,7 +73,7 @@
:status-content-properties="statusContentProperties" :status-content-properties="statusContentProperties"
:set-status-content-property="setStatusContentProperty" :set-status-content-property="setStatusContentProperty"
:toggle-status-content-property="toggleStatusContentProperty" :toggle-status-content-property="toggleStatusContentProperty"
:dive="diveIntoStatus" :dive="canDive ? diveIntoStatus : undefined"
/> />
</div> </div>
<div v-if="isLinearView"> <div v-if="isLinearView">

View File

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

View File

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

View File

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