Revert "More friendly experience when presenting repack options"

This commit is contained in:
Zamitto 2024-05-18 16:26:16 -03:00 committed by GitHub
parent e5fec91062
commit 2cb76a9ad4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 16 additions and 794 deletions

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sprout"><path d="M7 20h10"/><path d="M10 20c5.5-2.5.8-6.4 3-10"/><path d="M9.5 9.4c1.1.8 1.8 2.2 2.3 3.7-2 .4-3.5.4-4.8-.3-1.2-.6-2.3-1.9-3-4.2 2.8-.5 4.4 0 5.5.8z"/><path d="M14.1 6a7 7 0 0 0-1.1 4c1.9-.1 3.3-.6 4.3-1.4 1-1 1.6-2.3 1.7-4.6-2.7.1-4 1-4.9 2z"/></svg>

Before

Width:  |  Height:  |  Size: 469 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-users"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>

Before

Width:  |  Height:  |  Size: 373 B

View file

@ -8,4 +8,3 @@ export * from "./sidebar/sidebar";
export * from "./text-field/text-field";
export * from "./checkbox-field/checkbox-field";
export * from "./link/link";
export * from "./tag/tag";

View file

@ -1,12 +0,0 @@
import { SPACING_UNIT, vars } from "../../theme.css";
import { style } from "@vanilla-extract/css";
export const tagStyle = style({
borderRadius: "3px",
border: `1px solid ${vars.color.border}`,
padding: `${SPACING_UNIT / 4}px ${SPACING_UNIT}px`,
});
export const tagText = style({
fontSize: "11px",
});

View file

@ -1,9 +0,0 @@
import * as styles from "./tag.css";
export function Tag({ children }: Readonly<{ children: React.ReactNode }>) {
return (
<div className={styles.tagStyle}>
<span className={styles.tagText}>{children}</span>
</div>
);
}

View file

@ -1,36 +0,0 @@
import { style } from "@vanilla-extract/css";
export const tooltipStyle = style({
position: "relative",
display: "flex",
cursor: "pointer",
alignItems: "center",
});
export const tooltipTextStyle = style({
visibility: "hidden",
backgroundColor: "#555",
color: "#fff",
textAlign: "center",
borderRadius: "6px",
padding: "5px 5px",
position: "absolute",
zIndex: "1",
bottom: "125%",
left: "max(0%, min(100%, 50%))",
transform: "translateX(-50%)",
":after": {
content: '""',
position: "absolute",
top: "100%",
left: "50%",
marginLeft: "-5px",
borderWidth: "5px",
borderStyle: "solid",
borderColor: "#555 transparent transparent transparent",
},
});
export const tooltipVisible = style({
visibility: "visible",
});

View file

@ -1,26 +0,0 @@
import { useState } from "react";
import * as styles from "./tooltip.css";
interface TooltipProps {
children: React.ReactNode;
tooltipText: string;
}
export function Tooltip({ children, tooltipText }: Readonly<TooltipProps>) {
const [isVisible, setIsVisible] = useState(false);
return (
<div
className={styles.tooltipStyle}
onMouseEnter={() => setIsVisible(true)}
onMouseLeave={() => setIsVisible(false)}
>
{children}
<span
className={`${styles.tooltipTextStyle} ${isVisible ? styles.tooltipVisible : ""}`}
>
{tooltipText}
</span>
</div>
);
}

View file

