diving deeper into refactoring threads

This commit is contained in:
Henry Jameson 2026-06-30 06:00:41 +03:00
commit 415844e3da
6 changed files with 32 additions and 93 deletions

View file

@ -105,9 +105,10 @@
:profile-user-id="profileUserId" :profile-user-id="profileUserId"
:simple-tree="treeViewIsSimple" :simple-tree="treeViewIsSimple"
:show-other-replies-as-button="showOtherRepliesButtonInsideStatus" :show-other-replies-as-button="showOtherRepliesButtonInsideStatus"
:dive="() => diveIntoStatus(status.id)" can-dive
@goto="setHighlight" @goto="setHighlight"
@dive="() => diveIntoStatus(status.id)"
@suspendable-state-change="onStatusSuspendStateChange" @suspendable-state-change="onStatusSuspendStateChange"
/> />
<div <div
@ -160,12 +161,13 @@
:toggle-expanded="toggleExpanded" :toggle-expanded="toggleExpanded"
:simple="treeViewIsSimple" :simple="treeViewIsSimple"
:toggle-thread-display="toggleThreadDisplay"
:thread-display-status="threadDisplayStatus" :thread-display-status="threadDisplayStatus"
:show-thread-recursively="showThreadRecursively" :show-thread-recursively="showThreadRecursively"
:total-reply-count="totalReplyCount" :total-reply-count="totalReplyCount"
:total-reply-depth="totalReplyDepth" :total-reply-depth="totalReplyDepth"
:dive="canDive ? diveIntoStatus : undefined"
:can-dive="canDive"
@dive="diveIntoStatus"
@suspendable-state-change="onStatusSuspendStateChange" @suspendable-state-change="onStatusSuspendStateChange"
/> />
</div> </div>

View file

@ -165,8 +165,8 @@ const Gallery = {
} else { } else {
this.$emit('pause') this.$emit('pause')
} }
} },
} },
} }
export default Gallery export default Gallery

View file

