Skip to content

Commit

Permalink
feat: select with mouse while checkbox closed (#157)
Browse files Browse the repository at this point in the history
* feat: select with mouse while checkbox closed

* feat: context menu for multiselect

* fix: conflict of holding modifier key
  • Loading branch information
liuycy authored Mar 9, 2024
1 parent b00789d commit 0946e6a
Show file tree
Hide file tree
Showing 13 changed files with 377 additions and 156 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@solid-primitives/keyboard": "^1.2.5",
"@solid-primitives/storage": "^1.3.1",
"@stitches/core": "^1.2.8",
"@viselect/vanilla": "^3.5.0",
"aplayer": "^1.10.1",
"artplayer": "^5.0.9",
"artplayer-plugin-danmuku": "^5.0.1",
Expand Down
159 changes: 83 additions & 76 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/app/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,20 @@ export const globalStyles = globalCss({
flexWrap: "wrap",
rowGap: "0 !important",
},
".viselect-selection-area": {
background: "rgba(46, 115, 252, 0.11)",
border: "2px solid rgba(98, 155, 255, 0.81)",
borderRadius: "0.1em",
},
".viselect-container": {
userSelect: "none",
"& .viselect-item": {
"-webkit-user-drag": "none",
"& img": {
"-webkit-user-drag": "none",
},
},
},
})

