diff --git a/src/i18n/hu_HU.json b/src/i18n/hu_HU.json index 814ab20e..f1c47c8b 100644 --- a/src/i18n/hu_HU.json +++ b/src/i18n/hu_HU.json @@ -73,7 +73,6 @@ "term.viewAs": "Megjelenítés", "term.viewAs.coverArt": "Borító", "term.viewAs.list": "Lista", - "term.dynamic": "Dinamikus", "term.size": "Méret", "term.size.normal": "Normál", "term.size.compact": "Kompakt", diff --git a/src/i18n/zh_HK.json b/src/i18n/zh_HK.json index 64f05a03..3717198f 100644 --- a/src/i18n/zh_HK.json +++ b/src/i18n/zh_HK.json @@ -115,7 +115,7 @@ "term.contributors": "貢獻者", "term.equalizer": "均衡器", "term.reset": "重設", - "term.tracks": "首歌曲", + "term.tracks": "歌曲", "term.videos": "MV", "term.menu": "選項", "term.check": "檢查", @@ -225,6 +225,10 @@ "settings.option.general.resumebehavior.locally.description": "Cider 將還原你在這台電腦上的最後一次操作。", "settings.option.general.resumebehavior.history": "歷史", "settings.option.general.resumebehavior.history.description": "Cider 將跨裝置將你的整個 Apple Music 歷史記錄中的最後一首歌曲排隊入列。", + "settings.option.general.resumetabs" : "啟動時打開的選項", + "settings.option.general.resumetabs.description" : "你可以選擇啟動 Cider 時要打開的選項。", + "settings.option.general.resumetabs.dynamic" : "動態", + "settings.option.general.resumetabs.dynamic.description" : "Cider 將打開你上次停留的選項。", "settings.option.general.language": "語言", "settings.option.general.language.main": "語言", "settings.option.general.language.fun": "惡搞語言", @@ -236,6 +240,8 @@ "settings.option.general.updateCider.branch.develop": "測試", "settings.option.general.customizeSidebar": "自訂側邊欄的功能", "settings.option.general.customizeSidebar.customize": "自訂", + "settings.option.general.keybindings": "快捷操作鍵", + "settings.option.general.keybindings.open": "開啟", "settings.notyf.updateCider.update-not-available": "沒有可用的更新", "settings.notyf.updateCider.update-downloaded": "更新已成功下載,重啟後進行更新", "settings.notyf.updateCider.update-error": "更新時,發生錯誤", @@ -281,6 +287,7 @@ "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.standard": "標準", "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.audiophile": "發燒友", "settings.warn.audio.enableAdvancedFunctionality.audioSpatialization.compatibility": "空間音訊無法與 CAP 相容,請關閉 CAP 再進行操作。", + "settings.option.visual.uiscale": "介面顯示大小", "settings.header.visual": "外觀", "settings.header.visual.description": "調整 Cider 的外觀", "settings.option.visual.windowBackgroundStyle": "視窗背景樣式", @@ -335,14 +342,18 @@ "settings.option.lyrics.enableMusixmatchKaraoke": "開啟卡拉OK模式(僅限Musixmatch)", "settings.option.lyrics.musixmatchPreferredLanguage": "Musixmatch 歌詞語言偏好", "settings.option.lyrics.enableYoutubeLyrics": "播放 MV 時,使用 YouTube 歌詞", + "settings.option.lyrics.enableQQLyrics": "開啟 QQ 音樂的歌詞", "settings.header.connectivity": "外部連結", "settings.header.connectivity.description": "調整 Cider 與外部的連結", "settings.option.connectivity.discordRPC": "Discord 狀態", "settings.option.connectivity.playbackNotifications": "播放通知", + "settings.option.connectivity.discordRPC.clientName": "應用程式名稱", "settings.header.connectivity.discordRPC.cider": "顯示為'Cider'", "settings.header.connectivity.discordRPC.appleMusic": "顯示為'Apple Music'", "settings.option.connectivity.discordRPC.clearOnPause": "暫停時清除 Discord 狀態", "settings.option.connectivity.discordRPC.hideButtons": "隱藏 Discord 狀態上的按鈕", + "settings.option.connectivity.discordRPC.detailsFormat": "詳細資訊格式", + "settings.option.connectivity.discordRPC.stateFormat": "狀態格式", "settings.option.connectivity.lastfmScrobble": "Last.fm Scrobbling 記錄", "settings.option.connectivity.lastfmScrobble.delay": "Last.fm Scrobble 延遲 (%)", "settings.option.connectivity.lastfmScrobble.nowPlaying": "開啟 Last.fm 正在播放", @@ -366,6 +377,9 @@ "settings.option.visual.transparent": "透明視窗框架", "settings.option.visual.transparent.description": "需主題有支援透明框架,且須重新啟動才會套用。", "settings.header.advanced": "進階", + "settings.header.connect": "同步", + "settings.option.connect.link_account": "開啟與 Cider Connect 同步", + "settings.option.connect.link_account.description": "將您的 Discord 帳戶與 Cider Connect 連接後,你可以儲存使用者資料,包括設定、等化器,並最終在完成後儲存更多資料。(正在進行中)", "spatial.notTurnedOn": "請先在設定中開啟空間音訊。", "spatial.spatialProperties": "空間音訊屬性", "spatial.width": "闊度", diff --git a/src/renderer/less/directives.less b/src/renderer/less/directives.less index 22f839ea..5c9253da 100644 --- a/src/renderer/less/directives.less +++ b/src/renderer/less/directives.less @@ -16,6 +16,7 @@ height: var(--chromeHeight1); &.chrome-bottom { + -webkit-app-region: no-drag; height : var(--chromeHeight2); box-shadow: 0px -1px 0px rgba(0, 0, 0, 0.25); z-index : 1; @@ -30,6 +31,7 @@ .app-playback-controls .actions { align-self: center; } + -webkit-app-region: no-drag; .playback-button.play, .playback-button.pause { @@ -120,8 +122,9 @@ width : 30%; justify-content: flex-start; align-items : flex-start; - + -webkit-app-region: no-drag!important; .playback-controls { + -webkit-app-region: no-drag!important; .artwork { width : var(--chromeHeight2); height : var(--chromeHeight2); diff --git a/src/renderer/main/vueapp.js b/src/renderer/main/vueapp.js index bcc7dfce..58b49752 100644 --- a/src/renderer/main/vueapp.js +++ b/src/renderer/main/vueapp.js @@ -234,7 +234,7 @@ const app = new Vue({ watch: { cfg: { handler: function (val, oldVal) { - console.log(`cfg changed from ${oldVal} to ${val}`); + console.debug(`cfg changed from ${oldVal} to ${val}`); ipcRenderer.send("setStore", val); }, deep: true @@ -254,6 +254,12 @@ const app = new Vue({ app.resetState() } }, + mounted() { + window.addEventListener("hashchange", function (event) { + let currentPath = window.location.hash.slice(1); + console.debug("hashchange", currentPath); + }, false) + }, methods: { setTimeout(func, time) { return setTimeout(func, time); @@ -268,10 +274,10 @@ const app = new Vue({ if (httpRequest.readyState === 4) { if (httpRequest.status === 200) { let response = JSON.parse(httpRequest.responseText); - console.log(response); + console.debug(response); self.copyToClipboard(response.pageUrl) } else { - console.log('There was a problem with the request.'); + console.warn('There was a problem with the request.'); notyf.error(app.getLz('term.requestError')) } } @@ -940,7 +946,7 @@ const app = new Vue({ }) }, async setTheme(theme = "", onlyPrefs = false) { - console.log(theme) + console.debug(theme) if (this.cfg.visual.theme == "") { this.cfg.visual.theme = "default.less" } @@ -1121,15 +1127,15 @@ const app = new Vue({ const cachedTrackMapping = await CiderCache.getCache("library-playlists-tracks") if (cachedPlaylist) { - console.log("using cached playlists") + console.debug("using cached playlists") this.playlists.listing = cachedPlaylist self.sortPlaylists() } else { - console.log("playlist has no cache") + console.debug("playlist has no cache") } if (cachedTrackMapping) { - console.log("using cached track mapping") + console.debug("using cached track mapping") this.playlists.trackMapping = cachedTrackMapping } if (localOnly) { @@ -1140,7 +1146,7 @@ const app = new Vue({ this.library.backgroundNotification.show = true async function deepScan(parent = "p.playlistsroot") { - console.log(`scanning ${parent}`) + console.debug(`scanning ${parent}`) const playlistData = await app.mk.api.v3.music(`/v1/me/library/playlist-folders/${parent}/children/`) await asyncForEach(playlistData.data.data, async (playlist) => { playlist.parent = parent @@ -1259,7 +1265,7 @@ const app = new Vue({ // this.darwinShare(str) // } else { notyf.success(app.getLz('term.share.success')) - navigator.clipboard.writeText(str).then(r => console.log("Copied to clipboard.")) + navigator.clipboard.writeText(str).then(r => console.debug("Copied to clipboard.")) // } }, newPlaylist(name = app.getLz('term.newPlaylist'), tracks = []) { @@ -1282,7 +1288,7 @@ const app = new Vue({ } }).then(res => { res = res.data.data[0] - console.log(res) + console.debug(res) self.appRoute(`playlist_` + res.id); self.showingPlaylist = []; self.getPlaylistFromID(app.page.substring(9), true) @@ -1317,7 +1323,7 @@ const app = new Vue({ }, async showCollection(response, title, type, requestBody = {}) { let self = this - console.log(response) + console.debug(response) this.collectionList.requestBody = {} this.collectionList.response = response this.collectionList.title = title @@ -1327,7 +1333,7 @@ const app = new Vue({ }, async showArtistView(artist, title, view) { let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artist}/view/${view}?l=${this.mklang}`, {}, { includeResponseMeta: !0 })).data - console.log(response) + console.debug(response) await this.showCollection(response, title, "artists") }, async showRecordLabelView(label, title, view) { @@ -1367,7 +1373,7 @@ const app = new Vue({ includeResponseMeta: !0 }) - console.log('searchres', response) + console.debug('searchres', response) let responseFormat = { data: response.data.results[group].data, next: response.data.results[group].next, @@ -1421,13 +1427,13 @@ const app = new Vue({ app.mk.api.v3.music(`/v1/me/library/playlists/${id}`, params).then(res => { self.getPlaylistContinuous(res, transient) }).catch((e) => { - console.log(e); + console.debug(e); try { app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`, params).then(res => { self.getPlaylistContinuous(res, transient) }) } catch (err) { - console.log(err) + console.debug(err) } }) @@ -1444,7 +1450,7 @@ const app = new Vue({ "art[url]": "f", l: this.mklang }, { includeResponseMeta: !0 }) - console.log(artistData.data.data[0]) + console.debug(artistData.data.data[0]) this.artistPage.data = artistData.data.data[0] this.page = "artist-page" }, @@ -1479,12 +1485,12 @@ const app = new Vue({ "meta": {} } if (response.next) { - console.log("has next") + console.debug("has next") returnData.data.concat(response.data) returnData.meta = response.meta return await this.getRecursive(await response.next()) } else { - console.log("no next") + console.debug("no next") returnData.data.concat(response.data) return returnData } @@ -1573,7 +1579,7 @@ const app = new Vue({ } route = route.replace(/#/g, "") if (app.cfg.general.resumeTabs.tab == "dynamic") { - if (route == "home" || route == "library-songs" || route == "library-albums" || route == "library-artists" || route == "library-videos" || route == "podcasts") { + if (route == "home" || route == "listen_now" || route == "browse" || route == "radio" || route == "library-songs" || route == "library-albums" || route == "library-artists" || route == "library-videos" || route == "podcasts") { app.cfg.general.resumeTabs.dynamicData = route } else { app.cfg.general.resumeTabs.dynamicData = "home" @@ -1624,7 +1630,7 @@ const app = new Vue({ window.location.hash = `${kind}/${id}` document.querySelector("#app-content").scrollTop = 0 } else if (kind == "editorial-elements") { - console.log(item) + console.debug(item) if (item.relationships?.contents?.data != null && item.relationships?.contents?.data.length > 0) { this.routeView(item.relationships.contents.data[0]) } else if (item.attributes?.link?.url != null) { @@ -1665,28 +1671,16 @@ const app = new Vue({ params["meta[albums:tracks]"] = 'popularity' params["fields[albums]"] = "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialNotes,editorialVideo,name,playParams,releaseDate,url,copyright" } - - // if (this.cfg.advanced.experiments.includes('inline-playlists')) { - if (false) { - let showModal = kind.toString().includes("album") || kind.toString().includes("playlist") - if (app.page.includes("playlist") || app.page.includes("album")) { - showModal = false - } - if (showModal) { - app.modals.showPlaylist = true - app.chrome.contentAreaScrolling = false - } else { - app.page = (kind) + "_" + (id); - window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` - } - } else { + if(kind.includes("playlist") || kind.includes("album")){ app.page = (kind) + "_" + (id); window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` + app.getTypeFromID((kind), (id), (isLibrary), params); + }else{ + app.page = (kind) + window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` } - - app.getTypeFromID((kind), (id), (isLibrary), params); - // document.querySelector("#app-content").scrollTop = 0 + // app.getTypeFromID((kind), (id), (isLibrary), params); } else { app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '') } @@ -1752,12 +1746,12 @@ const app = new Vue({ try { if (artistQuery.artists.data.length > 0) { artistId = artistQuery.artists.data[0].id; - console.log(artistId) + console.debug(artistId) } } catch (e) { } } - console.log(artistId); + console.debug(artistId); if (artistId != "") self.appRoute(`artist/${artistId}`) break; @@ -1789,7 +1783,7 @@ const app = new Vue({ })).data.results; if (albumQuery.albums.data.length > 0) { albumId = albumQuery.albums.data[0].id; - console.log(albumId) + console.debug(albumId) } } catch (e) { } @@ -1813,7 +1807,7 @@ const app = new Vue({ })).data.results; if (labelQuery["record-labels"].data.length > 0) { labelId = labelQuery["record-labels"].data[0].id; - console.log(labelId) + console.debug(labelId) } } catch (e) { } @@ -1846,7 +1840,7 @@ const app = new Vue({ } }, followingArtist(id) { - console.log(`check for ${id}`) + console.debug(`check for ${id}`) return this.cfg.home.followedArtists.includes(id) }, playMediaItem(item) { @@ -1876,7 +1870,7 @@ const app = new Vue({ try { a = await this.mkapi(kind.toString(), isLibrary, id.toString(), params, params2); } catch (e) { - console.log(e); + console.debug(e); try { a = await this.mkapi(kind.toString(), !isLibrary, id.toString(), params, params2); } catch (err) { @@ -2131,7 +2125,7 @@ const app = new Vue({ return await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2) } } catch (e) { - console.log(e) + console.debug(e) return await this.mkapi(method, library, term, params, params2, attempts + 1) } }, @@ -2183,7 +2177,7 @@ const app = new Vue({ l: app.mklang, }, onProgress: (data) => { - console.log(`${data.total}/${data.response.data.meta.total}`) + console.debug(`${data.total}/${data.response.data.meta.total}`) self.library.backgroundNotification.show = true self.library.backgroundNotification.message = app.getLz('notification.updatingLibrarySongs') self.library.backgroundNotification.total = data.response.data.meta.total @@ -2199,7 +2193,7 @@ const app = new Vue({ self.library.backgroundNotification.show = false self.searchLibrarySongs() CiderCache.putCache(cacheId, library) - console.log("Done!") + console.debug("Done!") return }, @@ -2250,7 +2244,7 @@ const app = new Vue({ app.mk.api.v3.music(`/v1/me/library/albums/`, params).then((response) => { processChunk(response.data) }).catch((error) => { - console.log('safe loading'); + console.debug('safe loading'); app.mk.api.v3.music(`/v1/me/library/albums/`, safeparams).then((response) => { processChunk(response.data) }).catch((error) => { @@ -2264,7 +2258,7 @@ const app = new Vue({ app.mk.api.v3.music(downloaded.next, params).then((response) => { processChunk(response.data) }).catch((error) => { - console.log('safe loading'); + console.debug('safe loading'); app.mk.api.v3.music(downloaded.next, safeparams).then((response) => { processChunk(response.data) }).catch((error) => { @@ -2274,7 +2268,7 @@ const app = new Vue({ }) }) } else { - console.log("Download next", downloaded.next) + console.debug("Download next", downloaded.next) } } } @@ -2291,7 +2285,7 @@ const app = new Vue({ return } if (typeof downloaded.next == "undefined") { - console.log("downloaded.next is undefined") + console.debug("downloaded.next is undefined") self.library.albums.listing = library self.library.albums.downloadState = 2 self.library.backgroundNotification.show = false @@ -2299,7 +2293,7 @@ const app = new Vue({ self.searchLibraryAlbums(index) } if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { - console.log(`downloading next chunk - ${library.length + console.debug(`downloading next chunk - ${library.length } albums so far`) downloadChunk() } else { @@ -2357,7 +2351,7 @@ const app = new Vue({ app.mk.api.v3.music(`/v1/me/library/artists/`, params).then((response) => { processChunk(response.data) }).catch((error) => { - console.log('safe loading'); + console.debug('safe loading'); app.mk.api.v3.music(`/v1/me/library/artists/`, safeparams).then((response) => { processChunk(response.data) }).catch((error) => { @@ -2485,7 +2479,7 @@ const app = new Vue({ reload: !0 })).data; this.listennow.timestamp = Date.now() - console.log(this.listennow) + console.debug(this.listennow) } catch (e) { console.log(e) this.getListenNow(attempt + 1) @@ -2513,7 +2507,7 @@ const app = new Vue({ }); this.browsepage = browse.data.data[0]; this.browsepage.timestamp = Date.now() - console.log(this.browsepage) + console.debug(this.browsepage) } catch (e) { console.log(e) this.getBrowsePage(attempt + 1) @@ -2714,7 +2708,7 @@ const app = new Vue({ if (status2 == 200) { let token = jsonResponse["message"]["body"]["user_token"] ?? ''; if (token != "" && token != "UpgradeOnlyUpgradeOnlyUpgradeOnlyUpgradeOnly") { - console.log('200 token', mode); + console.debug('200 token', mode); // token good app.mxmtoken = token; @@ -2724,7 +2718,7 @@ const app = new Vue({ getMXMTrans(songid, lang, app.mxmtoken); } } else { - console.log('fake 200 token'); + console.debug('fake 200 token'); getToken(mode, track, artist, songid, lang, time) } } else { @@ -2759,7 +2753,7 @@ const app = new Vue({ req.onload = function () { try { let jsonResponse = JSON.parse(this.responseText); - console.log(jsonResponse); + console.debug(jsonResponse); let status1 = jsonResponse["message"]["header"]["status_code"]; if (status1 == 200) { @@ -2823,7 +2817,7 @@ const app = new Vue({ }); app.lyrics = preLrc; } - if (lrcfile != null && lrcfile != '' && lang != "disabled") { + if (lrcfile != null && lrcfile != '') { // load translation getMXMTrans(id, lang, token); } else { @@ -3145,7 +3139,7 @@ const app = new Vue({ }, playMediaItemById(id, kind, isLibrary, raurl = "") { let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - console.log(id, truekind, isLibrary) + console.debug(id, truekind, isLibrary) try { if (truekind.includes("artist")) { app.mk.setStationQueue({ artist: 'a-' + id }).then(() => { @@ -3770,7 +3764,7 @@ const app = new Vue({ volumeUp() { if ((app.mk.volume + app.cfg.audio.volumeStep) > app.cfg.audio.maxVolume) { app.mk.volume = app.cfg.audio.maxVolume; - console.log('setting max volume') + console.debug('setting max volume') } else { console.log('volume up') app.mk.volume = ((app.mk.volume * 100) + (app.cfg.audio.volumeStep * 100)) / 100 @@ -3779,7 +3773,7 @@ const app = new Vue({ volumeDown() { if ((app.mk.volume - app.cfg.audio.volumeStep) < 0) { app.mk.volume = 0; - console.log('setting volume to 0') + console.debug('setting volume to 0') } else { console.log('volume down') app.mk.volume = ((app.mk.volume * 100) - (app.cfg.audio.volumeStep * 100)) / 100 diff --git a/src/renderer/views/components/listitem-horizontal.ejs b/src/renderer/views/components/listitem-horizontal.ejs index ba00fe6f..25296c47 100644 --- a/src/renderer/views/components/listitem-horizontal.ejs +++ b/src/renderer/views/components/listitem-horizontal.ejs @@ -40,7 +40,7 @@ this.itemPages = app.arrayToChunk(this.items, 4); try{ this.simplifiedParent = JSON.stringify(this.items.map ( function(x){return x.attributes.playParams})); - console.log("simplifiedParent: " + this.simplifiedParent); + console.debug("simplifiedParent: " + this.simplifiedParent); } catch (e){} diff --git a/src/renderer/views/components/menu-panel.ejs b/src/renderer/views/components/menu-panel.ejs index 28295375..b6908ed0 100644 --- a/src/renderer/views/components/menu-panel.ejs +++ b/src/renderer/views/components/menu-panel.ejs @@ -54,7 +54,6 @@ } }, mounted() { - console.log("MOUNTED") if (this.event) { this.position = [this.event.clientX, this.event.clientY]; } @@ -81,7 +80,6 @@ }, getStyle() { let style = {} - console.debug(this.$refs.menubody) this.size = [this.$refs.menubody.offsetWidth, this.$refs.menubody.offsetHeight]; if (this.event) { style["position"] = "absolute"; diff --git a/src/renderer/views/pages/settings.ejs b/src/renderer/views/pages/settings.ejs index bacca2d8..09ff4a8c 100644 --- a/src/renderer/views/pages/settings.ejs +++ b/src/renderer/views/pages/settings.ejs @@ -1,6 +1,6 @@ \ No newline at end of file