@ -75,44 +75,6 @@ library.add(
const camelCase = (name) => name.charAt(0).toUpperCase() + name.slice(1) const camelCase = (name) => name.charAt(0).toUpperCase() + name.slice(1)
const controlledOrUncontrolledGetters = (list) =>
list.reduce((res, name) => {
const camelized = camelCase(name)
const toggle = `controlledToggle${camelized}`
const controlledName = `controlled${camelized}`
const uncontrolledName = `uncontrolled${camelized}`
res[name] = function () {
return (this.$data[toggle] !== undefined ||
this.$props[toggle] !== undefined) &&
this[toggle]
? this[controlledName]
: this[uncontrolledName]
}
return res
}, {})
const controlledOrUncontrolledToggle = (obj, name) => {
const camelized = camelCase(name)
const toggle = `controlledToggle${camelized}`
const uncontrolledName = `uncontrolled${camelized}`
if (obj[toggle]) {
obj[toggle]()
} else {
obj[uncontrolledName] = !obj[uncontrolledName]
}
}
const controlledOrUncontrolledSet = (obj, name, val) => {
const camelized = camelCase(name)
const set = `controlledSet${camelized}`
const uncontrolledName = `uncontrolled${camelized}`
if (obj[set]) {
obj[set](val)
} else {
obj[uncontrolledName] = val
}
}
const Status = { const Status = {
name: 'Status', name: 'Status',
components: { components: {
@ -146,17 +108,22 @@ const Status = {
inProfile: Boolean, inProfile: Boolean,
inConversation: Boolean, inConversation: Boolean,
inQuote: Boolean, inQuote: Boolean,
canDive: Boolean,
profileUserId: String, profileUserId: String,
simpleTree: Boolean, simpleTree: Boolean,
showOtherRepliesAsButton: Boolean, showOtherRepliesAsButton: Boolean,
dive: Function, canDive: Boolean,
ignoreMute: Boolean, ignoreMute: Boolean,
controlledThreadDisplayStatus: String, threadDisplayStatus: String,
controlledToggleThreadDisplay: Function,
}, },
emits: ['goto', 'toggleExpanded', 'suspendableStateChange'], emits: [
'goto',
'dive',
'toggleExpanded',
'suspendableStateChange'
],
data() { data() {
return { return {
replying: false, replying: false,
@ -480,10 +447,10 @@ const Status = {
return !this.replying && this.mediaPlaying.size === 0 return !this.replying && this.mediaPlaying.size === 0
}, },
inThreadForest() { inThreadForest() {
return !!this.controlledThreadDisplayStatus return !!this.threadDisplayStatus
}, },
threadShowing() { threadShowing() {
return this.controlledThreadDisplayStatus === 'showing' return this.threadDisplayStatus === 'showing'
}, },
visibilityLocalized() { visibilityLocalized() {
return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility) return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility)

View file

@ -236,10 +236,10 @@
/> />
</button> </button>
<button <button
v-if="dive && !simpleTree" v-if="canDive && !simpleTree"
class="button-unstyled" class="button-unstyled"
:title="$t('status.show_only_conversation_under_this')" :title="$t('status.show_only_conversation_under_this')"
@click.prevent="dive" @click.prevent="$emit('dive')"
> >
<FAIcon <FAIcon
fixed-width fixed-width
@ -432,7 +432,7 @@
v-if="showOtherRepliesAsButton && replies.length > 1" v-if="showOtherRepliesAsButton && replies.length > 1"
class="button-unstyled -link" class="button-unstyled -link"
:title="$t('status.ancestor_follow', { numReplies: replies.length - 1 }, replies.length - 1)" :title="$t('status.ancestor_follow', { numReplies: replies.length - 1 }, replies.length - 1)"
@click.prevent="dive" @click.prevent="$emit('dive')"
> >
{{ $t('status.replies_list_with_others', { numReplies: replies.length - 1 }, replies.length - 1) }} {{ $t('status.replies_list_with_others', { numReplies: replies.length - 1 }, replies.length - 1) }}
</button> </button>

View file

@ -26,28 +26,14 @@ const ThreadTree = {
toggleExpanded: Function, toggleExpanded: Function,
simple: Boolean, simple: Boolean,
// to control display of the whole thread forest canDive: Boolean,
toggleThreadDisplay: Function,
threadDisplayStatus: Object, threadDisplayStatus: Object,
showThreadRecursively: Function, showThreadRecursively: Function,
totalReplyCount: Object, totalReplyCount: Object,
totalReplyDepth: Object, totalReplyDepth: Object,
dive: Function,
}, },
emits: ['suspendableStateChange'], emits: ['suspendableStateChange', 'dive'],
computed: { computed: {
suspendable() {
const selfSuspendable = this.$refs.statusComponent
? this.$refs.statusComponent.suspendable
: true
if (this.$refs.childComponent) {
return (
selfSuspendable &&
this.$refs.childComponent.every((s) => s.suspendable)
)
}
return selfSuspendable
},
reverseLookupTable() { reverseLookupTable() {
return this.conversation.reduce( return this.conversation.reduce(
(table, status, index) => { (table, status, index) => {
@ -72,21 +58,6 @@ const ThreadTree = {
statusById(id) { statusById(id) {
return this.conversation[this.reverseLookupTable[id]] return this.conversation[this.reverseLookupTable[id]]
}, },
collapseThread() {
/* no-op */
},
showThread() {
/* no-op */
},
showAllSubthreads() {
/* no-op */
},
toggleCurrentProp(name) {
this.toggleStatusContentProperty(this.status.id, name)
},
setCurrentProp(name) {
this.setStatusContentProperty(this.status.id, name)
},
}, },
} }

View file

@ -3,30 +3,29 @@
<Status <Status
:key="status.id" :key="status.id"
ref="statusComponent" ref="statusComponent"
:inline-expanded="collapsable && isExpanded"
:statusoid="status" :statusoid="status"
:replies="getReplies(status.id)"
:inline-expanded="collapsable && isExpanded"
:expandable="!isExpanded" :expandable="!isExpanded"
:show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]" :show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]"
:focused="isFocusedFunction(status.id)" :focused="isFocusedFunction(status.id)"
:in-conversation="isExpanded" :in-conversation="isExpanded"
:highlight="highlight" :highlight="highlight"
:replies="getReplies(status.id)"
:in-profile="inProfile" :in-profile="inProfile"
:profile-user-id="profileUserId" :profile-user-id="profileUserId"
class="conversation-status conversation-status-treeview status-fadein panel-body" class="conversation-status conversation-status-treeview status-fadein panel-body"
:simple-tree="simple" :simple-tree="simple"
:controlled-thread-display-status="threadDisplayStatus[status.id]" :thread-display-status="threadDisplayStatus[status.id]"
:controlled-toggle-thread-display="() => toggleThreadDisplay(status.id)"
:dive="dive ? () => dive(status.id) : undefined"
:can-dive="canDive"
@dive="$emit('dive', status.id)"
@goto="setHighlight" @goto="setHighlight"
@toggle-expanded="toggleExpanded" @toggle-expanded="toggleExpanded"
@suspendable-state-change="e => $emit('suspendableStateChange', e)" @suspendable-state-change="e => $emit('suspendableStateChange', e)"
/> />
<div <div
v-if="currentReplies.length && threadShowing" v-if="currentReplies.length > 0 && threadShowing"
class="thread-tree-replies" class="thread-tree-replies"
> >
<ThreadTree <ThreadTree
@ -50,13 +49,13 @@
:toggle-expanded="toggleExpanded" :toggle-expanded="toggleExpanded"
:simple="simple" :simple="simple"
:toggle-thread-display="toggleThreadDisplay"
:thread-display-status="threadDisplayStatus" :thread-display-status="threadDisplayStatus"
:show-thread-recursively="showThreadRecursively" :show-thread-recursively="showThreadRecursively"
:total-reply-count="totalReplyCount" :total-reply-count="totalReplyCount"
:total-reply-depth="totalReplyDepth" :total-reply-depth="totalReplyDepth"
:dive="dive"
:can-dive="canDive"
@dive="(e) => $emit('dive', e)"
@suspendable-state-change="e => $emit('suspendableStateChange', e)" @suspendable-state-change="e => $emit('suspendableStateChange', e)"
/> />
</div> </div>
@ -70,7 +69,7 @@
tag="button" tag="button"
keypath="status.thread_follow_with_icon" keypath="status.thread_follow_with_icon"
class="button-unstyled -link thread-tree-show-replies-button" class="button-unstyled -link thread-tree-show-replies-button"
@click.prevent="dive(status.id)" @click.prevent="$emit('dive', status.id)"
> >
<template #icon> <template #icon>
<FAIcon <FAIcon