export { theme }
5 changes: 5 additions & 0 deletions src/lang/en/home.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"direct": "Direct",
"with_ctrl": "With Ctrl/Command hold",
"with_alt": "With Alt/Option hold"
},
"select_with_mouse": "Select item with mouse while checkbox closed",
"select_with_mouse_options": {
"disabled": "Disabled",
"open_item_with_dblclick": "Open item with double click"
}
},
"package_download": {
Expand Down
6 changes: 6 additions & 0 deletions src/pages/home/folder/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ import { For } from "solid-js"
import { GridItem } from "./GridItem"
import "lightgallery/css/lightgallery-bundle.css"
import { local, objStore } from "~/store"
import { useSelectWithMouse } from "./helper"

const GridLayout = () => {
const { isMouseSupported, registerSelectContainer, captureContentMenu } =
useSelectWithMouse()
registerSelectContainer()
return (
<Grid
oncapture:contextmenu={captureContentMenu}
classList={{ "viselect-container": isMouseSupported() }}
w="$full"
gap="$1"
templateColumns={`repeat(auto-fill, minmax(${
Expand Down
31 changes: 27 additions & 4 deletions src/pages/home/folder/GridItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { ObjType, StoreObj } from "~/types"
import { bus, hoverColor } from "~/utils"
import { getIconByObj } from "~/utils/icon"
import { useOpenItemWithCheckbox } from "./helper"
import { useOpenItemWithCheckbox, useSelectWithMouse } from "./helper"

export const GridItem = (props: { obj: StoreObj; index: number }) => {
const { isHide } = useUtil()
Expand All @@ -35,6 +35,7 @@ export const GridItem = (props: { obj: StoreObj; index: number }) => {
)
const { show } = useContextMenu({ id: 1 })
const { pushHref, to } = useRouter()
const { isMouseSupported } = useSelectWithMouse()
const isShouldOpenItem = useOpenItemWithCheckbox()
return (
<Motion.div
Expand All @@ -46,7 +47,9 @@ export const GridItem = (props: { obj: StoreObj; index: number }) => {
}}
>
<VStack
class="grid-item"
classList={{ selected: !!props.obj.selected }}
class="grid-item viselect-item"
data-index={props.index}
w="$full"
p="$1"
spacing="$1"
Expand All @@ -58,8 +61,19 @@ export const GridItem = (props: { obj: StoreObj; index: number }) => {
}}
as={LinkWithPush}
href={props.obj.name}
cursor={!checkboxOpen() || isShouldOpenItem() ? "pointer" : "default"}
cursor={
!isMouseSupported() && (!checkboxOpen() || isShouldOpenItem())
? "pointer"
: "default"
}
bgColor={props.obj.selected ? hoverColor() : undefined}
on:dblclick={(e: MouseEvent) => {
if (!isMouseSupported()) return
if (e.ctrlKey || e.metaKey || e.shiftKey) return
to(pushHref(props.obj.name))
}}
on:click={(e: MouseEvent) => {
if (isMouseSupported()) return e.preventDefault()
if (!checkboxOpen()) return
e.preventDefault()
if (isShouldOpenItem()) {
Expand Down Expand Up @@ -90,8 +104,17 @@ export const GridItem = (props: { obj: StoreObj; index: number }) => {
class="item-thumbnail"
h={`${parseInt(local["grid_item_size"])}px`}
w="$full"
on:dblclick={(e: MouseEvent) => {
if (!isMouseSupported()) return
if (props.obj.type === ObjType.IMAGE) {
e.stopPropagation()
e.preventDefault()
bus.emit("gallery", props.obj.name)
}
}}
on:click={(e: MouseEvent) => {
if (checkboxOpen()) return
if (isMouseSupported()) return
if (checkboxOpen() && !isShouldOpenItem()) return
if (props.obj.type === ObjType.IMAGE) {
e.stopPropagation()
e.preventDefault()
Expand Down
21 changes: 17 additions & 4 deletions src/pages/home/folder/ImageItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { checkboxOpen, getMainColor, selectAll, selectIndex } from "~/store"
import { ObjType, StoreObj } from "~/types"
import { bus } from "~/utils"
import { getIconByObj } from "~/utils/icon"
import { useOpenItemWithCheckbox } from "./helper"
import { useOpenItemWithCheckbox, useSelectWithMouse } from "./helper"

export const ImageItem = (props: { obj: StoreObj; index: number }) => {
const { isHide } = useUtil()
Expand All @@ -25,6 +25,7 @@ export const ImageItem = (props: { obj: StoreObj; index: number }) => {
)
const { show } = useContextMenu({ id: 1 })
const { rawLink } = useLink()
const { isMouseSupported } = useSelectWithMouse()
const isShouldOpenItem = useOpenItemWithCheckbox()
return (
<Motion.div
Expand All @@ -37,7 +38,9 @@ export const ImageItem = (props: { obj: StoreObj; index: number }) => {
>
<VStack
w="$full"
class="image-item"
classList={{ selected: !!props.obj.selected }}
class="image-item viselect-item"
data-index={props.index}
p="$1"
spacing="$1"
rounded="$lg"
Expand All @@ -62,7 +65,9 @@ export const ImageItem = (props: { obj: StoreObj; index: number }) => {
}}
>
<Center w="$full" pos="relative">
<Show when={showCheckbox()}>
<Show
when={showCheckbox() || (isMouseSupported() && props.obj.selected)}
>
<Checkbox
pos="absolute"
left="$1"
Expand All @@ -84,9 +89,17 @@ export const ImageItem = (props: { obj: StoreObj; index: number }) => {
src={rawLink(props.obj)}
loading="lazy"
cursor={
!checkboxOpen() || isShouldOpenItem() ? "pointer" : "default"
!isMouseSupported() && (!checkboxOpen() || isShouldOpenItem())
? "pointer"
: "default"
}
on:dblclick={(e: MouseEvent) => {
if (!isMouseSupported()) return
if (e.ctrlKey || e.metaKey || e.shiftKey) return
bus.emit("gallery", props.obj.name)
}}
on:click={() => {
if (isMouseSupported()) return
if (!checkboxOpen() || isShouldOpenItem()) {
bus.emit("gallery", props.obj.name)
return
Expand Down
11 changes: 10 additions & 1 deletion src/pages/home/folder/Images.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { local, objStore } from "~/store"
import { GridItem } from "./GridItem"
import { StoreObj } from "~/types"
import { useT } from "~/hooks"
import { useSelectWithMouse } from "./helper"

const ImageLayout = (props: { images: StoreObj[] }) => {
const t = useT()
Expand All @@ -22,8 +23,16 @@ const ImageLayout = (props: { images: StoreObj[] }) => {
</For>
</Grid>
))
const { isMouseSupported, registerSelectContainer, captureContentMenu } =
useSelectWithMouse()
registerSelectContainer()
return (
<VStack spacing="$2" w="$full">
<VStack
oncapture:contextmenu={captureContentMenu}
classList={{ "viselect-container": isMouseSupported() }}
spacing="$2"
w="$full"
>
<Show when={local["show_folder_in_image_view"] === "top"}>
{folders()}
</Show>
Expand Down
12 changes: 11 additions & 1 deletion src/pages/home/folder/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "~/store"
import { OrderBy } from "~/store"
import { Col, cols, ListItem } from "./ListItem"
import { useSelectWithMouse } from "./helper"

const ListLayout = () => {
const t = useT()
Expand Down Expand Up @@ -40,8 +41,17 @@ const ListLayout = () => {
},
}
}
const { isMouseSupported, registerSelectContainer, captureContentMenu } =
useSelectWithMouse()
registerSelectContainer()
return (
<VStack class="list" w="$full" spacing="$1">
<VStack
oncapture:contextmenu={captureContentMenu}
classList={{ "viselect-container": isMouseSupported() }}
class="list"
w="$full"
spacing="$1"
>
<HStack class="title" w="$full" p="$2">
<HStack w={cols[0].w} spacing="$1">
<Show when={checkboxOpen()}>
Expand Down
20 changes: 17 additions & 3 deletions src/pages/home/folder/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { ObjType, StoreObj } from "~/types"
import { bus, formatDate, getFileSize, hoverColor } from "~/utils"
import { getIconByObj } from "~/utils/icon"
import { useOpenItemWithCheckbox } from "./helper"
import { useOpenItemWithCheckbox, useSelectWithMouse } from "./helper"

export interface Col {
name: OrderBy
Expand All @@ -37,6 +37,7 @@ export const ListItem = (props: { obj: StoreObj; index: number }) => {
const { setPathAs } = usePath()
const { show } = useContextMenu({ id: 1 })
const { pushHref, to } = useRouter()
const { isMouseSupported } = useSelectWithMouse()
const isShouldOpenItem = useOpenItemWithCheckbox()
const filenameStyle = () => local["list_item_filename_overflow"]
return (
Expand All @@ -49,7 +50,9 @@ export const ListItem = (props: { obj: StoreObj; index: number }) => {
}}
>
<HStack
class="list-item"
classList={{ selected: !!props.obj.selected }}
class="list-item viselect-item"
data-index={props.index}
w="$full"
p="$2"
rounded="$lg"
Expand All @@ -60,8 +63,19 @@ export const ListItem = (props: { obj: StoreObj; index: number }) => {
}}
as={LinkWithPush}
href={props.obj.name}
cursor={!checkboxOpen() || isShouldOpenItem() ? "pointer" : "default"}
cursor={
!isMouseSupported() && (!checkboxOpen() || isShouldOpenItem())
? "pointer"
: "default"
}
bgColor={props.obj.selected ? hoverColor() : undefined}
on:dblclick={(e: MouseEvent) => {
if (!isMouseSupported()) return
if (e.ctrlKey || e.metaKey || e.shiftKey) return
to(pushHref(props.obj.name))
}}
on:click={(e: MouseEvent) => {
if (isMouseSupported()) return e.preventDefault()
if (!checkboxOpen()) return
e.preventDefault()
if (isShouldOpenItem()) {
Expand Down
Loading

0 comments on commit 0946e6a

Please sign in to comment.