feat: ゲーミングモード

This commit is contained in:
mattyatea 2023-09-23 09:01:20 +09:00
parent 093540375d
commit 13de104634
28 changed files with 2917 additions and 865 deletions

View file

@ -20,8 +20,8 @@ SPDX-License-Identifier: AGPL-3.0-only
[$style.large]: large,
[$style.transparent]: transparent,
[$style.asLike]: asLike,
[$style.gamingDark]: gaming === 'dark', // gaming1gamingDark
[$style.gamingLight]: gaming === 'light', // gaming2gamingLight
[$style.gamingDark]: gaming === 'dark',
[$style.gamingLight]: gaming === 'light',
}
]"
:type="type"
@ -50,8 +50,8 @@ SPDX-License-Identifier: AGPL-3.0-only
[$style.large]: large,
[$style.transparent]: transparent,
[$style.asLike]: asLike,
[$style.gamingDark]: gaming === 'dark', // gaming1gamingDark
[$style.gamingLight]: gaming === 'light', // gaming2gamingLight
[$style.gamingDark]: gaming === 'dark',
[$style.gamingLight]: gaming === 'light',
}
]"
:to="to"
@ -96,18 +96,18 @@ const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
let gaming = ref(''); // 0-off , 1-dark , 2-light
// gaming.value
if (darkMode.value && gamingMode.value && props.primary) {
if (darkMode.value && gamingMode.value && props.primary || props.gradate ) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value && props.primary) {
} else if (!darkMode.value && gamingMode.value && props.primary|| props.gradate ) {
gaming.value = 'light';
}else{
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value && props.primary) {
if (darkMode.value && gamingMode.value && props.primary || props.gradate || props.large || props.small || props.full ) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value && props.primary) {
} else if (!darkMode.value && gamingMode.value && props.primary || props.gradate || props.large || props.small || props.full ) {
gaming.value = 'light';
}else{
gaming.value = '';
@ -115,9 +115,9 @@ watch(darkMode, () => {
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value && props.primary) {
if (darkMode.value && gamingMode.value && props.primary || props.gradate || props.large || props.small || props.full ) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value && props.primary) {
} else if (!darkMode.value && gamingMode.value && props.primary || props.gradate || props.large || props.small || props.full ) {
gaming.value = 'light';
}else{
gaming.value = '';
@ -290,53 +290,53 @@ function onMousedown(evt: MouseEvent): void {
}
&.gamingLight {
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;
animation: AnimationLight 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;
color: white !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
&:not(:disabled):hover {
background: linear-gradient(270deg, #d08c8c, #cfb28c, #dbdb8b, #95d08e, #8bdbdb, #94a9cf, #b09ecf, #cfa0cf, #e0a0bd);
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;
animation: AnimationLight 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;
color: white !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&:not(:disabled):active {
background: linear-gradient(270deg, #d08c8c, #cfb28c, #dbdb8b, #95d08e, #8bdbdb, #94a9cf, #b09ecf, #cfa0cf, #e0a0bd);
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.45, 0.30, 1) infinite ;
animation: AnimationLight 45s cubic-bezier(0, 0.45, 0.30, 1) infinite ;
color: white !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite ;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite ;
}
}
&.gamingDark {
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800%;
color: white !important;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.45, 0.30, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.45, 0.30, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.45, 0.30, 1) infinite;
&:not(:disabled):hover {
background: linear-gradient(270deg, #a84f4f, #a88c4f, #9aa24b, #6da85c, #53a8a6, #7597b5, #8679b5, #b579b5, #b56d96);
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% ;
color: white !important;
-webkit-animation: AnimationDark 45s cubic-bezier(0, 0.45, 0.30, 1) infinite ;
-moz-animation: AnimationDark 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;
animation: AnimationDark 45s cubic-bezier(0, 0.45, 0.30, 1) infinite ;
}
&:not(:disabled):active {
background: linear-gradient(270deg, #a84f4f, #a88c4f, #9aa24b, #6da85c, #53a8a6, #7597b5, #8679b5, #b579b5, #b56d96);
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
color: white !important;
-webkit-animation: AnimationDark 45s cubic-bezier(0, 0.45, 0.30, 1) infinite ;
-moz-animation: AnimationDark 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;
animation: AnimationDark 45s cubic-bezier(0, 0.45, 0.30, 1) infinite;

View file

@ -6,28 +6,29 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<button
class="_button"
:class="[$style.root, { [$style.wait]: wait, [$style.active]: isFollowing, [$style.full]: full }]"
:class="[$style.root, { [$style.wait]: wait, [$style.active]: isFollowing, [$style.full]: full },[$style.text,{[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light'}]]"
:disabled="wait"
@click="onClick"
>
<template v-if="!wait">
<template v-if="isFollowing">
<span v-if="full" :class="$style.text">{{ i18n.ts.unfollow }}</span><i class="ti ti-minus"></i>
<span v-if="full" :class="[$style.text,{[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light'}]">{{ i18n.ts.unfollow }}</span><i class="ti ti-minus"></i>
</template>
<template v-else>
<span v-if="full" :class="$style.text">{{ i18n.ts.follow }}</span><i class="ti ti-plus"></i>
<span v-if="full" :class="[$style.text,{[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light'}]">{{ i18n.ts.follow }}</span><i class="ti ti-plus"></i>
</template>
</template>
<template v-else>
<span v-if="full" :class="$style.text">{{ i18n.ts.processing }}</span><MkLoading :em="true"/>
<span v-if="full" :class="[$style.text,{[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light'}]">{{ i18n.ts.processing }}</span><MkLoading :em="true"/>
</template>
</button>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import {computed, ref, watch} from 'vue';
import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import {defaultStore} from "@/store.js";
const props = withDefaults(defineProps<{
channel: Record<string, any>;
@ -36,6 +37,39 @@ const props = withDefaults(defineProps<{
full: false,
});
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
console.log(gaming)
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const isFollowing = ref<boolean>(props.channel.isFollowing);
const wait = ref(false);
@ -75,7 +109,28 @@ async function onClick() {
font-size: 16px;
border-radius: 32px;
background: #fff;
&.gamingDark {
color: black;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
&.gamingLight {
color: #fff;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
&.full {
padding: 0 8px 0 12px;
font-size: 14px;
@ -107,25 +162,83 @@ async function onClick() {
//background: mix($primary, #fff, 40);
}
&.active {
color: var(--fgOnAccent);
background: var(--accent);
&.active {
color: var(--fgOnAccent);
background: var(--accent);
&:hover {
background: var(--accentLighten);
border-color: var(--accentLighten);
}
&:hover {
background: var(--accentLighten);
border-color: var(--accentLighten);
}
&:active {
background: var(--accentDarken);
border-color: var(--accentDarken);
}
}
&:active {
background: var(--accentDarken);
border-color: var(--accentDarken);
}
&.wait {
cursor: wait !important;
opacity: 0.7;
}
&.gamingDark:hover {
-webkit-text-fill-color: unset;
color: black;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingDark:active {
-webkit-text-fill-color: unset !important;
color: white;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
border-color: white;
}
&.gamingLight:hover {
-webkit-text-fill-color: unset !important;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
border-color: white;
}
&.gamingLight:active {
-webkit-text-fill-color: unset !important;
color: white;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
border-color: white;
}
&.gamingDark {
-webkit-text-fill-color: unset !important;
color: black;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingLight {
-webkit-text-fill-color: unset !important;
color: white;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
&.wait {
cursor: wait !important;
opacity: 0.7;
}
}
}
.text {

View file

@ -77,7 +77,6 @@ if (darkMode.value && gamingMode.value == true) {
}
watch(darkMode, () => {
console.log(gaming)
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
@ -198,6 +197,27 @@ onBeforeUnmount(() => {
border-radius: 32px;
background: #fff;
&.gamingDark {
color: black;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
&.gamingLight {
color: #dee7e4;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
&.full {
padding: 0 8px 0 12px;
font-size: 14px;
@ -250,56 +270,60 @@ onBeforeUnmount(() => {
}
&.gamingDark:hover {
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-webkit-text-fill-color: unset;
color: white;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingDark:active {
-webkit-text-fill-color: unset !important;
color: white;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
border-color: white;
}
&.gamingLight:hover {
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
-webkit-text-fill-color: unset !important;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
border-color: white;
}
&.gamingLight:active {
-webkit-text-fill-color: unset !important;
color: white;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
border-color: white;
}
&.gamingDark {
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-webkit-text-fill-color: unset !important;
color: white;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingLight {
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-webkit-text-fill-color: unset !important;
color: white;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
@ -315,23 +339,13 @@ onBeforeUnmount(() => {
margin-right: 6px;
&.gamingDark {
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
color: black;
-webkit-text-fill-color: unset !important;
}
&.gamingLight {
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
color: white;
-webkit-text-fill-color: unset !important;
}
}

View file

@ -8,12 +8,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="szkkfdyq _popup _shadow" :class="{ asDrawer: type === 'drawer' }" :style="{ maxHeight: maxHeight ? maxHeight + 'px' : '' }">
<div class="main">
<template v-for="item in items">
<button v-if="item.action" v-click-anime class="_button item" @click="$event => { item.action($event); close(); }">
<button v-if="item.action" v-click-anime class="_button item" :class="{gamingDark: gaming === 'dark',gamingLight: gaming === 'light' }" @click="$event => { item.action($event); close(); }">
<i class="icon" :class="item.icon"></i>
<div class="text">{{ item.text }}</div>
<span v-if="item.indicate" class="indicator"><i class="_indicatorCircle"></i></span>
</button>
<MkA v-else v-click-anime :to="item.to" class="item" @click.passive="close()">
<MkA v-else v-click-anime :to="item.to" class="item" :class="{gamingDark: gaming === 'dark',gamingLight: gaming === 'light' }" @click.passive="close()">
<i class="icon" :class="item.icon"></i>
<div class="text">{{ item.text }}</div>
<span v-if="item.indicate" class="indicator"><i class="_indicatorCircle"></i></span>
@ -25,12 +25,43 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref , computed , watch} from 'vue';
import MkModal from '@/components/MkModal.vue';
import { navbarItemDef } from '@/navbar';
import { defaultStore } from '@/store.js';
import { deviceKind } from '@/scripts/device-kind.js';
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const props = withDefaults(defineProps<{
src?: HTMLElement;
anchor?: { x: string; y: string; };
@ -98,7 +129,20 @@ function close() {
vertical-align: bottom;
height: 100px;
border-radius: 10px;
&.gamingDark:hover{
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
color: black;
}
&.gamingLight:hover{
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
color: white;
}
&:hover {
color: var(--accent);
background: var(--accentedBg);
@ -132,4 +176,69 @@ function close() {
}
}
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<MkA v-user-preview="canonical" :class="[$style.root, { [$style.isMe]: isMe }]" :to="url" :style="{ background: bgCss }">
<MkA v-user-preview="canonical" :class="[$style.root, { [$style.isMe]: isMe && gaming === '' , [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]" :to="url" :style="{ background: bgCss }">
<img :class="$style.icon" :src="`/avatar/@${username}@${host}`" alt="">
<span>
<span>@{{ username }}</span>
@ -15,12 +15,43 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { toUnicode } from 'punycode';
import {computed, ref, watch} from 'vue';
import { } from 'vue';
import tinycolor from 'tinycolor2';
import { host as localHost } from '@/config.js';
import { $i } from '@/account.js';
import { defaultStore } from '@/store.js';
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const props = defineProps<{
username: string;
host: string;
@ -36,7 +67,8 @@ const isMe = $i && (
const bg = tinycolor(getComputedStyle(document.documentElement).getPropertyValue(isMe ? '--mentionMe' : '--mention'));
bg.setAlpha(0.1);
const bgCss = bg.toRgbString();
const bgCss = (gaming.value === '') ? bg.toRgbString() : "";
//const bgCss = `background:${bg.toRgbString()}; ${result}` ;
</script>
<style lang="scss" module>
@ -46,8 +78,26 @@ const bgCss = bg.toRgbString();
border-radius: 999px;
color: var(--mention);
&.gamingLight{
color: white;
opacity: 0.9;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
&.gamingDark{
opacity: 0.9;
color: white;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation:AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation:AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation:AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.isMe {
color: var(--mentionMe);
}
}
@ -63,4 +113,69 @@ const bgCss = bg.toRgbString();
.host {
opacity: 0.5;
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -14,44 +14,44 @@ SPDX-License-Identifier: AGPL-3.0-only
>
<template v-for="(item, i) in items2">
<div v-if="item === null" role="separator" :class="$style.divider"></div>
<span v-else-if="item.type === 'label'" role="menuitem" :class="[$style.label, $style.item]">
<span v-else-if="item.type === 'label'" role="menuitem" :class="[$style.label, $style.item, { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]">
<span>{{ item.text }}</span>
</span>
<span v-else-if="item.type === 'pending'" role="menuitem" :tabindex="i" :class="[$style.pending, $style.item]">
<span v-else-if="item.type === 'pending'" role="menuitem" :tabindex="i" :class="[$style.pending, $style.item, { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]">
<span><MkEllipsis/></span>
</span>
<MkA v-else-if="item.type === 'link'" role="menuitem" :to="item.to" :tabindex="i" class="_button" :class="$style.item" @click.passive="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<MkA v-else-if="item.type === 'link'" role="menuitem" :to="item.to" :tabindex="i" class="_button" :class="$style.item, { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }" @click.passive="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
<MkAvatar v-if="item.avatar" :user="item.avatar" :class="$style.avatar"/>
<span>{{ item.text }}</span>
<span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span>
</MkA>
<a v-else-if="item.type === 'a'" role="menuitem" :href="item.href" :target="item.target" :download="item.download" :tabindex="i" class="_button" :class="$style.item" @click="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<a v-else-if="item.type === 'a'" role="menuitem" :href="item.href" :target="item.target" :download="item.download" :tabindex="i" class="_button" :class="$style.item, { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }" @click="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
<span>{{ item.text }}</span>
<span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span>
</a>
<button v-else-if="item.type === 'user'" role="menuitem" :tabindex="i" class="_button" :class="[$style.item, { [$style.active]: item.active }]" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<button v-else-if="item.type === 'user'" role="menuitem" :tabindex="i" class="_button" :class="[$style.item, { [$style.active]: item.active }, { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<MkAvatar :user="item.user" :class="$style.avatar"/><MkUserName :user="item.user"/>
<span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span>
</button>
<button v-else-if="item.type === 'switch'" role="menuitemcheckbox" :tabindex="i" class="_button" :class="[$style.item, $style.switch, { [$style.switchDisabled]: item.disabled } ]" @click="switchItem(item)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<button v-else-if="item.type === 'switch'" role="menuitemcheckbox" :tabindex="i" class="_button" :class="[$style.item, $style.switch, { [$style.switchDisabled]: item.disabled } , { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]" @click="switchItem(item)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<MkSwitchButton :class="$style.switchButton" :checked="item.ref" :disabled="item.disabled" @toggle="switchItem(item)" />
<span :class="$style.switchText">{{ item.text }}</span>
</button>
<div v-else-if="item.type === 'parent'" role="menuitem" :tabindex="i" :class="[$style.item, $style.parent, { [$style.childShowing]: childShowingItem === item }]" @mouseenter="preferClick ? null : showChildren(item, $event)" @click="!preferClick ? null : showChildren(item, $event)">
<div v-else-if="item.type === 'parent'" role="menuitem" :tabindex="i" :class="[$style.item, $style.parent, { [$style.childShowing]: childShowingItem === item } , { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]" @mouseenter="preferClick ? null : showChildren(item, $event)" @click="!preferClick ? null : showChildren(item, $event)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
<span>{{ item.text }}</span>
<span :class="$style.caret"><i class="ti ti-chevron-right ti-fw"></i></span>
</div>
<button v-else :tabindex="i" class="_button" role="menuitem" :class="[$style.item, { [$style.danger]: item.danger, [$style.active]: item.active }]" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
<button v-else :tabindex="i" class="_button" role="menuitem" :class="[$style.item, { [$style.danger]: item.danger, [$style.active]: item.active }, { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon, { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]"></i>
<MkAvatar v-if="item.avatar" :user="item.avatar" :class="$style.avatar"/>
<span>{{ item.text }}</span>
<span v-if="item.indicate" :class="$style.indicator"><i class="_indicatorCircle"></i></span>
</button>
</template>
<span v-if="items2.length === 0" :class="[$style.none, $style.item]">
<span v-if="items2.length === 0" :class="[$style.none, $style.item, { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]">
<span>{{ i18n.ts.none }}</span>
</span>
</div>
@ -62,14 +62,51 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts">
import { Ref, defineAsyncComponent, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import {Ref, defineAsyncComponent, nextTick, onBeforeUnmount, onMounted, ref, watch, computed} from 'vue';
import { focusPrev, focusNext } from '@/scripts/focus.js';
import MkSwitchButton from '@/components/MkSwitch.button.vue';
import { MenuItem, InnerMenuItem, MenuPending, MenuAction, MenuSwitch, MenuParent } from '@/types/menu';
import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { isTouchUsing } from '@/scripts/touch.js';
import {defaultStore} from '@/store.js'
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
document.documentElement.style.setProperty('--accent', '#fff');
document.documentElement.style.setProperty('--accentLighten', '#fff');
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
document.documentElement.style.setProperty('--accent', '#fff');
document.documentElement.style.setProperty('--accentLighten', '#fff');
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
document.documentElement.style.setProperty('--accent', '#fff');
document.documentElement.style.setProperty('--accentLighten', '#fff');
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const childrenCache = new WeakMap<MenuParent, MenuItem[]>();
</script>
@ -294,10 +331,32 @@ onBeforeUnmount(() => {
&:not(:disabled):hover {
color: var(--accent);
text-decoration: none;
&:before {
background: var(--accentedBg);
}
&.gamingDark{
color:black !important;
}
&.gamingLight{
color:white !important;
}
&.gamingDark:before{
color:black !important;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingLight:before{
color:white !important;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
&:before {
background: var(--accentedBg);
}
}
&.danger {
@ -322,12 +381,32 @@ onBeforeUnmount(() => {
&:active,
&.active {
color: var(--fgOnAccent) !important;
color: var(--fgOnAccent);
opacity: 1;
&.gamingDark{
color:black !important;
}
&.gamingLight{
color:white !important;
}
&:before {
background: var(--accent) !important;
background: var(--accent);
}
&.gamingDark:before{
color:black !important;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingLight:before{
color:white !important;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
}
&:not(:active):focus-visible {
@ -364,9 +443,32 @@ onBeforeUnmount(() => {
color: var(--accent);
text-decoration: none;
&:before {
background: var(--accentedBg);
}
&:before {
background: var(--accentedBg);
}
&.gamingDark{
color:black !important;
}
&.gamingLight{
color:white !important;
}
&.gamingDark:before{
color:black !important;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingLight:before{
color:white !important;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
}
}
}
@ -429,4 +531,69 @@ onBeforeUnmount(() => {
margin: 8px 0;
border-top: solid 0.5px var(--divider);
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -131,9 +131,9 @@ SPDX-License-Identifier: AGPL-3.0-only
</footer>
</article>
<div :class="$style.tabs">
<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'replies' }]" @click="tab = 'replies'"><i class="ti ti-arrow-back-up"></i> {{ i18n.ts.replies }}</button>
<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'renotes' }]" @click="tab = 'renotes'"><i class="ti ti-repeat"></i> {{ i18n.ts.renotes }}</button>
<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'reactions' }]" @click="tab = 'reactions'"><i class="ti ti-icons"></i> {{ i18n.ts.reactions }}</button>
<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'replies' },{[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' && tab === 'replies'}]" @click="tab = 'replies'"><i class="ti ti-arrow-back-up"></i> {{ i18n.ts.replies }}</button>
<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'renotes'},{[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' && tab === 'renotes'}]" @click="tab = 'renotes'"><i class="ti ti-repeat"></i> {{ i18n.ts.renotes }}</button>
<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'reactions'},{[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' && tab === 'reactions'}]" @click="tab = 'reactions'"><i class="ti ti-icons"></i> {{ i18n.ts.reactions }}</button>
</div>
<div>
<div v-if="tab === 'replies'" :class="$style.tab_replies">
@ -180,7 +180,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed, inject, onMounted, ref, shallowRef } from 'vue';
import {computed, inject, onMounted, ref, shallowRef, watch} from 'vue';
import * as mfm from 'mfm-js';
import * as Misskey from 'misskey-js';
import MkNoteSub from '@/components/MkNoteSub.vue';
@ -223,6 +223,39 @@ const inChannel = inject('inChannel', null);
let note = $ref(deepClone(props.note));
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
console.log(gaming)
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
// plugin
if (noteViewInterruptors.length > 0) {
onMounted(async () => {
@ -730,6 +763,9 @@ function loadConversation() {
.tabActive {
border-bottom: solid 2px var(--accent);
&.gamingLight{
border-bottom: solid 2px black;
}
}
.tab_renotes {
@ -755,6 +791,12 @@ function loadConversation() {
.reactionTabActive {
border-color: var(--accent);
&.gamingLight{
border-bottom: solid 2px black;
}
&.gamingDark{
border-bottom: solid 2px black;
}
}
@container (max-width: 500px) {
@ -808,4 +850,37 @@ function loadConversation() {
text-align: center;
opacity: 0.7;
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div
v-adaptive-border
:class="[$style.root, { [$style.disabled]: disabled, [$style.checked]: checked }]"
:class="[$style.root, { [$style.disabled]: disabled, [$style.checked]: checked ,[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' } ]"
:aria-checked="checked"
:aria-disabled="disabled"
@click="toggle"
@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:disabled="disabled"
:class="$style.input"
>
<span :class="$style.button">
<span :class="[$style.button , {[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light'}]">
<span></span>
</span>
<span :class="$style.label"><slot></slot></span>
@ -24,8 +24,40 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref,computed,watch } from 'vue';
import {defaultStore} from "@/store.js";
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const props = defineProps<{
modelValue: any;
value: any;
@ -74,14 +106,48 @@ function toggle(): void {
border-color: var(--accentedBg) !important;
color: var(--accent);
cursor: default !important;
&.gamingDark{
color:black !important;
border-color: black !important;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
}
&.gamingLight{
color:white;
border-color: white !important;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
}
> .button {
border-color: var(--accent);
&.gamingDark{
border-color:black;
color:black !important;
}
&.gamingLight{
border-color: white;
color:white;
}
&.gamingDark:after{
background-color: black;
transform: scale(1);
opacity: 1;
}
&.gamingLight:after{
background-color:white !important;
transform: scale(1);
opacity: 1;
}
&:after {
background-color: var(--accent);
transform: scale(1);
opacity: 1;
}
}
}
@ -125,4 +191,69 @@ function toggle(): void {
line-height: 20px;
cursor: pointer;
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -9,12 +9,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-adaptive-border class="body">
<div ref="containerEl" class="container">
<div class="track">
<div class="highlight" :style="{ width: (steppedRawValue * 100) + '%' }"></div>
<div :class="{gamingDark: gaming === 'dark',gamingLight: gaming === 'light'}" class="highlight" :style="{ width: (steppedRawValue * 100) + '%' }"></div>
</div>
<div v-if="steps && showTicks" class="ticks">
<div v-for="i in (steps + 1)" class="tick" :style="{ left: (((i - 1) / steps) * 100) + '%' }"></div>
</div>
<div ref="thumbEl" v-tooltip="textConverter(finalValue)" class="thumb" :style="{ left: thumbPosition + 'px' }" @mousedown="onMousedown" @touchstart="onMousedown"></div>
<div ref="thumbEl" v-tooltip="textConverter(finalValue)" :class="{gamingDark: gaming === 'dark',gamingLight: gaming === 'light'}" class="thumb" :style="{ left: thumbPosition + 'px' }" @mousedown="onMousedown" @touchstart="onMousedown"></div>
</div>
</div>
<div class="caption"><slot name="caption"></slot></div>
@ -24,7 +24,41 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { computed, defineAsyncComponent, onMounted, onUnmounted, ref, watch, shallowRef } from 'vue';
import * as os from '@/os.js';
import {defaultStore} from "@/store.js";
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
console.log(gaming)
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const props = withDefaults(defineProps<{
modelValue: number;
disabled?: boolean;
@ -207,6 +241,20 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
height: 100%;
background: var(--accent);
opacity: 0.5;
&.gamingLight{
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingDark{
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
}
}
@ -239,9 +287,36 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
cursor: grab;
background: var(--accent);
border-radius: 999px;
&.gamingDark{
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
&.gamingLight{
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&:hover {
background: var(--accentLighten);
&.gamingDark{
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
&.gamingLight{
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
}
}
}
@ -263,4 +338,69 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
}
}
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -8,16 +8,16 @@ SPDX-License-Identifier: AGPL-3.0-only
ref="buttonEl"
v-ripple="canToggle"
class="_button"
:class="[$style.root, { [$style.reacted]: note.myReaction == reaction, [$style.canToggle]: canToggle, [$style.small]: defaultStore.state.reactionsDisplaySize === 'small', [$style.large]: defaultStore.state.reactionsDisplaySize === 'large' }]"
:class="[$style.root, { [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' ,[$style.reacted]: note.myReaction == reaction, [$style.canToggle]: canToggle, [$style.small]: defaultStore.state.reactionsDisplaySize === 'small', [$style.large]: defaultStore.state.reactionsDisplaySize === 'large' }]"
@click="toggleReaction()"
>
<MkReactionIcon :class="$style.icon" :reaction="reaction" :emojiUrl="note.reactionEmojis[reaction.substring(1, reaction.length - 1)]"/>
<span :class="$style.count">{{ count }}</span>
<span :class="[$style.count,{ [$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light'}]">{{ count }}</span>
</button>
</template>
<script lang="ts" setup>
import { computed, onMounted, shallowRef, watch } from 'vue';
import {computed, onMounted, ref, shallowRef, watch} from 'vue';
import * as Misskey from 'misskey-js';
import XDetails from '@/components/MkReactionsViewer.details.vue';
import MkReactionIcon from '@/components/MkReactionIcon.vue';
@ -29,6 +29,37 @@ import { claimAchievement } from '@/scripts/achievements.js';
import { defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const props = defineProps<{
reaction: string;
count: number;
@ -160,8 +191,29 @@ useTooltip(buttonEl, async (showing) => {
color: var(--accent);
box-shadow: 0 0 0px 1px var(--accent) inset;
&.gamingDark{
color:white;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
box-shadow: 0 0 0px 1px white inset;
}
&.gamingLight{
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4); background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
box-shadow: 0 0 0px 1px white inset;
color: white !important;
}
> .count {
color: var(--accent);
&.gamingLight{
color: white;
}
}
> .icon {
@ -179,4 +231,69 @@ useTooltip(buttonEl, async (showing) => {
line-height: 42px;
margin: 0 0 0 4px;
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -4,99 +4,166 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div>
<div :class="$style.banner">
<i class="ti ti-user-edit"></i>
</div>
<MkSpacer :marginMin="20" :marginMax="32">
<form class="_gaps_m" autocomplete="new-password" @submit.prevent="onSubmit">
<MkInput v-if="instance.disableRegistration" v-model="invitationCode" type="text" :spellcheck="false" required>
<template #label>{{ i18n.ts.invitationCode }}</template>
<template #prefix><i class="ti ti-key"></i></template>
</MkInput>
<MkInput v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :spellcheck="false" autocomplete="username" required data-cy-signup-username @update:modelValue="onChangeUsername">
<template #label>{{ i18n.ts.username }} <div v-tooltip:dialog="i18n.ts.usernameInfo" class="_button _help"><i class="ti ti-help-circle"></i></div></template>
<template #prefix>@</template>
<template #suffix>@{{ host }}</template>
<template #caption>
<div><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.cannotBeChangedLater }}</div>
<span v-if="usernameState === 'wait'" style="color:#999"><MkLoading :em="true"/> {{ i18n.ts.checking }}</span>
<span v-else-if="usernameState === 'ok'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
<span v-else-if="usernameState === 'unavailable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
<span v-else-if="usernameState === 'error'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
<span v-else-if="usernameState === 'invalid-format'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.usernameInvalidFormat }}</span>
<span v-else-if="usernameState === 'min-range'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooShort }}</span>
<span v-else-if="usernameState === 'max-range'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooLong }}</span>
</template>
</MkInput>
<MkInput v-if="instance.emailRequiredForSignup" v-model="email" :debounce="true" type="email" :spellcheck="false" required data-cy-signup-email @update:modelValue="onChangeEmail">
<template #label>{{ i18n.ts.emailAddress }} <div v-tooltip:dialog="i18n.ts._signup.emailAddressInfo" class="_button _help"><i class="ti ti-help-circle"></i></div></template>
<template #prefix><i class="ti ti-mail"></i></template>
<template #caption>
<span v-if="emailState === 'wait'" style="color:#999"><MkLoading :em="true"/> {{ i18n.ts.checking }}</span>
<span v-else-if="emailState === 'ok'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
<span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span>
<span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span>
<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span>
<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span>
<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span>
<span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
<span v-else-if="emailState === 'error'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
</template>
</MkInput>
<MkInput v-model="password" type="password" autocomplete="new-password" required data-cy-signup-password @update:modelValue="onChangePassword">
<template #label>{{ i18n.ts.password }}</template>
<template #prefix><i class="ti ti-lock"></i></template>
<template #caption>
<span v-if="passwordStrength == 'low'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.weakPassword }}</span>
<span v-if="passwordStrength == 'medium'" style="color: var(--warn)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.normalPassword }}</span>
<span v-if="passwordStrength == 'high'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.strongPassword }}</span>
</template>
</MkInput>
<MkInput v-model="retypedPassword" type="password" autocomplete="new-password" required data-cy-signup-password-retype @update:modelValue="onChangePasswordRetype">
<template #label>{{ i18n.ts.password }} ({{ i18n.ts.retype }})</template>
<template #prefix><i class="ti ti-lock"></i></template>
<template #caption>
<span v-if="passwordRetypeState == 'match'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.passwordMatched }}</span>
<span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.passwordNotMatched }}</span>
</template>
</MkInput>
<MkCaptcha v-if="instance.enableHcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" :class="$style.captcha" provider="hcaptcha" :sitekey="instance.hcaptchaSiteKey"/>
<MkCaptcha v-if="instance.enableRecaptcha" ref="recaptcha" v-model="reCaptchaResponse" :class="$style.captcha" provider="recaptcha" :sitekey="instance.recaptchaSiteKey"/>
<MkCaptcha v-if="instance.enableTurnstile" ref="turnstile" v-model="turnstileResponse" :class="$style.captcha" provider="turnstile" :sitekey="instance.turnstileSiteKey"/>
<MkButton type="submit" :disabled="shouldDisableSubmitting" large gradate rounded data-cy-signup-submit style="margin: 0 auto;">
<template v-if="submitting">
<MkLoading :em="true" :colored="false"/>
</template>
<template v-else>{{ i18n.ts.start }}</template>
</MkButton>
</form>
</MkSpacer>
</div>
<div>
<div :class="[$style.banner ,{[$style.gamingDark]: gaming==='dark' , [$style.gamingLight]: gaming==='light'}]">
<i class="ti ti-user-edit"></i>
</div>
<MkSpacer :marginMin="20" :marginMax="32">
<form class="_gaps_m" autocomplete="new-password" @submit.prevent="onSubmit">
<MkInput v-if="instance.disableRegistration" v-model="invitationCode" type="text" :spellcheck="false" required>
<template #label>{{ i18n.ts.invitationCode }}</template>
<template #prefix><i class="ti ti-key"></i></template>
</MkInput>
<MkInput v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :spellcheck="false"
autocomplete="username" required data-cy-signup-username @update:modelValue="onChangeUsername">
<template #label>{{ i18n.ts.username }}
<div v-tooltip:dialog="i18n.ts.usernameInfo" class="_button _help"><i class="ti ti-help-circle"></i></div>
</template>
<template #prefix>@</template>
<template #suffix>@{{ host }}</template>
<template #caption>
<div><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.cannotBeChangedLater }}</div>
<span v-if="usernameState === 'wait'" style="color:#999"><MkLoading :em="true"/> {{
i18n.ts.checking
}}</span>
<span v-else-if="usernameState === 'ok'" style="color: var(--success)"><i
class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
<span v-else-if="usernameState === 'unavailable'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
<span v-else-if="usernameState === 'error'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
<span v-else-if="usernameState === 'invalid-format'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.usernameInvalidFormat }}</span>
<span v-else-if="usernameState === 'min-range'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooShort }}</span>
<span v-else-if="usernameState === 'max-range'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooLong }}</span>
</template>
</MkInput>
<MkInput v-if="instance.emailRequiredForSignup" v-model="email" :debounce="true" type="email"
:spellcheck="false" required data-cy-signup-email @update:modelValue="onChangeEmail">
<template #label>{{ i18n.ts.emailAddress }}
<div v-tooltip:dialog="i18n.ts._signup.emailAddressInfo" class="_button _help"><i
class="ti ti-help-circle"></i></div>
</template>
<template #prefix><i class="ti ti-mail"></i></template>
<template #caption>
<span v-if="emailState === 'wait'" style="color:#999"><MkLoading :em="true"/> {{ i18n.ts.checking }}</span>
<span v-else-if="emailState === 'ok'" style="color: var(--success)"><i
class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
<span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span>
<span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span>
<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span>
<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span>
<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span>
<span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
<span v-else-if="emailState === 'error'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
</template>
</MkInput>
<MkInput v-model="password" type="password" autocomplete="new-password" required data-cy-signup-password
@update:modelValue="onChangePassword">
<template #label>{{ i18n.ts.password }}</template>
<template #prefix><i class="ti ti-lock"></i></template>
<template #caption>
<span v-if="passwordStrength == 'low'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.weakPassword }}</span>
<span v-if="passwordStrength == 'medium'" style="color: var(--warn)"><i
class="ti ti-check ti-fw"></i> {{ i18n.ts.normalPassword }}</span>
<span v-if="passwordStrength == 'high'" style="color: var(--success)"><i
class="ti ti-check ti-fw"></i> {{ i18n.ts.strongPassword }}</span>
</template>
</MkInput>
<MkInput v-model="retypedPassword" type="password" autocomplete="new-password" required
data-cy-signup-password-retype @update:modelValue="onChangePasswordRetype">
<template #label>{{ i18n.ts.password }} ({{ i18n.ts.retype }})</template>
<template #prefix><i class="ti ti-lock"></i></template>
<template #caption>
<span v-if="passwordRetypeState == 'match'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{
i18n.ts.passwordMatched
}}</span>
<span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i
class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.passwordNotMatched }}</span>
</template>
</MkInput>
<MkCaptcha v-if="instance.enableHcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" :class="$style.captcha"
provider="hcaptcha" :sitekey="instance.hcaptchaSiteKey"/>
<MkCaptcha v-if="instance.enableRecaptcha" ref="recaptcha" v-model="reCaptchaResponse" :class="$style.captcha"
provider="recaptcha" :sitekey="instance.recaptchaSiteKey"/>
<MkCaptcha v-if="instance.enableTurnstile" ref="turnstile" v-model="turnstileResponse" :class="$style.captcha"
provider="turnstile" :sitekey="instance.turnstileSiteKey"/>
<MkButton type="submit" :disabled="shouldDisableSubmitting" large gradate rounded data-cy-signup-submit
style="margin: 0 auto;">
<template v-if="submitting">
<MkLoading :em="true" :colored="false"/>
</template>
<template v-else>{{ i18n.ts.start }}</template>
</MkButton>
</form>
</MkSpacer>
</div>
</template>
<script lang="ts" setup>
import { } from 'vue';
import { toUnicode } from 'punycode/';
import {computed, ref, watch} from 'vue';
import {toUnicode} from 'punycode/';
import MkButton from './MkButton.vue';
import MkInput from './MkInput.vue';
import MkSwitch from './MkSwitch.vue';
import MkCaptcha, { type Captcha } from '@/components/MkCaptcha.vue';
import MkCaptcha, {type Captcha} from '@/components/MkCaptcha.vue';
import * as config from '@/config.js';
import * as os from '@/os.js';
import { login } from '@/account.js';
import { instance } from '@/instance.js';
import { i18n } from '@/i18n.js';
import {login} from '@/account.js';
import {instance} from '@/instance.js';
import {i18n} from '@/i18n.js';
import {defaultStore} from "@/store.js";
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const props = withDefaults(defineProps<{
autoSet?: boolean;
autoSet?: boolean;
}>(), {
autoSet: false,
autoSet: false,
});
const emit = defineEmits<{
(ev: 'signup', user: Record<string, any>): void;
(ev: 'signupEmailPending'): void;
(ev: 'signup', user: Record<string, any>): void;
(ev: 'signupEmailPending'): void;
}>();
const host = toUnicode(config.host);
@ -122,179 +189,269 @@ let usernameAbortController: null | AbortController = $ref(null);
let emailAbortController: null | AbortController = $ref(null);
const shouldDisableSubmitting = $computed((): boolean => {
return submitting ||
instance.enableHcaptcha && !hCaptchaResponse ||
instance.enableRecaptcha && !reCaptchaResponse ||
instance.enableTurnstile && !turnstileResponse ||
instance.emailRequiredForSignup && emailState !== 'ok' ||
usernameState !== 'ok' ||
passwordRetypeState !== 'match';
return submitting ||
instance.enableHcaptcha && !hCaptchaResponse ||
instance.enableRecaptcha && !reCaptchaResponse ||
instance.enableTurnstile && !turnstileResponse ||
instance.emailRequiredForSignup && emailState !== 'ok' ||
usernameState !== 'ok' ||
passwordRetypeState !== 'match';
});
function getPasswordStrength(source: string): number {
let strength = 0;
let power = 0.018;
let strength = 0;
let power = 0.018;
//
if (/[a-zA-Z]/.test(source) && /[0-9]/.test(source)) {
power += 0.020;
}
//
if (/[a-zA-Z]/.test(source) && /[0-9]/.test(source)) {
power += 0.020;
}
//
if (/[a-z]/.test(source) && /[A-Z]/.test(source)) {
power += 0.015;
}
//
if (/[a-z]/.test(source) && /[A-Z]/.test(source)) {
power += 0.015;
}
//
if (/[!\x22\#$%&@'()*+,-./_]/.test(source)) {
power += 0.02;
}
//
if (/[!\x22\#$%&@'()*+,-./_]/.test(source)) {
power += 0.02;
}
strength = power * source.length;
strength = power * source.length;
return Math.max(0, Math.min(1, strength));
return Math.max(0, Math.min(1, strength));
}
function onChangeUsername(): void {
if (username === '') {
usernameState = null;
return;
}
if (username === '') {
usernameState = null;
return;
}
{
const err =
!username.match(/^[a-zA-Z0-9_]+$/) ? 'invalid-format' :
username.length < 1 ? 'min-range' :
username.length > 20 ? 'max-range' :
null;
{
const err =
!username.match(/^[a-zA-Z0-9_]+$/) ? 'invalid-format' :
username.length < 1 ? 'min-range' :
username.length > 20 ? 'max-range' :
null;
if (err) {
usernameState = err;
return;
}
}
if (err) {
usernameState = err;
return;
}
}
if (usernameAbortController != null) {
usernameAbortController.abort();
}
usernameState = 'wait';
usernameAbortController = new AbortController();
if (usernameAbortController != null) {
usernameAbortController.abort();
}
usernameState = 'wait';
usernameAbortController = new AbortController();
os.api('username/available', {
username,
}, undefined, usernameAbortController.signal).then(result => {
usernameState = result.available ? 'ok' : 'unavailable';
}).catch((err) => {
if (err.name !== 'AbortError') {
usernameState = 'error';
}
});
os.api('username/available', {
username,
}, undefined, usernameAbortController.signal).then(result => {
usernameState = result.available ? 'ok' : 'unavailable';
}).catch((err) => {
if (err.name !== 'AbortError') {
usernameState = 'error';
}
});
}
function onChangeEmail(): void {
if (email === '') {
emailState = null;
return;
}
if (email === '') {
emailState = null;
return;
}
if (emailAbortController != null) {
emailAbortController.abort();
}
emailState = 'wait';
emailAbortController = new AbortController();
if (emailAbortController != null) {
emailAbortController.abort();
}
emailState = 'wait';
emailAbortController = new AbortController();
os.api('email-address/available', {
emailAddress: email,
}, undefined, emailAbortController.signal).then(result => {
emailState = result.available ? 'ok' :
result.reason === 'used' ? 'unavailable:used' :
result.reason === 'format' ? 'unavailable:format' :
result.reason === 'disposable' ? 'unavailable:disposable' :
result.reason === 'mx' ? 'unavailable:mx' :
result.reason === 'smtp' ? 'unavailable:smtp' :
'unavailable';
}).catch((err) => {
if (err.name !== 'AbortError') {
emailState = 'error';
}
});
os.api('email-address/available', {
emailAddress: email,
}, undefined, emailAbortController.signal).then(result => {
emailState = result.available ? 'ok' :
result.reason === 'used' ? 'unavailable:used' :
result.reason === 'format' ? 'unavailable:format' :
result.reason === 'disposable' ? 'unavailable:disposable' :
result.reason === 'mx' ? 'unavailable:mx' :
result.reason === 'smtp' ? 'unavailable:smtp' :
'unavailable';
}).catch((err) => {
if (err.name !== 'AbortError') {
emailState = 'error';
}
});
}
function onChangePassword(): void {
if (password === '') {
passwordStrength = '';
return;
}
if (password === '') {
passwordStrength = '';
return;
}
const strength = getPasswordStrength(password);
passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
const strength = getPasswordStrength(password);
passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
}
function onChangePasswordRetype(): void {
if (retypedPassword === '') {
passwordRetypeState = null;
return;
}
if (retypedPassword === '') {
passwordRetypeState = null;
return;
}
passwordRetypeState = password === retypedPassword ? 'match' : 'not-match';
passwordRetypeState = password === retypedPassword ? 'match' : 'not-match';
}
async function onSubmit(): Promise<void> {
if (submitting) return;
submitting = true;
if (submitting) return;
submitting = true;
try {
await os.api('signup', {
username,
password,
emailAddress: email,
invitationCode,
'hcaptcha-response': hCaptchaResponse,
'g-recaptcha-response': reCaptchaResponse,
'turnstile-response': turnstileResponse,
});
if (instance.emailRequiredForSignup) {
os.alert({
type: 'success',
title: i18n.ts._signup.almostThere,
text: i18n.t('_signup.emailSent', { email }),
});
emit('signupEmailPending');
} else {
const res = await os.api('signin', {
username,
password,
});
emit('signup', res);
try {
await os.api('signup', {
username,
password,
emailAddress: email,
invitationCode,
'hcaptcha-response': hCaptchaResponse,
'g-recaptcha-response': reCaptchaResponse,
'turnstile-response': turnstileResponse,
});
if (instance.emailRequiredForSignup) {
os.alert({
type: 'success',
title: i18n.ts._signup.almostThere,
text: i18n.t('_signup.emailSent', {email}),
});
emit('signupEmailPending');
} else {
const res = await os.api('signin', {
username,
password,
});
emit('signup', res);
if (props.autoSet) {
return login(res.i);
}
}
} catch {
submitting = false;
hcaptcha?.reset?.();
recaptcha?.reset?.();
turnstile?.reset?.();
if (props.autoSet) {
return login(res.i);
}
}
} catch {
submitting = false;
hcaptcha?.reset?.();
recaptcha?.reset?.();
turnstile?.reset?.();
os.alert({
type: 'error',
text: i18n.ts.somethingHappened,
});
}
os.alert({
type: 'error',
text: i18n.ts.somethingHappened,
});
}
}
</script>
<style lang="scss" module>
.banner {
padding: 16px;
text-align: center;
font-size: 26px;
background-color: var(--accentedBg);
color: var(--accent);
padding: 16px;
text-align: center;
font-size: 26px;
background-color: var(--accentedBg);
color: var(--accent);
&.gamingDark {
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingLight {
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationLight cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationLight cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationLight cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
}
.captcha {
margin: 16px 0;
margin: 16px 0;
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div>
<div :class="$style.banner">
<div :class="[$style.banner ,{[$style.gamingDark]: gaming==='dark' , [$style.gamingLight]: gaming==='light'}]">
<i class="ti ti-checklist"></i>
</div>
<MkSpacer :marginMin="20" :marginMax="28">
@ -68,7 +68,39 @@ import MkFolder from '@/components/MkFolder.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkInfo from '@/components/MkInfo.vue';
import * as os from '@/os.js';
import {defaultStore} from "@/store.js";
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const availableServerRules = instance.serverRules.length > 0;
const availableTos = instance.tosUrl != null;
@ -130,11 +162,29 @@ async function updateAgreeNote(v: boolean) {
<style lang="scss" module>
.banner {
padding: 16px;
text-align: center;
font-size: 26px;
background-color: var(--accentedBg);
color: var(--accent);
padding: 16px;
text-align: center;
font-size: 26px;
background-color: var(--accentedBg);
color: var(--accent);
&.gamingDark {
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingLight {
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationLight cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationLight cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationLight cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
}
.rules {
@ -172,4 +222,70 @@ async function updateAgreeNote(v: boolean) {
.ruleText {
padding-top: 6px;
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -10,15 +10,15 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="items">
<template v-for="(item, i) in group.items">
<a v-if="item.type === 'a'" :href="item.href" :target="item.target" :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active }">
<a v-if="item.type === 'a'" :href="item.href" :target="item.target" :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active, gamingDark: gaming === 'dark',gamingLight: gaming === 'light' }">
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
<span class="text">{{ item.text }}</span>
</a>
<button v-else-if="item.type === 'button'" :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active }" :disabled="item.active" @click="ev => item.action(ev)">
<button v-else-if="item.type === 'button'" :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active , gamingDark: gaming === 'dark',gamingLight: gaming === 'light' }" :disabled="item.active" @click="ev => item.action(ev)">
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
<span class="text">{{ item.text }}</span>
</button>
<MkA v-else :to="item.to" :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active }">
<MkA v-else :to="item.to" :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active , gamingDark: gaming === 'dark',gamingLight: gaming === 'light' }">
<span v-if="item.icon" class="icon"><i :class="item.icon" class="ti-fw"></i></span>
<span class="text">{{ item.text }}</span>
</MkA>
@ -29,8 +29,40 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { } from 'vue';
import {ref , computed , watch } from 'vue';
import {defaultStore} from "@/store.js";
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
defineProps<{
def: any[];
grid?: boolean;
@ -70,6 +102,21 @@ defineProps<{
&.active {
color: var(--accent);
background: var(--accentedBg);
&.gamingDark{
color: black !important;
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd); background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingLight{
color: white;
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
}
&.danger {
@ -154,4 +201,70 @@ defineProps<{
}
}
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -5,19 +5,20 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<span
v-tooltip="checked ? i18n.ts.itsOn : i18n.ts.itsOff"
:class="{
v-tooltip="checked ? i18n.ts.itsOn : i18n.ts.itsOff"
:class="{
[$style.button]: true,
[$style.gamingDark]: gaming === 'dark' && checked,
[$style.gamingLight]: gaming === 'light' && checked,
[$style.buttonChecked]: checked,
[$style.buttonDisabled]: props.disabled,
[$style.gamingDark]: gaming === 'dark' && checked,
[$style.gamingLight]: gaming === 'light' && checked
}"
data-cy-switch-toggle
@click.prevent.stop="toggle"
data-cy-switch-toggle
@click.prevent.stop="toggle"
>
<div
:class="{ [$style.knob]: true, [$style.knobChecked]: checked, [$style.gamingDark]: gaming === 'dark' && checked,[$style.gamingLight]: gaming === 'light' && checked}"></div>
:class="{ [$style.knob]: true, [$style.knobChecked]: checked, [$style.gamingDark]: gaming === 'dark' && checked,[$style.gamingLight]: gaming === 'light' && checked}"></div>
</span>
</template>
@ -31,202 +32,201 @@ let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
gaming.value = 'light';
} else {
gaming.value = '';
gaming.value = '';
}
watch(darkMode, () => {
console.log(gaming)
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
console.log(gaming)
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const props = withDefaults(defineProps<{
checked: boolean | Ref<boolean>;
disabled?: boolean;
checked: boolean | Ref<boolean>;
disabled?: boolean;
}>(), {
disabled: false,
disabled: false,
});
const emit = defineEmits<{
(ev: 'toggle'): void;
(ev: 'toggle'): void;
}>();
const checked = toRefs(props).checked;
const toggle = () => {
emit('toggle');
emit('toggle');
};
</script>
<style lang="scss" module>
.button {
position: relative;
display: inline-flex;
flex-shrink: 0;
margin: 0;
box-sizing: border-box;
width: 32px;
height: 23px;
outline: none;
background: var(--switchOffBg);
background-clip: content-box;
border: solid 1px var(--switchOffBg);
border-radius: 999px;
cursor: pointer;
transition: inherit;
user-select: none;
position: relative;
display: inline-flex;
flex-shrink: 0;
margin: 0;
box-sizing: border-box;
width: 32px;
height: 23px;
outline: none;
background: var(--switchOffBg);
background-clip: content-box;
border: solid 1px var(--switchOffBg);
border-radius: 999px;
cursor: pointer;
transition: inherit;
user-select: none;
&.gamingLight {
border-image: conic-gradient(#e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd) 1;
border: solid 1px;
}
&.gamingLight {
border-image: conic-gradient(#e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd) 1;
border: solid 1px;
}
&.gamingDark {
border-image: conic-gradient(#c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4) 1;
border: solid 1px;
}
&.gamingDark {
border-image: conic-gradient(#c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4) 1;
border: solid 1px;
}
}
.buttonChecked {
background-color: var(--switchOnBg) !important;
border-color: var(--switchOnBg) !important;
&.gamingLight {
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
}
&.gamingDark {
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
}
background-color: var(--switchOnBg);
border-color: var(--switchOnBg);
}
.gamingLight {
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
.gamingDark {
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
.buttonDisabled {
cursor: not-allowed;
cursor: not-allowed;
}
.knob {
position: absolute;
top: 3px;
width: 15px;
height: 15px;
border-radius: 999px;
transition: all 0.2s ease;
position: absolute;
top: 3px;
width: 15px;
height: 15px;
border-radius: 999px;
transition: all 0.2s ease;
&:not(.knobChecked) {
left: 3px;
background: var(--switchOffFg);
&:not(.knobChecked) {
left: 3px;
background: var(--switchOffFg);
}
}
}
.knobChecked {
left: 12px;
background: var(--switchOnFg);
left: 12px;
background: var(--switchOnFg);
&.gamingDark {
background: white !important;
}
&.gamingDark {
background: white !important;
}
&.gamingLight {
background: white !important;
}
&.gamingLight {
background: white !important;
}
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -4,8 +4,40 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<script lang="ts">
import { defineComponent, h, resolveDirective, withDirectives } from 'vue';
import {computed, defineComponent, h, resolveDirective, withDirectives , ref , watch} from 'vue';
import {defaultStore} from "@/store.js";
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
export default defineComponent({
props: {
modelValue: {
@ -18,7 +50,7 @@ export default defineComponent({
return () => h('div', {
class: 'pxhvhrfw',
}, options.map(option => withDirectives(h('button', {
class: ['_button', { active: props.modelValue === option.props.value }],
class: ['_button', { active: props.modelValue === option.props.value , gamingDark: gaming.value == 'dark' && props.modelValue === option.props.value,gamingLight: gaming.value == 'light' && props.modelValue === option.props.value } ],
key: option.key,
disabled: props.modelValue === option.props.value,
onClick: () => {
@ -49,6 +81,21 @@ export default defineComponent({
&.active {
color: var(--accent);
background: var(--accentedBg);
&.gamingDark{
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingLight{
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
}
&:not(.active):hover {
@ -75,4 +122,69 @@ export default defineComponent({
}
}
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div style="overflow-x: clip;">
<div :class="$style.progressBar">
<div :class="$style.progressBarValue" :style="{ width: `${(page / 5) * 100}%` }"></div>
<div :class="[$style.progressBarValue , {[$style.gamingDark]: gaming === 'dark',[$style.gamingLight]: gaming === 'light' }]" :style="{ width: `${(page / 5) * 100}%` }"></div>
</div>
<Transition
mode="out-in"
@ -123,7 +123,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { ref, shallowRef, watch } from 'vue';
import {computed, ref, shallowRef, watch} from 'vue';
import MkModalWindow from '@/components/MkModalWindow.vue';
import MkButton from '@/components/MkButton.vue';
import XProfile from '@/components/MkUserSetupDialog.Profile.vue';
@ -137,6 +137,38 @@ import MkPushNotificationAllowButton from '@/components/MkPushNotificationAllowB
import { defaultStore } from '@/store.js';
import * as os from '@/os.js';
let gaming = ref('');
const gamingMode = computed(defaultStore.makeGetterSetter('gamingMode'));
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
watch(darkMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
watch(gamingMode, () => {
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
gaming.value = 'light';
} else {
gaming.value = '';
}
})
const emit = defineEmits<{
(ev: 'closed'): void;
}>();
@ -203,6 +235,20 @@ async function later(later: boolean) {
height: 100%;
background: linear-gradient(90deg, var(--buttonGradateA), var(--buttonGradateB));
transition: all 0.5s cubic-bezier(0,.5,.5,1);
&.gamingLight{
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.gamingDark{
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
}
.centerPage {
@ -223,4 +269,69 @@ async function later(later: boolean) {
-webkit-backdrop-filter: blur(15px);
backdrop-filter: blur(15px);
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkInfo warn>{{ i18n.ts.invitationRequiredToRegister }}</MkInfo>
</div>
<div class="_gaps_s" :class="$style.mainActions">
<MkButton :class="$style.mainAction" full rounded gradate data-cy-signup style="margin-right: 12px;" @click="signup()">{{ i18n.ts.joinThisServer }}</MkButton>
<MkButton :class="[$style.mainAction , $style.gamingDark]" full rounded data-cy-signup style="margin-right: 12px;" @click="signup()">{{ i18n.ts.joinThisServer }}</MkButton>
<MkButton :class="$style.mainAction" full rounded @click="exploreOtherServers()">{{ i18n.ts.exploreOtherServers }}</MkButton>
<MkButton :class="$style.mainAction" full rounded data-cy-signin @click="signin()">{{ i18n.ts.login }}</MkButton>
</div>
@ -190,6 +190,14 @@ function exploreOtherServers() {
line-height: 28px;
}
.gamingDark{
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800%;
-webkit-animation:AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation:AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation:AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
.stats {
display: grid;
grid-template-columns: 1fr 1fr;
@ -225,4 +233,69 @@ function exploreOtherServers() {
height: 350px;
overflow: auto;
}
@-webkit-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
} @keyframes AnimationLight {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-webkit-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@-moz-keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
@keyframes AnimationDark {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
</style>

View file

@ -56,7 +56,7 @@ const props = withDefaults(defineProps<{
--size: 38px;
&.colored {
color: var(--accent);
color: #5f5f5f;
}
&.inline {

View file

@ -68,7 +68,6 @@ if (darkMode.value && gamingMode.value == true) {
}
watch(darkMode, () => {
console.log(gaming)
if (darkMode.value && gamingMode.value == true) {
gaming.value = 'dark';
} else if (!darkMode.value && gamingMode.value == true) {
@ -277,18 +276,18 @@ onUnmounted(() => {
transition: none;
pointer-events: none;
&.gamingLight{
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background-size: 1800% 1800% !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.25, 0.25, 1) infinite !important;
-webkit-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
-moz-animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
animation: AnimationLight 45s cubic-bezier(0, 0.2, 0.90, 1) infinite !important;
}
&.gamingDark{
background: linear-gradient(270deg, #c06161, #c0a567, #b6ba69, #81bc72, #63c3be, #8bacd6, #9f8bd6, #d18bd6, #d883b4);
background: linear-gradient(270deg, #e7a2a2, #e3cfa2, #ebefa1, #b3e7a6, #a6ebe7, #aec5e3, #cabded, #e0b9e3, #f4bddd);
background-size: 1800% 1800%;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.25, 0.25, 1) infinite;
-webkit-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
-moz-animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
animation: AnimationDark 44s cubic-bezier(0, 0.2, 0.90, 1) infinite;
}
&.animate {
transition: width 0.15s ease, left 0.15s ease;