2
0
Fork 0

add "cohost-like" display mode, based off of 1df79a1f12 with a minor tweak

This commit is contained in:
notfire 2025-07-30 14:46:59 -04:00
commit 07d5b6073a
No known key found for this signature in database
16 changed files with 139 additions and 21 deletions

View file

@ -82,6 +82,9 @@ const conversation = {
streamingEnabled () { streamingEnabled () {
return this.mergedConfig.useStreamingApi && this.mastoUserSocketStatus === WSConnectionStatus.JOINED return this.mergedConfig.useStreamingApi && this.mastoUserSocketStatus === WSConnectionStatus.JOINED
}, },
timelineStyle () {
return this.$store.getters.mergedConfig.timelineStyle
},
displayStyle () { displayStyle () {
return this.$store.getters.mergedConfig.conversationDisplay return this.$store.getters.mergedConfig.conversationDisplay
}, },
@ -267,11 +270,11 @@ const conversation = {
}, },
replies () { replies () {
let i = 1 let i = 1
return reduce(this.conversation, (result, { id, in_reply_to_status_id }) => { return reduce(this.conversation, (result, { id, in_reply_to_status_id }) => {
const irid = in_reply_to_status_id const irid = in_reply_to_status_id
if (irid) { if (irid) {
result[irid] = result[irid] || [] result[irid] = result[irid] || []
result[irid].push({ result[irid].push({

View file

@ -69,6 +69,7 @@
:in-profile="inProfile" :in-profile="inProfile"
:profile-user-id="profileUserId" :profile-user-id="profileUserId"
class="conversation-status status-fadein panel-body" class="conversation-status status-fadein panel-body"
:class="timelineStyle"
:simple-tree="treeViewIsSimple" :simple-tree="treeViewIsSimple"
:toggle-thread-display="toggleThreadDisplay" :toggle-thread-display="toggleThreadDisplay"
@ -173,6 +174,7 @@
:in-profile="inProfile" :in-profile="inProfile"
:profile-user-id="profileUserId" :profile-user-id="profileUserId"
class="conversation-status status-fadein panel-body" class="conversation-status status-fadein panel-body"
:class="timelineStyle"
:toggle-thread-display="toggleThreadDisplay" :toggle-thread-display="toggleThreadDisplay"
:thread-display-status="threadDisplayStatus" :thread-display-status="threadDisplayStatus"
@ -243,7 +245,7 @@
padding: var(--status-margin, $status-margin); padding: var(--status-margin, $status-margin);
} }
.conversation-status { .conversation-status.classic {
border-bottom-width: 1px; border-bottom-width: 1px;
border-bottom-style: solid; border-bottom-style: solid;
border-bottom-color: var(--border, $fallback--border); border-bottom-color: var(--border, $fallback--border);

View file

@ -39,6 +39,9 @@ const EmojiReactions = {
return acc return acc
}, {}) }, {})
}, },
timelineStyle () {
return this.$store.getters.mergedConfig.timelineStyle
},
loggedIn () { loggedIn () {
return !!this.$store.state.users.currentUser return !!this.$store.state.users.currentUser
}, },
@ -52,7 +55,7 @@ const EmojiReactions = {
var toPush = [] var toPush = []
finalReacts.forEach((react) => { finalReacts.forEach((react) => {
var rawReact = toRaw(react)["name"] var rawReact = toRaw(react)["name"]
if ( if (
// match regex // match regex
// >1 check is to prevent = just disabling all emoji reacts // >1 check is to prevent = just disabling all emoji reacts
@ -63,7 +66,7 @@ const EmojiReactions = {
|| (rawReact.match(/.*@.*/) ? rawReact.split("@")[0] : rawReact) == item || (rawReact.match(/.*@.*/) ? rawReact.split("@")[0] : rawReact) == item
) { ) {
toPush.push(react) toPush.push(react)
} }
}) })
toPush.forEach((nice) => { toPush.forEach((nice) => {

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="emoji-reactions"> <div class="emoji-reactions" :class="timelineStyle">
<UserListPopover <UserListPopover
v-for="(reaction) in filteredReactions" v-for="(reaction) in filteredReactions"
:key="reaction.url || reaction.name" :key="reaction.url || reaction.name"
@ -47,8 +47,19 @@
@import '../../_variables.scss'; @import '../../_variables.scss';
.emoji-reactions { .emoji-reactions {
&.classic {
margin-top: 0.25em;
}
&.chostlike {
padding-left: 10px;
padding-right: 10px;
padding-bottom: .5em;
background: var(--bg);
border-bottom: 1px solid var(--faint);
}
display: flex; display: flex;
margin-top: 0.25em;
flex-wrap: wrap; flex-wrap: wrap;
container-type: inline-size; container-type: inline-size;
} }
@ -100,6 +111,7 @@
border: 1px solid var(--accent, $fallback--link); border: 1px solid var(--accent, $fallback--link);
margin-left: -1px; // offset the border, can't use inset shadows either margin-left: -1px; // offset the border, can't use inset shadows either
margin-right: calc(0.5em - 1px); margin-right: calc(0.5em - 1px);
box-shadow: 0 0 4px 4px rgba(255,255,255,.5) inset;
} }
</style> </style>

View file

@ -132,7 +132,7 @@ const Notification = {
|| (emoji.match(/.*@.*/) ? emoji.split("@")[0] : emoji) == item || (emoji.match(/.*@.*/) ? emoji.split("@")[0] : emoji) == item
) { ) {
isFiltered = true isFiltered = true
} }
}) })
return isFiltered return isFiltered
@ -150,6 +150,9 @@ const Notification = {
user () { user () {
return this.$store.getters.findUser(this.notification.from_profile.id) return this.$store.getters.findUser(this.notification.from_profile.id)
}, },
timelineStyle () {
return this.$store.getters.mergedConfig.timelineStyle
},
userProfileLink () { userProfileLink () {
return this.generateUserProfileLink(this.user) return this.generateUserProfileLink(this.user)
}, },

View file

@ -2,6 +2,7 @@
<Status <Status
v-if="notification.type === 'mention'" v-if="notification.type === 'mention'"
class="Notification" class="Notification"
:class="timelineStyle"
:compact="true" :compact="true"
:statusoid="notification.status" :statusoid="notification.status"
/> />

View file

@ -40,6 +40,7 @@
z-index: 500; z-index: 500;
position: absolute; position: absolute;
min-width: 0; min-width: 0;
filter: drop-shadow(1px 1px 4px rgba(0,0,0,0.6));
} }
.popover-default { .popover-default {
@ -53,8 +54,6 @@
left: 0; left: 0;
right: 0; right: 0;
z-index: 3; z-index: 3;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6);
box-shadow: var(--panelShadow);
pointer-events: none; pointer-events: none;
} }

View file

@ -14,7 +14,10 @@ const QuoteCard = {
computed: { computed: {
...mapGetters([ ...mapGetters([
'mergedConfig' 'mergedConfig'
]) ]),
timelineStyle () {
return this.$store.getters.mergedConfig.timelineStyle
},
}, },
components: { components: {
QuoteCardContent QuoteCardContent

View file

@ -2,6 +2,7 @@
<div> <div>
<router-link <router-link
class="quote-card" class="quote-card"
:class="timelineStyle"
:to="{ name: 'conversation', params: { id: status.id } }" :to="{ name: 'conversation', params: { id: status.id } }"
> >
<QuoteCardContent <QuoteCardContent
@ -23,6 +24,10 @@
overflow: hidden; overflow: hidden;
margin-top: 0.5em; margin-top: 0.5em;
&.chostian .right-side {
background: linear-gradient(180deg, var(--selectedPost, $fallback--lightBg) 0%, var(--selectedPost, $fallback--lightBg) 75%, var(--bg) 75%, var(--bg) 100%) !important;
}
.card-image { .card-image {
flex-shrink: 0; flex-shrink: 0;
width: 120px; width: 120px;
@ -64,11 +69,14 @@
color: $fallback--text; color: $fallback--text;
color: var(--text, $fallback--text); color: var(--text, $fallback--text);
border-style: solid;
border-width: 1px; &.classic {
border-radius: $fallback--attachmentRadius; border-style: solid;
border-radius: var(--attachmentRadius, $fallback--attachmentRadius); border-width: 1px;
border-color: $fallback--border; border-radius: $fallback--attachmentRadius;
border-color: var(--border, $fallback--border); border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
border-color: $fallback--border;
border-color: var(--border, $fallback--border);
}
} }
</style> </style>

View file

@ -55,6 +55,11 @@ const GeneralTab = {
value: tab, value: tab,
label: this.$t(`user_card.${tab}`) label: this.$t(`user_card.${tab}`)
})), })),
timelineStyleOptions: ['classic', 'chostlike'].map(mode => ({
key: mode,
value: mode,
label: this.$t(`settings.timeline_${mode}`)
})),
profilesExpanded: false, profilesExpanded: false,
newProfileName: '', newProfileName: '',
loopSilentAvailable: loopSilentAvailable:

View file

@ -104,6 +104,15 @@
<div class="setting-item"> <div class="setting-item">
<h2>{{ $t('settings.interface') }}</h2> <h2>{{ $t('settings.interface') }}</h2>
<ul class="setting-list"> <ul class="setting-list">
<li>
<ChoiceSetting
id="timelineStyle"
path="timelineStyle"
:options="timelineStyleOptions"
>
{{ $t('settings.timeline_style_choice') }}
</ChoiceSetting>
</li>
<li v-if="instanceSpecificPanelPresent"> <li v-if="instanceSpecificPanelPresent">
<BooleanSetting path="hideISP"> <BooleanSetting path="hideISP">
{{ $t('settings.hide_isp') }} {{ $t('settings.hide_isp') }}

View file

@ -38,9 +38,72 @@
} }
} }
&.classic .status-container {
padding: var(--status-margin, $status-margin);
}
&.classic .status-heading {
margin-bottom: 0.5em;
}
&.classic .replies {
margin-top: 0.25em;
}
&.chostlike .status-container {
padding: calc(10px + var(--status-margin, 0.75em)) var(--status-margin, 0.75em);
.content {
padding-bottom: .5em;
padding-top: 1em;
padding-left: 10px;
padding-right: 10px;
background: var(--bg);
}
.right-side {
background-color: var(--selectedPost);
border-radius: 10px;
padding: 10px 0 10px 0;
box-shadow: #000c 0px 0px 10px;
}
.status-heading {
border-bottom: 1px solid var(--faint);
padding: .3em 1em .7em 1em;
}
.replies {
padding-top: 0.25em;
padding-left: 10px;
padding-right: 10px;
background: var(--bg);
}
&.repeat-info {
padding-top: calc(10px + var(--status-margin, 0.75em));
padding-bottom: 0px;
.right-side {
border-radius: 10px 10px 0 0;
padding-left: 10px;
padding-right: 10px;
border-bottom: 1px solid #0003;
}
}
&.repeat-info + .status-container .right-side {
border-radius: 0px 0px 10px 10px;
}
.status-actions {
padding-left: 10px;
padding-right: 10px;
}
}
.status-container { .status-container {
display: flex; display: flex;
padding: var(--status-margin, $status-margin);
.content { .content {
overflow: hidden; overflow: hidden;
@ -104,7 +167,7 @@
} }
.status-heading { .status-heading {
margin-bottom: 0.5em;
.emoji { .emoji {
--emoji-size: 16px; --emoji-size: 16px;
@ -244,7 +307,6 @@
} }
.replies { .replies {
margin-top: 0.25em;
line-height: 1.3; line-height: 1.3;
font-size: 0.85em; font-size: 0.85em;
display: flex; display: flex;

View file

@ -58,6 +58,9 @@ const ThreadTree = {
return table return table
}, {}) }, {})
}, },
timelineStyle () {
return this.$store.getters.mergedConfig.timelineStyle
},
currentReplies () { currentReplies () {
return this.getReplies(this.status.id).map(({ id }) => this.statusById(id)) return this.getReplies(this.status.id).map(({ id }) => this.statusById(id))
}, },

View file

@ -14,6 +14,7 @@
:in-profile="inProfile" :in-profile="inProfile"
:profile-user-id="profileUserId" :profile-user-id="profileUserId"
class="conversation-status conversation-status-treeview status-fadein panel-body" class="conversation-status conversation-status-treeview status-fadein panel-body"
:class="timelineStyle"
:simple-tree="simple" :simple-tree="simple"
:controlled-thread-display-status="threadDisplayStatus[status.id]" :controlled-thread-display-status="threadDisplayStatus[status.id]"

View file

@ -957,6 +957,9 @@
"third_column_mode_none": "Don't show third column at all", "third_column_mode_none": "Don't show third column at all",
"third_column_mode_notifications": "Notifications column", "third_column_mode_notifications": "Notifications column",
"third_column_mode_postform": "Main post form and navigation", "third_column_mode_postform": "Main post form and navigation",
"timeline_classic": "Classic",
"timeline_chostlike": "Cohost-like",
"timeline_style_choice": "Timeline post style",
"token": "Token", "token": "Token",
"tooltipRadius": "Tooltips/alerts", "tooltipRadius": "Tooltips/alerts",
"translation_language": "Automatic Translation Language", "translation_language": "Automatic Translation Language",

View file

@ -142,6 +142,7 @@ export const defaultState = {
postLanguage: undefined, // instance default, postLanguage: undefined, // instance default,
supportedTranslationLanguages: {}, // instance default supportedTranslationLanguages: {}, // instance default
userProfileDefaultTab: 'statuses', userProfileDefaultTab: 'statuses',
timelineStyle: 'classic',
useBlurhash: true, useBlurhash: true,
} }