mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-29 14:50:13 -05:00
Exported images w/ SQ season summary downloadable (#3272)
This commit is contained in:
@@ -1,10 +1,22 @@
|
||||
import clsx from "clsx";
|
||||
import { Lock, MessageCircleMore, SquarePen, Trash } from "lucide-react";
|
||||
import {
|
||||
HardDriveDownload,
|
||||
Lock,
|
||||
MessageCircleMore,
|
||||
SquarePen,
|
||||
Trash,
|
||||
} from "lucide-react";
|
||||
import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router";
|
||||
import type { Tables } from "~/db/tables";
|
||||
import { useUser } from "~/features/auth/core/user";
|
||||
import type { BuildWeaponWithTop500Info } from "~/features/builds/builds-types";
|
||||
import {
|
||||
BuildGraphic,
|
||||
type BuildGraphicOwner,
|
||||
} from "~/features/img-export/components/BuildGraphic";
|
||||
import { ImageExportDialog } from "~/features/img-export/components/ImageExportDialog";
|
||||
import type {
|
||||
Ability as AbilityType,
|
||||
BuildAbilitiesTuple,
|
||||
@@ -28,6 +40,7 @@ import { Ability } from "./Ability";
|
||||
import styles from "./BuildCard.module.css";
|
||||
import { LinkButton, SendouButton } from "./elements/Button";
|
||||
import { SendouPopover } from "./elements/Popover";
|
||||
import { SendouSwitch } from "./elements/Switch";
|
||||
import { FormWithConfirm } from "./FormWithConfirm";
|
||||
import { Image } from "./Image";
|
||||
import { LocaleTime } from "./LocaleTime";
|
||||
@@ -48,11 +61,21 @@ interface BuildProps {
|
||||
modes: ModeShort[] | null;
|
||||
weapons: Array<BuildWeaponWithTop500Info>;
|
||||
};
|
||||
owner?: Pick<UserWithPlusTier, "discordId" | "username" | "plusTier">;
|
||||
owner?: Pick<UserWithPlusTier, "discordId" | "username" | "plusTier"> &
|
||||
Partial<
|
||||
Pick<BuildGraphicOwner, "customUrl" | "discordAvatar" | "customAvatarUrl">
|
||||
>;
|
||||
/** Set to false when the page context already shows the owner (e.g. their own builds page) */
|
||||
showOwner?: boolean;
|
||||
canEdit?: boolean;
|
||||
}
|
||||
|
||||
export function BuildCard({ build, owner, canEdit = false }: BuildProps) {
|
||||
export function BuildCard({
|
||||
build,
|
||||
owner,
|
||||
showOwner = true,
|
||||
canEdit = false,
|
||||
}: BuildProps) {
|
||||
const user = useUser();
|
||||
const { t } = useTranslation(["weapons", "builds", "common", "game-misc"]);
|
||||
|
||||
@@ -100,15 +123,15 @@ export function BuildCard({ build, owner, canEdit = false }: BuildProps) {
|
||||
</h2>
|
||||
</div>
|
||||
<div className={styles.dateAuthorRow}>
|
||||
{owner && (
|
||||
{owner && showOwner ? (
|
||||
<>
|
||||
<Link to={userBuildsPage(owner)} className={styles.ownerLink}>
|
||||
{owner.username}
|
||||
</Link>
|
||||
<div>•</div>
|
||||
</>
|
||||
)}
|
||||
{owner?.plusTier ? (
|
||||
) : null}
|
||||
{owner?.plusTier && showOwner ? (
|
||||
<>
|
||||
<span>+{owner.plusTier}</span>
|
||||
<div>•</div>
|
||||
@@ -180,6 +203,7 @@ export function BuildCard({ build, owner, canEdit = false }: BuildProps) {
|
||||
path={navIconUrl("analyzer")}
|
||||
/>
|
||||
</LinkButton>
|
||||
{owner ? <BuildImageExportDialog build={build} owner={owner} /> : null}
|
||||
{description ? (
|
||||
<SendouPopover
|
||||
trigger={
|
||||
@@ -229,6 +253,67 @@ export function BuildCard({ build, owner, canEdit = false }: BuildProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function BuildImageExportDialog({
|
||||
build,
|
||||
owner,
|
||||
}: {
|
||||
build: BuildProps["build"];
|
||||
owner: BuildGraphicOwner;
|
||||
}) {
|
||||
const { t } = useTranslation(["common"]);
|
||||
const [showTitle, setShowTitle] = React.useState(true);
|
||||
const [showAbilityPoints, setShowAbilityPoints] = React.useState(true);
|
||||
const [showAbilityChunks, setShowAbilityChunks] = React.useState(false);
|
||||
|
||||
return (
|
||||
<ImageExportDialog
|
||||
trigger={
|
||||
<SendouButton
|
||||
shape="circle"
|
||||
size="small"
|
||||
variant="minimal"
|
||||
icon={<HardDriveDownload />}
|
||||
className={styles.smallText}
|
||||
aria-label={t("common:imageExport.export")}
|
||||
/>
|
||||
}
|
||||
heading={t("common:imageExport.export")}
|
||||
filename={`build-${mySlugify(build.title)}`}
|
||||
qrCodePath={analyzerPage({
|
||||
weaponId: build.weapons[0].weaponSplId,
|
||||
abilities: build.abilities.flat(),
|
||||
})}
|
||||
settings={
|
||||
<>
|
||||
<SendouSwitch isSelected={showTitle} onChange={setShowTitle}>
|
||||
{t("common:imageExport.buildTitle")}
|
||||
</SendouSwitch>
|
||||
<SendouSwitch
|
||||
isSelected={showAbilityPoints}
|
||||
onChange={setShowAbilityPoints}
|
||||
>
|
||||
{t("common:imageExport.abilityPoints")}
|
||||
</SendouSwitch>
|
||||
<SendouSwitch
|
||||
isSelected={showAbilityChunks}
|
||||
onChange={setShowAbilityChunks}
|
||||
>
|
||||
{t("common:imageExport.abilityChunks")}
|
||||
</SendouSwitch>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<BuildGraphic
|
||||
build={build}
|
||||
owner={owner}
|
||||
showTitle={showTitle}
|
||||
showAbilityPoints={showAbilityPoints}
|
||||
showAbilityChunks={showAbilityChunks}
|
||||
/>
|
||||
</ImageExportDialog>
|
||||
);
|
||||
}
|
||||
|
||||
function RoundWeaponImage({ weapon }: { weapon: BuildWeaponWithTop500Info }) {
|
||||
const normalizedWeaponSplId = canonicalWeaponSplId(weapon.weaponSplId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user