Merge branch 'develop' of https://github.com/Apple-Music-Electron/Cider into develop

This commit is contained in:
cryptofyre 2022-02-14 16:46:00 -06:00
commit 00d9292cd8
19 changed files with 6411 additions and 104 deletions

View file

@ -299,6 +299,8 @@
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
"settings.header.visual.theme": "Theme", "settings.header.visual.theme": "Theme",
"settings.option.visual.theme.github.download": "Install from GitHub URL", "settings.option.visual.theme.github.download": "Install from GitHub URL",
"settings.option.visual.theme.github.explore": "Explore GitHub Themes",
"settings.option.visual.theme.github.install.confirm": "Are you sure you want to install {{ repo }}?",
"settings.prompt.visual.theme.github.URL": "Enter the URL of the theme you want to install", "settings.prompt.visual.theme.github.URL": "Enter the URL of the theme you want to install",
"settings.notyf.visual.theme.install.success": "Theme installed successfully", "settings.notyf.visual.theme.install.success": "Theme installed successfully",
"settings.notyf.visual.theme.install.error": "Theme installation failed", "settings.notyf.visual.theme.install.error": "Theme installation failed",

View file

@ -119,6 +119,7 @@
"one" : "曲", "one" : "曲",
"other" : "曲" "other" : "曲"
}, },
"term.tracks": "曲",
"term.videos": "ビデオ", "term.videos": "ビデオ",
"term.menu": "メニュー", "term.menu": "メニュー",
"term.check": "確認", "term.check": "確認",

View file

@ -34,6 +34,7 @@
"term.about": "关于", "term.about": "关于",
"term.privateSession": "私人聆听", "term.privateSession": "私人聆听",
"term.queue": "队列", "term.queue": "队列",
"term.history": "播放历史",
"term.search": "搜索", "term.search": "搜索",
"term.library": "资料库", "term.library": "资料库",
"term.listenNow": "现在就听", "term.listenNow": "现在就听",
@ -111,13 +112,15 @@
"term.clearAll": "清空", "term.clearAll": "清空",
"term.recentStations": "最近播放的频道", "term.recentStations": "最近播放的频道",
"term.language": "语言", "term.language": "语言",
"term.noLyrics": "加载中... / 搜索无结果 / 纯音乐", "term.funLanguages": "恶搞",
"term.noLyrics": "加载中... / 无搜索结果 / 纯音乐",
"term.copyright": "版权所有", "term.copyright": "版权所有",
"term.rightsReserved": "保留所有权利。", "term.rightsReserved": "保留所有权利。",
"term.sponsor": "赞助", "term.sponsor": "赞助",
"term.ciderTeam": "Cider 团队", "term.ciderTeam": "Cider 团队",
"term.developer": "开发者", "term.developer": "开发者",
"term.socialTeam": "媒体团队", "term.socialTeam": "媒体团队",
"term.socials": "媒体",
"term.contributors": "贡献者", "term.contributors": "贡献者",
"term.equalizer": "均衡器", "term.equalizer": "均衡器",
"term.reset": "重置", "term.reset": "重置",
@ -137,7 +140,7 @@
"term.defaultPresets": "默认预设", "term.defaultPresets": "默认预设",
"term.userPresets": "用户预设", "term.userPresets": "用户预设",
"term.requestError": "请求出现一个问题。", "term.requestError": "请求出现一个问题。",
"term.song.link.generate": "获取 song.link 共享URL...", "term.song.link.generate": "获取 song.link 共享链接...",
"term.musicVideos": "音乐视频", // Search page friendlyTypes "term.musicVideos": "音乐视频", // Search page friendlyTypes
"term.stations": "电台", "term.stations": "电台",
//"term.curators": "Curators", //"term.curators": "Curators",
@ -148,6 +151,8 @@
//"term.top": "Top", //"term.top": "Top",
"term.version": "版本", "term.version": "版本",
// Home // Home
"home.title": "主页", "home.title": "主页",
"home.recentlyPlayed": "最近播放", "home.recentlyPlayed": "最近播放",
@ -186,6 +191,7 @@
"action.removeFromQueue": "从加入待播清单中移除", "action.removeFromQueue": "从加入待播清单中移除",
"action.removeFromQueue.success": "已从加入待播清单中移除", "action.removeFromQueue.success": "已从加入待播清单中移除",
"action.removeFromQueue.error": "从加入待播清单中移除的过程发生了错误", "action.removeFromQueue.error": "从加入待播清单中移除的过程发生了错误",
"action.createPlaylist": "新建播放列表",
"action.addToPlaylist": "加入播放列表", "action.addToPlaylist": "加入播放列表",
"action.removeFromPlaylist": "从播放列表中移除", "action.removeFromPlaylist": "从播放列表中移除",
"action.addToFavorites": "加至收藏", "action.addToFavorites": "加至收藏",
@ -257,6 +263,8 @@
"settings.option.audio.enableAdvancedFunctionality.description": "启用 AudioContext 将解锁例如音量标准化和音频空间化的功能,但可能会在小部分设备上出现音频上的卡顿。", "settings.option.audio.enableAdvancedFunctionality.description": "启用 AudioContext 将解锁例如音量标准化和音频空间化的功能,但可能会在小部分设备上出现音频上的卡顿。",
"settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 数字增强引擎™️", // Toggle "settings.option.audio.enableAdvancedFunctionality.ciderPPE": "Cider 数字增强引擎™️", // Toggle
"settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "将欺骗您的大脑来感知到近似无损音频的效果。", "settings.option.audio.enableAdvancedFunctionality.ciderPPE.description": "将欺骗您的大脑来感知到近似无损音频的效果。",
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength": "数字增强引擎强度", // Toggle
"settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description": "改变音频处理的强度。(激进选项可能产生杂音)",
"settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音量标准化", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioNormalization": "音量标准化", // Toggle
"settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "使所感知到的音频响度统一", "settings.option.audio.enableAdvancedFunctionality.audioNormalization.description": "使所感知到的音频响度统一",
"settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "音频空间化", // Toggle "settings.option.audio.enableAdvancedFunctionality.audioSpatialization": "音频空间化", // Toggle
@ -290,6 +298,8 @@
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
"settings.header.visual.theme": "主题", "settings.header.visual.theme": "主题",
"settings.option.visual.theme.github.download": "通过GitHub URL安装", "settings.option.visual.theme.github.download": "通过GitHub URL安装",
"settings.option.visual.theme.github.explore": "浏览 GitHub 上的主题",
"settings.option.visual.theme.github.install.confirm": "确定要安装 {{ repo }}?",
"settings.prompt.visual.theme.github.URL": "请输入欲安装主题的URL", "settings.prompt.visual.theme.github.URL": "请输入欲安装主题的URL",
"settings.notyf.visual.theme.install.success": "主题安装成功", "settings.notyf.visual.theme.install.success": "主题安装成功",
"settings.notyf.visual.theme.install.error": "主题安装失败", "settings.notyf.visual.theme.install.error": "主题安装失败",

