diff --git a/package-lock.json b/package-lock.json index f1481677..b7d0133d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1861,6 +1861,15 @@ "@types/jest": "*" } }, + "@types/use-double-click": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/use-double-click/-/use-double-click-1.0.1.tgz", + "integrity": "sha512-mkoH+XW24GIPZO/0FO7ms6SiLxwvPPl8KxYxemoigSkPS9cQxI6CH6lw5gwQ5bLeProgzMGlULUANOnUCJ8GJg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -12554,6 +12563,11 @@ "prepend-http": "^2.0.0" } }, + "use-double-click": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/use-double-click/-/use-double-click-1.0.5.tgz", + "integrity": "sha512-71LUca6NtzpzHYlcfM/dOdmwvmvpMbzeIVQpN87w+DctpLiMCXtZpsN8FNWPgHpPBtNhvucPUHIDh5al8D8C7w==" + }, "utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", diff --git a/package.json b/package.json index e20a2812..e98258bf 100644 --- a/package.json +++ b/package.json @@ -157,6 +157,7 @@ "@types/react-outside-click-handler": "^1.3.1", "@types/react-test-renderer": "^17.0.2", "@types/terser-webpack-plugin": "^5.0.4", + "@types/use-double-click": "^1.0.1", "@types/uuid": "^8.3.4", "@types/webpack-bundle-analyzer": "^4.4.2", "@types/webpack-env": "^1.18.0", @@ -245,6 +246,7 @@ "rxjs": "^7.5.6", "semver": "^7.3.8", "tailwind-scrollbar-hide": "^1.1.7", + "use-double-click": "^1.0.5", "uuid": "^9.0.0" }, "devEngines": { diff --git a/src/renderer/components/shared/bsm-checkbox.component.tsx b/src/renderer/components/shared/bsm-checkbox.component.tsx index 1755cc3a..5fb00b79 100644 --- a/src/renderer/components/shared/bsm-checkbox.component.tsx +++ b/src/renderer/components/shared/bsm-checkbox.component.tsx @@ -15,10 +15,10 @@ export function BsmCheckbox({className, checked, onChange, disabled} : Props) { } return ( -
{e.stopPropagation(); handleClick()}}> +
{!disabled && } - + {e.stopPropagation(); handleClick()}}>
diff --git a/src/renderer/components/version-viewer/slides/mods/mod-item.component.tsx b/src/renderer/components/version-viewer/slides/mods/mod-item.component.tsx index b5c936a2..453e0d24 100644 --- a/src/renderer/components/version-viewer/slides/mods/mod-item.component.tsx +++ b/src/renderer/components/version-viewer/slides/mods/mod-item.component.tsx @@ -1,21 +1,30 @@ import { BsmButton } from "renderer/components/shared/bsm-button.component"; import { BsmCheckbox } from "renderer/components/shared/bsm-checkbox.component"; import { Mod } from "shared/models/mods/mod.interface"; -import { CSSProperties } from "react" +import { CSSProperties, useRef, useState } from "react" import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; import { BsModsManagerService } from "renderer/services/bs-mods-manager.service"; import { useObservable } from "renderer/hooks/use-observable.hook"; import { PageStateService } from "renderer/services/page-state.service"; +import useDoubleClick from 'use-double-click'; -type Props = {mod: Mod, installedVersion: string, isDependency?: boolean, isSelected?: boolean, onChange?: (val: boolean) => void, wantInfo?: boolean} +type Props = {mod: Mod, installedVersion: string, isDependency?: boolean, isSelected?: boolean, onChange?: (val: boolean) => void, wantInfo?: boolean, onWantInfo?: (mod: Mod) => void} -export function ModItem({mod, installedVersion, isDependency, isSelected, onChange, wantInfo}: Props) { +export function ModItem({mod, installedVersion, isDependency, isSelected, onChange, wantInfo, onWantInfo}: Props) { const modsManager = BsModsManagerService.getInstance(); const pageState = PageStateService.getInstance(); const themeColor = useThemeColor("second-color"); const uninstalling = useObservable(modsManager.isUninstalling$); + const clickRef = useRef(); + + useDoubleClick({ + onSingleClick: e => handleWantInfo(e), + onDoubleClick: e => handleOnChange(e), + ref: clickRef, + latency: 200 + }) const wantInfoStyle: CSSProperties = wantInfo ? {borderColor: themeColor} : {borderColor: "transparent"}; const isOutDated = installedVersion < mod.version; @@ -24,10 +33,15 @@ export function ModItem({mod, installedVersion, isDependency, isSelected, onChan modsManager.uninstallMod(mod, pageState.getState()); } + const handleWantInfo = (e: React.MouseEvent) => { e.preventDefault(); onWantInfo(mod); } + const handleOnChange = (e: React.MouseEvent) => { e.preventDefault(); onChange(!isChecked); } + + const isChecked = isDependency || isSelected || mod.required; + return ( -
+
- +
{mod.name} {installedVersion || "-"} diff --git a/src/renderer/components/version-viewer/slides/mods/mods-grid.component.tsx b/src/renderer/components/version-viewer/slides/mods/mods-grid.component.tsx index 0c779ed2..44d4fa57 100644 --- a/src/renderer/components/version-viewer/slides/mods/mods-grid.component.tsx +++ b/src/renderer/components/version-viewer/slides/mods/mods-grid.component.tsx @@ -73,8 +73,8 @@ export function ModsGrid({modsMap, installed, modsSelected, onModChange, moreInf

    {key}

    {modsMap.get(key).map(mod => mod.name.toLowerCase().includes(filter) && ( -
  • onWantInfos(mod)} key={mod.name}> - onModChange(val, mod)} wantInfo={mod.name === moreInfoMod?.name}/> +
  • + onModChange(val, mod)} onWantInfo={onWantInfos} wantInfo={mod.name === moreInfoMod?.name}/>
  • ))}