feat: add grayscale mode to user preferences (#1177)

This commit is contained in:
rshigg 2023-01-17 09:25:36 -03:30 committed by GitHub
parent bb41c468bb
commit 0b2b9a713b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 49 additions and 11 deletions

View file

@ -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"

View file

@ -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')"

View file

@ -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)">

View file

@ -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>

View file

@ -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,

View file

@ -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>

View file

@ -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",

View file

@ -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')"

View file

@ -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);
}