From 34dc96769439e7777ca4a7e5079ed64827f139a7 Mon Sep 17 00:00:00 2001 From: 22 <60903333+nini22P@users.noreply.github.com> Date: Tue, 3 Jun 2025 20:08:16 +0800 Subject: [PATCH 1/5] update changelog --- CHANGELOG.md | 8 +++ package-lock.json | 159 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 4 +- 3 files changed, 166 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d127db..e774b43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v1.9.4 +### Changelog +* Release android PWA apk + +### 更新日志 +* 发布 android PWA apk + + ## v1.9.3 ### ⚠ Warning For self-deployed instances, please check [readme.md](https://github.com/nini22P/omp/blob/main/readme.md#running-and-build) before upgrading to add any missing environment variables: `ONEDRIVE_AUTH`, `ONEDRIVE_GME` diff --git a/package-lock.json b/package-lock.json index be51e78..8641471 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "omp", - "version": "1.9.3", + "version": "1.9.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "omp", - "version": "1.9.3", + "version": "1.9.4", "dependencies": { "@azure/msal-browser": "3.28.1", "@azure/msal-react": "2.2.0", @@ -40,7 +40,7 @@ "@lingui/cli": "5.3.2", "@lingui/swc-plugin": "5.5.2", "@pmmmwh/react-refresh-webpack-plugin": "0.6.0", - "@swc/core": "1.11.29", + "@swc/core": "^1.11.29", "@types/color": "4.2.0", "@types/extract-colors": "^1.1.4", "@types/node": "22.15.29", @@ -3189,6 +3189,159 @@ } } }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.11.29", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.29.tgz", + "integrity": "sha512-whsCX7URzbuS5aET58c75Dloby3Gtj/ITk2vc4WW6pSDQKSPDuONsIcZ7B2ng8oz0K6ttbi4p3H/PNPQLJ4maQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.11.29", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.11.29.tgz", + "integrity": "sha512-S3eTo/KYFk+76cWJRgX30hylN5XkSmjYtCBnM4jPLYn7L6zWYEPajsFLmruQEiTEDUg0gBEWLMNyUeghtswouw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.11.29", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.29.tgz", + "integrity": "sha512-o9gdshbzkUMG6azldHdmKklcfrcMx+a23d/2qHQHPDLUPAN+Trd+sDQUYArK5Fcm7TlpG4sczz95ghN0DMkM7g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.11.29", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.29.tgz", + "integrity": "sha512-sLoaciOgUKQF1KX9T6hPGzvhOQaJn+3DHy4LOHeXhQqvBgr+7QcZ+hl4uixPKTzxk6hy6Hb0QOvQEdBAAR1gXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.11.29", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.29.tgz", + "integrity": "sha512-PwjB10BC0N+Ce7RU/L23eYch6lXFHz7r3NFavIcwDNa/AAqywfxyxh13OeRy+P0cg7NDpWEETWspXeI4Ek8otw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.11.29", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.29.tgz", + "integrity": "sha512-i62vBVoPaVe9A3mc6gJG07n0/e7FVeAvdD9uzZTtGLiuIfVfIBta8EMquzvf+POLycSk79Z6lRhGPZPJPYiQaA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.11.29", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.29.tgz", + "integrity": "sha512-YER0XU1xqFdK0hKkfSVX1YIyCvMDI7K07GIpefPvcfyNGs38AXKhb2byySDjbVxkdl4dycaxxhRyhQ2gKSlsFQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.11.29", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.29.tgz", + "integrity": "sha512-po+WHw+k9g6FAg5IJ+sMwtA/fIUL3zPQ4m/uJgONBATCVnDDkyW6dBA49uHNVtSEvjvhuD8DVWdFP847YTcITw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.11.29", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.29.tgz", + "integrity": "sha512-h+NjOrbqdRBYr5ItmStmQt6x3tnhqgwbj9YxdGPepbTDamFv7vFnhZR0YfB3jz3UKJ8H3uGJ65Zw1VsC+xpFkg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@swc/core-win32-x64-msvc": { "version": "1.11.29", "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.29.tgz", diff --git a/package.json b/package.json index 081cc11..a447c90 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "omp", "description": "OneDrive Media Player", "private": true, - "version": "1.9.3", + "version": "1.9.4", "scripts": { "build": "npm run generate && webpack --mode=production --node-env=production", "build:dev": "npm run generate:dev && webpack --mode=production --node-env=production", @@ -47,7 +47,7 @@ "@lingui/cli": "5.3.2", "@lingui/swc-plugin": "5.5.2", "@pmmmwh/react-refresh-webpack-plugin": "0.6.0", - "@swc/core": "1.11.29", + "@swc/core": "^1.11.29", "@types/color": "4.2.0", "@types/extract-colors": "^1.1.4", "@types/node": "22.15.29", From 18af251187ec92787dc1ef9ec5445f13063b2038 Mon Sep 17 00:00:00 2001 From: 22 <60903333+nini22P@users.noreply.github.com> Date: Wed, 4 Jun 2025 09:22:29 +0800 Subject: [PATCH 2/5] update readme --- README.md | 13 +++++++++++-- README_CN.md | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b111762..3a3bb71 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,21 @@ # OMP - OneDrive Media Player ![ci](https://github.com/nini22P/omp/actions/workflows/ci.yml/badge.svg) -Afdaian + + + + + Afdaian + [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/nini22p) English | [中文](./README_CN.md) -**[Now Playing](https://nini22p.github.io/omp/)** +**Try OMP Now:** + +* **[Web Version](https://nini22p.github.io/omp/)** +* **[Microsoft Store (PWA)](https://apps.microsoft.com/detail/9p6w6x16q7l9)** +* **[Download Android APK (PWA)](https://github.com/nini22P/omp/releases/latest/download/OMP-android.apk)** ## Features diff --git a/README_CN.md b/README_CN.md index b591d4f..edd5b0c 100644 --- a/README_CN.md +++ b/README_CN.md @@ -3,12 +3,21 @@ # OMP - OneDrive 媒体播放器 ![ci](https://github.com/nini22P/omp/actions/workflows/ci.yml/badge.svg) -Afdaian + + + + + Afdaian + [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/nini22p) [English](./README.md) | 中文 -**[立即播放](https://nini22p.github.io/omp/)** +**立即体验 OMP:** + +* **[网页版](https://nini22p.github.io/omp/)** +* **[微软商店 (PWA)](https://apps.microsoft.com/detail/9p6w6x16q7l9)** +* **[下载 Android APK (PWA)](https://github.com/nini22P/omp/releases/latest/download/OMP-android.apk)** ## 功能 From 7e29f6909a915ecbd36ce125a9a77c1301e14f2c Mon Sep 17 00:00:00 2001 From: Anlor Date: Mon, 18 Aug 2025 04:15:18 +0000 Subject: [PATCH 3/5] feat: Add /delta api --- src/graph/graph.ts | 18 ++++++++++++ src/hooks/graph/useFilesData.ts | 45 ++++++++++++++++++++++++++++- src/store/useLocalDeltaDataStore.ts | 41 ++++++++++++++++++++++++++ src/types/file.ts | 3 +- 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/store/useLocalDeltaDataStore.ts diff --git a/src/graph/graph.ts b/src/graph/graph.ts index 23e5477..afe4629 100644 --- a/src/graph/graph.ts +++ b/src/graph/graph.ts @@ -112,4 +112,22 @@ export const search = async (path: string, searchQuery: string, accessToken: str return fetch(`${graphConfig.graphMeEndpoint}/me/drive/root:/${encodeURIComponent(path)}:/search(q='${searchQuery}')`, options) .then(response => response.json()) .catch(error => console.log(error)) +} + +export const getDelta = async (path: string, accessToken: string, nextLink?: string) => { + const headers = new Headers() + const bearer = `Bearer ${accessToken}` + + headers.append('Authorization', bearer) + + const options = { + method: 'GET', + headers: headers + } + + const param = '?$top=2147483647&$select=name, parentReference, size, folder, lastModifiedDateTime, id, @microsoft.graph.downloadUrl' + + return fetch(nextLink || `${graphConfig.graphMeEndpoint}/me/drive/root:/${encodeURIComponent(path)}:/delta${param}`, options) + .then(response => response.json()) + .catch(error => console.log(error)) } \ No newline at end of file diff --git a/src/hooks/graph/useFilesData.ts b/src/hooks/graph/useFilesData.ts index b4690ea..082439f 100644 --- a/src/hooks/graph/useFilesData.ts +++ b/src/hooks/graph/useFilesData.ts @@ -1,10 +1,13 @@ -import { getAppRootFiles, getFile, getFiles, search, uploadAppRootJson } from '@/graph/graph' +import { getAppRootFiles, getFile, getFiles, search, uploadAppRootJson, getDelta } from '@/graph/graph' import { loginRequest } from '@/graph/authConfig' import { useMsal } from '@azure/msal-react' import { AccountInfo } from '@azure/msal-browser' +import useLocalDeltaDataStore, { deltaDataCache } from '@/store/useLocalDeltaDataStore' +import { RemoteItem } from '@/types/file' const useFilesData = () => { const { instance } = useMsal() + const { setLocalDeltaData, getLocalDeltaData } = useLocalDeltaDataStore() /** * 获取文件夹数据 @@ -51,12 +54,52 @@ const useFilesData = () => { return response.value } + const getRemoteDeltaData = async (account: AccountInfo, path: string, url?: string) => { + await instance.initialize() + const acquireToken = await instance.acquireTokenSilent({ ...loginRequest, account: account }) + let response = await getDelta(path, acquireToken.accessToken, url) + const result:RemoteItem[] = response.value + while (response['@odata.nextLink']) { + const nextResponse = await getDelta(path, acquireToken.accessToken, response['@odata.nextLink']) + result.push(...nextResponse.value) + response = nextResponse + } + const deltaData: deltaDataCache = {items: result, url: response['@odata.deltaLink']} + return deltaData + } + + const getDeltaData = async(account: AccountInfo, path: string) => { + const localData = await getLocalDeltaData(path) + if (localData && localData.url) { + try { + const response = await getRemoteDeltaData(account, path, localData.url) + const result = localData.items + response.items.forEach((item: RemoteItem) => { + const index = result.findIndex(i => i.id === item.id) + if (item.deleted) { + if (index !== -1) result.splice(index, 1) + } else { + if (index === -1) result.push(item) + } + }) + setLocalDeltaData(path, {items: result, url: response.url}) + return result + } catch (error) { + console.error('Get delta data error:', error) + } + } + const response = await getRemoteDeltaData(account, path) + setLocalDeltaData(path, response) + return response.items + } + return { getFilesData, getFileData, getAppRootFilesData, uploadAppRootJsonData, getSearchData, + getDeltaData, } } diff --git a/src/store/useLocalDeltaDataStore.ts b/src/store/useLocalDeltaDataStore.ts new file mode 100644 index 0000000..3e740c2 --- /dev/null +++ b/src/store/useLocalDeltaDataStore.ts @@ -0,0 +1,41 @@ +import { get, getMany, set, clear, entries, createStore } from 'idb-keyval' +import { RemoteItem } from '../types/file' + +export interface deltaDataCache { + items: RemoteItem[]; + url?: string; // @odata.deltaLink +} + +const useLocalDeltaDataStore = () => { + + const deltaDataStore = createStore('deltadata', 'deltadata-store') + + const getLocalDeltaData = async (filePath: string) => { + if (!filePath || filePath.length === 0) return null + else { + const deltaData = await get(filePath, deltaDataStore) + return deltaData ? JSON.parse(deltaData) as deltaDataCache : null + } + } + + const getManyLocalDeltaData = async (filePaths: string[]) => { + if (!filePaths || filePaths.length === 0) return null + else { + const deltaData = await getMany(filePaths, deltaDataStore) + return deltaData.map(deltaData => deltaData ? JSON.parse(deltaData) as deltaDataCache : null) + } + } + + const setLocalDeltaData = async (path: string, deltaData: deltaDataCache) => { + await set(path, JSON.stringify(deltaData), deltaDataStore) + } + + const getAllLocalDeltaData = async () => await entries(deltaDataStore) + + const clearLocalDeltaData = async () => await clear(deltaDataStore) + + return { getLocalDeltaData, getManyLocalDeltaData, setLocalDeltaData, getAllLocalDeltaData, clearLocalDeltaData } + +} + +export default useLocalDeltaDataStore \ No newline at end of file diff --git a/src/types/file.ts b/src/types/file.ts index c488514..40c0487 100644 --- a/src/types/file.ts +++ b/src/types/file.ts @@ -9,7 +9,8 @@ export interface RemoteItem { parentReference: { name: string, path: string, - } + }, + deleted?: object } export interface FileItem { From e4710f6008458eba08eafad7fd3e7de7c6b8ede4 Mon Sep 17 00:00:00 2001 From: Anlor Date: Mon, 18 Aug 2025 04:15:39 +0000 Subject: [PATCH 4/5] feat: Play files under subfolders when shuffling --- src/components/CommonList/CommonList.tsx | 38 ++++++++++++++---- src/components/CommonList/ShuffleAll.tsx | 12 ++++-- src/locales/en/messages.po | 49 +++++++++++++----------- src/locales/zh-CN/messages.po | 49 +++++++++++++----------- src/pages/Files/Files.tsx | 40 ++++++++++++++++++- src/pages/Setting.tsx | 12 ++++++ 6 files changed, 143 insertions(+), 57 deletions(-) diff --git a/src/components/CommonList/CommonList.tsx b/src/components/CommonList/CommonList.tsx index 1e8c5b8..f9886ba 100644 --- a/src/components/CommonList/CommonList.tsx +++ b/src/components/CommonList/CommonList.tsx @@ -7,7 +7,7 @@ import { shufflePlayQueue } from '../../utils' import CommonMenu from './CommonMenu' import { FileItem } from '../../types/file' import CommonListItem from './CommonListItem' -import { Box, Fab, List, useMediaQuery, useTheme } from '@mui/material' +import { Box, CircularProgress, Fab, List, useMediaQuery, useTheme } from '@mui/material' import { AutoSizer, List as VirtualList } from 'react-virtualized' import CommonListItemCard from './CommonListItemCard' import ShuffleRoundedIcon from '@mui/icons-material/ShuffleRounded' @@ -35,6 +35,7 @@ const CommonList = ( func?: { open?: (index: number) => void, remove?: (indexArray: number[]) => void, + deltaListFetcher?:() => Promise, }, }) => { @@ -50,9 +51,10 @@ const CommonList = ( const [dialogOpen, setDialogOpen] = useState(false) const [selectIndex, setSelectIndex] = useState(null) const [selectIndexArray, setSelectIndexArray] = useState([]) + const [shuffleLoading, setShuffleLoading] = useState(false) const isSelectMode = selectIndexArray.length > 0 - const shuffleDisplay = listData.filter(item => item.fileType === 'audio' || item.fileType === 'video').length > 0 + const shuffleDisplay = true const playAllDisplay = shuffleDisplay || listData.filter(item => item.fileType === 'folder' && /^(disc|disk)\s*\d+$/.test(item.fileName.toLocaleLowerCase())).length > 0 const addSelectIndex = (index: number) => { setSelectIndexArray([...selectIndexArray, index].sort()) } @@ -75,9 +77,22 @@ const CommonList = ( } // 点击随机播放全部 - const handleClickShuffleAll = () => { - if (listData) { - const list = listData + const handleClickShuffleAll = async () => { + setShuffleLoading(true) + let dataToUse = listData + if (func?.deltaListFetcher) { + try { + const deltaData = await func.deltaListFetcher() + if (deltaData && deltaData.length > 0) { + dataToUse = deltaData + } + } catch (error) { + console.error('Error fetching delta data:', error) + } + } + + if (dataToUse) { + const list = dataToUse .filter((item) => item.fileType === 'audio' || item.fileType === 'video') .map((item, index) => { return { index, ...item } }) if (!shuffle) @@ -87,6 +102,7 @@ const CommonList = ( updateCurrentIndex(shuffleList[0].index) updateAutoPlay(true) } + setShuffleLoading(false) } const openMenu = (event: React.MouseEvent) => { @@ -372,8 +388,16 @@ const CommonList = ( <> { shuffleDisplay && - - + + {shuffleLoading ? ( + + ) : ( + + )} } { diff --git a/src/components/CommonList/ShuffleAll.tsx b/src/components/CommonList/ShuffleAll.tsx index 4e71095..59b1009 100644 --- a/src/components/CommonList/ShuffleAll.tsx +++ b/src/components/CommonList/ShuffleAll.tsx @@ -1,8 +1,8 @@ -import { ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material' +import { CircularProgress, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material' import { t } from '@lingui/macro' import ShuffleRoundedIcon from '@mui/icons-material/ShuffleRounded' -const ShuffleAll = ({ handleClickShuffleAll }: { handleClickShuffleAll: () => void }) => { +const ShuffleAll = ({ handleClickShuffleAll, loading = false }: { handleClickShuffleAll: () => void, loading?: boolean }) => { return ( vo }, }} > - + - + {loading ? ( + + ) : ( + + )} diff --git a/src/locales/en/messages.po b/src/locales/en/messages.po index 1792044..bc1695f 100644 --- a/src/locales/en/messages.po +++ b/src/locales/en/messages.po @@ -13,15 +13,15 @@ msgstr "" "Language-Team: \n" "Plural-Forms: \n" -#: src/pages/Setting.tsx:161 +#: src/pages/Setting.tsx:173 msgid "About" msgstr "About" -#: src/pages/Setting.tsx:95 +#: src/pages/Setting.tsx:97 msgid "Account" msgstr "Account" -#: src/pages/Setting.tsx:225 +#: src/pages/Setting.tsx:237 msgid "Add account" msgstr "Add account" @@ -46,15 +46,15 @@ msgstr "Add to playlist" msgid "Ascending" msgstr "Ascending" -#: src/pages/Setting.tsx:137 +#: src/pages/Setting.tsx:149 msgid "Auto" msgstr "Auto" -#: src/pages/Setting.tsx:176 +#: src/pages/Setting.tsx:188 msgid "Build time" msgstr "Build time" -#: src/pages/Setting.tsx:230 +#: src/pages/Setting.tsx:242 #: src/pages/Playlist/Playlist.tsx:217 #: src/pages/Playlist/Playlist.tsx:240 #: src/pages/Player/PlayerMenu.tsx:363 @@ -70,7 +70,8 @@ msgstr "Cancel select" msgid "Classic" msgstr "Classic" -#: src/pages/Setting.tsx:118 +#: src/pages/Setting.tsx:120 +#: src/pages/Setting.tsx:130 msgid "Clear" msgstr "Clear" @@ -80,7 +81,7 @@ msgstr "Clear" msgid "Close" msgstr "Close" -#: src/pages/Setting.tsx:144 +#: src/pages/Setting.tsx:156 msgid "Color mode" msgstr "Color mode" @@ -92,15 +93,15 @@ msgstr "Current" msgid "Currently using a development version, please be careful with your data!" msgstr "Currently using a development version, please be careful with your data!" -#: src/pages/Setting.tsx:127 +#: src/pages/Setting.tsx:139 msgid "Customize" msgstr "Customize" -#: src/pages/Setting.tsx:139 +#: src/pages/Setting.tsx:151 msgid "Dark" msgstr "Dark" -#: src/pages/Setting.tsx:114 +#: src/pages/Setting.tsx:116 msgid "Data" msgstr "Data" @@ -149,7 +150,7 @@ msgstr "History" msgid "Last modified" msgstr "Last modified" -#: src/pages/Setting.tsx:138 +#: src/pages/Setting.tsx:150 msgid "Light" msgstr "Light" @@ -157,7 +158,11 @@ msgstr "Light" msgid "List" msgstr "List" -#: src/pages/Setting.tsx:122 +#: src/pages/Setting.tsx:134 +msgid "Local file index cache" +msgstr "Local file index cache" + +#: src/pages/Setting.tsx:124 msgid "Local metaData cache" msgstr "Local metaData cache" @@ -165,7 +170,7 @@ msgstr "Local metaData cache" msgid "Lyrics" msgstr "Lyrics" -#: src/pages/Setting.tsx:98 +#: src/pages/Setting.tsx:100 msgid "Manage" msgstr "Manage" @@ -216,11 +221,11 @@ msgstr "OK" msgid "Open in folder" msgstr "Open in folder" -#: src/pages/Setting.tsx:182 +#: src/pages/Setting.tsx:194 msgid "Open source dependencies" msgstr "Open source dependencies" -#: src/components/CommonList/CommonList.tsx:383 +#: src/components/CommonList/CommonList.tsx:407 msgid "Play all" msgstr "Play all" @@ -235,7 +240,7 @@ msgstr "Play queue" msgid "Playback rate" msgstr "Playback rate" -#: src/pages/Setting.tsx:107 +#: src/pages/Setting.tsx:109 #: src/pages/LogIn.tsx:24 msgid "Please use Microsoft account authorization to log in" msgstr "Please use Microsoft account authorization to log in" @@ -264,7 +269,7 @@ msgstr "Search" msgid "Select" msgstr "Select" -#: src/pages/Setting.tsx:196 +#: src/pages/Setting.tsx:208 msgid "Select account" msgstr "Select account" @@ -276,7 +281,7 @@ msgstr "Select all" msgid "Setting" msgstr "Setting" -#: src/components/CommonList/ShuffleAll.tsx:24 +#: src/components/CommonList/ShuffleAll.tsx:28 msgid "Shuffle all" msgstr "Shuffle all" @@ -284,7 +289,7 @@ msgstr "Shuffle all" msgid "Sign in" msgstr "登录" -#: src/pages/Setting.tsx:204 +#: src/pages/Setting.tsx:216 msgid "Sign out" msgstr "Sign out" @@ -305,10 +310,10 @@ msgstr "Switch theme" msgid "The playlist will be deleted" msgstr "The playlist will be deleted" -#: src/pages/Setting.tsx:156 +#: src/pages/Setting.tsx:168 msgid "Use album cover theme color" msgstr "Use album cover theme color" -#: src/pages/Setting.tsx:170 +#: src/pages/Setting.tsx:182 msgid "Version" msgstr "Version" diff --git a/src/locales/zh-CN/messages.po b/src/locales/zh-CN/messages.po index 4988ac8..9400be1 100644 --- a/src/locales/zh-CN/messages.po +++ b/src/locales/zh-CN/messages.po @@ -13,15 +13,15 @@ msgstr "" "Language-Team: \n" "Plural-Forms: \n" -#: src/pages/Setting.tsx:161 +#: src/pages/Setting.tsx:173 msgid "About" msgstr "关于" -#: src/pages/Setting.tsx:95 +#: src/pages/Setting.tsx:97 msgid "Account" msgstr "账户" -#: src/pages/Setting.tsx:225 +#: src/pages/Setting.tsx:237 msgid "Add account" msgstr "添加账户" @@ -46,15 +46,15 @@ msgstr "添加到播放列表" msgid "Ascending" msgstr "正序" -#: src/pages/Setting.tsx:137 +#: src/pages/Setting.tsx:149 msgid "Auto" msgstr "自动" -#: src/pages/Setting.tsx:176 +#: src/pages/Setting.tsx:188 msgid "Build time" msgstr "编译日期" -#: src/pages/Setting.tsx:230 +#: src/pages/Setting.tsx:242 #: src/pages/Playlist/Playlist.tsx:217 #: src/pages/Playlist/Playlist.tsx:240 #: src/pages/Player/PlayerMenu.tsx:363 @@ -70,7 +70,8 @@ msgstr "取消选择" msgid "Classic" msgstr "经典" -#: src/pages/Setting.tsx:118 +#: src/pages/Setting.tsx:120 +#: src/pages/Setting.tsx:130 msgid "Clear" msgstr "清除" @@ -80,7 +81,7 @@ msgstr "清除" msgid "Close" msgstr "关闭" -#: src/pages/Setting.tsx:144 +#: src/pages/Setting.tsx:156 msgid "Color mode" msgstr "颜色模式" @@ -92,15 +93,15 @@ msgstr "当前" msgid "Currently using a development version, please be careful with your data!" msgstr "当前正在使用开发版本,请注意数据安全!" -#: src/pages/Setting.tsx:127 +#: src/pages/Setting.tsx:139 msgid "Customize" msgstr "定制" -#: src/pages/Setting.tsx:139 +#: src/pages/Setting.tsx:151 msgid "Dark" msgstr "深色" -#: src/pages/Setting.tsx:114 +#: src/pages/Setting.tsx:116 msgid "Data" msgstr "数据" @@ -149,7 +150,7 @@ msgstr "历史" msgid "Last modified" msgstr "最后修改" -#: src/pages/Setting.tsx:138 +#: src/pages/Setting.tsx:150 msgid "Light" msgstr "浅色" @@ -157,7 +158,11 @@ msgstr "浅色" msgid "List" msgstr "列表" -#: src/pages/Setting.tsx:122 +#: src/pages/Setting.tsx:134 +msgid "Local file index cache" +msgstr "本地文件索引缓存" + +#: src/pages/Setting.tsx:124 msgid "Local metaData cache" msgstr "本地元数据缓存" @@ -165,7 +170,7 @@ msgstr "本地元数据缓存" msgid "Lyrics" msgstr "歌词" -#: src/pages/Setting.tsx:98 +#: src/pages/Setting.tsx:100 msgid "Manage" msgstr "管理" @@ -216,11 +221,11 @@ msgstr "确定" msgid "Open in folder" msgstr "打开所在文件夹" -#: src/pages/Setting.tsx:182 +#: src/pages/Setting.tsx:194 msgid "Open source dependencies" msgstr "开源库" -#: src/components/CommonList/CommonList.tsx:383 +#: src/components/CommonList/CommonList.tsx:407 msgid "Play all" msgstr "全部播放" @@ -235,7 +240,7 @@ msgstr "播放队列" msgid "Playback rate" msgstr "播放速度" -#: src/pages/Setting.tsx:107 +#: src/pages/Setting.tsx:109 #: src/pages/LogIn.tsx:24 msgid "Please use Microsoft account authorization to log in" msgstr "请使用微软账户授权登录" @@ -264,7 +269,7 @@ msgstr "搜索" msgid "Select" msgstr "选择" -#: src/pages/Setting.tsx:196 +#: src/pages/Setting.tsx:208 msgid "Select account" msgstr "选择账户" @@ -276,7 +281,7 @@ msgstr "全选" msgid "Setting" msgstr "设置" -#: src/components/CommonList/ShuffleAll.tsx:24 +#: src/components/CommonList/ShuffleAll.tsx:28 msgid "Shuffle all" msgstr "全部随机播放" @@ -284,7 +289,7 @@ msgstr "全部随机播放" msgid "Sign in" msgstr "登录" -#: src/pages/Setting.tsx:204 +#: src/pages/Setting.tsx:216 msgid "Sign out" msgstr "注销" @@ -305,10 +310,10 @@ msgstr "切换主题" msgid "The playlist will be deleted" msgstr "播放列表将会被删除" -#: src/pages/Setting.tsx:156 +#: src/pages/Setting.tsx:168 msgid "Use album cover theme color" msgstr "使用专辑封面主题色" -#: src/pages/Setting.tsx:170 +#: src/pages/Setting.tsx:182 msgid "Version" msgstr "版本号" diff --git a/src/pages/Files/Files.tsx b/src/pages/Files/Files.tsx index b08c08a..121fe51 100644 --- a/src/pages/Files/Files.tsx +++ b/src/pages/Files/Files.tsx @@ -57,7 +57,7 @@ const Files = () => { const updateAutoPlay = usePlayerStore(state => state.updateAutoPlay) - const { getFilesData } = useFilesData() + const { getFilesData, getDeltaData } = useFilesData() const navigate = useNavigate() const { account } = useUser() @@ -69,6 +69,42 @@ const Files = () => { return remoteItemToFile(res) } + const deltaListFetcher = async () => { + const res: RemoteItem[] = await getDeltaData(account, path) + const deltaListData = remoteItemToFile(res) + const filteredDeltaList = deltaListData.filter((item) => mediaOnly ? item.fileType !== 'other' : true) + const sortedDeltaList = filteredDeltaList.sort((a, b) => { + if (foldersFirst) { + if (a.fileType === 'folder' && b.fileType !== 'folder') { + return -1 + } else if (a.fileType !== 'folder' && b.fileType === 'folder') { + return 1 + } + } + + if (sortBy === 'name') { + if (orderBy === 'asc') { + return (a.fileName).localeCompare(b.fileName) + } else { + return (b.fileName).localeCompare(a.fileName) + } + } else if (sortBy === 'size') { + if (orderBy === 'asc') { + return a.fileSize - b.fileSize + } else { + return b.fileSize - a.fileSize + } + } else if (sortBy === 'datetime' && a.lastModifiedDateTime && b.lastModifiedDateTime) { + if (orderBy === 'asc') { + return new Date(a.lastModifiedDateTime).getTime() - new Date(b.lastModifiedDateTime).getTime() + } else { + return new Date(b.lastModifiedDateTime).getTime() - new Date(a.lastModifiedDateTime).getTime() + } + } else return 0 + }) + return sortedDeltaList + } + const { data: fileListData, error: fileListError, isLoading: fileListIsLoading } = useSWR( `${account.username}/${path}`, @@ -210,7 +246,7 @@ const Files = () => { listData={sortedFileList} listType='files' scrollIndex={scrollIndex} - func={{ open }} + func={{ open, deltaListFetcher }} /> } diff --git a/src/pages/Setting.tsx b/src/pages/Setting.tsx index f1aca86..cfab3fb 100644 --- a/src/pages/Setting.tsx +++ b/src/pages/Setting.tsx @@ -3,6 +3,7 @@ import useUser from '../hooks/graph/useUser' import { t } from '@lingui/macro' import { licenses } from '../data/licenses' import useLocalMetaDataStore from '../store/useLocalMetaDataStore' +import useLocalDeltaDataStore from '../store/useLocalDeltaDataStore' import useUiStore from '@/store/useUiStore' import { UiStatus } from '@/types/ui' import { useState } from 'react' @@ -30,6 +31,7 @@ const Setting = () => { const { accounts, account, login, logout } = useUser() const { clearLocalMetaData } = useLocalMetaDataStore() + const { clearLocalDeltaData } = useLocalDeltaDataStore() const [ currentAccount, @@ -121,6 +123,16 @@ const Setting = () => { > + + clearLocalDeltaData()}> + {t`Clear`} + + } + > + + From bebfaff0310acc55445ac8f575e1f0fc78410711 Mon Sep 17 00:00:00 2001 From: Anlor Date: Mon, 18 Aug 2025 07:15:20 +0000 Subject: [PATCH 5/5] fix: build error --- package-lock.json | 152 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 4 +- 2 files changed, 149 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 39efd4e..af7070e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@mui/icons-material": "7.3.1", "@mui/material": "7.3.1", "@react-spring/web": "10.0.1", + "@swc/core": "^1.13.3", "@tauri-apps/api": "^2.7.0", "@use-gesture/react": "^10.3.1", "buffer": "^6.0.3", @@ -40,7 +41,6 @@ "@lingui/cli": "^5.4.1", "@lingui/swc-plugin": "5.6.0", "@pmmmwh/react-refresh-webpack-plugin": "0.6.1", - "@swc/core": "1.13.3", "@tauri-apps/cli": "^2.7.1", "@types/color": "4.2.0", "@types/extract-colors": "^1.1.4", @@ -2741,7 +2741,8 @@ }, "node_modules/@swc/core": { "version": "1.13.3", - "dev": true, + "resolved": "https://registry.npmmirror.com/@swc/core/-/core-1.13.3.tgz", + "integrity": "sha512-ZaDETVWnm6FE0fc+c2UE8MHYVS3Fe91o5vkmGfgwGXFbxYvAjKSqxM/j4cRc9T7VZNSJjriXq58XkfCp3Y6f+w==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -2776,12 +2777,155 @@ } } }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.13.3", + "resolved": "https://registry.npmmirror.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.3.tgz", + "integrity": "sha512-ux0Ws4pSpBTqbDS9GlVP354MekB1DwYlbxXU3VhnDr4GBcCOimpocx62x7cFJkSpEBF8bmX8+/TTCGKh4PbyXw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.13.3", + "resolved": "https://registry.npmmirror.com/@swc/core-darwin-x64/-/core-darwin-x64-1.13.3.tgz", + "integrity": "sha512-p0X6yhxmNUOMZrbeZ3ZNsPige8lSlSe1llllXvpCLkKKxN/k5vZt1sULoq6Nj4eQ7KeHQVm81/+AwKZyf/e0TA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.13.3", + "resolved": "https://registry.npmmirror.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.3.tgz", + "integrity": "sha512-OmDoiexL2fVWvQTCtoh0xHMyEkZweQAlh4dRyvl8ugqIPEVARSYtaj55TBMUJIP44mSUOJ5tytjzhn2KFxFcBA==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.13.3", + "resolved": "https://registry.npmmirror.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.3.tgz", + "integrity": "sha512-STfKku3QfnuUj6k3g9ld4vwhtgCGYIFQmsGPPgT9MK/dI3Lwnpe5Gs5t1inoUIoGNP8sIOLlBB4HV4MmBjQuhw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.13.3", + "resolved": "https://registry.npmmirror.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.3.tgz", + "integrity": "sha512-bc+CXYlFc1t8pv9yZJGus372ldzOVscBl7encUBlU1m/Sig0+NDJLz6cXXRcFyl6ABNOApWeR4Yl7iUWx6C8og==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.13.3", + "resolved": "https://registry.npmmirror.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.3.tgz", + "integrity": "sha512-dFXoa0TEhohrKcxn/54YKs1iwNeW6tUkHJgXW33H381SvjKFUV53WR231jh1sWVJETjA3vsAwxKwR23s7UCmUA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.13.3", + "resolved": "https://registry.npmmirror.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.3.tgz", + "integrity": "sha512-ieyjisLB+ldexiE/yD8uomaZuZIbTc8tjquYln9Quh5ykOBY7LpJJYBWvWtm1g3pHv6AXlBI8Jay7Fffb6aLfA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.13.3", + "resolved": "https://registry.npmmirror.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.3.tgz", + "integrity": "sha512-elTQpnaX5vESSbhCEgcwXjpMsnUbqqHfEpB7ewpkAsLzKEXZaK67ihSRYAuAx6ewRQTo7DS5iTT6X5aQD3MzMw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.13.3", + "resolved": "https://registry.npmmirror.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.3.tgz", + "integrity": "sha512-nvehQVEOdI1BleJpuUgPLrclJ0TzbEMc+MarXDmmiRFwEUGqj+pnfkTSb7RZyS1puU74IXdK/YhTirHurtbI9w==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@swc/core-win32-x64-msvc": { "version": "1.13.3", "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -2793,12 +2937,10 @@ }, "node_modules/@swc/counter": { "version": "0.1.3", - "dev": true, "license": "Apache-2.0" }, "node_modules/@swc/types": { "version": "0.1.24", - "dev": true, "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" diff --git a/package.json b/package.json index 43c52a3..fae065a 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@mui/icons-material": "7.3.1", "@mui/material": "7.3.1", "@react-spring/web": "10.0.1", + "@swc/core": "^1.13.3", "@tauri-apps/api": "^2.7.0", "@use-gesture/react": "^10.3.1", "buffer": "^6.0.3", @@ -49,7 +50,6 @@ "@lingui/cli": "^5.4.1", "@lingui/swc-plugin": "5.6.0", "@pmmmwh/react-refresh-webpack-plugin": "0.6.1", - "@swc/core": "1.13.3", "@tauri-apps/cli": "^2.7.1", "@types/color": "4.2.0", "@types/extract-colors": "^1.1.4", @@ -83,4 +83,4 @@ "webpack-merge": "6.0.1", "workbox-webpack-plugin": "7.3.0" } -} \ No newline at end of file +}