[client] Add wellness preferences

This commit is contained in:
Laura Hausmann 2023-11-04 21:28:57 +01:00
parent 3c2143efd5
commit dbdd60d89f
No known key found for this signature in database
GPG Key ID: D044E84C5BE01605
7 changed files with 100 additions and 2 deletions

View File

@ -2138,3 +2138,9 @@ _cwStyle:
alternative: "Alternative (Firefish-like)" alternative: "Alternative (Firefish-like)"
alwaysExpandCws: "Always expand posts with content warnings" alwaysExpandCws: "Always expand posts with content warnings"
hideFromHome: "Hide from home timeline" hideFromHome: "Hide from home timeline"
_wellness:
name: "Wellness"
description: "These settings allow you to adjust possibly addictive or anxiety-inducing aspects of social media. Choose the settings that are ideal for you."
newPostsButton: "Enable new posts alert button"
newPostsGlowOpacity: "New posts glow opacity"
immediacy: "Immediacy"

View File

@ -9,11 +9,16 @@
<template #icon></template> <template #icon></template>
</I18n> </I18n>
</MkInfo> </MkInfo>
<div v-if="queue > 0" class="new"> <div
v-if="queue > 0"
class="new"
:class="{ noShadow: newPostsGlowOpacity < 0.05 }"
:style="{ '--opacity': newPostsGlowOpacity }"
>
<button <button
class="_buttonPrimary _shadow" class="_buttonPrimary _shadow"
@click="tlComponent.scrollTop()" @click="tlComponent.scrollTop()"
:class="{ instant: !$store.state.animation }" :class="{ instant: !$store.state.animation, isHidden: !newPostsButton }"
> >
{{ i18n.ts.newNoteRecived }} {{ i18n.ts.newNoteRecived }}
<i class="ph-arrow-up ph-bold"></i> <i class="ph-arrow-up ph-bold"></i>
@ -246,6 +251,15 @@ const timetravel = (date?: Date) => {
this.$refs.tl.reload(); this.$refs.tl.reload();
}; };
*/ */
const newPostsButton = computed(
defaultStore.makeGetterSetter("newPostsButton"),
);
const newPostsGlowOpacity = computed(
defaultStore.makeGetterSetter("newPostsGlowOpacity"),
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@keyframes slideUp { @keyframes slideUp {
@ -267,11 +281,21 @@ const timetravel = (date?: Date) => {
margin-top: -60px; margin-top: -60px;
z-index: 1001; z-index: 1001;
box-shadow: 0 24px 24px -20px var(--accentedBg); box-shadow: 0 24px 24px -20px var(--accentedBg);
> .isHidden {
display: none;
}
&.noShadow {
box-shadow: 0 0;
}
&::after { &::after {
content: ""; content: "";
position: absolute; position: absolute;
inset: -2px 0; inset: -2px 0;
border: 2px solid var(--accentDarken); border: 2px solid var(--accentDarken);
opacity: var(--opacity);
mask: linear-gradient( mask: linear-gradient(
to right, to right,
transparent, transparent,

View File

@ -176,6 +176,12 @@ const menuDef = computed(() => [
to: "/settings/sounds", to: "/settings/sounds",
active: currentPage?.route.name === "sounds", active: currentPage?.route.name === "sounds",
}, },
{
icon: "ph-heart ph-bold ph-lg",
text: i18n.ts._wellness.name,
to: "/settings/wellness",
active: currentPage?.route.name === "wellness",
},
{ {
icon: "ph-plug ph-bold ph-lg", icon: "ph-plug ph-bold ph-lg",
text: i18n.ts.plugins, text: i18n.ts.plugins,

View File

@ -118,6 +118,8 @@ const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [
"expandOnNoteClick", "expandOnNoteClick",
"alwaysExpandCws", "alwaysExpandCws",
"cwStyle", "cwStyle",
"newPostsButton",
"newPostsGlowOpacity",
]; ];
const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [ const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
"lightTheme", "lightTheme",

View File

@ -0,0 +1,47 @@
<template>
<div class="_formRoot">
<MkInfo>
{{ i18n.ts._wellness.description }}
</MkInfo>
<FormSection>
<template #label>{{ i18n.ts._wellness.immediacy }}</template>
<FormSwitch v-model="newPostsButton" class="_formBlock">{{
i18n.ts._wellness.newPostsButton
}}</FormSwitch>
<FormRange
v-model="newPostsGlowOpacity"
:min="0"
:max="1"
:step="0.05"
:text-converter="(v) => `${Math.floor(v * 100)}%`"
class="_formBlock"
>
<template #label>{{ i18n.ts._wellness.newPostsGlowOpacity }}</template>
</FormRange>
</FormSection>
</div>
</template>
<script lang="ts" setup>
import { computed } from "vue";
import FormRange from "@/components/form/range.vue";
import { defaultStore } from "@/store";
import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata";
import FormSwitch from "@/components/form/switch.vue";
import MkInfo from "@/components/MkInfo.vue";
import FormSection from "@/components/form/section.vue";
const newPostsButton = computed(
defaultStore.makeGetterSetter("newPostsButton"),
);
const newPostsGlowOpacity = computed(
defaultStore.makeGetterSetter("newPostsGlowOpacity"),
);
definePageMetadata({
title: i18n.ts._wellness.wellness,
icon: "ph-heart ph-bold ph-lg",
});
</script>

View File

@ -261,6 +261,11 @@ export const routes = [
name: "other", name: "other",
component: page(() => import("./pages/settings/other.vue")), component: page(() => import("./pages/settings/other.vue")),
}, },
{
path: "/wellness",
name: "wellness",
component: page(() => import("./pages/settings/wellness.vue")),
},
{ {
path: "/", path: "/",
component: page(() => import("./pages/_empty_.vue")), component: page(() => import("./pages/_empty_.vue")),

View File

@ -343,6 +343,14 @@ export const defaultStore = markRaw(
where: "device", where: "device",
default: false, default: false,
}, },
newPostsButton: {
where: "device",
default: true,
},
newPostsGlowOpacity: {
where: "device",
default: 1.0,
},
}), }),
); );