From d9a9f97751b2f51f55848652e5126700aea0f3fe Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sat, 7 Aug 2021 18:53:23 -0400 Subject: [PATCH] Add simple tree style navigation --- src/components/conversation/conversation.js | 70 ++++++++++++++++--- src/components/conversation/conversation.vue | 3 +- .../settings_modal/tabs/general_tab.js | 2 +- src/components/status/status.js | 16 +++-- src/components/status/status.vue | 4 +- src/components/thread_tree/thread_tree.js | 14 +++- src/components/thread_tree/thread_tree.vue | 22 +++++- src/modules/instance.js | 2 +- 8 files changed, 113 insertions(+), 20 deletions(-) diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index b2af1d6c..a1991888 100644 --- 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 index 99bc7bcc..0ffd8c37 100644 --- 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 index abe8f6f7..c43abe8a 100644 --- 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 index f119f42e..15c2d029 100644 --- 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 index 47d35de8..e4812711 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -220,7 +220,7 @@ />