From e014281f6ca852045de2af0b8addfbfa7b00e198 Mon Sep 17 00:00:00 2001 From: Siirko Date: Sun, 26 Nov 2023 12:16:36 +0100 Subject: [PATCH 1/4] search bar added but lazy load not more effective --- package.json | 4 +- pnpm-lock.yaml | 59 ++++++++---------------- src/components/ui/MusicCard.tsx | 2 +- src/components/ui/command.tsx | 24 +++++++++- src/pages/music.tsx | 81 +++++++++++++++++++++------------ 5 files changed, 98 insertions(+), 72 deletions(-) diff --git a/package.json b/package.json index 3b0e1f7..aba0b49 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dependencies": { "@egjs/react-flicking": "^4.11.0", "@egjs/react-grid": "^1.15.2", + "@faker-js/faker": "^8.3.1", "@hookform/resolvers": "^3.1.1", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", @@ -40,7 +41,6 @@ "@radix-ui/react-tooltip": "^1.0.6", "@tanstack/react-table": "^8.10.7", "@tauri-apps/api": "^1.4.0", - "@types/react-virtualized": "^9.21.28", "@types/react-window": "^1.8.8", "@types/react-window-infinite-loader": "^1.0.9", "byte-base64": "^1.1.0", @@ -56,7 +56,7 @@ "react-dom": "^18.2.0", "react-hook-form": "^7.45.2", "react-toast": "^1.0.3", - "react-virtualized": "^9.22.5", + "react-viewport-list": "^7.1.1", "react-window": "^1.8.9", "react-window-infinite-loader": "^1.0.9", "shadcn-ui": "^0.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e6f4215..aa52898 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ dependencies: '@egjs/react-grid': specifier: ^1.15.2 version: 1.15.2 + '@faker-js/faker': + specifier: ^8.3.1 + version: 8.3.1 '@hookform/resolvers': specifier: ^3.1.1 version: 3.1.1(react-hook-form@7.45.2) @@ -77,9 +80,6 @@ dependencies: '@tauri-apps/api': specifier: ^1.4.0 version: 1.4.0 - '@types/react-virtualized': - specifier: ^9.21.28 - version: 9.21.28 '@types/react-window': specifier: ^1.8.8 version: 1.8.8 @@ -125,9 +125,9 @@ dependencies: react-toast: specifier: ^1.0.3 version: 1.0.3(react@18.2.0) - react-virtualized: - specifier: ^9.22.5 - version: 9.22.5(react-dom@18.2.0)(react@18.2.0) + react-viewport-list: + specifier: ^7.1.1 + version: 7.1.1(react@18.2.0) react-window: specifier: ^1.8.9 version: 1.8.9(react-dom@18.2.0)(react@18.2.0) @@ -733,6 +733,11 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@faker-js/faker@8.3.1: + resolution: {integrity: sha512-FdgpFxY6V6rLZE9mmIBb9hM0xpfvQOSNOLnzolzKwsE1DH+gC7lEKV1p1IbR0lAYyvYd5a4u3qWJzowUkw1bIw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'} + dev: false + /@floating-ui/core@1.3.1: resolution: {integrity: sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==} dev: false @@ -3038,13 +3043,6 @@ packages: dependencies: '@types/react': 18.2.14 - /@types/react-virtualized@9.21.28: - resolution: {integrity: sha512-GE9tPk6vinqh2cqVs5xyqF5g6HdHJMVY1msJRSY12MN8+GrI0f9KUmXbryek6Pyry5fM2wTX1VvZxQj3ZKgTRg==} - dependencies: - '@types/prop-types': 15.7.5 - '@types/react': 18.2.14 - dev: false - /@types/react-window-infinite-loader@1.0.9: resolution: {integrity: sha512-gEInTjQwURCnDOFyIEK2+fWB5gTjqwx30O62QfxA9stE5aiB6EWkGj4UMhc0axq7/FV++Gs/TGW8FtgEx0S6Tw==} dependencies: @@ -4100,13 +4098,6 @@ packages: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} dev: true - /dom-helpers@5.2.1: - resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} - dependencies: - '@babel/runtime': 7.22.6 - csstype: 3.1.2 - dev: false - /dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} dependencies: @@ -6436,6 +6427,7 @@ packages: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 + dev: true /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} @@ -6509,6 +6501,7 @@ packages: /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true /react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -6518,10 +6511,6 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true - /react-lifecycles-compat@3.0.4: - resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} - dev: false - /react-remove-scroll-bar@2.3.4(@types/react@18.2.14)(react@18.2.0): resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} engines: {node: '>=10'} @@ -6601,29 +6590,21 @@ packages: react: 18.2.0 dev: false - /react-virtual@2.10.4(react@18.2.0): - resolution: {integrity: sha512-Ir6+oPQZTVHfa6+JL9M7cvMILstFZH/H3jqeYeKI4MSUX+rIruVwFC6nGVXw9wqAw8L0Kg2KvfXxI85OvYQdpQ==} + /react-viewport-list@7.1.1(react@18.2.0): + resolution: {integrity: sha512-O3gxykg3DgpcyYH+/X2kFwWFaZjckJ0FK3UBb4vFhZe+CsGLcX8OVJb0VSYI+IupEuQ9pl8dvJak8JRkIuvNjw==} peerDependencies: - react: ^16.6.3 || ^17.0.0 + react: '>=17.0.0' dependencies: - '@reach/observe-rect': 1.2.0 react: 18.2.0 dev: false - /react-virtualized@9.22.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-YqQMRzlVANBv1L/7r63OHa2b0ZsAaDp1UhVNEdUaXI8A5u6hTpA5NYtUueLH2rFuY/27mTGIBl7ZhqFKzw18YQ==} + /react-virtual@2.10.4(react@18.2.0): + resolution: {integrity: sha512-Ir6+oPQZTVHfa6+JL9M7cvMILstFZH/H3jqeYeKI4MSUX+rIruVwFC6nGVXw9wqAw8L0Kg2KvfXxI85OvYQdpQ==} peerDependencies: - react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 - react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 + react: ^16.6.3 || ^17.0.0 dependencies: - '@babel/runtime': 7.22.6 - clsx: 1.2.1 - dom-helpers: 5.2.1 - loose-envify: 1.4.0 - prop-types: 15.8.1 + '@reach/observe-rect': 1.2.0 react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-lifecycles-compat: 3.0.4 dev: false /react-window-infinite-loader@1.0.9(react-dom@18.2.0)(react@18.2.0): diff --git a/src/components/ui/MusicCard.tsx b/src/components/ui/MusicCard.tsx index c8c257f..2d7421a 100644 --- a/src/components/ui/MusicCard.tsx +++ b/src/components/ui/MusicCard.tsx @@ -47,7 +47,7 @@ export default function MusicCard({ await play(context, audio, true) }} id={`audio-${audio.id}`} - className="hover:cursor-pointer p-4 rounded-lg transition ease-in-out delay-90 dark:hover:bg-gray-900 hover:bg-gray-50 duration-150 flex items-center space-x-8 w-full" + className="hover:cursor-pointer p-4 rounded-lg transition ease-in-out delay-90 dark:hover:bg-gray-900 hover:bg-gray-50 duration-150 flex items-center space-x-6 w-full" >
(({ className, ...props }, ref) => ( +)) + +// eslint-disable-next-line react/display-name +const CommandMusicList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + )) @@ -118,6 +130,14 @@ const CommandItem = React.forwardRef< /> )) +// eslint-disable-next-line react/display-name +const CommandMusicItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + CommandItem.displayName = CommandPrimitive.Item.displayName const CommandShortcut = ({ @@ -141,6 +161,8 @@ export { CommandInput, CommandItem, CommandList, + CommandMusicItem, + CommandMusicList, CommandSeparator, CommandShortcut, } diff --git a/src/pages/music.tsx b/src/pages/music.tsx index 1c392d0..cf849c1 100644 --- a/src/pages/music.tsx +++ b/src/pages/music.tsx @@ -1,3 +1,7 @@ +/* eslint-disable prettier/prettier */ +/* eslint-disable react/display-name */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ @@ -5,8 +9,9 @@ import { /*Book,*/ PenBox, Shuffle } from "lucide-react" import Image from "next/image" import { useContext, useEffect } from "react" -import { List } from "react-virtualized" +// import { ViewportList } from 'react-viewport-list' +// import { FixedSizeList as List } from "react-window" import { AppContext } from "@/components/AppContext" import { fetchPlaylistCheckedState, @@ -14,12 +19,21 @@ import { } from "@/components/contexts_menu/CPlaylistSub" import { shuffle } from "@/components/player/Player" import { Button } from "@/components/ui/button" +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandMusicItem, + CommandMusicList, +} from "@/components/ui/command" import MusicCard from "@/components/ui/MusicCard" import { b64imageWrap, cn, isObjectEmpty } from "@/lib/utils" + + export default function Music({ name }: { name: string }) { const context = useContext(AppContext) - useEffect(() => { setAudiosFromPlaylist(name, context.setAudioList) // eslint-disable-next-line react-hooks/exhaustive-deps @@ -78,33 +92,42 @@ export default function Music({ name }: { name: string }) {
{/* 2/4 */} -
-
- {/* {context.audioList.map((value, index) => { - // needs to be lazy loaded - return - })} */} - {/* Not reponsive :( */} - -
-
+ + + {/* Not reponsive :( */} + + No music found. + + {/* + {rowRenderer(context, name)} + */} + {context.audioList.map((value, index) => { + // needs to be lazy loaded + return ( + + + + ) + })} + + + ) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - function rowRenderer({ key, style }: any) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unused-vars - const index = key.split("-")[0] - return ( -
- -
- ) - } } + +// const rowRenderer = +// (context: appContext, name: string) => +// ({ index, style }: any) => { + +// return ( +// +// +// +// ) +// } \ No newline at end of file From a764d2191e963eaf35733e732cb5455765ff8b2c Mon Sep 17 00:00:00 2001 From: Siirko Date: Sun, 26 Nov 2023 16:56:31 +0100 Subject: [PATCH 2/4] search handled with backend --- package.json | 3 +- pnpm-lock.yaml | 54 +++++++++++++------- src-tauri/Cargo.lock | 29 +++++++++++ src-tauri/Cargo.toml | 1 + src-tauri/src/api/player.rs | 26 ++++++++++ src-tauri/src/api/utils.rs | 32 ++++++------ src-tauri/src/main.rs | 1 + src-tauri/src/music/audio.rs | 13 +++++ src/components/player/Player.tsx | 6 +-- src/pages/music.tsx | 85 ++++++++++++++++---------------- 10 files changed, 167 insertions(+), 83 deletions(-) diff --git a/package.json b/package.json index aba0b49..212f623 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@radix-ui/react-tooltip": "^1.0.6", "@tanstack/react-table": "^8.10.7", "@tauri-apps/api": "^1.4.0", + "@types/react-virtualized": "^9.21.28", "@types/react-window": "^1.8.8", "@types/react-window-infinite-loader": "^1.0.9", "byte-base64": "^1.1.0", @@ -57,7 +58,7 @@ "react-hook-form": "^7.45.2", "react-toast": "^1.0.3", "react-viewport-list": "^7.1.1", - "react-window": "^1.8.9", + "react-virtualized": "^9.22.5", "react-window-infinite-loader": "^1.0.9", "shadcn-ui": "^0.3.0", "tailwind-merge": "^1.13.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa52898..424ea5f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -80,6 +80,9 @@ dependencies: '@tauri-apps/api': specifier: ^1.4.0 version: 1.4.0 + '@types/react-virtualized': + specifier: ^9.21.28 + version: 9.21.28 '@types/react-window': specifier: ^1.8.8 version: 1.8.8 @@ -128,9 +131,9 @@ dependencies: react-viewport-list: specifier: ^7.1.1 version: 7.1.1(react@18.2.0) - react-window: - specifier: ^1.8.9 - version: 1.8.9(react-dom@18.2.0)(react@18.2.0) + react-virtualized: + specifier: ^9.22.5 + version: 9.22.5(react-dom@18.2.0)(react@18.2.0) react-window-infinite-loader: specifier: ^1.0.9 version: 1.0.9(react-dom@18.2.0)(react@18.2.0) @@ -3043,6 +3046,13 @@ packages: dependencies: '@types/react': 18.2.14 + /@types/react-virtualized@9.21.28: + resolution: {integrity: sha512-GE9tPk6vinqh2cqVs5xyqF5g6HdHJMVY1msJRSY12MN8+GrI0f9KUmXbryek6Pyry5fM2wTX1VvZxQj3ZKgTRg==} + dependencies: + '@types/prop-types': 15.7.5 + '@types/react': 18.2.14 + dev: false + /@types/react-window-infinite-loader@1.0.9: resolution: {integrity: sha512-gEInTjQwURCnDOFyIEK2+fWB5gTjqwx30O62QfxA9stE5aiB6EWkGj4UMhc0axq7/FV++Gs/TGW8FtgEx0S6Tw==} dependencies: @@ -4098,6 +4108,13 @@ packages: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} dev: true + /dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dependencies: + '@babel/runtime': 7.22.6 + csstype: 3.1.2 + dev: false + /dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} dependencies: @@ -5581,10 +5598,6 @@ packages: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} dev: true - /memoize-one@5.2.1: - resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} - dev: false - /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -6427,7 +6440,6 @@ packages: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 - dev: true /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} @@ -6501,7 +6513,6 @@ packages: /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - dev: true /react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -6511,6 +6522,10 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true + /react-lifecycles-compat@3.0.4: + resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} + dev: false + /react-remove-scroll-bar@2.3.4(@types/react@18.2.14)(react@18.2.0): resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} engines: {node: '>=10'} @@ -6607,26 +6622,29 @@ packages: react: 18.2.0 dev: false - /react-window-infinite-loader@1.0.9(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw==} - engines: {node: '>8.0.0'} + /react-virtualized@9.22.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-YqQMRzlVANBv1L/7r63OHa2b0ZsAaDp1UhVNEdUaXI8A5u6hTpA5NYtUueLH2rFuY/27mTGIBl7ZhqFKzw18YQ==} peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 dependencies: + '@babel/runtime': 7.22.6 + clsx: 1.2.1 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + react-lifecycles-compat: 3.0.4 dev: false - /react-window@1.8.9(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q==} + /react-window-infinite-loader@1.0.9(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw==} engines: {node: '>8.0.0'} peerDependencies: - react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 - react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 + react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 dependencies: - '@babel/runtime': 7.22.6 - memoize-one: 5.2.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index cb109af..bd321bb 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -24,6 +24,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", + "getrandom 0.2.10", "once_cell", "version_check", ] @@ -110,6 +111,7 @@ dependencies = [ "env_logger", "file-format", "futures", + "indicium", "lofty", "log", "rand 0.8.5", @@ -959,6 +961,12 @@ dependencies = [ "time 0.3.23", ] +[[package]] +name = "eddie" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ad36183b190ad1632999a8735b9842f3fda7a5afa433d9132e80860ef7051a" + [[package]] name = "embed-resource" version = "2.2.0" @@ -1856,6 +1864,18 @@ dependencies = [ "hashbrown 0.14.0", ] +[[package]] +name = "indicium" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c8e0829bc7bb361e0418535075a519519361022d691077e0dd4d0dc8c2afc5" +dependencies = [ + "ahash", + "eddie", + "kstring", + "tracing", +] + [[package]] name = "infer" version = "0.12.0" @@ -2001,6 +2021,15 @@ dependencies = [ "treediff", ] +[[package]] +name = "kstring" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +dependencies = [ + "static_assertions", +] + [[package]] name = "kuchiki" version = "0.8.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index d210b70..424608d 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -33,6 +33,7 @@ futures = "0.3.29" youtube_dl = { version = "0.9.0", features = ["tokio"] } tokio = { version = "1.20.1", features = ["full"] } base64 = { version = "0.21.5" } +indicium = "0.6.0" [features] # by default Tauri runs in production mode diff --git a/src-tauri/src/api/player.rs b/src-tauri/src/api/player.rs index 6c31122..c7e9ad7 100644 --- a/src-tauri/src/api/player.rs +++ b/src-tauri/src/api/player.rs @@ -4,6 +4,7 @@ use std::{ sync::{Arc, Mutex}, }; +use indicium::simple::SearchIndex; use log::{error, info}; use tauri::{AppHandle, State}; @@ -95,3 +96,28 @@ pub async fn seek_to( Err(e) => Err(e.to_string()), } } + +#[tauri::command] +pub async fn search_audio( + query: String, + playlist: String, + player: State<'_, Arc>>, +) -> Result, String> { + let player = player.lock().unwrap(); + if query.is_empty() { + return Ok(super::utils::create_audio_list(player, &playlist)); + } + let mut results = Vec::new(); + let mut search_index: SearchIndex = SearchIndex::default(); + + player.playlists[&playlist] + .iter() + .enumerate() + .for_each(|(i, audio)| search_index.insert(&i, audio)); + + let search_results = search_index.search(&query); + for result in search_results { + results.push(super::utils::create_audio(&player.audios[*result], result)); + } + Ok(results) +} diff --git a/src-tauri/src/api/utils.rs b/src-tauri/src/api/utils.rs index 4e1f0eb..f15c3eb 100644 --- a/src-tauri/src/api/utils.rs +++ b/src-tauri/src/api/utils.rs @@ -29,29 +29,25 @@ pub fn create_audio_list(player: MutexGuard<'_, MusicPlayer>, str: &str) -> Vec< let mut audios = Vec::new(); if !str.is_empty() { for (id, audio) in player.playlists[str].iter().enumerate() { - audios.push(Audio { - path: audio.path.clone(), - title: audio.tag.title.clone(), - artist: audio.tag.artist.clone(), - album: audio.tag.album.clone(), - duration: audio.duration.as_secs(), - id, - cover: audio.cover.clone(), - }); + audios.push(create_audio(audio, &id)); } } else { for (id, audio) in player.audios.iter().enumerate() { - audios.push(Audio { - path: audio.path.clone(), - title: audio.tag.title.clone(), - artist: audio.tag.artist.clone(), - album: audio.tag.album.clone(), - duration: audio.duration.as_secs(), - id, - cover: audio.cover.clone(), - }); + audios.push(create_audio(audio, &id)); } } audios } + +pub fn create_audio(audio: &crate::music::audio::_Audio, id: &usize) -> Audio { + Audio { + path: audio.path.clone(), + title: audio.tag.title.clone(), + artist: audio.tag.artist.clone(), + album: audio.tag.album.clone(), + duration: audio.duration.as_secs(), + id: *id, + cover: audio.cover.clone(), + } +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index c23a394..d3f42ba 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -78,6 +78,7 @@ fn main() { player::pause, player::update_player, player::seek_to, + player::search_audio, audio::updated_current_playlist, audio::retrieve_audios, audio::current_audio_status, diff --git a/src-tauri/src/music/audio.rs b/src-tauri/src/music/audio.rs index 0729614..1017a28 100644 --- a/src-tauri/src/music/audio.rs +++ b/src-tauri/src/music/audio.rs @@ -142,6 +142,19 @@ impl std::cmp::PartialEq for _Audio { } } +struct AudioWrapper(_Audio); + +impl indicium::simple::Indexable for AudioWrapper { + fn strings(&self) -> Vec { + vec![ + self.0.path.clone(), + duration_to_string(self.0.duration), + self.0.format.clone(), + self.0.status.to_string(), + ] + } +} + fn gen_tag(path: &PathBuf) -> TaggedFile { let tagged_file = Probe::open(path); match tagged_file { diff --git a/src/components/player/Player.tsx b/src/components/player/Player.tsx index 6a4f68a..7dc32ae 100644 --- a/src/components/player/Player.tsx +++ b/src/components/player/Player.tsx @@ -63,8 +63,8 @@ export async function update_after_play( const playlist = isObjectEmpty(currentPlaylistListening as unknown as object) ? name : !fromMusicPage - ? currentPlaylistListening - : name + ? currentPlaylistListening + : name console.log(playlist) await invoke("update_player", { playlist: playlist, @@ -202,7 +202,7 @@ export function Player() { }, [wupdate_status, status]) useEffect(() => { - ;(() => { + ; (() => { if (!isObjectEmpty(audio)) { invoke("update_history") .then(() => { diff --git a/src/pages/music.tsx b/src/pages/music.tsx index cf849c1..995ab54 100644 --- a/src/pages/music.tsx +++ b/src/pages/music.tsx @@ -6,32 +6,26 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable @typescript-eslint/no-misused-promises */ +import { invoke } from "@tauri-apps/api/tauri" import { /*Book,*/ PenBox, Shuffle } from "lucide-react" import Image from "next/image" import { useContext, useEffect } from "react" - // import { ViewportList } from 'react-viewport-list' -// import { FixedSizeList as List } from "react-window" -import { AppContext } from "@/components/AppContext" +import { List } from "react-virtualized" + +import { AppContext, appContext } from "@/components/AppContext" import { fetchPlaylistCheckedState, setAudiosFromPlaylist, } from "@/components/contexts_menu/CPlaylistSub" import { shuffle } from "@/components/player/Player" +import { Audio } from "@/components/types/audio" import { Button } from "@/components/ui/button" -import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandMusicItem, - CommandMusicList, -} from "@/components/ui/command" +import { Input } from "@/components/ui/input" import MusicCard from "@/components/ui/MusicCard" import { b64imageWrap, cn, isObjectEmpty } from "@/lib/utils" - export default function Music({ name }: { name: string }) { const context = useContext(AppContext) useEffect(() => { @@ -89,45 +83,50 @@ export default function Music({ name }: { name: string }) { > Shuffle + + {/* 2/4 */} - - +
{/* Not reponsive :( */} - - No music found. - - {/* - {rowRenderer(context, name)} - */} - {context.audioList.map((value, index) => { +
+ { + const inputValue = value.target.value.toLowerCase(); + invoke("search_audio", { query: inputValue, playlist: name }).then((filteredAudioList) => { + context.setAudioList(filteredAudioList) + }).catch(console.error) + }} /> + + {/* {context.audioList.map((value, index) => { // needs to be lazy loaded - return ( - - - + return ( ) - })} - - - + })} */} +
+
) } -// const rowRenderer = -// (context: appContext, name: string) => -// ({ index, style }: any) => { +const rowRenderer = + (context: appContext, name: string) => + ({ index, style }: any) => { -// return ( -// -// -// -// ) -// } \ No newline at end of file + return ( +
+ +
+ ) + } \ No newline at end of file From 5d4d34c7a7ce75234e47a8ec02d722536c61cec5 Mon Sep 17 00:00:00 2001 From: Siirko Date: Sun, 26 Nov 2023 17:13:27 +0100 Subject: [PATCH 3/4] added comments and stylized search bar --- src-tauri/src/api/player.rs | 1 + src/components/player/Player.tsx | 1 + src/components/ui/input.tsx | 26 +++++++++++++++++++++++++- src/pages/music.tsx | 16 +++++----------- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src-tauri/src/api/player.rs b/src-tauri/src/api/player.rs index c7e9ad7..d6d3d73 100644 --- a/src-tauri/src/api/player.rs +++ b/src-tauri/src/api/player.rs @@ -110,6 +110,7 @@ pub async fn search_audio( let mut results = Vec::new(); let mut search_index: SearchIndex = SearchIndex::default(); + // this has to be done when the app starts ! player.playlists[&playlist] .iter() .enumerate() diff --git a/src/components/player/Player.tsx b/src/components/player/Player.tsx index 7dc32ae..b95313a 100644 --- a/src/components/player/Player.tsx +++ b/src/components/player/Player.tsx @@ -171,6 +171,7 @@ export function Player() { total: 0, status: "stopped", } as AudioStatus) + // the audio should be retrieved from backend and the not the context const { audio } = useContext(AppContext) const wupdate_status = () => { void invoke("current_audio_status") diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx index 5b51786..20f161a 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/input.tsx @@ -1,3 +1,4 @@ +import { Search } from "lucide-react" import * as React from "react" import { cn } from "@/lib/utils" @@ -19,6 +20,29 @@ const Input = React.forwardRef( ) }, ) + +const SearchInput = React.forwardRef( + ({ className, ...props }, ref) => { + return ( +
+ + +
+ ) + }, +) + Input.displayName = "Input" +SearchInput.displayName = "SearchInput" -export { Input } +export { Input, SearchInput } diff --git a/src/pages/music.tsx b/src/pages/music.tsx index 995ab54..a405791 100644 --- a/src/pages/music.tsx +++ b/src/pages/music.tsx @@ -21,7 +21,7 @@ import { import { shuffle } from "@/components/player/Player" import { Audio } from "@/components/types/audio" import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" +import { SearchInput } from "@/components/ui/input" import MusicCard from "@/components/ui/MusicCard" import { b64imageWrap, cn, isObjectEmpty } from "@/lib/utils" @@ -83,28 +83,22 @@ export default function Music({ name }: { name: string }) { > Shuffle - - {/* 2/4 */}
{/* Not reponsive :( */} -
- { +
+ { const inputValue = value.target.value.toLowerCase(); invoke("search_audio", { query: inputValue, playlist: name }).then((filteredAudioList) => { context.setAudioList(filteredAudioList) }).catch(console.error) }} /> + Date: Sun, 26 Nov 2023 17:27:50 +0100 Subject: [PATCH 4/4] added comments about a bug --- src-tauri/src/api/player.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src-tauri/src/api/player.rs b/src-tauri/src/api/player.rs index d6d3d73..38f8ee1 100644 --- a/src-tauri/src/api/player.rs +++ b/src-tauri/src/api/player.rs @@ -111,6 +111,7 @@ pub async fn search_audio( let mut search_index: SearchIndex = SearchIndex::default(); // this has to be done when the app starts ! + // this create a problem when we switch between playlist and search player.playlists[&playlist] .iter() .enumerate()