From 0946e6aec5837ebac5acd0fd7699fd8d899a3a08 Mon Sep 17 00:00:00 2001 From: liuycy Date: Sat, 9 Mar 2024 14:53:32 +0800 Subject: [PATCH] feat: select with mouse while checkbox closed (#157) * feat: select with mouse while checkbox closed * feat: context menu for multiselect * fix: conflict of holding modifier key --- package.json | 1 + pnpm-lock.yaml | 159 +++++++++++++------------ src/app/theme.ts | 14 +++ src/lang/en/home.json | 5 + src/pages/home/folder/Grid.tsx | 6 + src/pages/home/folder/GridItem.tsx | 31 ++++- src/pages/home/folder/ImageItem.tsx | 21 +++- src/pages/home/folder/Images.tsx | 11 +- src/pages/home/folder/List.tsx | 12 +- src/pages/home/folder/ListItem.tsx | 20 +++- src/pages/home/folder/context-menu.tsx | 157 ++++++++++++++---------- src/pages/home/folder/helper.ts | 89 +++++++++++++- src/store/local_settings.ts | 7 ++ 13 files changed, 377 insertions(+), 156 deletions(-) diff --git a/package.json b/package.json index 5cd3c6106..281fd7044 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce5d8cec8..59e710ed7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ dependencies: '@stitches/core': specifier: ^1.2.8 version: 1.2.8 + '@viselect/vanilla': + specifier: ^3.5.0 + version: 3.5.0 aplayer: specifier: ^1.10.1 version: 1.10.1 @@ -843,6 +846,10 @@ packages: resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} dev: false + /@viselect/vanilla@3.5.0: + resolution: {integrity: sha512-drPkEQ/0CZl/c7D0gx5lWkY6iCdbyJm6KWFJpY2oQEKEnCrW9LUdQOsbNP/RG2L8BNUaiDBmwyTTW2RYIroZhA==} + dev: false + /@vitejs/plugin-legacy@2.0.1(terser@5.14.2)(vite@3.0.8): resolution: {integrity: sha512-kKC56rfsXwebApzyuZqdQlGmqTyH1ugy0l0rY58gx5OXzq4/t5/DCqGUoz53Db51OqfjRqsHfqmvq9or6w9k/Q==} engines: {node: ^14.18.0 || >=16.0.0} @@ -866,7 +873,7 @@ packages: dev: true /aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==, tarball: https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz} + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} dependencies: clean-stack: 2.2.0 @@ -874,38 +881,38 @@ packages: dev: true /ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, tarball: https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz} + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} dependencies: type-fest: 0.21.3 dev: true /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, tarball: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz} + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: true /ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==, tarball: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz} + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} dev: true /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz} + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} dependencies: color-convert: 1.9.3 dev: true /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz} + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 dev: true /ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz} + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} dev: true @@ -940,7 +947,7 @@ packages: dev: false /astral-regex@2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==, tarball: https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz} + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} dev: true @@ -1003,7 +1010,7 @@ packages: dev: true /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==, tarball: https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz} + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} dependencies: fill-range: 7.0.1 @@ -1054,19 +1061,19 @@ packages: dev: true /clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==, tarball: https://registry.npmmirror.com/clean-stack/-/clean-stack-2.2.0.tgz} + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} dev: true /cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==, tarball: https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz} + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} dependencies: restore-cursor: 3.1.0 dev: true /cli-truncate@2.1.0: - resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==, tarball: https://registry.npmmirror.com/cli-truncate/-/cli-truncate-2.1.0.tgz} + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} engines: {node: '>=8'} dependencies: slice-ansi: 3.0.0 @@ -1074,7 +1081,7 @@ packages: dev: true /cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==, tarball: https://registry.npmmirror.com/cli-truncate/-/cli-truncate-3.1.0.tgz} + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: slice-ansi: 5.0.0 @@ -1092,24 +1099,24 @@ packages: dev: false /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz} + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 dev: true /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz} + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 dev: true /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz} + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} dev: true /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz} + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true /colorette@1.4.0: @@ -1117,7 +1124,7 @@ packages: dev: true /colorette@2.0.19: - resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==, tarball: https://registry.npmmirror.com/colorette/-/colorette-2.0.19.tgz} + resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} dev: true /combined-stream@1.0.8: @@ -1146,7 +1153,7 @@ packages: dev: false /commander@9.4.1: - resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==, tarball: https://registry.npmmirror.com/commander/-/commander-9.4.1.tgz} + resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} engines: {node: ^12.20.0 || >=14} dev: true @@ -1180,7 +1187,7 @@ packages: dev: true /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, tarball: https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz} + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} dependencies: path-key: 3.1.1 @@ -1212,7 +1219,7 @@ packages: dev: false /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, tarball: https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz} + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1278,7 +1285,7 @@ packages: dev: true /eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, tarball: https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz} + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true /electron-to-chromium@1.4.221: @@ -1286,11 +1293,11 @@ packages: dev: true /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, tarball: https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz} + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true /emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, tarball: https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz} + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true /entities@2.2.0: @@ -1531,7 +1538,7 @@ packages: dev: false /execa@6.1.0: - resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==, tarball: https://registry.npmmirror.com/execa/-/execa-6.1.0.tgz} + resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: cross-spawn: 7.0.3 @@ -1573,7 +1580,7 @@ packages: dev: true /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==, tarball: https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz} + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 @@ -1648,7 +1655,7 @@ packages: dev: true /get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, tarball: https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz} + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} dev: true @@ -1837,12 +1844,12 @@ packages: dev: false /human-signals@3.0.1: - resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==, tarball: https://registry.npmmirror.com/human-signals/-/human-signals-3.0.1.tgz} + resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==} engines: {node: '>=12.20.0'} dev: true /husky@8.0.2: - resolution: {integrity: sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==, tarball: https://registry.npmmirror.com/husky/-/husky-8.0.2.tgz} + resolution: {integrity: sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==} engines: {node: '>=14'} hasBin: true dev: true @@ -1853,7 +1860,7 @@ packages: dev: true /indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==, tarball: https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz} + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} dev: true @@ -1894,12 +1901,12 @@ packages: dev: true /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, tarball: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz} + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} dev: true /is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==, tarball: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz} + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} dev: true @@ -1911,7 +1918,7 @@ packages: dev: true /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, tarball: https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz} + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: true @@ -1926,7 +1933,7 @@ packages: dev: true /is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==, tarball: https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz} + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true @@ -1936,7 +1943,7 @@ packages: dev: true /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, tarball: https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz} + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true /js-tokens@4.0.0: @@ -1992,12 +1999,12 @@ packages: dev: false /lilconfig@2.0.6: - resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==, tarball: https://registry.npmmirror.com/lilconfig/-/lilconfig-2.0.6.tgz} + resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} engines: {node: '>=10'} dev: true /lint-staged@13.0.4: - resolution: {integrity: sha512-HxlHCXoYRsq9QCby5wFozmZW00hMs/9e3l+/dz6Qr8Kle4UH0kJTdABAbqhzG+3pcG6QjL9kz7NgGBfph+a5dw==, tarball: https://registry.npmmirror.com/lint-staged/-/lint-staged-13.0.4.tgz} + resolution: {integrity: sha512-HxlHCXoYRsq9QCby5wFozmZW00hMs/9e3l+/dz6Qr8Kle4UH0kJTdABAbqhzG+3pcG6QjL9kz7NgGBfph+a5dw==} engines: {node: ^14.13.1 || >=16.0.0} hasBin: true dependencies: @@ -2020,7 +2027,7 @@ packages: dev: true /listr2@5.0.6: - resolution: {integrity: sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==, tarball: https://registry.npmmirror.com/listr2/-/listr2-5.0.6.tgz} + resolution: {integrity: sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==} engines: {node: ^14.13.1 || >=16.0.0} peerDependencies: enquirer: '>= 2.3.0 < 3' @@ -2043,7 +2050,7 @@ packages: dev: false /log-update@4.0.0: - resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==, tarball: https://registry.npmmirror.com/log-update/-/log-update-4.0.0.tgz} + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} engines: {node: '>=10'} dependencies: ansi-escapes: 4.3.2 @@ -2214,7 +2221,7 @@ packages: dev: true /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, tarball: https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz} + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true /merge2@1.4.1: @@ -2484,7 +2491,7 @@ packages: dev: false /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==, tarball: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz} + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} dependencies: braces: 3.0.2 @@ -2504,12 +2511,12 @@ packages: dev: false /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, tarball: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz} + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} dev: true /mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==, tarball: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz} + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} dev: true @@ -2557,7 +2564,7 @@ packages: dev: false /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz} + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} /nanoid@3.3.4: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} @@ -2601,12 +2608,12 @@ packages: dev: true /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, tarball: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz} + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} dev: true /npm-run-path@5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==, tarball: https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.1.0.tgz} + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: path-key: 4.0.0 @@ -2619,7 +2626,7 @@ packages: dev: true /object-inspect@1.12.2: - resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==, tarball: https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz} + resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} dev: true /once@1.4.0: @@ -2629,14 +2636,14 @@ packages: dev: true /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, tarball: https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz} + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} dependencies: mimic-fn: 2.1.0 dev: true /onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==, tarball: https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz} + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} dependencies: mimic-fn: 4.0.0 @@ -2649,7 +2656,7 @@ packages: dev: false /p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==, tarball: https://registry.npmmirror.com/p-map/-/p-map-4.0.0.tgz} + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} dependencies: aggregate-error: 3.1.0 @@ -2671,12 +2678,12 @@ packages: dev: true /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, tarball: https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz} + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} dev: true /path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, tarball: https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz} + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} dev: true @@ -2698,12 +2705,12 @@ packages: dev: true /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, tarball: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz} + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} dev: true /pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==, tarball: https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz} + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} hasBin: true dev: true @@ -2822,7 +2829,7 @@ packages: dev: true /restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==, tarball: https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz} + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} dependencies: onetime: 5.1.2 @@ -2835,7 +2842,7 @@ packages: dev: true /rfdc@1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==, tarball: https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz} + resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} dev: true /rollup-plugin-copy@3.5.0: @@ -2864,7 +2871,7 @@ packages: dev: true /rxjs@7.5.7: - resolution: {integrity: sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==, tarball: https://registry.npmmirror.com/rxjs/-/rxjs-7.5.7.tgz} + resolution: {integrity: sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==} dependencies: tslib: 2.4.0 dev: true @@ -2905,14 +2912,14 @@ packages: dev: false /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, tarball: https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz} + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 dev: true /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, tarball: https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz} + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} dev: true @@ -2927,7 +2934,7 @@ packages: dev: true /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, tarball: https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz} + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true /slash@3.0.0: @@ -2936,7 +2943,7 @@ packages: dev: true /slice-ansi@3.0.0: - resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==, tarball: https://registry.npmmirror.com/slice-ansi/-/slice-ansi-3.0.0.tgz} + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} engines: {node: '>=8'} dependencies: ansi-styles: 4.3.0 @@ -2945,7 +2952,7 @@ packages: dev: true /slice-ansi@4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==, tarball: https://registry.npmmirror.com/slice-ansi/-/slice-ansi-4.0.0.tgz} + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} dependencies: ansi-styles: 4.3.0 @@ -2954,7 +2961,7 @@ packages: dev: true /slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==, tarball: https://registry.npmmirror.com/slice-ansi/-/slice-ansi-5.0.0.tgz} + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} dependencies: ansi-styles: 6.2.1 @@ -3062,12 +3069,12 @@ packages: dev: false /string-argv@0.3.1: - resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==, tarball: https://registry.npmmirror.com/string-argv/-/string-argv-0.3.1.tgz} + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} engines: {node: '>=0.6.19'} dev: true /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, tarball: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz} + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} dependencies: emoji-regex: 8.0.0 @@ -3076,7 +3083,7 @@ packages: dev: true /string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, tarball: https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz} + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} dependencies: eastasianwidth: 0.2.0 @@ -3085,21 +3092,21 @@ packages: dev: true /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, tarball: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz} + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 dev: true /strip-ansi@7.0.1: - resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==, tarball: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.0.1.tgz} + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} engines: {node: '>=12'} dependencies: ansi-regex: 6.0.1 dev: true /strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==, tarball: https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz} + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} dev: true @@ -3154,7 +3161,7 @@ packages: dev: true /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==, tarball: https://registry.npmmirror.com/through/-/through-2.3.8.tgz} + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true /to-fast-properties@2.0.0: @@ -3163,7 +3170,7 @@ packages: dev: true /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, tarball: https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz} + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 @@ -3193,7 +3200,7 @@ packages: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, tarball: https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz} + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} dev: true @@ -3395,7 +3402,7 @@ packages: dev: true /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, tarball: https://registry.npmmirror.com/which/-/which-2.0.2.tgz} + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true dependencies: @@ -3403,7 +3410,7 @@ packages: dev: true /wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==, tarball: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz} + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} dependencies: ansi-styles: 4.3.0 @@ -3412,7 +3419,7 @@ packages: dev: true /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, tarball: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz} + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} dependencies: ansi-styles: 4.3.0 @@ -3429,7 +3436,7 @@ packages: dev: true /yaml@2.1.3: - resolution: {integrity: sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==, tarball: https://registry.npmmirror.com/yaml/-/yaml-2.1.3.tgz} + resolution: {integrity: sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==} engines: {node: '>= 14'} dev: true diff --git a/src/app/theme.ts b/src/app/theme.ts index 32c7b8c80..6c775ff90 100644 --- a/src/app/theme.ts +++ b/src/app/theme.ts @@ -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 } diff --git a/src/lang/en/home.json b/src/lang/en/home.json index 31b3b242a..a29a3fe3a 100644 --- a/src/lang/en/home.json +++ b/src/lang/en/home.json @@ -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": { diff --git a/src/pages/home/folder/Grid.tsx b/src/pages/home/folder/Grid.tsx index e7a6d027e..288f744b0 100644 --- a/src/pages/home/folder/Grid.tsx +++ b/src/pages/home/folder/Grid.tsx @@ -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 ( { const { isHide } = useUtil() @@ -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 ( { }} > { }} 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()) { @@ -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() diff --git a/src/pages/home/folder/ImageItem.tsx b/src/pages/home/folder/ImageItem.tsx index 93ed83a59..43e165393 100644 --- a/src/pages/home/folder/ImageItem.tsx +++ b/src/pages/home/folder/ImageItem.tsx @@ -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() @@ -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 ( { > { }} >
- + { 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 diff --git a/src/pages/home/folder/Images.tsx b/src/pages/home/folder/Images.tsx index ad4a7d3d6..6a3f1a3ed 100644 --- a/src/pages/home/folder/Images.tsx +++ b/src/pages/home/folder/Images.tsx @@ -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() @@ -22,8 +23,16 @@ const ImageLayout = (props: { images: StoreObj[] }) => { )) + const { isMouseSupported, registerSelectContainer, captureContentMenu } = + useSelectWithMouse() + registerSelectContainer() return ( - + {folders()} diff --git a/src/pages/home/folder/List.tsx b/src/pages/home/folder/List.tsx index 3d05e7c23..188429e7c 100644 --- a/src/pages/home/folder/List.tsx +++ b/src/pages/home/folder/List.tsx @@ -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() @@ -40,8 +41,17 @@ const ListLayout = () => { }, } } + const { isMouseSupported, registerSelectContainer, captureContentMenu } = + useSelectWithMouse() + registerSelectContainer() return ( - + diff --git a/src/pages/home/folder/ListItem.tsx b/src/pages/home/folder/ListItem.tsx index b8a5013ea..e7279033c 100644 --- a/src/pages/home/folder/ListItem.tsx +++ b/src/pages/home/folder/ListItem.tsx @@ -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 @@ -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 ( @@ -49,7 +50,9 @@ 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()) { diff --git a/src/pages/home/folder/context-menu.tsx b/src/pages/home/folder/context-menu.tsx index 734941df4..24852a5be 100644 --- a/src/pages/home/folder/context-menu.tsx +++ b/src/pages/home/folder/context-menu.tsx @@ -3,10 +3,10 @@ import { useCopyLink, useDownload, useLink, useT } from "~/hooks" import "solid-contextmenu/dist/style.css" import { HStack, Icon, Text, useColorMode, Image } from "@hope-ui/solid" import { operations } from "../toolbar/operations" -import { For } from "solid-js" +import { For, Show } from "solid-js" import { bus, convertURL, notify } from "~/utils" import { ObjType, UserMethods, UserPermissions } from "~/types" -import { getSettingBool, me } from "~/store" +import { getSettingBool, haveSelected, me, oneChecked } from "~/store" import { players } from "../previews/video_box" import { BsPlayCircleFill } from "solid-icons/bs" @@ -29,7 +29,7 @@ export const ContextMenu = () => { const t = useT() const { colorMode } = useColorMode() const { copySelectedRawLink, copySelectedPreviewPage } = useCopyLink() - const { batchDownloadSelected } = useDownload() + const { batchDownloadSelected, sendToAria2 } = useDownload() const canPackageDownload = () => { return UserMethods.is_admin(me()) || getSettingBool("package_download") } @@ -55,67 +55,102 @@ export const ContextMenu = () => { )} - { - if (props.is_dir) { - copySelectedPreviewPage() - } else { - copySelectedRawLink(true) - } - }} - > - - - { - if (props.is_dir) { - if (!canPackageDownload()) { - notify.warning(t("home.toolbar.package_download_disabled")) - return + + { + if (props.is_dir) { + copySelectedPreviewPage() + } else { + copySelectedRawLink(true) + } + }} + > + + + { + if (props.is_dir) { + if (!canPackageDownload()) { + notify.warning(t("home.toolbar.package_download_disabled")) + return + } + bus.emit("tool", "package_download") + } else { + batchDownloadSelected() } - bus.emit("tool", "package_download") - } else { - batchDownloadSelected() + }} + > + + + - + + + }> + + {t("home.toolbar.preview_page")} + + copySelectedRawLink()}> + {t("home.toolbar.down_link")} + + copySelectedRawLink(true)}> + {t("home.toolbar.encode_down_link")} + + + }> + + {t("home.toolbar.batch_download")} + + + bus.emit("tool", "package_download")}> + {t("home.toolbar.package_download")} - )} - - + + {t("home.toolbar.send_aria2")} + + ) } diff --git a/src/pages/home/folder/helper.ts b/src/pages/home/folder/helper.ts index 5178014b9..16bbfc1da 100644 --- a/src/pages/home/folder/helper.ts +++ b/src/pages/home/folder/helper.ts @@ -1,15 +1,28 @@ import { createKeyHold } from "@solid-primitives/keyboard" -import { createEffect, createSignal } from "solid-js" -import { isMac } from "~/utils/compatibility" -import { local } from "~/store" +import { createEffect, createSignal, on, onCleanup } from "solid-js" +import SelectionArea from "@viselect/vanilla" +import { + checkboxOpen, + haveSelected, + local, + objStore, + oneChecked, + selectAll, + selectIndex, + selectedObjs, +} from "~/store" +import { isMac, isMobile } from "~/utils/compatibility" +import { useContextMenu } from "solid-contextmenu" export function useOpenItemWithCheckbox() { const [shouldOpen, setShouldOpen] = createSignal( local["open_item_on_checkbox"] === "direct", ) - const isAltKeyPressed = createKeyHold("Alt") - const isMetaKeyPressed = createKeyHold("Meta") - const isControlKeyPressed = createKeyHold("Control") + const isAltKeyPressed = createKeyHold("Alt", { preventDefault: false }) + const isMetaKeyPressed = createKeyHold("Meta", { preventDefault: false }) + const isControlKeyPressed = createKeyHold("Control", { + preventDefault: false, + }) createEffect(() => { switch (local["open_item_on_checkbox"]) { case "direct": { @@ -30,3 +43,67 @@ export function useOpenItemWithCheckbox() { }) return shouldOpen } + +export function useSelectWithMouse() { + const disabled = () => local["select_with_mouse"] === "disabled" + + const isMouseSupported = () => !isMobile && !disabled() && !checkboxOpen() + + const registerSelectContainer = () => { + createEffect(() => { + if (!isMouseSupported()) return + const selection = new SelectionArea({ + selectionAreaClass: "viselect-selection-area", + startAreas: [".viselect-container"], + boundaries: [".viselect-container"], + selectables: [".viselect-item"], + }) + selection.on("start", ({ event }) => { + const ev = event as MouseEvent + selection.clearSelection(true, true) + selection.select(".viselect-item.selected", true) + if (!ev.ctrlKey && !ev.metaKey) { + selectAll(false) + selection.clearSelection() + } + }) + selection.on( + "move", + ({ + store: { + changed: { added, removed }, + }, + }) => { + for (const el of added) { + selectIndex(Number(el.getAttribute("data-index")), true) + } + for (const el of removed) { + selectIndex(Number(el.getAttribute("data-index")), false) + } + }, + ) + onCleanup(() => selection.destroy()) + }) + } + + const { show } = useContextMenu({ id: 1 }) + + const captureContentMenu = (e: MouseEvent) => { + e.preventDefault() + + if (haveSelected() && !oneChecked()) { + const $target = e.target as Element + const $selectedItem = $target.closest(".viselect-item") + const index = Number($selectedItem?.getAttribute("data-index")) + + const isClickOnContainer = Number.isNaN(index) + const isClickOnSelectedItems = () => !!objStore.objs[index].selected + if (isClickOnContainer || !isClickOnSelectedItems()) return + + e.stopPropagation() + show(e, { props: objStore.obj }) + } + } + + return { isMouseSupported, registerSelectContainer, captureContentMenu } +} diff --git a/src/store/local_settings.ts b/src/store/local_settings.ts index 8c75fbdf5..af0974a59 100644 --- a/src/store/local_settings.ts +++ b/src/store/local_settings.ts @@ -1,4 +1,5 @@ import { createLocalStorage } from "@solid-primitives/storage" +import { isMobile } from "~/utils/compatibility" const [local, setLocal, { remove, clear, toJSON }] = createLocalStorage() // export function isValidKey( @@ -58,6 +59,12 @@ export const initialLocalSettings = [ type: "select", options: ["direct", "with_alt", "with_ctrl"], }, + { + key: "select_with_mouse", + default: "disabled", + type: "select", + options: ["disabled", "open_item_with_dblclick"], + }, ] export type LocalSetting = (typeof initialLocalSettings)[number] for (const setting of initialLocalSettings) {