Make replying and mediaPlaying controlled

$refs is not a reliable way to deal with child components under
tree threading as it is not reactive, but the children may change at
any time. The only good way seems to be making these states aggregated on
the conversation component.

Ref: tree-threading
This commit is contained in:
Tusooa Zhu 2021-09-16 00:29:14 -04:00
parent cc5cff2038
commit 20880cdf0b
No known key found for this signature in database
GPG key ID: 7B467EDE43A08224
5 changed files with 72 additions and 10 deletions

View file

@ -99,6 +99,10 @@ const conversation = {
return this.otherRepliesButtonPosition === 'inside' return this.otherRepliesButtonPosition === 'inside'
}, },
suspendable () { suspendable () {
if (this.isTreeView) {
return Object.entries(this.statusContentProperties)
.every(([k, prop]) => !prop.replying && prop.mediaPlaying.length === 0)
}
if (this.$refs.statusComponent && this.$refs.statusComponent[0]) { if (this.$refs.statusComponent && this.$refs.statusComponent[0]) {
return this.$refs.statusComponent.every(s => s.suspendable) return this.$refs.statusComponent.every(s => s.suspendable)
} else { } else {
@ -303,14 +307,21 @@ const conversation = {
return this.conversation.reduce((a, k) => { return this.conversation.reduce((a, k) => {
const id = k.id const id = k.id
const props = (() => { const props = (() => {
if (this.statusContentPropertiesObject[id]) { const def = {
return this.statusContentPropertiesObject[id]
}
return {
showingTall: false, showingTall: false,
expandingSubject: false, expandingSubject: false,
showingLongSubject: false showingLongSubject: false,
isReplying: false,
mediaPlaying: []
} }
if (this.statusContentPropertiesObject[id]) {
return {
...def,
...this.statusContentPropertiesObject[id]
}
}
return def
})() })()
a[id] = props a[id] = props

View file

@ -78,9 +78,13 @@
:controlled-showing-tall="statusContentProperties[status.id].showingTall" :controlled-showing-tall="statusContentProperties[status.id].showingTall"
:controlled-expanding-subject="statusContentProperties[status.id].expandingSubject" :controlled-expanding-subject="statusContentProperties[status.id].expandingSubject"
:controlled-showing-long-subject="statusContentProperties[status.id].showingLongSubject" :controlled-showing-long-subject="statusContentProperties[status.id].showingLongSubject"
:controlled-replying="statusContentProperties[status.id].replying"
:controlled-media-playing="statusContentProperties[status.id].mediaPlaying"
:controlled-toggle-showing-tall="() => toggleStatusContentProperty(status.id, 'showingTall')" :controlled-toggle-showing-tall="() => toggleStatusContentProperty(status.id, 'showingTall')"
:controlled-toggle-expanding-subject="() => toggleStatusContentProperty(status.id, 'expandingSubject')" :controlled-toggle-expanding-subject="() => toggleStatusContentProperty(status.id, 'expandingSubject')"
:controlled-toggle-showing-long-subject="() => toggleStatusContentProperty(status.id, 'showingLongSubject')" :controlled-toggle-showing-long-subject="() => toggleStatusContentProperty(status.id, 'showingLongSubject')"
:controlled-toggle-replying="() => toggleStatusContentProperty(status.id, 'replying')"
:controlled-set-media-playing="(newVal) => toggleStatusContentProperty(status.id, 'mediaPlaying', newVal)"
@goto="setHighlight" @goto="setHighlight"
@toggleExpanded="toggleExpanded" @toggleExpanded="toggleExpanded"

View file

@ -61,6 +61,41 @@ library.add(
faAngleDoubleRight faAngleDoubleRight
) )
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[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: {
@ -108,20 +143,25 @@ const Status = {
'controlledToggleExpandingSubject', 'controlledToggleExpandingSubject',
'controlledShowingLongSubject', 'controlledShowingLongSubject',
'controlledToggleShowingLongSubject', 'controlledToggleShowingLongSubject',
'controlledReplying',
'controlledToggleReplying',
'controlledMediaPlaying',
'controlledSetMediaPlaying',
'dive' 'dive'
], ],
data () { data () {
return { return {
replying: false, uncontrolledReplying: false,
unmuted: false, unmuted: false,
userExpanded: false, userExpanded: false,
mediaPlaying: [], uncontrolledMediaPlaying: [],
suspendable: true, suspendable: true,
error: null, error: null,
headTailLinks: null headTailLinks: null
} }
}, },
computed: { computed: {
...controlledOrUncontrolledGetters(['replying', 'mediaPlaying']),
muteWords () { muteWords () {
return this.mergedConfig.muteWords return this.mergedConfig.muteWords
}, },
@ -351,7 +391,7 @@ const Status = {
this.error = undefined this.error = undefined
}, },
toggleReplying () { toggleReplying () {
this.replying = !this.replying controlledOrUncontrolledToggle(this, 'replying')
}, },
gotoOriginal (id) { gotoOriginal (id) {
if (this.inConversation) { if (this.inConversation) {
@ -371,10 +411,10 @@ const Status = {
return generateProfileLink(id, name, this.$store.state.instance.restrictedNicknames) return generateProfileLink(id, name, this.$store.state.instance.restrictedNicknames)
}, },
addMediaPlaying (id) { addMediaPlaying (id) {
this.mediaPlaying.push(id) controlledOrUncontrolledSet(this, 'mediaPlaying', this.mediaPlaying.concat(id))
}, },
removeMediaPlaying (id) { removeMediaPlaying (id) {
this.mediaPlaying = this.mediaPlaying.filter(mediaId => mediaId !== id) controlledOrUncontrolledSet(this, 'mediaPlaying', this.mediaPlaying.filter(mediaId => mediaId !== id))
}, },
setHeadTailLinks (headTailLinks) { setHeadTailLinks (headTailLinks) {
this.headTailLinks = headTailLinks this.headTailLinks = headTailLinks

View file

@ -80,6 +80,9 @@ const ThreadTree = {
}, },
toggleCurrentProp (name) { toggleCurrentProp (name) {
this.toggleStatusContentProperty(this.status.id, name) this.toggleStatusContentProperty(this.status.id, name)
},
setCurrentProp (name, newVal) {
this.setStatusContentProperty(this.status.id, name)
} }
} }
} }

View file

@ -22,9 +22,13 @@
:controlled-showing-tall="currentProp.showingTall" :controlled-showing-tall="currentProp.showingTall"
:controlled-expanding-subject="currentProp.expandingSubject" :controlled-expanding-subject="currentProp.expandingSubject"
:controlled-showing-long-subject="currentProp.showingLongSubject" :controlled-showing-long-subject="currentProp.showingLongSubject"
:controlled-replying="currentProp.replying"
:controlled-media-playing="currentProp.mediaPlaying"
:controlled-toggle-showing-tall="() => toggleCurrentProp('showingTall')" :controlled-toggle-showing-tall="() => toggleCurrentProp('showingTall')"
:controlled-toggle-expanding-subject="() => toggleCurrentProp('expandingSubject')" :controlled-toggle-expanding-subject="() => toggleCurrentProp('expandingSubject')"
:controlled-toggle-showing-long-subject="() => toggleCurrentProp('showingLongSubject')" :controlled-toggle-showing-long-subject="() => toggleCurrentProp('showingLongSubject')"
:controlled-toggle-replying="() => toggleCurrentProp('replying')"
:controlled-set-media-playing="(newVal) => setCurrentProp('mediaPlaying', newVal)"
:dive="dive ? () => dive(status.id) : undefined" :dive="dive ? () => dive(status.id) : undefined"
@goto="setHighlight" @goto="setHighlight"