@ -90,9 +90,6 @@ declare global {
options: Electron.OpenDialogOptions
) => Promise<Electron.OpenDialogReturnValue>;
platform: NodeJS.Platform;
getMagnetHealth: (
magnet: string
) => Promise<{ seeders: number; peers: number }>;
}
interface Window {

View file

@ -1,39 +0,0 @@
import { toCapitalize } from "./string";
export const isMultiplayerRepack = (title: string, repacker: string) => {
const titleToLower = title.toLowerCase();
const repackerToLower = repacker.toLowerCase();
return (
titleToLower.includes("multiplayer") ||
titleToLower.includes("onlinefix") ||
titleToLower.includes("online fix") ||
repackerToLower.includes("onlinefix") ||
repackerToLower.includes("online fix")
);
};
export const supportMultiLanguage = (title: string) => {
const multiFollowedByDigitsRegex = /multi\d+/;
return multiFollowedByDigitsRegex.test(title.toLowerCase());
};
export const getRepackLanguageBasedOnRepacker = (
repacker: string,
userLanguage: string
) => {
const languageCodes = {
xatab: "ru",
};
const languageCode = languageCodes[repacker.toLowerCase()] || "en";
const displayNames = new Intl.DisplayNames([userLanguage], {
type: "language",
});
const language = displayNames.of(languageCode);
return language ? toCapitalize(language) : "English";
};

View file

@ -1,3 +0,0 @@
export function toCapitalize(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}

View file

@ -16,9 +16,3 @@ export const repackButton = style({
color: vars.color.bodyText,
padding: `${SPACING_UNIT * 2}px`,
});
export const tagsContainer = style({
display: "flex",
gap: `${SPACING_UNIT}px`,
flexWrap: "wrap",
});

View file

@ -9,14 +9,6 @@ import * as styles from "./repacks-modal.css";
import { SPACING_UNIT } from "../../theme.css";
import { format } from "date-fns";
import { SelectFolderModal } from "./select-folder-modal";
import { SeedersAndPeers } from "./seeders-and-peers/seeders-and-peers";
import {
isMultiplayerRepack,
supportMultiLanguage,
} from "@renderer/helpers/searcher";
import { Tag } from "@renderer/components/tag/tag";
import { getRepackLanguageBasedOnRepacker } from "../../helpers/searcher";
import { useAppSelector } from "@renderer/hooks";
export interface RepacksModalProps {
visible: boolean;
@ -34,9 +26,6 @@ export function RepacksModal({
const [filteredRepacks, setFilteredRepacks] = useState<GameRepack[]>([]);
const [repack, setRepack] = useState<GameRepack | null>(null);
const [showSelectFolderModal, setShowSelectFolderModal] = useState(false);
const { value: userPreferences } = useAppSelector(
(state) => state.userPreferences
);
const { t } = useTranslation("game_details");
@ -94,41 +83,12 @@ export function RepacksModal({
<p style={{ color: "#DADBE1", wordBreak: "break-word" }}>
{repack.title}
</p>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
}}
>
<div>
<p style={{ fontSize: "12px" }}>
{repack.fileSize} - {repack.repacker} -{" "}
{repack.uploadDate
? format(repack.uploadDate, "dd/MM/yyyy")
: ""}
{userPreferences?.language && (
<>
{" - " +
getRepackLanguageBasedOnRepacker(
repack.repacker,
userPreferences?.language
)}
</>
)}
</p>
</div>
<SeedersAndPeers repack={repack} />
</div>
<div className={styles.tagsContainer}>
{supportMultiLanguage(repack.title) && (
<Tag>{t("multi_language")}</Tag>
)}
{isMultiplayerRepack(repack.title, repack.repacker) && (
<Tag>{t("multiplayer")}</Tag>
)}
</div>
<p style={{ fontSize: "12px" }}>
{repack.fileSize} - {repack.repacker} -{" "}
{repack.uploadDate
? format(repack.uploadDate, "dd/MM/yyyy")
: ""}
</p>
</Button>
))}
</div>

View file

@ -1,20 +0,0 @@
import Skeleton from "react-loading-skeleton";
export function SeedersAndPeersSkeleton() {
return (
<div
style={{
display: "flex",
}}
>
<Skeleton width={40} height={20} />
<Skeleton
width={40}
height={20}
style={{
marginLeft: "12px",
}}
/>
</div>
);
}

View file

@ -1,55 +0,0 @@
import { GameRepack } from "@types";
import UsersIcon from "@renderer/assets/users-icon.svg?react";
import SproutIcon from "@renderer/assets/sprout-icon.svg?react";
import { useMagnetHealth } from "./useMagnetHealth";
import { Tooltip } from "@renderer/components/tooltip/tooltip";
import { SeedersAndPeersSkeleton } from "./seeders-and-peers-skeleton";
import { SPACING_UNIT, vars } from "@renderer/theme.css";
interface SeedersAndPeersProps {
repack: GameRepack;
}
export function SeedersAndPeers({ repack }: Readonly<SeedersAndPeersProps>) {
const { magnetData, isLoading, error } = useMagnetHealth(repack.magnet);
if (isLoading) {
return <SeedersAndPeersSkeleton />;
}
if (error) {
return null;
}
return (
<div
style={{
display: "flex",
justifyContent: "space-around",
}}
>
<Tooltip tooltipText="Seeders">
<SproutIcon stroke={vars.color.bodyText} />
<span
style={{
marginLeft: `${SPACING_UNIT - 5}px`,
marginRight: `${SPACING_UNIT}px`,
}}
>
{magnetData?.seeders}
</span>
</Tooltip>
<Tooltip tooltipText="Peers">
<UsersIcon stroke={vars.color.bodyText} />
<span
style={{
marginLeft: `${SPACING_UNIT - 5}px`,
}}
>
{magnetData?.peers}
</span>
</Tooltip>
</div>
);
}

View file

@ -1,5 +0,0 @@
export type TorrentData = {
seeders: number;
peers: number;
lastTracked?: Date;
};

View file

@ -1,80 +0,0 @@
import { useEffect, useState } from "react";
import { TorrentData } from "./types";
const cache: Record<string, TorrentData> = {};
export function useMagnetHealth(magnet: string) {
const [magnetData, setMagnetData] = useState<TorrentData | null>(
cache[magnet] || null
);
const [isLoading, setIsLoading] = useState(() => {
if (cache[magnet]) {
return false;
}
return true;
});
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
if (!magnet) {
return;
}
if (cache[magnet]) {
setMagnetData(cache[magnet]);
setIsLoading(false);
return;
}
window.electron
.getMagnetHealth(magnet)
.then(
(result) => {
if (result) {
setMagnetData(result);
setIsLoading(false);
cache[magnet] = result;
cache[magnet].lastTracked = new Date();
}
},
(error) => {
setError(error);
setIsLoading(false);
}
)
.catch(() => {});
}, [magnet]);
useEffect(() => {
function invalidateCache() {
const TWO_MINUTES = 2 * 60 * 1000;
const cacheExpiresIn = TWO_MINUTES;
Object.keys(cache).forEach((key) => {
const lastTracked = cache[key].lastTracked;
if (!lastTracked) {
return;
}
if (Date.now() - lastTracked.getTime() > cacheExpiresIn) {
delete cache[key];
}
});
}
invalidateCache();
return () => {
invalidateCache();
};
}, []);
return {
magnetData,
isLoading,
error,
};
}