View file

@ -275,8 +275,8 @@
"settings.header.visual.hardwareAcceleration.default": "預設", "settings.header.visual.hardwareAcceleration.default": "預設",
"settings.header.visual.hardwareAcceleration.webGPU": "WebGPU", "settings.header.visual.hardwareAcceleration.webGPU": "WebGPU",
"settings.header.visual.theme": "主題", "settings.header.visual.theme": "主題",
"settings.option.visual.theme.github.download" : "從 GitHub 連結安裝" , "settings.option.visual.theme.github.download" : "從 GitHub 網址安裝" ,
"settings.prompt.visual.theme.github.URL" : "輸入你要安裝的主題連結" , "settings.prompt.visual.theme.github.URL" : "輸入你要安裝的主題網址" ,
"settings.notyf.visual.theme.install.success" : "主題成功安裝" , "settings.notyf.visual.theme.install.success" : "主題成功安裝" ,
"settings.notyf.visual.theme.install.error" : "主題安裝失敗" , "settings.notyf.visual.theme.install.error" : "主題安裝失敗" ,

View file

@ -46,6 +46,7 @@ export class BrowserWindow {
"pages/about", "pages/about",
"pages/library-videos", "pages/library-videos",
"pages/remote-pair", "pages/remote-pair",
"pages/themes-github",
"components/mediaitem-artwork", "components/mediaitem-artwork",
"components/artwork-material", "components/artwork-material",
"components/menu-panel", "components/menu-panel",
@ -430,7 +431,7 @@ export class BrowserWindow {
description: themeJson.description || themeDescription, description: themeJson.description || themeDescription,
path: themePath, path: themePath,
file: theme, file: theme,
test: join(themePath, "theme.json") github_repo: themeJson.github_repo || ""
}); });
} else { } else {
themeObjects.push({ themeObjects.push({
@ -438,7 +439,7 @@ export class BrowserWindow {
description: themeDescription, description: themeDescription,
path: themePath, path: themePath,
file: theme, file: theme,
test: join(themePath, "theme.json") github_repo: ""
}); });
} }
} }

View file

