Implement LotusGuild TDS v1.2 terminal mode
- Rewrite lotus-terminal.css.ts: TDS-exact dot-grid bg, scanlines, vignette, glitch keyframes, orange caret, cyan scrollbars, all --lt-* CSS vars - Fix lotusTerminalTheme in colors.css.ts: full TDS color palette (Orange primary, Cyan secondary, Green success, Amber warning, Red critical) - Add lotus-boot.ts: matrix boot sequence at 65ms intervals, green phosphor glow - Update ThemeManager.tsx: call runLotusBootSequence on terminal mode activate, UnAuthRouteThemeManager now supports lotusTerminal setting - Update index.html: add JetBrains Mono + VT323 from Google Fonts
This commit is contained in:
@@ -25,6 +25,9 @@
|
||||
/>
|
||||
<meta name="theme-color" content="#000000" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,600;0,700;1,400&family=VT323&display=swap" rel="stylesheet">
|
||||
<link id="favicon" rel="shortcut icon" href="./public/favicon.ico" />
|
||||
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
|
||||
@@ -12,20 +12,24 @@ import {
|
||||
import { lotusTerminalBodyClass } from '../../lotus-terminal.css';
|
||||
import { useSetting } from '../state/hooks/settings';
|
||||
import { settingsAtom } from '../state/settings';
|
||||
import { runLotusBootSequence } from '../../lotus-boot';
|
||||
|
||||
export function UnAuthRouteThemeManager() {
|
||||
const systemThemeKind = useSystemThemeKind();
|
||||
const [lotusTerminal] = useSetting(settingsAtom, 'lotusTerminal');
|
||||
|
||||
useEffect(() => {
|
||||
document.body.className = '';
|
||||
document.body.classList.add(configClass, varsClass);
|
||||
if (systemThemeKind === ThemeKind.Dark) {
|
||||
if (lotusTerminal) {
|
||||
document.body.classList.add(...LotusTerminalTheme.classNames);
|
||||
document.body.classList.add(lotusTerminalBodyClass);
|
||||
} else if (systemThemeKind === ThemeKind.Dark) {
|
||||
document.body.classList.add(...DarkTheme.classNames);
|
||||
}
|
||||
if (systemThemeKind === ThemeKind.Light) {
|
||||
} else {
|
||||
document.body.classList.add(...LightTheme.classNames);
|
||||
}
|
||||
}, [systemThemeKind]);
|
||||
}, [systemThemeKind, lotusTerminal]);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -43,6 +47,7 @@ export function AuthRouteThemeManager({ children }: { children: ReactNode }) {
|
||||
document.body.classList.add(...effectiveTheme.classNames);
|
||||
if (lotusTerminal) {
|
||||
document.body.classList.add(lotusTerminalBodyClass);
|
||||
runLotusBootSequence();
|
||||
}
|
||||
if (monochromeMode && !lotusTerminal) {
|
||||
document.body.style.filter = 'grayscale(1)';
|
||||
|
||||
+67
-67
@@ -239,97 +239,97 @@ export const butterTheme = createTheme(color, {
|
||||
|
||||
export const lotusTerminalTheme = createTheme(color, {
|
||||
Background: {
|
||||
Container: '#0a0000',
|
||||
ContainerHover: '#140500',
|
||||
ContainerActive: '#1e0800',
|
||||
ContainerLine: '#2a0b00',
|
||||
OnContainer: '#ffd0b8',
|
||||
Container: '#030508',
|
||||
ContainerHover: '#060c14',
|
||||
ContainerActive: '#0d1520',
|
||||
ContainerLine: '#07101a',
|
||||
OnContainer: '#c4d9ee',
|
||||
},
|
||||
|
||||
Surface: {
|
||||
Container: '#140500',
|
||||
ContainerHover: '#1e0800',
|
||||
ContainerActive: '#2a0b00',
|
||||
ContainerLine: '#360e00',
|
||||
OnContainer: '#ffd0b8',
|
||||
Container: '#060c14',
|
||||
ContainerHover: '#0d1520',
|
||||
ContainerActive: '#07101a',
|
||||
ContainerLine: '#111d2b',
|
||||
OnContainer: '#c4d9ee',
|
||||
},
|
||||
|
||||
SurfaceVariant: {
|
||||
Container: '#1e0800',
|
||||
ContainerHover: '#2a0b00',
|
||||
ContainerActive: '#360e00',
|
||||
ContainerLine: '#421100',
|
||||
OnContainer: '#ffd0b8',
|
||||
Container: '#0d1520',
|
||||
ContainerHover: '#07101a',
|
||||
ContainerActive: '#111d2b',
|
||||
ContainerLine: '#162436',
|
||||
OnContainer: '#c4d9ee',
|
||||
},
|
||||
|
||||
Primary: {
|
||||
Main: '#ff3300',
|
||||
MainHover: '#ff4d1a',
|
||||
MainActive: '#ff5c2e',
|
||||
MainLine: '#ff6640',
|
||||
OnMain: '#0a0000',
|
||||
Container: '#3d0d00',
|
||||
ContainerHover: '#4a1000',
|
||||
ContainerActive: '#571300',
|
||||
ContainerLine: '#641600',
|
||||
OnContainer: '#ffb399',
|
||||
Main: '#FF6B00',
|
||||
MainHover: '#FF8C2B',
|
||||
MainActive: '#FF9940',
|
||||
MainLine: '#FFA655',
|
||||
OnMain: '#030508',
|
||||
Container: '#2a1200',
|
||||
ContainerHover: '#3a1a00',
|
||||
ContainerActive: '#4a2200',
|
||||
ContainerLine: '#5a2a00',
|
||||
OnContainer: '#FFB87A',
|
||||
},
|
||||
|
||||
Secondary: {
|
||||
Main: '#00dd66',
|
||||
MainHover: '#00c75c',
|
||||
MainActive: '#00b352',
|
||||
MainLine: '#009e49',
|
||||
OnMain: '#0a0000',
|
||||
Container: '#003318',
|
||||
ContainerHover: '#00401e',
|
||||
ContainerActive: '#004d24',
|
||||
ContainerLine: '#005a2a',
|
||||
OnContainer: '#99ffcc',
|
||||
Main: '#00D4FF',
|
||||
MainHover: '#33DFFF',
|
||||
MainActive: '#4DE5FF',
|
||||
MainLine: '#66EBFF',
|
||||
OnMain: '#030508',
|
||||
Container: '#001a22',
|
||||
ContainerHover: '#002233',
|
||||
ContainerActive: '#002a3d',
|
||||
ContainerLine: '#003347',
|
||||
OnContainer: '#99E8FF',
|
||||
},
|
||||
|
||||
Success: {
|
||||
Main: '#00dd66',
|
||||
MainHover: '#00c75c',
|
||||
MainActive: '#00b352',
|
||||
MainLine: '#009e49',
|
||||
OnMain: '#0a0000',
|
||||
Container: '#003318',
|
||||
ContainerHover: '#00401e',
|
||||
ContainerActive: '#004d24',
|
||||
ContainerLine: '#005a2a',
|
||||
OnContainer: '#99ffcc',
|
||||
Main: '#00FF88',
|
||||
MainHover: '#33FFAA',
|
||||
MainActive: '#4DFFB8',
|
||||
MainLine: '#66FFC6',
|
||||
OnMain: '#030508',
|
||||
Container: '#002211',
|
||||
ContainerHover: '#002a16',
|
||||
ContainerActive: '#00331b',
|
||||
ContainerLine: '#003b20',
|
||||
OnContainer: '#99FFCC',
|
||||
},
|
||||
|
||||
Warning: {
|
||||
Main: '#ffaa00',
|
||||
MainHover: '#e69900',
|
||||
MainActive: '#cc8800',
|
||||
MainLine: '#b37700',
|
||||
OnMain: '#0a0000',
|
||||
Container: '#332200',
|
||||
ContainerHover: '#402b00',
|
||||
ContainerActive: '#4d3300',
|
||||
ContainerLine: '#5a3c00',
|
||||
OnContainer: '#ffd980',
|
||||
Main: '#FFB300',
|
||||
MainHover: '#FFC233',
|
||||
MainActive: '#FFCC4D',
|
||||
MainLine: '#FFD566',
|
||||
OnMain: '#030508',
|
||||
Container: '#221900',
|
||||
ContainerHover: '#2a2000',
|
||||
ContainerActive: '#332800',
|
||||
ContainerLine: '#3b2e00',
|
||||
OnContainer: '#FFE08A',
|
||||
},
|
||||
|
||||
Critical: {
|
||||
Main: '#ff6666',
|
||||
MainHover: '#ff5252',
|
||||
MainActive: '#ff3d3d',
|
||||
MainLine: '#ff2929',
|
||||
OnMain: '#0a0000',
|
||||
Container: '#3d0000',
|
||||
ContainerHover: '#4a0000',
|
||||
ContainerActive: '#570000',
|
||||
ContainerLine: '#640000',
|
||||
OnContainer: '#ffb3b3',
|
||||
Main: '#FF2D55',
|
||||
MainHover: '#FF4D6D',
|
||||
MainActive: '#FF6080',
|
||||
MainLine: '#FF7390',
|
||||
OnMain: '#030508',
|
||||
Container: '#22000d',
|
||||
ContainerHover: '#2a0011',
|
||||
ContainerActive: '#330015',
|
||||
ContainerLine: '#3b0019',
|
||||
OnContainer: '#FF99AA',
|
||||
},
|
||||
|
||||
Other: {
|
||||
FocusRing: 'rgba(255, 51, 0, 0.6)',
|
||||
FocusRing: 'rgba(0, 212, 255, 0.5)',
|
||||
Shadow: 'rgba(0, 0, 0, 1)',
|
||||
Overlay: 'rgba(0, 0, 0, 0.85)',
|
||||
Overlay: 'rgba(3, 5, 8, 0.94)',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
const BOOT_MESSAGES = [
|
||||
'╔═══════════════════════════════════════════════════╗',
|
||||
'║ LOTUS CHAT — LOTUSGUILD PLATFORM ║',
|
||||
'║ SECURE MATRIX CLIENT — TERMINAL MODE ACTIVE ║',
|
||||
'╚════════════════════════════════════════════════════╝',
|
||||
'',
|
||||
'[ OK ] Kernel modules loaded',
|
||||
'[ OK ] Filesystem mounted read-write',
|
||||
'[ OK ] Network interfaces configured',
|
||||
'[ OK ] Matrix homeserver connection established',
|
||||
'[ OK ] End-to-end encryption initialized',
|
||||
'[ OK ] Authentication service started',
|
||||
'[ OK ] Security headers applied',
|
||||
'[ OK ] Room state synchronized',
|
||||
'[ OK ] Terminal interface rendered',
|
||||
'',
|
||||
'> ALL SYSTEMS NOMINAL — LOTUS CHAT',
|
||||
'',
|
||||
];
|
||||
|
||||
const STORAGE_KEY = 'lt_booted_lotus-chat';
|
||||
|
||||
export function resetBootSequence(): void {
|
||||
sessionStorage.removeItem(STORAGE_KEY);
|
||||
}
|
||||
|
||||
export function runLotusBootSequence(force = false): void {
|
||||
if (!force && sessionStorage.getItem(STORAGE_KEY)) return;
|
||||
sessionStorage.setItem(STORAGE_KEY, '1');
|
||||
|
||||
const overlay = document.createElement('div');
|
||||
overlay.id = 'lt-boot';
|
||||
overlay.style.cssText = [
|
||||
'position:fixed',
|
||||
'inset:0',
|
||||
'background:#000',
|
||||
'z-index:10100',
|
||||
'display:flex',
|
||||
'align-items:flex-start',
|
||||
'justify-content:flex-start',
|
||||
'padding:3rem',
|
||||
"font-family:'JetBrains Mono','Fira Code','Courier New',monospace",
|
||||
].join(';');
|
||||
|
||||
const pre = document.createElement('pre');
|
||||
pre.style.cssText = [
|
||||
'font-family:inherit',
|
||||
'font-size:0.78rem',
|
||||
'color:#00FF88',
|
||||
'text-shadow:0 0 6px #00FF88,0 0 16px rgba(0,255,136,0.45)',
|
||||
'line-height:1.7',
|
||||
'white-space:pre-wrap',
|
||||
'overflow:hidden',
|
||||
].join(';');
|
||||
overlay.appendChild(pre);
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
let i = 0;
|
||||
let text = '';
|
||||
const interval = setInterval(() => {
|
||||
if (i >= BOOT_MESSAGES.length) {
|
||||
clearInterval(interval);
|
||||
setTimeout(() => {
|
||||
overlay.style.transition = 'opacity 0.5s ease';
|
||||
overlay.style.opacity = '0';
|
||||
setTimeout(() => overlay.remove(), 500);
|
||||
}, 500);
|
||||
return;
|
||||
}
|
||||
text += BOOT_MESSAGES[i] + '\n';
|
||||
pre.textContent = text;
|
||||
i++;
|
||||
}, 65);
|
||||
}
|
||||
+147
-16
@@ -1,28 +1,159 @@
|
||||
import { globalStyle, style } from '@vanilla-extract/css';
|
||||
import { globalStyle, keyframes, style } from '@vanilla-extract/css';
|
||||
|
||||
export const lotusTerminalBodyClass = style({});
|
||||
|
||||
globalStyle(`body.${lotusTerminalBodyClass}`, {
|
||||
fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, 'Courier New', monospace",
|
||||
letterSpacing: '0.01em',
|
||||
const glitch1 = keyframes({
|
||||
'0%, 90%, 100%': { clipPath: 'inset(0)', transform: 'skewX(0)' },
|
||||
'92%': { clipPath: 'inset(15% 0 72% 0)', transform: 'skewX(-4deg)' },
|
||||
'94%': { clipPath: 'inset(54% 0 22% 0)', transform: 'skewX(3deg)' },
|
||||
'96%': { clipPath: 'inset(30% 0 48% 0)', transform: 'skewX(-2deg)' },
|
||||
});
|
||||
|
||||
const glitch2 = keyframes({
|
||||
'0%, 90%, 100%': { clipPath: 'inset(0)', transform: 'skewX(0)' },
|
||||
'92%': { clipPath: 'inset(60% 0 8% 0)', transform: 'skewX(3deg)' },
|
||||
'94%': { clipPath: 'inset(8% 0 68% 0)', transform: 'skewX(-3deg)' },
|
||||
'96%': { clipPath: 'inset(42% 0 38% 0)', transform: 'skewX(1deg)' },
|
||||
});
|
||||
|
||||
export const lotusTerminalBodyClass = style({
|
||||
fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace",
|
||||
letterSpacing: '0.02em',
|
||||
// Dot-grid background — TDS exact (on body since we're scoped to body class)
|
||||
backgroundColor: '#030508',
|
||||
backgroundImage: 'radial-gradient(circle, rgba(0,212,255,0.055) 1px, transparent 1px)',
|
||||
backgroundSize: '28px 28px',
|
||||
vars: {
|
||||
// Backgrounds
|
||||
'--lt-bg-primary': '#030508',
|
||||
'--lt-bg-secondary': '#060c14',
|
||||
'--lt-bg-tertiary': '#0d1520',
|
||||
'--lt-bg-card': '#07101a',
|
||||
'--lt-bg-terminal': '#010304',
|
||||
// Accent — Orange
|
||||
'--lt-accent-orange': '#FF6B00',
|
||||
'--lt-accent-orange-bright': '#FF8C2B',
|
||||
'--lt-accent-orange-dim': 'rgba(255,107,0,0.12)',
|
||||
'--lt-accent-orange-border': 'rgba(255,107,0,0.35)',
|
||||
// Accent — Amber
|
||||
'--lt-accent-amber': '#FFB300',
|
||||
'--lt-accent-amber-dim': 'rgba(255,179,0,0.10)',
|
||||
// Accent — Cyan
|
||||
'--lt-accent-cyan': '#00D4FF',
|
||||
'--lt-accent-cyan-bright': '#33DFFF',
|
||||
'--lt-accent-cyan-dim': 'rgba(0,212,255,0.10)',
|
||||
'--lt-accent-cyan-border': 'rgba(0,212,255,0.22)',
|
||||
// Accent — Green
|
||||
'--lt-accent-green': '#00FF88',
|
||||
'--lt-accent-green-bright': '#33FFAA',
|
||||
'--lt-accent-green-dim': 'rgba(0,255,136,0.10)',
|
||||
'--lt-accent-green-border': 'rgba(0,255,136,0.22)',
|
||||
// Accent — Red
|
||||
'--lt-accent-red': '#FF2D55',
|
||||
'--lt-accent-red-dim': 'rgba(255,45,85,0.12)',
|
||||
// Accent — Gold
|
||||
'--lt-accent-gold': '#FFD700',
|
||||
'--lt-accent-gold-dim': 'rgba(255,215,0,0.10)',
|
||||
// Accent — Purple
|
||||
'--lt-accent-purple': '#BF5FFF',
|
||||
'--lt-accent-purple-dim': 'rgba(191,95,255,0.10)',
|
||||
// Text
|
||||
'--lt-text-primary': '#c4d9ee',
|
||||
'--lt-text-secondary': '#7fa3bf',
|
||||
'--lt-text-muted': '#3e607a',
|
||||
'--lt-text-dim': '#1e3347',
|
||||
// Borders
|
||||
'--lt-border-color': 'rgba(0,212,255,0.16)',
|
||||
'--lt-border-color-hi': '#00D4FF',
|
||||
'--lt-border-color-dim': 'rgba(0,212,255,0.07)',
|
||||
// Glows — text
|
||||
'--lt-glow-orange': '0 0 6px #FF6B00, 0 0 16px rgba(255,107,0,0.55)',
|
||||
'--lt-glow-orange-intense':'0 0 8px #FF6B00, 0 0 22px #FF6B00, 0 0 40px rgba(255,107,0,0.45)',
|
||||
'--lt-glow-cyan': '0 0 6px #00D4FF, 0 0 16px rgba(0,212,255,0.45)',
|
||||
'--lt-glow-cyan-intense': '0 0 8px #00D4FF, 0 0 22px #00D4FF, 0 0 38px rgba(0,212,255,0.35)',
|
||||
'--lt-glow-green': '0 0 6px #00FF88, 0 0 16px rgba(0,255,136,0.45)',
|
||||
'--lt-glow-green-intense': '0 0 8px #00FF88, 0 0 22px #00FF88, 0 0 36px rgba(0,255,136,0.35)',
|
||||
'--lt-glow-amber': '0 0 6px #FFB300, 0 0 14px rgba(255,179,0,0.40)',
|
||||
'--lt-glow-amber-intense': '0 0 8px #FFB300, 0 0 20px #FFB300, 0 0 34px rgba(255,179,0,0.45)',
|
||||
'--lt-glow-red': '0 0 6px #FF2D55, 0 0 16px rgba(255,45,85,0.45)',
|
||||
// Glows — box
|
||||
'--lt-box-glow-orange': '0 0 18px rgba(255,107,0,0.22), 0 0 36px rgba(255,107,0,0.08)',
|
||||
'--lt-box-glow-cyan': '0 0 18px rgba(0,212,255,0.18), 0 0 36px rgba(0,212,255,0.06)',
|
||||
'--lt-box-glow-green': '0 0 18px rgba(0,255,136,0.18), 0 0 36px rgba(0,255,136,0.06)',
|
||||
'--lt-box-glow-red': '0 0 18px rgba(255,45,85,0.22), 0 0 36px rgba(255,45,85,0.08)',
|
||||
'--lt-box-glow-amber': '0 0 18px rgba(255,179,0,0.18), 0 0 36px rgba(255,179,0,0.06)',
|
||||
// Fonts
|
||||
'--lt-font-mono': "'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace",
|
||||
'--lt-font-display': "'JetBrains Mono', 'Fira Code', 'Courier New', monospace",
|
||||
'--lt-font-crt': "'VT323', 'Courier New', monospace",
|
||||
} as any,
|
||||
});
|
||||
|
||||
// Font on all descendants
|
||||
globalStyle(`body.${lotusTerminalBodyClass} *`, {
|
||||
fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, 'Courier New', monospace !important" as any,
|
||||
fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New', monospace",
|
||||
});
|
||||
|
||||
globalStyle(`body.${lotusTerminalBodyClass}::after`, {
|
||||
content: '""',
|
||||
// Scanlines — EXACT from TDS body::before
|
||||
globalStyle(`body.${lotusTerminalBodyClass}::before`, {
|
||||
content: "''",
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
inset: 0,
|
||||
background: 'repeating-linear-gradient(0deg, rgba(0,0,0,0.07) 0px, rgba(0,0,0,0.07) 1px, transparent 1px, transparent 3px)',
|
||||
pointerEvents: 'none',
|
||||
zIndex: 9999,
|
||||
backgroundImage: 'repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.12) 2px, rgba(0,0,0,0.12) 4px)',
|
||||
});
|
||||
|
||||
globalStyle(`body.${lotusTerminalBodyClass} input, body.${lotusTerminalBodyClass} textarea`, {
|
||||
caretColor: '#ff3300',
|
||||
// Vignette — EXACT from TDS body::after
|
||||
globalStyle(`body.${lotusTerminalBodyClass}::after`, {
|
||||
content: "''",
|
||||
position: 'fixed',
|
||||
inset: 0,
|
||||
background: 'radial-gradient(ellipse at center, transparent 55%, rgba(0,0,0,0.60) 100%)',
|
||||
pointerEvents: 'none',
|
||||
zIndex: 9998,
|
||||
});
|
||||
|
||||
// Orange caret
|
||||
globalStyle(`body.${lotusTerminalBodyClass} input, body.${lotusTerminalBodyClass} textarea`, {
|
||||
caretColor: '#FF6B00',
|
||||
});
|
||||
|
||||
// Glitch class support
|
||||
globalStyle(`body.${lotusTerminalBodyClass} .lt-glitch`, { position: 'relative' });
|
||||
|
||||
globalStyle(
|
||||
`body.${lotusTerminalBodyClass} .lt-glitch::before, body.${lotusTerminalBodyClass} .lt-glitch::after`,
|
||||
{
|
||||
content: 'attr(data-text)' as any,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
}
|
||||
);
|
||||
|
||||
globalStyle(`body.${lotusTerminalBodyClass} .lt-glitch::before`, {
|
||||
color: '#00D4FF',
|
||||
opacity: 0.65,
|
||||
animationName: glitch1,
|
||||
animationDuration: '4s',
|
||||
animationIterationCount: 'infinite',
|
||||
});
|
||||
|
||||
globalStyle(`body.${lotusTerminalBodyClass} .lt-glitch::after`, {
|
||||
color: '#FF6B00',
|
||||
animationName: glitch2,
|
||||
animationDuration: '4s',
|
||||
animationIterationCount: 'infinite',
|
||||
});
|
||||
|
||||
// Scrollbar styling — matching TDS
|
||||
globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar`, { width: '6px', height: '6px' });
|
||||
globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar-track`, { background: '#030508' });
|
||||
globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar-thumb`, {
|
||||
background: 'rgba(0,212,255,0.25)',
|
||||
borderRadius: '3px',
|
||||
});
|
||||
globalStyle(`body.${lotusTerminalBodyClass} ::-webkit-scrollbar-thumb:hover`, {
|
||||
background: 'rgba(0,212,255,0.50)',
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user