"autoprefixer": "^10.4.2",
"axios": "^1.5.0",
"bootstrap": "^5.1.3",
+ "copy-to-clipboard": "^3.3.3",
"eslint": "^9.29.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-react": "^7.29.3",
"csstype": "^3.0.2"
}
},
- "node_modules/@types/react-dom": {
- "version": "18.3.7",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
- "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "peerDependencies": {
- "@types/react": "^18.0.0"
- }
- },
"node_modules/@types/react-transition-group": {
"version": "4.4.12",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz",
"dev": true,
"license": "MIT"
},
+ "node_modules/copy-to-clipboard": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
+ "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "toggle-selection": "^1.0.6"
+ }
+ },
"node_modules/core-js-compat": {
"version": "3.43.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz",
"jquery": ">=1.12.0"
}
},
+ "node_modules/toggle-selection": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
+ "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"autoprefixer": "^10.4.2",
"axios": "^1.5.0",
"bootstrap": "^5.1.3",
+ "copy-to-clipboard": "^3.3.3",
"eslint": "^9.29.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-react": "^7.29.3",
+import copy from 'copy-to-clipboard';
import PropTypes from 'prop-types';
import React from 'react';
-import { Button } from 'react-bootstrap';
+import { Button, Overlay, Tooltip } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { useUser } from '../../hooks/user';
const Item = ({ episode }) => {
+ const [showCopied, setShowCopied] = React.useState(false);
+ const copyButton = React.useRef();
+ const copyTimer = React.useRef(null);
+
const { onAddRestream, onEditEpisode, onEditRestream } = useEpisodes();
const { t } = useTranslation();
const { user } = useUser();
+ const copyTime = React.useCallback(() => {
+ copy(`<t:${Math.floor(new Date(episode.start).getTime() / 1000)}:F>`);
+ setShowCopied(true);
+ if (copyTimer.current) {
+ clearTimeout(copyTimer.current);
+ }
+ copyTimer.current = setTimeout(() => {
+ setShowCopied(false);
+ copyTimer.current = null;
+ }, 1000);
+ }, [episode, setShowCopied]);
+
const classNames = [
'episodes-item',
'my-3',
return <div className={classNames.join(' ')} style={style}>
<div className="d-flex align-items-stretch">
<div className="episode-start me-3 fs-5 fs-md-4 text-end">
- {t('schedule.startTime', { date: new Date(episode.start) })}
+ <button className="m-none p-none border-0 bg-transparent" onClick={copyTime} ref={copyButton}>
+ {t('schedule.startTime', { date: new Date(episode.start) })}
+ </button>
</div>
+ <Overlay
+ placement="bottom"
+ show={showCopied}
+ target={copyButton}
+ >
+ <Tooltip>
+ {t('general.copied')}
+ </Tooltip>
+ </Overlay>
<div className="episode-titlebar">
{episode.title || episode.event ?
<h3 className="episode-title fs-5 fs-md-4">
anonymous: 'Anonym',
appDescription: 'Turniere und Tutorials für The Legend of Zelda: A Link to the Past Randomizer',
appName: 'ALttP',
+ copied: 'Kopiert',
languages: {
de: 'Deutsch',
en: 'Englisch',
anonymous: 'Anonym',
appDescription: 'Tournaments and tutorials for The Legend of Zelda: A Link to the Past Randomizer',
appName: 'ALttP',
+ copied: 'Copied',
languages: {
de: 'German',
en: 'English',
// Fixes
$form-select-indicator: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$body-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/></svg>");
$table-color: $body-color;
+$tooltip-color: $body-color;