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'),
}"
>
<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 gap-2 items-center overflow-hidden w-full>
<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="~ items-center" w-full>
<button
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')"
@click="$router.go(-1)"
>
<div text-lg i-ri:arrow-left-line class="rtl-flip" />
</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" />
</div>
<div sm:hidden h-7 w-1px />
</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" />
<PwaBadge xl:hidden />
<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>
<MainContent>
<template #title>
<span timeline-title-style>Error</span>
<MainTitle>Error</MainTitle>
</template>
<slot>
<form p5 grid gap-y-4 @submit="reload">

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -13,10 +13,9 @@ useHydratedHead({
<template>
<MainContent>
<template #title>
<NuxtLink to="/pinned" timeline-title-style flex items-center gap-2 @click="$scrollToTop">
<div i-ri:pushpin-line />
<span>{{ t('account.pinned') }}</span>
</NuxtLink>
<MainTitle as="router-link" to="/pinned" icon="i-ri:pushpin-line">
{{ t('account.pinned') }}
</MainTitle>
</template>
<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'">
<MainContent>
<template #title>
<div timeline-title-style flex items-center gap-2 @click="$scrollToTop">
<div i-ri:settings-3-line />
<span>{{ $t('nav.settings') }}</span>
</div>
<MainTitle icon="i-ri:settings-3-line">
{{ $t('nav.settings') }}
</MainTitle>
</template>
<div xl:w-97 lg:w-78 w-full>
<SettingsItem

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -11,9 +11,9 @@ const userSettings = useUserSettings()
<template>
<MainContent back-on-small-screen>
<template #title>
<h1 text-lg font-bold flex items-center gap-2 @click="$scrollToTop">
<MainTitle as="h1" secondary>
{{ $t('settings.preferences.label') }}
</h1>
</MainTitle>
</template>
<section>
<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>
<MainContent back>
<template #title>
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop">
<span>{{ $t('settings.profile.appearance.title') }}</span>
</div>
<MainTitle as="h1" secondary>
{{ $t('settings.profile.appearance.title') }}
</MainTitle>
</template>
<form space-y-5 @submit.prevent="submit">

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -65,8 +65,6 @@ export default defineConfig({
'flex-v-center': 'items-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)',
'timeline-title-style': 'text-primary text-lg font-bold',
},
[/^elk-group-hover[:-]([a-z0-9/-]+)$/, ([,r]) => `media-mouse-group-hover-${r} group-active-${r}`],
],