a (#1334)
* Update ru_RU.json keeping russian lang actual * ok * Add gradient to lyric-footer * *Commit en español Ñ (#1304) * i hate my life (#1307) * world is now a better place * meltdown avoided * meltdown avoided * stylize new listen now childs * full scale artwork, finally * dynamic width for search categories * hd all album work * Update afterPack.js * force hq quality * oops * attempt to fix * misc cleanup * why what * what was i thinking * fix duplicated text in listen now childs * Paginate/infinite scroll for albums, playlists (#1234) * Infinite scroll, pagination to album, playlists * move pagination below tracks * Make page size configurable * remove renderer * Mitigate songs / album slow app issue. * add ratings, library change to web remote (#1285) * Add compact artist header option (#1308) * Support compact artist header (optional) * Add required term * pain e19 still bugged * improve pagination styling * el16 fix * up 1.5.2 * Disable Fullscreen view when artist/album name is clicked. (#1315) * Disable Fullscreen view when artist/album name is clicked. idk why this change didn't exist * Seperate dash from album name * Replace `$root.showSearch()` with `app.appRoute('search')` `$root.showSearch()` prevents going back to previous page from sidebar. * Fix Anim (#1316) * make tracks tab active (#1318) * welp that wasn't it. * Thnks (#1319) * Thnks * i need sleep * Update cider-playlist.ejs * remove v-ripple * attempt to fix flatpak * Update config.yml * minimize categories names * fix versioning * fix versioning v2 * version fix v3 - final * fix categories name for other storefronts * ident unparsed title * center fullscreen * fix share * Add protocol for playpause and nextitem (#1329) * Moved to minimize hide window instead of close * Moved state saving to before quit * build test * fix ci * sudo * ci * use old branch fn * d * revert * Exposed songid in attributes, reimplemented lastfm primary artist scrobbling, cleaned up mkinterop * Moved it back * im over this * attempt airts * use new airtunes branch * *eye roll* * Moved time conversion to built-in MK function * Moved to Electron Notifications * Swapped to array index * keeping this here until for now * debuggin * run ci * allow noti button on macs * No image for now * revert space * Latest releases -> Latest Release * Artwork caching (sorta) * holy balls optimization * save sentry from this Co-authored-by: h0ckerman <35598335+h0ckerman@users.noreply.github.com> Co-authored-by: vapormusic <vietanhfat@gmail.com> Co-authored-by: Monochromish <chillygamer7@gmail.com> Co-authored-by: Gabriel Davila <56521591+mefsaal@users.noreply.github.com> Co-authored-by: Core <64542347+coredev-uk@users.noreply.github.com> Co-authored-by: Maikiwi <stella@mai.kiwi> Co-authored-by: yazninja <yazlesean@gmail.com> Co-authored-by: booploops <49113086+booploops@users.noreply.github.com> Co-authored-by: Kendall Garner <17521368+kgarner7@users.noreply.github.com> Co-authored-by: Pedro Galhardo <pgalhardo@icloud.com> Co-authored-by: Monochromish <79590499+Monochromish@users.noreply.github.com> Co-authored-by: Core <core@c0r3.uk>
This commit is contained in:
parent
a99dddf2b6
commit
5ed045aad1
27 changed files with 298 additions and 183 deletions
|
@ -15,6 +15,11 @@ jobs:
|
|||
executor: cider-ci
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install buildtools
|
||||
command: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y autoconf automake g++ libtool || true
|
||||
- run:
|
||||
name: Update Version Number of App
|
||||
command: sudo chmod +x resources/version.sh && ./resources/version.sh || true
|
||||
|
|
1
.github/workflows/build-macos.yml
vendored
1
.github/workflows/build-macos.yml
vendored
|
@ -91,6 +91,7 @@ jobs:
|
|||
run: |
|
||||
rm cider-yarn.lock || true
|
||||
xcodebuild -version
|
||||
brew install autoconf automake libtool
|
||||
yarn install
|
||||
cp resources/verror-types node_modules/@types/verror/index.d.ts
|
||||
cp resources/macPackager.js node_modules/app-builder-lib/out/macPackager.js
|
||||
|
|
|
@ -227,7 +227,10 @@
|
|||
"darkModeSupport": true,
|
||||
"target": [
|
||||
"dmg"
|
||||
]
|
||||
],
|
||||
"extendInfo": {
|
||||
"NSUserNotificationAlertStyle": "alert"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
LATEST_SHA=$(curl -s https://api.github.com/repos/ciderapp/Cider/branches/stable | grep sha | cut -d '"' -f 4 | sed 's/v//' | xargs)
|
||||
COMMITSINCESTABLE=$(git rev-list $LATEST_SHA..HEAD --count)
|
||||
LATEST_SHA=$(curl -s https://api.github.com/repos/ciderapp/Cider/branches/stable | grep '"sha"' | head -1 | cut -d '"' -f 4)
|
||||
SHA_DATE=$(git show -s --format=%ci $LATEST_SHA)
|
||||
COMMITSINCESTABLE=$(git rev-list $LATEST_SHA..HEAD --count --since="$SHA_DATE")
|
||||
CURRENT_VERSION=$(node -p -e "require('./package.json').version")
|
||||
if [[ $CIRCLE_BRANCH == "main" && $COMMITSINCESTABLE -gt 0 ]]; then
|
||||
NEW_VERSION="${CURRENT_VERSION}-beta.${COMMITSINCESTABLE}"
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
"term.showMore": "Show more",
|
||||
"term.showLess": "Show less",
|
||||
"term.topSongs": "Top Songs",
|
||||
"term.latestReleases": "Latest Releases",
|
||||
"term.latestReleases": "Latest Release",
|
||||
"term.time.added": "Added",
|
||||
"term.time.released": "Released",
|
||||
"term.time.updated": "Updated",
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
"term.showMore": "Show more",
|
||||
"term.showLess": "Show less",
|
||||
"term.topSongs": "Top Songs",
|
||||
"term.latestReleases": "Latest Releases",
|
||||
"term.latestReleases": "Latest Release",
|
||||
"term.time.added": "Added",
|
||||
"term.time.released": "Released",
|
||||
"term.time.updated": "Updated",
|
||||
|
|
|
@ -168,6 +168,14 @@ export class AppEvents {
|
|||
utils.getWindow().webContents.executeJavaScript(`ipcRenderer.send('lastfm:auth', "${authURI.split('lastfm?token=')[1]}")`).catch(console.error)
|
||||
}
|
||||
}
|
||||
else if (arg.includes('playpause')) {
|
||||
//language=JS
|
||||
utils.getWindow().webContents.executeJavaScript('MusicKitInterop.playPause()')
|
||||
}
|
||||
else if (arg.includes('nextitem')) {
|
||||
//language=JS
|
||||
utils.getWindow().webContents.executeJavaScript('app.mk.skipToNextItem()')
|
||||
}
|
||||
// Play
|
||||
else if (arg.includes('/play/')) { //Steer away from protocol:// specific conditionals
|
||||
const playParam = arg.split('/play/')[1]
|
||||
|
|
|
@ -1183,11 +1183,6 @@ export class BrowserWindow {
|
|||
app.quit();
|
||||
})
|
||||
|
||||
app.on('before-quit', () => {
|
||||
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('play', (_event, type, id) => {
|
||||
BrowserWindow.win.webContents.executeJavaScript(`
|
||||
MusicKit.getInstance().setQueue({ ${type}: '${id}', parameters : {l : app.mklang}}).then(function(queue) {
|
||||
|
@ -1442,70 +1437,63 @@ export class BrowserWindow {
|
|||
FULL_SCREEN: 3,
|
||||
};
|
||||
let wndState = WND_STATE.NORMAL;
|
||||
const win = BrowserWindow.win;
|
||||
let isQuitting = false;
|
||||
|
||||
BrowserWindow.win.on("resize", (_: any) => {
|
||||
const isMaximized = BrowserWindow.win.isMaximized();
|
||||
const isMinimized = BrowserWindow.win.isMinimized();
|
||||
const isFullScreen = BrowserWindow.win.isFullScreen();
|
||||
win.on("resize", (_: any) => {
|
||||
const isMaximized = win.isMaximized();
|
||||
const isMinimized = win.isMinimized();
|
||||
const isFullScreen = win.isFullScreen();
|
||||
const state = wndState;
|
||||
if (isMinimized && state !== WND_STATE.MINIMIZED) {
|
||||
wndState = WND_STATE.MINIMIZED;
|
||||
BrowserWindow.win.webContents.send('window-state-changed', 'minimized');
|
||||
win.webContents.send('window-state-changed', 'minimized');
|
||||
} else if (isFullScreen && state !== WND_STATE.FULL_SCREEN) {
|
||||
wndState = WND_STATE.FULL_SCREEN;
|
||||
BrowserWindow.win.webContents.send('window-state-changed', 'fullscreen')
|
||||
win.webContents.send('window-state-changed', 'fullscreen')
|
||||
} else if (isMaximized && state !== WND_STATE.MAXIMIZED) {
|
||||
wndState = WND_STATE.MAXIMIZED;
|
||||
BrowserWindow.win.webContents.send('window-state-changed', 'maximized')
|
||||
BrowserWindow.win.webContents.executeJavaScript(`app.chrome.maximized = true`);
|
||||
win.webContents.send('window-state-changed', 'maximized')
|
||||
win.webContents.executeJavaScript(`app.chrome.maximized = true`);
|
||||
} else if (state !== WND_STATE.NORMAL) {
|
||||
wndState = WND_STATE.NORMAL;
|
||||
BrowserWindow.win.webContents.send('window-state-changed', 'normal')
|
||||
BrowserWindow.win.webContents.executeJavaScript(
|
||||
win.webContents.send('window-state-changed', 'normal')
|
||||
win.webContents.executeJavaScript(
|
||||
`app.chrome.maximized = false`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
win.on("close", (e: any) => {
|
||||
if ((process.platform === "darwin" || utils.getStoreValue("general.close_button_hide")) && !isQuitting) {
|
||||
e.preventDefault()
|
||||
win.hide()
|
||||
}
|
||||
})
|
||||
|
||||
let isQuiting = false
|
||||
|
||||
BrowserWindow.win.on("close", (event: Event) => {
|
||||
if ((utils.getStoreValue('general.close_button_hide') || process.platform === "darwin") && !isQuiting) {
|
||||
event.preventDefault();
|
||||
BrowserWindow.win.hide();
|
||||
} else {
|
||||
BrowserWindow.win.webContents.executeJavaScript(`
|
||||
win.on("closed", (_: any) => {
|
||||
win.webContents.executeJavaScript(`
|
||||
window.localStorage.setItem("currentTrack", JSON.stringify(app.mk.nowPlayingItem));
|
||||
window.localStorage.setItem("currentTime", JSON.stringify(app.mk.currentPlaybackTime));
|
||||
window.localStorage.setItem("currentQueue", JSON.stringify(app.mk.queue._unplayedQueueItems));
|
||||
ipcRenderer.send('stopGCast','');`)
|
||||
BrowserWindow.win.destroy();
|
||||
}
|
||||
})
|
||||
|
||||
app.on('before-quit', () => {
|
||||
isQuiting = true
|
||||
isQuitting = true;
|
||||
});
|
||||
|
||||
app.on('activate', function () {
|
||||
BrowserWindow.win.show()
|
||||
BrowserWindow.win.focus()
|
||||
win.show()
|
||||
});
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', () => {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
BrowserWindow.win.on("closed", () => {
|
||||
BrowserWindow.win = null;
|
||||
});
|
||||
|
||||
// Set window Handler
|
||||
BrowserWindow.win.webContents.setWindowOpenHandler((x: any) => {
|
||||
if (x.url.includes("apple") || x.url.includes("localhost")) {
|
||||
|
|
|
@ -65,6 +65,7 @@ export class Store {
|
|||
],
|
||||
"albums": [
|
||||
"CommandOrControl",
|
||||
process.platform == "darwin" ? "Option" : (process.platform == "linux" ? "Shift" : "Alt"),
|
||||
"A"
|
||||
],
|
||||
"artists": [
|
||||
|
@ -134,6 +135,7 @@ export class Store {
|
|||
"scrobble_after": 50,
|
||||
"filter_loop": false,
|
||||
"filter_types": {},
|
||||
"remove_featured": false,
|
||||
"secrets": {
|
||||
"username": "",
|
||||
"key": ""
|
||||
|
|
|
@ -90,7 +90,8 @@ export class utils {
|
|||
|
||||
if (language !== "en_US" && fs.existsSync(path.join(this.paths.i18nPath, `${language}.json`))) {
|
||||
i18n = Object.assign(i18n, JSON.parse(fs.readFileSync(path.join(this.paths.i18nPath, `${language}.json`), "utf8")));
|
||||
} else if (!fs.existsSync(path.join(this.paths.i18nPath, `${language}.json`))) {
|
||||
}
|
||||
/* else if (!fs.existsSync(path.join(this.paths.i18nPath, `${language}.json`))) {
|
||||
fetch(`https://raw.githubusercontent.com/ciderapp/Cider/main/src/i18n/${language}.json`)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
|
@ -101,7 +102,8 @@ export class utils {
|
|||
i18n = Object.assign(i18n, JSON.parse(fs.readFileSync(path.join(this.paths.i18nPath, `en_US.json`), "utf8")));
|
||||
}
|
||||
})
|
||||
}
|
||||
} */
|
||||
|
||||
if (key) {
|
||||
return i18n[key]
|
||||
} else {
|
||||
|
|
|
@ -131,7 +131,7 @@ export default class lastfm {
|
|||
|
||||
if (!attributes.lfmAlbum) {
|
||||
this._lfm.album.getInfo({
|
||||
"artist": attributes.artistName,
|
||||
"artist": attributes.primaryArtist,
|
||||
"album": attributes.albumName
|
||||
}, (err: any, data: any) => {
|
||||
if (err) {
|
||||
|
@ -144,7 +144,7 @@ export default class lastfm {
|
|||
}
|
||||
})
|
||||
} else {
|
||||
this._lfm.track.getCorrection(attributes.artistName, attributes.name, (err: any, data: any) => {
|
||||
this._lfm.track.getCorrection(attributes.primaryArtist, attributes.name, (err: any, data: any) => {
|
||||
if (err) {
|
||||
console.error(`[${lastfm.name}] [track.getCorrection] Error: ${typeof err === "string" ? err : err.message}`)
|
||||
return {};
|
||||
|
|
118
src/main/plugins/playbackNotifications.ts
Normal file
118
src/main/plugins/playbackNotifications.ts
Normal file
|
@ -0,0 +1,118 @@
|
|||
import fetch from "electron-fetch";
|
||||
import {nativeImage, Notification} from "electron";
|
||||
import NativeImage = Electron.NativeImage;
|
||||
|
||||
export default class playbackNotifications {
|
||||
|
||||
|
||||
/**
|
||||
* Base Plugin Details (Eventually implemented into a GUI in settings)
|
||||
*/
|
||||
public name: string = 'Playback Notifications';
|
||||
public description: string = 'Creates notifications on playback.';
|
||||
public version: string = '1.0.0';
|
||||
public author: string = 'Core';
|
||||
public contributors: string[] = ['Core', 'Monochromish'];
|
||||
|
||||
private _utils: any;
|
||||
private _notification: Notification | undefined;
|
||||
private _artworkImage: { [key: string]: NativeImage } = {};
|
||||
private _artworkNums: Array<string> = [];
|
||||
|
||||
/**
|
||||
* Creates playback notification
|
||||
* @param a: Music Attributes
|
||||
*/
|
||||
createNotification(a: any): void {
|
||||
if (this._notification) {
|
||||
this._notification.close();
|
||||
}
|
||||
|
||||
this._notification = new Notification({
|
||||
title: a.name,
|
||||
body: `${a.artistName} — ${a.albumName}`,
|
||||
silent: true,
|
||||
icon: this._artworkImage[a.artwork.url],
|
||||
urgency: 'low',
|
||||
actions: [
|
||||
{
|
||||
'type': 'button',
|
||||
'text': 'Play/Pause'
|
||||
},
|
||||
{
|
||||
'type': 'button',
|
||||
'text': 'Next'
|
||||
}
|
||||
],
|
||||
toastXml: `
|
||||
<toast>
|
||||
<visual>
|
||||
<binding template="ToastText02">
|
||||
<text id="1">${a?.name.replace(/&/g, '&')}</text>
|
||||
<text id="2">${a?.artistName.replace(/&/g, '&')} — ${a?.albumName.replace(/&/g, '&')}</text>
|
||||
</binding>
|
||||
</visual>
|
||||
<actions>
|
||||
<action content="Play/Pause" activationType="protocol" arguments="cider://playpause/"/>
|
||||
<action content="Next" activationType="protocol" arguments="cider://nextitem/"/>
|
||||
</actions>
|
||||
</toast>`
|
||||
});
|
||||
|
||||
// image implementation in windows toasts
|
||||
//<image id="1" src="path to image" alt="img"/>
|
||||
|
||||
this._notification.on('click', (_: any) => {
|
||||
this._utils.getWindow().show()
|
||||
this._utils.getWindow().focus()
|
||||
})
|
||||
|
||||
this._notification.on('close', (_: any) => {
|
||||
this._notification = undefined;
|
||||
})
|
||||
|
||||
this._notification.on('action', (event: any, action: any) => {
|
||||
if (action === 0) {
|
||||
this._utils.playback.playPause()
|
||||
} else if (action === 1) {
|
||||
this._utils.playback.next()
|
||||
}
|
||||
})
|
||||
|
||||
this._notification.show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************************
|
||||
* Public Methods
|
||||
* ****************************************************************************************/
|
||||
|
||||
/**
|
||||
* Runs on plugin load (Currently run on application start)
|
||||
*/
|
||||
constructor(utils: any) {
|
||||
this._utils = utils;
|
||||
console.debug(`[Plugin][${this.name}] Loading Complete.`);
|
||||
|
||||
utils.getIPCMain().on('playbackNotifications:create', (event: any, a: any) => {
|
||||
a.artwork.url = a.artwork.url.replace('/{w}x{h}bb', '/512x512bb').replace('/2000x2000bb', '/35x35bb');
|
||||
|
||||
if (this._artworkNums.length > 20) {
|
||||
delete this._artworkImage[this._artworkNums[0]];
|
||||
this._artworkNums.shift();
|
||||
}
|
||||
|
||||
if (this._artworkImage[a.artwork.url]) {
|
||||
this.createNotification(a);
|
||||
} else {
|
||||
fetch(a.artwork.url).then(async blob => {
|
||||
this._artworkImage[a.artwork.url] = nativeImage.createFromBuffer(Buffer.from(await blob.arrayBuffer()));
|
||||
this._artworkNums[this._artworkNums.length] = a.artwork.url;
|
||||
this.createNotification(a);
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -88,14 +88,16 @@ export default class RAOP {
|
|||
|
||||
`;
|
||||
|
||||
private ondeviceup(name: any, host: any, port: any, addresses: any, text: any) {
|
||||
if (this.castDevices.findIndex((item: any) => item.name == host.replace(".local","") && item.port == port && item.addresses == addresses) === -1) {
|
||||
private ondeviceup(name: any, host: any, port: any, addresses: any, text: any, airplay2: any = null) {
|
||||
console.log(this.castDevices.findIndex((item: any) => {return (item.name == host.replace(".local","") && item.port == port )}))
|
||||
if (this.castDevices.findIndex((item: any) => {return (item.name == host.replace(".local","") && item.port == port )}) == -1) {
|
||||
this.castDevices.push({
|
||||
name: host.replace(".local",""),
|
||||
host: addresses ? addresses[0] : '',
|
||||
port: port,
|
||||
addresses: addresses,
|
||||
txt: text
|
||||
txt: text,
|
||||
airplay2: airplay2
|
||||
});
|
||||
if (this.devices.indexOf(host) === -1) {
|
||||
this.devices.push(host);
|
||||
|
@ -147,7 +149,7 @@ export default class RAOP {
|
|||
browser.on('ready', browser.discover);
|
||||
|
||||
browser.on('update', (service: any) => {
|
||||
if (service.addresses && service.fullname && (service.fullname.includes('_raop._tcp') || service.fullname.includes('_airplay._tcp'))) {
|
||||
if (service.addresses && service.fullname && (service.fullname.includes('_raop._tcp'))) {
|
||||
// console.log(service.txt)
|
||||
this._win.webContents.executeJavaScript(`console.log(
|
||||
"${service.name} ${service.host}:${service.port} ${service.addresses}"
|
||||
|
@ -156,6 +158,19 @@ export default class RAOP {
|
|||
}
|
||||
});
|
||||
|
||||
const browser2 = this.mdns.createBrowser(this.mdns.tcp('airplay'));
|
||||
browser2.on('ready', browser2.discover);
|
||||
|
||||
browser2.on('update', (service: any) => {
|
||||
if (service.addresses && service.fullname && (service.fullname.includes('_airplay._tcp'))) {
|
||||
// console.log(service.txt)
|
||||
this._win.webContents.executeJavaScript(`console.log(
|
||||
"${service.name} ${service.host}:${service.port} ${service.addresses}"
|
||||
)`);
|
||||
this.ondeviceup(service.name, service.host, service.port, service.addresses, service.txt, true);
|
||||
}
|
||||
});
|
||||
|
||||
// const browser2 = this.mdns.createBrowser(this.mdns.tcp('airplay'));
|
||||
// browser2.on('ready', browser2.discover);
|
||||
|
||||
|
@ -173,7 +188,7 @@ export default class RAOP {
|
|||
|
||||
|
||||
|
||||
electron.ipcMain.on("performAirplayPCM", (event, ipv4, ipport, sepassword, title, artist, album, artworkURL,txt) => {
|
||||
electron.ipcMain.on("performAirplayPCM", (event, ipv4, ipport, sepassword, title, artist, album, artworkURL,txt,airplay2dv) => {
|
||||
|
||||
if (ipv4 != this.ipairplay || ipport != this.portairplay) {
|
||||
if (this.airtunes == null) { this.airtunes = new this.u()}
|
||||
|
@ -183,7 +198,9 @@ export default class RAOP {
|
|||
port: ipport,
|
||||
volume: 50,
|
||||
password: sepassword,
|
||||
txt: txt
|
||||
txt: txt,
|
||||
airplay2: airplay2dv,
|
||||
debug: true
|
||||
});
|
||||
// console.log('lol',txt)
|
||||
this.device.on('status', (status: any) => {
|
||||
|
|
|
@ -6,6 +6,7 @@ let cache = {playParams: {id: 0}, status: null, remainingTime: 0},
|
|||
|
||||
const MusicKitInterop = {
|
||||
init: function () {
|
||||
/* MusicKit.Events.playbackStateDidChange */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackStateDidChange, () => {
|
||||
const attributes = MusicKitInterop.getAttributes()
|
||||
if (MusicKitInterop.filterTrack(attributes, true, false)) {
|
||||
|
@ -14,19 +15,28 @@ const MusicKitInterop = {
|
|||
}
|
||||
});
|
||||
|
||||
/** wsapi */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackProgressDidChange, () => {
|
||||
ipcRenderer.send('wsapi-updatePlaybackState', MusicKitInterop.getAttributes());
|
||||
/* MusicKit.Events.playbackProgressDidChange */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackProgressDidChange, async () => {
|
||||
const attributes = MusicKitInterop.getAttributes()
|
||||
// wsapi call
|
||||
ipcRenderer.send('wsapi-updatePlaybackState', attributes);
|
||||
// lastfm call
|
||||
if (app.mk.currentPlaybackProgress === (app.cfg.connectivity.lastfm.scrobble_after / 100)) {
|
||||
attributes.primaryArtist = (app.cfg.connectivity.lastfm.enabled && app.cfg.connectivity.lastfm.remove_featured) ? await this.fetchPrimaryArtist(attributes.artistName) : attributes.artistName;
|
||||
ipcRenderer.send('lastfm:scrobbleTrack', attributes);
|
||||
}
|
||||
});
|
||||
/** wsapi */
|
||||
|
||||
/* MusicKit.Events.playbackTimeDidChange */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackTimeDidChange, () => {
|
||||
ipcRenderer.send('mpris:playbackTimeDidChange', (MusicKit.getInstance()?.currentPlaybackTime * 1000 * 1000 ) ?? 0);
|
||||
})
|
||||
ipcRenderer.send('mpris:playbackTimeDidChange', (MusicKit.getInstance()?.currentPlaybackTime * 1000 * 1000) ?? 0);
|
||||
});
|
||||
|
||||
/* MusicKit.Events.nowPlayingItemDidChange */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, async () => {
|
||||
console.debug('[cider:preload] nowPlayingItemDidChange')
|
||||
const attributes = MusicKitInterop.getAttributes()
|
||||
attributes.primaryArtist = (app.cfg.connectivity.lastfm.enabled && app.cfg.connectivity.lastfm.remove_featured) ? await this.fetchPrimaryArtist(attributes.artistName) : attributes.artistName;
|
||||
|
||||
if (MusicKitInterop.filterTrack(attributes, false, true)) {
|
||||
global.ipcRenderer.send('nowPlayingItemDidChange', attributes);
|
||||
|
@ -34,24 +44,32 @@ const MusicKitInterop = {
|
|||
global.ipcRenderer.send('lastfm:nowPlayingChange', attributes);
|
||||
}
|
||||
|
||||
if (app.cfg.general.playbackNotifications && !document.hasFocus() && attributes.artistName && attributes.artwork && attributes.name) {
|
||||
global.ipcRenderer.send('playbackNotifications:create', attributes);
|
||||
}
|
||||
|
||||
if (MusicKit.getInstance().nowPlayingItem) {
|
||||
await this.sleep(750);
|
||||
MusicKit.getInstance().playbackRate = app.cfg.audio.playbackRate;
|
||||
}
|
||||
});
|
||||
|
||||
/* MusicKit.Events.authorizationStatusDidChange */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.authorizationStatusDidChange, () => {
|
||||
global.ipcRenderer.send('authorizationStatusDidChange', MusicKit.getInstance().authorizationStatus)
|
||||
});
|
||||
|
||||
/* MusicKit.Events.mediaPlaybackError */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.mediaPlaybackError, (e) => {
|
||||
console.warn(`[cider:preload] mediaPlaybackError] ${e}`);
|
||||
});
|
||||
|
||||
/* MusicKit.Events.shuffleModeDidChange */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.shuffleModeDidChange, () => {
|
||||
global.ipcRenderer.send('shuffleModeDidChange', MusicKit.getInstance().shuffleMode)
|
||||
});
|
||||
|
||||
/* MusicKit.Events.repeatModeDidChange */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.repeatModeDidChange, () => {
|
||||
global.ipcRenderer.send('repeatModeDidChange', MusicKit.getInstance().repeatMode)
|
||||
});
|
||||
|
@ -63,6 +81,15 @@ const MusicKitInterop = {
|
|||
});
|
||||
},
|
||||
|
||||
async fetchPrimaryArtist(artist) {
|
||||
if (app.mk.nowPlayingItem?.relationships?.artists) {
|
||||
const artist = await app.mk.api.artist(app.mk.nowPlayingItem.relationships.artists.data[0].id)
|
||||
return artist.attributes.name
|
||||
} else {
|
||||
return artist
|
||||
}
|
||||
},
|
||||
|
||||
getAttributes: function () {
|
||||
const mk = MusicKit.getInstance()
|
||||
const nowPlayingItem = mk.nowPlayingItem;
|
||||
|
@ -71,6 +98,7 @@ const MusicKitInterop = {
|
|||
const currentPlaybackProgress = mk.currentPlaybackProgress;
|
||||
const attributes = (nowPlayingItem != null ? nowPlayingItem.attributes : {});
|
||||
|
||||
attributes.songId = attributes.songId ?? attributes.playParams?.catalogId ?? attributes.playParams?.id
|
||||
attributes.status = isPlayingExport ?? null;
|
||||
attributes.name = attributes?.name ?? 'no-title-found';
|
||||
attributes.artwork = attributes?.artwork ?? {url: ''};
|
||||
|
|
|
@ -480,6 +480,7 @@
|
|||
display: inline-flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,11 +33,14 @@ if (app.cfg.advanced.disableLogging === true) {
|
|||
// Mount Vue to #app
|
||||
app.$mount("#app")
|
||||
|
||||
// Init CiderAudio
|
||||
if (app.cfg.advanced.AudioContext === true) {
|
||||
CiderAudio.init()
|
||||
// Init CiderAudio and force audiocontext
|
||||
if (app.cfg.advanced.AudioContext != true) {
|
||||
app.cfg.advanced.AudioContext = true;
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
CiderAudio.init()
|
||||
|
||||
// Import gamepad support
|
||||
app.simulateGamepad = simulateGamepad
|
||||
app.spawnMica = spawnMica
|
||||
|
|
|
@ -949,12 +949,6 @@ const app = new Vue({
|
|||
}
|
||||
});
|
||||
|
||||
this.mk.addEventListener(MusicKit.Events.playbackProgressDidChange, () => {
|
||||
if (self.mk.currentPlaybackProgress === (app.cfg.connectivity.lastfm.scrobble_after / 100)) {
|
||||
ipcRenderer.send('lastfm:scrobbleTrack', MusicKitInterop.getAttributes());
|
||||
}
|
||||
})
|
||||
|
||||
this.mk.addEventListener(MusicKit.Events.playbackStateDidChange, (event) => {
|
||||
ipcRenderer.send('wsapi-updatePlaybackState', wsapi.getAttributes());
|
||||
document.body.setAttribute("playback-state", event.state == 2 ? "playing" : "paused")
|
||||
|
@ -1013,8 +1007,8 @@ const app = new Vue({
|
|||
try {localStorage.setItem("playingBitrate", app.mk.nowPlayingItem.flavor)}
|
||||
catch(e) {}
|
||||
}
|
||||
if (!app.cfg.audio.normalization && app.cfg.advanced.AudioContext === false) { CiderAudio.hierarchical_loading(); }
|
||||
|
||||
if (app.cfg.audio.normalization === false) { CiderAudio.hierarchical_loading(); } // Just Reload for Adaptive CAP if norm is off
|
||||
else {
|
||||
// get unencrypted audio previews to get SoundCheck's normalization tag
|
||||
try {
|
||||
|
@ -1080,17 +1074,6 @@ const app = new Vue({
|
|||
app.getNowPlayingArtworkBG(32);
|
||||
app.loadLyrics();
|
||||
|
||||
// Playback Notifications
|
||||
if (this.cfg.general.playbackNotifications && !document.hasFocus() && a.artistName && a.artwork && a.name) {
|
||||
if (this.notification) {
|
||||
this.notification.close()
|
||||
}
|
||||
this.notification = new Notification(a.name, {
|
||||
body: `${a.artistName} — ${a.albumName}`,
|
||||
icon: a.artwork.url.replace('/{w}x{h}bb', '/512x512bb').replace('/2000x2000bb', '/35x35bb'),
|
||||
silent: true,
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
let i = (document.querySelector('#apple-music-player')?.src ?? "")
|
||||
if (i.endsWith(".m3u8") || i.endsWith(".m3u")) {
|
||||
|
@ -1887,27 +1870,7 @@ const app = new Vue({
|
|||
|
||||
return dDisplay + (dDisplay && hDisplay ? ", " : "") + hDisplay + (hDisplay && mDisplay ? ", " : "") + mDisplay;
|
||||
} else {
|
||||
let returnTime = datetime.toISOString().substring(11, 19);
|
||||
|
||||
const timeGates = {
|
||||
600: 15, // 10 Minutes
|
||||
3600: 14, // Hour
|
||||
36000: 12, // 10 Hours
|
||||
}
|
||||
|
||||
for (let key in timeGates) {
|
||||
if (seconds < key) {
|
||||
returnTime = datetime.toISOString().substring(timeGates[key], 19)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Add the days on the front
|
||||
if (seconds >= 86400) {
|
||||
returnTime = parseInt(datetime.toISOString().substring(8, 10)) - 1 + ":" + returnTime
|
||||
}
|
||||
|
||||
return returnTime
|
||||
return MusicKit.formatMediaTime(seconds);
|
||||
}
|
||||
},
|
||||
hashCode(str) {
|
||||
|
@ -4391,7 +4354,7 @@ const app = new Vue({
|
|||
"id": "equalizer",
|
||||
"icon": "../views/svg/speaker.svg",
|
||||
"name": app.getLz('term.equalizer'),
|
||||
"hidden": true,
|
||||
"hidden": false,
|
||||
"action": function () {
|
||||
app.modals.equalizer = true
|
||||
app.modals.audioSettings = false
|
||||
|
@ -4401,7 +4364,7 @@ const app = new Vue({
|
|||
"id": "audioLab",
|
||||
"icon": "../views/svg/speaker.svg",
|
||||
"name": app.getLz('settings.option.audio.audioLab'),
|
||||
"hidden": true,
|
||||
"hidden": false,
|
||||
"action": function () {
|
||||
app.openSettingsPage('audiolabs')
|
||||
}
|
||||
|
@ -4409,10 +4372,12 @@ const app = new Vue({
|
|||
]
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (this.cfg.advanced.AudioContext) {
|
||||
menus.normal.items.find(i => i.id === 'audioLab').hidden = false
|
||||
menus.normal.items.find(i => i.id === 'equalizer').hidden = false
|
||||
}
|
||||
*/
|
||||
if (this.contextExt) {
|
||||
if (this.contextExt.normal) {
|
||||
menus.normal.items = menus.normal.items.concat(this.contextExt.normal)
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
</button>
|
||||
<button
|
||||
class="usermenu-item"
|
||||
@click="cfg.advanced.AudioContext ? modals.castMenu = true :(cfg.advanced.AudioContext = true, modals.castMenu = true)"
|
||||
@click="modals.castMenu = true"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/cast.svg") %>
|
||||
|
@ -76,7 +76,7 @@
|
|||
</button>
|
||||
<button
|
||||
class="usermenu-item"
|
||||
@click="cfg.advanced.AudioContext ? modals.audioSettings = true : (cfg.advanced.AudioContext = true, modals.audioSettings = true)"
|
||||
@click="modals.audioSettings = true"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/headphones.svg") %>
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
<button class="playback-button--small cast"
|
||||
:title="$root.getLz('term.cast')"
|
||||
v-b-tooltip.hover
|
||||
@click="cfg.advanced.AudioContext ? modals.castMenu = true : (cfg.advanced.AudioContext = true, modals.castMenu = true)"></button>
|
||||
@click="modals.castMenu = true"></button>
|
||||
</div>
|
||||
<div class="app-chrome-item generic">
|
||||
<button class="playback-button--small queue" :class="{'active': drawer.panel == 'queue'}"
|
||||
|
|
|
@ -231,7 +231,7 @@
|
|||
</div>
|
||||
<div class="app-chrome-item generic">
|
||||
<button class="playback-button--small cast" :title="$root.getLz('term.cast')"
|
||||
@click="cfg.advanced.AudioContext ? modals.castMenu = true : (cfg.advanced.AudioContext = true, modals.castMenu = true)"
|
||||
@click="modals.castMenu = true"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item generic">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class="modal-window airplay-modal">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">{{'Enter password'}}</div>
|
||||
<button class="close-btn" @click="close()" :aria-label="app.getLz('action.close')"></button>
|
||||
<button class="close-btn" @click="close()" :aria-label="this.$root.getLz('action.close')"></button>
|
||||
</div>
|
||||
<div class="modal-content" style="overflow-y: overlay; padding: 3%">
|
||||
<input type="text" v-model="passcode"/>
|
||||
|
|
|
@ -116,7 +116,7 @@
|
|||
},
|
||||
setAirPlayCast(device) {
|
||||
this.activeCasts.push(device);
|
||||
ipcRenderer.send("performAirplayPCM",device.host,device.port,null,"","","","",device.txt)
|
||||
ipcRenderer.send("performAirplayPCM",device.host,device.port,null,"","","","",device.txt,device.airplay2)
|
||||
},
|
||||
stopCasting() {
|
||||
CiderAudio.stopAudio();
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
return color
|
||||
},
|
||||
async checkLibrary() {
|
||||
if ((this.item?.id ?? '').toString().startsWith('ciderlocal')){
|
||||
if ((this.item?.id ?? '').toString().startsWith('ciderlocal')) {
|
||||
return true
|
||||
}
|
||||
if (this.addedToLibrary) { return this.addedToLibrary }
|
||||
|
@ -408,7 +408,7 @@
|
|||
"icon": "./assets/arrow-bend-up.svg",
|
||||
"action": function () {
|
||||
let type = self.item.attributes.playParams?.kind ?? self.item.type
|
||||
if (type == "podcast-episodes") {type = "episode"}
|
||||
if (type == "podcast-episodes") { type = "episode" }
|
||||
app.mk.playNext({ [type]: self.item.attributes.playParams?.id ?? self.item.id })
|
||||
app.mk.queue._reindex()
|
||||
app.selectedMediaItems = []
|
||||
|
@ -419,7 +419,7 @@
|
|||
"icon": "./assets/arrow-bend-down.svg",
|
||||
"action": function () {
|
||||
let type = self.item.attributes.playParams?.kind ?? self.item.type
|
||||
if (type == "podcast-episodes") {type = "episode"}
|
||||
if (type == "podcast-episodes") { type = "episode" }
|
||||
app.mk.playLater({ [type]: self.item.attributes.playParams?.id ?? self.item.id })
|
||||
app.mk.queue._reindex()
|
||||
app.selectedMediaItems = []
|
||||
|
@ -452,10 +452,16 @@
|
|||
{
|
||||
"icon": "./assets/feather/share.svg",
|
||||
"name": app.getLz('action.share'),
|
||||
"action": function () {
|
||||
if (!self.item.attributes.url && self.item.relationships) {
|
||||
if (self.item.relationships.catalog) {
|
||||
app.mkapi(self.item.attributes.playParams?.kind, false, self.item.relationships.catalog.data[0].id).then(u => { self.app.copyToClipboard((u.data.data.length && u.data.data.length > 0) ? u.data.data[0].attributes.url : u.data.data.attributes.url) })
|
||||
"action": async function () {
|
||||
let item = self.item
|
||||
if (!item.attributes.url) {
|
||||
if (item.type.includes("library")) {
|
||||
let result = (await app.mk.api.v3.music(`/v1/me/library/${item.type.replace("library-", '')}/${item.id}/catalog`)).data.data[0]
|
||||
if(result.attributes.url) {
|
||||
self.app.copyToClipboard(result.attributes.url)
|
||||
}else{
|
||||
notyf.error("Failed to get share URL")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.app.copyToClipboard(self.item.attributes.url)
|
||||
|
@ -465,10 +471,16 @@
|
|||
{
|
||||
"icon": "./assets/feather/share.svg",
|
||||
"name": `${app.getLz('action.share')} (song.link)`,
|
||||
"action": function () {
|
||||
if (!self.item.attributes.url && self.item.relationships) {
|
||||
if (self.item.relationships.catalog) {
|
||||
app.mkapi(self.item.attributes.playParams?.kind, false, self.item.relationships.catalog.data[0].id).then(u => { self.app.songLinkShare((u.data.data.length && u.data.data.length > 0) ? u.data.data[0].attributes.url : u.data.data.attributes.url) })
|
||||
"action": async function () {
|
||||
let item = self.item
|
||||
if (!item.attributes.url) {
|
||||
if (item.type.includes("library")) {
|
||||
let result = (await app.mk.api.v3.music(`/v1/me/library/${item.type.replace("library-", '')}/${item.id}/catalog`)).data.data[0]
|
||||
if(result.attributes.url) {
|
||||
self.app.copyToClipboard(result.attributes.url)
|
||||
}else{
|
||||
notyf.error("Failed to get share URL")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.app.songLinkShare(self.item.attributes.url)
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<div class="title"
|
||||
:title="item.attributes?.name ?? (item.relationships?.contents?.data[0]?.attributes?.name ?? (item.attributes?.editorialNotes?.name ?? ''))"
|
||||
v-if="item.attributes.artistNames == null || kind != 'card'" @click='app.routeView(item)'>
|
||||
<div class="item-navigate text-overflow-elipsis">{{ item.attributes?.name ??
|
||||
<div class="item-navigate text-overflow-elipsis">{{ item.attributes?.name.replace(/ /g, ' ').replace(/Apple Music |^Apple |/g, '') ??
|
||||
(item.relationships?.contents?.data[0]?.attributes?.name ??
|
||||
(item.attributes?.editorialNotes?.name ?? '')) }}
|
||||
</div>
|
||||
|
|
|
@ -348,20 +348,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality')}}
|
||||
<br>
|
||||
<small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.description')}}</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.advanced.AudioContext"
|
||||
v-on:change="toggleAudioContext"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('term.equalizer')}}
|
||||
</div>
|
||||
|
@ -371,7 +357,7 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment" style="white-space: pre-line;">
|
||||
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.audioNormalization')}}
|
||||
<small>{{app.cfg.audio.equalizer.vibrantBass != 0 ||
|
||||
|
@ -391,7 +377,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="md-option-line"
|
||||
v-show="app.cfg.advanced.AudioContext && app.cfg.audio.normalization && app.cfg.audio.advanced">
|
||||
v-show="app.cfg.audio.normalization && app.cfg.audio.advanced">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.audio.dbspl.display')}}
|
||||
<br>
|
||||
|
@ -419,7 +405,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</b-tab>
|
||||
<b-tab v-if="app.cfg.advanced.AudioContext">
|
||||
<b-tab>
|
||||
<template #title>
|
||||
<div>
|
||||
<svg-icon url="./assets/feather/zap.svg" classes="svg-md" name="settings-audiolabs"/>
|
||||
|
@ -1062,6 +1048,17 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.connectivity.lastfm.enabled">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.connectivity.lastfmScrobble.removeFeatured')}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.connectivity.lastfm.remove_featured"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.connectivity.lastfm.enabled">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.connectivity.lastfmScrobble.filterTypes')}}
|
||||
|
@ -1462,21 +1459,6 @@
|
|||
removeExperiment(flag) {
|
||||
app.cfg.advanced.experiments.splice(app.cfg.advanced.experiments.indexOf(flag), 1);
|
||||
},
|
||||
toggleAudioContext: function () {
|
||||
if (app.cfg.advanced.AudioContext === true) {
|
||||
if (navigator.hardwareConcurrency < 6) {
|
||||
app.confirm(app.getLz("settings.warn.audio.enableAdvancedFunctionality.lowcores"), function (result) {
|
||||
if (result) {
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
window.location.reload()
|
||||
}
|
||||
} else {
|
||||
window.location.reload()
|
||||
}
|
||||
},
|
||||
toggleNormalization: function () {
|
||||
if (app.cfg.audio.normalization) {
|
||||
CiderAudio.normalizerOn()
|
||||
|
|
|
@ -6,15 +6,7 @@
|
|||
<b-jumbotron :header="$root.getLz('settings.option.audio.audioLab')"
|
||||
lead="Designed by Cider Acoustic Technologies in California"></b-jumbotron>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext === false">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.warn.audioLab.withoutAF')}}
|
||||
</div>
|
||||
<button class="md-btn" style="margin-top: 5px;" onclick="app.appRoute('settings')">
|
||||
{{$root.getLz('term.settings')}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext === true">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE')}}
|
||||
<br>
|
||||
|
@ -44,7 +36,7 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext === true">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
Cider Opportunistic Correction System
|
||||
<br>
|
||||
|
@ -59,7 +51,7 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext === true">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer')}} [1]
|
||||
<br>
|
||||
|
@ -84,7 +76,7 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext === true">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.atmosphereRealizer')}} [2]
|
||||
<br>
|
||||
|
@ -109,7 +101,7 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext === true">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization')}}
|
||||
<br>
|
||||
|
@ -139,7 +131,7 @@
|
|||
<div class="md-option-header">
|
||||
<span>{{$root.getLz('settings.header.unfinished')}}</span>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext === true">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
Cider Origami™️ Vocal Enhancer/Remasterer
|
||||
<br>
|
||||
|
|
|
@ -98,19 +98,6 @@
|
|||
<div class="md-option-container">
|
||||
<div class="settings-option-body">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{getLz('settings.option.audio.enableAdvancedFunctionality')}}
|
||||
<br>
|
||||
<small>{{getLz('settings.option.audio.enableAdvancedFunctionality.description')}}</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="$root.cfg.advanced.AudioContext"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="$root.cfg.advanced.AudioContext === true">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE')}}
|
||||
<br>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue