logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
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:

Msrc/components/conversation/conversation.js70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/components/conversation/conversation.vue3++-
Msrc/components/settings_modal/tabs/general_tab.js2+-
Msrc/components/status/status.js16++++++++++++----
Msrc/components/status/status.vue4++--
Msrc/components/thread_tree/thread_tree.js14+++++++++++++-
Msrc/components/thread_tree/thread_tree.vue22++++++++++++++++++++--
Msrc/modules/instance.js2+-
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: [],