From d1dc7bbca0a4b3640f15e2752dff4e026472f05d Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Thu, 4 May 2023 00:08:52 +0200 Subject: [PATCH] [feature-136] Add default image + fix not get local platforms + Add temp icon in nav bar + some style adjustements --- src/main/helpers/fs.helpers.ts | 6 --- .../local-models-manager.service.ts | 11 ++-- .../model-item.component.tsx | 37 ++++++++++---- .../models-grid.component.tsx | 2 +- .../models-tabs-navbar.component.tsx | 51 ++++++++++--------- .../shared/bs-content-nav-bar.component.tsx | 2 + .../hooks/use-switchable-observable.hook.ts | 4 +- src/shared/models/models/constants.ts | 7 +++ 8 files changed, 75 insertions(+), 45 deletions(-) diff --git a/src/main/helpers/fs.helpers.ts b/src/main/helpers/fs.helpers.ts index a3a629c2..4dc75ebf 100644 --- a/src/main/helpers/fs.helpers.ts +++ b/src/main/helpers/fs.helpers.ts @@ -127,12 +127,6 @@ export async function copyDirectoryWithJunctions(src: string, dest: string, opti } } -export function extname(filePath: string, withDot = true){ - const ext = path.extname(filePath); - if(withDot){ return ext; } - return ext.split('.').at(-1); -} - export interface Progression{ total: number; current: number; diff --git a/src/main/services/additional-content/local-models-manager.service.ts b/src/main/services/additional-content/local-models-manager.service.ts index 0ca6b6a5..ff35e956 100644 --- a/src/main/services/additional-content/local-models-manager.service.ts +++ b/src/main/services/additional-content/local-models-manager.service.ts @@ -11,8 +11,8 @@ import path from "path"; import { RequestService } from "../request.service"; import { copyFileSync } from "fs-extra"; import sanitize from "sanitize-filename"; -import { Progression, ensureFolderExist, extname } from "../../helpers/fs.helpers"; -import { MODEL_TYPE_FOLDERS } from "../../../shared/models/models/constants"; +import { Progression, ensureFolderExist } from "../../helpers/fs.helpers"; +import { MODEL_FILE_EXTENSIONS, MODEL_TYPE_FOLDERS } from "../../../shared/models/models/constants"; import { InstallationLocationService } from "../installation-location.service"; import { Observable } from "rxjs"; import { readdir } from "fs/promises"; @@ -118,7 +118,12 @@ export class LocalModelsManagerService { const modelsPath = await this.getModelFolderPath(type, version); const files = await readdir(modelsPath, {withFileTypes: true}); - return files.filter(file => file.isFile() && extname(file.name, false) === type).map(file => path.join(modelsPath, file.name)); + //return files.filter(file => file.isFile() && path.extname(file.name) === MODEL_FILE_EXTENSIONS[type]).map(file => path.join(modelsPath, file.name)); + return files.reduce((acc, file) => { + if(!file.isFile() || path.extname(file.name) !== MODEL_FILE_EXTENSIONS[type]){ return acc; } + acc.push(path.join(modelsPath, file.name)); + return acc; + }, []); } public getModels(type: MSModelType, version?: BSVersion): Observable>{ diff --git a/src/renderer/components/models-management/model-item.component.tsx b/src/renderer/components/models-management/model-item.component.tsx index 92a27ae0..be4dea3f 100644 --- a/src/renderer/components/models-management/model-item.component.tsx +++ b/src/renderer/components/models-management/model-item.component.tsx @@ -1,6 +1,6 @@ import equal from "fast-deep-equal"; import { memo, useState } from "react"; -import { MSModel, MSModelType } from "shared/models/models/model-saber.model"; +import { MSModel } 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"; @@ -9,11 +9,13 @@ 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" +import defaultImage from '../../../../assets/images/default-version-img.jpg' type Props = { className?: string, selected?: boolean, hash: string, + onClick?: React.ComponentProps<"li">["onClick"], } & Partial export const ModelItem = memo(({ @@ -25,13 +27,14 @@ export const ModelItem = memo(({ name, thumbnail, author, - discord, discordid, - tags + tags, + onClick }: Props) => { const color = useThemeColor("first-color"); const [hovered, setHovered] = useState(false); + const [idContentCopied, setIdContentCopied] = useState(null); const modelPageUrl = (() => { if(!id){ return null; } @@ -47,22 +50,36 @@ export const ModelItem = memo(({ return url.toString(); })(); + const copyContent = (value: string, id?: string) => { + navigator.clipboard.writeText(value); + setIdContentCopied(() => id); + setTimeout(() => { + setIdContentCopied(() => null); + }, 700); + } + return ( - setHovered(() => true)} onHoverEnd={() => setHovered(() => false)}> + // TODO TRANSLATE ALL TEXT + setHovered(() => true)} onHoverEnd={() => setHovered(() => false)} onClick={onClick}>
- - - {name} - {author ?? ''} + + {e.stopPropagation(); e.preventDefault()}}> + {name} + {author ?? ''}
    {tags?.map(tag => (
  • {tag}
  • ))}
- -
{hash}
+ + copyContent(`${hash}`, 'hash')}>{hash} + {id && ( + + copyContent(`${id}`, 'id')}>{id} + + )}
diff --git a/src/renderer/components/models-management/models-grid.component.tsx b/src/renderer/components/models-management/models-grid.component.tsx index 8a6372dd..b1c223f9 100644 --- a/src/renderer/components/models-management/models-grid.component.tsx +++ b/src/renderer/components/models-management/models-grid.component.tsx @@ -43,7 +43,7 @@ export function ModelsGrid({className, version, type}: Props) { {isLoading && <>loading} {!hasModels && <>no models} {hasModels && !isLoading && ( -
    +
      {models.extra.map(localModel => ( ( - + ( + )}/> ) } @@ -33,11 +34,12 @@ export function ModelsTabsNavbar({className, version, tabIndex, onTabChange}: Pr type TabProps = { version?: BSVersion, modelType: MSModelType, + active?: boolean, onLink?: (type: MSModelType) => void, onUnlink?: (type: MSModelType) => void, -} & DetailedHTMLProps, HTMLLIElement>; +} & React.ComponentProps<"li">; -function ModelTab({version, modelType, onClick, onLink, onUnlink}: TabProps){ +function ModelTab({version, modelType, active, onClick, onLink, onUnlink}: TabProps){ const modelsManager = useConstant(() => ModelsManagerService.getInstance()); @@ -45,7 +47,7 @@ function ModelTab({version, modelType, onClick, onLink, onUnlink}: TabProps){ const [linkBtnDisabled, setLinkBtnDisabled] = useState(false); useOnUpdate(() => { - if(!version){ return; } + if(!version){ return null; } const sub = modelsManager.$modelsLinkingPending(version, modelType).subscribe(async (pending) => { if(pending){ return setLinkBtnDisabled(() => pending); } @@ -69,24 +71,27 @@ function ModelTab({version, modelType, onClick, onLink, onUnlink}: TabProps){ } return ( -
    • - {modelType} -
      - {!!version && ( - - )} -
      -
    • +
    • +
      + + {modelType} +
      +
      + {!!version && ( + + )} +
      +
    • ) } diff --git a/src/renderer/components/shared/bs-content-nav-bar.component.tsx b/src/renderer/components/shared/bs-content-nav-bar.component.tsx index b1732a3f..f68ef852 100644 --- a/src/renderer/components/shared/bs-content-nav-bar.component.tsx +++ b/src/renderer/components/shared/bs-content-nav-bar.component.tsx @@ -1,4 +1,5 @@ import { DetailedHTMLProps, Fragment } from "react"; +import { BsmIconType } from "../svgs/bsm-icon.component"; type Props = { className?: string; @@ -10,6 +11,7 @@ type Props = { export type BsContentNavBarTab = { text: string; + icon?: BsmIconType; extra?: T } diff --git a/src/renderer/hooks/use-switchable-observable.hook.ts b/src/renderer/hooks/use-switchable-observable.hook.ts index 08e4bc49..a7b4d7ad 100644 --- a/src/renderer/hooks/use-switchable-observable.hook.ts +++ b/src/renderer/hooks/use-switchable-observable.hook.ts @@ -1,7 +1,7 @@ import { Observable } from "rxjs"; import { useState, useEffect } from "react"; -export function useSwitchableObservable(observable?: Observable, clearOnSwitch = true): [T, React.Dispatch>>]{ +export function useSwitchableObservable(observable?: Observable, clearOnSwitch = true): [T, React.Dispatch>>, Observable]{ const [currentObs, setCurrentObs] = useState(observable); const [obsValue, setObsValue] = useState(); @@ -15,5 +15,5 @@ export function useSwitchableObservable(observable?: Observable, clearOnSw } }, [currentObs]) - return [obsValue, setCurrentObs]; + return [obsValue, setCurrentObs, currentObs]; } \ No newline at end of file diff --git a/src/shared/models/models/constants.ts b/src/shared/models/models/constants.ts index dcce515f..0aa20cdf 100644 --- a/src/shared/models/models/constants.ts +++ b/src/shared/models/models/constants.ts @@ -14,4 +14,11 @@ export const MODELS_TYPE_MS_PAGE_ROOT = { [MSModelType.Bloq]: "Bloqs", [MSModelType.Platfrom]: "Platforms", [MSModelType.Saber]: "Sabers" +} + +export const MODEL_FILE_EXTENSIONS = { + [MSModelType.Avatar]: ".avatar", + [MSModelType.Bloq]: ".bloq", + [MSModelType.Platfrom]: ".plat", + [MSModelType.Saber]: ".saber" } \ No newline at end of file