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
このコミットが含まれているのは:
Tusooa Zhu 2021-09-16 00:29:14 -04:00
コミット 20880cdf0b
この署名に対応する既知のキーがデータベースに存在しません
GPGキーID: 7B467EDE43A08224
5個のファイルの変更72行の追加10行の削除

ファイルの表示

@ -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

ファイルの表示

@ -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"

ファイルの表示

@ -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

ファイルの表示

@ -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)
} }
} }
} }

ファイルの表示

@ -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"