From 96bcba93bf09a66ebe1963e6a67ca3faab7aab0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=AB=E5=A4=B4=E7=8C=AB?= Date: Sun, 16 Jun 2024 18:13:39 +0800 Subject: [PATCH] feat: recently play&lang --- .vscode/settings.json | 8 +- package.json | 2 +- res/lang/en-US.json | 54 ++++++++---- res/lang/es-ES.json | 54 ++++++++---- res/lang/zh-CN.json | 4 +- res/lang/zh-TW.json | 54 ++++++++---- src/assets/icons/clock.svg | 3 + src/renderer/components/MusicList/index.tsx | 2 + .../components/Body/index.scss | 4 - .../components/Header/index.scss | 5 +- .../components/Header/index.tsx | 30 +++++-- .../components/MusicSheetlikeView/index.tsx | 14 ++- src/renderer/components/SvgAsset/index.tsx | 1 + src/renderer/core/recently-playlist/index.ts | 80 +++++++++++++++++ src/renderer/document/bootstrap.ts | 11 +++ src/renderer/document/index.scss | 2 + src/renderer/document/index.tsx | 2 - .../main-page/components/SideBar/index.tsx | 5 ++ src/renderer/pages/main-page/index.scss | 26 +++--- src/renderer/pages/main-page/index.tsx | 87 +++++++++---------- .../main-page/views/album-view/index.tsx | 14 +-- .../artist-view/components/Body/index.tsx | 22 +++-- .../artist-view/components/Header/index.tsx | 8 +- .../main-page/views/artist-view/index.tsx | 6 +- .../main-page/views/download-view/index.tsx | 5 +- .../views/local-music-view/index.tsx | 3 +- .../views/music-sheet-view/index.tsx | 17 ++-- .../music-sheet-view/local-sheet/index.tsx | 1 + .../views/plugin-manager-view/index.tsx | 5 +- .../views/recently-play-view/index.tsx | 40 +++++++++ .../views/recommend-sheets-view/index.tsx | 72 +++++++-------- .../main-page/views/search-view/index.tsx | 2 +- .../main-page/views/setting-view/index.tsx | 8 +- .../main-page/views/theme-view/index.tsx | 36 ++++---- .../views/toplist-detail-view/index.tsx | 14 +-- .../main-page/views/toplist-view/index.tsx | 12 ++- src/types/user-perference.d.ts | 2 + 37 files changed, 479 insertions(+), 236 deletions(-) create mode 100644 src/assets/icons/clock.svg create mode 100644 src/renderer/core/recently-playlist/index.ts create mode 100644 src/renderer/pages/main-page/views/recently-play-view/index.tsx diff --git a/.vscode/settings.json b/.vscode/settings.json index 23fd35f..2c99ebc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,7 @@ { - "editor.formatOnSave": true -} \ No newline at end of file + "editor.formatOnSave": true, + "files.associations": { + "*.html": "html", + "map": "cpp" + } +} diff --git a/package.json b/package.json index d213882..8e921ec 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "musicfree-desktop", "productName": "MusicFree", - "version": "0.0.3", + "version": "0.0.4", "description": "一个插件化的音乐播放器", "main": ".webpack/main", "scripts": { diff --git a/res/lang/en-US.json b/res/lang/en-US.json index 718e17c..716bcb6 100644 --- a/res/lang/en-US.json +++ b/res/lang/en-US.json @@ -27,7 +27,8 @@ "add": "Add", "save": "Save", "clear": "Clear", - "open": "Open" + "open": "Open", + "status": "Status" }, "media": { @@ -156,7 +157,10 @@ "create_local_sheet": "Create Playlist", "starred_sheets": "Favorites", - "delete_sheet": "Delete Playlist" + "delete_sheet": "Delete", + "rename_sheet": "Rename", + "unstar_sheet": "Unstar", + "recently_play": "Recently Play" }, "app_header": { "nav_back": "Back", @@ -165,7 +169,9 @@ "search_history": "Search History", "settings": "Settings", "minimize": "Minimize", - "exit": "Exit" + "minimode": "Minimode", + "exit": "Exit", + "theme": "Theme" }, "music_bar": { "open_music_detail_page": "Open Song Details", @@ -193,7 +199,10 @@ "link_media_lyric": "Link Lyric", "media_lyric_linked": "Lyric Linked: ", "unlink_media_lyric": "Unlink Lyric", - "toast_media_lyric_unlinked": "Lyric Unlinked" + "toast_media_lyric_unlinked": "Lyric Unlinked", + "translation": "Translation", + "show_translation": "Show Translation", + "hide_translation": "Hide Translation" }, "bottom_loading_state": { "reached_end": "~~~ End ~~~", @@ -232,7 +241,8 @@ }, "music_sheet_like_view": { "play_all": "Play All", - "add_to_sheet": "Add to Playlist" + "add_to_sheet": "Add to Playlist", + "star": "Star" }, "settings": { "choose_path": "Choose Path", @@ -277,7 +287,9 @@ "double_click_music_list": "When double-clicking the music list", "add_music_to_playlist": "Add the selected song to the playback queue", "replace_playlist_with_musiclist": "Replace playback queue with current music list", - "audio_output_device": "Audio output device" + "audio_output_device": "Audio output device", + "when_device_removed": "When device is removed", + "continue_playing": "Continue playing" }, "download": { "download_folder": "Download Directory", @@ -300,18 +312,6 @@ "auto_update_plugin": "Automatically update plugins on startup", "not_check_plugin_version": "Do not check plugin version when installing" }, - "theme": { - "example_theme_hint": "Here are some example themes:", - "example_theme_subscription_hint": "You can also follow the WeChat public account: A Cat-headed Cat, and reply with MusicFree Theme Pack to get the download link (updated periodically)", - "install_theme": "Install Theme Pack", - "uninstall_theme": "Uninstall Theme Pack", - "musicfree_theme": "MusicFree Theme", - "all_files": "All Files", - "install_theme_success": "Installed theme {{name}} successfully~", - "install_theme_fail": "Failed to install theme: {{reason}}", - "uninstall_theme_success": "Uninstalled theme {{name}} successfully~", - "uninstall_theme_fail": "Failed to uninstall theme: {{reason}}" - }, "short_cut": { "enable_local": "Enable in-app shortcuts", "enable_global": "Enable global shortcuts", @@ -373,5 +373,23 @@ "unlock_desktop_lyric": "Unlock Desktop Lyrics", "lock_desktop_lyric": "Lock Desktop Lyrics", "no_playing_music": "No Music Playing" + }, + "theme": { + "tab_local": "Local Theme", + "tab_remote": "Theme Marketplace", + "download_and_use": "Download and Use", + "use_theme": "Use Theme", + "install_theme": "Install Theme", + "update_theme": "Update Theme", + "uninstall_theme": "Uninstall Theme", + "musicfree_theme": "MusicFree Theme", + "all_files": "All Files", + "install_theme_success": "Successfully installed theme {{name}}~", + "install_theme_fail": "Failed to install theme: {{reason}}", + "uninstall_theme_success": "Successfully uninstalled theme {{name}}~", + "uninstall_theme_fail": "Failed to uninstall theme: {{reason}}", + "how_to_submit_new_theme": "💡How to submit a new theme: The themes in the theme marketplace are synchronized with the MusicFreeThemePacks repository. If you need to submit a new theme, please make a pull request directly.", + "load_remote_theme_error": "An error occurred...", + "invalid_theme": "Invalid theme: {{reason}}" } } diff --git a/res/lang/es-ES.json b/res/lang/es-ES.json index a3c2a95..9f74f78 100644 --- a/res/lang/es-ES.json +++ b/res/lang/es-ES.json @@ -27,7 +27,8 @@ "add": "Añadir", "save": "Guardar", "clear": "Limpiar", - "open": "Abrir" + "open": "Abrir", + "status": "Estado" }, "media": { @@ -156,7 +157,10 @@ "create_local_sheet": "Crear lista de canciones", "starred_sheets": "Mis favoritos", - "delete_sheet": "Eliminar lista de canciones" + "delete_sheet": "Eliminar lista de canciones", + "rename_sheet": "Cambiar nombre", + "unstar_sheet": "Desmarcar", + "recently_play": "Reproducido recientemente" }, "app_header": { "nav_back": "Atrás", @@ -165,7 +169,9 @@ "search_history": "Historial de búsqueda", "settings": "Configuración", "minimize": "Minimizar", - "exit": "Salir" + "minimode": "Modo minimalista", + "exit": "Salir", + "theme": "tema" }, "music_bar": { "open_music_detail_page": "Abrir detalles de la canción", @@ -193,7 +199,10 @@ "link_media_lyric": "Vincular letra", "media_lyric_linked": "Letra vinculada: ", "unlink_media_lyric": "Desvincular letra", - "toast_media_lyric_unlinked": "Letra desvinculada" + "toast_media_lyric_unlinked": "Letra desvinculada", + "translation": "Traducción", + "show_translation": "Mostrar traducción", + "hide_translation": "Ocultar traducción" }, "bottom_loading_state": { "reached_end": "~~~ Fin ~~~", @@ -232,7 +241,8 @@ }, "music_sheet_like_view": { "play_all": "Reproducir todo", - "add_to_sheet": "Añadir a la lista de canciones" + "add_to_sheet": "Añadir a la lista de canciones", + "star": "favorito" }, "settings": { "choose_path": "Elegir ruta", @@ -277,7 +287,9 @@ "double_click_music_list": "Al hacer doble clic en la lista de canciones", "add_music_to_playlist": "Añadir canción a la lista de reproducción", "replace_playlist_with_musiclist": "Reemplazar la lista de reproducción con la lista de canciones actual", - "audio_output_device": "Dispositivo de salida de audio" + "audio_output_device": "Dispositivo de salida de audio", + "when_device_removed": "Cuando se elimina el dispositivo de audio", + "continue_playing": "Continuar reproduciendo" }, "download": { "download_folder": "Carpeta de descargas", @@ -300,18 +312,6 @@ "auto_update_plugin": "Actualizar complementos automáticamente al iniciar la aplicación", "not_check_plugin_version": "No verificar la versión al instalar complementos" }, - "theme": { - "example_theme_hint": "Aquí hay algunos temas de ejemplo:", - "example_theme_subscription_hint": "También puedes seguir nuestro WeChat: Una GatoGato, responde con Paquete de temas MusicFree para obtener el enlace de descarga (actualizado periódicamente)", - "install_theme": "Instalar paquete de temas", - "uninstall_theme": "Desinstalar paquete de temas", - "musicfree_theme": "Tema MusicFree", - "all_files": "Todos los archivos", - "install_theme_success": "Tema {{name}} instalado con éxito~", - "install_theme_fail": "Error al instalar el tema: {{reason}}", - "uninstall_theme_success": "Tema {{name}} desinstalado con éxito~", - "uninstall_theme_fail": "Error al desinstalar el tema: {{reason}}" - }, "short_cut": { "enable_local": "Habilitar atajos en la aplicación", "enable_global": "Habilitar atajos globales", @@ -373,5 +373,23 @@ "unlock_desktop_lyric": "Desbloquear letra en pantalla", "lock_desktop_lyric": "Bloquear letra en pantalla", "no_playing_music": "No hay música reproduciéndose actualmente" + }, + "theme": { + "tab_local": "Tema local", + "tab_remote": "Mercado de temas", + "download_and_use": "Descargar y usar", + "use_theme": "Usar tema", + "install_theme": "Instalar tema", + "update_theme": "Actualizar tema", + "uninstall_theme": "Desinstalar tema", + "musicfree_theme": "Tema de MusicFree", + "all_files": "Todos los archivos", + "install_theme_success": "Tema {{name}} instalado con éxito~", + "install_theme_fail": "Error al instalar el tema: {{reason}}", + "uninstall_theme_success": "Tema {{name}} desinstalado con éxito~", + "uninstall_theme_fail": "Error al desinstalar el tema: {{reason}}", + "how_to_submit_new_theme": "💡Cómo enviar un nuevo tema: Los temas en el mercado de temas están sincronizados con el repositorio MusicFreeThemePacks. Si necesita enviar un nuevo tema, envíe una solicitud de extracción directamente.", + "load_remote_theme_error": "Ha ocurrido un error...", + "invalid_theme": "Tema inválido: {{reason}}" } } diff --git a/res/lang/zh-CN.json b/res/lang/zh-CN.json index ce49f6b..bbe73df 100644 --- a/res/lang/zh-CN.json +++ b/res/lang/zh-CN.json @@ -159,7 +159,8 @@ "delete_sheet": "删除歌单", "rename_sheet": "重命名歌单", - "unstar_sheet": "取消收藏" + "unstar_sheet": "取消收藏", + "recently_play": "最近播放" }, "app_header": { "nav_back": "后退", @@ -311,7 +312,6 @@ "auto_update_plugin": "打开软件时自动更新插件", "not_check_plugin_version": "安装插件时不校验版本" }, - "short_cut": { "enable_local": "启用软件内快捷键", "enable_global": "启用全局快捷键", diff --git a/res/lang/zh-TW.json b/res/lang/zh-TW.json index 6d85cc7..ea80fa1 100644 --- a/res/lang/zh-TW.json +++ b/res/lang/zh-TW.json @@ -27,7 +27,8 @@ "add": "新增", "save": "保存", "clear": "清除", - "open": "打開" + "open": "打開", + "status": "狀態" }, "media": { @@ -156,7 +157,10 @@ "create_local_sheet": "創建歌單", "starred_sheets": "我的收藏", - "delete_sheet": "刪除歌單" + "delete_sheet": "刪除歌單", + "rename_sheet": "重歌單", + "unstar_sheet": "取消收藏", + "recently_play": "最近播放" }, "app_header": { "nav_back": "返回", @@ -165,7 +169,9 @@ "search_history": "搜尋歷史", "settings": "設置", "minimize": "最小化", - "exit": "退出" + "minimode": "迷你模式", + "exit": "退出", + "theme": "主題" }, "music_bar": { "open_music_detail_page": "打開歌曲詳情", @@ -193,7 +199,10 @@ "link_media_lyric": "鏈接歌詞", "media_lyric_linked": "已鏈接歌詞:", "unlink_media_lyric": "取消鏈接歌詞", - "toast_media_lyric_unlinked": "已取消鏈接歌詞" + "toast_media_lyric_unlinked": "已取消鏈接歌詞", + "translation": "翻譯", + "show_translation": "顯示翻譯", + "hide_translation": "隱藏翻譯" }, "bottom_loading_state": { "reached_end": "~~~ 沒有更多了 ~~~", @@ -232,7 +241,8 @@ }, "music_sheet_like_view": { "play_all": "播放全部", - "add_to_sheet": "添加到歌單" + "add_to_sheet": "添加到歌單", + "star": "收藏" }, "settings": { "choose_path": "選擇路徑", @@ -277,7 +287,9 @@ "double_click_music_list": "雙擊歌曲列表時", "add_music_to_playlist": "添加歌曲到播放清單", "replace_playlist_with_musiclist": "用當前歌單替換播放清單", - "audio_output_device": "音頻輸出設備" + "audio_output_device": "音頻輸出設備", + "when_device_removed": "當音頻裝置被移除時", + "continue_playing": "繼續播放" }, "download": { "download_folder": "下載文件夾", @@ -300,18 +312,6 @@ "auto_update_plugin": "啟動應用時自動更新插件", "not_check_plugin_version": "安裝插件時不檢查版本" }, - "theme": { - "example_theme_hint": "這裡有一些示例主題:", - "example_theme_subscription_hint": "你也可以關注我們的微信:一隻貓貓,回復 MusicFree 主題包 獲取下載連結(定期更新)", - "install_theme": "安裝主題包", - "uninstall_theme": "卸載主題包", - "musicfree_theme": "MusicFree 主題", - "all_files": "所有文件", - "install_theme_success": "主題 {{name}} 安裝成功~", - "install_theme_fail": "安裝主題失敗:{{reason}}", - "uninstall_theme_success": "主題 {{name}} 卸載成功~", - "uninstall_theme_fail": "卸載主題失敗:{{reason}}" - }, "short_cut": { "enable_local": "啟用應用內快捷鍵", "enable_global": "啟用全局快捷鍵", @@ -373,5 +373,23 @@ "unlock_desktop_lyric": "解鎖桌面歌詞", "lock_desktop_lyric": "鎖定桌面歌詞", "no_playing_music": "目前無正在播放的音樂" + }, + "theme": { + "tab_local": "本地主題", + "tab_remote": "主題市場", + "download_and_use": "下載並使用", + "use_theme": "使用主題", + "install_theme": "安裝主題", + "update_theme": "更新主題", + "uninstall_theme": "卸載主題", + "musicfree_theme": "MusicFree 主題", + "all_files": "全部檔案", + "install_theme_success": "安裝主題{{name}}成功~", + "install_theme_fail": "安裝主題失敗: {{reason}}", + "uninstall_theme_success": "卸載主題{{name}}成功~", + "uninstall_theme_fail": "卸載主題失敗: {{reason}}", + "how_to_submit_new_theme": "💡如何提交新主題: 主題市場中的主題與 MusicFreeThemePacks 倉庫同步,如果需要提交新主題請直接提PR。", + "load_remote_theme_error": "出錯啦...", + "invalid_theme": "主題無效: {{reason}}" } } diff --git a/src/assets/icons/clock.svg b/src/assets/icons/clock.svg new file mode 100644 index 0000000..d9fcd01 --- /dev/null +++ b/src/assets/icons/clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/renderer/components/MusicList/index.tsx b/src/renderer/components/MusicList/index.tsx index d61a55f..d3c4640 100644 --- a/src/renderer/components/MusicList/index.tsx +++ b/src/renderer/components/MusicList/index.tsx @@ -74,6 +74,8 @@ interface IMusicListProps { enableDrag?: boolean; /** 拖拽结束 */ onDragEnd?: (newMusicList: IMusic.IMusicItem[]) => void; + /** context */ + contextMenu?: IContextMenuItem[]; } const columnHelper = createColumnHelper(); diff --git a/src/renderer/components/MusicSheetlikeView/components/Body/index.scss b/src/renderer/components/MusicSheetlikeView/components/Body/index.scss index f3cd687..4a189ea 100644 --- a/src/renderer/components/MusicSheetlikeView/components/Body/index.scss +++ b/src/renderer/components/MusicSheetlikeView/components/Body/index.scss @@ -18,10 +18,6 @@ padding-left: 0.8em; padding-right: 0.8em; - &:not([data-type="primaryButton"]) { - background-color: color-mix(in srgb, currentColor 15%, transparent); - } - & svg { width: 1.3em; height: 1.3em; diff --git a/src/renderer/components/MusicSheetlikeView/components/Header/index.scss b/src/renderer/components/MusicSheetlikeView/components/Header/index.scss index e5a79c6..d34b217 100644 --- a/src/renderer/components/MusicSheetlikeView/components/Header/index.scss +++ b/src/renderer/components/MusicSheetlikeView/components/Header/index.scss @@ -26,11 +26,14 @@ flex: 1; font-size: 1.4rem; font-weight: 600; - margin-left: 8px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; + + &:not(:first-child) { + margin-left: 8px; + } } } diff --git a/src/renderer/components/MusicSheetlikeView/components/Header/index.tsx b/src/renderer/components/MusicSheetlikeView/components/Header/index.tsx index ec8bc4a..0b556bc 100644 --- a/src/renderer/components/MusicSheetlikeView/components/Header/index.tsx +++ b/src/renderer/components/MusicSheetlikeView/components/Header/index.tsx @@ -12,12 +12,13 @@ import { useTranslation } from "react-i18next"; interface IProps { musicSheet: IMusic.IMusicSheetItem; musicList: IMusic.IMusicItem[]; + hidePlatform?: boolean; } export default function Header(props: IProps) { - const { musicSheet, musicList } = props; + const { musicSheet, musicList, hidePlatform } = props; const containerRef = useRef(); - const {t} = useTranslation(); + const { t } = useTranslation(); return (
@@ -28,28 +29,39 @@ export default function Header(props: IProps) { >
- + {musicSheet?.platform && !hidePlatform ? ( {musicSheet?.platform} - -
{musicSheet?.title ?? t("media.unknown_title")}
+ ) : null} + +
+ {musicSheet?.title ?? t("media.unknown_title")} +
- {t("media.media_create_at")}: {dayjs(musicSheet?.createAt).format("YYYY-MM-DD")} + {t("media.media_create_at")}:{" "} + {dayjs(musicSheet?.createAt).format("YYYY-MM-DD")} - {t("media.media_type_artist")}: {musicSheet?.artist} + + {t("media.media_type_artist")}: {musicSheet?.artist} +
- {t("media.media_play_count")}: {musicSheet?.playCount} + + {t("media.media_play_count")}: {musicSheet?.playCount} + - {t("media.media_music_count")}: {musicSheet?.worksNum ?? musicList?.length ?? 0} + + {t("media.media_music_count")}:{" "} + {musicSheet?.worksNum ?? musicList?.length ?? 0} +
diff --git a/src/renderer/components/MusicSheetlikeView/index.tsx b/src/renderer/components/MusicSheetlikeView/index.tsx index d6dcc60..bdd6471 100644 --- a/src/renderer/components/MusicSheetlikeView/index.tsx +++ b/src/renderer/components/MusicSheetlikeView/index.tsx @@ -1,10 +1,9 @@ +import { ReactNode, useEffect } from "react"; import { RequestStateCode } from "@/common/constant"; import Body from "./components/Body"; import Header from "./components/Header"; - -import "./index.scss"; -import { ReactNode, useEffect } from "react"; import { initValue, offsetHeightStore } from "./store"; +import "./index.scss"; interface IMusicSheetlikeViewProps { scrollElement?: HTMLElement; @@ -13,6 +12,8 @@ interface IMusicSheetlikeViewProps { state?: RequestStateCode; onLoadMore?: () => void; options?: ReactNode; + /** 是否展示来源tag */ + hidePlatform?: boolean; } export default function MusicSheetlikeView(props: IMusicSheetlikeViewProps) { @@ -22,6 +23,7 @@ export default function MusicSheetlikeView(props: IMusicSheetlikeViewProps) { state = RequestStateCode.IDLE, onLoadMore, options, + hidePlatform, } = props; useEffect(() => { @@ -32,7 +34,11 @@ export default function MusicSheetlikeView(props: IMusicSheetlikeViewProps) { return (
-
+
([]); + +const immer = new Immer({ + autoFreeze: false, +}); + +const HARD_LIMIT = 500; + +async function fetchRecentlyPlaylist() { + return (await getUserPreferenceIDB("recentlyPlayList")) || []; +} + +async function setRecentlyPlaylist(musicItems: IMusic.IMusicItem[]) { + recentlyPlayListStore.setValue(musicItems); + return await setUserPreferenceIDB("recentlyPlayList", musicItems); +} + +export async function setupRecentlyPlaylist() { + const playList = await fetchRecentlyPlaylist(); + recentlyPlayListStore.setValue(playList); +} + +export async function addToRecentlyPlaylist(musicItem: IMusic.IMusicItem) { + const playList = recentlyPlayListStore.getValue(); + const existId = playList.findIndex((it) => isSameMedia(musicItem, it)); + let newPlayList = playList; + + if (existId !== -1) { + newPlayList = immer.produce(playList, (draft) => { + draft.splice(existId, 1); + }); + } + newPlayList = [musicItem].concat(newPlayList).slice(0, HARD_LIMIT); + setRecentlyPlaylist(newPlayList); +} + +export async function removeRecentlyPlayList(musicItem: IMusic.IMusicItem) { + const playList = recentlyPlayListStore.getValue(); + const existId = playList.findIndex((it) => isSameMedia(musicItem, it)); + let newPlayList = playList; + + if (existId !== -1) { + newPlayList = immer.produce(playList, (draft) => { + draft.splice(existId, 1); + }); + setRecentlyPlaylist(newPlayList); + } +} + +export async function clearRecentlyPlaylist() { + setRecentlyPlaylist([]); +} + +export function useRecentlyPlaylistSheet() { + const recentlyPlayList = recentlyPlayListStore.useValue(); + const { t } = useTranslation(); + + const musicSheet: IMusic.IMusicSheetItem = useMemo(() => { + return { + id: "recently-play", + title: t("side_bar.recently_play"), + platform: "recently-play", + playCount: recentlyPlayList?.length || 0, + artwork: recentlyPlayList?.[0]?.artwork, + musicList: recentlyPlayList || [], + }; + }, [recentlyPlayList, t]); + + return musicSheet; +} diff --git a/src/renderer/document/bootstrap.ts b/src/renderer/document/bootstrap.ts index 9904b29..a7f6ae4 100644 --- a/src/renderer/document/bootstrap.ts +++ b/src/renderer/document/bootstrap.ts @@ -23,6 +23,11 @@ import { setupPlayerSyncHandler, } from "../core/command-handler"; import ThemePack from "@/shared/themepack/renderer"; +import { + addToRecentlyPlaylist, + setupRecentlyPlaylist, +} from "../core/recently-playlist"; +import { TrackPlayerEvent } from "../core/track-player/enum"; setAutoFreeze(false); @@ -43,6 +48,7 @@ export default async function () { setupDeviceChange(); localMusic.setupLocalMusic(); await Downloader.setupDownloader(); + setupRecentlyPlaylist(); // 自动更新插件 if (getAppConfigPath("plugin.autoUpdatePlugin")) { @@ -152,6 +158,11 @@ function setupEvents() { MusicSheet.frontend.addMusicToFavorite(realItem); } }); + + // 最近播放 + trackPlayer.on(TrackPlayerEvent.MusicChanged, (musicItem) => { + addToRecentlyPlaylist(musicItem); + }); } async function setupDeviceChange() { diff --git a/src/renderer/document/index.scss b/src/renderer/document/index.scss index f0ea6b6..377843e 100644 --- a/src/renderer/document/index.scss +++ b/src/renderer/document/index.scss @@ -87,6 +87,7 @@ input { } } +// 按钮样式 div[role="button"] { cursor: pointer; user-select: none; @@ -114,6 +115,7 @@ div[role="button"] { border: 1px solid currentColor; width: fit-content; line-height: 1em; + background-color: color-mix(in srgb, currentColor 15%, transparent); } &[data-type="dangerButton"] { diff --git a/src/renderer/document/index.tsx b/src/renderer/document/index.tsx index 602a2e9..2982e35 100644 --- a/src/renderer/document/index.tsx +++ b/src/renderer/document/index.tsx @@ -8,7 +8,6 @@ import MainPage from "../pages/main-page"; import { ContextMenuComponent } from "../components/ContextMenu"; import { ToastContainer } from "react-toastify"; - import "rc-slider/assets/index.css"; import "react-toastify/dist/ReactToastify.css"; import "./index.css"; // 全局样式 @@ -48,7 +47,6 @@ function Root() { } function BootstrapComponent(): null { - useBootstrap(); return null; diff --git a/src/renderer/pages/main-page/components/SideBar/index.tsx b/src/renderer/pages/main-page/components/SideBar/index.tsx index 12edae5..23c1cd4 100644 --- a/src/renderer/pages/main-page/components/SideBar/index.tsx +++ b/src/renderer/pages/main-page/components/SideBar/index.tsx @@ -36,6 +36,11 @@ export default function () { title: t("side_bar.plugin_management"), route: "plugin-manager-view", }, + { + iconName: "clock", + title: t("side_bar.recently_play"), + route: "recently_play", + }, ] as const; return ( diff --git a/src/renderer/pages/main-page/index.scss b/src/renderer/pages/main-page/index.scss index 66d45ac..bd446ae 100644 --- a/src/renderer/pages/main-page/index.scss +++ b/src/renderer/pages/main-page/index.scss @@ -1,14 +1,20 @@ .page-container { - flex: auto; - overflow-y: auto; - overflow-x: hidden; - width: 100%; - padding-left: 1.5rem; - padding-right: 1.5rem; - position: relative; + flex: auto; + overflow-y: auto; + overflow-x: hidden; + width: 100%; + padding-left: 1.5rem; + padding-right: 1.5rem; + position: relative; } .page-container-full-width { - padding-left: 0; - padding-right: 0; -} \ No newline at end of file + padding-left: 0; + padding-right: 0; +} + +.page-container-fw { + @extend .page-container; + padding-left: 0; + padding-right: 0; +} diff --git a/src/renderer/pages/main-page/index.tsx b/src/renderer/pages/main-page/index.tsx index 4589b93..80c4e4f 100644 --- a/src/renderer/pages/main-page/index.tsx +++ b/src/renderer/pages/main-page/index.tsx @@ -13,58 +13,55 @@ import SettingView from "./views/setting-view"; import LocalMusicView from "./views/local-music-view"; import Empty from "@/renderer/components/Empty"; import DownloadView from "./views/download-view"; +import ThemeView from "./views/theme-view"; +import RecentlyPlayView from "./views/recently-play-view"; import "./index.scss"; -import ThemeView from "./views/theme-view"; export default function MainPage() { return ( <> -
- - } - > - } - > - } - > - } - > - } - > - }> - } - > - } - > - } - > - } - > - }> - }> - }> - -
+ + }> + } + > + } + > + } + > + } + > + }> + } + > + } + > + } + > + }> + }> + }> + } + > + }> + ); diff --git a/src/renderer/pages/main-page/views/album-view/index.tsx b/src/renderer/pages/main-page/views/album-view/index.tsx index 22b2fe7..6319c28 100644 --- a/src/renderer/pages/main-page/views/album-view/index.tsx +++ b/src/renderer/pages/main-page/views/album-view/index.tsx @@ -20,11 +20,13 @@ export default function AlbumView() { useAlbumDetail(originalAlbumItem); return ( - +
+ +
); } diff --git a/src/renderer/pages/main-page/views/artist-view/components/Body/index.tsx b/src/renderer/pages/main-page/views/artist-view/components/Body/index.tsx index 336103b..2a44d79 100644 --- a/src/renderer/pages/main-page/views/artist-view/components/Body/index.tsx +++ b/src/renderer/pages/main-page/views/artist-view/components/Body/index.tsx @@ -12,11 +12,9 @@ interface IBodyProps { const supportedMediaType = ["music", "album"]; export default function Body(props: IBodyProps) { - const {artistItem} = props; + const { artistItem } = props; const [currentMediaType, setCurrentMediaType] = useState("music"); const { t } = useTranslation(); - - return (
@@ -28,21 +26,21 @@ export default function Body(props: IBodyProps) { {supportedMediaType.map((type) => ( - {t(type)} + {t(`media.media_type_${type}`)} ))} {supportedMediaType.map((type) => ( - - - - - - - - + + + + + + + + ))} diff --git a/src/renderer/pages/main-page/views/artist-view/components/Header/index.tsx b/src/renderer/pages/main-page/views/artist-view/components/Header/index.tsx index 0ed0cbf..cea64d2 100644 --- a/src/renderer/pages/main-page/views/artist-view/components/Header/index.tsx +++ b/src/renderer/pages/main-page/views/artist-view/components/Header/index.tsx @@ -11,7 +11,7 @@ interface IProps { export default function Header(props: IProps) { const { artistItem } = props; - const {t} = useTranslation(); + const { t } = useTranslation(); return (
@@ -23,7 +23,9 @@ export default function Header(props: IProps) {
{artistItem?.platform} -
{artistItem?.name ?? t("media.unknown_artist")}
+
+ {artistItem?.name ?? t("media.unknown_artist")} +
@@ -35,7 +37,7 @@ export default function Header(props: IProps) { dataset.fold = dataset.fold === "true" ? "false" : "true"; }} > - 简介:{artistItem?.description} + {artistItem?.description}
diff --git a/src/renderer/pages/main-page/views/artist-view/index.tsx b/src/renderer/pages/main-page/views/artist-view/index.tsx index 8f129f0..7ba8265 100644 --- a/src/renderer/pages/main-page/views/artist-view/index.tsx +++ b/src/renderer/pages/main-page/views/artist-view/index.tsx @@ -22,12 +22,12 @@ export default function ArtistView() { return () => { queryResultStore.setValue(initQueryResult); }; - }) + }); return ( -
+
- +
); } diff --git a/src/renderer/pages/main-page/views/download-view/index.tsx b/src/renderer/pages/main-page/views/download-view/index.tsx index bb57a3b..57944f2 100644 --- a/src/renderer/pages/main-page/views/download-view/index.tsx +++ b/src/renderer/pages/main-page/views/download-view/index.tsx @@ -8,7 +8,10 @@ export default function DownloadView() { const { t } = useTranslation(); return ( -
+
diff --git a/src/renderer/pages/main-page/views/local-music-view/index.tsx b/src/renderer/pages/main-page/views/local-music-view/index.tsx index 9acc3a4..55de1b7 100644 --- a/src/renderer/pages/main-page/views/local-music-view/index.tsx +++ b/src/renderer/pages/main-page/views/local-music-view/index.tsx @@ -74,7 +74,8 @@ export default function LocalMusicView() { return (
{t("local_music_page.local_music")}
diff --git a/src/renderer/pages/main-page/views/music-sheet-view/index.tsx b/src/renderer/pages/main-page/views/music-sheet-view/index.tsx index 076e6ec..7172f9f 100644 --- a/src/renderer/pages/main-page/views/music-sheet-view/index.tsx +++ b/src/renderer/pages/main-page/views/music-sheet-view/index.tsx @@ -1,10 +1,10 @@ import { useParams } from "react-router-dom"; -import "./index.scss"; -import Condition from "@/renderer/components/Condition"; import { localPluginName } from "@/common/constant"; import LocalSheet from "./local-sheet"; import RemoteSheet from "./remote-sheet"; +import "./index.scss"; + /** * path: /main/musicsheet/platform/id * @@ -17,11 +17,12 @@ export default function MusicSheetView() { const { platform } = useParams() ?? {}; return ( - } - > - - +
+ {platform === localPluginName ? ( + + ) : ( + + )} +
); } diff --git a/src/renderer/pages/main-page/views/music-sheet-view/local-sheet/index.tsx b/src/renderer/pages/main-page/views/music-sheet-view/local-sheet/index.tsx index c4cf5f4..1bf767e 100644 --- a/src/renderer/pages/main-page/views/music-sheet-view/local-sheet/index.tsx +++ b/src/renderer/pages/main-page/views/music-sheet-view/local-sheet/index.tsx @@ -19,6 +19,7 @@ export default function LocalSheet() { return ( +
{t("plugin_management_page.plugin_management")}
diff --git a/src/renderer/pages/main-page/views/recently-play-view/index.tsx b/src/renderer/pages/main-page/views/recently-play-view/index.tsx new file mode 100644 index 0000000..346eac5 --- /dev/null +++ b/src/renderer/pages/main-page/views/recently-play-view/index.tsx @@ -0,0 +1,40 @@ +import MusicSheetlikeView from "@/renderer/components/MusicSheetlikeView"; +import SvgAsset from "@/renderer/components/SvgAsset"; +import { + clearRecentlyPlaylist, + useRecentlyPlaylistSheet, +} from "@/renderer/core/recently-playlist"; +import { useTranslation } from "react-i18next"; + +export default function RecentlyPlayView() { + const recentlyPlaylistSheet = useRecentlyPlaylistSheet(); + const { t } = useTranslation(); + + const options = ( + <> +
{ + clearRecentlyPlaylist(); + }} + > + + {t("common.clear")} +
+ + ); + + return ( +
+ +
+ ); +} diff --git a/src/renderer/pages/main-page/views/recommend-sheets-view/index.tsx b/src/renderer/pages/main-page/views/recommend-sheets-view/index.tsx index 41c3dd4..3b37137 100644 --- a/src/renderer/pages/main-page/views/recommend-sheets-view/index.tsx +++ b/src/renderer/pages/main-page/views/recommend-sheets-view/index.tsx @@ -10,41 +10,43 @@ export default function RecommendSheetsView() { const navigate = useNavigate(); return ( - } - > - { - const usr = history.state.usr ?? {}; - - navigate("", { - replace: true, - state: { - ...usr, - pluginHash: availablePlugins[index].hash, - pluginIndex: index, - tag: null - }, - }); - }} +
+ } > - - {availablePlugins.map((plugin) => ( - - {plugin.platform} - - ))} - - - {availablePlugins.map((plugin) => ( - - - - ))} - - - + { + const usr = history.state.usr ?? {}; + + navigate("", { + replace: true, + state: { + ...usr, + pluginHash: availablePlugins[index].hash, + pluginIndex: index, + tag: null, + }, + }); + }} + > + + {availablePlugins.map((plugin) => ( + + {plugin.platform} + + ))} + + + {availablePlugins.map((plugin) => ( + + + + ))} + + + +
); } diff --git a/src/renderer/pages/main-page/views/search-view/index.tsx b/src/renderer/pages/main-page/views/search-view/index.tsx index 2be3b02..f79f7d9 100644 --- a/src/renderer/pages/main-page/views/search-view/index.tsx +++ b/src/renderer/pages/main-page/views/search-view/index.tsx @@ -39,7 +39,7 @@ export default function SearchView() { }, []); return ( -
+
「{decodeURIComponent(query)}」 {t("search_result_page.search_result_title")} diff --git a/src/renderer/pages/main-page/views/setting-view/index.tsx b/src/renderer/pages/main-page/views/setting-view/index.tsx index 17d8a0c..4a649ad 100644 --- a/src/renderer/pages/main-page/views/setting-view/index.tsx +++ b/src/renderer/pages/main-page/views/setting-view/index.tsx @@ -18,9 +18,6 @@ export default function SettingView() { const intersectionRatioRef = useRef>(new Map()); useEffect(() => { - document - .getElementById("page-container") - ?.classList?.add("page-container-full-width"); intersectionObserverRef.current = new IntersectionObserver( (targets) => { const ratio = intersectionRatioRef.current; @@ -62,7 +59,10 @@ export default function SettingView() { }, []); return ( -
+
{routers.map((setting) => ( diff --git a/src/renderer/pages/main-page/views/theme-view/index.tsx b/src/renderer/pages/main-page/views/theme-view/index.tsx index 1af76b0..4a8b533 100644 --- a/src/renderer/pages/main-page/views/theme-view/index.tsx +++ b/src/renderer/pages/main-page/views/theme-view/index.tsx @@ -10,22 +10,24 @@ export default function ThemeView() { const { t } = useTranslation(); return ( - - - {routes.map((it) => ( - - {t(`theme.tab_${it}`)} - - ))} - - - - - - - - - - +
+ + + {routes.map((it) => ( + + {t(`theme.tab_${it}`)} + + ))} + + + + + + + + + + +
); } diff --git a/src/renderer/pages/main-page/views/toplist-detail-view/index.tsx b/src/renderer/pages/main-page/views/toplist-detail-view/index.tsx index b8f42b7..b8933b8 100644 --- a/src/renderer/pages/main-page/views/toplist-detail-view/index.tsx +++ b/src/renderer/pages/main-page/views/toplist-detail-view/index.tsx @@ -10,11 +10,13 @@ export default function TopListDetailView() { ); return ( - +
+ +
); } diff --git a/src/renderer/pages/main-page/views/toplist-view/index.tsx b/src/renderer/pages/main-page/views/toplist-view/index.tsx index 5cfcce3..17048f0 100644 --- a/src/renderer/pages/main-page/views/toplist-view/index.tsx +++ b/src/renderer/pages/main-page/views/toplist-view/index.tsx @@ -14,17 +14,21 @@ import { useTranslation } from "react-i18next"; import "./index.scss"; - export default function ToplistView() { const availablePlugins = getSortedSupportedPlugin("getTopLists"); const navigate = useNavigate(); - const {t} = useTranslation(); + const { t } = useTranslation(); return ( -
+
} + falsy={ + + } >