Skip to content

Commit

Permalink
Fix copy to clipboard
Browse files Browse the repository at this point in the history
  • Loading branch information
JensForstmann committed Nov 15, 2023
1 parent 7f58627 commit a34acc3
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 90 deletions.
73 changes: 4 additions & 69 deletions frontend/src/components/GameServerCard.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { Component, createSignal } from 'solid-js';
import { IMatchResponse, IMatchUpdateDto } from '../../../common';
import { Component } from 'solid-js';
import { IMatchResponse } from '../../../common';
import { SvgCopyAll, SvgOpenInNew } from '../assets/Icons';
import { createFetcher } from '../utils/fetcher';
import { t } from '../utils/locale';
import { Card } from './Card';
import { CardMenu } from './CardMenu';
import { Modal } from './Modal';
import { TextInput } from './Inputs';
import { copyToClipboard } from '../utils/copyToClipboard';

export const GameServerCard: Component<{
match: IMatchResponse;
Expand All @@ -16,82 +13,20 @@ export const GameServerCard: Component<{
const command = () =>
(props.match.serverPassword ? `password "${props.match.serverPassword}"; ` : '') +
`connect ${ipPort()}`;
let modalRef: HTMLDialogElement | undefined;

return (
<Card class="text-center">
<CardMenu show entries={[[t('change game server'), () => modalRef?.showModal()]]} />
<h2 class="text-lg font-bold">{t('Game Server')}</h2>
<p>
<a href={steamUrl()}>
{steamUrl()} <SvgOpenInNew class="inline-block" />
</a>
<br />
<span class="align-middle">{command()}</span>
<button
class="ml-1 align-middle"
onClick={() => navigator.clipboard.writeText(command())}
>
<button class="ml-1 align-middle" onClick={() => copyToClipboard(command())}>
<SvgCopyAll />
</button>
</p>
<Modal ref={modalRef}>
<GameServerChangeForm match={props.match} onClose={() => modalRef?.close()} />
</Modal>
</Card>
);
};

const GameServerChangeForm: Component<{
match: IMatchResponse;
onClose: () => void;
}> = (props) => {
const [ip, setIp] = createSignal(props.match.gameServer.ip);
const [port, setPort] = createSignal(props.match.gameServer.port);
const [rconPassword, setRconPassword] = createSignal(props.match.gameServer.rconPassword);

const fetcher = createFetcher(props.match.tmtSecret);
const changeGameServer = async () => {
await fetcher('PATCH', `/api/matches/${props.match.id}`, {
gameServer: {
ip: ip(),
port: port(),
rconPassword: rconPassword(),
},
} as IMatchUpdateDto);
props.onClose();
};

return (
<>
<div class="text-left">
<TextInput
label={t('IP Address')}
value={ip()}
onChange={(e) => setIp(e.currentTarget.value)}
class="bg-base-300"
/>
<TextInput
label={t('Port')}
type="number"
value={port()}
onChange={(e) => setPort(parseInt(e.currentTarget.value))}
class="bg-base-300"
/>
<TextInput
label={t('Rcon Password')}
value={rconPassword()}
onChange={(e) => setRconPassword(e.currentTarget.value)}
class="bg-base-300"
/>
</div>
<div class="h-4" />
<button class="btn btn-primary mr-4" onClick={changeGameServer}>
{t('save')}
</button>
<button class="btn ml-4" onClick={props.onClose}>
{t('cancel')}
</button>
</>
);
};
25 changes: 4 additions & 21 deletions frontend/src/components/MatchCard.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { useNavigate, useSearchParams } from '@solidjs/router';
import { Component, Show } from 'solid-js';
import {
getMapDraws,
getMapScore,
IMatchResponse,
IMatchUpdateDto,
TMatchState,
} from '../../../common';
import { IMatchResponse, IMatchUpdateDto, getMapDraws, getMapScore } from '../../../common';
import { SvgCopyAll } from '../assets/Icons';
import { createFetcher } from '../utils/fetcher';
import { t } from '../utils/locale';
import { mustConfirm } from '../utils/mustConfirm';
import { Card } from './Card';
import { CardMenu } from './CardMenu';
import { Modal } from './Modal';
import { TextInput } from './Inputs';
import { Modal } from './Modal';
import { copyToClipboard } from '../utils/copyToClipboard';

export const MatchCard: Component<{
match: IMatchResponse;
Expand All @@ -29,14 +24,6 @@ export const MatchCard: Component<{
const init = () => patchMatch({ _init: true });
const setup = () => patchMatch({ _setup: true });
const revive = () => fetcher('PATCH', `/api/matches/${props.match.id}/revive`);
const changeState = () => {
const response = prompt(t('enter state'), 'MATCH_MAP');
if (response) {
patchMatch({
state: response as TMatchState,
});
}
};
const l = window.location;
const shareLink = l.protocol + '//' + l.host + l.pathname + '?secret=' + props.match.tmtSecret;
let modalRef: HTMLDialogElement | undefined;
Expand All @@ -52,7 +39,6 @@ export const MatchCard: Component<{
[t('restart election'), mustConfirm(restartElection)],
[t('init'), init],
[t('setup'), setup],
[t('change state'), changeState],
[t('share match with token'), () => modalRef?.showModal()],
[
t('edit match'),
Expand Down Expand Up @@ -94,10 +80,7 @@ export const MatchCard: Component<{
class="bg-base-300 w-full"
containerClass="w-full"
/>
<button
class="btn ml-4"
onClick={() => navigator.clipboard.writeText(shareLink)}
>
<button class="btn ml-4" onClick={() => copyToClipboard(shareLink)}>
<SvgCopyAll />
</button>
</div>
Expand Down
26 changes: 26 additions & 0 deletions frontend/src/utils/copyToClipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// from https://stackoverflow.com/a/65996386
export const copyToClipboard = async (textToCopy: string) => {
// Navigator clipboard api needs a secure context (https)
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(textToCopy);
} else {
// Use the 'out of viewport hidden text area' trick
const textArea = document.createElement('textarea');
textArea.value = textToCopy;

// Move textarea out of the viewport so it's not visible
textArea.style.position = 'absolute';
textArea.style.left = '-999999px';

document.body.prepend(textArea);
textArea.select();

try {
document.execCommand('copy');
} catch (error) {
console.error(error);
} finally {
textArea.remove();
}
}
};

0 comments on commit a34acc3

Please sign in to comment.