mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feature-136] Add tags + author + hash in models items
This commit is contained in:
Generated
+166
-18844
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
},
|
||||
|
||||
Generated
+1
-17
@@ -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}
|
||||
/>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user