mirror of
https://github.com/Vikeo/LifeTrinket.git
synced 2025-11-12 14:16:21 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a18c253624 | ||
|
|
3f319c4f3c | ||
|
|
db80e563f2 | ||
|
|
573af42b75 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "life-trinket",
|
"name": "life-trinket",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.6.1",
|
"version": "0.6.3",
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18",
|
"node": ">=18",
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ export type RotationButtonProps = TwcComponentProps<'button'> & {
|
|||||||
$rotation?: number;
|
$rotation?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const MAX_TAP_MOVE_DISTANCE = 20;
|
||||||
|
|
||||||
const CommanderDamageContainer = twc.div<RotationDivProps>((props) => [
|
const CommanderDamageContainer = twc.div<RotationDivProps>((props) => [
|
||||||
'flex flex-grow',
|
'flex flex-grow',
|
||||||
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
|
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
|
||||||
@@ -38,7 +40,7 @@ const CommanderDamageTextContainer = twc.div<RotationDivProps>((props) => [
|
|||||||
: '',
|
: '',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const PartnerDamageSeperator = twc.div<RotationDivProps>((props) => [
|
const PartnerDamageSeparator = twc.div<RotationDivProps>((props) => [
|
||||||
'bg-black',
|
'bg-black',
|
||||||
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
|
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
|
||||||
? 'w-full h-px'
|
? 'w-full h-px'
|
||||||
@@ -54,6 +56,7 @@ type CommanderDamageButtonComponentProps = {
|
|||||||
type InputProps = {
|
type InputProps = {
|
||||||
opponentIndex: number;
|
opponentIndex: number;
|
||||||
isPartner: boolean;
|
isPartner: boolean;
|
||||||
|
event: React.PointerEvent<HTMLButtonElement>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CommanderDamage = ({
|
export const CommanderDamage = ({
|
||||||
@@ -65,6 +68,7 @@ export const CommanderDamage = ({
|
|||||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||||
const [hasPressedDown, setHasPressedDown] = useState(false);
|
const [hasPressedDown, setHasPressedDown] = useState(false);
|
||||||
|
const downPositionRef = useRef({ x: 0, y: 0 });
|
||||||
|
|
||||||
const handleCommanderDamageChange = (
|
const handleCommanderDamageChange = (
|
||||||
index: number,
|
index: number,
|
||||||
@@ -103,7 +107,8 @@ export const CommanderDamage = ({
|
|||||||
handleLifeChange(player.lifeTotal - increment);
|
handleLifeChange(player.lifeTotal - increment);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDownInput = ({ opponentIndex, isPartner }: InputProps) => {
|
const handleDownInput = ({ opponentIndex, isPartner, event }: InputProps) => {
|
||||||
|
downPositionRef.current = { x: event.clientX, y: event.clientY };
|
||||||
setTimeoutFinished(false);
|
setTimeoutFinished(false);
|
||||||
setHasPressedDown(true);
|
setHasPressedDown(true);
|
||||||
timeoutRef.current = setTimeout(() => {
|
timeoutRef.current = setTimeout(() => {
|
||||||
@@ -112,11 +117,23 @@ export const CommanderDamage = ({
|
|||||||
}, decrementTimeoutMs);
|
}, decrementTimeoutMs);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpInput = ({ opponentIndex, isPartner }: InputProps) => {
|
const handleUpInput = ({ opponentIndex, isPartner, event }: InputProps) => {
|
||||||
if (!(hasPressedDown && !timeoutFinished)) {
|
if (!(hasPressedDown && !timeoutFinished)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clearTimeout(timeoutRef.current);
|
|
||||||
|
const upPosition = { x: event.clientX, y: event.clientY };
|
||||||
|
|
||||||
|
const hasMoved =
|
||||||
|
Math.abs(upPosition.x - downPositionRef.current.x) >
|
||||||
|
MAX_TAP_MOVE_DISTANCE ||
|
||||||
|
Math.abs(upPosition.y - downPositionRef.current.y) >
|
||||||
|
MAX_TAP_MOVE_DISTANCE;
|
||||||
|
|
||||||
|
if (hasMoved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
handleCommanderDamageChange(opponentIndex, 1, isPartner);
|
handleCommanderDamageChange(opponentIndex, 1, isPartner);
|
||||||
setHasPressedDown(false);
|
setHasPressedDown(false);
|
||||||
};
|
};
|
||||||
@@ -141,10 +158,12 @@ export const CommanderDamage = ({
|
|||||||
<CommanderDamageButton
|
<CommanderDamageButton
|
||||||
key={opponentIndex}
|
key={opponentIndex}
|
||||||
$rotation={player.settings.rotation}
|
$rotation={player.settings.rotation}
|
||||||
onPointerDown={() =>
|
onPointerDown={(e) =>
|
||||||
handleDownInput({ opponentIndex, isPartner: false })
|
handleDownInput({ opponentIndex, isPartner: false, event: e })
|
||||||
|
}
|
||||||
|
onPointerUp={(e) =>
|
||||||
|
handleUpInput({ opponentIndex, isPartner: false, event: e })
|
||||||
}
|
}
|
||||||
onPointerUp={() => handleUpInput({ opponentIndex, isPartner: false })}
|
|
||||||
onPointerLeave={handleLeaveInput}
|
onPointerLeave={handleLeaveInput}
|
||||||
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -167,15 +186,15 @@ export const CommanderDamage = ({
|
|||||||
|
|
||||||
{opponent.settings.usePartner && (
|
{opponent.settings.usePartner && (
|
||||||
<>
|
<>
|
||||||
<PartnerDamageSeperator $rotation={player.settings.rotation} />
|
<PartnerDamageSeparator $rotation={player.settings.rotation} />
|
||||||
<CommanderDamageButton
|
<CommanderDamageButton
|
||||||
key={opponentIndex}
|
key={opponentIndex}
|
||||||
$rotation={player.settings.rotation}
|
$rotation={player.settings.rotation}
|
||||||
onPointerDown={() =>
|
onPointerDown={(e) =>
|
||||||
handleDownInput({ opponentIndex, isPartner: true })
|
handleDownInput({ opponentIndex, isPartner: true, event: e })
|
||||||
}
|
}
|
||||||
onPointerUp={() =>
|
onPointerUp={(e) =>
|
||||||
handleUpInput({ opponentIndex, isPartner: true })
|
handleUpInput({ opponentIndex, isPartner: true, event: e })
|
||||||
}
|
}
|
||||||
onPointerLeave={handleLeaveInput}
|
onPointerLeave={handleLeaveInput}
|
||||||
onContextMenu={(
|
onContextMenu={(
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { twc } from 'react-twc';
|
|||||||
import { decrementTimeoutMs } from '../../Data/constants';
|
import { decrementTimeoutMs } from '../../Data/constants';
|
||||||
import { CounterType, Rotation } from '../../Types/Player';
|
import { CounterType, Rotation } from '../../Types/Player';
|
||||||
import { OutlinedText } from '../Misc/OutlinedText';
|
import { OutlinedText } from '../Misc/OutlinedText';
|
||||||
import { RotationDivProps } from './CommanderDamage';
|
import { MAX_TAP_MOVE_DISTANCE, RotationDivProps } from './CommanderDamage';
|
||||||
|
|
||||||
const ExtraCounterContainer = twc.div`
|
const ExtraCounterContainer = twc.div`
|
||||||
flex
|
flex
|
||||||
@@ -63,6 +63,7 @@ const ExtraCounter = ({
|
|||||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||||
const [hasPressedDown, setHasPressedDown] = useState(false);
|
const [hasPressedDown, setHasPressedDown] = useState(false);
|
||||||
|
const downPositionRef = useRef({ x: 0, y: 0 });
|
||||||
|
|
||||||
const handleCountChange = (increment: number) => {
|
const handleCountChange = (increment: number) => {
|
||||||
if (!counterTotal) {
|
if (!counterTotal) {
|
||||||
@@ -72,7 +73,8 @@ const ExtraCounter = ({
|
|||||||
setCounterTotal(counterTotal + increment, type);
|
setCounterTotal(counterTotal + increment, type);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDownInput = () => {
|
const handleDownInput = (event: React.PointerEvent<HTMLButtonElement>) => {
|
||||||
|
downPositionRef.current = { x: event.clientX, y: event.clientY };
|
||||||
setTimeoutFinished(false);
|
setTimeoutFinished(false);
|
||||||
setHasPressedDown(true);
|
setHasPressedDown(true);
|
||||||
timeoutRef.current = setTimeout(() => {
|
timeoutRef.current = setTimeout(() => {
|
||||||
@@ -81,10 +83,23 @@ const ExtraCounter = ({
|
|||||||
}, decrementTimeoutMs);
|
}, decrementTimeoutMs);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpInput = () => {
|
const handleUpInput = (event: React.PointerEvent<HTMLButtonElement>) => {
|
||||||
if (!(hasPressedDown && !timeoutFinished)) {
|
if (!(hasPressedDown && !timeoutFinished)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const upPosition = { x: event.clientX, y: event.clientY };
|
||||||
|
|
||||||
|
const hasMoved =
|
||||||
|
Math.abs(upPosition.x - downPositionRef.current.x) >
|
||||||
|
MAX_TAP_MOVE_DISTANCE ||
|
||||||
|
Math.abs(upPosition.y - downPositionRef.current.y) >
|
||||||
|
MAX_TAP_MOVE_DISTANCE;
|
||||||
|
|
||||||
|
if (hasMoved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
clearTimeout(timeoutRef.current);
|
clearTimeout(timeoutRef.current);
|
||||||
handleCountChange(1);
|
handleCountChange(1);
|
||||||
setHasPressedDown(false);
|
setHasPressedDown(false);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useRef, useState } from 'react';
|
|||||||
import { TwcComponentProps, twc } from 'react-twc';
|
import { TwcComponentProps, twc } from 'react-twc';
|
||||||
import { lifeLongPressMultiplier } from '../../Data/constants';
|
import { lifeLongPressMultiplier } from '../../Data/constants';
|
||||||
import { Rotation } from '../../Types/Player';
|
import { Rotation } from '../../Types/Player';
|
||||||
|
import { MAX_TAP_MOVE_DISTANCE } from './CommanderDamage';
|
||||||
|
|
||||||
type RotationButtonProps = TwcComponentProps<'div'> & {
|
type RotationButtonProps = TwcComponentProps<'div'> & {
|
||||||
$align?: string;
|
$align?: string;
|
||||||
@@ -56,12 +57,14 @@ const LifeCounterButton = ({
|
|||||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||||
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
const [timeoutFinished, setTimeoutFinished] = useState(false);
|
||||||
const [hasPressedDown, setHasPressedDown] = useState(false);
|
const [hasPressedDown, setHasPressedDown] = useState(false);
|
||||||
|
const downPositionRef = useRef({ x: 0, y: 0 });
|
||||||
|
|
||||||
const handleLifeChange = (increment: number) => {
|
const handleLifeChange = (increment: number) => {
|
||||||
setLifeTotal(lifeTotal + increment);
|
setLifeTotal(lifeTotal + increment);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDownInput = () => {
|
const handleDownInput = (event: React.PointerEvent<HTMLButtonElement>) => {
|
||||||
|
downPositionRef.current = { x: event.clientX, y: event.clientY };
|
||||||
setTimeoutFinished(false);
|
setTimeoutFinished(false);
|
||||||
setHasPressedDown(true);
|
setHasPressedDown(true);
|
||||||
timeoutRef.current = setTimeout(() => {
|
timeoutRef.current = setTimeout(() => {
|
||||||
@@ -70,10 +73,23 @@ const LifeCounterButton = ({
|
|||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpInput = () => {
|
const handleUpInput = (event: React.PointerEvent<HTMLButtonElement>) => {
|
||||||
if (!(hasPressedDown && !timeoutFinished)) {
|
if (!(hasPressedDown && !timeoutFinished)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const upPosition = { x: event.clientX, y: event.clientY };
|
||||||
|
|
||||||
|
const hasMoved =
|
||||||
|
Math.abs(upPosition.x - downPositionRef.current.x) >
|
||||||
|
MAX_TAP_MOVE_DISTANCE ||
|
||||||
|
Math.abs(upPosition.y - downPositionRef.current.y) >
|
||||||
|
MAX_TAP_MOVE_DISTANCE;
|
||||||
|
|
||||||
|
if (hasMoved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
clearTimeout(timeoutRef.current);
|
clearTimeout(timeoutRef.current);
|
||||||
handleLifeChange(operation === 'add' ? 1 : -1);
|
handleLifeChange(operation === 'add' ? 1 : -1);
|
||||||
setHasPressedDown(false);
|
setHasPressedDown(false);
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
import { twc } from 'react-twc';
|
|
||||||
import { Cog } from '../../Icons/generated';
|
|
||||||
import { Rotation } from '../../Types/Player';
|
|
||||||
import { RotationButtonProps } from './CommanderDamage';
|
|
||||||
|
|
||||||
const SettingsButtonTwc = twc.button<RotationButtonProps>((props) => [
|
|
||||||
'absolute flex-grow border-none outline-none cursor-pointer bg-transparent z-[1] select-none webkit-user-select-none',
|
|
||||||
props.$rotation === Rotation.Side || props.$rotation === Rotation.SideFlipped
|
|
||||||
? `right-auto top-[1vmax] left-[27%]`
|
|
||||||
: 'top-1/4 right-[1vmax]',
|
|
||||||
]);
|
|
||||||
|
|
||||||
type SettingsButtonProps = {
|
|
||||||
onClick: () => void;
|
|
||||||
rotation: Rotation;
|
|
||||||
};
|
|
||||||
|
|
||||||
const SettingsButton = ({ onClick, rotation }: SettingsButtonProps) => {
|
|
||||||
return (
|
|
||||||
<SettingsButtonTwc
|
|
||||||
onClick={onClick}
|
|
||||||
$rotation={rotation}
|
|
||||||
aria-label={`Settings`}
|
|
||||||
>
|
|
||||||
<Cog size="5vmin" color="black" opacity="0.3" />
|
|
||||||
</SettingsButtonTwc>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SettingsButton;
|
|
||||||
@@ -64,6 +64,8 @@ type LifeCounterProps = {
|
|||||||
opponents: Player[];
|
opponents: Player[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const RECENT_DIFFERENCE_TTL = 3_000;
|
||||||
|
|
||||||
const LifeCounter = ({ player, opponents }: LifeCounterProps) => {
|
const LifeCounter = ({ player, opponents }: LifeCounterProps) => {
|
||||||
const { updatePlayer, updateLifeTotal } = usePlayers();
|
const { updatePlayer, updateLifeTotal } = usePlayers();
|
||||||
const { settings } = useGlobalSettings();
|
const { settings } = useGlobalSettings();
|
||||||
@@ -81,24 +83,26 @@ const LifeCounter = ({ player, opponents }: LifeCounterProps) => {
|
|||||||
|
|
||||||
const handlers = useSwipeable({
|
const handlers = useSwipeable({
|
||||||
trackMouse: true,
|
trackMouse: true,
|
||||||
onSwipedDown: () => {
|
onSwipedDown: (e) => {
|
||||||
|
e.event.stopPropagation();
|
||||||
console.log(`User DOWN Swiped on player ${player.index}`);
|
console.log(`User DOWN Swiped on player ${player.index}`);
|
||||||
setShowPlayerMenu(true);
|
setShowPlayerMenu(true);
|
||||||
},
|
},
|
||||||
onSwipedUp: () => {
|
onSwipedUp: (e) => {
|
||||||
|
e.event.stopPropagation();
|
||||||
console.log(`User UP Swiped on player ${player.index}`);
|
console.log(`User UP Swiped on player ${player.index}`);
|
||||||
setShowPlayerMenu(false);
|
setShowPlayerMenu(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
swipeDuration: 500,
|
swipeDuration: 500,
|
||||||
onSwiping: (eventData) => console.log(eventData),
|
onSwiping: (e) => e.event.stopPropagation(),
|
||||||
rotationAngle,
|
rotationAngle,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
setRecentDifference(0);
|
setRecentDifference(0);
|
||||||
}, 3_000);
|
}, RECENT_DIFFERENCE_TTL);
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver(() => {
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
if (document.body.clientWidth > document.body.clientHeight)
|
if (document.body.clientWidth > document.body.clientHeight)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const PlayerMenuWrapper = twc.div`
|
|||||||
w-full
|
w-full
|
||||||
h-full
|
h-full
|
||||||
bg-background-settings
|
bg-background-settings
|
||||||
|
backdrop-blur-[10px]
|
||||||
items-center
|
items-center
|
||||||
justify-center
|
justify-center
|
||||||
z-[2]
|
z-[2]
|
||||||
@@ -40,16 +41,19 @@ const BetterRowContainer = twc.div`
|
|||||||
flex-grow
|
flex-grow
|
||||||
w-full
|
w-full
|
||||||
h-full
|
h-full
|
||||||
justify-end
|
justify-between
|
||||||
items-stretch
|
items-stretch
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const TogglesSection = twc.div`
|
const TogglesSection = twc.div`
|
||||||
flex
|
flex
|
||||||
relative
|
|
||||||
flex-row
|
flex-row
|
||||||
|
flex-wrap
|
||||||
|
relative
|
||||||
gap-2
|
gap-2
|
||||||
|
h-full
|
||||||
justify-evenly
|
justify-evenly
|
||||||
|
items-center
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ButtonsSections = twc.div`
|
const ButtonsSections = twc.div`
|
||||||
@@ -59,14 +63,14 @@ const ButtonsSections = twc.div`
|
|||||||
justify-between
|
justify-between
|
||||||
p-[3%]
|
p-[3%]
|
||||||
items-center
|
items-center
|
||||||
|
flex-wrap
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ColorPicker = twc.input`
|
const ColorPicker = twc.input`
|
||||||
absolute
|
|
||||||
top-[5%]
|
|
||||||
left-[5%]
|
|
||||||
h-[8vmax]
|
h-[8vmax]
|
||||||
w-[8vmax]
|
w-[8vmax]
|
||||||
|
max-h-12
|
||||||
|
max-w-11
|
||||||
border-none
|
border-none
|
||||||
outline-none
|
outline-none
|
||||||
cursor-pointer
|
cursor-pointer
|
||||||
@@ -156,6 +160,8 @@ const PlayerMenu = ({
|
|||||||
}}
|
}}
|
||||||
ref={settingsContainerRef}
|
ref={settingsContainerRef}
|
||||||
>
|
>
|
||||||
|
<BetterRowContainer>
|
||||||
|
<TogglesSection>
|
||||||
<ColorPicker
|
<ColorPicker
|
||||||
type="color"
|
type="color"
|
||||||
value={player.color}
|
value={player.color}
|
||||||
@@ -163,8 +169,6 @@ const PlayerMenu = ({
|
|||||||
role="button"
|
role="button"
|
||||||
aria-label="Color picker"
|
aria-label="Color picker"
|
||||||
/>
|
/>
|
||||||
<BetterRowContainer>
|
|
||||||
<TogglesSection>
|
|
||||||
{player.settings.useCommanderDamage && (
|
{player.settings.useCommanderDamage && (
|
||||||
<CheckboxContainer>
|
<CheckboxContainer>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -341,7 +345,7 @@ const PlayerMenu = ({
|
|||||||
ref={dialogRef}
|
ref={dialogRef}
|
||||||
className="z-[9999] min-h-2/4 bg-background-default text-text-primary rounded-2xl border-none absolute bottom-[20%]"
|
className="z-[9999] min-h-2/4 bg-background-default text-text-primary rounded-2xl border-none absolute bottom-[20%]"
|
||||||
>
|
>
|
||||||
<div className="h-full flex flex-col p-4 gap-2">
|
<div className="flex flex-col p-4 gap-2">
|
||||||
<h1 className="text-center">Reset Game?</h1>
|
<h1 className="text-center">Reset Game?</h1>
|
||||||
<div className="flex justify-evenly gap-4">
|
<div className="flex justify-evenly gap-4">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -2,8 +2,18 @@
|
|||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
html {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
background-color: theme('colors.background.default');
|
background-color: theme('colors.background.default');
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||||
|
|||||||
Reference in New Issue
Block a user