refactor(ui): move timeline title style and logic to component

pull/3331/head
Florens Verschelde 2025-07-12 22:19:47 +02:00
rodzic 24d99aa562
commit 65ea50e5ed
Nie znaleziono w bazie danych klucza dla tego podpisu
33 zmienionych plików z 126 dodań i 107 usunięć

Wyświetl plik

@ -33,22 +33,22 @@ const containerClass = computed(() => {
'backdrop-blur': !getPreferences(userSettings, 'optimizeForLowPerformanceDevice'), 'backdrop-blur': !getPreferences(userSettings, 'optimizeForLowPerformanceDevice'),
}" }"
> >
<div flex justify-between gap-2 min-h-53px px5 py1 :class="{ 'xl:hidden': $route.name !== 'tag' }" class="native:xl:flex" border="b base"> <div flex="~ justify-between" min-h-53px px-2 py-1 :class="{ 'xl:hidden': $route.name !== 'tag' }" class="native:xl:flex" border="b base">
<div flex gap-2 items-center overflow-hidden w-full> <div flex="~ items-center" w-full>
<button <button
v-if="backOnSmallScreen || back" v-if="backOnSmallScreen || back"
btn-text flex items-center ms="-3" p-3 xl:hidden btn-text flex items-center p-3 xl:hidden
:aria-label="$t('nav.back')" :aria-label="$t('nav.back')"
@click="$router.go(-1)" @click="$router.go(-1)"
> >
<div text-lg i-ri:arrow-left-line class="rtl-flip" /> <div text-lg i-ri:arrow-left-line class="rtl-flip" />
</button> </button>
<div truncate flex w-full data-tauri-drag-region class="native-mac:justify-start native-mac:text-center"> <div flex w-full data-tauri-drag-region class="native-mac:justify-start">
<slot name="title" /> <slot name="title" />
</div> </div>
<div sm:hidden h-7 w-1px /> <div sm:hidden h-7 w-1px />
</div> </div>
<div flex items-center flex-shrink-0 gap-x-2> <div flex="~ items-center shrink-0 gap-x-2" px-3>
<slot name="actions" /> <slot name="actions" />
<PwaBadge xl:hidden /> <PwaBadge xl:hidden />
<NavUser v-if="isHydrated" /> <NavUser v-if="isHydrated" />

Wyświetl plik

@ -0,0 +1,33 @@
<script setup lang="ts">
const { as = 'div' } = defineProps<{
as?: string
icon?: string
secondary?: boolean
}>()
function doScroll({ currentTarget, metaKey, ctrlKey }: MouseEvent | KeyboardEvent) {
// Ctrl+click or Command+click to open the link in a new tab
// should not scroll the current tab's timeline
if ((metaKey || ctrlKey) && (currentTarget as HTMLElement)?.nodeName === 'A') {
return
}
useNuxtApp().$scrollToTop()
}
</script>
<template>
<component
:is="as"
class="
flex items-center gap-2 min-h-10 px-3
text-start text-lg lh-tight font-bold cursor-pointer
"
:class="{ 'text-primary': !secondary }"
@click="doScroll($event)"
>
<span v-if="icon" :class="icon" />
<span min-w-8 line-clamp-2>
<slot />
</span>
</component>
</template>

Wyświetl plik

@ -36,7 +36,7 @@ async function reload() {
<NuxtLayout> <NuxtLayout>
<MainContent> <MainContent>
<template #title> <template #title>
<span timeline-title-style>Error</span> <MainTitle>Error</MainTitle>
</template> </template>
<slot> <slot>
<form p5 grid gap-y-4 @submit="reload"> <form p5 grid gap-y-4 @submit="reload">

Wyświetl plik

@ -23,12 +23,13 @@ onReactivated(() => {
<template> <template>
<MainContent back> <MainContent back>
<template #title> <template #title>
<ContentRich <MainTitle>
timeline-title-style <ContentRich
:content="account ? getDisplayName(account) : t('nav.profile')" :content="account ? getDisplayName(account) : t('nav.profile')"
:show-emojis="!getPreferences(userSettings, 'hideUsernameEmojis')" :show-emojis="!getPreferences(userSettings, 'hideUsernameEmojis')"
:markdown="false" :markdown="false"
/> />
</MainTitle>
</template> </template>
<template v-if="pending" /> <template v-if="pending" />

Wyświetl plik

@ -42,10 +42,9 @@ const tabs = computed<CommonRouteTabOption[]>(() => [
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<span timeline-title-style flex items-center gap-2 cursor-pointer @click="$scrollToTop"> <MainTitle icon="i-ri:compass-3-line">
<div i-ri:compass-3-line /> {{ t('nav.explore') }}
<span>{{ t('nav.explore') }}</span> </MainTitle>
</span>
</template> </template>
<template #header> <template #header>

Wyświetl plik

@ -9,10 +9,9 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/lists" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/lists" icon="i-ri:list-check">
<div i-ri:list-check /> {{ t('nav.lists') }}
<span text-lg font-bold>{{ t('nav.lists') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<NuxtPage v-if="isHydrated" /> <NuxtPage v-if="isHydrated" />
</MainContent> </MainContent>

Wyświetl plik

@ -9,10 +9,9 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/public" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/public" icon="i-ri:earth-line">
<div i-ri:earth-line /> {{ $t('title.federated_timeline') }}
<span>{{ $t('title.federated_timeline') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<TimelinePublic v-if="isHydrated" /> <TimelinePublic v-if="isHydrated" />

Wyświetl plik

@ -9,10 +9,9 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/public/local" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/public/local" icon="i-ri:group-2-line">
<div i-ri:group-2-line /> {{ $t('title.local_timeline') }}
<span>{{ t('title.local_timeline') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<TimelinePublicLocal v-if="isHydrated" /> <TimelinePublicLocal v-if="isHydrated" />

Wyświetl plik

@ -25,10 +25,9 @@ watch(keys['/'], (v) => {
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/search" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/search" icon="i-ri:search-line rtl-flip">
<div i-ri:search-line class="rtl-flip" /> {{ $t('nav.search') }}
<span>{{ $t('nav.search') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<div px2 mt3> <div px2 mt3>

Wyświetl plik

@ -13,7 +13,7 @@ useHydratedHead({
<template> <template>
<MainContent back> <MainContent back>
<template #title> <template #title>
<span timeline-title-style>{{ $t('nav.blocked_users') }}</span> <MainTitle>{{ $t('nav.blocked_users') }}</MainTitle>
</template> </template>
<TimelineBlocks v-if="isHydrated" /> <TimelineBlocks v-if="isHydrated" />

Wyświetl plik

@ -13,10 +13,9 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/bookmarks" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/bookmarks" icon="i-ri:bookmark-line">
<div i-ri:bookmark-line /> {{ t('nav.bookmarks') }}
<span>{{ t('nav.bookmarks') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<TimelineBookmarks v-if="isHydrated" /> <TimelineBookmarks v-if="isHydrated" />

Wyświetl plik

@ -13,10 +13,9 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/compose" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/compose" icon="i-ri:quill-pen-line">
<div i-ri:quill-pen-line /> {{ $t('nav.compose') }}
<span>{{ $t('nav.compose') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<PublishWidgetFull /> <PublishWidgetFull />
</MainContent> </MainContent>

Wyświetl plik

@ -13,10 +13,9 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/conversations" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/conversations" icon="i-ri:at-line">
<div i-ri:at-line /> {{ t('nav.conversations') }}
<span>{{ t('nav.conversations') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<TimelineConversations v-if="isHydrated" /> <TimelineConversations v-if="isHydrated" />

Wyświetl plik

@ -13,7 +13,7 @@ useHydratedHead({
<template> <template>
<MainContent back> <MainContent back>
<template #title> <template #title>
<span timeline-title-style>{{ $t('nav.blocked_domains') }}</span> <MainTitle>{{ $t('nav.blocked_domains') }}</MainTitle>
</template> </template>
<TimelineDomainBlocks v-if="isHydrated" /> <TimelineDomainBlocks v-if="isHydrated" />

Wyświetl plik

@ -14,10 +14,12 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/favourites" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle
<div :class="useStarFavoriteIcon ? 'i-ri:star-line' : 'i-ri:heart-3-line'" /> as="router-link" to="/favourites"
<span>{{ t('nav.favourites') }}</span> :icon="useStarFavoriteIcon ? 'i-ri:star-line' : 'i-ri:heart-3-line'"
</NuxtLink> >
{{ t('nav.favourites') }}
</MainTitle>
</template> </template>
<TimelineFavourites v-if="isHydrated" /> <TimelineFavourites v-if="isHydrated" />

Wyświetl plik

@ -9,10 +9,9 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/hashtags" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/hashtags" icon="i-ri:hashtag">
<div class="i-ri:hashtag" /> {{ t('nav.hashtags') }}
<span>{{ t('nav.hashtags') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<NuxtPage v-if="isHydrated && currentUser" /> <NuxtPage v-if="isHydrated && currentUser" />

Wyświetl plik

@ -18,10 +18,9 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/home" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/home" icon="i-ri:home-5-line">
<div i-ri:home-5-line /> {{ $t('nav.home') }}
<span>{{ $t('nav.home') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<TimelineHome v-if="isHydrated" /> <TimelineHome v-if="isHydrated" />

Wyświetl plik

@ -13,7 +13,7 @@ useHydratedHead({
<template> <template>
<MainContent back> <MainContent back>
<template #title> <template #title>
<span timeline-title-style>{{ $t('nav.muted_users') }}</span> <MainTitle>{{ $t('nav.muted_users') }}</MainTitle>
</template> </template>
<TimelineMutes v-if="isHydrated" /> <TimelineMutes v-if="isHydrated" />

Wyświetl plik

@ -72,10 +72,9 @@ const moreOptions = computed<CommonRouteTabMoreOption>(() => ({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/notifications" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/notifications" icon="i-ri:notification-4-line">
<div i-ri:notification-4-line /> {{ t('nav.notifications') }}
<span>{{ t('nav.notifications') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<template #actions> <template #actions>

Wyświetl plik

@ -13,10 +13,9 @@ useHydratedHead({
<template> <template>
<MainContent> <MainContent>
<template #title> <template #title>
<NuxtLink to="/pinned" timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="router-link" to="/pinned" icon="i-ri:pushpin-line">
<div i-ri:pushpin-line /> {{ t('account.pinned') }}
<span>{{ t('account.pinned') }}</span> </MainTitle>
</NuxtLink>
</template> </template>
<TimelinePinned v-if="isHydrated && currentUser" /> <TimelinePinned v-if="isHydrated && currentUser" />

Wyświetl plik

@ -20,10 +20,9 @@ const isRootPath = computed(() => route.name === 'settings')
<div border="e base" :class="isRootPath ? 'block lg:flex-none flex-1' : 'hidden lg:block'"> <div border="e base" :class="isRootPath ? 'block lg:flex-none flex-1' : 'hidden lg:block'">
<MainContent> <MainContent>
<template #title> <template #title>
<div timeline-title-style flex items-center gap-2 @click="$scrollToTop"> <MainTitle icon="i-ri:settings-3-line">
<div i-ri:settings-3-line /> {{ $t('nav.settings') }}
<span>{{ $t('nav.settings') }}</span> </MainTitle>
</div>
</template> </template>
<div xl:w-97 lg:w-78 w-full> <div xl:w-97 lg:w-78 w-full>
<SettingsItem <SettingsItem

Wyświetl plik

@ -19,9 +19,9 @@ function handleShowCommit() {
<template> <template>
<MainContent back-on-small-screen> <MainContent back-on-small-screen>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary>
<span>{{ $t('settings.about.label') }}</span> {{ $t('settings.about.label') }}
</div> </MainTitle>
</template> </template>
<div flex="~ col gap4" w-full items-center justify-center my5> <div flex="~ col gap4" w-full items-center justify-center my5>

Wyświetl plik

@ -9,9 +9,9 @@ useHydratedHead({
<template> <template>
<MainContent back-on-small-screen> <MainContent back-on-small-screen>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary>
<span>{{ $t('settings.interface.label') }}</span> {{ $t('settings.interface.label') }}
</div> </MainTitle>
</template> </template>
<div px-6 pt-3 pb-6 flex="~ col gap6"> <div px-6 pt-3 pb-6 flex="~ col gap6">
<SettingsFontSize /> <SettingsFontSize />

Wyświetl plik

@ -17,9 +17,9 @@ const status = computed(() => {
<template> <template>
<MainContent back-on-small-screen> <MainContent back-on-small-screen>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary>
<span>{{ $t('settings.language.label') }}</span> {{ $t('settings.language.label') }}
</div> </MainTitle>
</template> </template>
<div p6> <div p6>
<section space-y-2> <section space-y-2>

Wyświetl plik

@ -14,9 +14,9 @@ useHydratedHead({
<template> <template>
<MainContent back-on-small-screen> <MainContent back-on-small-screen>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary>
<span>{{ $t('settings.notifications.label') }}</span> {{ $t('settings.notifications.label') }}
</div> </MainTitle>
</template> </template>
<SettingsItem <SettingsItem

Wyświetl plik

@ -13,10 +13,9 @@ useHydratedHead({
<template> <template>
<MainContent back> <MainContent back>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary icon="i-ri:test-tube-line">
<div i-ri:test-tube-line /> {{ $t('settings.notifications.notifications.label') }}
<span>{{ $t('settings.notifications.notifications.label') }}</span> </MainTitle>
</div>
</template> </template>
<div text-center mt-10> <div text-center mt-10>
<h1 text-4xl> <h1 text-4xl>

Wyświetl plik

@ -16,9 +16,9 @@ useHydratedHead({
<template> <template>
<MainContent back> <MainContent back>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary>
<span>{{ $t('settings.notifications.push_notifications.label') }}</span> {{ $t('settings.notifications.push_notifications.label') }}
</div> </MainTitle>
</template> </template>
<NotificationPreferences show /> <NotificationPreferences show />
</MainContent> </MainContent>

Wyświetl plik

@ -11,9 +11,9 @@ const userSettings = useUserSettings()
<template> <template>
<MainContent back-on-small-screen> <MainContent back-on-small-screen>
<template #title> <template #title>
<h1 text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary>
{{ $t('settings.preferences.label') }} {{ $t('settings.preferences.label') }}
</h1> </MainTitle>
</template> </template>
<section> <section>
<h2 px6 py4 mt2 font-bold text-xl flex="~ gap-1" items-center sr-only> <h2 px6 py4 mt2 font-bold text-xl flex="~ gap-1" items-center sr-only>

Wyświetl plik

@ -105,9 +105,9 @@ onReactivated(refreshInfo)
<template> <template>
<MainContent back> <MainContent back>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary>
<span>{{ $t('settings.profile.appearance.title') }}</span> {{ $t('settings.profile.appearance.title') }}
</div> </MainTitle>
</template> </template>
<form space-y-5 @submit.prevent="submit"> <form space-y-5 @submit.prevent="submit">

Wyświetl plik

@ -13,10 +13,9 @@ useHydratedHead({
<template> <template>
<MainContent back> <MainContent back>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary icon="i-ri:test-tube-line">
<div i-ri:test-tube-line /> {{ $t('settings.profile.featured_tags.label') }}
<span>{{ $t('settings.profile.featured_tags.label') }}</span> </MainTitle>
</div>
</template> </template>
<div text-center mt-10> <div text-center mt-10>
<h1 text-4xl> <h1 text-4xl>

Wyświetl plik

@ -13,9 +13,9 @@ useHydratedHead({
<template> <template>
<MainContent back-on-small-screen> <MainContent back-on-small-screen>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary>
<span>{{ $t('settings.profile.label') }}</span> {{ $t('settings.profile.label') }}
</div> </MainTitle>
</template> </template>
<SettingsItem <SettingsItem

Wyświetl plik

@ -68,9 +68,9 @@ async function importTokens() {
<template> <template>
<MainContent back-on-small-screen> <MainContent back-on-small-screen>
<template #title> <template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop"> <MainTitle as="h1" secondary>
<span>{{ $t('settings.users.label') }}</span> {{ $t('settings.users.label') }}
</div> </MainTitle>
</template> </template>
<div p6> <div p6>
<template v-if="loggedInUsers.length"> <template v-if="loggedInUsers.length">

Wyświetl plik

@ -65,8 +65,6 @@ export default defineConfig({
'flex-v-center': 'items-center', 'flex-v-center': 'items-center',
'flex-h-center': 'justify-center', 'flex-h-center': 'justify-center',
'bg-hover-overflow': 'relative z-0 transition-colors duration-250 after-content-empty after:(absolute inset--4px bg-transparent rounded-full z--1 transition-colors duration-250) hover:after:(bg-active)', 'bg-hover-overflow': 'relative z-0 transition-colors duration-250 after-content-empty after:(absolute inset--4px bg-transparent rounded-full z--1 transition-colors duration-250) hover:after:(bg-active)',
'timeline-title-style': 'text-primary text-lg font-bold',
}, },
[/^elk-group-hover[:-]([a-z0-9/-]+)$/, ([,r]) => `media-mouse-group-hover-${r} group-active-${r}`], [/^elk-group-hover[:-]([a-z0-9/-]+)$/, ([,r]) => `media-mouse-group-hover-${r} group-active-${r}`],
], ],