[feature-136] Add tags + author + hash in models items

This commit is contained in:
MathieuG-P
2023-05-03 17:18:24 +02:00
parent ab798437d5
commit d7d3c980cb
5 changed files with 225 additions and 18903 deletions
+166 -18844
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -259,6 +259,7 @@
"semver": "^7.3.8",
"tailwind-scrollbar-hide": "^1.1.7",
"tailwindcss-scoped-groups": "^2.0.0",
"tippy.js": "^6.3.7",
"use-double-click": "^1.0.5",
"use-fit-text": "^2.4.0"
},
+1 -17
View File
@@ -1,24 +1,8 @@
{
"name": "bs-manager",
"version": "1.1.1",
"lockfileVersion": 2,
"lockfileVersion": 1,
"requires": true,
"packages": {
"": {
"name": "bs-manager",
"version": "1.1.1",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"ctrlc-windows": "^2.1.0"
}
},
"node_modules/ctrlc-windows": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ctrlc-windows/-/ctrlc-windows-2.1.0.tgz",
"integrity": "sha512-OrX5KI+K+2NMN91QIhYZdW7VDO2YsSdTZW494pA7Nvw/wBdU2hz+MGP006bR978zOTrG6Q8EIeJvLJmLqc6MsQ=="
}
},
"dependencies": {
"ctrlc-windows": {
"version": "2.1.0",
@@ -1,56 +1,68 @@
import equal from "fast-deep-equal";
import { memo, useState } from "react";
import { MSModelType } from "shared/models/models/model-saber.model";
import { MSModel, MSModelType } from "shared/models/models/model-saber.model";
import { BsmImage } from "../shared/bsm-image.component";
import { motion } from "framer-motion";
import { GlowEffect } from "../shared/glow-effect.component";
import { useConstant } from "renderer/hooks/use-constant.hook";
import { LinkOpenerService } from "renderer/services/link-opener.service";
import { MODELS_TYPE_MS_PAGE_ROOT, MODEL_SABER_URL } from "shared/models/models/constants";
import { BsmLink } from "../shared/bsm-link.component";
import { useThemeColor } from "renderer/hooks/use-theme-color.hook";
import Tippy from "@tippyjs/react";
import { followCursor } from "tippy.js"
type Props = {
className?: string,
selected?: boolean,
// Model props
modelHash: string,
modelType: MSModelType,
modelId?: number,
modelName: string,
modelImage?: string,
modelAuthor?: string,
modelTags?: string[],
}
hash: string,
} & Partial<MSModel>
export const ModelItem = memo(({
className,
selected,
modelHash,
modelType,
modelId,
modelName,
modelImage,
modelAuthor,
modelTags,
hash,
id,
type,
name,
thumbnail,
author,
discord,
discordid,
tags
}: Props) => {
const linkOpener = useConstant(() => LinkOpenerService.getInstance());
const color = useThemeColor("first-color");
const [hovered, setHovered] = useState(false);
const openModelPage = () => {
if(!modelId){ return; }
const url = new URL(MODELS_TYPE_MS_PAGE_ROOT[modelType], MODEL_SABER_URL);
url.searchParams.set("id", modelId.toString());
linkOpener.open(url.toString());
};
const modelPageUrl = (() => {
if(!id){ return null; }
const url = new URL(MODELS_TYPE_MS_PAGE_ROOT[type], MODEL_SABER_URL);
url.searchParams.set("id", id.toString());
return url.toString();
})();
const authorPageUrl = (() => {
if(!discordid){ return null; }
const url = new URL("Profile", MODEL_SABER_URL);
url.searchParams.set("user", discordid.toString());
return url.toString();
})();
return (
<motion.li className={`relative w-52 h-52 cursor-pointer ${className ?? ""}`} onHoverStart={() => setHovered(() => true)} onHoverEnd={() => setHovered(() => false)}>
<GlowEffect visible={selected || hovered}/>
<div className="absolute top-0 left-0 w-full h-full rounded-lg overflow-hidden blur-none">
<BsmImage className="absolute top-0 left-0 w-full h-full" image={modelImage} loading="lazy"/>
<motion.div className="absolute cursor-default top-[80%] left-0 w-full h-full p-2 bg-main-color-1 z-[1] bg-opacity-60 backdrop-blur-md transition-all hover:top-0">
<h1 className={`w-full max-w-full overflow-hidden font-bold whitespace-nowrap text-ellipsis ${modelId ? "cursor-pointer hover:underline" : ""}`} onClick={openModelPage}>{modelName}</h1>
<BsmImage className="absolute top-0 left-0 w-full h-full" image={thumbnail} loading="lazy"/>
<motion.div className="absolute cursor-default top-[80%] left-0 w-full h-full p-2 flex flex-col gap-1.5 bg-main-color-2 z-[1] bg-opacity-60 backdrop-blur-md transition-all hover:top-0">
<BsmLink className={`block w-full max-w-full overflow-hidden font-bold whitespace-nowrap text-ellipsis ${id ? "cursor-pointer hover:underline" : ""}`} href={modelPageUrl}>{name}</BsmLink>
<BsmLink className={`block w-full max-w-full overflow-hidden whitespace-nowrap text-ellipsis brightness-200 ${authorPageUrl ? "cursor-pointer hover:underline" : ""}`} style={{color}} href={authorPageUrl}>{author ?? ''}</BsmLink>
<ul className="flex flex-row flex-wrap gap-1">
{tags?.map(tag => (
<li key={tag} className="inline-block mr-1 text-xs bg-white text-black px-1 rounded-full p-0.5">{tag}</li>
))}
</ul>
<Tippy placement="top" content="Copy hash" followCursor="horizontal" plugins={[followCursor]}>
<div className="cursor-copy block w-full max-w-full overflow-hidden whitespace-nowrap text-ellipsis bg-main-color-2 rounded-md p-1 uppercase text-sm pointer-events-auto">{hash}</div>
</Tippy>
</motion.div>
</div>
</motion.li>
@@ -25,6 +25,9 @@ export function ModelsGrid({className, version, type}: Props) {
const [models, setModelsLoadObservable] = useSwitchableObservable<Progression<BsmLocalModel[]>>();
const isLoading = !models || !models?.extra;
const hasModels = !isLoading && models?.extra.length;
console.log(models);
useOnUpdate(() => {
@@ -37,22 +40,22 @@ export function ModelsGrid({className, version, type}: Props) {
return (
<div ref={ref} className={`w-full h-full flex-shrink-0 ${className ?? ""}`}>
{!models || !models?.extra ? (
<>loading</>
) : !models?.extra.length ? (
<>no models</>
) : (
{isLoading && <>loading</>}
{!hasModels && <>no models</>}
{hasModels && !isLoading && (
<ul className="flex w-full h-full overflow-scroll p-4 gap-4">
{models.extra.map(localModel => (
<ModelItem
key={localModel.model?.hash ?? localModel.hash}
modelHash={localModel.model?.hash ?? localModel.hash}
modelId={localModel.model?.id}
modelType={localModel.type}
modelName={localModel.model?.name ?? localModel.fileName}
modelImage={localModel.model?.thumbnail}
modelAuthor={localModel.model?.author}
modelTags={localModel.model?.tags}
hash={localModel.model?.hash ?? localModel.hash}
id={localModel.model?.id}
type={localModel.type}
name={localModel.model?.name ?? localModel.fileName}
thumbnail={localModel.model?.thumbnail}
author={localModel.model?.author}
discord={localModel.model?.discord}
discordid={localModel.model?.discordid}
tags={localModel.model?.tags}
selected={false}
/>
))}