diff options
| author | Tusooa Zhu <tusooa@kazv.moe> | 2021-09-16 00:29:14 -0400 |
|---|---|---|
| committer | Tusooa Zhu <tusooa@kazv.moe> | 2022-03-07 19:19:31 -0500 |
| commit | 20880cdf0bd33d6c189549441ab0ee26b59abf6d (patch) | |
| tree | cb3165ad5a1dec3e1c59551ff978b493a4a82ff6 /src | |
| parent | cc5cff2038c067ceacd98f218bbcffa2a50069eb (diff) | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/conversation/conversation.js | 21 | ||||
| -rw-r--r-- | src/components/conversation/conversation.vue | 4 | ||||
| -rw-r--r-- | src/components/status/status.js | 50 | ||||
| -rw-r--r-- | src/components/thread_tree/thread_tree.js | 3 | ||||
| -rw-r--r-- | src/components/thread_tree/thread_tree.vue | 4 |
5 files changed, 72 insertions, 10 deletions
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 7f9f24b5..9aa7b183 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -99,6 +99,10 @@ const conversation = { return this.otherRepliesButtonPosition === 'inside' }, 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]) { return this.$refs.statusComponent.every(s => s.suspendable) } else { @@ -303,14 +307,21 @@ const conversation = { return this.conversation.reduce((a, k) => { const id = k.id const props = (() => { - if (this.statusContentPropertiesObject[id]) { - return this.statusContentPropertiesObject[id] - } - return { + const def = { showingTall: false, expandingSubject: false, - showingLongSubject: false + showingLongSubject: false, + isReplying: false, + mediaPlaying: [] + } + + if (this.statusContentPropertiesObject[id]) { + return { + ...def, + ...this.statusContentPropertiesObject[id] + } } + return def })() a[id] = props diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue index 0cd74539..4d64cf08 100644 --- a/src/components/conversation/conversation.vue +++ b/src/components/conversation/conversation.vue @@ -78,9 +78,13 @@ :controlled-showing-tall="statusContentProperties[status.id].showingTall" :controlled-expanding-subject="statusContentProperties[status.id].expandingSubject" :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-expanding-subject="() => toggleStatusContentProperty(status.id, 'expandingSubject')" :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" @toggleExpanded="toggleExpanded" diff --git a/src/components/status/status.js b/src/components/status/status.js index 700b9764..73fad45f 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -61,6 +61,41 @@ library.add( 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 = { name: 'Status', components: { @@ -108,20 +143,25 @@ const Status = { 'controlledToggleExpandingSubject', 'controlledShowingLongSubject', 'controlledToggleShowingLongSubject', + 'controlledReplying', + 'controlledToggleReplying', + 'controlledMediaPlaying', + 'controlledSetMediaPlaying', 'dive' ], data () { return { - replying: false, + uncontrolledReplying: false, unmuted: false, userExpanded: false, - mediaPlaying: [], + uncontrolledMediaPlaying: [], suspendable: true, error: null, headTailLinks: null } }, computed: { + ...controlledOrUncontrolledGetters(['replying', 'mediaPlaying']), muteWords () { return this.mergedConfig.muteWords }, @@ -351,7 +391,7 @@ const Status = { this.error = undefined }, toggleReplying () { - this.replying = !this.replying + controlledOrUncontrolledToggle(this, 'replying') }, gotoOriginal (id) { if (this.inConversation) { @@ -371,10 +411,10 @@ const Status = { return generateProfileLink(id, name, this.$store.state.instance.restrictedNicknames) }, addMediaPlaying (id) { - this.mediaPlaying.push(id) + controlledOrUncontrolledSet(this, 'mediaPlaying', this.mediaPlaying.concat(id)) }, removeMediaPlaying (id) { - this.mediaPlaying = this.mediaPlaying.filter(mediaId => mediaId !== id) + controlledOrUncontrolledSet(this, 'mediaPlaying', this.mediaPlaying.filter(mediaId => mediaId !== id)) }, setHeadTailLinks (headTailLinks) { this.headTailLinks = headTailLinks diff --git a/src/components/thread_tree/thread_tree.js b/src/components/thread_tree/thread_tree.js index 0e499b85..71e63725 100644 --- a/src/components/thread_tree/thread_tree.js +++ b/src/components/thread_tree/thread_tree.js @@ -80,6 +80,9 @@ const ThreadTree = { }, toggleCurrentProp (name) { this.toggleStatusContentProperty(this.status.id, name) + }, + setCurrentProp (name, newVal) { + this.setStatusContentProperty(this.status.id, name) } } } diff --git a/src/components/thread_tree/thread_tree.vue b/src/components/thread_tree/thread_tree.vue index dce03f27..cee223e8 100644 --- a/src/components/thread_tree/thread_tree.vue +++ b/src/components/thread_tree/thread_tree.vue @@ -22,9 +22,13 @@ :controlled-showing-tall="currentProp.showingTall" :controlled-expanding-subject="currentProp.expandingSubject" :controlled-showing-long-subject="currentProp.showingLongSubject" + :controlled-replying="currentProp.replying" + :controlled-media-playing="currentProp.mediaPlaying" :controlled-toggle-showing-tall="() => toggleCurrentProp('showingTall')" :controlled-toggle-expanding-subject="() => toggleCurrentProp('expandingSubject')" :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" @goto="setHighlight" |