@ -81,7 +81,7 @@ export default class LastFMPlugin {
private scrobbleSong(attributes: any) { private scrobbleSong(attributes: any) {
if(this._timer) clearTimeout(this._timer); if(this._timer) clearTimeout(this._timer);
var self = this; var self = this;
this._timer = setTimeout(() => { this._timer = setTimeout(async () => {
const currentAttributes = attributes; const currentAttributes = attributes;
if (!self._lastfm || self._lastfm.cachedAttributes === attributes) { if (!self._lastfm || self._lastfm.cachedAttributes === attributes) {
@ -92,15 +92,17 @@ export default class LastFMPlugin {
if (self._lastfm.cachedAttributes.playParams.id === attributes.playParams.id) return; if (self._lastfm.cachedAttributes.playParams.id === attributes.playParams.id) return;
} }
const artist = await this.getPrimaryArtist(attributes)
if (currentAttributes.status && currentAttributes === attributes) { if (currentAttributes.status && currentAttributes === attributes) {
if (fs.existsSync(this.sessionPath)) { if (fs.existsSync(this.sessionPath)) {
// Scrobble playing song. // Scrobble playing song.
if (attributes.status === true) { if (attributes.status === true) {
self._lastfm.track.scrobble({ self._lastfm.track.scrobble({
'artist': this.filterArtistName(attributes.artistName), 'artist': artist,
'track': attributes.name, 'track': attributes.name,
'album': attributes.albumName, 'album': attributes.albumName,
'albumArtist': self.filterArtistName(attributes.artistName), 'albumArtist': artist,
'timestamp': new Date().getTime() / 1000 'timestamp': new Date().getTime() / 1000
}, function (err: any, scrobbled: any) { }, function (err: any, scrobbled: any) {
if (err) { if (err) {
@ -115,29 +117,11 @@ export default class LastFMPlugin {
self.authenticate(); self.authenticate();
} }
} else { } else {
return console.log('[LastFM] Did not add ', attributes.name, '—', self.filterArtistName(attributes.artistName), 'because now playing a other song.'); return console.log('[LastFM] Did not add ', attributes.name, '—', artist, 'because now playing a other song.');
}},Math.round(attributes.durationInMillis * (self._store.lastfm.scrobble_after / 100))); }},Math.round(attributes.durationInMillis * (self._store.lastfm.scrobble_after / 100)));
} }
private filterArtistName(artist: any) { private async updateNowPlayingSong(attributes: any) {
if (!this._store.lastfm.enabledRemoveFeaturingArtists) return artist;
artist = artist.split(' ');
if (artist.includes('&')) {
artist.length = artist.indexOf('&');
}
if (artist.includes('and')) {
artist.length = artist.indexOf('and');
}
artist = artist.join(' ');
if (artist.includes(',')) {
artist = artist.split(',')
artist = artist[0]
}
return artist.charAt(0).toUpperCase() + artist.slice(1);
}
private updateNowPlayingSong(attributes: any) {
if (!this._lastfm || this._lastfm.cachedNowPlayingAttributes === attributes || !this._store.lastfm.NowPlaying) { if (!this._lastfm || this._lastfm.cachedNowPlayingAttributes === attributes || !this._store.lastfm.NowPlaying) {
return return
} }
@ -147,13 +131,15 @@ export default class LastFMPlugin {
} }
if (fs.existsSync(this.sessionPath)) { if (fs.existsSync(this.sessionPath)) {
const artist = await this.getPrimaryArtist(attributes)
// update Now Playing // update Now Playing
if (attributes.status === true) { if (attributes.status === true) {
this._lastfm.track.updateNowPlaying({ this._lastfm.track.updateNowPlaying({
'artist': this.filterArtistName(attributes.artistName), 'artist': artist,
'track': attributes.name, 'track': attributes.name,
'album': attributes.albumName, 'album': attributes.albumName,
'albumArtist': this.filterArtistName(attributes.artistName) 'albumArtist': artist
}, function (err: any, nowPlaying: any) { }, function (err: any, nowPlaying: any) {
if (err) { if (err) {
return console.error('[LastFM] An error occurred while updating nowPlayingSong', err); return console.error('[LastFM] An error occurred while updating nowPlayingSong', err);
@ -169,6 +155,40 @@ export default class LastFMPlugin {
} }
} }
private async getPrimaryArtist (attributes: any) {
const songId = attributes.playParams.catalogId || attributes.playParams.id
if (!this._store.lastfm.enabledRemoveFeaturingArtists || !songId) return attributes.artistName;
const res = await this._win.webContents.executeJavaScript(`
(async () => {
const subMk = await MusicKit.getInstance().api.v3.music("/v1/catalog/" + MusicKit.getInstance().storefrontId + "/songs/${songId}", {
include: {
songs: ["artists"]
}
})
if (!subMk) console.error('[LastFM] Request failed: /v1/catalog/us/songs/${songId}')
return subMk.data
})()
`).catch(console.error)
if (!res) return attributes.artistName
const data = res.data
if (!data.length) {
console.error(`[LastFM] Unable to locate song with id of ${songId}`)
return attributes.artistName;
}
const artists = res.data[0].relationships.artists.data
if (!artists.length) {
console.error(`[LastFM] Unable to find artists related to the song with id of ${songId}`)
return attributes.artistName;
}
const primaryArtist = artists[0]
return primaryArtist.attributes.name
}
/** /**
* Base Plugin Details (Eventually implemented into a GUI in settings) * Base Plugin Details (Eventually implemented into a GUI in settings)
*/ */

View file

@ -75,11 +75,8 @@ var CiderAudio = {
CiderAudio.audioNodes.gainNode.gain.setTargetAtTime(1, CiderAudio.context.currentTime+ 1, 0.5); CiderAudio.audioNodes.gainNode.gain.setTargetAtTime(1, CiderAudio.context.currentTime+ 1, 0.5);
}, },
spatialOn: function (){ spatialOn: function (){
try{
CiderAudio.audioNodes.gainNode.disconnect(CiderAudio.context.destination);} catch(e){}
CiderAudio.audioNodes.spatialNode = new ResonanceAudio(CiderAudio.context); CiderAudio.audioNodes.spatialNode = new ResonanceAudio(CiderAudio.context);
CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.context.destination); //CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.context.destination);
let roomDimensions = { let roomDimensions = {
width: 32, width: 32,
height: 12, height: 12,
@ -96,13 +93,9 @@ var CiderAudio = {
}; };
CiderAudio.audioNodes.spatialNode.setRoomProperties(roomDimensions, roomMaterials); CiderAudio.audioNodes.spatialNode.setRoomProperties(roomDimensions, roomMaterials);
CiderAudio.audioNodes.spatialInput = CiderAudio.audioNodes.spatialNode.createSource(); CiderAudio.audioNodes.spatialInput = CiderAudio.audioNodes.spatialNode.createSource();
CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialInput.input);
CiderAudio.hierarchical_loading(); CiderAudio.hierarchical_loading();
}, },
spatialOff: function (){ spatialOff: function (){
try{
CiderAudio.audioNodes.spatialNode.output.disconnect(CiderAudio.context.destination);
CiderAudio.audioNodes.gainNode.disconnect(CiderAudio.audioNodes.spatialInput.input);} catch(e){}
CiderAudio.hierarchical_loading(); CiderAudio.hierarchical_loading();
}, },
sendAudio: function (){ sendAudio: function (){
@ -125,6 +118,8 @@ var CiderAudio = {
let LLPW_Q = [5, 1, 3.536, 1.25, 8.409, 1.25, 14.14, 7.071, 5, 0.625, 16.82, 20, 20, 20, 28.28, 28.28, 28.28, 20, 33.64, 33.64, 10, 28.28, 7.071, 3.856]; let LLPW_Q = [5, 1, 3.536, 1.25, 8.409, 1.25, 14.14, 7.071, 5, 0.625, 16.82, 20, 20, 20, 28.28, 28.28, 28.28, 20, 33.64, 33.64, 10, 28.28, 7.071, 3.856];
let LLPW_GAIN = [0.38, -1.81, -0.23, -0.51, 0.4, 0.84, 0.36, -0.34, 0.27, -1.2, -0.42, -0.67, 0.81, 1.31, -0.71, 0.68, -1.04, 0.79, -0.73, -1.33, 1.17, 0.57, 0.35, 6.33]; let LLPW_GAIN = [0.38, -1.81, -0.23, -0.51, 0.4, 0.84, 0.36, -0.34, 0.27, -1.2, -0.42, -0.67, 0.81, 1.31, -0.71, 0.68, -1.04, 0.79, -0.73, -1.33, 1.17, 0.57, 0.35, 6.33];
let LLPW_FREQUENCIES = [16.452, 24.636, 37.134, 74.483, 159.54, 308.18, 670.21, 915.81, 1200.7, 2766.4, 2930.6, 4050.6, 4409.1, 5395.2, 5901.6, 6455.5, 7164.1, 7724.1, 8449, 10573, 12368, 14198, 17910, 18916]; let LLPW_FREQUENCIES = [16.452, 24.636, 37.134, 74.483, 159.54, 308.18, 670.21, 915.81, 1200.7, 2766.4, 2930.6, 4050.6, 4409.1, 5395.2, 5901.6, 6455.5, 7164.1, 7724.1, 8449, 10573, 12368, 14198, 17910, 18916];
CiderAudio.audioNodes.llpw = []
for (i = 0; i < LLPW_FREQUENCIES.length; i++) { for (i = 0; i < LLPW_FREQUENCIES.length; i++) {
CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.llpw[i] = CiderAudio.context.createBiquadFilter();
CiderAudio.audioNodes.llpw[i].type = 'peaking'; // 'peaking'; CiderAudio.audioNodes.llpw[i].type = 'peaking'; // 'peaking';
@ -151,6 +146,7 @@ var CiderAudio = {
let VIBRANTBASSBANDS = app.cfg.audio.vibrantBass.frequencies; let VIBRANTBASSBANDS = app.cfg.audio.vibrantBass.frequencies;
let VIBRANTBASSGAIN = app.cfg.audio.vibrantBass.gain; let VIBRANTBASSGAIN = app.cfg.audio.vibrantBass.gain;
let VIBRANTBASSQ = app.cfg.audio.vibrantBass.Q; let VIBRANTBASSQ = app.cfg.audio.vibrantBass.Q;
CiderAudio.audioNodes.vibrantbassNode = []
for (i = 0; i < VIBRANTBASSBANDS.length; i++) { for (i = 0; i < VIBRANTBASSBANDS.length; i++) {
CiderAudio.audioNodes.vibrantbassNode[i] = CiderAudio.context.createBiquadFilter(); CiderAudio.audioNodes.vibrantbassNode[i] = CiderAudio.context.createBiquadFilter();
@ -168,7 +164,7 @@ var CiderAudio = {
} }
}, },
hiererchical_unloading: function (){ hierarchical_unloading: function (){
try {CiderAudio.audioNodes.spatialNode.output.disconnect();} catch(e){} try {CiderAudio.audioNodes.spatialNode.output.disconnect();} catch(e){}
try {CiderAudio.audioNodes.gainNode.disconnect();} catch(e){} try {CiderAudio.audioNodes.gainNode.disconnect();} catch(e){}
try {for (var i of CiderAudio.audioNodes.llpw){i.disconnect();} CiderAudio.audioNodes.llpw = []} catch(e){} try {for (var i of CiderAudio.audioNodes.llpw){i.disconnect();} CiderAudio.audioNodes.llpw = []} catch(e){}
@ -178,37 +174,45 @@ var CiderAudio = {
}, },
hierarchical_loading: function (){ hierarchical_loading: function (){
CiderAudio.hiererchical_unloading(); CiderAudio.hierarchical_unloading();
if (app.cfg.audio.vibrantBass.multiplier !== 0) { // If vibrant bass is enabled if (app.cfg.audio.vibrantBass.multiplier !== 0) { // If vibrant bass is enabled
if (app.cfg.audio.ciderPPE) { // If CAP & vibrant bass is enabled if (app.cfg.advanced.ciderPPE) { // If CAP & vibrant bass is enabled
CiderAudio.vibrantbass_h2_1(true) CiderAudio.vibrantbass_h2_1(true)
CiderAudio.llpw_h2_2(true, 2) if (app.cfg.audio.spatial) {
if (app.cfg.audio.spatial) {CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.audioNodes.llpw[0]);} app.cfg.advanced.ciderPPE = false;
else {CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.llpw[0]);} notyf.error(app.getLz('settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility'));
console.log("[Cider][Audio] CAP & vibrant bass is enabled") CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialInput.input);
CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.audioNodes.vibrantbassNode[0]);
}
else {CiderAudio.llpw_h2_2(true, 2); CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.llpw[0]);}
} }
else { // If only vibrant bass is enabled else { // If only vibrant bass is enabled
CiderAudio.vibrantbass_h2_1(true) CiderAudio.vibrantbass_h2_1(true)
//CiderAudio.llpw_h2_2(false, 0) //CiderAudio.llpw_h2_2(false, 0)
if (app.cfg.audio.spatial) {CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.audioNodes.vibrantbassNode[0]);} if (app.cfg.audio.spatial) {
CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialInput.input);
CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.audioNodes.vibrantbassNode[0]);}
else {CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.vibrantbassNode[0]);} else {CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.vibrantbassNode[0]);}
console.log("[Cider][Audio] Only vibrant bass is enabled")
} }
} }
else { // If vibrant bass is disabled else { // If vibrant bass is disabled
if (app.cfg.audio.ciderPPE) { // If CAP is enabled & vibrant bass is disabled if (app.cfg.advanced.ciderPPE) { // If CAP is enabled & vibrant bass is disabled
//CiderAudio.vibrantbass_h2_1(false) //CiderAudio.vibrantbass_h2_1(false)
CiderAudio.llpw_h2_2(true, 1) if (app.cfg.audio.spatial) {
if (app.cfg.audio.spatial) {CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.audioNodes.llpw[0]);} app.cfg.advanced.ciderPPE = false;
else {CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.llpw[0]);} notyf.error(app.getLz('settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility'));
console.log("[Cider][Audio] CAP is enabled & vibrant bass is disabled") CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialInput.input);
CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.audioNodes.audioBands[0]);
}
else {CiderAudio.llpw_h2_2(true, 1); CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.llpw[0]);}
} }
else { // If CAP & vibrant bass is disabled else { // If CAP & vibrant bass is disabled
//CiderAudio.vibrantbass_h2_1(false) //CiderAudio.vibrantbass_h2_1(false)
//CiderAudio.llpw_h2_2(false, 0) //CiderAudio.llpw_h2_2(false, 0)
if (app.cfg.audio.spatial) {CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.audioNodes.audioBands[0]);} if (app.cfg.audio.spatial) {
CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.spatialInput.input);
CiderAudio.audioNodes.spatialNode.output.connect(CiderAudio.audioNodes.audioBands[0]);}
else {CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.audioBands[0]);} else {CiderAudio.audioNodes.gainNode.connect(CiderAudio.audioNodes.audioBands[0]);}
console.log("[Cider][Audio] CAP & vibrant bass is disabled")
} }
} }

View file

@ -4003,6 +4003,12 @@ webGPU().then()
let screenWidth = screen.width; let screenWidth = screen.width;
let screenHeight = screen.height; let screenHeight = screen.height;
window.onerror = function(error) {
console.log(error)
bootbox.alert("Error occured: " + error)
};
// Key bind to unjam MusicKit in case it fails: CTRL+F10 // Key bind to unjam MusicKit in case it fails: CTRL+F10
document.addEventListener('keydown', function (event) { document.addEventListener('keydown', function (event) {
if (event.ctrlKey && event.keyCode == 121) { if (event.ctrlKey && event.keyCode == 121) {

5531
src/renderer/js/showdown.min.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,498 @@
// List Group
.list-group {
display: flex;
flex-direction: column;
padding-left: 0;
margin-bottom: 0;
border-radius: 0.25rem;
}
.list-group-numbered {
list-style-type: none;
counter-reset: section;
}
.list-group-numbered > li::before {
content: counters(section, ".") ". ";
counter-increment: section;
}
.list-group-item-action {
width: 100%;
color: #495057;
text-align: inherit;
}
.list-group-item-action:hover, .list-group-item-action:focus {
z-index: 1;
color: #495057;
text-decoration: none;
background-color: #f8f9fa;
}
.list-group-item-action:active {
color: #212529;
background-color: #e9ecef;
}
.list-group-item {
position: relative;
display: block;
padding: 0.5rem 1rem;
color: #212529;
text-decoration: none;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.125);
}
.list-group-item:first-child {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}
.list-group-item:last-child {
border-bottom-right-radius: inherit;
border-bottom-left-radius: inherit;
}
.list-group-item.disabled, .list-group-item:disabled {
color: #6c757d;
pointer-events: none;
background-color: #fff;
}
.list-group-item.active {
z-index: 2;
color: #fff;
background-color: #0d6efd;
border-color: #0d6efd;
}
.list-group-item + .list-group-item {
border-top-width: 0;
}
.list-group-item + .list-group-item.active {
margin-top: -1px;
border-top-width: 1px;
}
.list-group-horizontal {
flex-direction: row;
}
.list-group-horizontal > .list-group-item:first-child {
border-bottom-left-radius: 0.25rem;
border-top-right-radius: 0;
}
.list-group-horizontal > .list-group-item:last-child {
border-top-right-radius: 0.25rem;
border-bottom-left-radius: 0;
}
.list-group-horizontal > .list-group-item.active {
margin-top: 0;
}
.list-group-horizontal > .list-group-item + .list-group-item {
border-top-width: 1px;
border-left-width: 0;
}
.list-group-horizontal > .list-group-item + .list-group-item.active {
margin-left: -1px;
border-left-width: 1px;
}
@media (min-width: 576px) {
.list-group-horizontal-sm {
flex-direction: row;
}
.list-group-horizontal-sm > .list-group-item:first-child {
border-bottom-left-radius: 0.25rem;
border-top-right-radius: 0;
}
.list-group-horizontal-sm > .list-group-item:last-child {
border-top-right-radius: 0.25rem;
border-bottom-left-radius: 0;
}
.list-group-horizontal-sm > .list-group-item.active {
margin-top: 0;
}
.list-group-horizontal-sm > .list-group-item + .list-group-item {
border-top-width: 1px;
border-left-width: 0;
}
.list-group-horizontal-sm > .list-group-item + .list-group-item.active {
margin-left: -1px;
border-left-width: 1px;
}
}
@media (min-width: 768px) {
.list-group-horizontal-md {
flex-direction: row;
}
.list-group-horizontal-md > .list-group-item:first-child {
border-bottom-left-radius: 0.25rem;
border-top-right-radius: 0;
}
.list-group-horizontal-md > .list-group-item:last-child {
border-top-right-radius: 0.25rem;
border-bottom-left-radius: 0;
}
.list-group-horizontal-md > .list-group-item.active {
margin-top: 0;
}
.list-group-horizontal-md > .list-group-item + .list-group-item {
border-top-width: 1px;
border-left-width: 0;
}
.list-group-horizontal-md > .list-group-item + .list-group-item.active {
margin-left: -1px;
border-left-width: 1px;
}
}
@media (min-width: 992px) {
.list-group-horizontal-lg {
flex-direction: row;
}
.list-group-horizontal-lg > .list-group-item:first-child {
border-bottom-left-radius: 0.25rem;
border-top-right-radius: 0;
}
.list-group-horizontal-lg > .list-group-item:last-child {
border-top-right-radius: 0.25rem;
border-bottom-left-radius: 0;
}
.list-group-horizontal-lg > .list-group-item.active {
margin-top: 0;
}
.list-group-horizontal-lg > .list-group-item + .list-group-item {
border-top-width: 1px;
border-left-width: 0;
}
.list-group-horizontal-lg > .list-group-item + .list-group-item.active {
margin-left: -1px;
border-left-width: 1px;
}
}
@media (min-width: 1200px) {
.list-group-horizontal-xl {
flex-direction: row;
}
.list-group-horizontal-xl > .list-group-item:first-child {
border-bottom-left-radius: 0.25rem;
border-top-right-radius: 0;
}
.list-group-horizontal-xl > .list-group-item:last-child {
border-top-right-radius: 0.25rem;
border-bottom-left-radius: 0;
}
.list-group-horizontal-xl > .list-group-item.active {
margin-top: 0;
}
.list-group-horizontal-xl > .list-group-item + .list-group-item {
border-top-width: 1px;
border-left-width: 0;
}
.list-group-horizontal-xl > .list-group-item + .list-group-item.active {
margin-left: -1px;
border-left-width: 1px;
}
}
@media (min-width: 1400px) {
.list-group-horizontal-xxl {
flex-direction: row;
}
.list-group-horizontal-xxl > .list-group-item:first-child {
border-bottom-left-radius: 0.25rem;
border-top-right-radius: 0;
}
.list-group-horizontal-xxl > .list-group-item:last-child {
border-top-right-radius: 0.25rem;
border-bottom-left-radius: 0;
}
.list-group-horizontal-xxl > .list-group-item.active {
margin-top: 0;
}
.list-group-horizontal-xxl > .list-group-item + .list-group-item {
border-top-width: 1px;
border-left-width: 0;
}
.list-group-horizontal-xxl > .list-group-item + .list-group-item.active {
margin-left: -1px;
border-left-width: 1px;
}
}
.list-group-flush {
border-radius: 0;
}
.list-group-flush > .list-group-item {
border-width: 0 0 1px;
}
.list-group-flush > .list-group-item:last-child {
border-bottom-width: 0;
}
.list-group-item-primary {
color: #084298;
background-color: #cfe2ff;
}
.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {
color: #084298;
background-color: #bacbe6;
}
.list-group-item-primary.list-group-item-action.active {
color: #fff;
background-color: #084298;
border-color: #084298;
}
.list-group-item-secondary {
color: #41464b;
background-color: #e2e3e5;
}
.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {
color: #41464b;
background-color: #cbccce;
}
.list-group-item-secondary.list-group-item-action.active {
color: #fff;
background-color: #41464b;
border-color: #41464b;
}
.list-group-item-success {
color: #0f5132;
background-color: #d1e7dd;
}
.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {
color: #0f5132;
background-color: #bcd0c7;
}
.list-group-item-success.list-group-item-action.active {
color: #fff;
background-color: #0f5132;
border-color: #0f5132;
}
.list-group-item-info {
color: #055160;
background-color: #cff4fc;
}
.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {
color: #055160;
background-color: #badce3;
}
.list-group-item-info.list-group-item-action.active {
color: #fff;
background-color: #055160;
border-color: #055160;
}
.list-group-item-warning {
color: #664d03;
background-color: #fff3cd;
}
.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {
color: #664d03;
background-color: #e6dbb9;
}
.list-group-item-warning.list-group-item-action.active {
color: #fff;
background-color: #664d03;
border-color: #664d03;
}
.list-group-item-danger {
color: #842029;
background-color: #f8d7da;
}
.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {
color: #842029;
background-color: #dfc2c4;
}
.list-group-item-danger.list-group-item-action.active {
color: #fff;
background-color: #842029;
border-color: #842029;
}
.list-group-item-light {
color: #636464;
background-color: #fefefe;
}
.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {
color: #636464;
background-color: #e5e5e5;
}
.list-group-item-light.list-group-item-action.active {
color: #fff;
background-color: #636464;
border-color: #636464;
}
.list-group-item-dark {
color: var(--textColor);
background-color: #333;
}
.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {
color: #141619;
background-color: #bebebf;
}
.list-group-item-dark.list-group-item-action.active {
color: #fff;
background-color: #141619;
border-color: #141619;
}
// Card
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #333;
background-clip: border-box;
border: 1px solid rgba(0, 0, 0, 0.125);
border-radius: 0.25rem;
}
.card > hr {
margin-right: 0;
margin-left: 0;
}
.card > .list-group {
border-top: inherit;
border-bottom: inherit;
}
.card > .list-group:first-child {
border-top-width: 0;
border-top-left-radius: calc(0.25rem - 1px);
border-top-right-radius: calc(0.25rem - 1px);
}
.card > .list-group:last-child {
border-bottom-width: 0;
border-bottom-right-radius: calc(0.25rem - 1px);
border-bottom-left-radius: calc(0.25rem - 1px);
}
.card > .card-header + .list-group,
.card > .list-group + .card-footer {
border-top: 0;
}
.card-body {
flex: 1 1 auto;
padding: 1rem 1rem;
}
.card-title {
margin-bottom: 0.5rem;
}
.card-subtitle {
margin-top: -0.25rem;
margin-bottom: 0;
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link + .card-link {
margin-left: 1rem;
}
.card-header {
padding: 0.5rem 1rem;
margin-bottom: 0;
background-color: rgba(0, 0, 0, 0.03);
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
}
.card-header:first-child {
border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;
}
.card-footer {
padding: 0.5rem 1rem;
background-color: rgba(0, 0, 0, 0.03);
border-top: 1px solid rgba(0, 0, 0, 0.125);
}
.card-footer:last-child {
border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);
}
.card-header-tabs {
margin-right: -0.5rem;
margin-bottom: -0.5rem;
margin-left: -0.5rem;
border-bottom: 0;
}
.card-header-pills {
margin-right: -0.5rem;
margin-left: -0.5rem;
}
.card-img-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 1rem;
border-radius: calc(0.25rem - 1px);
}
.card-img,
.card-img-top,
.card-img-bottom {
width: 100%;
}
.card-img,
.card-img-top {
border-top-left-radius: calc(0.25rem - 1px);
border-top-right-radius: calc(0.25rem - 1px);
}
.card-img,
.card-img-bottom {
border-bottom-right-radius: calc(0.25rem - 1px);
border-bottom-left-radius: calc(0.25rem - 1px);
}
.card-group > .card {
margin-bottom: 0.75rem;
}
@media (min-width: 576px) {
.card-group {
display: flex;
flex-flow: row wrap;
}
.card-group > .card {
flex: 1 0 0%;
margin-bottom: 0;
}
.card-group > .card + .card {
margin-left: 0;
border-left: 0;
}
.card-group > .card:not(:last-child) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.card-group > .card:not(:last-child) .card-img-top,
.card-group > .card:not(:last-child) .card-header {
border-top-right-radius: 0;
}
.card-group > .card:not(:last-child) .card-img-bottom,
.card-group > .card:not(:last-child) .card-footer {
border-bottom-right-radius: 0;
}
.card-group > .card:not(:first-child) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.card-group > .card:not(:first-child) .card-img-top,
.card-group > .card:not(:first-child) .card-header {
border-top-left-radius: 0;
}
.card-group > .card:not(:first-child) .card-img-bottom,
.card-group > .card:not(:first-child) .card-footer {
border-bottom-left-radius: 0;
}
}
.modal { .modal {
position: fixed; position: fixed;
top: 0; top: 0;

View file

@ -1222,6 +1222,10 @@
height: 18px; height: 18px;
width: 18px; width: 18px;
background: var(--color); background: var(--color);
&.inline {
display: inline-block;
}
} }
.sidebar-icon { .sidebar-icon {

View file

@ -18,6 +18,78 @@
} }
// End Helpers // End Helpers
// GitHub Themes
.github-themes-page {
display: flex;
flex-direction: column;
padding: 0px;
height: calc(100% - var(--navigationBarHeight));
.github-avatar {
height: 42px;
width: 42px;
margin: 6px;
border-radius: 32px;
}
.repo-name {
margin:0px;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.repo-url {
color: var(--textColor);
font-size: 0.8em;
}
.repo-preview-name {
margin:0px;
}
.repos-list {
height: 100%;
overflow-y: overlay;
width: 320px;
font-size: 14px;
>.list-group {
margin:0px;
}
.list-group-item {
padding: 12px 6px;
&:hover {
filter: brightness(1.2);
}
&:active {
filter: brightness(0.8);
}
}
}
.github-preview {
height: 100%;
flex: 1;
background: var(--color2);
padding: 16px 32px;
overflow-y:overlay;
}
.gh-content {
display: flex;
flex-direction: row;
flex: 1;
overflow: hidden;
}
.gh-header {
padding: 16px;
}
}
// Library - Songs page // Library - Songs page
.library-page { .library-page {

View file

@ -140,7 +140,7 @@ body.notransparency::before {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: var(--color1); background: var(--color1);
color: white; color: var(--textColor);
user-select: none; user-select: none;
margin: 0 auto; margin: 0 auto;
position: relative; position: relative;

View file

@ -159,6 +159,12 @@
<cider-applecurator :data="appleCurator"></cider-applecurator> <cider-applecurator :data="appleCurator"></cider-applecurator>
</template> </template>
</transition> </transition>
<!-- Github themes-->
<transition name="wpfade">
<template v-if="page == 'themes-github'">
<themes-github></themes-github>
</template>
</transition>
<!-- Library - Library Videos --> <!-- Library - Library Videos -->
<transition name="wpfade"> <transition name="wpfade">
<template v-if="page == 'remote-pair'"> <template v-if="page == 'remote-pair'">

View file

@ -1,17 +1,5 @@
<cider-menu-panel v-if="menuPanel.visible"> <cider-menu-panel v-if="menuPanel.visible">
</cider-menu-panel> </cider-menu-panel>
<transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'fullscreen'">
<fullscreen-view :image="currentArtUrl.replace('50x50', '600x600')" :time="lyriccurrenttime"
:lyrics="lyrics" :richlyrics="richlyrics"></fullscreen-view>
</div>
</transition>
<transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'mini'">
<mini-view :image="currentArtUrl.replace('50x50', '600x600')" :time="lyriccurrenttime"
:lyrics="lyrics" :richlyrics="richlyrics"></mini-view>
</div>
</transition>
<transition name="wpfade"> <transition name="wpfade">
<div class="bg-artwork-container" v-if="cfg.visual.window_background_style == 'artwork'" <div class="bg-artwork-container" v-if="cfg.visual.window_background_style == 'artwork'"
:class="{noanimation: (!cfg.visual.bg_artwork_rotation || !animateBackground)}"> :class="{noanimation: (!cfg.visual.bg_artwork_rotation || !animateBackground)}">

View file

@ -6,10 +6,10 @@
<button class="close-btn" @click="close()"></button> <button class="close-btn" @click="close()"></button>
<div class="md-option-segment md-option-segment_auto"> <div class="md-option-segment md-option-segment_auto">
<select class="md-select" style="width:220px;text-align:center;margin-right:245px" v-model="$root.cfg.audio.equalizer.preset" v-on:change="changePreset($root.cfg.audio.equalizer.preset)"> <select class="md-select" style="width:220px;text-align:center;margin-right:245px" v-model="$root.cfg.audio.equalizer.preset" v-on:change="changePreset($root.cfg.audio.equalizer.preset)">
<optgroup :label="app.getLz('term.userPresets')"> <optgroup :label="$root.getLz('term.userPresets')">
<option v-for="preset in $root.cfg.audio.equalizer.presets" :value="preset.preset">{{preset.name}}</option> <option v-for="preset in $root.cfg.audio.equalizer.presets" :value="preset.preset">{{preset.name}}</option>
</optgroup> </optgroup>
<optgroup :label="app.getLz('term.defaultPresets')"> <optgroup :label="$root.getLz('term.defaultPresets')">
<option v-for="preset in defaultPresets" :value="preset.preset">{{preset.name}}</option> <option v-for="preset in defaultPresets" :value="preset.preset">{{preset.name}}</option>
</optgroup> </optgroup>
</select> </select>

View file

@ -33,6 +33,7 @@
<script src="./js/bootstrap.min.js"></script> <script src="./js/bootstrap.min.js"></script>
<script src="./js/bootbox.min.js"></script> <script src="./js/bootbox.min.js"></script>
<script src="./js/notyf.min.js"></script> <script src="./js/notyf.min.js"></script>
<script src="./js/showdown.min.js"></script>
</head> </head>
<body oncontextmenu="return false;" loading="1" platform="<%= env.platform %>"> <body oncontextmenu="return false;" loading="1" platform="<%= env.platform %>">
@ -43,6 +44,18 @@
<%- include('app/app-navigation'); %> <%- include('app/app-navigation'); %>
</div> </div>
</transition> </transition>
<transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'fullscreen'">
<fullscreen-view :image="currentArtUrl.replace('50x50', '600x600')" :time="lyriccurrenttime"
:lyrics="lyrics" :richlyrics="richlyrics"></fullscreen-view>
</div>
</transition>
<transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'mini'">
<mini-view :image="currentArtUrl.replace('50x50', '600x600')" :time="lyriccurrenttime"
:lyrics="lyrics" :richlyrics="richlyrics"></mini-view>
</div>
</transition>
<%- include('app/panels'); %> <%- include('app/panels'); %>
</div> </div>

View file

@ -68,7 +68,7 @@
<small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE.description')}}</small> <small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE.description')}}</small>
</div> </div>
<div class="md-option-segment md-option-segment_auto"> <div class="md-option-segment md-option-segment_auto">
<input type="checkbox" v-model="app.cfg.advanced.ciderPPE" v-on:change="ciderPPE" switch/> <input type="checkbox" v-model="app.cfg.advanced.ciderPPE" :disabled="app.cfg.audio.spatial === true" v-on:change="CiderAudio.hierarchical_loading();" switch/>
</div> </div>
</div> </div>
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext && app.cfg.advanced.ciderPPE === true"> <div class="md-option-line" v-show="app.cfg.advanced.AudioContext && app.cfg.advanced.ciderPPE === true">
@ -78,10 +78,10 @@
<small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description')}}</small> <small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.description')}}</small>
</div> </div>
<div class="md-option-segment md-option-segment_auto"> <div class="md-option-segment md-option-segment_auto">
<button class="md-btn" :disabled="app.cfg.audio.ciderPPE_value === 0.5" v-model="app.cfg.audio.ciderPPE_value" onclick="app.cfg.audio.ciderPPE_value = 0.5"> <button class="md-btn" :disabled="app.cfg.audio.ciderPPE_value === 0.5" v-model="app.cfg.audio.ciderPPE_value" onclick="app.cfg.audio.ciderPPE_value = 0.5; CiderAudio.hierarchical_loading();">
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard')}} {{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard')}}
</button> </button>
<button class="md-btn" style="margin-top: 5px;" :disabled="app.cfg.audio.ciderPPE_value === 0.55" v-model="app.cfg.audio.ciderPPE_value" onclick="app.cfg.audio.ciderPPE_value = 0.55"> <button class="md-btn" style="margin-top: 5px;" :disabled="app.cfg.audio.ciderPPE_value === 0.55" v-model="app.cfg.audio.ciderPPE_value" onclick="app.cfg.audio.ciderPPE_value = 0.55; CiderAudio.hierarchical_loading();">
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive')}} {{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.aggressive')}}
</button> </button>
</div> </div>
@ -114,7 +114,7 @@
<small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description')}}</small> <small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.audioSpatialization.description')}}</small>
</div> </div>
<div class="md-option-segment md-option-segment_auto"> <div class="md-option-segment md-option-segment_auto">
<input type="checkbox" v-model="app.cfg.audio.spatial" v-on:change="toggleSpatial" switch/> <input type="checkbox" v-model="app.cfg.audio.spatial" :disabled="app.cfg.advanced.ciderPPE === true" v-on:change="toggleSpatial" switch/>
</div> </div>
</div> </div>
</div> </div>
@ -132,8 +132,8 @@
<option value="dark.less">{{$root.getLz('settings.option.visual.theme.dark')}}</option> <option value="dark.less">{{$root.getLz('settings.option.visual.theme.dark')}}</option>
<option v-for="theme in themes" :value="theme.file">{{ theme.name }}</option> <option v-for="theme in themes" :value="theme.file">{{ theme.name }}</option>
</select> </select>
<button class="md-btn md-btn-small md-btn-block" @click="installTheme()" style="margin-top: 8px"> <button class="md-btn md-btn-small md-btn-block" @click="gitHubExplore()" style="margin-top: 8px">
{{$root.getLz('settings.option.visual.theme.github.download')}} {{$root.getLz('settings.option.visual.theme.github.explore')}}
</button> </button>
</div> </div>
</div> </div>
@ -774,21 +774,8 @@
} }
}, },
methods: { methods: {
installTheme() { gitHubExplore() {
let self = this app.appRoute("themes-github")
bootbox.prompt(app.getLz('settings.prompt.visual.theme.github.URL'), (result) => {
if (result) {
ipcRenderer.once("theme-installed", (event, arg) => {
if (arg.success) {
self.themes = ipcRenderer.sendSync("get-themes")
notyf.success(app.getLz('settings.notyf.visual.theme.install.success'));
} else {
notyf.error(app.getLz('settings.notyf.visual.theme.install.error'));
}
});
ipcRenderer.invoke("get-github-theme", result)
}
});
}, },
copyLogs() { copyLogs() {
ipcRenderer.send('fetch-log') ipcRenderer.send('fetch-log')
@ -839,15 +826,6 @@
CiderAudio.normalizerOff() CiderAudio.normalizerOff()
} }
}, },
ciderPPE: function () {
if (app.cfg.advanced.ciderPPE) {
if (app.cfg.audio.spatial) {
app.cfg.advanced.ciderPPE = false;
notyf.error(app.getLz('settings.warn.audio.enableAdvancedFunctionality.ciderPPE.compatibility'))
}
}
CiderAudio.hierarchical_loading();
},
toggleSpatial: function () { toggleSpatial: function () {
if (app.cfg.audio.spatial) { if (app.cfg.audio.spatial) {
if (!app.cfg.advanced.ciderPPE) { if (!app.cfg.advanced.ciderPPE) {

View file

@ -0,0 +1,176 @@
<script type="text/x-template" id="themes-github">
<div class="content-inner github-themes-page">
<div class="gh-header">
<div class="row">
<div class="col nopadding">
<h1 class="header-text">Themes from GitHub</h1>
</div>
<div class="col-auto nopadding flex-center">
<button class="md-btn md-btn-small md-btn-block" @click="installThemeURL()">
{{$root.getLz('settings.option.visual.theme.github.download')}}
</button>
</div>
</div>
</div>
<div class="gh-content">
<div class="repos-list">
<ul class="list-group list-group-flush">
<li @click="showRepo(repo)" class="list-group-item list-group-item-dark"
:style="{'background': (repo.id == openRepo.id) ? 'var(--keyColor)' : ''}"
v-for="repo in repos">
<div class="row">
<div class="col flex-center">
<div>
<h4 class="repo-name">{{ repo.description }}</h4>
<div>⭐ {{ repo.stargazers_count }}</div>
</div>
</div>
</div>
</li>
</ul>
</div>
<div class="github-preview" v-if="openRepo.full_name">
<div class="gh-preview-header">
<div class="row nopadding">
<div class="col nopadding flex-center">
<div>
<h3 class="repo-preview-name">{{ openRepo.description }}</h3>
<div>
<div class="svg-icon inline" :style="{'--url': 'url(\'./assets/github.svg\')'}"></div>
<a class="repo-url" target="_blank" :href="openRepo.html_url">{{ openRepo.full_name
}}</a></div>
<div>⭐ {{ openRepo.stargazers_count }}</div>
</div>
</div>
<div class="col-auto nopadding flex-center">
<button class="md-btn md-btn-primary" @click="installThemeRepo(openRepo)">
<span v-if="!themesInstalled.includes(openRepo.full_name)">Install</span>
<span v-else>Update</span>
</button>
</div>
</div>
</div>
<hr>
<div v-html="openRepo.readme" class="github-content"></div>
</div>
<div class="github-preview" v-else>
</div>
</transition>
</div>
</div>
</script>
<script>
Vue.component('themes-github', {
template: "#themes-github",
props: [],
data: function () {
return {
repos: [],
openRepo: {
id: -1,
name: '',
description: '',
html_url: '',
stargazers_count: 0,
owner: {
avatar_url: ''
},
readme: ""
},
themesInstalled: []
}
},
mounted() {
this.getRepos();
this.getInstalledThemes();
},
methods: {
getInstalledThemes() {
let self = this
const themes = ipcRenderer.sendSync("get-themes")
// for each theme, get the github_repo property and push it to the themesInstalled array, if not blank
themes.forEach(theme => {
if (theme.github_repo !== "") {
self.themesInstalled.push(theme.github_repo)
}
})
},
showRepo(repo) {
const self = this
const readmeUrl = `https://raw.githubusercontent.com/${repo.full_name}/main/README.md`;
var requestOptions = {
method: 'GET',
redirect: 'follow'
};
fetch(readmeUrl, requestOptions)
.then(response => response.text())
.then(result => {
self.openRepo = repo
self.openRepo.readme = self.convertReadMe(result);
})
.catch(error => {
self.openRepo = repo
self.openRepo.readme = `This repository doesn't have a README.md file.`;
console.log('error', error)
});
},
convertReadMe(text) {
var converter = new showdown.Converter(),
html = converter.makeHtml(text);
return html
},
installThemeRepo(repo) {
let self = this
let msg = app.stringTemplateParser(app.getLz('settings.option.visual.theme.github.install.confirm'), {
repo: repo.full_name
});
bootbox.confirm(msg, (res) => {
if (res) {
ipcRenderer.once("theme-installed", (event, arg) => {
if (arg.success) {
self.themes = ipcRenderer.sendSync("get-themes")
notyf.success(app.getLz('settings.notyf.visual.theme.install.success'));
} else {
notyf.error(app.getLz('settings.notyf.visual.theme.install.error'));
}
});
ipcRenderer.invoke("get-github-theme", repo.html_url)
}
})
},
installThemeURL() {
let self = this
bootbox.prompt(app.getLz('settings.prompt.visual.theme.github.URL'), (result) => {
if (result) {
ipcRenderer.once("theme-installed", (event, arg) => {
if (arg.success) {
self.themes = ipcRenderer.sendSync("get-themes")
notyf.success(app.getLz('settings.notyf.visual.theme.install.success'));
} else {
notyf.error(app.getLz('settings.notyf.visual.theme.install.error'));
}
});
ipcRenderer.invoke("get-github-theme", result)
}
});
},
getRepos() {
let self = this
var requestOptions = {
method: 'GET',
redirect: 'follow'
};
fetch("https://api.github.com/search/repositories?q=topic:cidermusictheme fork:true", requestOptions)
.then(response => response.text())
.then(result => {
self.repos = JSON.parse(result).items
})
.catch(error => console.log('error', error));
}
}
})
</script>