various fixes, mainly for tree view

This commit is contained in:
Henry Jameson 2026-09-09 16:16:51 +03:00
commit bb55776c37
7 changed files with 77 additions and 60 deletions

View file

@ -40,24 +40,6 @@
/* stylelint-enable declaration-no-important */ /* stylelint-enable declaration-no-important */
} }
.thread-ancestor-dive-box {
padding-left: var(--status-margin);
border-bottom: 1px solid var(--border);
border-radius: 0;
/* Make the button stretch along the whole row */
&,
&-inner {
display: flex;
align-items: stretch;
flex-direction: column;
}
}
.thread-ancestor-dive-box-inner {
padding: var(--status-margin);
}
.thread-ancestors + .thread-tree > .conversation-status { .thread-ancestors + .thread-tree > .conversation-status {
border-top: 1px solid var(--border); border-top: 1px solid var(--border);
} }

View file

@ -105,7 +105,7 @@
:replies="getReplies(element.status.id)" :replies="getReplies(element.status.id)"
:focused="focused === element.status.id" :focused="focused === element.status.id"
can-dive conversation-rank="ancestor"
@goto="setFocused" @goto="setFocused"
@dive="diveIntoStatus(element.status.id)" @dive="diveIntoStatus(element.status.id)"
@ -117,33 +117,6 @@
class="virtual-spacer" class="virtual-spacer"
:style="{ height: element.height + 'px' }" :style="{ height: element.height + 'px' }"
/> />
<div
v-if="shouldShowOtherRepliesButton && getReplies(status.id).size > 1"
class="thread-ancestor-dive-box"
>
<div
class="thread-ancestor-dive-box-inner"
>
<i18n-t
tag="button"
scope="global"
keypath="status.ancestor_follow_with_icon"
class="button-unstyled -link thread-tree-show-replies-button"
@click.prevent="diveIntoStatus(status.id)"
>
<template #icon>
<FAIcon
icon="angle-double-right"
/>
</template>
<template #text>
<span>
{{ $t('status.ancestor_follow', { numReplies: getReplies(status.id).size - 1 }) }}
</span>
</template>
</i18n-t>
</div>
</div>
</article> </article>
</div> </div>
<div <div
@ -186,9 +159,9 @@
<Status <Status
v-if="element.type === 'status'" v-if="element.type === 'status'"
class="conversation-status" class="conversation-status"
:class="getStatusClasses(status)" :class="getStatusClasses(element.status)"
:status-id="element.status.id" :status-id="element.status.id"
:replies="getReplies(status.id)" :replies="getReplies(element.status.id)"
:focused="focused === element.id || focused === element.status.retweeted_status?.id" :focused="focused === element.id || focused === element.status.retweeted_status?.id"

View file

