mirror of
https://github.com/unraid/api.git
synced 2025-12-31 13:39:52 -06:00
feat: eliminate all alpha beta gamma variable usage
This commit is contained in:
@@ -89,8 +89,8 @@ body {
|
||||
--border: 0 0% 14.9%;
|
||||
--input: 0 0% 14.9%;
|
||||
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 0 0% 9%;
|
||||
--primary: 24 100% 50%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
|
||||
--secondary: 0 0% 14.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
|
||||
@@ -48,7 +48,7 @@ const classes = computed(() => {
|
||||
buttonColors = 'text-white bg-transparent border-white hover:text-black focus:text-black hover:bg-white focus:bg-white';
|
||||
break;
|
||||
case 'underline':
|
||||
buttonColors = 'opacity-75 underline border-transparent transition hover:text-alpha hover:bg-beta hover:border-beta focus:text-alpha focus:bg-beta focus:border-beta hover:opacity-100 focus:opacity-100';
|
||||
buttonColors = 'opacity-75 underline border-transparent transition hover:text-primary hover:bg-muted hover:border-muted focus:text-primary focus:bg-muted focus:border-muted hover:opacity-100 focus:opacity-100';
|
||||
break;
|
||||
case 'underline-hover-red':
|
||||
buttonColors = 'opacity-75 underline border-transparent transition hover:text-white hover:bg-unraid-red hover:border-unraid-red focus:text-white focus:bg-unraid-red focus:border-unraid-red hover:opacity-100 focus:opacity-100';
|
||||
|
||||
@@ -137,7 +137,7 @@ const ariaLablledById = computed((): string|undefined => props.title ? `ModalTit
|
||||
</div>
|
||||
|
||||
<footer v-if="$slots['footer']" class="text-14px relative p-16px md:p-24px">
|
||||
<div class="absolute z-0 inset-0 opacity-10 bg-beta" />
|
||||
<div class="absolute z-0 inset-0 opacity-10 bg-popover" />
|
||||
<div class="relative z-10">
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
|
||||
@@ -14,15 +14,6 @@ const computedStyleClasses = computed(() => {
|
||||
let textSize = '';
|
||||
let iconSize = '';
|
||||
switch (props.color) {
|
||||
case 'alpha':
|
||||
colorClasses = 'bg-alpha text-white group-hover:opacity-75 group-focus:opacity-75';
|
||||
break;
|
||||
case 'beta':
|
||||
colorClasses = 'bg-beta text-white group-hover:opacity-75 group-focus:opacity-75';
|
||||
break;
|
||||
case 'gamma':
|
||||
colorClasses = 'bg-gamma text-white group-hover:opacity-75 group-focus:opacity-75';
|
||||
break;
|
||||
case 'red':
|
||||
colorClasses = 'bg-unraid-red text-white group-hover:bg-orange-dark group-focus:bg-orange-dark';
|
||||
break;
|
||||
|
||||
@@ -23,7 +23,7 @@ withDefaults(defineProps<{
|
||||
hover && 'hover:shadow-orange/50 transition-all',
|
||||
error && 'text-white bg-unraid-red border-unraid-red',
|
||||
warning && 'text-black bg-yellow-100 border-yellow-100',
|
||||
!error && !warning && 'text-beta bg-alpha border-gamma-opaque',
|
||||
!error && !warning && 'text-foreground bg-background border-muted',
|
||||
]"
|
||||
>
|
||||
<slot />
|
||||
|
||||
@@ -22,7 +22,7 @@ const checked = ref(false);
|
||||
:class="checked ? 'bg-gradient-to-r from-unraid-red to-orange' : 'bg-transparent'"
|
||||
class="relative inline-flex h-24px w-[48px] items-center rounded-full overflow-hidden"
|
||||
>
|
||||
<span v-show="!checked" class="absolute z-0 inset-0 opacity-10 bg-beta" />
|
||||
<span v-show="!checked" class="absolute z-0 inset-0 opacity-10 bg-primary" />
|
||||
<span
|
||||
:class="checked ? 'translate-x-[26px]' : 'translate-x-[2px]'"
|
||||
class="inline-block h-20px w-20px transform rounded-full bg-white transition"
|
||||
|
||||
@@ -268,7 +268,7 @@ const modalWidth = computed(() => {
|
||||
:class="ignoreThisRelease ? 'bg-gradient-to-r from-unraid-red to-orange' : 'bg-transparent'"
|
||||
class="relative inline-flex h-24px w-[48px] items-center rounded-full overflow-hidden"
|
||||
>
|
||||
<span v-show="!ignoreThisRelease" class="absolute z-0 inset-0 opacity-10 bg-beta" />
|
||||
<span v-show="!ignoreThisRelease" class="absolute z-0 inset-0 opacity-10 bg-foreground" />
|
||||
<span
|
||||
:class="ignoreThisRelease ? 'translate-x-[26px]' : 'translate-x-[2px]'"
|
||||
class="inline-block h-20px w-20px transform rounded-full bg-white transition"
|
||||
|
||||
@@ -125,7 +125,7 @@ onBeforeMount(() => {
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<div class="block w-2px h-24px bg-gamma" />
|
||||
<div class="block w-2px h-24px bg-popover" />
|
||||
|
||||
<!-- Keep the sidebar out of staging/prod builds, but easily accessible for development -->
|
||||
<NotificationsSidebar />
|
||||
@@ -144,7 +144,7 @@ onBeforeMount(() => {
|
||||
@tailwind utilities;
|
||||
|
||||
.DropdownWrapper_blip {
|
||||
box-shadow: var(--ring-offset-shadow), var(--ring-shadow), var(--shadow-beta);
|
||||
box-shadow: var(--ring-offset-shadow), var(--ring-shadow), var(--shadow-popover-foreground);
|
||||
|
||||
&::before {
|
||||
@apply absolute z-20 block;
|
||||
|
||||
@@ -27,7 +27,7 @@ const showLaunchpad = computed(() => state.value === 'ENOKEYFILE');
|
||||
leave-from="opacity-100"
|
||||
leave-to="opacity-0 translate-y-[16px]"
|
||||
>
|
||||
<UpcDropdownWrapper class="DropdownWrapper_blip text-beta absolute z-30 top-full right-0 transition-all">
|
||||
<UpcDropdownWrapper class="DropdownWrapper_blip text-foreground absolute z-30 top-full right-0 transition-all">
|
||||
<UpcDropdownLaunchpad v-if="showLaunchpad" :t="t" />
|
||||
<UpcDropdownContent v-else :t="t" />
|
||||
</UpcDropdownWrapper>
|
||||
|
||||
@@ -174,7 +174,7 @@ const unraidConnectWelcome = computed(() => {
|
||||
<div class="flex flex-col gap-y-8px min-w-300px max-w-350px">
|
||||
<header v-if="connectPluginInstalled" class="flex flex-col items-start justify-between mt-8px mx-8px">
|
||||
<h2 class="text-18px leading-none flex flex-row gap-x-4px items-center justify-between">
|
||||
<BrandLogoConnect gradient-start="currentcolor" gradient-stop="currentcolor" class="text-beta w-[120px]" />
|
||||
<BrandLogoConnect gradient-start="currentcolor" gradient-stop="currentcolor" class="text-foreground w-[120px]" />
|
||||
<UpcBeta />
|
||||
</h2>
|
||||
<template v-if="unraidConnectWelcome">
|
||||
|
||||
@@ -27,7 +27,7 @@ const showExternalIconOnHover = computed(() => props.item?.external && props.ite
|
||||
:rel="item?.external ? 'noopener noreferrer' : null"
|
||||
class="text-left text-14px w-full flex flex-row items-center justify-between gap-x-8px px-8px py-8px cursor-pointer"
|
||||
:class="{
|
||||
'text-beta bg-transparent hover:text-white hover:bg-gradient-to-r hover:from-unraid-red hover:to-orange focus:text-white focus:bg-gradient-to-r focus:from-unraid-red focus:to-orange focus:outline-none': !item?.emphasize,
|
||||
'text-foreground bg-transparent hover:text-white hover:bg-gradient-to-r hover:from-unraid-red hover:to-orange focus:text-white focus:bg-gradient-to-r focus:from-unraid-red focus:to-orange focus:outline-none': !item?.emphasize,
|
||||
'text-white bg-gradient-to-r from-unraid-red to-orange hover:from-unraid-red/60 hover:to-orange/60 focus:from-unraid-red/60 focus:to-orange/60': item?.emphasize,
|
||||
'group': showExternalIconOnHover,
|
||||
'rounded-md': rounded,
|
||||
|
||||
@@ -56,7 +56,7 @@ const showExpireTime = computed(() => (state.value === 'TRIAL' || state.value ==
|
||||
@tailwind utilities;
|
||||
|
||||
.DropdownWrapper_blip {
|
||||
box-shadow: var(--ring-offset-shadow), var(--ring-shadow), var(--shadow-beta);
|
||||
box-shadow: var(--ring-offset-shadow), var(--ring-shadow), var(--shadow-foreground);
|
||||
|
||||
&::before {
|
||||
@apply absolute z-20 block;
|
||||
@@ -67,7 +67,7 @@ const showExpireTime = computed(() => (state.value === 'TRIAL' || state.value ==
|
||||
top: -10px;
|
||||
right: 42px;
|
||||
border-right: 11px solid transparent;
|
||||
border-bottom: 11px solid var(--color-alpha);
|
||||
border-bottom: 11px solid var(--color-popover);
|
||||
border-left: 11px solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
// shadow-[var(--ring-offset-shadow)_var(--ring-shadow)_var(--shadow-beta)]
|
||||
// border border-solid border-beta/5
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav class="flex flex-col gap-y-8px p-8px bg-alpha rounded-lg shadow-xl shadow-orange/10">
|
||||
<nav class="flex flex-col gap-y-8px p-8px bg-popover rounded-lg shadow-xl shadow-orange/10">
|
||||
<slot />
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
@@ -21,7 +21,7 @@ const upgradeAction = computed((): ServerStateDataAction | undefined => {
|
||||
<span class="flex flex-row items-center gap-x-8px">
|
||||
<template v-if="upgradeAction">
|
||||
<UpcServerStateBuy
|
||||
class="text-gamma"
|
||||
class="text-white"
|
||||
:title="t('Upgrade Key')"
|
||||
@click="upgradeAction.click?.()"
|
||||
>
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
ArrowPathIcon,
|
||||
ArrowTopRightOnSquareIcon,
|
||||
BellAlertIcon,
|
||||
CheckCircleIcon,
|
||||
ExclamationTriangleIcon,
|
||||
InformationCircleIcon,
|
||||
XCircleIcon,
|
||||
} from '@heroicons/vue/24/solid';
|
||||
import { serverState } from '~/_data/serverState';
|
||||
import type { SendPayloads } from '~/store/callback';
|
||||
import AES from 'crypto-js/aes';
|
||||
|
||||
import BrandButton from '~/components/Brand/Button.vue';
|
||||
const { registerEntry } = useCustomElements();
|
||||
onBeforeMount(() => {
|
||||
registerEntry('UnraidComponents');
|
||||
@@ -118,6 +127,20 @@ onMounted(() => {
|
||||
<pre>{{ callbackDestination }}</pre>
|
||||
</code>
|
||||
</div>
|
||||
<div class="bg-background">
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h2 class="text-xl font-semibold font-mono">Legacy Badge Components</h2>
|
||||
<template v-for="color in ['black', 'white', 'red', 'yellow', 'green', 'blue', 'indigo', 'purple', 'pink', 'orange', 'transparent', 'current', 'gray', 'custom']" :key="color">
|
||||
<UiBadge size="14px" :icon="ExclamationTriangleIcon" :color="color">{{ color }}</UiBadge>
|
||||
</template>
|
||||
</div>
|
||||
<div class="bg-background">
|
||||
<hr class="border-black dark:border-white" />
|
||||
<h2 class="text-xl font-semibold font-mono">Legacy Button Components</h2>
|
||||
<template v-for="color in ['black', 'fill', 'gray', 'outline', 'outline-black', 'outline-white', 'underline', 'underline-hover-red', 'white',]" :key="color">
|
||||
<BrandButton type="button" size="14px" :icon="ExclamationTriangleIcon" :btn-style="color">{{ color }}</BrandButton>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</client-only>
|
||||
</div>
|
||||
|
||||
@@ -64,7 +64,7 @@ export const useReplaceRenewStore = defineStore('replaceRenewCheck', () => {
|
||||
switch (keyLinkedStatus.value) {
|
||||
case 'checking':
|
||||
return {
|
||||
color: 'gamma',
|
||||
color: 'gray',
|
||||
icon: BrandLoadingWhite,
|
||||
text: 'Checking...',
|
||||
};
|
||||
@@ -110,7 +110,7 @@ export const useReplaceRenewStore = defineStore('replaceRenewCheck', () => {
|
||||
switch (replaceStatus.value) {
|
||||
case 'checking':
|
||||
return {
|
||||
color: 'gamma',
|
||||
color: 'gray',
|
||||
icon: BrandLoadingWhite,
|
||||
text: 'Checking...',
|
||||
};
|
||||
|
||||
@@ -78,16 +78,7 @@ export const useThemeStore = defineStore('theme', () => {
|
||||
body.style.setProperty('--header-text-primary', headerTextPrimary);
|
||||
body.style.setProperty('--header-text-secondary', headerTextSecondary);
|
||||
body.style.setProperty('--header-background-color', headerBackgroundColor);
|
||||
body.style.setProperty('--color-gamma-opaque', hexToRgba(headerTextSecondary, 0.25));
|
||||
// box shadow
|
||||
body.style.setProperty(
|
||||
'--shadow-beta',
|
||||
`0 25px 50px -12px ${hexToRgba(headerBackgroundColor, 0.15)}`
|
||||
);
|
||||
body.style.setProperty('--ring-offset-shadow', `0 0 ${headerBackgroundColor}`);
|
||||
body.style.setProperty('--ring-shadow', `0 0 ${headerBackgroundColor}`);
|
||||
body.style.setProperty('--dev-test', `0 0 ${headerBackgroundColor}`);
|
||||
|
||||
|
||||
if (darkMode.value) {
|
||||
document.body.classList.add('dark');
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'dotenv/config';
|
||||
import type { Config } from 'tailwindcss';
|
||||
import type { PluginAPI } from 'tailwindcss/types/config';
|
||||
|
||||
|
||||
// @ts-expect-error - just trying to get this to build @fixme
|
||||
export default <Partial<Config>>{
|
||||
darkMode: ['selector'],
|
||||
@@ -79,11 +78,6 @@ export default <Partial<Config>>{
|
||||
'900': '#284126',
|
||||
'950': '#122211',
|
||||
},
|
||||
|
||||
alpha: 'var(--color-alpha)',
|
||||
beta: 'var(--color-beta)',
|
||||
gamma: 'var(--color-gamma)',
|
||||
'gamma-opaque': 'var(--color-gamma-opaque)',
|
||||
'header-text-primary': 'var(--header-text-primary)',
|
||||
'header-text-secondary': 'var(--header-text-secondary)',
|
||||
'header-background-color': 'var(--header-background-color)',
|
||||
@@ -221,83 +215,46 @@ export default <Partial<Config>>{
|
||||
typography: (theme: PluginAPI['theme']) => ({
|
||||
DEFAULT: {
|
||||
css: {
|
||||
color: theme('colors.beta'),
|
||||
color: theme('colors.foreground'),
|
||||
a: {
|
||||
color: theme('colors.orange'),
|
||||
color: theme('colors.primary'),
|
||||
textDecoration: 'underline',
|
||||
'&:hover': {
|
||||
color: theme('colors.orange-dark'),
|
||||
color: theme('colors.primary-foreground'),
|
||||
},
|
||||
},
|
||||
'--tw-prose-body': theme('colors.beta'),
|
||||
'--tw-prose-headings': theme('colors.beta'),
|
||||
'--tw-prose-lead': theme('colors.beta'),
|
||||
'--tw-prose-links': theme('colors.orange'),
|
||||
'--tw-prose-bold': theme('colors.beta'),
|
||||
'--tw-prose-counters': theme('colors.beta'),
|
||||
'--tw-prose-bullets': theme('colors.beta'),
|
||||
'--tw-prose-hr': theme('colors.beta'),
|
||||
'--tw-prose-quotes': theme('colors.beta'),
|
||||
'--tw-prose-quote-borders': theme('colors.beta'),
|
||||
'--tw-prose-captions': theme('colors.beta'),
|
||||
'--tw-prose-code': theme('colors.beta'),
|
||||
'--tw-prose-pre-code': theme('colors.beta'),
|
||||
'--tw-prose-pre-bg': theme('colors.alpha'),
|
||||
'--tw-prose-th-borders': theme('colors.beta'),
|
||||
'--tw-prose-td-borders': theme('colors.beta'),
|
||||
'--tw-prose-invert-body': theme('colors.alpha'),
|
||||
'--tw-prose-invert-headings': theme('colors.alpha'),
|
||||
'--tw-prose-invert-lead': theme('colors.alpha'),
|
||||
'--tw-prose-invert-links': theme('colors.orange'),
|
||||
'--tw-prose-invert-bold': theme('colors.alpha'),
|
||||
'--tw-prose-invert-counters': theme('colors.alpha'),
|
||||
'--tw-prose-invert-bullets': theme('colors.alpha'),
|
||||
'--tw-prose-invert-hr': theme('colors.alpha'),
|
||||
'--tw-prose-invert-quotes': theme('colors.alpha'),
|
||||
'--tw-prose-invert-quote-borders': theme('colors.alpha'),
|
||||
'--tw-prose-invert-captions': theme('colors.alpha'),
|
||||
'--tw-prose-invert-code': theme('colors.alpha'),
|
||||
'--tw-prose-invert-code-bg': theme('colors.gamma-opaque'),
|
||||
'--tw-prose-invert-pre-code': theme('colors.alpha'),
|
||||
'--tw-prose-invert-pre-bg': theme('colors.beta'),
|
||||
'--tw-prose-invert-th-borders': theme('colors.alpha'),
|
||||
'--tw-prose-invert-td-borders': theme('colors.alpha'),
|
||||
},
|
||||
},
|
||||
black: {
|
||||
css: {
|
||||
'--tw-prose-body': theme('colors.black'),
|
||||
'--tw-prose-headings': theme('colors.black'),
|
||||
'--tw-prose-lead': theme('colors.black'),
|
||||
'--tw-prose-links': theme('colors.black'),
|
||||
'--tw-prose-bold': theme('colors.black'),
|
||||
'--tw-prose-counters': theme('colors.black'),
|
||||
'--tw-prose-bullets': theme('colors.black'),
|
||||
'--tw-prose-hr': theme('colors.black'),
|
||||
'--tw-prose-quotes': theme('colors.black'),
|
||||
'--tw-prose-quote-borders': theme('colors.black'),
|
||||
'--tw-prose-captions': theme('colors.black'),
|
||||
'--tw-prose-code': theme('colors.black'),
|
||||
'--tw-prose-pre-code': theme('colors.black'),
|
||||
'--tw-prose-pre-bg': theme('colors.black'),
|
||||
'--tw-prose-th-borders': theme('colors.black'),
|
||||
'--tw-prose-td-borders': theme('colors.black'),
|
||||
'--tw-prose-invert-body': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-headings': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-lead': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-links': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-bold': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-counters': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-bullets': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-hr': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-quotes': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-quote-borders': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-captions': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-code': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-pre-code': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-pre-bg': 'rgb(0 0 0 / 50%)',
|
||||
'--tw-prose-invert-th-borders': theme('colors.grey-darkest'),
|
||||
'--tw-prose-invert-td-borders': theme('colors.grey-darkest'),
|
||||
'--tw-prose-body': theme('colors.foreground'),
|
||||
'--tw-prose-headings': theme('colors.foreground'),
|
||||
'--tw-prose-lead': theme('colors.foreground'),
|
||||
'--tw-prose-links': theme('colors.primary'),
|
||||
'--tw-prose-bold': theme('colors.foreground'),
|
||||
'--tw-prose-counters': theme('colors.foreground'),
|
||||
'--tw-prose-bullets': theme('colors.foreground'),
|
||||
'--tw-prose-hr': theme('colors.foreground'),
|
||||
'--tw-prose-quotes': theme('colors.foreground'),
|
||||
'--tw-prose-quote-borders': theme('colors.foreground'),
|
||||
'--tw-prose-captions': theme('colors.foreground'),
|
||||
'--tw-prose-code': theme('colors.foreground'),
|
||||
'--tw-prose-pre-code': theme('colors.foreground'),
|
||||
'--tw-prose-pre-bg': theme('colors.background'),
|
||||
'--tw-prose-th-borders': theme('colors.foreground'),
|
||||
'--tw-prose-td-borders': theme('colors.foreground'),
|
||||
'--tw-prose-invert-body': theme('colors.background'),
|
||||
'--tw-prose-invert-headings': theme('colors.background'),
|
||||
'--tw-prose-invert-lead': theme('colors.background'),
|
||||
'--tw-prose-invert-links': theme('colors.primary'),
|
||||
'--tw-prose-invert-bold': theme('colors.background'),
|
||||
'--tw-prose-invert-counters': theme('colors.background'),
|
||||
'--tw-prose-invert-bullets': theme('colors.background'),
|
||||
'--tw-prose-invert-hr': theme('colors.background'),
|
||||
'--tw-prose-invert-quotes': theme('colors.background'),
|
||||
'--tw-prose-invert-quote-borders': theme('colors.background'),
|
||||
'--tw-prose-invert-captions': theme('colors.background'),
|
||||
'--tw-prose-invert-code': theme('colors.background'),
|
||||
'--tw-prose-invert-pre-code': theme('colors.background'),
|
||||
'--tw-prose-invert-pre-bg': theme('colors.foreground'),
|
||||
'--tw-prose-invert-th-borders': theme('colors.background'),
|
||||
'--tw-prose-invert-td-borders': theme('colors.background'),
|
||||
},
|
||||
},
|
||||
}),
|
||||
@@ -317,4 +274,4 @@ export default <Partial<Config>>{
|
||||
newFontSize: process.env.VITE_TAILWIND_BASE_FONT_SIZE ?? 10,
|
||||
}),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { XCircleIcon } from '@heroicons/vue/24/solid';
|
||||
import type { Component } from 'vue';
|
||||
|
||||
export type UiBadgePropsColor = 'alpha' | 'beta' | 'gamma' | 'gray' | 'red' | 'yellow' | 'green' | 'blue' | 'indigo' | 'purple' | 'pink' | 'orange' | 'black' | 'white' | 'transparent' | 'current' | 'custom';
|
||||
export type UiBadgePropsColor = 'gray' | 'red' | 'yellow' | 'green' | 'blue' | 'indigo' | 'purple' | 'pink' | 'orange' | 'black' | 'white' | 'transparent' | 'current' | 'custom';
|
||||
|
||||
export interface UiBadgeProps {
|
||||
color?: UiBadgePropsColor;
|
||||
|
||||
Reference in New Issue
Block a user