commit: d9a9f97751b2f51f55848652e5126700aea0f3fe
parent 8c0deb905eb9860430d831d8d215e1eb6910f117
Author: Tusooa Zhu <tusooa@kazv.moe>
Date: Sat, 7 Aug 2021 18:53:23 -0400
Add simple tree style navigation
Diffstat:
8 files changed, 113 insertions(+), 20 deletions(-)
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
@@ -80,7 +80,10 @@ const conversation = {
return this.$store.state.config.conversationDisplay
},
isTreeView () {
- return this.displayStyle === 'tree'
+ return this.displayStyle === 'tree' || this.displayStyle === 'simple_tree'
+ },
+ treeViewIsSimple () {
+ return this.displayStyle === 'simple_tree'
},
isLinearView () {
return this.displayStyle === 'linear'
@@ -297,6 +300,14 @@ const conversation = {
},
canDive () {
return this.isTreeView && this.isExpanded
+ },
+ focused () {
+ return (id) => {
+ return (this.isExpanded) && id === this.highlight
+ }
+ },
+ maybeHighlight () {
+ return this.isExpanded ? this.highlight : null
}
},
components: {
@@ -316,6 +327,9 @@ const conversation = {
expanded (value) {
if (value) {
this.fetchConversation()
+ } else {
+ // if we collapse it, we should reset the dive
+ this._diven = false
}
},
virtualHidden (value) {
@@ -323,6 +337,9 @@ const conversation = {
'setVirtualHeight',
{ statusId: this.statusId, height: `${this.$el.clientHeight}px` }
)
+ },
+ highlight (value, old) {
+ console.log('highlight:', old, ' => ', value)
}
},
methods: {
@@ -341,7 +358,8 @@ const conversation = {
'this.threadDisplayStatus ', this.threadDisplayStatus,
'this.statusId', this.statusId)
if (this.threadDisplayStatus[this.statusId] === 'hidden') {
- this.diveIntoStatus(parentOrSelf)
+ this.diveIntoStatus(parentOrSelf, /* preventScroll */ true)
+ this.tryScrollTo(this.statusId)
}
}
},
@@ -365,18 +383,16 @@ const conversation = {
getReplies (id) {
return this.replies[id] || []
},
- focused (id) {
- return (this.isExpanded) && id === this.statusId
+ getHighlight () {
+ return this.isExpanded ? this.highlight : null
},
setHighlight (id) {
+ console.log('setHighlight', id)
if (!id) return
this.highlight = id
this.$store.dispatch('fetchFavsAndRepeats', id)
this.$store.dispatch('fetchEmojiReactionsBy', id)
},
- getHighlight () {
- return this.isExpanded ? this.highlight : null
- },
toggleExpanded () {
this.expanded = !this.expanded
},
@@ -420,14 +436,52 @@ const conversation = {
toggleStatusContentProperty (id, name) {
this.setStatusContentProperty(id, name, !this.statusContentProperties[id][name])
},
- diveIntoStatus (id) {
+ leastShowingAncestor (id) {
+ let cur = id
+ let parent = this.parentOf(cur)
+ while (cur) {
+ // if the parent is showing it means cur is visible
+ if (this.threadDisplayStatus[parent] === 'showing') {
+ return cur
+ }
+ parent = this.parentOf(parent)
+ cur = this.parentOf(cur)
+ }
+ // nothing found, fall back to toplevel
+ return topLevel[0].id
+ },
+ diveIntoStatus (id, preventScroll) {
this.diveHistory = [...this.diveHistory, id]
+ if (!preventScroll) {
+ this.goToCurrent()
+ }
},
diveBack () {
+ const oldHighlight = this.highlight
this.diveHistory = [...this.diveHistory.slice(0, this.diveHistory.length - 1)]
+ if (oldHighlight) {
+ this.tryScrollTo(this.leastShowingAncestor(oldHighlight))
+ }
},
undive () {
+ const oldHighlight = this.highlight
this.diveHistory = []
+ if (oldHighlight) {
+ this.tryScrollTo(this.leastShowingAncestor(oldHighlight))
+ } else {
+ this.goToCurrent()
+ }
+ },
+ tryScrollTo (id) {
+ if (this.isPage) {
+ // set statusId
+ this.$router.push({ name: 'conversation', params: { id } })
+ }
+
+ this.setHighlight(id)
+ },
+ goToCurrent () {
+ this.tryScrollTo(this.diveRoot || this.topLevel[0].id)
},
statusById (id) {
return this.statusMap[id]
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
@@ -61,10 +61,11 @@
:focused="focused"
:get-replies="getReplies"
- :get-highlight="getHighlight"
+ :highlight="maybeHighlight"
:set-highlight="setHighlight"
:toggle-expanded="toggleExpanded"
+ :simple="treeViewIsSimple"
:toggle-thread-display="toggleThreadDisplay"
:thread-display-status="threadDisplayStatus"
:show-thread-recursively="showThreadRecursively"
diff --git a/src/components/settings_modal/tabs/general_tab.js b/src/components/settings_modal/tabs/general_tab.js
@@ -20,7 +20,7 @@ const GeneralTab = {
value: mode,
label: this.$t(`settings.subject_line_${mode === 'masto' ? 'mastodon' : mode}`)
})),
- conversationDisplayOptions: ['tree', 'linear'].map(mode => ({
+ conversationDisplayOptions: ['tree', 'simple_tree', 'linear'].map(mode => ({
key: mode,
value: mode,
label: this.$t(`settings.conversation_display_${mode}`)
diff --git a/src/components/status/status.js b/src/components/status/status.js
@@ -97,6 +97,7 @@ const Status = {
'inProfile',
'profileUserId',
+ 'simpleTree',
'controlledThreadDisplayStatus',
'controlledToggleThreadDisplay',
@@ -379,10 +380,9 @@ const Status = {
},
toggleThreadDisplay () {
this.controlledToggleThreadDisplay()
- }
- },
- watch: {
- 'highlight': function (id) {
+ },
+ scrollIfHighlighted (highlightId) {
+ const id = highlightId
if (this.status.id === id) {
let rect = this.$el.getBoundingClientRect()
if (rect.top < 100) {
@@ -396,6 +396,14 @@ const Status = {
window.scrollBy(0, rect.bottom - window.innerHeight + 50)
}
}
+ }
+ },
+ mounted () {
+ this.scrollIfHighlighted(this.highlight)
+ },
+ watch: {
+ 'highlight': function (id) {
+ this.scrollIfHighlighted(id)
},
'status.repeat_num': function (num) {
// refetch repeats when repeat_num is changed in any way
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
@@ -220,7 +220,7 @@
/>
</button>
<button
- v-if="inThreadForest && replies && replies.length && toggleThreadDisplay"
+ v-if="inThreadForest && replies && replies.length && !simpleTree"
class="button-unstyled"
:title="threadShowing ? $t('status.thread_hide') : $t('status.thread_show')"
:aria-expanded="threadShowing ? 'true' : 'false'"
@@ -233,7 +233,7 @@
/>
</button>
<button
- v-if="dive"
+ v-if="dive && !simpleTree"
class="button-unstyled"
:title="$t('status.show_only_conversation_under_this')"
@click.prevent="dive"
diff --git a/src/components/thread_tree/thread_tree.js b/src/components/thread_tree/thread_tree.js
@@ -1,5 +1,16 @@
import Status from '../status/status.vue'
+import { library } from '@fortawesome/fontawesome-svg-core'
+import {
+ faAngleDoubleDown,
+ faAngleDoubleRight
+} from '@fortawesome/free-solid-svg-icons'
+
+library.add(
+ faAngleDoubleDown,
+ faAngleDoubleRight
+)
+
// const debug = console.log
const debug = () => {}
@@ -19,11 +30,12 @@ const ThreadTree = {
profileUserId: String,
focused: Function,
- getHighlight: Function,
+ highlight: String,
getReplies: Function,
setHighlight: Function,
toggleExpanded: Function,
+ simple: Boolean,
// to control display of the whole thread forest
toggleThreadDisplay: Function,
threadDisplayStatus: Object,
diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue
@@ -9,12 +9,13 @@
:show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]"
:focused="focused(status.id)"
:in-conversation="isExpanded"
- :highlight="getHighlight()"
+ :highlight="highlight"
:replies="getReplies(status.id)"
:in-profile="inProfile"
:profile-user-id="profileUserId"
class="conversation-status conversation-status-treeview status-fadein panel-body"
+ :simple-tree="simple"
:controlled-thread-display-status="threadDisplayStatus[status.id]"
:controlled-toggle-thread-display="() => toggleThreadDisplay(status.id)"
@@ -49,10 +50,11 @@
:focused="focused"
:get-replies="getReplies"
- :get-highlight="getHighlight"
+ :highlight="highlight"
:set-highlight="setHighlight"
:toggle-expanded="toggleExpanded"
+ :simple="simple"
:toggle-thread-display="toggleThreadDisplay"
:thread-display-status="threadDisplayStatus"
:show-thread-recursively="showThreadRecursively"
@@ -69,6 +71,22 @@
class="thread-tree-replies thread-tree-replies-hidden"
>
<i18n
+ v-if="simple"
+ tag="button"
+ path="status.thread_follow_with_icon"
+ class="button-unstyled -link thread-tree-show-replies-button"
+ @click.prevent="dive(status.id)"
+ >
+ <FAIcon
+ place="icon"
+ icon="angle-double-right"
+ />
+ <span place="text">
+ {{ $tc('status.thread_follow', totalReplyCount[status.id], { numStatus: totalReplyCount[status.id] }) }}
+ </span>
+ </i18n>
+ <i18n
+ v-else
tag="button"
path="status.thread_show_full_with_icon"
class="button-unstyled -link thread-tree-show-replies-button"
diff --git a/src/modules/instance.js b/src/modules/instance.js
@@ -53,7 +53,7 @@ const defaultState = {
theme: 'pleroma-dark',
virtualScrolling: true,
sensitiveByDefault: false,
- conversationDisplay: 'tree',
+ conversationDisplay: 'simple_tree',
// Nasty stuff
customEmoji: [],