@ -107,6 +107,10 @@ const Status = {
ignoreMute: Boolean, ignoreMute: Boolean,
threadDisplayState: String, threadDisplayState: String,
conversationRank: {
type: String,
default: 'linear',
},
}, },
emits: [ emits: [
'goto', 'goto',
@ -116,9 +120,22 @@ const Status = {
'heightChange', 'heightChange',
], ],
inject: { inject: {
profileUserId: { default: null }, profileUserId: {
isPage: { default: false }, type: String,
isExpanded: { default: false }, default: null,
},
isPage: {
type: Boolean,
default: false,
},
isExpanded: {
type: Boolean,
default: false,
},
expandable: {
type: Boolean,
default: false,
},
}, },
data() { data() {
return { return {
@ -134,6 +151,12 @@ const Status = {
useScrobblesStore().getLatestScrobble(this.status.user.id) useScrobblesStore().getLatestScrobble(this.status.user.id)
}, },
computed: { computed: {
rootClasses() {
return [
{'-focused': this.focused, '-conversation': !this.isPage && this.isExpanded },
`-conversation-rank-${this.conversationRank}`,
]
},
// Whatever we're given to work with // Whatever we're given to work with
status() { status() {
return this.statusoid ?? useStatusesStore().allStatuses.get(this.statusId) return this.statusoid ?? useStatusesStore().allStatuses.get(this.statusId)
@ -173,9 +196,12 @@ const Status = {
simpleTree() { simpleTree() {
return !this.mergedConfig.conversationTreeAdvanced return !this.mergedConfig.conversationTreeAdvanced
}, },
showOtherRepliesAsButton() { showOtherRepliesInside() {
return this.mergedConfig.conversationOtherRepliesButton === 'inside' return this.mergedConfig.conversationOtherRepliesButton === 'inside'
}, },
showOtherRepliesBelow() {
return this.mergedConfig.conversationOtherRepliesButton === 'below'
},
showReasonMutedThread() { showReasonMutedThread() {
return ( return (
(this.mainStatus.thread_muted || this.repeatStatus?.thread_muted) && (this.mainStatus.thread_muted || this.repeatStatus?.thread_muted) &&

View file

@ -3,6 +3,8 @@
white-space: normal; white-space: normal;
overflow-wrap: break-word; overflow-wrap: break-word;
text-wrap: pretty; text-wrap: pretty;
display: flex;
flex-direction: column;
&:hover { &:hover {
--_still-image-img-visibility: visible; --_still-image-img-visibility: visible;
@ -281,6 +283,10 @@
margin-top: var(--status-margin); margin-top: var(--status-margin);
} }
.status-action-buttons {
margin-top: var(--status-margin);
}
.muted { .muted {
padding: 0.25em 0.6em; padding: 0.25em 0.6em;
height: 1.2em; height: 1.2em;
@ -372,7 +378,9 @@
} }
} }
.status-action-buttons { .thread-tree-show-replies-button {
margin-top: var(--status-margin); display: block;
padding: var(--status-margin);
padding-left: var(--status-margin);
} }
} }

View file

@ -3,7 +3,7 @@
v-if="!hideStatus" v-if="!hideStatus"
ref="root" ref="root"
class="Status" class="Status"
:class="[{ '-focused': focused }, { '-conversation': !isPage && isExpanded }]" :class="rootClasses"
> >
<div <div
v-if="error" v-if="error"
@ -427,7 +427,7 @@
class="replies" class="replies"
> >
<button <button
v-if="showOtherRepliesAsButton && replies.size > 1" v-if="showOtherRepliesInside && replies.size > 1"
class="button-unstyled -link" class="button-unstyled -link"
:title="$t('status.ancestor_follow', { numReplies: replies.size - 1 }, replies.size - 1)" :title="$t('status.ancestor_follow', { numReplies: replies.size - 1 }, replies.size - 1)"
@click.prevent="$emit('dive')" @click.prevent="$emit('dive')"
@ -548,6 +548,25 @@
@close-accepted="closeReplyForm" @close-accepted="closeReplyForm"
/> />
</div> </div>
<i18n-t
v-if="inConversation && conversationRank === 'ancestor' && !isPreview && showOtherRepliesBelow && replies?.size > 1"
tag="button"
scope="global"
keypath="status.ancestor_follow_with_icon"
class="button-unstyled -link thread-tree-show-replies-button"
@click.prevent="$emit('dive')"
>
<template #icon>
<FAIcon
icon="angle-double-right"
/>
</template>
<template #text>
<span>
{{ $t('status.ancestor_follow', { numReplies: replies.size - 1 }) }}
</span>
</template>
</i18n-t>
</template> </template>
</div> </div>
</template> </template>

View file

@ -1,4 +1,5 @@
import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useStatusesStore } from 'src/stores/statuses.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
@ -43,14 +44,21 @@ const ThreadTree = {
'isPage', 'isPage',
], ],
computed: { computed: {
status() {
const status = useStatusesStore().allStatuses.get(this.statusId)
if (status.retweeted_status) {
return useStatusesStore().allStatuses.get(status.retweeted_status.id)
}
return status
},
currentReplies() { currentReplies() {
return [...this.getReplies(this.statusId)].map(({ id }) => id) return [...this.getReplies(this.status.id)].map(({ id }) => id)
}, },
simple() { simple() {
return !useMergedConfigStore().mergedConfig.conversationTreeAdvanced return !useMergedConfigStore().mergedConfig.conversationTreeAdvanced
}, },
threadShowing() { threadShowing() {
return this.threadDisplay.get(this.statusId) === 'showing' return this.threadDisplay.get(this.status.id) === 'showing'
}, },
canDive() { canDive() {
return this.isExpanded return this.isExpanded

View file

@ -10,6 +10,7 @@
:replies="getReplies(statusId)" :replies="getReplies(statusId)"
:focused="focused === statusId" :focused="focused === statusId"
:conversation-rank="depth === 0 ? 'current' : 'child'"
:thread-display-state="threadDisplay.get(statusId)" :thread-display-state="threadDisplay.get(statusId)"
@dive="$emit('dive', statusId)" @dive="$emit('dive', statusId)"
@ -53,7 +54,7 @@
</template> </template>
<template #text> <template #text>
<span> <span>
{{ $t('status.thread_follow', { numStatus: totalReplyCount[statusId] }, totalReplyCount[statusId]) }} {{ $t('status.thread_follow', { numStatus: totalReplyCount[status.id] }, totalReplyCount[status.id]) }}
</span> </span>
</template> </template>
</i18n-t> </i18n-t>
@ -72,7 +73,7 @@
</template> </template>
<template #text> <template #text>
<span> <span>
{{ $t('status.thread_show_full', { numStatus: totalReplyCount[statusId], depth: totalReplyDepth[statusId] }, totalReplyCount[statusId]) }} {{ $t('status.thread_show_full', { numStatus: totalReplyCount[status.id], depth: totalReplyDepth[status.id] }, totalReplyCount[status.id]) }}
</span> </span>
</template> </template>
</i18n-t> </i18n-t>