Add share url button (#3259)
Some checks are pending
E2E Tests / e2e (push) Waiting to run
Tests and checks on push / run-checks-and-tests (push) Waiting to run
Updates translation progress / update-translation-progress-issue (push) Waiting to run

This commit is contained in:
hfcRed 2026-07-29 13:27:05 +02:00 committed by GitHub
parent 1b553addfb
commit 2f5a0207c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 44 deletions

View File

@ -15,7 +15,7 @@ import {
import * as React from "react";
import { Dialog, Modal, ModalOverlay } from "react-aria-components";
import { useTranslation } from "react-i18next";
import { Link } from "react-router";
import { Link, useLocation } from "react-router";
import { useUser } from "~/features/auth/core/user";
import { useChatContext } from "~/features/chat/useChatContext";
import { FriendMenu } from "~/features/friends/components/FriendMenu";
@ -27,6 +27,7 @@ import {
EVENTS_PAGE,
FRIENDS_PAGE,
navIconUrl,
SENDOU_INK_BASE_URL,
SETTINGS_PAGE,
SUPPORT_PAGE,
userPage,
@ -44,6 +45,7 @@ import {
import { navItems } from "./layout/nav-items";
import styles from "./MobileNav.module.css";
import { NotificationDot } from "./NotificationDot";
import { ShareUrlButton } from "./ShareUrlButton";
import { StreamListItems } from "./StreamListItems";
type SidebarData = RootLoaderData["sidebar"] | undefined;
@ -346,6 +348,7 @@ function MenuOverlay({
}) {
const { t } = useTranslation(["front", "common"]);
const user = useUser();
const location = useLocation();
return (
<ModalOverlay
@ -377,6 +380,11 @@ function MenuOverlay({
{t("common:pages.support")}
</LinkButton>
) : null}
<ShareUrlButton
variant="minimal"
shape="square"
url={`${SENDOU_INK_BASE_URL}${location.pathname}${location.search}`}
/>
<button
type="button"
className={styles.panelCloseButton}

View File

@ -0,0 +1,44 @@
import { Share2 } from "lucide-react";
import { useTranslation } from "react-i18next";
import { SendouButton } from "~/components/elements/Button";
import { CopyToClipboardPopover } from "./CopyToClipboardPopover";
export function ShareUrlButton({
url,
...buttonProps
}: { url: string } & React.ComponentProps<typeof SendouButton>) {
const { t } = useTranslation(["common"]);
const canNativeShare =
typeof navigator !== "undefined" && typeof navigator.share === "function";
if (canNativeShare) {
return (
<SendouButton
variant="outlined"
size="small"
shape="circle"
icon={<Share2 />}
onPress={() => navigator.share({ url })}
aria-label={t("common:actions.share")}
{...buttonProps}
/>
);
}
return (
<CopyToClipboardPopover
url={url}
trigger={
<SendouButton
variant="outlined"
size="small"
shape="circle"
icon={<Share2 />}
aria-label={t("common:actions.share")}
{...buttonProps}
/>
}
/>
);
}

View File

@ -1,11 +1,11 @@
import { Bookmark, BookmarkCheck, Share2 } from "lucide-react";
import { Bookmark, BookmarkCheck } from "lucide-react";
import { useTranslation } from "react-i18next";
import { Link, useFetcher } from "react-router";
import * as R from "remeda";
import { Avatar } from "~/components/Avatar";
import { CopyToClipboardPopover } from "~/components/CopyToClipboardPopover";
import { LinkButton, SendouButton } from "~/components/elements/Button";
import { DiscordIcon } from "~/components/icons/Discord";
import { ShareUrlButton } from "~/components/ShareUrlButton";
import TimePopover from "~/components/TimePopover";
import { useUser } from "~/features/auth/core/user";
import type { Tournament } from "~/features/tournament-bracket/core/Tournament";
@ -93,7 +93,9 @@ export function TournamentHeaderActions({
aria-label="Discord"
/>
) : null}
<ShareTournamentButton tournament={tournament} />
<ShareUrlButton
url={`${SENDOU_INK_BASE_URL}${tournamentPage(tournament.ctx.id)}`}
/>
</div>
);
}
@ -167,43 +169,3 @@ function OrganizerLink({ tournament }: { tournament: Tournament }) {
</Link>
);
}
function ShareTournamentButton({ tournament }: { tournament: Tournament }) {
const { t } = useTranslation(["common"]);
const url = `${SENDOU_INK_BASE_URL}${tournamentPage(tournament.ctx.id)}`;
const handleShare = () => {
navigator.share({ url });
};
if (
typeof navigator !== "undefined" &&
typeof navigator.share === "function"
) {
return (
<SendouButton
variant="outlined"
size="small"
shape="circle"
icon={<Share2 />}
onPress={handleShare}
aria-label={t("common:actions.share")}
/>
);
}
return (
<CopyToClipboardPopover
url={url}
trigger={
<SendouButton
variant="outlined"
size="small"
shape="circle"
icon={<Share2 />}
aria-label={t("common:actions.share")}
/>
}
/>
);
}