feat: add grayscale mode to user preferences (#1177)
parent
bb41c468bb
commit
0b2b9a713b
|
@ -19,6 +19,7 @@ const error = $ref(false)
|
||||||
:src="(error || !loaded) ? 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' : account.avatar"
|
:src="(error || !loaded) ? 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' : account.avatar"
|
||||||
:alt="$t('account.avatar_description', [account.username])"
|
:alt="$t('account.avatar_description', [account.username])"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
|
class="account-avatar"
|
||||||
:class="(loaded ? 'bg-base' : 'bg-gray:10') + (square ? ' ' : ' rounded-full')"
|
:class="(loaded ? 'bg-base' : 'bg-gray:10') + (square ? ' ' : ' rounded-full')"
|
||||||
:style="{ 'clip-path': square ? `url(#avatar-mask)` : 'none' }"
|
:style="{ 'clip-path': square ? `url(#avatar-mask)` : 'none' }"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
|
|
@ -33,7 +33,7 @@ const reply = () => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div flex justify-between>
|
<div flex justify-between items-center class="status-actions">
|
||||||
<div flex-1>
|
<div flex-1>
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
:content="$t('action.reply')"
|
:content="$t('action.reply')"
|
||||||
|
|
|
@ -125,7 +125,7 @@ const showReplyTo = $computed(() => !replyToMain && !directReply)
|
||||||
p="t-1 b-0.5 x-1px"
|
p="t-1 b-0.5 x-1px"
|
||||||
relative text-secondary ws-nowrap
|
relative text-secondary ws-nowrap
|
||||||
>
|
>
|
||||||
<div i-ri:repeat-fill me-46px text-green w-16px h-16px />
|
<div i-ri:repeat-fill me-46px text-green w-16px h-16px class="status-boosted" />
|
||||||
<div absolute top-1 ms-24px w-32px h-32px rounded-full>
|
<div absolute top-1 ms-24px w-32px h-32px rounded-full>
|
||||||
<AccountHoverWrapper :account="rebloggedBy">
|
<AccountHoverWrapper :account="rebloggedBy">
|
||||||
<NuxtLink :to="getAccountRoute(rebloggedBy)">
|
<NuxtLink :to="getAccountRoute(rebloggedBy)">
|
||||||
|
|
|
@ -43,7 +43,7 @@ const votersCount = $computed(() => poll.votersCount ?? poll.votesCount ?? 0)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div flex flex-col w-full items-stretch gap-2 py3 dir="auto">
|
<div flex flex-col w-full items-stretch gap-2 py3 dir="auto" class="poll-wrapper">
|
||||||
<form v-if="!poll.voted && !poll.expired" flex="~ col gap3" accent-primary @click.stop="noop" @submit.prevent="vote">
|
<form v-if="!poll.voted && !poll.expired" flex="~ col gap3" accent-primary @click.stop="noop" @submit.prevent="vote">
|
||||||
<label v-for="(option, index) of poll.options" :key="index" flex="~ gap2" items-center>
|
<label v-for="(option, index) of poll.options" :key="index" flex="~ gap2" items-center>
|
||||||
<input name="choices" :value="index" :type="poll.multiple ? 'checkbox' : 'radio'" cursor-pointer>
|
<input name="choices" :value="index" :type="poll.multiple ? 'checkbox' : 'radio'" cursor-pointer>
|
||||||
|
|
|
@ -7,6 +7,7 @@ export interface PreferencesSettings {
|
||||||
hideBoostCount: boolean
|
hideBoostCount: boolean
|
||||||
hideFavoriteCount: boolean
|
hideFavoriteCount: boolean
|
||||||
hideFollowerCount: boolean
|
hideFollowerCount: boolean
|
||||||
|
grayscaleMode: boolean
|
||||||
experimentalVirtualScroller: boolean
|
experimentalVirtualScroller: boolean
|
||||||
experimentalGitHubCards: boolean
|
experimentalGitHubCards: boolean
|
||||||
experimentalUserPicker: boolean
|
experimentalUserPicker: boolean
|
||||||
|
@ -56,6 +57,7 @@ export const DEFAULT__PREFERENCES_SETTINGS: PreferencesSettings = {
|
||||||
hideBoostCount: false,
|
hideBoostCount: false,
|
||||||
hideFavoriteCount: false,
|
hideFavoriteCount: false,
|
||||||
hideFollowerCount: false,
|
hideFollowerCount: false,
|
||||||
|
grayscaleMode: false,
|
||||||
experimentalVirtualScroller: true,
|
experimentalVirtualScroller: true,
|
||||||
experimentalGitHubCards: true,
|
experimentalGitHubCards: true,
|
||||||
experimentalUserPicker: true,
|
experimentalUserPicker: true,
|
||||||
|
|
|
@ -10,10 +10,12 @@ const showUserPicker = logicAnd(
|
||||||
usePreferences('experimentalUserPicker'),
|
usePreferences('experimentalUserPicker'),
|
||||||
() => useUsers().value.length > 1,
|
() => useUsers().value.length > 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const isGrayscale = usePreferences('grayscaleMode')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div h-full>
|
<div h-full :data-mode="isHydrated && isGrayscale ? 'grayscale' : ''">
|
||||||
<main flex w-full mxa lg:max-w-80rem>
|
<main flex w-full mxa lg:max-w-80rem>
|
||||||
<aside class="hidden sm:flex w-1/8 md:w-1/6 lg:w-1/5 xl:w-1/4 justify-end xl:me-4 zen-hide" relative>
|
<aside class="hidden sm:flex w-1/8 md:w-1/6 lg:w-1/5 xl:w-1/4 justify-end xl:me-4 zen-hide" relative>
|
||||||
<div sticky top-0 w-20 xl:w-100 h-screen flex="~ col" lt-xl-items-center>
|
<div sticky top-0 w-20 xl:w-100 h-screen flex="~ col" lt-xl-items-center>
|
||||||
|
|
|
@ -357,6 +357,7 @@
|
||||||
"notifications_settings": "Notifications",
|
"notifications_settings": "Notifications",
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"github_cards": "GitHub Cards",
|
"github_cards": "GitHub Cards",
|
||||||
|
"grayscale_mode": "Grayscale mode",
|
||||||
"hide_boost_count": "Hide boost count",
|
"hide_boost_count": "Hide boost count",
|
||||||
"hide_favorite_count": "Hide favorite count",
|
"hide_favorite_count": "Hide favorite count",
|
||||||
"hide_follower_count": "Hide follower count",
|
"hide_follower_count": "Hide follower count",
|
||||||
|
|
|
@ -10,6 +10,11 @@ const userSettings = useUserSettings()
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MainContent back-on-small-screen>
|
<MainContent back-on-small-screen>
|
||||||
|
<template #title>
|
||||||
|
<h1 text-lg font-bold flex items-center gap-2 @click="$scrollToTop">
|
||||||
|
{{ $t('settings.preferences.label') }}
|
||||||
|
</h1>
|
||||||
|
</template>
|
||||||
<SettingsToggleItem
|
<SettingsToggleItem
|
||||||
:checked="getPreferences(userSettings, 'hideBoostCount')"
|
:checked="getPreferences(userSettings, 'hideBoostCount')"
|
||||||
@click="togglePreferences('hideBoostCount')"
|
@click="togglePreferences('hideBoostCount')"
|
||||||
|
@ -28,15 +33,16 @@ const userSettings = useUserSettings()
|
||||||
>
|
>
|
||||||
{{ $t('settings.preferences.hide_follower_count') }}
|
{{ $t('settings.preferences.hide_follower_count') }}
|
||||||
</SettingsToggleItem>
|
</SettingsToggleItem>
|
||||||
<template #title>
|
<SettingsToggleItem
|
||||||
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop">
|
:checked="getPreferences(userSettings, 'grayscaleMode')"
|
||||||
<span>{{ $t('settings.preferences.label') }}</span>
|
@click="togglePreferences('grayscaleMode')"
|
||||||
</div>
|
>
|
||||||
</template>
|
{{ $t('settings.preferences.grayscale_mode') }}
|
||||||
<h3 px6 py4 mt2 font-bold text-xl flex="~ gap-1" items-center>
|
</SettingsToggleItem>
|
||||||
|
<h2 px6 py4 mt2 font-bold text-xl flex="~ gap-1" items-center>
|
||||||
<div i-ri-flask-line />
|
<div i-ri-flask-line />
|
||||||
{{ $t('settings.preferences.title') }}
|
{{ $t('settings.preferences.title') }}
|
||||||
</h3>
|
</h2>
|
||||||
<SettingsToggleItem
|
<SettingsToggleItem
|
||||||
:checked="getPreferences(userSettings, 'experimentalVirtualScroller')"
|
:checked="getPreferences(userSettings, 'experimentalVirtualScroller')"
|
||||||
@click="togglePreferences('experimentalVirtualScroller')"
|
@click="togglePreferences('experimentalVirtualScroller')"
|
||||||
|
|
|
@ -250,3 +250,29 @@ footer {
|
||||||
.squircle {
|
.squircle {
|
||||||
clip-path: url(#avatar-mask);
|
clip-path: url(#avatar-mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Grayscale mode
|
||||||
|
Setting each element filter to a different var
|
||||||
|
allows controlling them individually
|
||||||
|
*/
|
||||||
|
[data-mode="grayscale"] img,
|
||||||
|
[data-mode="grayscale"] video {
|
||||||
|
filter: grayscale(var(--media-grayscale, 1));
|
||||||
|
transition: filter .23s ease-in-out .2s;
|
||||||
|
}
|
||||||
|
[data-mode="grayscale"] pre {
|
||||||
|
filter: grayscale(var(--code-grayscale, 1));
|
||||||
|
}
|
||||||
|
[data-mode="grayscale"] .poll-wrapper {
|
||||||
|
filter: grayscale(var(--poll-grayscale, 1));
|
||||||
|
}
|
||||||
|
[data-mode="grayscale"] .status-actions,
|
||||||
|
[data-mode="grayscale"] .status-boosted {
|
||||||
|
filter: grayscale(var(--status-grayscale, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-mode="grayscale"] img:hover,
|
||||||
|
[data-mode="grayscale"] video:hover {
|
||||||
|
filter: grayscale(0);
|
||||||
|
}
|
Loading…
Reference in New Issue