mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-06 23:57:19 +02:00
Refactor BxIcon
This commit is contained in:
parent
3d3a013a5c
commit
3670946da4
@ -1,5 +1,6 @@
|
|||||||
import { t } from "@utils/translation";
|
import { t } from "@utils/translation";
|
||||||
import { CE, createButton, ButtonStyle, Icon } from "@utils/html";
|
import { CE, createButton, ButtonStyle } from "@utils/html";
|
||||||
|
import { BxIcon } from "@utils/bx-icon";
|
||||||
|
|
||||||
type DialogOptions = Partial<{
|
type DialogOptions = Partial<{
|
||||||
title: string;
|
title: string;
|
||||||
@ -47,7 +48,7 @@ export class Dialog {
|
|||||||
this.$dialog = CE('div', {'class': `bx-dialog ${className || ''} bx-gone`},
|
this.$dialog = CE('div', {'class': `bx-dialog ${className || ''} bx-gone`},
|
||||||
this.$title = CE('h2', {}, CE('b', {}, title),
|
this.$title = CE('h2', {}, CE('b', {}, title),
|
||||||
helpUrl && createButton({
|
helpUrl && createButton({
|
||||||
icon: Icon.QUESTION,
|
icon: BxIcon.QUESTION,
|
||||||
style: ButtonStyle.GHOST,
|
style: ButtonStyle.GHOST,
|
||||||
title: t('help'),
|
title: t('help'),
|
||||||
url: helpUrl,
|
url: helpUrl,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { MkbPreset } from "./mkb-preset";
|
import { MkbPreset } from "./mkb-preset";
|
||||||
import { GamepadKey, MkbPresetKey, GamepadStick, MouseMapTo } from "./definitions";
|
import { GamepadKey, MkbPresetKey, GamepadStick, MouseMapTo } from "./definitions";
|
||||||
import { createButton, Icon, ButtonStyle, CE } from "@utils/html";
|
import { createButton, ButtonStyle, CE } from "@utils/html";
|
||||||
import { BxEvent } from "@utils/bx-event";
|
import { BxEvent } from "@utils/bx-event";
|
||||||
import { PrefKey, getPref } from "@utils/preferences";
|
import { PrefKey, getPref } from "@utils/preferences";
|
||||||
import { Toast } from "@utils/toast";
|
import { Toast } from "@utils/toast";
|
||||||
@ -12,6 +12,7 @@ import { showStreamSettings } from "@modules/stream/stream-ui";
|
|||||||
import { STATES } from "@utils/global";
|
import { STATES } from "@utils/global";
|
||||||
import { UserAgent } from "@utils/user-agent";
|
import { UserAgent } from "@utils/user-agent";
|
||||||
import { BxLogger } from "@utils/bx-logger";
|
import { BxLogger } from "@utils/bx-logger";
|
||||||
|
import { BxIcon } from "@utils/bx-icon";
|
||||||
|
|
||||||
const LOG_TAG = 'MkbHandler';
|
const LOG_TAG = 'MkbHandler';
|
||||||
|
|
||||||
@ -381,7 +382,7 @@ export class MkbHandler {
|
|||||||
|
|
||||||
this.#$message = CE('div', {'class': 'bx-mkb-pointer-lock-msg bx-gone'},
|
this.#$message = CE('div', {'class': 'bx-mkb-pointer-lock-msg bx-gone'},
|
||||||
createButton({
|
createButton({
|
||||||
icon: Icon.MOUSE_SETTINGS,
|
icon: BxIcon.MOUSE_SETTINGS,
|
||||||
style: ButtonStyle.PRIMARY,
|
style: ButtonStyle.PRIMARY,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -8,7 +8,7 @@ import { KeyHelper } from "./key-helper";
|
|||||||
import { MkbPreset } from "./mkb-preset";
|
import { MkbPreset } from "./mkb-preset";
|
||||||
import { MkbHandler } from "./mkb-handler";
|
import { MkbHandler } from "./mkb-handler";
|
||||||
import { LocalDb } from "@utils/local-db";
|
import { LocalDb } from "@utils/local-db";
|
||||||
import { Icon } from "@utils/html";
|
import { BxIcon } from "@utils/bx-icon";
|
||||||
import { SettingElement } from "@utils/settings";
|
import { SettingElement } from "@utils/settings";
|
||||||
import type { MkbPresetData, MkbStoredPresets } from "@/types/mkb";
|
import type { MkbPresetData, MkbStoredPresets } from "@/types/mkb";
|
||||||
|
|
||||||
@ -340,7 +340,7 @@ export class MkbRemapper {
|
|||||||
// Rename button
|
// Rename button
|
||||||
createButton({
|
createButton({
|
||||||
title: t('rename'),
|
title: t('rename'),
|
||||||
icon: Icon.CURSOR_TEXT,
|
icon: BxIcon.CURSOR_TEXT,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
const preset = this.#getCurrentPreset();
|
const preset = this.#getCurrentPreset();
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ export class MkbRemapper {
|
|||||||
|
|
||||||
// New button
|
// New button
|
||||||
createButton({
|
createButton({
|
||||||
icon: Icon.NEW,
|
icon: BxIcon.NEW,
|
||||||
title: t('new'),
|
title: t('new'),
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
let newName = promptNewName('');
|
let newName = promptNewName('');
|
||||||
@ -375,7 +375,7 @@ export class MkbRemapper {
|
|||||||
|
|
||||||
// Copy button
|
// Copy button
|
||||||
createButton({
|
createButton({
|
||||||
icon: Icon.COPY,
|
icon: BxIcon.COPY,
|
||||||
title: t('copy'),
|
title: t('copy'),
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
const preset = this.#getCurrentPreset();
|
const preset = this.#getCurrentPreset();
|
||||||
@ -395,7 +395,7 @@ export class MkbRemapper {
|
|||||||
|
|
||||||
// Delete button
|
// Delete button
|
||||||
createButton({
|
createButton({
|
||||||
icon: Icon.TRASH,
|
icon: BxIcon.TRASH,
|
||||||
style: ButtonStyle.DANGER,
|
style: ButtonStyle.DANGER,
|
||||||
title: t('delete'),
|
title: t('delete'),
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { STATES, AppInterface } from "@utils/global";
|
import { STATES, AppInterface } from "@utils/global";
|
||||||
import { CE, createButton, ButtonStyle, Icon } from "@utils/html";
|
import { CE, createButton, ButtonStyle } from "@utils/html";
|
||||||
|
import { BxIcon } from "@utils/bx-icon";
|
||||||
import { Toast } from "@utils/toast";
|
import { Toast } from "@utils/toast";
|
||||||
import { BxEvent } from "@utils/bx-event";
|
import { BxEvent } from "@utils/bx-event";
|
||||||
import { getPref, PrefKey, setPref } from "@utils/preferences";
|
import { getPref, PrefKey, setPref } from "@utils/preferences";
|
||||||
@ -183,7 +184,7 @@ export class RemotePlay {
|
|||||||
|
|
||||||
// Add Help button
|
// Add Help button
|
||||||
$fragment.appendChild(createButton({
|
$fragment.appendChild(createButton({
|
||||||
icon: Icon.QUESTION,
|
icon: BxIcon.QUESTION,
|
||||||
style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE,
|
style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE,
|
||||||
url: 'https://better-xcloud.github.io/remote-play',
|
url: 'https://better-xcloud.github.io/remote-play',
|
||||||
label: t('help'),
|
label: t('help'),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { STATES } from "@utils/global.ts";
|
import { STATES } from "@utils/global.ts";
|
||||||
import { Icon, createSvgIcon } from "@utils/html.ts";
|
import { createSvgIcon } from "@utils/html.ts";
|
||||||
|
import { BxIcon } from "@utils/bx-icon";
|
||||||
import { BxEvent } from "@utils/bx-event.ts";
|
import { BxEvent } from "@utils/bx-event.ts";
|
||||||
import { PrefKey, getPref } from "@utils/preferences.ts";
|
import { PrefKey, getPref } from "@utils/preferences.ts";
|
||||||
import { t } from "@utils/translation.ts";
|
import { t } from "@utils/translation.ts";
|
||||||
@ -66,7 +67,7 @@ class MouseHoldEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function cloneStreamHudButton($orgButton: HTMLElement, label: string, svgIcon: Icon) {
|
function cloneStreamHudButton($orgButton: HTMLElement, label: string, svgIcon: typeof BxIcon) {
|
||||||
const $container = $orgButton.cloneNode(true) as HTMLElement;
|
const $container = $orgButton.cloneNode(true) as HTMLElement;
|
||||||
let timeout: number | null;
|
let timeout: number | null;
|
||||||
|
|
||||||
@ -249,7 +250,7 @@ export function injectStreamMenuButtons() {
|
|||||||
|
|
||||||
// Create Stream Settings button
|
// Create Stream Settings button
|
||||||
if (!$btnStreamSettings) {
|
if (!$btnStreamSettings) {
|
||||||
$btnStreamSettings = cloneStreamHudButton($orgButton, t('menu-stream-settings'), Icon.STREAM_SETTINGS);
|
$btnStreamSettings = cloneStreamHudButton($orgButton, t('menu-stream-settings'), BxIcon.STREAM_SETTINGS);
|
||||||
$btnStreamSettings.addEventListener('click', e => {
|
$btnStreamSettings.addEventListener('click', e => {
|
||||||
hideGripHandle();
|
hideGripHandle();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -267,7 +268,7 @@ export function injectStreamMenuButtons() {
|
|||||||
|
|
||||||
// Create Stream Stats button
|
// Create Stream Stats button
|
||||||
if (!$btnStreamStats) {
|
if (!$btnStreamStats) {
|
||||||
$btnStreamStats = cloneStreamHudButton($orgButton, t('menu-stream-stats'), Icon.STREAM_STATS);
|
$btnStreamStats = cloneStreamHudButton($orgButton, t('menu-stream-stats'), BxIcon.STREAM_STATS);
|
||||||
$btnStreamStats.addEventListener('click', e => {
|
$btnStreamStats.addEventListener('click', e => {
|
||||||
hideGripHandle();
|
hideGripHandle();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { STATES, AppInterface, SCRIPT_HOME, SCRIPT_VERSION } from "@utils/global";
|
import { STATES, AppInterface, SCRIPT_HOME, SCRIPT_VERSION } from "@utils/global";
|
||||||
import { CE, createButton, Icon, ButtonStyle } from "@utils/html";
|
import { CE, createButton, ButtonStyle } from "@utils/html";
|
||||||
|
import { BxIcon } from "@utils/bx-icon";
|
||||||
import { getPreferredServerRegion } from "@utils/region";
|
import { getPreferredServerRegion } from "@utils/region";
|
||||||
import { UserAgent, UserAgentProfile } from "@utils/user-agent";
|
import { UserAgent, UserAgentProfile } from "@utils/user-agent";
|
||||||
import { getPref, Preferences, PrefKey, setPref, toPrefElement } from "@utils/preferences";
|
import { getPref, Preferences, PrefKey, setPref, toPrefElement } from "@utils/preferences";
|
||||||
@ -120,7 +121,7 @@ export function setupSettingsUi() {
|
|||||||
'href': SCRIPT_HOME,
|
'href': SCRIPT_HOME,
|
||||||
'target': '_blank',
|
'target': '_blank',
|
||||||
}, 'Better xCloud ' + SCRIPT_VERSION),
|
}, 'Better xCloud ' + SCRIPT_VERSION),
|
||||||
createButton({icon: Icon.QUESTION, label: t('help'), url: 'https://better-xcloud.github.io/features/'}),
|
createButton({icon: BxIcon.QUESTION, label: t('help'), url: 'https://better-xcloud.github.io/features/'}),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$updateAvailable = CE('a', {
|
$updateAvailable = CE('a', {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { SCRIPT_VERSION } from "@utils/global";
|
import { SCRIPT_VERSION } from "@utils/global";
|
||||||
import { createButton, Icon, ButtonStyle } from "@utils/html";
|
import { createButton, ButtonStyle } from "@utils/html";
|
||||||
|
import { BxIcon } from "@utils/bx-icon";
|
||||||
import { getPreferredServerRegion } from "@utils/region";
|
import { getPreferredServerRegion } from "@utils/region";
|
||||||
import { PrefKey, getPref } from "@utils/preferences";
|
import { PrefKey, getPref } from "@utils/preferences";
|
||||||
import { RemotePlay } from "@modules/remote-play";
|
import { RemotePlay } from "@modules/remote-play";
|
||||||
@ -21,7 +22,7 @@ function injectSettingsButton($parent?: HTMLElement) {
|
|||||||
if (getPref(PrefKey.REMOTE_PLAY_ENABLED)) {
|
if (getPref(PrefKey.REMOTE_PLAY_ENABLED)) {
|
||||||
const $remotePlayBtn = createButton({
|
const $remotePlayBtn = createButton({
|
||||||
classes: ['bx-header-remote-play-button'],
|
classes: ['bx-header-remote-play-button'],
|
||||||
icon: Icon.REMOTE_PLAY,
|
icon: BxIcon.REMOTE_PLAY,
|
||||||
title: t('remote-play'),
|
title: t('remote-play'),
|
||||||
style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE,
|
style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { STATES } from "@utils/global";
|
import { STATES } from "@utils/global";
|
||||||
import { Icon, CE, createButton, ButtonStyle, createSvgIcon } from "@utils/html";
|
import { CE, createButton, ButtonStyle, createSvgIcon } from "@utils/html";
|
||||||
|
import { BxIcon } from "@utils/bx-icon";
|
||||||
import { UserAgent } from "@utils/user-agent";
|
import { UserAgent } from "@utils/user-agent";
|
||||||
import { BxEvent } from "@utils/bx-event";
|
import { BxEvent } from "@utils/bx-event";
|
||||||
import { MkbRemapper } from "@modules/mkb/mkb-remapper";
|
import { MkbRemapper } from "@modules/mkb/mkb-remapper";
|
||||||
@ -70,7 +71,7 @@ function setupQuickSettingsBar() {
|
|||||||
|
|
||||||
const SETTINGS_UI = [
|
const SETTINGS_UI = [
|
||||||
getPref(PrefKey.MKB_ENABLED) && {
|
getPref(PrefKey.MKB_ENABLED) && {
|
||||||
icon: Icon.MOUSE,
|
icon: BxIcon.MOUSE,
|
||||||
group: 'mkb',
|
group: 'mkb',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -83,7 +84,7 @@ function setupQuickSettingsBar() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
icon: Icon.DISPLAY,
|
icon: BxIcon.DISPLAY,
|
||||||
group: 'stream',
|
group: 'stream',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -145,7 +146,7 @@ function setupQuickSettingsBar() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
icon: Icon.CONTROLLER,
|
icon: BxIcon.CONTROLLER,
|
||||||
group: 'controller',
|
group: 'controller',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -232,7 +233,7 @@ function setupQuickSettingsBar() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
icon: Icon.STREAM_STATS,
|
icon: BxIcon.STREAM_STATS,
|
||||||
group: 'stats',
|
group: 'stats',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -331,7 +332,7 @@ function setupQuickSettingsBar() {
|
|||||||
$group.appendChild(CE('h2', {},
|
$group.appendChild(CE('h2', {},
|
||||||
CE('span', {}, settingGroup.label),
|
CE('span', {}, settingGroup.label),
|
||||||
settingGroup.help_url && createButton({
|
settingGroup.help_url && createButton({
|
||||||
icon: Icon.QUESTION,
|
icon: BxIcon.QUESTION,
|
||||||
style: ButtonStyle.GHOST,
|
style: ButtonStyle.GHOST,
|
||||||
url: settingGroup.help_url,
|
url: settingGroup.help_url,
|
||||||
title: t('help'),
|
title: t('help'),
|
||||||
|
30
src/utils/bx-icon.ts
Normal file
30
src/utils/bx-icon.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import iconController from "@assets/svg/controller.svg" with { type: "text" };
|
||||||
|
import iconCopy from "@assets/svg/copy.svg" with { type: "text" };
|
||||||
|
import iconCursorText from "@assets/svg/cursor-text.svg" with { type: "text" };
|
||||||
|
import iconDisplay from "@assets/svg/display.svg" with { type: "text" };
|
||||||
|
import iconMouseSettings from "@assets/svg/mouse-settings.svg" with { type: "text" };
|
||||||
|
import iconMouse from "@assets/svg/mouse.svg" with { type: "text" };
|
||||||
|
import iconNew from "@assets/svg/new.svg" with { type: "text" };
|
||||||
|
import iconQuestion from "@assets/svg/question.svg" with { type: "text" };
|
||||||
|
import iconRemotePlay from "@assets/svg/remote-play.svg" with { type: "text" };
|
||||||
|
import iconStreamSettings from "@assets/svg/stream-settings.svg" with { type: "text" };
|
||||||
|
import iconStreamStats from "@assets/svg/stream-stats.svg" with { type: "text" };
|
||||||
|
import iconTrash from "@assets/svg/trash.svg" with { type: "text" };
|
||||||
|
|
||||||
|
export const BxIcon = {
|
||||||
|
STREAM_SETTINGS: iconStreamSettings,
|
||||||
|
STREAM_STATS: iconStreamStats,
|
||||||
|
CONTROLLER: iconController,
|
||||||
|
DISPLAY: iconDisplay,
|
||||||
|
MOUSE: iconMouse,
|
||||||
|
MOUSE_SETTINGS: iconMouseSettings,
|
||||||
|
NEW: iconNew,
|
||||||
|
COPY: iconCopy,
|
||||||
|
TRASH: iconTrash,
|
||||||
|
CURSOR_TEXT: iconCursorText,
|
||||||
|
QUESTION: iconQuestion,
|
||||||
|
|
||||||
|
REMOTE_PLAY: iconRemotePlay,
|
||||||
|
|
||||||
|
// HAND_TAP = '<path d="M6.537 8.906c0-4.216 3.469-7.685 7.685-7.685s7.685 3.469 7.685 7.685M7.719 30.778l-4.333-7.389C3.133 22.944 3 22.44 3 21.928a2.97 2.97 0 0 1 2.956-2.956 2.96 2.96 0 0 1 2.55 1.461l2.761 4.433V8.906a2.97 2.97 0 0 1 2.956-2.956 2.97 2.97 0 0 1 2.956 2.956v8.276a2.97 2.97 0 0 1 2.956-2.956 2.97 2.97 0 0 1 2.956 2.956v2.365a2.97 2.97 0 0 1 2.956-2.956A2.97 2.97 0 0 1 29 19.547v5.32c0 3.547-1.182 5.911-1.182 5.911"/>',
|
||||||
|
} as const;
|
@ -1,22 +1,10 @@
|
|||||||
import iconController from "@assets/svg/controller.svg" with { type: "text" };
|
import type { BxIcon } from "@utils/bx-icon";
|
||||||
import iconCopy from "@assets/svg/copy.svg" with { type: "text" };
|
|
||||||
import iconCursorText from "@assets/svg/cursor-text.svg" with { type: "text" };
|
|
||||||
import iconDisplay from "@assets/svg/display.svg" with { type: "text" };
|
|
||||||
import iconMouseSettings from "@assets/svg/mouse-settings.svg" with { type: "text" };
|
|
||||||
import iconMouse from "@assets/svg/mouse.svg" with { type: "text" };
|
|
||||||
import iconNew from "@assets/svg/new.svg" with { type: "text" };
|
|
||||||
import iconQuestion from "@assets/svg/question.svg" with { type: "text" };
|
|
||||||
import iconRemotePlay from "@assets/svg/remote-play.svg" with { type: "text" };
|
|
||||||
import iconStreamSettings from "@assets/svg/stream-settings.svg" with { type: "text" };
|
|
||||||
import iconStreamStats from "@assets/svg/stream-stats.svg" with { type: "text" };
|
|
||||||
import iconTrash from "@assets/svg/trash.svg" with { type: "text" };
|
|
||||||
|
|
||||||
|
|
||||||
type BxButton = {
|
type BxButton = {
|
||||||
style?: number | string;
|
style?: number | string;
|
||||||
url?: string;
|
url?: string;
|
||||||
classes?: string[];
|
classes?: string[];
|
||||||
icon?: Icon;
|
icon?: typeof BxIcon;
|
||||||
label?: string;
|
label?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
@ -68,25 +56,7 @@ export const CE = createElement;
|
|||||||
// Credit: https://phosphoricons.com
|
// Credit: https://phosphoricons.com
|
||||||
const svgParser = (svg: string) => new DOMParser().parseFromString(svg, 'image/svg+xml').documentElement;
|
const svgParser = (svg: string) => new DOMParser().parseFromString(svg, 'image/svg+xml').documentElement;
|
||||||
|
|
||||||
export enum Icon {
|
export const createSvgIcon = (icon: typeof BxIcon) => {
|
||||||
STREAM_SETTINGS = iconStreamSettings,
|
|
||||||
STREAM_STATS = iconStreamStats,
|
|
||||||
CONTROLLER = iconController,
|
|
||||||
DISPLAY = iconDisplay,
|
|
||||||
MOUSE = iconMouse,
|
|
||||||
MOUSE_SETTINGS = iconMouseSettings,
|
|
||||||
NEW = iconNew,
|
|
||||||
COPY = iconCopy,
|
|
||||||
TRASH = iconTrash,
|
|
||||||
CURSOR_TEXT = iconCursorText,
|
|
||||||
QUESTION = iconQuestion,
|
|
||||||
|
|
||||||
REMOTE_PLAY = iconRemotePlay,
|
|
||||||
|
|
||||||
// HAND_TAP = '<path d="M6.537 8.906c0-4.216 3.469-7.685 7.685-7.685s7.685 3.469 7.685 7.685M7.719 30.778l-4.333-7.389C3.133 22.944 3 22.44 3 21.928a2.97 2.97 0 0 1 2.956-2.956 2.96 2.96 0 0 1 2.55 1.461l2.761 4.433V8.906a2.97 2.97 0 0 1 2.956-2.956 2.97 2.97 0 0 1 2.956 2.956v8.276a2.97 2.97 0 0 1 2.956-2.956 2.97 2.97 0 0 1 2.956 2.956v2.365a2.97 2.97 0 0 1 2.956-2.956A2.97 2.97 0 0 1 29 19.547v5.32c0 3.547-1.182 5.911-1.182 5.911"/>',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createSvgIcon = (icon: Icon) => {
|
|
||||||
return svgParser(icon.toString());
|
return svgParser(icon.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user