diff --git a/src/main/services/additional-content/local-maps-manager.service.ts b/src/main/services/additional-content/local-maps-manager.service.ts index 0fdf040c..b30349aa 100644 --- a/src/main/services/additional-content/local-maps-manager.service.ts +++ b/src/main/services/additional-content/local-maps-manager.service.ts @@ -7,7 +7,7 @@ import { InstallationLocationService } from "../installation-location.service"; import { UtilsService } from "../utils.service"; import crypto from "crypto"; import { lstatSync } from "fs"; -import { copy, createReadStream, ensureDir, realpath, unlink } from "fs-extra"; +import { copy, createReadStream, ensureDir, pathExists, realpath, unlink } from "fs-extra"; import StreamZip from "node-stream-zip"; import { RequestService } from "../request.service"; import sanitize from "sanitize-filename"; @@ -255,10 +255,12 @@ export class LocalMapsManagerService { const mapFolderName = sanitize(`${map.id}-${map.name}`); const mapsFolder = await this.getMapsFolderPath(version); - const installedMap = await this.loadMapInfoFromPath(path.join(mapsFolder, mapFolderName)).catch(e => { - log.error("loadMapInfoFromPath", e); - return null; - }); + const mapPath = path.join(mapsFolder, mapFolderName); + + const installedMap = await pathExists(mapPath).then(exists => { + if(!exists){ return null; } + return this.loadMapInfoFromPath(mapPath); + }).catch(() => null); if(map.versions.every(version => version.hash === installedMap?.hash)) { return installedMap; @@ -270,8 +272,6 @@ export class LocalMapsManagerService { throw `Cannot download ${zipUrl}`; } - const mapPath = path.join(mapsFolder, mapFolderName); - await ensureFolderExist(mapPath); await zip.extract(null, mapPath); diff --git a/src/renderer/components/maps-mangement-components/link-button.component.tsx b/src/renderer/components/maps-mangement-components/link-button.component.tsx index bc8d1d6c..5f353b77 100644 --- a/src/renderer/components/maps-mangement-components/link-button.component.tsx +++ b/src/renderer/components/maps-mangement-components/link-button.component.tsx @@ -1,48 +1,60 @@ import { motion } from "framer-motion"; -import { forwardRef } from "react"; +import { useState } from "react"; import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; import { BsmIcon } from "../svgs/bsm-icon.component"; import { useTranslation } from "renderer/hooks/use-translation.hook"; +import { FolderLinkState } from "renderer/services/version-folder-linker.service"; +import { Observable } from "rxjs"; +import { useObservable } from "renderer/hooks/use-observable.hook"; -type Props = { +export type LinkBtnProps = { className?: string; title?: string; - linked?: boolean; - disabled?: boolean; + state$: Observable; onClick?: () => void; }; -export const LinkButton = motion( - forwardRef((props: Props, ref) => { - const t = useTranslation(); - const color = useThemeColor("first-color"); +export const LinkButton = ({className, title, state$, onClick}: LinkBtnProps) => { + const t = useTranslation(); + + const state = useObservable(state$); + const color = useThemeColor("first-color"); + const disabled = state === FolderLinkState.Processing || state === FolderLinkState.Pending; - const linkedColor = (() => { - if (props.disabled) { - return "orange"; - } - if (props.linked) { + const btnColor = () => { + switch (state) { + case FolderLinkState.Linked: return color; - } - return "red"; - })(); + case FolderLinkState.Pending: + case FolderLinkState.Processing: + return "orange"; + case FolderLinkState.Unlinked: + return "red"; + default: + return "red"; + } + } - return ( -
{ - e.preventDefault(); - e.stopPropagation(); - !props.disabled && props.onClick?.(); - }} - style={{ pointerEvents: props.disabled ? "none" : "auto" }} - tabIndex={-1} - > - - -
- ); - }) -); + const handleClick = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + !disabled && onClick?.(); + } + + return ( + + + + + ); +} diff --git a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx index e7af8ece..a6f66cf9 100644 --- a/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/local-maps-list-panel.component.tsx @@ -429,7 +429,7 @@ export const LocalMapsListPanel = forwardRef(({ version, className, filter, sear return (
- 108} itemCount={preppedMaps.length} itemData={preppedMaps} layout="vertical" style={{ scrollbarGutter: "stable both-edges" }} itemKey={(i, data) => data[i].map(map => map.hash).join()}> + 108} itemCount={preppedMaps.length} itemData={preppedMaps} layout="vertical" style={{ scrollbarGutter: "stable both-edges" }} itemKey={(i, data) => data[i].map(map => map.hash).join()}> {props => }
diff --git a/src/renderer/components/maps-mangement-components/map-item.component.tsx b/src/renderer/components/maps-mangement-components/map-item.component.tsx index b71ccd33..c015725f 100644 --- a/src/renderer/components/maps-mangement-components/map-item.component.tsx +++ b/src/renderer/components/maps-mangement-components/map-item.component.tsx @@ -191,8 +191,8 @@ export const MapItem = memo(({ hash, title, autor, songAutor, coverUrl, songUrl,
- -
+ +

{title} @@ -240,7 +240,7 @@ export const MapItem = memo(({ hash, title, autor, songAutor, coverUrl, songUrl,

-
+
diff --git a/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx b/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx index db26ff29..200f5952 100644 --- a/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx +++ b/src/renderer/components/maps-mangement-components/maps-playlists-panel.component.tsx @@ -1,24 +1,18 @@ -import { DetailedHTMLProps, useEffect, useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { BSVersion } from "shared/bs-version.interface"; -import { TabNavBar } from "../shared/tab-nav-bar.component"; import { LocalMapsListPanel } from "./local-maps-list-panel.component"; import { BsmDropdownButton, DropDownItem } from "../shared/bsm-dropdown-button.component"; import { FilterPanel } from "./filter-panel.component"; import { MapFilter } from "shared/models/maps/beat-saver.model"; -import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; import { MapsManagerService } from "renderer/services/maps-manager.service"; -import { motion, Variants } from "framer-motion"; import { MapsDownloaderService } from "renderer/services/maps-downloader.service"; import { BsmImage } from "../shared/bsm-image.component"; import wipGif from "../../../../assets/images/gifs/wip.gif"; -import { OsDiagnosticService } from "renderer/services/os-diagnostic.service"; -import { useObservable } from "renderer/hooks/use-observable.hook"; -import { BsmIcon } from "../svgs/bsm-icon.component"; import { useTranslation } from "renderer/hooks/use-translation.hook"; -import { LinkButton } from "./link-button.component"; -import { debounceTime } from "rxjs/operators"; import { VersionFolderLinkerService, VersionLinkerActionListener } from "renderer/services/version-folder-linker.service"; import { useService } from "renderer/hooks/use-service.hook"; +import { BsContentTabPanel } from "../shared/bs-content-tab-panel/bs-content-tab-panel.component"; +import { BsmButton } from "../shared/bsm-button.component"; type Props = { version?: BSVersion; @@ -29,7 +23,6 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) { const mapsService = useService(MapsManagerService); const mapsDownloader = useService(MapsDownloaderService); - const osDiagnostic = useService(OsDiagnosticService); const linker = useService(VersionFolderLinkerService); const [tabIndex, setTabIndex] = useState(0); @@ -37,9 +30,6 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) { const [mapSearch, setMapSearch] = useState(""); const [playlistSearch, setPlaylistSearch] = useState(""); const [mapsLinked, setMapsLinked] = useState(false); - const [linkingPending, setLinkingPending] = useState(false); - const isOnline = useObservable(osDiagnostic.isOnline$); - const color = useThemeColor("first-color"); const t = useTranslation(); const mapsRef = useRef(); @@ -50,8 +40,6 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) { loadMapIsLinked(); - const sub = mapsService.$mapsLinkingPending(version).pipe(debounceTime(50)).subscribe(setLinkingPending); - const onMapsLinked: VersionLinkerActionListener = action => { if (!action.relativeFolder.includes(MapsManagerService.RELATIVE_MAPS_FOLDER)) { return; @@ -63,7 +51,6 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) { linker.onVersionFolderUnlinked(onMapsLinked); return () => { - sub.unsubscribe(); linker.removeVersionFolderLinkedListener(onMapsLinked); linker.removeVersionFolderUnlinkedListener(onMapsLinked); }; @@ -80,6 +67,10 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) { return setPlaylistSearch(() => value); }; + const handleMapsAddClick = () => { + mapsDownloader.openDownloadMapModal(version, mapsRef.current.getMaps?.()); + }; + const handleMapsLinkClick = () => { if (!mapsLinked) { return mapsService.linkVersion(version); @@ -87,56 +78,6 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) { return mapsService.unlinkVersion(version); }; - const handleMapsAddClick = () => { - mapsDownloader.openDownloadMapModal(version, mapsRef.current.getMaps?.()); - }; - - const renderTab = (props: DetailedHTMLProps, HTMLLIElement>, text: string, index: number): JSX.Element => { - const onClickLink = (index: number) => { - if (index === 0) { - handleMapsLinkClick(); - } - }; - - const onClickAdd = (index: number) => { - if (index === 0) { - handleMapsAddClick(); - } - }; - - const variants: Variants = { hover: { rotate: 22.5 }, tap: { rotate: 45 } }; - - return ( -
  • - {text} - {index === 0 && ( -
    - {isOnline && ( - { - e.stopPropagation(); - onClickAdd(index); - }} - tabIndex={-1} - > - - - - - {t("misc.add")} - - )} - {!!version && onClickLink(index)} />} -
    - )} -
  • - ); - }; - const dropDownItems = ((): DropDownItem[] => { if (tabIndex === 1) { return []; @@ -150,6 +91,15 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) { return (
    -
    - -
    + setTabIndex(index)} + tabs={[ + { + text: "misc.maps", + icon: "trash", + onClick: () => setTabIndex(0), + linkProps: version ? { + state$: mapsService.$mapsFolderLinkState(version), + onClick: handleMapsLinkClick, + } : undefined, + }, + { + text: "misc.playlists", + icon: "trash", + onClick: () => setTabIndex(1), + }, + ]} + > + <>
    Coming soon
    -
    -
    + +
    ); } diff --git a/src/renderer/components/maps-mangement-components/maps-row.component.tsx b/src/renderer/components/maps-mangement-components/maps-row.component.tsx index e92d4ac2..4aa185e4 100644 --- a/src/renderer/components/maps-mangement-components/maps-row.component.tsx +++ b/src/renderer/components/maps-mangement-components/maps-row.component.tsx @@ -52,7 +52,7 @@ export const MapsRow = memo(({ maps, style, selectedMaps$, onMapSelect, onMapDel }; return ( -
      +
        {maps?.map(renderMapItem)}
      ); diff --git a/src/renderer/components/modal/modal-types/share-folders-modal.component.tsx b/src/renderer/components/modal/modal-types/share-folders-modal.component.tsx index 75907e77..a4d33886 100644 --- a/src/renderer/components/modal/modal-types/share-folders-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/share-folders-modal.component.tsx @@ -1,9 +1,9 @@ import Tippy from "@tippyjs/react"; -import { Variants } from "framer-motion"; import { useEffect, useState } from "react"; import { LinkButton } from "renderer/components/maps-mangement-components/link-button.component"; import { BsmBasicSpinner } from "renderer/components/shared/bsm-basic-spinner/bsm-basic-spinner.component"; import { BsmButton } from "renderer/components/shared/bsm-button.component"; +import { useConstant } from "renderer/hooks/use-constant.hook"; import { useObservable } from "renderer/hooks/use-observable.hook"; import { useService } from "renderer/hooks/use-service.hook"; import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; @@ -12,7 +12,7 @@ import { BSVersionManagerService } from "renderer/services/bs-version-manager.se import { ConfigurationService } from "renderer/services/configuration.service"; import { IpcService } from "renderer/services/ipc.service"; import { ModalComponent } from "renderer/services/modale.service"; -import { VersionFolderLinkerService, VersionLinkerActionType } from "renderer/services/version-folder-linker.service"; +import { FolderLinkState, VersionFolderLinkerService, VersionLinkerActionType } from "renderer/services/version-folder-linker.service"; import { BSVersion } from "shared/bs-version.interface"; export const ShareFoldersModal: ModalComponent = ({ data }) => { @@ -107,33 +107,13 @@ const FolderItem = ({ version, relativeFolder, onDelete }: FolderProps) => { const t = useTranslation(); - const name = relativeFolder.split(window.electron.path.sep).at(-1); const color = useThemeColor("first-color"); - - const variants: Variants = { - hover: { rotate: 22.5 }, - tap: { rotate: 45 }, - }; - - const pending = useObservable(linker.isPending(version, relativeFolder)); - const processing = useObservable(linker.isProcessing(version, relativeFolder)); - const linkDisabled = pending || processing; - - const [linked, setLinked] = useState(false); - - useEffect(() => { - if (pending) { - return; - } - loadFolderIsLinked(); - }, [version, relativeFolder, pending]); - - const loadFolderIsLinked = () => { - linker.isVersionFolderLinked(version, relativeFolder).toPromise().then(setLinked); - }; + const state$ = useConstant(() => linker.$folderLinkedState(version, relativeFolder)); + const state = useObservable(state$); + const name = relativeFolder.split(window.electron.path.sep).at(-1); const onClickLink = () => { - if (linked) { + if (state === FolderLinkState.Linked) { return linker.unlinkVersionFolder({ version, relativeFolder, @@ -150,7 +130,6 @@ const FolderItem = ({ version, relativeFolder, onDelete }: FolderProps) => { const cancelLink = () => { linker.cancelAction(version, relativeFolder); - loadFolderIsLinked(); }; return ( @@ -159,14 +138,18 @@ const FolderItem = ({ version, relativeFolder, onDelete }: FolderProps) => { {name}
      - - + + {(() => { - if (processing) { + if (state === FolderLinkState.Processing) { return ; } - if (pending) { + if (state === FolderLinkState.Pending) { return ( void }) { const modelsManager = useService(ModelsManagerService); @@ -93,6 +97,31 @@ export function ModelsPanel({ version, isActive, goToMods }: { version?: BSVersi { text: "models.panel.actions.drop-down.delete", onClick: deleteModels, icon: "trash" }, ]; + const getModelTabProps = (model: MSModelType): BsContentTabItemProps => { + + const onClick = async () => { + const state = await lastValueFrom(modelsManager.$modelsLinkingState(version, model).pipe(take(1))); + if (state === FolderLinkState.Pending || state === FolderLinkState.Processing) { return; } + if (state === FolderLinkState.Linked) { + modelsManager.unlinkModels(model, version); + } else { + modelsManager.linkModels(model, version); + } + } + + const linkProps: LinkBtnProps = version ? { + state$: modelsManager.$modelsLinkingState(version, model), + onClick, + } : undefined; + + return { + text: `models.types.plural.${model}`, + icon: model, + onClick: () => setModelTypeTab(model), + linkProps + } + }; + return (
      @@ -112,24 +141,23 @@ export function ModelsPanel({ version, isActive, goToMods }: { version?: BSVersi
      -
      - { - setModelTypeTab(() => tab.extra); - setCurrentTabIndex(() => index); - }} - /> - -
      + setCurrentTabIndex(index)} + tabs={[ + getModelTabProps(MSModelType.Avatar), + getModelTabProps(MSModelType.Saber), + getModelTabProps(MSModelType.Platfrom), + getModelTabProps(MSModelType.Bloq), + ]} + > + <> -
      -
      + +
      ); } diff --git a/src/renderer/components/models-management/models-tabs-navbar.component.tsx b/src/renderer/components/models-management/models-tabs-navbar.component.tsx deleted file mode 100644 index 71d59464..00000000 --- a/src/renderer/components/models-management/models-tabs-navbar.component.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { BSVersion } from "shared/bs-version.interface"; -import { MSModelType } from "../../../shared/models/models/model-saber.model"; -import { LinkButton } from "../maps-mangement-components/link-button.component"; -import { useState } from "react"; -import { useOnUpdate } from "renderer/hooks/use-on-update.hook"; -import { ModelsManagerService } from "renderer/services/models-management/models-manager.service"; -import { BsContentNavBar, BsContentNavBarTab } from "../shared/bs-content-nav-bar.component"; -import { useConstant } from "renderer/hooks/use-constant.hook"; -import { BsmIcon } from "../svgs/bsm-icon.component"; -import { MODEL_TYPES } from "../../../shared/models/models/constants"; -import { useService } from "renderer/hooks/use-service.hook"; -import { useTranslation } from "renderer/hooks/use-translation.hook"; - -type Props = { - className?: string; - version?: BSVersion; - tabIndex: number; - onTabChange: (index: number, tab: BsContentNavBarTab) => void; -}; - -export function ModelsTabsNavbar({ className, version, tabIndex, onTabChange }: Props) { - const tabs = useConstant[]>(() => { - return MODEL_TYPES.map(type => ({ - text: type, - extra: type, - })); - }); - - return } />; -} - -type TabProps = { - version?: BSVersion; - modelType: MSModelType; - active?: boolean; -} & React.ComponentProps<"li">; - -function ModelTab({ version, modelType, active, onClick }: TabProps) { - const modelsManager = useService(ModelsManagerService); - - const t = useTranslation(); - - const [modelsAreLinked, setModelsAreLinked] = useState(false); - const [linkBtnDisabled, setLinkBtnDisabled] = useState(false); - - useOnUpdate(() => { - if (!version) { - return; - } - - const sub = modelsManager.$modelsLinkingPending(version, modelType).subscribe(async pending => { - if (pending) { - return setLinkBtnDisabled(() => pending); - } - const modelsLinked = await modelsManager.isModelsLinked(version, modelType); - setModelsAreLinked(() => modelsLinked); - setLinkBtnDisabled(() => pending); - }); - - return () => { - sub.unsubscribe(); - }; - }, [version]); - - const linkModels = () => modelsManager.linkModels(modelType, version); - const unlinkModels = () => modelsManager.unlinkModels(modelType, version); - - const onClickLink = () => { - if (!version) { - return Promise.resolve(); - } - if (modelsAreLinked) { - return unlinkModels(); - } - return linkModels(); - }; - - return ( -
    • -
      - - {t(`models.types.plural.${modelType}`)} -
      -
      {!!version && }
      -
    • - ); -} diff --git a/src/renderer/components/settings/setting-radio-array.component.tsx b/src/renderer/components/settings/setting-radio-array.component.tsx index 60eb44a1..1a7f2e60 100644 --- a/src/renderer/components/settings/setting-radio-array.component.tsx +++ b/src/renderer/components/settings/setting-radio-array.component.tsx @@ -21,7 +21,7 @@ export function SettingRadioArray({ id, items, selectedItemId, selectedItemVa return (
      {items.map(i => ( -
      onItemSelected(i)} key={i.id} className={`py-3 w-full flex cursor-pointer justify-between items-center rounded-md px-2 transition-colors duration-200 ${isSelected(i) ? "bg-light-main-color-3 dark:bg-main-color-3" : "bg-light-main-color-1 dark:bg-main-color-1"} ${i.className}`}> +
      onItemSelected(i)} key={i.id} className={`py-3 w-full flex cursor-pointer justify-between items-center rounded-md px-2 transition-colors duration-300 ${isSelected(i) ? "bg-light-main-color-3 dark:bg-main-color-3" : "bg-light-main-color-1 dark:bg-main-color-1"} ${i.className}`}>
      diff --git a/src/renderer/components/shared/bs-content-nav-bar.component.tsx b/src/renderer/components/shared/bs-content-nav-bar.component.tsx deleted file mode 100644 index e747df83..00000000 --- a/src/renderer/components/shared/bs-content-nav-bar.component.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { DetailedHTMLProps, Fragment } from "react"; -import { BsmIconType } from "../svgs/bsm-icon.component"; - -type Props = { - className?: string; - tabIndex: number; - tabs: BsContentNavBarTab[]; - renderTab: (props: DetailedHTMLProps, any>, tab?: BsContentNavBarTab, activeTab?: BsContentNavBarTab) => JSX.Element; - onTabChange?: (index: number, tab?: BsContentNavBarTab) => void; -}; - -export type BsContentNavBarTab = { - text: string; - icon?: BsmIconType; - extra?: T; -}; - -export function BsContentNavBar({ className, tabIndex, tabs, renderTab, onTabChange }: Props) { - const handleTabClick = (index: number) => { - onTabChange?.(index, tabs[index]); - }; - - return ( - - ); -} diff --git a/src/renderer/components/shared/bs-content-tab-panel/bs-content-tab-item.component.tsx b/src/renderer/components/shared/bs-content-tab-panel/bs-content-tab-item.component.tsx new file mode 100644 index 00000000..edb55553 --- /dev/null +++ b/src/renderer/components/shared/bs-content-tab-panel/bs-content-tab-item.component.tsx @@ -0,0 +1,44 @@ +import { LinkBtnProps, LinkButton } from "renderer/components/maps-mangement-components/link-button.component"; +import { BsmIcon, BsmIconType } from "renderer/components/svgs/bsm-icon.component"; +import { useTranslation } from "renderer/hooks/use-translation.hook"; + +export type BsContentTabItemProps = { + text: string; + icon: BsmIconType; + active?: boolean; + value?: T; + linkProps?: LinkBtnProps; + onClick: (value?: T) => void; +}; + +type BsContentTabItemComponent = ({text, icon, active, value, linkProps, onClick}: BsContentTabItemProps) => JSX.Element; + +export const BsContentTabItem: BsContentTabItemComponent = ({ text, icon, active, value, linkProps, onClick }) => { + + const t = useTranslation(); + + const handleClick = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + onClick(value); + } + + return ( +
    • +
      + + {t(text)} +
      + {linkProps && ( +
      + +
      + )} +
    • + ); +} \ No newline at end of file diff --git a/src/renderer/components/shared/bs-content-tab-panel/bs-content-tab-panel.component.tsx b/src/renderer/components/shared/bs-content-tab-panel/bs-content-tab-panel.component.tsx new file mode 100644 index 00000000..8a4239f6 --- /dev/null +++ b/src/renderer/components/shared/bs-content-tab-panel/bs-content-tab-panel.component.tsx @@ -0,0 +1,35 @@ +import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; +import { LaserSlider } from "../laser-slider.component"; +import { BsContentTabItem, BsContentTabItemProps } from "./bs-content-tab-item.component"; + +type Props = { + className?: string; + tabs: BsContentTabItemProps[]; + tabIndex: number; + onTabChange: (index: number, tab: BsContentTabItemProps) => void; + children: JSX.Element; +} + +export function BsContentTabPanel({className, tabIndex, tabs, onTabChange, children}: Props) { + + const sliderColor = useThemeColor("second-color"); + + return ( +
      + + +
      + {children} +
      +
      + ) +} diff --git a/src/renderer/components/shared/laser-slider.component.tsx b/src/renderer/components/shared/laser-slider.component.tsx new file mode 100644 index 00000000..fd5812af --- /dev/null +++ b/src/renderer/components/shared/laser-slider.component.tsx @@ -0,0 +1,35 @@ +import { CSSProperties } from "react"; + +type Props = { + mode: "horizontal" | "vertical"; + color: string; + className?: string; + nbSteps: number; + step: number; +} + +export function LaserSlider({mode, color, className, nbSteps, step}: Props) { + + const sliderStyle = ((): CSSProperties => { + if(mode === "vertical"){ + return { + transform: `translate(0, ${step * 100}%)`, + height: `calc(100% / ${nbSteps})`, + width: "100%" + } + } + + return { + transform: `translate(${step * 100}%, 0)`, + width: `calc(100% / ${nbSteps})`, + height: "100%" + } + })(); + + return ( +
      + + +
      + ) +} diff --git a/src/renderer/components/shared/tab-nav-bar.component.tsx b/src/renderer/components/shared/tab-nav-bar.component.tsx index 0484ec58..960ab97e 100644 --- a/src/renderer/components/shared/tab-nav-bar.component.tsx +++ b/src/renderer/components/shared/tab-nav-bar.component.tsx @@ -1,6 +1,7 @@ import { DetailedHTMLProps, Fragment } from "react"; import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; import { useTranslation } from "renderer/hooks/use-translation.hook"; +import { LaserSlider } from "./laser-slider.component"; type Props = { tabIndex: number; @@ -22,10 +23,7 @@ export function TabNavBar(props: Props) { return (