pleroma-fe/src/components/thread_tree/thread_tree.js

122 lines
3 KiB
JavaScript
Raw Normal View History

import { useMergedConfigStore } from 'src/stores/merged_config.js'
2026-09-09 16:16:51 +03:00
import { useStatusesStore } from 'src/stores/statuses.js'
2021-08-07 18:53:23 -04:00
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAngleDoubleDown,
2026-01-06 16:22:52 +02:00
faAngleDoubleRight,
2021-08-07 18:53:23 -04:00
} from '@fortawesome/free-solid-svg-icons'
2026-01-06 16:22:52 +02:00
library.add(faAngleDoubleDown, faAngleDoubleRight)
2021-08-07 18:53:23 -04:00
2021-08-06 20:18:27 -04:00
const ThreadTree = {
2026-06-04 21:59:09 +03:00
components: {},
2021-08-06 20:18:27 -04:00
name: 'ThreadTree',
props: {
2026-08-18 18:00:36 +03:00
statusId: String,
depth: Number,
2021-08-06 20:18:27 -04:00
},
data() {
return {
resizeObserver: new ResizeObserver(this.updateVirtualHeight),
}
},
mounted() {
this.resizeObserver.observe(this.$refs.root)
},
unmounted() {
this.resizeObserver.disconnect()
},
emits: [
'heightChange',
'suspendableStateChange',
'goto',
'dive',
'toggleExpanded',
'showThreadRecursively',
],
inject: [
'conversation',
'focused',
'replies',
'threadDisplay',
'isExpanded',
'isPage',
],
2021-08-06 20:18:27 -04:00
computed: {
2026-09-09 16:16:51 +03:00
status() {
const status = useStatusesStore().allStatuses.get(this.statusId)
if (status.retweeted_status) {
return useStatusesStore().allStatuses.get(status.retweeted_status.id)
}
return status
},
2026-01-06 16:22:52 +02:00
currentReplies() {
2026-09-09 16:16:51 +03:00
return [...this.getReplies(this.status.id)].map(({ id }) => id)
},
simple() {
return !useMergedConfigStore().mergedConfig.conversationTreeAdvanced
2021-08-06 20:18:27 -04:00
},
2026-01-06 16:22:52 +02:00
threadShowing() {
2026-09-09 16:16:51 +03:00
return this.threadDisplay.get(this.status.id) === 'showing'
},
canDive() {
return this.isExpanded
},
totalReplyCount() {
const sizes = {}
const subTreeSizeFor = (id) => {
if (sizes[id]) {
return sizes[id]
}
sizes[id] =
1 +
[...this.getReplies(id)]
.map(({ id }) => id)
.map((cid) => subTreeSizeFor(cid))
.reduce((a, b) => a + b, 0)
return sizes[id]
}
this.conversation.map((k) => k.id).forEach(subTreeSizeFor)
return Object.keys(sizes).reduce((res, id) => {
res[id] = sizes[id] - 1 // exclude itself
return res
}, {})
},
totalReplyDepth() {
const depths = {}
const subTreeDepthFor = (id) => {
if (depths[id]) {
return depths[id]
}
depths[id] =
1 +
[...this.getReplies(id)]
.map(({ id }) => id)
.map((cid) => subTreeDepthFor(cid))
.reduce((a, b) => (a > b ? a : b), 0)
return depths[id]
}
this.conversation.map((k) => k.id).forEach(subTreeDepthFor)
return Object.keys(depths).reduce((res, id) => {
res[id] = depths[id] - 1 // exclude itself
return res
}, {})
2021-08-07 10:28:45 -04:00
},
2021-08-06 20:18:27 -04:00
},
methods: {
getReplies(id) {
return this.replies.get(id) ?? new Set()
},
updateVirtualHeight(e) {
const [entry] = e
this.$emit('heightChange', {
id: this.statusId,
height: entry.contentRect.height,
element: this.$refs.root,
})
},
},
2021-08-06 20:18:27 -04:00
}
export default ThreadTree