Merge branch 'main' of https://github.com/ciderapp/Cider into main
This commit is contained in:
commit
90dcde279a
137 changed files with 8653 additions and 4265 deletions
|
@ -1,4 +1,4 @@
|
|||
<div id="app-content" @scroll.passive="setContentScrollPos" :scrollpos="chrome.contentScrollPosY" scrollaxis="y" :style="{'overflow': (chrome.contentAreaScrolling ? '' : 'hidden')}">
|
||||
<div id="app-content" :scrollpos="chrome.contentScrollPosY" scrollaxis="y" :style="{'overflow': (chrome.contentAreaScrolling ? '' : 'hidden')}">
|
||||
<div id="navigation-bar" v-if="getThemeDirective('appNavigation') == 'seperate'">
|
||||
<button class="nav-item" @click="navigateBack()">
|
||||
<%- include('../svg/chevron-left.svg') %>
|
||||
|
@ -24,11 +24,6 @@
|
|||
</template>
|
||||
</transition>
|
||||
<% } %>
|
||||
|
||||
<!-- Library - Recently Added -->
|
||||
<transition :name="chrome.desiredPageTransition" v-on:enter="getLibraryAlbumsFull(null, 0); searchLibraryAlbums(0);">
|
||||
<%- include('../pages/library-recentlyadded') %>');
|
||||
</transition>
|
||||
<!-- Library - Made For You -->
|
||||
<transition :name="chrome.desiredPageTransition" v-on:enter="getMadeForYou()">
|
||||
<template v-if="page == 'library-madeforyou'">
|
||||
|
|
|
@ -1,4 +1,129 @@
|
|||
<div class="app-navigation" v-cloak>
|
||||
<transition name="wpfade">
|
||||
<div class="usermenu-container" v-if="chrome.menuOpened">
|
||||
<div class="usermenu-body">
|
||||
<button
|
||||
class="app-sidebar-button"
|
||||
style="width: 100%"
|
||||
@click="appRoute('apple-account-settings')"
|
||||
>
|
||||
<img
|
||||
class="sidebar-user-icon"
|
||||
loading="lazy"
|
||||
:src="getMediaItemArtwork(chrome.hideUserInfo ? './assets/logocut.png' : (chrome.userinfo.attributes['artwork'] ? chrome.userinfo.attributes['artwork']['url'] : ''), 26)"
|
||||
/>
|
||||
|
||||
<div class="sidebar-user-text" v-if="!chrome.hideUserInfo">
|
||||
<template v-if="chrome.userinfo.id || mk.isAuthorized">
|
||||
<div class="fullname text-overflow-elipsis">
|
||||
{{
|
||||
chrome.userinfo != null &&
|
||||
chrome.userinfo.attributes != null
|
||||
? chrome.userinfo.attributes.name ?? ""
|
||||
: ""
|
||||
}}
|
||||
</div>
|
||||
<div class="handle-text text-overflow-elipsis">
|
||||
{{
|
||||
chrome.userinfo != null &&
|
||||
chrome.userinfo.attributes != null
|
||||
? chrome.userinfo.attributes.handle ?? ""
|
||||
: ""
|
||||
}}
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div @click="mk.authorize()">
|
||||
{{ $root.getLz("term.login") }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="sidebar-user-text" v-else>
|
||||
{{ $root.getLz("app.name") }}
|
||||
</div>
|
||||
</button>
|
||||
<!-- Use 20px SVG for usermenu icon -->
|
||||
<button
|
||||
class="usermenu-item"
|
||||
v-if="cfg.general.privateEnabled"
|
||||
@click="cfg.general.privateEnabled = false"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/x.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.disablePrivateSession")
|
||||
}}</span>
|
||||
</button>
|
||||
<button class="usermenu-item" @click="appRoute('remote-pair')">
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/smartphone.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("action.showWebRemoteQR")
|
||||
}}</span>
|
||||
</button>
|
||||
<button
|
||||
class="usermenu-item"
|
||||
@click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/cast.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.cast")
|
||||
}}</span>
|
||||
</button>
|
||||
<button
|
||||
class="usermenu-item"
|
||||
@click="cfg.advanced.AudioContext ? modals.audioSettings = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/headphones.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.audioSettings")
|
||||
}}</span>
|
||||
</button>
|
||||
<button
|
||||
class="usermenu-item"
|
||||
v-if="pluginInstalled"
|
||||
@click="modals.pluginMenu = true"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/grid.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.plugin")
|
||||
}}</span>
|
||||
</button>
|
||||
<button class="usermenu-item" @click="appRoute('about')">
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/info.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.about")
|
||||
}}</span>
|
||||
</button>
|
||||
<button class="usermenu-item" @click="appRoute('settings')">
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/settings.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.settings")
|
||||
}}</span>
|
||||
</button>
|
||||
<button class="usermenu-item" @click="unauthorize()">
|
||||
<span class="usermenu-item-icon" style="right: 2.5px">
|
||||
<%- include("../svg/log-out.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.logout")
|
||||
}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<transition name="sidebartransition">
|
||||
<%- include("sidebar") %>
|
||||
</transition>
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
<b-popover custom-class="mediainfo-popover" target="artworkLCD" triggers="hover" placement="right">
|
||||
<div class="content">
|
||||
<div class="shadow-artwork">
|
||||
<mediaitem-artwork :url="currentArtUrl" :url="currentArtUrlRaw"></mediaitem-artwork>
|
||||
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="popover-artwork">
|
||||
<mediaitem-artwork :size="210" :url="currentArtUrlRaw"></mediaitem-artwork>
|
||||
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="song-name">{{ mk.nowPlayingItem["attributes"]["name"] }}</div>
|
||||
<div class="song-artist" @click="getNowPlayingItemDetailed(`artist`)">{{ mk.nowPlayingItem["attributes"]["artistName"] }}</div>
|
||||
|
@ -60,13 +60,27 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<div class="app-playback-controls">
|
||||
<div class="artwork" id="artworkLCD" style="pointer-events: none;">
|
||||
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="playback-info">
|
||||
<div class="song-name">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="app-chrome--center">
|
||||
<div class="app-chrome-playback-duration-bottom">
|
||||
<b-row>
|
||||
<b-col sm="auto">{{ convertTime(getSongProgress()) }}</b-col>
|
||||
<b-row v-if="mkReady()">
|
||||
<b-col sm="auto" v-if="!mk.nowPlayingItem?.isLiveRadioStation">{{ convertTime(getSongProgress()) }}</b-col>
|
||||
<b-col sm="auto" v-else>--:--</b-col>
|
||||
<b-col>
|
||||
<input type="range" step="0.01" min="0" :style="progressBarStyle()"
|
||||
@input="playerLCD.desiredDuration = $event.target.value;playerLCD.userInteraction = true"
|
||||
|
@ -74,7 +88,8 @@
|
|||
@touchend="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
|
||||
:max="mk.currentPlaybackDuration" :value="getSongProgress()">
|
||||
</b-col>
|
||||
<b-col sm="auto">{{ convertTime(mk.currentPlaybackDuration) }}</b-col>
|
||||
<b-col sm="auto" v-if="!mk.nowPlayingItem?.isLiveRadioStation">{{ convertTime(mk.currentPlaybackDuration) }}</b-col>
|
||||
<b-col sm="auto" v-else>{{ getLz("term.live") }}</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
<div class="app-chrome-playback-controls">
|
||||
|
|
|
@ -1,217 +1,118 @@
|
|||
<div
|
||||
class="app-chrome"
|
||||
:style="{'display': chrome.topChromeVisible ? '' : 'none'}"
|
||||
>
|
||||
<div class="app-chrome" :style="{'display': chrome.topChromeVisible ? '' : 'none'}">
|
||||
<div class="app-chrome--left">
|
||||
<div
|
||||
class="app-chrome-item full-height"
|
||||
v-if="chrome.windowControlPosition == 'left' && !chrome.nativeControls"
|
||||
>
|
||||
<div class="app-chrome-item full-height" v-if="chrome.windowControlPosition == 'left' && !chrome.nativeControls">
|
||||
<div class="window-controls-macos">
|
||||
<div class="close" @click="ipcRenderer.send('close')"></div>
|
||||
<div class="minimize" @click="ipcRenderer.send('minimize')"></div>
|
||||
<div
|
||||
class="minmax restore"
|
||||
v-if="chrome.maximized"
|
||||
@click="ipcRenderer.send('maximize')"
|
||||
></div>
|
||||
<div class="minmax restore" v-if="chrome.maximized" @click="ipcRenderer.send('maximize')"></div>
|
||||
<div class="minmax" v-else @click="ipcRenderer.send('maximize')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-chrome-item full-height" v-else>
|
||||
<button
|
||||
class="app-mainmenu"
|
||||
@blur="mainMenuVisibility(false)"
|
||||
@click="mainMenuVisibility(true)"
|
||||
:class="{active: chrome.menuOpened}"
|
||||
:aria-label="$root.getLz('term.quickNav')"
|
||||
></button>
|
||||
<button class="app-mainmenu" @blur="mainMenuVisibility(false, true)" @click="mainMenuVisibility(true, false)"
|
||||
@contextmenu="mainMenuVisibility(true, true)" :class="{active: chrome.menuOpened}"
|
||||
:aria-label="$root.getLz('term.quickNav')"></button>
|
||||
</div>
|
||||
<template v-if="getThemeDirective('appNavigation') != 'seperate'">
|
||||
<div
|
||||
class="vdiv"
|
||||
v-if="getThemeDirective('windowLayout') == 'twopanel'"
|
||||
></div>
|
||||
<div class="vdiv" v-if="getThemeDirective('windowLayout') == 'twopanel'"></div>
|
||||
<div class="app-chrome-item">
|
||||
<button
|
||||
class="playback-button navigation"
|
||||
@click="navigateBack()"
|
||||
:title="$root.getLz('term.navigateBack')"
|
||||
v-b-tooltip.hover
|
||||
>
|
||||
<button class="playback-button navigation" @click="navigateBack()" :title="$root.getLz('term.navigateBack')"
|
||||
v-b-tooltip.hover>
|
||||
<%- include('../svg/chevron-left.svg') %>
|
||||
</button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button
|
||||
class="playback-button navigation"
|
||||
@click="navigateForward()"
|
||||
:title="$root.getLz('term.navigateForward')"
|
||||
v-b-tooltip.hover
|
||||
>
|
||||
<button class="playback-button navigation" @click="navigateForward()"
|
||||
:title="$root.getLz('term.navigateForward')" v-b-tooltip.hover>
|
||||
<%- include('../svg/chevron-right.svg') %>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="vdiv display--large"
|
||||
v-if="getThemeDirective('windowLayout') != 'twopanel'"
|
||||
></div>
|
||||
<div class="app-chrome-item" v-if="getThemeDirective('windowLayout') == 'twopanel'">
|
||||
<button class="playback-button collapseLibrary" v-b-tooltip.hover
|
||||
:title="chrome.sidebarCollapsed ? getLz('action.showLibrary') : getLz('action.hideLibrary')"
|
||||
@click="chrome.sidebarCollapsed = !chrome.sidebarCollapsed">
|
||||
<transition name="fade">
|
||||
<span v-if="chrome.sidebarCollapsed"></span>
|
||||
</transition>
|
||||
<transition name="fade">
|
||||
<span v-if="!chrome.sidebarCollapsed"></span>
|
||||
</transition>
|
||||
|
||||
</button>
|
||||
</div>
|
||||
<div class="vdiv display--large" v-if="getThemeDirective('windowLayout') != 'twopanel'"></div>
|
||||
</template>
|
||||
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
||||
<div class="app-chrome-item display--large">
|
||||
<button
|
||||
class="playback-button--small shuffle"
|
||||
v-if="mk.shuffleMode == 0"
|
||||
:class="isDisabled() && 'disabled'"
|
||||
@click="mk.shuffleMode = 1"
|
||||
:title="$root.getLz('term.enableShuffle')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button
|
||||
class="playback-button--small shuffle active"
|
||||
v-else
|
||||
:class="isDisabled() && 'disabled'"
|
||||
@click="mk.shuffleMode = 0"
|
||||
:title="$root.getLz('term.disableShuffle')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0" :class="isDisabled() && 'disabled'"
|
||||
@click="mk.shuffleMode = 1" :title="$root.getLz('term.enableShuffle')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small shuffle active" v-else :class="isDisabled() && 'disabled'"
|
||||
@click="mk.shuffleMode = 0" :title="$root.getLz('term.disableShuffle')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button
|
||||
class="playback-button previous"
|
||||
@click="prevButton()"
|
||||
:class="isPrevDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.previous')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button class="playback-button previous" @click="prevButton()" :class="isPrevDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.previous')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button
|
||||
class="playback-button stop"
|
||||
@click="mk.stop()"
|
||||
<button class="playback-button stop" @click="mk.stop()"
|
||||
v-if="mk.isPlaying && mk.nowPlayingItem.attributes.playParams.kind == 'radioStation'"
|
||||
:title="$root.getLz('term.stop')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button
|
||||
class="playback-button pause"
|
||||
@click="mk.pause()"
|
||||
v-else-if="mk.isPlaying"
|
||||
:title="$root.getLz('term.pause')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button
|
||||
class="playback-button play"
|
||||
@click="mk.play()"
|
||||
v-else
|
||||
:title="$root.getLz('term.play')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
:title="$root.getLz('term.stop')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button pause" @click="mk.pause()" v-else-if="mk.isPlaying"
|
||||
:title="$root.getLz('term.pause')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button play" @click="mk.play()" v-else :title="$root.getLz('term.play')"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button
|
||||
class="playback-button next"
|
||||
@click="skipToNextItem()"
|
||||
:class="isNextDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.next')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button class="playback-button next" @click="skipToNextItem()" :class="isNextDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.next')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button
|
||||
class="playback-button--small repeat"
|
||||
v-if="mk.repeatMode == 0"
|
||||
:class="isDisabled() && 'disabled'"
|
||||
@click="mk.repeatMode = 1"
|
||||
:title="$root.getLz('term.enableRepeatOne')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button
|
||||
class="playback-button--small repeat repeatOne"
|
||||
@click="mk.repeatMode = 2"
|
||||
:class="isDisabled() && 'disabled'"
|
||||
v-else-if="mk.repeatMode == 1"
|
||||
:title="$root.getLz('term.disableRepeatOne')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button
|
||||
class="playback-button--small repeat active"
|
||||
@click="mk.repeatMode = 0"
|
||||
:class="isDisabled() && 'disabled'"
|
||||
v-else-if="mk.repeatMode == 2"
|
||||
:title="$root.getLz('term.disableRepeat')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0" :class="isDisabled() && 'disabled'"
|
||||
@click="mk.repeatMode = 1" :title="$root.getLz('term.enableRepeatOne')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
|
||||
:class="isDisabled() && 'disabled'" v-else-if="mk.repeatMode == 1"
|
||||
:title="$root.getLz('term.disableRepeatOne')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small repeat active" @click="mk.repeatMode = 0"
|
||||
:class="isDisabled() && 'disabled'" v-else-if="mk.repeatMode == 2" :title="$root.getLz('term.disableRepeat')"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="app-chrome--center">
|
||||
<div
|
||||
class="app-chrome-item playback-controls"
|
||||
v-if="getThemeDirective('windowLayout') != 'twopanel'"
|
||||
>
|
||||
<div class="app-chrome-item playback-controls" v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
||||
<template v-if="mkReady()">
|
||||
<div
|
||||
class="app-playback-controls"
|
||||
@mouseover="chrome.progresshover = true"
|
||||
@mouseleave="chrome.progresshover = false"
|
||||
@contextmenu="nowPlayingContextMenu"
|
||||
>
|
||||
<div class="app-playback-controls" @mouseover="chrome.progresshover = true"
|
||||
@mouseleave="chrome.progresshover = false" @contextmenu="nowPlayingContextMenu">
|
||||
<div class="artwork" id="artworkLCD">
|
||||
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
|
||||
</div>
|
||||
<b-popover
|
||||
custom-class="mediainfo-popover"
|
||||
target="artworkLCD"
|
||||
triggers="hover"
|
||||
placement="bottom"
|
||||
>
|
||||
<b-popover custom-class="mediainfo-popover" target="artworkLCD" triggers="hover" placement="bottom">
|
||||
<div class="content">
|
||||
<div class="shadow-artwork">
|
||||
<mediaitem-artwork
|
||||
:url="currentArtUrl"
|
||||
:url="currentArtUrlRaw"
|
||||
></mediaitem-artwork>
|
||||
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="popover-artwork">
|
||||
<mediaitem-artwork
|
||||
:size="210"
|
||||
:url="currentArtUrlRaw"
|
||||
></mediaitem-artwork>
|
||||
<mediaitem-artwork :size="210" :url="currentArtUrl"></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="song-name">
|
||||
{{ mk.nowPlayingItem["attributes"]["name"] }}
|
||||
</div>
|
||||
<div
|
||||
class="song-artist"
|
||||
@click="getNowPlayingItemDetailed(`artist`)"
|
||||
>
|
||||
<div class="song-artist" @click="getNowPlayingItemDetailed(`artist`)">
|
||||
{{ mk.nowPlayingItem["attributes"]["artistName"] }}
|
||||
</div>
|
||||
<div
|
||||
class="song-album"
|
||||
@click="getNowPlayingItemDetailed(`album`)"
|
||||
>
|
||||
<div class="song-album" @click="getNowPlayingItemDetailed(`album`)">
|
||||
{{
|
||||
mk.nowPlayingItem["attributes"]["albumName"]
|
||||
? mk.nowPlayingItem["attributes"]["albumName"]
|
||||
: ""
|
||||
mk.nowPlayingItem["attributes"]["albumName"]
|
||||
? mk.nowPlayingItem["attributes"]["albumName"]
|
||||
: ""
|
||||
}}
|
||||
</div>
|
||||
<hr />
|
||||
<div class="btn-group" style="width: 100%">
|
||||
<button
|
||||
class="md-btn md-btn-small"
|
||||
style="width: 100%"
|
||||
@click="drawer.open = false; miniPlayer(true)"
|
||||
>
|
||||
<button class="md-btn md-btn-small" style="width: 100%" @click="drawer.open = false; miniPlayer(true)">
|
||||
{{ $root.getLz("term.miniplayer") }}
|
||||
</button>
|
||||
<button
|
||||
class="md-btn md-btn-small"
|
||||
style="width: 100%"
|
||||
@click="drawer.open = false; fullscreen(true)"
|
||||
>
|
||||
<button class="md-btn md-btn-small" style="width: 100%" @click="drawer.open = false; fullscreen(true)">
|
||||
{{ $root.getLz("term.fullscreenView") }}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -219,183 +120,121 @@
|
|||
</b-popover>
|
||||
<div class="playback-info">
|
||||
<div class="chrome-icon-container">
|
||||
<div
|
||||
class="audio-type private-icon"
|
||||
v-if="cfg.general.privateEnabled === true"
|
||||
></div>
|
||||
<div
|
||||
class="audio-type ppe-icon"
|
||||
v-if="cfg.audio.maikiwiAudio.ciderPPE === true"
|
||||
></div>
|
||||
<div class="audio-type private-icon" v-if="cfg.general.privateEnabled === true"></div>
|
||||
<div class="audio-type ppe-icon" v-if="cfg.audio.maikiwiAudio.ciderPPE === true"></div>
|
||||
</div>
|
||||
<div
|
||||
class="song-name"
|
||||
:class="[isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') ? 'marquee' : '']"
|
||||
>
|
||||
{{ mk.nowPlayingItem["attributes"]["name"] }}
|
||||
<div
|
||||
class="explicit-icon"
|
||||
v-if="mk.nowPlayingItem['attributes']['contentRating'] == 'explicit'"
|
||||
style="display: inline-block"
|
||||
></div>
|
||||
</div>
|
||||
<div class="song-artist-album">
|
||||
<div
|
||||
class="song-artist-album-content"
|
||||
:class="[isElementOverflowing('#app-main > .app-chrome .app-chrome-item > .app-playback-controls > div >.song-artist-album > .song-artist-album-content') ? 'marquee' : '']"
|
||||
style="
|
||||
<div class="info-rect">
|
||||
<div class="song-name"
|
||||
:class="[isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') ? 'marquee' : '']">
|
||||
{{ mk.nowPlayingItem["attributes"]["name"] }}
|
||||
<div class="explicit-icon" v-if="mk.nowPlayingItem['attributes']['contentRating'] == 'explicit'"
|
||||
style="display: inline-block"></div>
|
||||
</div>
|
||||
<div class="song-artist-album">
|
||||
<div class="song-artist-album-content"
|
||||
:class="[isElementOverflowing('#app-main > .app-chrome .app-chrome-item > .app-playback-controls > div >.song-artist-album > .song-artist-album-content') ? 'marquee' : '']"
|
||||
style="
|
||||
display: inline-block;
|
||||
-webkit-box-orient: horizontal;
|
||||
white-space: nowrap;
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="item-navigate song-artist"
|
||||
style="display: inline-block"
|
||||
@click="getNowPlayingItemDetailed(`artist`)"
|
||||
>
|
||||
{{ mk.nowPlayingItem["attributes"]["artistName"] }}
|
||||
</div>
|
||||
<div
|
||||
class="song-artist item-navigate"
|
||||
style="display: inline-block"
|
||||
@click="getNowPlayingItemDetailed('album')"
|
||||
v-if="mk.nowPlayingItem['attributes']['albumName'] != ''"
|
||||
>
|
||||
<div class="separator" style="display: inline-block">
|
||||
{{ "—" }}
|
||||
">
|
||||
<div class="item-navigate song-artist" style="display: inline-block"
|
||||
@click="getNowPlayingItemDetailed(`artist`)">
|
||||
{{ mk.nowPlayingItem["attributes"]["artistName"] }}
|
||||
</div>
|
||||
{{
|
||||
<div class="song-artist item-navigate" style="display: inline-block"
|
||||
@click="getNowPlayingItemDetailed('album')"
|
||||
v-if="mk.nowPlayingItem['attributes']['albumName'] != ''">
|
||||
<div class="separator" style="display: inline-block">
|
||||
{{ "—" }}
|
||||
</div>
|
||||
{{
|
||||
mk.nowPlayingItem["attributes"]["albumName"]
|
||||
? mk.nowPlayingItem["attributes"]["albumName"]
|
||||
: ""
|
||||
}}
|
||||
? mk.nowPlayingItem["attributes"]["albumName"]
|
||||
: ""
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="song-progress">
|
||||
<div
|
||||
class="song-duration"
|
||||
style="justify-content: space-between; height: 1px"
|
||||
:style="[chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]"
|
||||
>
|
||||
<div class="song-duration" style="justify-content: space-between; height: 1px"
|
||||
:style="[chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]">
|
||||
<p style="width: auto">{{ convertTime(getSongProgress()) }}</p>
|
||||
<p style="width: auto">
|
||||
{{ convertTime(mk.currentPlaybackDuration) }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="range"
|
||||
step="0.01"
|
||||
min="0"
|
||||
:style="progressBarStyle()"
|
||||
<input type="range" step="0.01" min="0" :style="progressBarStyle()"
|
||||
@input="playerLCD.desiredDuration = $event.target.value;playerLCD.userInteraction = true"
|
||||
@mouseup="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
|
||||
@touchend="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
|
||||
:max="mk.currentPlaybackDuration"
|
||||
:value="getSongProgress()"
|
||||
/>
|
||||
:max="mk.currentPlaybackDuration" :value="getSongProgress()" />
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="mk.nowPlayingItem['attributes']['playParams']">
|
||||
<div class="actions">
|
||||
<button
|
||||
class="lcdMenu"
|
||||
@click="nowPlayingContextMenu"
|
||||
:title="$root.getLz('term.more')"
|
||||
v-b-tooltip.hover
|
||||
>
|
||||
<button class="lcdMenu" @click="nowPlayingContextMenu" :title="$root.getLz('term.more')"
|
||||
v-b-tooltip.hover>
|
||||
<div class="svg-icon"></div>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="app-playback-controls">
|
||||
<div class="artwork" id="artworkLCD" style="pointer-events: none;">
|
||||
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="playback-info">
|
||||
<div class="info-rect">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="app-chrome-item" v-else>
|
||||
<div class="top-nav-group">
|
||||
<sidebar-library-item
|
||||
:name="$root.getLz('home.title')"
|
||||
svg-icon="./assets/feather/home.svg"
|
||||
page="home"
|
||||
>
|
||||
<sidebar-library-item :name="$root.getLz('home.title')" svg-icon="./assets/feather/home.svg" page="home">
|
||||
</sidebar-library-item>
|
||||
<sidebar-library-item
|
||||
:name="$root.getLz('term.listenNow')"
|
||||
svg-icon="./assets/feather/play-circle.svg"
|
||||
page="listen_now"
|
||||
></sidebar-library-item>
|
||||
<sidebar-library-item
|
||||
:name="$root.getLz('term.browse')"
|
||||
svg-icon="./assets/feather/globe.svg"
|
||||
page="browse"
|
||||
>
|
||||
<sidebar-library-item :name="$root.getLz('term.listenNow')" svg-icon="./assets/feather/play-circle.svg"
|
||||
page="listen_now"></sidebar-library-item>
|
||||
<sidebar-library-item :name="$root.getLz('term.browse')" svg-icon="./assets/feather/globe.svg" page="browse">
|
||||
</sidebar-library-item>
|
||||
<sidebar-library-item :name="$root.getLz('term.radio')" svg-icon="./assets/feather/radio.svg" page="radio">
|
||||
</sidebar-library-item>
|
||||
<sidebar-library-item
|
||||
:name="$root.getLz('term.radio')"
|
||||
svg-icon="./assets/feather/radio.svg"
|
||||
page="radio"
|
||||
></sidebar-library-item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-chrome--right">
|
||||
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
|
||||
<div class="app-chrome-item volume display--large">
|
||||
<button
|
||||
class="volume-button--small volume"
|
||||
@click="muteButtonPressed()"
|
||||
<button class="volume-button--small volume" @click="muteButtonPressed()"
|
||||
:class="{'active': this.cfg.audio.volume == 0}"
|
||||
:title="cfg.audio.muted ? $root.getLz('term.unmute') : $root.getLz('term.mute')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<input
|
||||
type="range"
|
||||
@wheel="volumeWheel"
|
||||
:step="cfg.audio.volumeStep"
|
||||
min="0"
|
||||
:max="cfg.audio.maxVolume"
|
||||
v-model="mk.volume"
|
||||
v-if="typeof mk.volume != 'undefined'"
|
||||
@change="checkMuteChange()"
|
||||
v-b-tooltip.hover
|
||||
:title="formatVolumeTooltip()"
|
||||
/>
|
||||
:title="cfg.audio.muted ? $root.getLz('term.unmute') : $root.getLz('term.mute')" v-b-tooltip.hover></button>
|
||||
<input type="range" @wheel="volumeWheel" :step="cfg.audio.volumeStep" min="0" :max="cfg.audio.maxVolume"
|
||||
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()" v-b-tooltip.hover
|
||||
:title="formatVolumeTooltip()" />
|
||||
</div>
|
||||
<div class="app-chrome-item generic">
|
||||
<button
|
||||
class="playback-button--small cast"
|
||||
:title="$root.getLz('term.cast')"
|
||||
<button class="playback-button--small cast" :title="$root.getLz('term.cast')"
|
||||
@click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item generic">
|
||||
<button
|
||||
class="playback-button--small queue"
|
||||
:title="$root.getLz('term.queue')"
|
||||
v-b-tooltip.hover
|
||||
:class="{'active': drawer.panel == 'queue'}"
|
||||
@click="invokeDrawer('queue')"
|
||||
></button>
|
||||
<button class="playback-button--small queue" :title="$root.getLz('term.queue')" v-b-tooltip.hover
|
||||
:class="{'active': drawer.panel == 'queue'}" @click="invokeDrawer('queue')"></button>
|
||||
</div>
|
||||
<div class="app-chrome-item generic">
|
||||
<template v-if="lyrics && lyrics != [] && lyrics.length > 0">
|
||||
<button
|
||||
class="playback-button--small lyrics"
|
||||
:title="$root.getLz('term.lyrics')"
|
||||
v-b-tooltip.hover
|
||||
:class="{'active': drawer.panel == 'lyrics'}"
|
||||
@click="invokeDrawer('lyrics')"
|
||||
></button>
|
||||
<button class="playback-button--small lyrics" :title="$root.getLz('term.lyrics')" v-b-tooltip.hover
|
||||
:class="{'active': drawer.panel == 'lyrics'}" @click="invokeDrawer('lyrics')"></button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button
|
||||
class="playback-button--small lyrics"
|
||||
:style="{'opacity': 0.3, 'pointer-events': 'none'}"
|
||||
></button>
|
||||
<button class="playback-button--small lyrics" :style="{'opacity': 0.3, 'pointer-events': 'none'}"></button>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -403,31 +242,16 @@
|
|||
<div class="app-chrome-item search">
|
||||
<div class="search-input-container">
|
||||
<div class="search-input--icon"></div>
|
||||
<input
|
||||
type="search"
|
||||
spellcheck="false"
|
||||
@click="showSearch()"
|
||||
@focus="search.showHints = true"
|
||||
<input type="search" spellcheck="false" @click="showSearch()" @focus="search.showHints = true"
|
||||
@blur="setTimeout(()=>{search.showHints = false}, 300)"
|
||||
v-on:keyup.enter="searchQuery();search.showHints = false"
|
||||
@change="showSearch();"
|
||||
@input="getSearchHints()"
|
||||
:placeholder="$root.getLz('term.search') + '...'"
|
||||
v-model="search.term"
|
||||
ref="searchInput"
|
||||
class="search-input"
|
||||
/>
|
||||
v-on:keyup.enter="searchQuery();search.showHints = false" @change="showSearch();" @input="getSearchHints()"
|
||||
:placeholder="$root.getLz('term.search') + '...'" v-model="search.term" ref="searchInput"
|
||||
class="search-input" />
|
||||
|
||||
<div
|
||||
class="search-hints-container"
|
||||
v-if="search.showHints && search.hints.length != 0"
|
||||
>
|
||||
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
|
||||
<div class="search-hints">
|
||||
<button
|
||||
class="search-hint text-overflow-elipsis"
|
||||
v-for="hint in search.hints"
|
||||
@click="search.term = hint;search.showHints = false;searchQuery(hint)"
|
||||
>
|
||||
<button class="search-hint text-overflow-elipsis" v-for="hint in search.hints"
|
||||
@click="search.term = hint;search.showHints = false;searchQuery(hint)">
|
||||
{{ hint }}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -435,32 +259,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
class="app-chrome-item full-height"
|
||||
id="window-controls-container"
|
||||
v-if="chrome.windowControlPosition == 'right' && !chrome.nativeControls"
|
||||
>
|
||||
<div class="app-chrome-item full-height" id="window-controls-container"
|
||||
v-if="chrome.windowControlPosition == 'right' && !chrome.nativeControls">
|
||||
<div class="window-controls">
|
||||
<div class="minimize" @click="ipcRenderer.send('minimize')"></div>
|
||||
<div
|
||||
class="minmax restore"
|
||||
v-if="chrome.maximized"
|
||||
@click="ipcRenderer.send('maximize')"
|
||||
></div>
|
||||
<div class="minmax restore" v-if="chrome.maximized" @click="ipcRenderer.send('maximize')"></div>
|
||||
<div class="minmax" v-else @click="ipcRenderer.send('maximize')"></div>
|
||||
<div class="close" @click="ipcRenderer.send('close')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="app-chrome-item full-height"
|
||||
v-else-if="platform != 'darwin' && !chrome.nativeControls"
|
||||
>
|
||||
<button
|
||||
class="app-mainmenu"
|
||||
@blur="mainMenuVisibility(false)"
|
||||
@click="mainMenuVisibility(true)"
|
||||
:class="{active: chrome.menuOpened}"
|
||||
></button>
|
||||
<div class="app-chrome-item full-height" v-else-if="platform != 'darwin' && !chrome.nativeControls">
|
||||
<button class="app-mainmenu" @blur="mainMenuVisibility(false, true)" @click="mainMenuVisibility(true, false)"
|
||||
@contextmenu="mainMenuVisibility(true, true)" :class="{active: chrome.menuOpened}"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -13,9 +13,6 @@
|
|||
<transition name="modal">
|
||||
<add-to-playlist :playlists="playlists.listing" v-if="modals.addToPlaylist"></add-to-playlist>
|
||||
</transition>
|
||||
<transition name="modal">
|
||||
<spatial-properties v-if="modals.spatialProperties"></spatial-properties>
|
||||
</transition>
|
||||
<transition name="modal">
|
||||
<audio-controls v-if="modals.audioControls"></audio-controls>
|
||||
</transition>
|
||||
|
|
|
@ -183,136 +183,6 @@
|
|||
</sidebar-playlist>
|
||||
</template>
|
||||
</div>
|
||||
<transition name="wpfade">
|
||||
<div class="usermenu-container" v-if="chrome.menuOpened">
|
||||
<div class="usermenu-body">
|
||||
<button
|
||||
class="app-sidebar-button"
|
||||
style="width: 100%"
|
||||
@click="appRoute('apple-account-settings')"
|
||||
>
|
||||
<img
|
||||
class="sidebar-user-icon"
|
||||
loading="lazy"
|
||||
:src="getMediaItemArtwork(chrome.hideUserInfo ? 'http://localhost:9000/assets/logocut.png' : (chrome.userinfo.attributes['artwork'] ? chrome.userinfo.attributes['artwork']['url'] : ''), 26)"
|
||||
/>
|
||||
|
||||
<div class="sidebar-user-text" v-if="!chrome.hideUserInfo">
|
||||
<template v-if="chrome.userinfo.id || mk.isAuthorized">
|
||||
<div class="fullname text-overflow-elipsis">
|
||||
{{
|
||||
chrome.userinfo != null &&
|
||||
chrome.userinfo.attributes != null
|
||||
? chrome.userinfo.attributes.name ?? ""
|
||||
: ""
|
||||
}}
|
||||
</div>
|
||||
<div class="handle-text text-overflow-elipsis">
|
||||
{{
|
||||
chrome.userinfo != null &&
|
||||
chrome.userinfo.attributes != null
|
||||
? chrome.userinfo.attributes.handle ?? ""
|
||||
: ""
|
||||
}}
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div @click="mk.authorize()">
|
||||
{{ $root.getLz("term.login") }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="sidebar-user-text" v-else>
|
||||
{{ $root.getLz("app.name") }}
|
||||
</div>
|
||||
</button>
|
||||
<!-- Use 20px SVG for usermenu icon -->
|
||||
<button
|
||||
class="usermenu-item"
|
||||
v-if="cfg.general.privateEnabled"
|
||||
@click="cfg.general.privateEnabled = false"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/x.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.disablePrivateSession")
|
||||
}}</span>
|
||||
</button>
|
||||
<button class="usermenu-item" @click="appRoute('remote-pair')">
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/smartphone.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("action.showWebRemoteQR")
|
||||
}}</span>
|
||||
</button>
|
||||
<button
|
||||
class="usermenu-item"
|
||||
@click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/cast.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.cast")
|
||||
}}</span>
|
||||
</button>
|
||||
<button
|
||||
class="usermenu-item"
|
||||
@click="cfg.advanced.AudioContext ? modals.audioSettings = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/headphones.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.audioSettings")
|
||||
}}</span>
|
||||
</button>
|
||||
<button
|
||||
class="usermenu-item"
|
||||
v-if="pluginInstalled"
|
||||
@click="modals.pluginMenu = true"
|
||||
>
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/grid.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.plugin")
|
||||
}}</span>
|
||||
</button>
|
||||
<button class="usermenu-item" @click="appRoute('about')">
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/info.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.about")
|
||||
}}</span>
|
||||
</button>
|
||||
<button class="usermenu-item" @click="appRoute('settings')">
|
||||
<span class="usermenu-item-icon">
|
||||
<%- include("../svg/settings.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.settings")
|
||||
}}</span>
|
||||
</button>
|
||||
<button class="usermenu-item" @click="unauthorize()">
|
||||
<span class="usermenu-item-icon" style="right: 2.5px">
|
||||
<%- include("../svg/log-out.svg") %>
|
||||
</span>
|
||||
<span class="usermenu-item-name">{{
|
||||
$root.getLz("term.logout")
|
||||
}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<div class="app-sidebar-footer collapseTab" v-if="cfg.advanced.experiments.includes('collapseSidebar')">
|
||||
<button @click="chrome.sidebarCollapsed = !chrome.sidebarCollapsed">
|
||||
Collapse
|
||||
</button>
|
||||
</div>
|
||||
<div class="app-sidebar-footer display--small app-sidebar-footer--controls">
|
||||
<div
|
||||
class="app-playback-controls"
|
||||
|
@ -326,6 +196,7 @@
|
|||
v-if="mk.shuffleMode == 0"
|
||||
@click="mk.shuffleMode = 1"
|
||||
:title="$root.getLz('term.enableShuffle')"
|
||||
:class="$root.isDisabled() && 'disabled'"
|
||||
v-b-tooltip.hover.righttop
|
||||
></button>
|
||||
<button
|
||||
|
@ -333,6 +204,7 @@
|
|||
v-else
|
||||
@click="mk.shuffleMode = 0"
|
||||
:title="$root.getLz('term.disableShuffle')"
|
||||
:class="$root.isDisabled() && 'disabled'"
|
||||
v-b-tooltip.hover.righttop
|
||||
></button>
|
||||
</div>
|
||||
|
@ -340,31 +212,26 @@
|
|||
<button
|
||||
class="playback-button previous"
|
||||
@click="prevButton()"
|
||||
:class="$root.isPrevDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.previous')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button
|
||||
class="playback-button pause"
|
||||
@click="mk.pause()"
|
||||
v-if="mk.isPlaying"
|
||||
:title="$root.getLz('term.pause')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button
|
||||
class="playback-button play"
|
||||
@click="mk.play()"
|
||||
v-else
|
||||
:title="$root.getLz('term.play')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button class="playback-button stop" @click="$root.mk.stop()"
|
||||
v-if="$root.mk.isPlaying && $root.mk.nowPlayingItem.attributes.playParams.kind == 'radioStation'"
|
||||
:title="$root.getLz('term.stop')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button pause" @click="$root.mk.pause()" v-else-if="$root.mk.isPlaying"
|
||||
:title="$root.getLz('term.pause')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button play" @click="$root.mk.play()" v-else :title="$root.getLz('term.play')"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button
|
||||
class="playback-button next"
|
||||
@click="skipToNextItem()"
|
||||
:title="$root.getLz('term.next')"
|
||||
:class="$root.isNextDisabled() && 'disabled'"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
</div>
|
||||
|
@ -373,6 +240,7 @@
|
|||
class="playback-button--small repeat"
|
||||
v-if="mk.repeatMode == 0"
|
||||
@click="mk.repeatMode = 1"
|
||||
:class="$root.isDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.enableRepeatOne')"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
|
@ -381,6 +249,7 @@
|
|||
@click="mk.repeatMode = 2"
|
||||
v-else-if="mk.repeatMode == 1"
|
||||
:title="$root.getLz('term.disableRepeatOne')"
|
||||
:class="$root.isDisabled() && 'disabled'"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
<button
|
||||
|
@ -388,6 +257,7 @@
|
|||
@click="mk.repeatMode = 0"
|
||||
v-else-if="mk.repeatMode == 2"
|
||||
:title="$root.getLz('term.disableRepeat')"
|
||||
:class="$root.isDisabled() && 'disabled'"
|
||||
v-b-tooltip.hover
|
||||
></button>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
<script type="text/x-template" id="artist-chip">
|
||||
<div class="artist-chip" @click.self="route" tabindex="0">
|
||||
<div class="artist-chip__image">
|
||||
<mediaitem-artwork v-if="artist.id != null" :url="artist.attributes.artwork.url" :size="32"></mediaitem-artwork>
|
||||
<div class="artist-chip__image" v-if="image" :style="{backgroundColor: '#' + (artist.attributes.artwork?.bgColor ?? '000')}">
|
||||
<mediaitem-artwork v-if="artist.id != null" :url="artist.attributes.artwork.url" :size="80"></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="artist-chip__image" v-else>
|
||||
</div>
|
||||
<div class="artist-chip__name">
|
||||
<span>{{ item.attributes.name }}</span>
|
||||
</div>
|
||||
<button @click="$root.followArtistById(artist.id, true)" title="Follow" v-if="!$root.followingArtist(artist.id)" class="artist-chip__follow codicon codicon-add"></button>
|
||||
<button @click="$root.followArtistById(artist.id, false)" title="Following" v-else class="artist-chip__follow codicon codicon-check"></button>
|
||||
<button @click="$root.setArtistFavorite(artist.id, true)" title="Follow" v-if="!$root.followingArtist(artist.id)" class="artist-chip__follow codicon codicon-add"></button>
|
||||
<button @click="$root.setArtistFavorite(artist.id, false)" title="Following" v-else class="artist-chip__follow codicon codicon-check"></button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
@ -21,6 +23,7 @@
|
|||
},
|
||||
data: function() {
|
||||
return {
|
||||
image: false,
|
||||
artist: {
|
||||
id: null
|
||||
}
|
||||
|
@ -34,6 +37,7 @@
|
|||
}
|
||||
app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artistId}`).then(response => {
|
||||
this.artist = response.data.data[0];
|
||||
this.image = true;
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script type="text/x-template" id="artwork-material">
|
||||
<div class="artworkMaterial">
|
||||
<img :src="src" v-for="image in images"/>
|
||||
<mediaitem-artwork :url="src" :size="500" v-for="image in images"/>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
|
|
@ -35,6 +35,16 @@
|
|||
v-model="maxVolume"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.audio.advanced')}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.audio.advanced" switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -298,7 +298,7 @@
|
|||
try {
|
||||
for (var i = 0; i < 21; i++) {
|
||||
CiderAudio.audioNodes.vibrantbassNode[i].gain.value = app.cfg.audio.maikiwiAudio.vibrantBass.gain[i] * (app.cfg.audio.equalizer.vibrantBass / 10);
|
||||
} CiderAudio.intelliGainComp_h0_0();
|
||||
} CiderAudio.intelliGainComp_n0_0();
|
||||
}
|
||||
catch (e) {
|
||||
CiderAudio.hierarchical_loading();
|
||||
|
@ -315,7 +315,7 @@
|
|||
for (var i = 0; i < 10; i++) {
|
||||
CiderAudio.audioNodes.audioBands[i].gain.value = app.cfg.audio.equalizer.gain[i] * app.cfg.audio.equalizer.mix
|
||||
}
|
||||
CiderAudio.intelliGainComp_h0_0();
|
||||
CiderAudio.intelliGainComp_n0_0();
|
||||
} catch (e) { CiderAudio.hierarchical_loading(); }
|
||||
}
|
||||
},
|
||||
|
@ -323,7 +323,7 @@
|
|||
if (Math.max(...app.cfg.audio.equalizer.gain) != 0) {
|
||||
try {
|
||||
CiderAudio.audioNodes.audioBands[i].gain.value = app.cfg.audio.equalizer.gain[i] * app.cfg.audio.equalizer.mix
|
||||
CiderAudio.intelliGainComp_h0_0();
|
||||
CiderAudio.intelliGainComp_n0_0();
|
||||
}
|
||||
catch (e) { CiderAudio.hierarchical_loading(); }
|
||||
}
|
||||
|
@ -413,7 +413,7 @@
|
|||
CiderAudio.audioNodes.audioBands[i].frequency.value = app.cfg.audio.equalizer.frequencies[i]
|
||||
CiderAudio.audioNodes.audioBands[i].Q.value = app.cfg.audio.equalizer.Q[i]
|
||||
}
|
||||
CiderAudio.intelliGainComp_h0_0();
|
||||
CiderAudio.intelliGainComp_n0_0();
|
||||
},
|
||||
changePreset(id) {
|
||||
let userPresets = app.cfg.audio.equalizer.presets
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
<div class="artwork" @click="app.fullscreen(false)">
|
||||
<mediaitem-artwork
|
||||
:size="600"
|
||||
:url="(image ?? '').replace('{w}','600').replace('{h}','600') "
|
||||
:video="video"
|
||||
:videoPriority="true"
|
||||
:url="(image ?? '').replace('{w}','600').replace('{h}','600')"
|
||||
></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="controls-parents">
|
||||
|
@ -52,39 +54,40 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="control-buttons">
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button--small shuffle" v-if="app.mk.shuffleMode == 0"
|
||||
@click="app.mk.shuffleMode = 1" :title="$root.getLz('term.enableShuffle')"
|
||||
v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small shuffle active" v-else
|
||||
@click="app.mk.shuffleMode = 0" :title="$root.getLz('term.disableShuffle')"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button previous" @click="app.prevButton()"
|
||||
:title="$root.getLz('term.previous')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button pause" @click="app.mk.pause()" v-if="app.mk.isPlaying"
|
||||
:title="$root.getLz('term.pause')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button play" @click="app.mk.play()" v-else
|
||||
:title="$root.getLz('term.play')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button next" @click="app.skipToNextItem()"
|
||||
:title="$root.getLz('term.next')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button--small repeat" v-if="app.mk.repeatMode == 0"
|
||||
@click="app.mk.repeatMode = 1" :title="$root.getLz('term.enableRepeatOne')"
|
||||
v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small repeat repeatOne" @click="app.mk.repeatMode = 2"
|
||||
v-else-if="app.mk.repeatMode == 1" :title="$root.getLz('term.disableRepeatOne')"
|
||||
v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small repeat active" @click="app.mk.repeatMode = 0"
|
||||
v-else-if="app.mk.repeatMode == 2" :title="$root.getLz('term.disableRepeat')"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button--small shuffle" v-if="$root.mk.shuffleMode == 0" :class="$root.isDisabled() && 'disabled'"
|
||||
@click="$root.mk.shuffleMode = 1" :title="$root.getLz('term.enableShuffle')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small shuffle active" v-else :class="$root.isDisabled() && 'disabled'"
|
||||
@click="$root.mk.shuffleMode = 0" :title="$root.getLz('term.disableShuffle')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button previous" @click="$root.prevButton()" :class="$root.isPrevDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.previous')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button stop" @click="$root.mk.stop()"
|
||||
v-if="$root.mk.isPlaying && $root.mk.nowPlayingItem.attributes.playParams.kind == 'radioStation'"
|
||||
:title="$root.getLz('term.stop')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button pause" @click="$root.mk.pause()" v-else-if="$root.mk.isPlaying"
|
||||
:title="$root.getLz('term.pause')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button play" @click="$root.mk.play()" v-else :title="$root.getLz('term.play')"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button next" @click="$root.skipToNextItem()" :class="$root.isNextDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.next')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button--small repeat" v-if="$root.mk.repeatMode == 0" :class="$root.isDisabled() && 'disabled'"
|
||||
@click="$root.mk.repeatMode = 1" :title="$root.getLz('term.enableRepeatOne')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
|
||||
:class="$root.isDisabled() && 'disabled'" v-else-if="$root.mk.repeatMode == 1"
|
||||
:title="$root.getLz('term.disableRepeatOne')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small repeat active" @click="$root.mk.repeatMode = 0"
|
||||
:class="$root.isDisabled() && 'disabled'" v-else-if="$root.mk.repeatMode == 2" :title="$root.getLz('term.disableRepeat')"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-chrome-item volume display--large">
|
||||
<div class="input-container">
|
||||
|
@ -149,6 +152,37 @@
|
|||
return {
|
||||
app: this.$root,
|
||||
tabMode: "lyrics",
|
||||
video: null
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
if (app.mk.nowPlayingItem._container.type == "albums") {
|
||||
try {
|
||||
const result = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/${app.mk.nowPlayingItem._container.type}/${app.mk.nowPlayingItem._container.id}`, {
|
||||
"fields": "editorialArtwork,editorialVideo",
|
||||
})).data.data[0].attributes?.editorialVideo?.motionDetailSquare?.video
|
||||
if (result) {
|
||||
this.video = result
|
||||
} else {
|
||||
this.video = null
|
||||
}
|
||||
} catch (e) {
|
||||
this.video = null
|
||||
e = null
|
||||
}
|
||||
} else if (app.mk.nowPlayingItem._container.type == "library-albums") {
|
||||
try {
|
||||
const result = (await app.mk.api.v3.music(`/v1/me/library/albums/${app.mk.nowPlayingItem._container.id}/catalog`
|
||||
, { "fields": "editorialArtwork,editorialVideo" })).data.data[0].attributes?.editorialVideo?.motionDetailSquare?.video
|
||||
if (result) {
|
||||
this.video = result
|
||||
} else {
|
||||
this.video = null
|
||||
}
|
||||
} catch (e) {
|
||||
e = null
|
||||
this.video = null
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
class="cd-mediaitem-list-item"
|
||||
:class="{'mediaitem-selected': app.select_hasMediaItem(guid)}"
|
||||
@contextmenu="contextMenu">
|
||||
<template v-if="isVisible">
|
||||
<div class="artwork" v-if="showArtwork == true">
|
||||
<div class="artwork" v-show="isVisible" v-if="showArtwork == true">
|
||||
<mediaitem-artwork
|
||||
:url="getArtwork()"
|
||||
size="50"
|
||||
|
@ -17,7 +16,6 @@
|
|||
{{ item.attributes.name }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
<h3>{{ recom.attributes.title ? recom.attributes.title.stringForDisplay : " "}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="recom.relationships.contents.data.length >= 10">
|
||||
<button class="cd-btn-seeall" @click="app.showCollection(recom.relationships.contents, recom.attributes.title ? recom.attributes.title.stringForDisplay : '', 'listen_now')" >{{app.getLz('term.seeAll')}}</button>
|
||||
<button class="cd-btn-seeall" @click="showCollection(recom)" >{{app.getLz('term.seeAll')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="recom.attributes.display.kind == 'MusicCoverShelf'">
|
||||
<template v-if="recom.attributes.display.kind == 'MusicCoverShelf' || recom.attributes.display.kind == 'MusicCircleCoverShelf'">
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="recom.relationships.contents.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
|
@ -39,6 +39,10 @@
|
|||
visibilityChanged: function (isVisible, entry) {
|
||||
// this.isVisible = isVisible
|
||||
},
|
||||
showCollection: function (recom) {
|
||||
console.debug(recom)
|
||||
app.showCollection(recom.relationships.contents, recom.attributes.title ? recom.attributes.title.stringForDisplay : '', 'listen_now')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,9 +1,10 @@
|
|||
<script type="text/x-template" id="mediaitem-artwork">
|
||||
<div class="mediaitem-artwork" @contextmenu="contextMenu" :class="[{'rounded': (type == 'artists')}, classes]" :key="url">
|
||||
<div class="mediaitem-artwork" :style="awStyle" @contextmenu="contextMenu" :class="[{'rounded': (type == 'artists')}, classes]" :key="url">
|
||||
<img :src="app.getMediaItemArtwork(url, size, width)"
|
||||
decoding="async"
|
||||
loading="lazy"
|
||||
:style="{background: bgcolor}"
|
||||
:style="imgStyle"
|
||||
@load="imgLoaded()"
|
||||
class="mediaitem-artwork--img">
|
||||
<div v-if="video && getVideoPriority()" class="animatedartwork-view-box">
|
||||
<animatedartwork-view :priority="getVideoPriority()" :video="video"></animatedartwork-view>
|
||||
|
@ -50,11 +51,18 @@
|
|||
},
|
||||
data: function () {
|
||||
return {
|
||||
app:this.$root,
|
||||
app: this.$root,
|
||||
isVisible: false,
|
||||
style: {
|
||||
"box-shadow": ""
|
||||
},
|
||||
awStyle: {
|
||||
background: this.bgcolor
|
||||
},
|
||||
imgStyle: {
|
||||
opacity: 0,
|
||||
transition: "opacity .25s linear"
|
||||
},
|
||||
classes: []
|
||||
}
|
||||
},
|
||||
|
@ -62,6 +70,10 @@
|
|||
this.getClasses()
|
||||
},
|
||||
methods: {
|
||||
imgLoaded() {
|
||||
this.imgStyle.opacity = 1
|
||||
// this.awStyle.background = ""
|
||||
},
|
||||
contextMenu(event) {
|
||||
let self = this
|
||||
app.showMenuPanel({
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
@controller-click="route()"
|
||||
tabindex="0"
|
||||
:class="[{'mediaitem-selected': app.select_hasMediaItem(guid)}, addClasses]">
|
||||
<template v-if="isVisible">
|
||||
<div v-show="isVisible" class="listitem-content">
|
||||
<div class="popular" v-if="!showInLibrary && item?.meta?.popularity != null && item?.meta?.popularity > 0.7"></div>
|
||||
<div class="isLibrary" v-if="showLibraryStatus == true">
|
||||
<div v-if="showInLibrary" :style="{display: (showInLibrary ? 'block' : 'none'), 'margin-left':'11px'}">
|
||||
|
@ -87,7 +87,7 @@
|
|||
<div class="duration" v-if="item.attributes.playCount" @dblclick="route()">
|
||||
{{ item.attributes.playCount }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
<div v-if="reasonShown" class="reasonSP ">{{item?.meta?.reason?.stringForDisplay ?? ''}}</div>
|
||||
<div style="{'--spcolor': getBgColor()}"
|
||||
class="cd-mediaitem-square" :class="getClasses()" @contextmenu="getContextMenu">
|
||||
<template>
|
||||
<div class="artwork-container">
|
||||
<div class="artwork-container" v-show="isVisible">
|
||||
<div class="unavailable-overlay" v-if="unavailable">
|
||||
<div class="codicon codicon-circle-slash"></div>
|
||||
</div>
|
||||
|
@ -40,6 +39,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="info-rect" :class="{'info-rect-card': kind == 'card'}"
|
||||
v-show="isVisible"
|
||||
:style="{'--bgartwork': getArtworkUrl(size, true)}">
|
||||
<div class="title"
|
||||
:title="item.attributes?.name ?? (item.relationships?.contents?.data[0]?.attributes?.name ?? (item.attributes?.editorialNotes?.name ?? ''))"
|
||||
|
@ -58,7 +58,6 @@
|
|||
</div>
|
||||
<div class="subtitle" v-if="getSubtitle() == '' && kind != 'card'"> </div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
@ -88,6 +87,11 @@
|
|||
default: false,
|
||||
required: false
|
||||
},
|
||||
noScale: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: false
|
||||
},
|
||||
'contextExt': { type: Object, required: false },
|
||||
},
|
||||
data: function () {
|
||||
|
@ -252,6 +256,10 @@
|
|||
},
|
||||
getClasses() {
|
||||
let type = []
|
||||
let classes = []
|
||||
if(this.noScale) {
|
||||
classes.push("noscale")
|
||||
}
|
||||
try {
|
||||
type = this.item.type
|
||||
|
||||
|
@ -264,25 +272,26 @@
|
|||
}
|
||||
switch (type) {
|
||||
default:
|
||||
return []
|
||||
|
||||
break;
|
||||
case "editorial-elements":
|
||||
case "card":
|
||||
return ["mediaitem-card"]
|
||||
classes.push("mediaitem-card")
|
||||
break;
|
||||
case "385": // editorial
|
||||
return ["mediaitem-brick"]
|
||||
classes.push("mediaitem-brick")
|
||||
break;
|
||||
case "small":
|
||||
return ["mediaitem-small"]
|
||||
classes.push("mediaitem-small")
|
||||
break;
|
||||
case "music-videos":
|
||||
case "uploadedVideo":
|
||||
case "uploaded-videos":
|
||||
case "library-music-videos":
|
||||
return "mediaitem-video";
|
||||
classes.push("mediaitem-video")
|
||||
break;
|
||||
}
|
||||
return classes
|
||||
},
|
||||
visibilityChanged: function (isVisible, entry) {
|
||||
this.isVisible = isVisible
|
||||
|
@ -534,19 +543,16 @@
|
|||
let followActions = {
|
||||
follow: {
|
||||
icon: "./assets/feather/plus-circle.svg",
|
||||
name: app.getLz('action.follow'),
|
||||
name: app.getLz('action.favorite'),
|
||||
action: () => {
|
||||
self.app.cfg.home.followedArtists.push(this.item.id)
|
||||
self.$root.setArtistFavorite(this.item.id, true)
|
||||
}
|
||||
},
|
||||
unfollow: {
|
||||
icon: "./assets/feather/x-circle.svg",
|
||||
name: app.getLz('action.unfollow'),
|
||||
name: app.getLz('action.removeFavorite'),
|
||||
action: () => {
|
||||
let index = self.app.cfg.home.followedArtists.indexOf(this.item.id)
|
||||
if (index > -1) {
|
||||
self.app.cfg.home.followedArtists.splice(index, 1)
|
||||
}
|
||||
self.$root.setArtistFavorite(this.item.id, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,30 +66,40 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="control-buttons">
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button--small shuffle" v-if="app.mk.shuffleMode == 0"
|
||||
@click="app.mk.shuffleMode = 1"></button>
|
||||
<button class="playback-button--small shuffle active" v-else
|
||||
@click="app.mk.shuffleMode = 0"></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button previous" @click="app.prevButton()"></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button pause" @click="app.mk.pause()" v-if="app.mk.isPlaying"></button>
|
||||
<button class="playback-button play" @click="app.mk.play()" v-else></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button next" @click="app.skipToNextItem()"></button>
|
||||
</div>
|
||||
<div class="app-chrome-item">
|
||||
<button class="playback-button--small repeat" v-if="app.mk.repeatMode == 0"
|
||||
@click="app.mk.repeatMode = 1"></button>
|
||||
<button class="playback-button--small repeat repeatOne" @click="app.mk.repeatMode = 2"
|
||||
v-else-if="app.mk.repeatMode == 1"></button>
|
||||
<button class="playback-button--small repeat active" @click="app.mk.repeatMode = 0"
|
||||
v-else-if="app.mk.repeatMode == 2"></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button--small shuffle" v-if="$root.mk.shuffleMode == 0" :class="$root.isDisabled() && 'disabled'"
|
||||
@click="$root.mk.shuffleMode = 1" :title="$root.getLz('term.enableShuffle')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small shuffle active" v-else :class="$root.isDisabled() && 'disabled'"
|
||||
@click="$root.mk.shuffleMode = 0" :title="$root.getLz('term.disableShuffle')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button previous" @click="$root.prevButton()" :class="$root.isPrevDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.previous')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button stop" @click="$root.mk.stop()"
|
||||
v-if="$root.mk.isPlaying && $root.mk.nowPlayingItem.attributes.playParams.kind == 'radioStation'"
|
||||
:title="$root.getLz('term.stop')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button pause" @click="$root.mk.pause()" v-else-if="$root.mk.isPlaying"
|
||||
:title="$root.getLz('term.pause')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button play" @click="$root.mk.play()" v-else :title="$root.getLz('term.play')"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button next" @click="$root.skipToNextItem()" :class="$root.isNextDisabled() && 'disabled'"
|
||||
:title="$root.getLz('term.next')" v-b-tooltip.hover></button>
|
||||
</div>
|
||||
<div class="app-chrome-item display--large">
|
||||
<button class="playback-button--small repeat" v-if="$root.mk.repeatMode == 0" :class="$root.isDisabled() && 'disabled'"
|
||||
@click="$root.mk.repeatMode = 1" :title="$root.getLz('term.enableRepeatOne')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
|
||||
:class="$root.isDisabled() && 'disabled'" v-else-if="$root.mk.repeatMode == 1"
|
||||
:title="$root.getLz('term.disableRepeatOne')" v-b-tooltip.hover></button>
|
||||
<button class="playback-button--small repeat active" @click="$root.mk.repeatMode = 0"
|
||||
:class="$root.isDisabled() && 'disabled'" v-else-if="$root.mk.repeatMode == 2" :title="$root.getLz('term.disableRepeat')"
|
||||
v-b-tooltip.hover></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-chrome-item volume display--large">
|
||||
<div class="input-container">
|
||||
|
|
|
@ -1,355 +0,0 @@
|
|||
<script type="text/x-template" id="spatial-properties">
|
||||
<div class="modal-fullscreen spatialproperties-panel" @click.self="close()" @contextmenu.self="close()">
|
||||
<div class="modal-window" v-if="ready">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">{{$root.getLz('spatial.spatialProperties')}}</div>
|
||||
<button class="close-btn" @click="close()" :aria-label="$root.getLz('action.close')"></button>
|
||||
</div>
|
||||
<div class="modal-content">
|
||||
<template v-if="roomEditType == 'dimensions'">
|
||||
<div class="row">
|
||||
<div class="col"><h3>{{$root.getLz('spatial.roomDimensions')}}</h3></div>
|
||||
<div class="col-auto flex-center">
|
||||
<button class="md-btn" @click="roomEditType = 'positions'">{{$root.getLz('spatial.setPositions')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
{{$root.getLz('spatial.width')}}
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
||||
v-model="room_dimensions.width" step="1"/>
|
||||
</div>
|
||||
<div class="col-3 flex-center">
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
||||
v-model="room_dimensions.width" step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
{{$root.getLz('spatial.height')}}
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
||||
v-model="room_dimensions.height" step="1"/>
|
||||
</div>
|
||||
<div class="col-3 flex-center">
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
||||
v-model="room_dimensions.height" step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
{{$root.getLz('spatial.depth')}}
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
||||
v-model="room_dimensions.depth" step="1"/>
|
||||
</div>
|
||||
<div class="col-3 flex-center">
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
||||
v-model="room_dimensions.depth" step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
<label v-if="!app.cfg.audio.normalization">
|
||||
{{$root.getLz('spatial.gain')}}
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;"
|
||||
v-model="app.cfg.audio.spatial_properties.gain" step="0.1"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col visual-container">
|
||||
<div class="visual" :style="objectContainerStyle()">
|
||||
<div class="face" :style="[faceStyle()]"></div>
|
||||
<div class="face" :style="[faceStyle(), topFaceStyle()]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="roomEditType == 'positions'">
|
||||
<div class="row">
|
||||
<div class="col"><h3>{{$root.getLz('spatial.roomPositions')}}</h3></div>
|
||||
<div class="col-auto flex-center">
|
||||
<button class="md-btn" @click="roomEditType = 'dimensions'">{{$root.getLz('spatial.setDimensions')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
X ({{$root.getLz('spatial.listener')}})
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
||||
v-model="listener_position[0]" step="1"/>
|
||||
</div>
|
||||
<div class="col-3 flex-center">
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
||||
v-model="listener_position[0]" step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Y ({{$root.getLz('spatial.listener')}})
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
||||
v-model="listener_position[1]" step="1"/>
|
||||
</div>
|
||||
<div class="col-3 flex-center">
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
||||
v-model="listener_position[1]" step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Z ({{$root.getLz('spatial.listener')}})
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
||||
v-model="listener_position[2]" step="1"/>
|
||||
</div>
|
||||
<div class="col-3 flex-center">
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
||||
v-model="listener_position[2]" step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
X ({{$root.getLz('spatial.audioSource')}})
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
||||
v-model="audio_position[0]" step="1"/>
|
||||
</div>
|
||||
<div class="col-3 flex-center">
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
||||
v-model="audio_position[0]" step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Y ({{$root.getLz('spatial.audioSource')}})
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
||||
v-model="audio_position[1]" step="1"/>
|
||||
</div>
|
||||
<div class="col-3 flex-center">
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
||||
v-model="audio_position[1]" step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Z ({{$root.getLz('spatial.audioSource')}})
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<input type="range" class="md-slider" min="0" max="100" @change="setRoom()" style="width: 100%;"
|
||||
v-model="audio_position[2]" step="1"/>
|
||||
</div>
|
||||
<div class="col-3 flex-center">
|
||||
<input type="number" min="0" @change="setRoom()" style="width: 100%;text-align: center"
|
||||
v-model="audio_position[2]" step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col visual-container">
|
||||
<div class="visual">
|
||||
<div class="face" :style="[faceStyle()]"></div>
|
||||
<div class="face" :style="[faceStyle(), topFaceStyle()]"></div>
|
||||
|
||||
<!-- <div class="listener" :style="[listenerStyle()]">L</div> -->
|
||||
<!-- <div class="audiosource" :style="[audioSourceStyle()]">A</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="row">
|
||||
<div class="col"><h3>{{$root.getLz('spatial.roomMaterials')}}</h3></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"></div>
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
{{$root.getLz('spatial.up')}}
|
||||
<select class="md-select" @change="setRoom()"
|
||||
v-model="room_materials.up">
|
||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
{{$root.getLz('spatial.left')}}
|
||||
<select class="md-select" @change="setRoom()"
|
||||
v-model="room_materials.left">
|
||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
{{$root.getLz('spatial.front')}}
|
||||
<select class="md-select" @change="setRoom()"
|
||||
v-model="room_materials.front">
|
||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
{{$root.getLz('spatial.back')}}
|
||||
<select class="md-select" @change="setRoom()"
|
||||
v-model="room_materials.back">
|
||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
{{$root.getLz('spatial.right')}}
|
||||
<select class="md-select" @change="setRoom()"
|
||||
v-model="room_materials.right">
|
||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"></div>
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
{{$root.getLz('spatial.down')}}
|
||||
<select class="md-select" @change="setRoom()"
|
||||
v-model="room_materials.down">
|
||||
<option v-for="prop in roomProps" :value="prop">{{ prop }}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('spatial-properties', {
|
||||
template: '#spatial-properties',
|
||||
data: function () {
|
||||
return {
|
||||
app: this.$root,
|
||||
room_dimensions: null,
|
||||
room_materials: null,
|
||||
listener_position: null,
|
||||
audio_position: null,
|
||||
roomEditType: "dimensions",
|
||||
roomProps: [
|
||||
'transparent',
|
||||
'acoustic-ceiling-tiles',
|
||||
'brick-bare',
|
||||
'brick-painted',
|
||||
'concrete-block-coarse',
|
||||
'concrete-block-painted',
|
||||
'curtain-heavy',
|
||||
'fiber-glass-insulation',
|
||||
'glass-thin',
|
||||
'glass-thick',
|
||||
'grass',
|
||||
'linoleum-on-concrete',
|
||||
'marble',
|
||||
'metal',
|
||||
'parquet-on-concrete',
|
||||
'plaster-smooth',
|
||||
'plywood-panel',
|
||||
'polished-concrete-or-tile',
|
||||
'sheetrock',
|
||||
'water-or-ice-surface',
|
||||
'wood-ceiling',
|
||||
'wood-panel',
|
||||
'uniform'
|
||||
],
|
||||
visualMultiplier: 4,
|
||||
ready: false
|
||||
}
|
||||
},
|
||||
props: {},
|
||||
mounted() {
|
||||
this.room_dimensions = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.room_dimensions))
|
||||
this.room_materials = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.room_materials))
|
||||
this.audio_position = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.audio_position))
|
||||
this.listener_position = JSON.parse(JSON.stringify(this.$root.cfg.audio.spatial_properties.listener_position))
|
||||
if (typeof this.app.mk.nowPlayingItem != "undefined") {
|
||||
this.setRoom()
|
||||
}
|
||||
this.ready = true
|
||||
},
|
||||
methods: {
|
||||
listenerStyle() {
|
||||
let style = {
|
||||
transform: `rotateX(60deg) rotateZ(-45deg) translateX(${this.listener_position[0]}px) translateY(${this.listener_position[2]}px) translateZ(${100 + +this.listener_position[1]}px)`
|
||||
}
|
||||
return style
|
||||
},
|
||||
audioSourceStyle() {
|
||||
let style = {
|
||||
transform: `rotateX(60deg) rotateZ(-45deg) translateX(${this.audio_position[0]}px) translateY(${this.audio_position[2]}px) translateZ(${100 + +this.audio_position[1]}px)`
|
||||
}
|
||||
return style
|
||||
},
|
||||
topFaceStyle() {
|
||||
let style = {
|
||||
transform: `rotateX(60deg) rotateZ(-45deg) translateZ(${this.room_dimensions.height * this.visualMultiplier}px)`
|
||||
}
|
||||
return style
|
||||
},
|
||||
objectContainerStyle() {
|
||||
let scale = 1
|
||||
if (this.room_dimensions.width * this.visualMultiplier > 300) {
|
||||
scale = 300 / (this.room_dimensions.width * this.visualMultiplier)
|
||||
}
|
||||
let style = {
|
||||
transform: `scale(${scale})`
|
||||
}
|
||||
return style
|
||||
},
|
||||
faceStyle() {
|
||||
let style = {
|
||||
width: `${this.room_dimensions.width * this.visualMultiplier}px`,
|
||||
height: `${this.room_dimensions.depth * this.visualMultiplier}px`,
|
||||
}
|
||||
return style
|
||||
},
|
||||
close() {
|
||||
this.$root.cfg.audio.spatial_properties.room_dimensions = this.room_dimensions
|
||||
this.$root.cfg.audio.spatial_properties.room_materials = this.room_materials
|
||||
this.$root.cfg.audio.spatial_properties.audio_position = this.audio_position
|
||||
this.$root.cfg.audio.spatial_properties.listener_position = this.listener_position
|
||||
app.resetState()
|
||||
},
|
||||
setRoom() {
|
||||
window.CiderAudio.audioNodes.spatialNode.setRoomProperties(this.room_dimensions, this.room_materials);
|
||||
CiderAudio.audioNodes.spatialInput.setPosition(...this.audio_position)
|
||||
CiderAudio.audioNodes.spatialNode.setListenerPosition(...this.listener_position)
|
||||
if (!this.app.cfg.audio.normalization) {
|
||||
window.CiderAudio.audioNodes.gainNode.gain.value = app.cfg.audio.spatial_properties.gain
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -58,6 +58,12 @@
|
|||
#LOADER>svg {
|
||||
width: 128px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
#LOADER {
|
||||
background-color: #eee;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
@ -65,7 +71,7 @@
|
|||
<div id="LOADER">
|
||||
<%- include("../assets/cider-round.svg") %>
|
||||
</div>
|
||||
<div id="app" :class="getAppClasses()" :window-style="cfg.visual.directives.windowLayout">
|
||||
<div id="app" :class="getAppClasses()" :style="getAppStyle()" :library-visbile="(chrome.sidebarCollapsed ? 0 : 1)" :window-style="cfg.visual.directives.windowLayout">
|
||||
<transition name="fsModeSwitch">
|
||||
<div id="app-main" v-show="appMode == 'player'">
|
||||
<%- include('app/chrome-top'); %>
|
||||
|
@ -85,6 +91,11 @@
|
|||
</mini-view>
|
||||
</div>
|
||||
</transition>
|
||||
<transition name="fsModeSwitch">
|
||||
<div class="fullscreen-view-container oobe" v-if="appMode == 'oobe'">
|
||||
<cider-oobe></cider-oobe>
|
||||
</div>
|
||||
</transition>
|
||||
<%- include('app/panels'); %>
|
||||
<div class="cursor" v-if="chrome.showCursor"></div>
|
||||
</div>
|
||||
|
@ -94,7 +105,8 @@
|
|||
<% } %>
|
||||
|
||||
|
||||
<script async src="https://js-cdn.music.apple.com/musickit/v2/amp/musickit.js"></script>
|
||||
<script async src="<%- (env.useV3 ? "https://js-cdn.music.apple.com/musickit/v3/amp/musickit.js" : "https://js-cdn.music.apple.com/musickit/v2/amp/musickit.js" ) %>" data-web-components>
|
||||
</script>
|
||||
<script src="index.js?v=1"></script>
|
||||
|
||||
<script type="text/x-template" id="am-musiccovershelf">
|
||||
|
@ -104,7 +116,7 @@
|
|||
<!-- Sidebar Item -->
|
||||
<script type="text/x-template" id="sidebar-library-item">
|
||||
<button class="app-sidebar-item"
|
||||
:class="$parent.getSidebarItemClass(page)" @click="$root.appRoute(page)">
|
||||
:class="$parent.getSidebarItemClass(page)" @click="$root.setWindowHash(page)">
|
||||
<div class="sidebar-icon" v-html="svgIconData" v-if="svgIconData != ''"></div>
|
||||
{{ name }}
|
||||
</button>
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
<div class="col nopadding">
|
||||
<h3>{{app.getLz('home.followedArtists')}}</h3>
|
||||
</div>
|
||||
<div class="col-auto nopadding flex-center">
|
||||
<button class="cd-btn-seeall" @click="syncFavorites()" v-if="!syncingFavs">{{app.getLz('home.syncFavorites')}}</button>
|
||||
<div class="spinner" style="height: 26px;" v-else></div>
|
||||
</div>
|
||||
</div>
|
||||
<vue-horizontal>
|
||||
<div v-for="artist in artists" style="margin: 6px;">
|
||||
|
@ -14,7 +18,7 @@
|
|||
<button @click="unfollow(artist.id)" class="md-btn md-btn-glyph" style="display:flex;">
|
||||
<div class="sidebar-icon">
|
||||
<div class="svg-icon" :style="{'--url': 'url(./assets/feather/x-circle.svg)'}"></div>
|
||||
</div> {{app.getLz('action.unfollow')}}
|
||||
</div> {{app.getLz('action.removeFavorite')}}
|
||||
</button>
|
||||
</div>
|
||||
</vue-horizontal>
|
||||
|
@ -53,7 +57,8 @@
|
|||
app: this.$root,
|
||||
followedArtists: this.$root.cfg.home.followedArtists,
|
||||
artistFeed: [],
|
||||
artists: []
|
||||
artists: [],
|
||||
syncingFavs: false
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
|
@ -61,7 +66,13 @@
|
|||
await this.getArtistFeed()
|
||||
},
|
||||
methods: {
|
||||
unfollow(id) {
|
||||
async syncFavorites() {
|
||||
this.syncingFavs = true
|
||||
await app.syncFavorites()
|
||||
await this.getArtistFeed()
|
||||
this.syncingFavs = false
|
||||
},
|
||||
async unfollow(id) {
|
||||
let index = this.followedArtists.indexOf(id)
|
||||
if (index > -1) {
|
||||
this.followedArtists.splice(index, 1)
|
||||
|
@ -71,6 +82,16 @@
|
|||
if (index2 > -1) {
|
||||
this.artists.splice(index2, 1)
|
||||
}
|
||||
await app.mk.api.v3.music(`/v1/me/favorites`, {
|
||||
"art[url]": "f",
|
||||
"ids[artists]": id,
|
||||
"l": app.mklang,
|
||||
"platform": "web"
|
||||
}, {
|
||||
fetchOptions: {
|
||||
method: "DELETE"
|
||||
}
|
||||
})
|
||||
this.getArtistFeed()
|
||||
},
|
||||
async getArtistFeed() {
|
||||
|
@ -78,7 +99,7 @@
|
|||
let self = this
|
||||
this.artists = []
|
||||
this.artistFeed = []
|
||||
|
||||
|
||||
// Apple limits the number of IDs we can provide in a single API call to 50.
|
||||
// Divide it into groups of 50 and send parallel requests
|
||||
let chunks = []
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
<script type="text/x-template" id="cider-artist">
|
||||
<div class="content-inner artist-page" :class="[data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9) ? 'animated' : '']">
|
||||
<div class="content-inner artist-page"
|
||||
:class="[(data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9) || hasHero()) ? 'animated' : '']">
|
||||
<div class="artist-header" :key="data.id" v-observe-visibility="{callback: isHeaderVisible}">
|
||||
<animatedartwork-view
|
||||
:priority="true"
|
||||
v-if="data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9)"
|
||||
v-if="hasAnimated()"
|
||||
:video="data.attributes.editorialVideo.motionArtistWide16x9.video ?? (data.attributes.editorialVideo.motionArtistFullscreen16x9.video ?? '')">
|
||||
</animatedartwork-view>
|
||||
<div class="header-content" style="pointer-events: all;">
|
||||
<div class="row">
|
||||
<div class="col-sm" style="width: auto;">
|
||||
<div class="artist-image" v-if="!(data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9))">
|
||||
<div class="artist-image"
|
||||
v-if="!(data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9))&& !hasHero()">
|
||||
<mediaitem-artwork
|
||||
shadow="large"
|
||||
:url="data.attributes.artwork ? data.attributes.artwork.url : ''"
|
||||
size="190" type="artists"></mediaitem-artwork>
|
||||
<button class="overlay-play" @click="app.mk.setStationQueue({artist:'a-'+data.id}).then(()=>{
|
||||
<button class="overlay-play" @click="app.mk.setStationQueue({artist:'a-'+data.id}).then(()=>{
|
||||
app.mk.play()
|
||||
})" :aria-label="app.getLz('term.play')">
|
||||
<%- include("../svg/play.svg") %>
|
||||
|
@ -22,7 +24,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="col flex-center artist-title"
|
||||
:class="{'artist-animation-on': (data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9)) }"
|
||||
:class="{'artist-animation-on': (data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9)) || hasHero() }"
|
||||
>
|
||||
<button class="artist-play" @click="app.mk.setStationQueue({artist:'a-'+data.id}).then(()=>{
|
||||
app.mk.play()
|
||||
|
@ -30,15 +32,25 @@
|
|||
<h1>{{ data.attributes.name }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<button class="more-btn-round" @click="artistMenu" style="pointer-events: all;" :aria-label="app.getLz('term.more')">
|
||||
<button class="more-btn-round favorite" @click="artistMenu" style="pointer-events: all;"
|
||||
:aria-label="app.getLz('term.more')">
|
||||
<div class="svg-icon"></div>
|
||||
</button>
|
||||
<button class="more-btn-round menu" @click="artistMenu" style="pointer-events: all;"
|
||||
:aria-label="app.getLz('term.more')">
|
||||
<div class="svg-icon"></div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="artworkContainer" v-if="!(data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9))">
|
||||
<artwork-material :url="data.attributes.artwork.url" size="190" images="1"></artwork-material>
|
||||
<div class="artworkContainer"
|
||||
v-if="!(data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9)) && !hasHero()">
|
||||
<artwork-material :url="data.attributes.artwork.url" size="190" images="1"></artwork-material>
|
||||
</div>
|
||||
<div class="artist-hero" v-if="hasHero() && !hasAnimated()">
|
||||
<mediaitem-artwork shadow="none" :url="hasHero()" size="2048" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="floating-header" :style="{opacity: (headerVisible ? 0 : 1),'pointer-events': (headerVisible ? 'none' : '')}">
|
||||
<div class="floating-header"
|
||||
:style="{opacity: (headerVisible ? 0 : 1),'pointer-events': (headerVisible ? 'none' : '')}">
|
||||
<div class="row">
|
||||
<div class="col-auto flex-center">
|
||||
<button class="artist-play" style="display:block;" @click="app.mk.setStationQueue({artist:'a-'+data.id}).then(()=>{
|
||||
|
@ -49,7 +61,7 @@
|
|||
<h3>{{ data.attributes.name }}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center">
|
||||
<button class="more-btn-round" @click="artistMenu" :aria-label="app.getLz('term.more')">
|
||||
<button class="more-btn-round menu" @click="artistMenu" :aria-label="app.getLz('term.more')">
|
||||
<div class="svg-icon"></div>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -60,8 +72,8 @@
|
|||
<div class="latestRelease" v-if="data.views['latest-release'].data.length != 0">
|
||||
<h3>{{app.getLz('term.latestReleases')}}</h3>
|
||||
<div style="width: auto;margin: 0 auto;">
|
||||
<mediaitem-square kind="card" v-for="song in data.views['latest-release'].data"
|
||||
:item="song">
|
||||
<mediaitem-square kind="card" :no-scale="true" v-for="song in data.views['latest-release'].data"
|
||||
:item="song">
|
||||
</mediaitem-square>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -70,8 +82,12 @@
|
|||
<div class="col" style="padding:0;">
|
||||
<h3>{{app.getLz('term.topSongs')}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="data.views['top-songs'].data.length >= 20" style="padding:0;">
|
||||
<button class="cd-btn-seeall" @click="app.showArtistView(data.id, data.attributes.name + ' - Top Songs', 'top-songs')">{{app.getLz('term.seeAll')}}</button>
|
||||
<div class="col-auto flex-center" v-if="data.views['top-songs'].data.length >= 20"
|
||||
style="padding:0;">
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showArtistView(data.id, data.attributes.name + ' - Top Songs', 'top-songs')">
|
||||
{{app.getLz('term.seeAll')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -96,23 +112,27 @@
|
|||
</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="data.views[view].data.length >= 10">
|
||||
<button class="cd-btn-seeall" @click="app.showArtistView(data.id, data.attributes.name + ' - ' + data.views[view].attributes.title, view)">{{app.getLz('term.seeAll')}}</button>
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showArtistView(data.id, data.attributes.name + ' - ' + data.views[view].attributes.title, view)">
|
||||
{{app.getLz('term.seeAll')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="!((data.views[view].attributes.title ?
|
||||
data.views[view].attributes.title : '???').includes('Video') || (data.views[view].attributes.title ?
|
||||
data.views[view].attributes.title : '???').includes('More To See'))">
|
||||
<mediaitem-scroller-horizontal-large :items="data.views[view].data.limit(10)">
|
||||
</mediaitem-scroller-horizontal-large>
|
||||
<mediaitem-scroller-horizontal-large :items="data.views[view].data.limit(10)">
|
||||
</mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-else>
|
||||
<mediaitem-scroller-horizontal-mvview
|
||||
:items="data.views[view].data.limit(10)"></mediaitem-scroller-horizontal-mvview>
|
||||
:items="data.views[view].data.limit(10)"></mediaitem-scroller-horizontal-mvview>
|
||||
</template>
|
||||
</template>
|
||||
<div class="row">
|
||||
<div class="col" v-if="data.attributes.artistBio">
|
||||
<h3>{{ $root.stringTemplateParser($root.getLz('term.aboutArtist'), {"artistName": data.attributes.name}) }}</h3>
|
||||
<h3>{{ $root.stringTemplateParser($root.getLz('term.aboutArtist'), {"artistName":
|
||||
data.attributes.name}) }}</h3>
|
||||
<p v-html="data.attributes.artistBio"></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
|
@ -147,24 +167,40 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
hasAnimated() {
|
||||
if(this.data.attributes?.editorialVideo && (this.data.attributes?.editorialVideo?.motionArtistWide16x9 || this.data.attributes?.editorialVideo?.motionArtistFullscreen16x9)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
hasHero() {
|
||||
if(this.data.attributes?.editorialArtwork?.centeredFullscreenBackground){
|
||||
return this.data.attributes?.editorialArtwork?.centeredFullscreenBackground.url
|
||||
} else if(this.data.attributes?.editorialArtwork?.bannerUber) {
|
||||
return this.data.attributes?.editorialArtwork?.bannerUber.url
|
||||
}else if(this.data.attributes?.editorialArtwork?.subscriptionHero){
|
||||
return this.data.attributes?.editorialArtwork?.subscriptionHero.url
|
||||
}
|
||||
return false;
|
||||
},
|
||||
isHeaderVisible(visible) {
|
||||
this.headerVisible = visible
|
||||
},
|
||||
artistMenu (event) {
|
||||
async artistMenu(event) {
|
||||
let self = this
|
||||
let followAction = "follow"
|
||||
let followActions = {
|
||||
follow: {
|
||||
icon: "./assets/feather/plus-circle.svg",
|
||||
name: app.getLz('action.follow'),
|
||||
action: ()=>{
|
||||
action: () => {
|
||||
self.app.cfg.home.followedArtists.push(self.data.id)
|
||||
}
|
||||
},
|
||||
unfollow: {
|
||||
icon: "./assets/feather/x-circle.svg",
|
||||
name: app.getLz('action.unfollow'),
|
||||
action: ()=>{
|
||||
action: () => {
|
||||
let index = self.app.cfg.home.followedArtists.indexOf(self.data.id)
|
||||
if (index > -1) {
|
||||
self.app.cfg.home.followedArtists.splice(index, 1)
|
||||
|
@ -172,25 +208,45 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
let favoriteActions = {
|
||||
favorite: {
|
||||
icon: "./assets/star.svg",
|
||||
name: app.getLz('action.favorite'),
|
||||
action: () => {
|
||||
app.setArtistFavorite(app.artistPage.data.id, true)
|
||||
}
|
||||
},
|
||||
removeFavorite: {
|
||||
icon: "./assets/star.svg",
|
||||
name: app.getLz('action.removeFavorite'),
|
||||
action: () => {
|
||||
app.setArtistFavorite(app.artistPage.data.id, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.app.cfg.home.followedArtists.includes(self.data.id)) {
|
||||
followAction = "unfollow"
|
||||
}
|
||||
const inFavorites = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${app.artistPage.data.id}`, {
|
||||
"fields[artists]": "inFavorites"
|
||||
})).data.data[0].attributes?.inFavorites
|
||||
app.showMenuPanel({
|
||||
items: [
|
||||
{
|
||||
icon: "./assets/feather/play.svg",
|
||||
name: app.getLz('action.startRadio'),
|
||||
action: ()=>{
|
||||
app.mk.setStationQueue({artist:self.data.id}).then(()=>{
|
||||
action: () => {
|
||||
app.mk.setStationQueue({artist: self.data.id}).then(() => {
|
||||
app.mk.play()
|
||||
})
|
||||
}
|
||||
},
|
||||
followActions[followAction],
|
||||
favoriteActions[inFavorites ? "removeFavorite" : "favorite"],
|
||||
// followActions[followAction],
|
||||
{
|
||||
icon: "./assets/feather/share.svg",
|
||||
name: app.getLz('term.share'),
|
||||
action: ()=>{
|
||||
action: () => {
|
||||
self.app.copyToClipboard(self.data.attributes.url)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,12 @@
|
|||
<select class="md-select" style="width:180px;"
|
||||
v-model="app.cfg.audio.maikiwiAudio.ciderPPE_value"
|
||||
v-on:change="CiderAudio.hierarchical_loading()">
|
||||
<option value="MAIKIWI">Maikiwi</option>
|
||||
<option value="MAIKIWI">Maikiwi ({{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.adaptive')}})</option>
|
||||
<option value="MAIKIWI_LEGACY">Maikiwi ({{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy')}})</option>
|
||||
<option value="NATURAL">
|
||||
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.standard')}}
|
||||
</option>
|
||||
<option value="LEGACY">{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPEStrength.legacy')}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -100,7 +102,7 @@
|
|||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<input type="checkbox" v-model="app.cfg.audio.maikiwiAudio.spatial"
|
||||
v-on:change="toggleMaikiwiSpatial" switch/>
|
||||
v-on:change="CiderAudio.hierarchical_loading();" switch/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line"
|
||||
|
@ -113,7 +115,7 @@
|
|||
<div class="md-option-segment md-option-segment_auto">
|
||||
<select class="md-select" style="width:180px;"
|
||||
v-model="$root.cfg.audio.maikiwiAudio.spatialProfile"
|
||||
v-on:change="toggleMaikiwiSpatial">
|
||||
v-on:change="CiderAudio.hierarchical_loading();">
|
||||
<option v-for="profile in spprofiles" :value="profile.id">{{ getProfileLz("CTS", profile.name) }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
@ -170,11 +172,10 @@
|
|||
},
|
||||
methods: {
|
||||
getProfileLz(type, name) {
|
||||
let result = "";
|
||||
|
||||
// Hard-coded shiz
|
||||
switch (name) {
|
||||
case "CRYPTO":
|
||||
return "Cryptofyre";
|
||||
break;
|
||||
|
||||
case "Maikiwi":
|
||||
return "Maikiwi";
|
||||
break;
|
||||
|
@ -183,43 +184,33 @@
|
|||
return "Maikiwi+";
|
||||
break;
|
||||
|
||||
case "Minimal+":
|
||||
return this.$root.getLz('settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.minimal') + "+";
|
||||
break;
|
||||
|
||||
case "live":
|
||||
return "LIVE";
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (type) {
|
||||
case "CAR":
|
||||
return this.$root.getLz('settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.' + name);
|
||||
result = this.$root.getLz('settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode.' + name);
|
||||
if (result === "settings.option.audio.enableAdvancedFunctionality.atmosphereRealizerMode." + name) {
|
||||
return name;
|
||||
}
|
||||
else {return result;}
|
||||
break;
|
||||
case "CTS":
|
||||
return this.$root.getLz('settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.' + name.toLowerCase());
|
||||
result = this.$root.getLz('settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile.' + name.toLowerCase());
|
||||
if (result === "settings.option.audio.enableAdvancedFunctionality.tunedAudioSpatialization.profile." + name.toLowerCase()) {
|
||||
return name;
|
||||
}
|
||||
else {return result;}
|
||||
break;
|
||||
default:
|
||||
return name;
|
||||
}
|
||||
},
|
||||
toggleSpatial: function () {
|
||||
if (app.cfg.audio.maikiwiAudio.spatial) {
|
||||
CiderAudio.spatialOn()
|
||||
CiderAudio.hierarchical_loading();
|
||||
} else {
|
||||
CiderAudio.spatialOff()
|
||||
}
|
||||
},
|
||||
toggleMaikiwiSpatial: function () {
|
||||
if (app.cfg.audio.maikiwiAudio.spatial === true) {
|
||||
CiderAudio.spatialOn()
|
||||
CiderAudio.hierarchical_loading();
|
||||
//let normalized = Math.pow(10, (((Math.log10(app.mk.volume) * 20) - 14) / 20));
|
||||
//app.mk.volume = normalized
|
||||
// -13dBFS Target
|
||||
} else {
|
||||
//let normalized = Math.pow(10, (((Math.log10(app.mk.volume) * 20) + 14) / 20));
|
||||
//app.mk.volume = normalized
|
||||
CiderAudio.spatialOn()
|
||||
CiderAudio.hierarchical_loading();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
133
src/renderer/views/pages/charts.ejs
Normal file
133
src/renderer/views/pages/charts.ejs
Normal file
|
@ -0,0 +1,133 @@
|
|||
<script type="text/x-template" id="cider-charts">
|
||||
<div class="content-inner">
|
||||
<h1 class="header-text">{{$root.getLz("term.charts")}}</h1>
|
||||
<template v-if="songs != []">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ songs.name ?? ""}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="songs.data.length > 12">
|
||||
<button class="cd-btn-seeall" @click="app.showCollection((songs ?? []), songs.name ?? '', 'default')" >{{app.getLz('term.seeAll')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mediaitem-list-item__grid">
|
||||
<listitem-horizontal :items="(songs?.data ?? []).limit(12)">
|
||||
</listitem-horizontal>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="albums != []">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ albums.name ?? ""}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="songs.data.length > 12">
|
||||
<button class="cd-btn-seeall" @click="app.showCollection((albums ?? []), albums.name ?? '', 'default')" >{{app.getLz('term.seeAll')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="(albums?.data ?? []).limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-if="playlists != []">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ playlists.name ?? ""}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="playlists.data.length > 12">
|
||||
<button class="cd-btn-seeall" @click="app.showCollection((playlists ?? []), playlists.name ?? '', 'default')" >{{app.getLz('term.seeAll')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="(playlists?.data ?? []).limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-if="musicvideos != []">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ musicvideos.name ?? ""}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="musicvideos.data.length > 12">
|
||||
<button class="cd-btn-seeall" @click="app.showCollection((musicvideos ?? []), musicvideos.name ?? '', 'default')" >{{app.getLz('term.seeAll')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="(musicvideos?.data ?? []).limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-if="globalcharts != []">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ globalcharts.name ?? ""}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="globalcharts.data.length > 12">
|
||||
<button class="cd-btn-seeall" @click="app.showCollection((globalcharts ?? []), globalcharts.name ?? '', 'default')" >{{app.getLz('term.seeAll')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="(globalcharts?.data ?? []).limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-if="citycharts != []">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ citycharts.name ?? ""}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="citycharts.data.length > 12">
|
||||
<button class="cd-btn-seeall" @click="app.showCollection((citycharts ?? []), citycharts.name ?? '', 'default')" >{{app.getLz('term.seeAll')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="(citycharts?.data ?? []).limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('cider-charts', {
|
||||
template: "#cider-charts",
|
||||
data: function () {
|
||||
return {
|
||||
app: this.$root,
|
||||
songs: [],
|
||||
albums: [],
|
||||
playlists: [],
|
||||
musicvideos: [],
|
||||
citycharts: [],
|
||||
globalcharts: [],
|
||||
categories: [],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getData();
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
let self = this;
|
||||
app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/charts`, {
|
||||
types: 'albums,songs,music-videos,playlists',
|
||||
l: 'en-gb',
|
||||
platform: 'auto',
|
||||
limit: '50',
|
||||
genre: '34',
|
||||
include: 'tracks',
|
||||
with: 'cityCharts,dailyGlobalTopCharts',
|
||||
extend: 'artistUrl',
|
||||
'fields[albums]': 'artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url',
|
||||
'fields[playlists]': 'artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url,curatorName'
|
||||
}).then(res => {
|
||||
let page = res.data?.results ?? [];
|
||||
self.songs = page.songs[0] ?? [];
|
||||
self.albums = page.albums[0] ?? [];
|
||||
self.playlists = page.playlists[0] ?? [];
|
||||
self.musicvideos = page['music-videos'][0] ?? [];
|
||||
self.citycharts = page.cityCharts[0] ?? [];
|
||||
self.globalcharts = page.dailyGlobalTopCharts[0] ?? [];
|
||||
})
|
||||
// let self = this;
|
||||
// app.mk.api.music(`/v1/catalog/${app.mk.storefrontId}/charts?types=songs%2Calbums%2Cplaylists&limit=36`).then(res => {
|
||||
// let page = res.data?.results ?? [];
|
||||
// self.songs = page.songs[0] ?? [];
|
||||
// self.albums = page.albums[0] ?? [];
|
||||
// self.playlists = page.playlists[0] ?? [];
|
||||
// })
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -80,7 +80,7 @@
|
|||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="playlist-controls" v-observe-visibility="{callback: isHeaderVisible}">
|
||||
<div class="playlist-controls" v-observe-visibility="{callback: isHeaderVisible}" style="z-index: 20;">
|
||||
<button class="md-btn md-btn-primary md-btn-icon" style="min-width: 100px;"
|
||||
@click="app.mk.shuffleMode = 0; play()"><img class="md-ico-play">
|
||||
{{app.getLz('term.play')}}
|
||||
|
@ -121,7 +121,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="artworkContainer" v-if="data.attributes.artwork != null">
|
||||
<artwork-material :url="data.attributes.artwork.url" size="260" images="1"></artwork-material>
|
||||
<artwork-material :url="data.attributes.artwork.url" size="500" images="1"></artwork-material>
|
||||
</div>
|
||||
<button class="md-btn md-btn-small editTracksBtn" v-if="(data.attributes.canEdit && data.type == 'library-playlists')" @click="editing = !editing">
|
||||
<span v-if="!editing">
|
||||
|
@ -648,39 +648,11 @@
|
|||
app.copyToClipboard(res.data.data[0].attributes.url)
|
||||
})
|
||||
}
|
||||
},
|
||||
"follow": {
|
||||
name: app.getLz('action.follow'),
|
||||
icon: "./assets/feather/plus-circle.svg",
|
||||
hidden: false,
|
||||
action: () => {
|
||||
app.followArtistById(artistId, true)
|
||||
}
|
||||
},
|
||||
"unfollow": {
|
||||
name: app.getLz('action.unfollow'),
|
||||
icon: "./assets/feather/x-circle.svg",
|
||||
hidden: true,
|
||||
action: () => {
|
||||
app.followArtistById(artistId, false)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
app.showMenuPanel(menuItems, event)
|
||||
|
||||
if (artistId != null) {
|
||||
if (app.followingArtist(artistId)) {
|
||||
menuItems.items.follow.hidden = true
|
||||
menuItems.items.unfollow.hidden = false
|
||||
} else {
|
||||
menuItems.items.follow.hidden = false
|
||||
menuItems.items.unfollow.hidden = true
|
||||
}
|
||||
} else {
|
||||
menuItems.items.follow.hidden = true
|
||||
menuItems.items.unfollow.hidden = true
|
||||
}
|
||||
try {
|
||||
let rating = await app.getRating(self.data)
|
||||
if (rating == 0) {
|
||||
|
|
|
@ -58,19 +58,33 @@
|
|||
},
|
||||
methods: {
|
||||
getClasses() {
|
||||
if(this.commonKind != "song") {
|
||||
return "collection-list-square";
|
||||
}else{
|
||||
if ((this.data?.data?.length ?? 0) > 0) {
|
||||
let item = this.data.data[0]
|
||||
if (typeof item.kind != "undefined") {
|
||||
this.commonKind = item.kind;
|
||||
return item.kind
|
||||
}
|
||||
if (typeof item.attributes.playParams != "undefined") {
|
||||
this.commonKind = item.attributes.playParams.kind
|
||||
return item.attributes.playParams.kind
|
||||
}
|
||||
if (this.commonKind != "song") {
|
||||
return "collection-list-square";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
},
|
||||
getKind(item) {
|
||||
if (typeof item.kind != "undefined") {
|
||||
this.commonKind = item.kind;
|
||||
// this.commonKind = item.kind;
|
||||
return item.kind
|
||||
}
|
||||
if (typeof item.attributes.playParams != "undefined") {
|
||||
this.commonKind = item.attributes.playParams.kind
|
||||
// this.commonKind = item.attributes.playParams.kind
|
||||
return item.attributes.playParams.kind
|
||||
}
|
||||
return this.commonKind
|
||||
|
|
|
@ -61,18 +61,28 @@
|
|||
};
|
||||
},
|
||||
async mounted() {
|
||||
const queryDefaults = `?platform=web&l=en-us&extend=editorialArtwork%2CartistUrl&omit%5Bresource%3Aartists%5D=relationships&include[groupings]=curator&include[albums]=artists&include[songs]=artists&include[music-videos]=artists&fields%5Bartists%5D=name%2Curl%2Cartwork%2CeditorialArtwork%2CgenreNames%2CeditorialNotes`
|
||||
const queryDefaults = {
|
||||
"platform": "web",
|
||||
"l" : this.$root.mklang,
|
||||
"extend": "editorialArtwork,artistUrl",
|
||||
"omit[resource:artists]": "relationships",
|
||||
"include[groupings]": "curator",
|
||||
"include[albums]": "artists",
|
||||
"include[songs]": "artists",
|
||||
"include[music-videos]": "artists",
|
||||
"fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes",
|
||||
}
|
||||
const hash = window.location.hash;
|
||||
// get everything after the first / character but keep everything afterwards
|
||||
const query = hash.substring(hash.indexOf("/") + 1);
|
||||
const query = hash.substring(hash.indexOf("/") + 1, hash.indexOf("&") > 0 ? hash.indexOf("&") : hash.length);
|
||||
this.query = query;
|
||||
if(!this.query.includes("?")) {
|
||||
this.query += queryDefaults;
|
||||
}
|
||||
// if(!this.query.includes("?")) {
|
||||
// this.query += queryDefaults;
|
||||
// }
|
||||
console.debug(query);
|
||||
const result = await this.$root.mk.api.v3.music(
|
||||
`/v1/editorial/${this.$root.mk.storefrontId}/groupings/${this.query}`
|
||||
);
|
||||
,!this.query.includes("&") ? queryDefaults : {"platform": "web"});
|
||||
this.data = result.data.data[0];
|
||||
|
||||
console.log(this.data);
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
<h3>{{app.getLz('home.artistsFeed')}}</h3>
|
||||
</div>
|
||||
<div class="col-auto nopadding flex-center">
|
||||
<button class="cd-btn-seeall" @click="syncFavorites()" v-if="!syncingFavs">{{app.getLz('home.syncFavorites')}}</button>
|
||||
<div class="spinner" style="height: 26px;" v-else></div>
|
||||
<button class="cd-btn-seeall" @click="app.appRoute('artist-feed')">{{app.getLz('term.seeAll')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -113,7 +115,8 @@
|
|||
page: "main",
|
||||
sectionsReady: [],
|
||||
year: new Date().getFullYear(),
|
||||
seenReplay: localStorage.getItem('seenReplay')
|
||||
seenReplay: localStorage.getItem('seenReplay'),
|
||||
syncingFavs: false
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
|
@ -128,6 +131,12 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
async syncFavorites() {
|
||||
this.syncingFavs = true
|
||||
await app.syncFavorites()
|
||||
await this.getArtistFeed()
|
||||
this.syncingFavs = false
|
||||
},
|
||||
async seeAllRecentlyPlayed() {
|
||||
let hist = await app.mk.api.v3.music(`/v1/me/recent/played`, {
|
||||
l: this.$root.mklang,
|
||||
|
@ -188,7 +197,7 @@
|
|||
async getArtistFeed() {
|
||||
let artists = this.followedArtists
|
||||
let self = this
|
||||
|
||||
this.artistFeed = []
|
||||
let chunks = []
|
||||
for (let artistIdx = 0; artistIdx < artists.length; artistIdx += 50) {
|
||||
chunks.push(artists.slice(artistIdx, artistIdx + 50));
|
||||
|
|
|
@ -226,10 +226,10 @@
|
|||
name: "Reduce Visuals",
|
||||
file: "reduce_visuals.less"
|
||||
})
|
||||
themes.unshift({
|
||||
name: "Inline Drawer",
|
||||
file: "inline_drawer.less"
|
||||
})
|
||||
// themes.unshift({
|
||||
// name: "Inline Drawer",
|
||||
// file: "inline_drawer.less"
|
||||
// })
|
||||
themes.unshift({
|
||||
name: "Dark",
|
||||
file: "dark.less"
|
||||
|
|
|
@ -170,6 +170,11 @@
|
|||
Vue.component('keybinds-settings', {
|
||||
template: "#keybinds-settings",
|
||||
props: [],
|
||||
data: function () {
|
||||
return {
|
||||
app: this.$root
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
keyBindUpdate: function (action) {
|
||||
const blur = document.createElement('div');
|
||||
|
@ -230,14 +235,14 @@
|
|||
app.cfg.general.keybindings.browse = [app.platform == "darwin" ? "Command" : "Control", "B"];
|
||||
app.cfg.general.keybindings.recentAdd = [app.platform == "darwin" ? "Command" : "Control", "G"];
|
||||
app.cfg.general.keybindings.songs = [app.platform == "darwin" ? "Command" : "Control", "J"];
|
||||
app.cfg.general.keybindings.albums = [app.platform == "darwin" ? "Command" : "Control", "S"];
|
||||
app.cfg.general.keybindings.albums = [app.platform == "darwin" ? "Command" : "Control", "A"];
|
||||
app.cfg.general.keybindings.artists = [app.platform == "darwin" ? "Command" : "Control", "D"];
|
||||
app.cfg.general.keybindings.togglePrivateSession = [app.platform == "darwin" ? "Command" : "Control", "P"];
|
||||
app.cfg.general.keybindings.webRemote = [app.platform == "darwin" ? "Command" : "Control", "W"];
|
||||
app.cfg.general.keybindings.audioSettings = [app.platform == "darwin" ? "Option" : "Alt", "A"];
|
||||
app.cfg.general.keybindings.pluginMenu = [app.platform == "darwin" ? "Option" : "Alt", "P"];
|
||||
app.cfg.general.keybindings.castToDevices = [app.platform == "darwin" ? "Option" : "Alt", "C"];
|
||||
app.cfg.general.keybindings.settings = [app.platform == "darwin" ? "Option" : "Alt", "S"];
|
||||
app.cfg.general.keybindings.webRemote = [app.platform == "darwin" ? "Command" : "Control",app.platform == "darwin" ? "Option" : (app.platform == "linux" ? "Shift" : "Alt"), "W"];
|
||||
app.cfg.general.keybindings.audioSettings = [app.platform == "darwin" ? "Command" : "Control",app.platform == "darwin" ? "Option" : (app.platform == "linux" ? "Shift" : "Alt"), "A"];
|
||||
app.cfg.general.keybindings.pluginMenu = [app.platform == "darwin" ? "Command" : "Control",app.platform == "darwin" ? "Option" : (app.platform == "linux" ? "Shift" : "Alt"), "P"];
|
||||
app.cfg.general.keybindings.castToDevices = [app.platform == "darwin" ? "Command" : "Control",app.platform == "darwin" ? "Option" : (app.platform == "linux" ? "Shift" : "Alt"), "C"];
|
||||
app.cfg.general.keybindings.settings = [app.platform == "darwin" ? "Command" : "Control", ","];
|
||||
app.cfg.general.keybindings.openDeveloperTools = [app.platform == "darwin" ? "Command" : "Control", app.platform == "darwin" ? "Option" : "Shift", "I"];
|
||||
notyf.success(app.getLz('settings.notyf.general.keybindings.update.success'));
|
||||
bootbox.confirm(app.getLz("settings.prompt.general.keybindings.update.success"), (ok) => {
|
||||
|
|
|
@ -1,58 +1,70 @@
|
|||
<template v-if="page == 'library-recentlyadded'">
|
||||
<script type="text/x-template" id="cider-recentlyadded">
|
||||
<div class="content-inner">
|
||||
<div class="row">
|
||||
<div class="col" style="padding:0;">
|
||||
<h1 class="header-text">{{$root.getLz('term.recentlyAdded')}}</h1>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button v-if="library.albums.downloadState == 2" @click="getLibraryAlbumsFull(true, 0)"
|
||||
class="reload-btn" :aria-label="app.getLz('menubar.options.reload')"><%- include('../svg/redo.svg') %></button>
|
||||
</div>
|
||||
<h1 class="header-text">{{$root.getLz('term.recentlyAdded')}}</h1>
|
||||
<div class="well itemContainer" v-if="itemSize == 'normal'">
|
||||
<mediaitem-square v-for="item in items" :item="item"></mediaitem-square>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col" style="padding:0;">
|
||||
<div class="search-input-container" style="width:100%;margin: 16px 0;">
|
||||
<div class="search-input--icon"></div>
|
||||
<input type="search"
|
||||
style="width:100%;"
|
||||
spellcheck="false"
|
||||
:placeholder="$root.getLz('term.search') + '...'"
|
||||
@input="searchLibraryAlbums"
|
||||
v-model="library.albums.search" class="search-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto flex-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<select class="md-select" v-model="library.albums.sortOrder[0]"
|
||||
@change="searchLibraryAlbums(0)">
|
||||
<optgroup :label="$root.getLz('term.sortOrder')">
|
||||
<option value="asc">{{$root.getLz('term.sortOrder.ascending')}}</option>
|
||||
<option value="desc">{{$root.getLz('term.sortOrder.descending')}}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<select class="md-select" v-model="library.albums.viewAs">
|
||||
<optgroup :label="$root.getLz('term.viewAs')">
|
||||
<option value="covers">{{$root.getLz('term.viewAs.coverArt')}}</option>
|
||||
<option value="list">{{$root.getLz('term.viewAs.list')}}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="well itemContainer" v-else="itemSize == 'compact'">
|
||||
<mediaitem-list-item :show-meta-data="true" :show-library-status="false" v-for="item in items" :item="item"></mediaitem-list-item>
|
||||
</div>
|
||||
<div class="well">
|
||||
<div class="albums-square-container">
|
||||
<mediaitem-square v-if="library.albums.viewAs == 'covers'" :item="item"
|
||||
v-for="item in library.albums.displayListing">
|
||||
</mediaitem-square>
|
||||
</div>
|
||||
<mediaitem-list-item v-if="library.albums.viewAs == 'list'" :show-duration="false" :show-meta-data="true"
|
||||
:show-library-status="false" :item="item"
|
||||
v-for="item in library.albums.displayListing">
|
||||
</mediaitem-list-item>
|
||||
<div class="well itemContainer" v-show="loading">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
<button v-if="nextUrl && !loading" style="opacity:0;height: 32px;" v-observe-visibility="{callback: visibilityChanged}">{{$root.getLz('term.showMore')}}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component("cider-recentlyadded", {
|
||||
template: "#cider-recentlyadded",
|
||||
computed: {
|
||||
items() {
|
||||
return this.$store.state.pageState['recentlyAdded'].items;
|
||||
},
|
||||
nextUrl() {
|
||||
return this.$store.state.pageState['recentlyAdded'].nextUrl;
|
||||
},
|
||||
itemSize() {
|
||||
return this.$store.state.pageState['recentlyAdded'].size
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
loading: false,
|
||||
firstRoute: `/v1/me/library/recently-added?l=${app.mklang}&platform=web&include[library-albums]=artists&include[library-artists]=catalog&fields[artists]=url&fields%5Balbums%5D=artistName%2CartistUrl%2Cartwork%2CcontentRating%2CeditorialArtwork%2Cname%2CplayParams%2CreleaseDate%2Curl&includeOnly=catalog%2Cartists&limit=25`
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
if(this.$store.state.pageState['recentlyAdded'].items.length !== 0) return
|
||||
|
||||
const firstResult = await app.mk.api.v3.music(this.firstRoute)
|
||||
this.$store.state.pageState["recentlyAdded"].items = firstResult.data.data
|
||||
this.$store.state.pageState["recentlyAdded"].nextUrl = firstResult.data.next
|
||||
},
|
||||
beforeDestroy() {
|
||||
// this.$store.state.pageState["recently-added"].scrollPosY = $("#app-content").scrollTop()
|
||||
},
|
||||
methods: {
|
||||
visibilityChanged: function(isVisible, entry) {
|
||||
if (isVisible && !this.loading) {
|
||||
this.getNextData();
|
||||
}
|
||||
},
|
||||
async getNextData() {
|
||||
if (this.$store.state.pageState["recentlyAdded"].nextUrl) {
|
||||
this.loading = true;
|
||||
const nextResult = await app.mk.api.v3.music(this.$store.state.pageState["recentlyAdded"].nextUrl)
|
||||
this.$store.state.pageState["recentlyAdded"].items = this.$store.state.pageState["recentlyAdded"].items.concat(nextResult.data.data)
|
||||
if (nextResult.data.next) {
|
||||
this.$store.state.pageState["recentlyAdded"].nextUrl = nextResult.data.next
|
||||
} else {
|
||||
this.$store.state.pageState["recentlyAdded"].nextUrl = null
|
||||
}
|
||||
this.loading = false;
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
179
src/renderer/views/pages/oobe.ejs
Normal file
179
src/renderer/views/pages/oobe.ejs
Normal file
|
@ -0,0 +1,179 @@
|
|||
<script type="text/x-template" id="cider-oobe">
|
||||
<div class="content-inner oobe">
|
||||
<!-- before_we_start-->
|
||||
<!-- <transition name=""> -->
|
||||
<div class="oobe-view" v-if="screen == 'before_we_start'">
|
||||
<div class="oobe-header">
|
||||
{{ getLz("oobe.amupsell.title") }}
|
||||
</div>
|
||||
<div class="oobe-body text">{{ getLz("oobe.amupsell.text") }}</div>
|
||||
<div class="oobe-footer">
|
||||
<div class="btn-group">
|
||||
<div class="md-btn" @click="screen = 'welcome'">{{ getLz("oobe.next") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </transition> -->
|
||||
|
||||
<!-- Welcome -->
|
||||
<!-- <transition name=""> -->
|
||||
<div class="oobe-view" v-if="screen == 'welcome'">
|
||||
<div class="oobe-header">
|
||||
{{ getLz("oobe.intro.title") }}
|
||||
</div>
|
||||
<div class="oobe-body text">{{ getLz("oobe.intro.text") }}</div>
|
||||
<div class="oobe-footer">
|
||||
<div class="btn-group">
|
||||
<div class="md-btn" @click="screen = 'before_we_start'">{{ getLz("oobe.previous") }}</div>
|
||||
<div class="md-btn" @click="screen = 'general'">{{ getLz("oobe.next") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </transition> -->
|
||||
|
||||
<!-- General -->
|
||||
<!-- <transition name=""> -->
|
||||
<div class="oobe-view" v-if="screen == 'general'">
|
||||
<div class="oobe-header">
|
||||
{{ getLz("oobe.general.title") }}
|
||||
</div>
|
||||
<div class="oobe-body text">{{ getLz("oobe.general.text") }}</div>
|
||||
<div class="oobe-footer">
|
||||
<div class="btn-group">
|
||||
<div class="md-btn" @click="screen = 'welcome'">{{ getLz("oobe.previous") }}</div>
|
||||
<div class="md-btn" @click="screen = 'visual'">{{ getLz("oobe.next") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </transition> -->
|
||||
|
||||
<!-- Visual -->
|
||||
<!-- <transition name=""> -->
|
||||
<div class="oobe-view" v-if="screen == 'visual'">
|
||||
<div class="oobe-header">
|
||||
{{ getLz("oobe.visual.title") }}
|
||||
</div>
|
||||
<div class="oobe-body visual">
|
||||
<b-row>
|
||||
<b-col>
|
||||
<div class="card bg-dark text-white stylePicker" @click="$root.cfg.visual.directives.windowLayout = 'twopanel'" :class="{'style-active': ($root.cfg.visual.directives.windowLayout == 'twopanel')}">
|
||||
<div class="card-body">
|
||||
<img class="visualPreview" src="./assets/oobe/mojave.png" alt="TEMP">
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
Mojave
|
||||
</div>
|
||||
</div>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<div class="card bg-dark text-white stylePicker" @click="$root.cfg.visual.directives.windowLayout = 'default'" :class="{'style-active': ($root.cfg.visual.directives.windowLayout == 'default')}">
|
||||
<div class="card-body">
|
||||
<img class="visualPreview" src="./assets/oobe/maverick.png" alt="TEMP">
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
Maverick
|
||||
</div>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<div class="blurb">{{getLz("oobe.visual.layout.text")}}</div>
|
||||
</div>
|
||||
<div class="oobe-footer">
|
||||
<div class="btn-group">
|
||||
<div class="md-btn" @click="screen = 'general'">{{ getLz("oobe.previous") }}</div>
|
||||
<div class="md-btn" @click="screen = 'audio'">{{ getLz("oobe.next") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </transition> -->
|
||||
|
||||
<!-- Audio -->
|
||||
<!-- <transition name=""> -->
|
||||
<div class="oobe-view" v-if="screen == 'audio'">
|
||||
<div class="oobe-header">
|
||||
{{ getLz("oobe.audio.title") }}
|
||||
</div>
|
||||
<div class="oobe-body">
|
||||
<div class="blurb">{{ getLz("oobe.audio.text") }}</div>
|
||||
<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>
|
||||
<small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.ciderPPE.description')}}</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<input type="checkbox" v-model="$root.cfg.audio.maikiwiAudio.ciderPPE"
|
||||
switch/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oobe-footer">
|
||||
<div class="btn-group">
|
||||
<div class="md-btn" @click="screen = 'visual'">{{ getLz("oobe.previous") }}</div>
|
||||
<div class="md-btn" @click="signIn()">{{ getLz("oobe.next") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </transition> -->
|
||||
<div class="oobe-view" v-if="screen == 'signin'">
|
||||
<div class="oobe-header">
|
||||
Sign in with Apple Music
|
||||
</div>
|
||||
<div class="oobe-body">
|
||||
<div class="blurb"></div>
|
||||
</div>
|
||||
<div class="oobe-footer">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="oobe-titlebar">
|
||||
<div class="button-group" v-if="$root.platform !== 'darwin'">
|
||||
<button class="min" @click="$root.ipcRenderer.send('minimize')"></button>
|
||||
<button class="close" @click="$root.ipcRenderer.send('close')"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
Vue.component('cider-oobe', {
|
||||
template: '#cider-oobe',
|
||||
data: function () {
|
||||
return {
|
||||
screen: "before_we_start"
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
signIn() {
|
||||
if (localStorage.getItem("music.ampwebplay.media-user-token")) {
|
||||
localStorage.setItem("seenOOBE", 1)
|
||||
window.location.reload()
|
||||
}
|
||||
this.screen = "signin"
|
||||
capiInit()
|
||||
},
|
||||
getLz() {
|
||||
return this.$root.getLz.apply(this.$root, arguments);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -539,7 +539,7 @@
|
|||
icon: "./assets/feather/plus-circle.svg",
|
||||
hidden: false,
|
||||
action: () => {
|
||||
app.followArtistById(artistId, true)
|
||||
app.setArtistFavorite(artistId, true)
|
||||
}
|
||||
},
|
||||
"unfollow": {
|
||||
|
@ -547,7 +547,7 @@
|
|||
icon: "./assets/feather/x-circle.svg",
|
||||
hidden: true,
|
||||
action: () => {
|
||||
app.followArtistById(artistId, false)
|
||||
app.setArtistFavorite(artistId, false)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
fetch("https://api.github.com/search/repositories?q=topic:cidermusicplugin fork:true", requestOptions)
|
||||
fetch("https://api.github.com/search/repositories?q=topic:cidermusicplugin fork:true&per_page=100", requestOptions)
|
||||
.then(response => response.text())
|
||||
.then(result => {
|
||||
self.repos = JSON.parse(result).items
|
||||
|
@ -185,4 +185,4 @@
|
|||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
<transition name="wpfade">
|
||||
<div class="podcasts-details" v-if="selected.id != -1">
|
||||
<div class="podcasts-details-header">
|
||||
<button class="close-btn" @click="selected.id = -1" :aria-label="app.getLz('action.close')"></button>
|
||||
<button class="close-btn" @click="selected.id = -1" :aria-label="$root.getLz('action.close')"></button>
|
||||
</div>
|
||||
<div class="podcast-artwork">
|
||||
<mediaitem-artwork shadow="large" :url="selected.attributes.artwork.url" size="300"></mediaitem-artwork>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<h4>{{ loaded.attributes.uniqueSongCount }} {{$root.getLz('term.uniqueSongs')}}</h4>
|
||||
</div>
|
||||
<div class="col-auto replay-playlist-container">
|
||||
<mediaitem-square kind="card" :force-video="true" :item="loaded.playlist"></mediaitem-square>
|
||||
<mediaitem-square kind="card" :no-scale="true" :force-video="true" :item="loaded.playlist"></mediaitem-square>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Top Artists-->
|
||||
|
|
|
@ -1,82 +1,105 @@
|
|||
<script type="text/x-template" id="cider-search">
|
||||
<div class="content-inner search-page">
|
||||
<div class="btn-group searchToggle">
|
||||
<button
|
||||
@click="searchType = 'catalog'"
|
||||
class="md-btn md-btn-small" :class="{'md-btn-primary': searchType == 'catalog'}">{{ $root.getLz("term.appleMusic") }}</button>
|
||||
<button
|
||||
@click="searchType = 'library';"
|
||||
class="md-btn md-btn-small" :class="{'md-btn-primary': searchType == 'library'}">{{ $root.getLz("term.library") }}</button>
|
||||
</div>
|
||||
<div v-if="search != null && search != [] && search.term != ''">
|
||||
<h3>{{app.getLz('term.topResult')}}</h3>
|
||||
<mediaitem-scroller-horizontal
|
||||
:items="search.results[search.results.meta.results.order[0]]['data']"></mediaitem-scroller-horizontal>
|
||||
<div class="row">
|
||||
<div v-else style="text-align: center">
|
||||
<h3>{{app.getLz('error.noResults')}}</h3>
|
||||
<p>{{app.getLz('error.noResults.description')}}</p>
|
||||
</div>
|
||||
<div class="col" v-if="search.results.song">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{app.getLz('term.songs')}}</h3>
|
||||
<template v-if="searchType == 'catalog'">
|
||||
<h3>{{app.getLz('term.topResult')}}</h3>
|
||||
<mediaitem-scroller-horizontal
|
||||
:items="search.results[search.results.meta.results.order[0]]['data']"></mediaitem-scroller-horizontal>
|
||||
<div class="row">
|
||||
<div v-else style="text-align: center">
|
||||
<h3>{{app.getLz('error.noResults')}}</h3>
|
||||
<p>{{app.getLz('error.noResults.description')}}</p>
|
||||
</div>
|
||||
<div class="col" v-if="search.results.song">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{app.getLz('term.songs')}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center"
|
||||
@click="app.showSearchView(app.search.term, 'song', app.friendlyTypes('song'))"
|
||||
v-if="search.results.song.data.length >= 12">
|
||||
<button class="cd-btn-seeall">{{app.getLz('term.seeAll')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto flex-center"
|
||||
@click="app.showSearchView(app.search.term, 'song', app.friendlyTypes('song'))"
|
||||
v-if="search.results.song.data.length >= 12">
|
||||
<button class="cd-btn-seeall">{{app.getLz('term.seeAll')}}</button>
|
||||
<div class="mediaitem-list-item__grid">
|
||||
<listitem-horizontal :items="search.results.song.data.limit(12)">
|
||||
</listitem-horizontal>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mediaitem-list-item__grid">
|
||||
<listitem-horizontal :items="search.results.song.data.limit(12)">
|
||||
</listitem-horizontal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-if="search.results['meta'] != null">
|
||||
<template
|
||||
v-for="section in search.results.meta.results.order" v-if="section != 'song' && section != 'top'">
|
||||
<template v-if="search.results['meta'] != null">
|
||||
<template
|
||||
v-for="section in search.results.meta.results.order" v-if="section != 'song' && section != 'top'">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ app.friendlyTypes(section) }}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="search.results[section].data.length >= 10">
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showSearchView(app.search.term, section, app.friendlyTypes(section))">{{app.getLz('term.seeAll')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="!app.friendlyTypes(section).includes('Video')">
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="search.results[section].data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-else>
|
||||
<mediaitem-scroller-horizontal-mvview
|
||||
:items="search.results[section].data.limit(10)"></mediaitem-scroller-horizontal-mvview>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="search.resultsSocial.playlist">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ app.friendlyTypes(section) }}</h3>
|
||||
<h3>{{app.getLz('term.sharedPlaylists')}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="search.results[section].data.length >= 10">
|
||||
<div class="col-auto flex-center" v-if="search.resultsSocial.playlist.data.length >= 10">
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showSearchView(app.search.term, section, app.friendlyTypes(section))">{{app.getLz('term.seeAll')}}
|
||||
@click="app.showCollection(search.resultsSocial.playlist, 'Shared Playlists', 'default')">{{app.getLz('term.seeAll')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="!app.friendlyTypes(section).includes('Video')">
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="search.results[section].data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-else>
|
||||
<mediaitem-scroller-horizontal-mvview
|
||||
:items="search.results[section].data.limit(10)"></mediaitem-scroller-horizontal-mvview>
|
||||
</template>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="search.resultsSocial.playlist.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-if="search.resultsSocial.profile">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{app.getLz('term.people')}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="search.resultsSocial.profile.data.length >= 10">
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showCollection(search.resultsSocial.profile, 'People', 'default')">{{app.getLz('term.seeAll')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="search.resultsSocial.profile.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="search.resultsSocial.playlist">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{app.getLz('term.sharedPlaylists')}}</h3>
|
||||
<template v-else>
|
||||
<h1>{{ $root.getLz("term.library") }}</h1>
|
||||
<div v-for="(section, key) in $root.search.resultsLibrary">
|
||||
<h3>{{app.friendlyTypes(key)}}</h3>
|
||||
<div class="mediaitem-list-item__grid" v-if="key.includes('songs')">
|
||||
<listitem-horizontal :items="section.data"></listitem-horizontal>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="search.resultsSocial.playlist.data.length >= 10">
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showCollection(search.resultsSocial.playlist, 'Shared Playlists', 'default')">{{app.getLz('term.seeAll')}}
|
||||
</button>
|
||||
<div class="well" v-else>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="section.data"></mediaitem-scroller-horizontal-large>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="search.resultsSocial.playlist.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-if="search.resultsSocial.profile">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{app.getLz('term.people')}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="search.resultsSocial.profile.data.length >= 10">
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showCollection(search.resultsSocial.profile, 'People', 'default')">{{app.getLz('term.seeAll')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="search.resultsSocial.profile.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else>
|
||||
|
@ -111,6 +134,7 @@
|
|||
recentlyPlayed: [],
|
||||
categoriesView: [],
|
||||
categoriesReady: false,
|
||||
searchType: "catalog",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -96,7 +96,8 @@
|
|||
<option value="listen_now">{{$root.getLz('term.listenNow')}}</option>
|
||||
<option value="browse">{{$root.getLz('term.browse')}}</option>
|
||||
<option value="radio">{{$root.getLz('term.radio')}}</option>
|
||||
<option value="library-recentlyadded">{{$root.getLz('term.recentlyAdded')}}</option>
|
||||
<option value="library-recentlyadded">{{$root.getLz('term.recentlyAdded')}}
|
||||
</option>
|
||||
<option value="library-songs">{{$root.getLz('term.songs')}}</option>
|
||||
<option value="library-albums">{{$root.getLz('term.albums')}}</option>
|
||||
<option value="library-artists">{{$root.getLz('term.artists')}}</option>
|
||||
|
@ -124,7 +125,8 @@
|
|||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.general.sidebarItems.recentlyAdded"
|
||||
<input type="checkbox"
|
||||
v-model="app.cfg.general.sidebarItems.recentlyAdded"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -135,7 +137,8 @@
|
|||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.general.sidebarItems.songs" switch/>
|
||||
<input type="checkbox" v-model="app.cfg.general.sidebarItems.songs"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -185,17 +188,17 @@
|
|||
</div>
|
||||
</div>
|
||||
</b-modal>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.general.keybindings')}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<button class="md-btn" @click="app.appRoute('keybinds-settings')" >
|
||||
<button class="md-btn" @click="app.appRoute('keybinds-settings')">
|
||||
{{$root.getLz('settings.option.general.keybindings.open')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.general.themeUpdateNotification')}}
|
||||
|
@ -206,7 +209,7 @@
|
|||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.general.showLovedTracksInline')}}
|
||||
|
@ -217,7 +220,7 @@
|
|||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</b-tab>
|
||||
|
@ -241,7 +244,8 @@
|
|||
<option value="HIGH">{{$root.getLz('settings.header.audio.quality.high')}}
|
||||
({{$root.getLz('settings.header.audio.quality.high.description')}})
|
||||
</option>
|
||||
<option value="STANDARD">{{$root.getLz('settings.header.audio.quality.standard')}}
|
||||
<option value="STANDARD">
|
||||
{{$root.getLz('settings.header.audio.quality.standard')}}
|
||||
({{$root.getLz('settings.header.audio.quality.standard.description')}})
|
||||
</option>
|
||||
</select>
|
||||
|
@ -329,12 +333,13 @@
|
|||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.audio.normalization"
|
||||
v-on:change="toggleNormalization"
|
||||
:disabled="app.cfg.audio.spatial === true || app.cfg.audio.maikiwiAudio.spatial === true || app.cfg.audio.maikiwiAudio.ciderPPE === true || app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true || app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true"
|
||||
:disabled="app.cfg.audio.maikiwiAudio.spatial === true || app.cfg.audio.maikiwiAudio.ciderPPE === true || app.cfg.audio.maikiwiAudio.atmosphereRealizer1 === true || app.cfg.audio.maikiwiAudio.atmosphereRealizer2 === true"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext && app.cfg.audio.normalization">
|
||||
<div class="md-option-line"
|
||||
v-show="app.cfg.advanced.AudioContext && app.cfg.audio.normalization">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.audio.dbspl.display')}}
|
||||
<br>
|
||||
|
@ -408,13 +413,131 @@
|
|||
<option value="image">
|
||||
{{$root.getLz('settings.header.visual.windowBackgroundStyle.image')}}
|
||||
</option>
|
||||
<option value="mica">
|
||||
<option value="color">
|
||||
{{$root.getLz('settings.header.visual.windowBackgroundStyle.color')}}
|
||||
</option>
|
||||
<option v-if="$root.platform == 'win32'" value="mica">
|
||||
Mica (Beta)
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line child" v-if="app.cfg.visual.window_background_style == 'color'">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.visual.windowColor')}}
|
||||
</div>
|
||||
<div class="md-option-segment_auto">
|
||||
<input type="color" v-model="app.cfg.visual.windowColor"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.visual.customAccentColor')}}
|
||||
</div>
|
||||
<div class="md-option-segment_auto">
|
||||
<input type="checkbox" v-model="app.cfg.visual.customAccentColor" :disabled="app.cfg.visual.purplePodcastPlaybackBar" switch/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line child" v-if="app.cfg.visual.customAccentColor">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.visual.accentColor')}}
|
||||
</div>
|
||||
<div class="md-option-segment_auto">
|
||||
<input type="color" v-model="app.cfg.visual.accentColor"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.visual.purplePodcastPlaybackBar')}}
|
||||
</div>
|
||||
<div class="md-option-segment_auto">
|
||||
<input type="checkbox" v-model="app.cfg.visual.purplePodcastPlaybackBar" :disabled="app.cfg.visual.customAccentColor" switch/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.visual.hardwareAcceleration')}}<br>
|
||||
<small>({{$root.getLz('settings.option.visual.hardwareAcceleration.description')}})</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<select class="md-select" style="width:180px;"
|
||||
v-model="app.cfg.visual.hw_acceleration" @change="promptForRelaunch()">
|
||||
<option value="default">
|
||||
{{$root.getLz('settings.header.visual.hardwareAcceleration.default')}}
|
||||
</option>
|
||||
<option value="webgpu">
|
||||
{{$root.getLz('settings.header.visual.hardwareAcceleration.webGPU')}}
|
||||
</option>
|
||||
<option value="disabled">{{$root.getLz('term.disabled')}}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.visual.showPersonalInfo')}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.visual.showuserinfo"
|
||||
v-on:change="toggleUserInfo"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Window Settings -->
|
||||
<div class="md-option-header">
|
||||
<span>{{$root.getLz('settings.header.window')}}</span>
|
||||
</div>
|
||||
<div class="settings-option-body">
|
||||
<div class="md-option-line" v-show="app.platform !== 'darwin'">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz("settings.option.window.close_button_hide")}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.general.close_button_hide" switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.platform !== 'darwin'">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz("settings.option.window.useNativeTitleBar")}}<br>
|
||||
<small>({{$root.getLz("settings.option.visual.hardwareAcceleration.description")}})</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.visual.nativeTitleBar" switch
|
||||
@change="promptForRelaunch()"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.platform !== 'darwin'">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz("settings.option.window.windowControlStyle")}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<select class="md-select" v-model="app.cfg.visual.windowControlPosition">
|
||||
<option value="0">
|
||||
{{$root.getLz("settings.option.window.windowControlStyle.right")}}
|
||||
</option>
|
||||
<option value="1">
|
||||
{{$root.getLz("settings.option.window.windowControlStyle.left")}}
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Advanced Visual -->
|
||||
<div class="md-option-header">
|
||||
<span>{{$root.getLz('settings.header.advanced')}}</span>
|
||||
</div>
|
||||
<div class="settings-option-body">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.visual.animatedArtwork')}}
|
||||
|
@ -483,83 +606,8 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.visual.hardwareAcceleration')}}<br>
|
||||
<small>({{$root.getLz('settings.option.visual.hardwareAcceleration.description')}})</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<select class="md-select" style="width:180px;" v-model="app.cfg.visual.hw_acceleration" @change="promptForRelaunch()">
|
||||
<option value="default">
|
||||
{{$root.getLz('settings.header.visual.hardwareAcceleration.default')}}
|
||||
</option>
|
||||
<option value="webgpu">
|
||||
{{$root.getLz('settings.header.visual.hardwareAcceleration.webGPU')}}
|
||||
</option>
|
||||
<option value="disabled">{{$root.getLz('term.disabled')}}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.visual.showPersonalInfo')}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.visual.showuserinfo"
|
||||
v-on:change="toggleUserInfo"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Window Settings -->
|
||||
<div class="md-option-header">
|
||||
<span>{{$root.getLz('settings.header.window')}}</span>
|
||||
</div>
|
||||
<div class="settings-option-body">
|
||||
<div class="md-option-line" v-show="app.platform !== 'darwin'">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz("settings.option.window.close_button_hide")}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.general.close_button_hide" switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.platform !== 'darwin'">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz("settings.option.window.useNativeTitleBar")}}<br>
|
||||
<small>({{$root.getLz("settings.option.visual.hardwareAcceleration.description")}})</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.visual.nativeTitleBar" switch
|
||||
@change="promptForRelaunch()"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line" v-show="app.platform !== 'darwin'">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz("settings.option.window.windowControlStyle")}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<select class="md-select" v-model="app.cfg.visual.windowControlPosition">
|
||||
<option value="0">
|
||||
{{$root.getLz("settings.option.window.windowControlStyle.right")}}
|
||||
</option>
|
||||
<option value="1">
|
||||
{{$root.getLz("settings.option.window.windowControlStyle.left")}}
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</b-tab>
|
||||
<b-tab :title="$root.getLz('settings.header.lyrics')">
|
||||
|
@ -998,6 +1046,17 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md-option-line" v-show="app.cfg.general.discordrpc.enabled != false">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.connectivity.discordRPC.reload')}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<button class="md-btn" @click="reloadDiscordRPC()">
|
||||
{{$root.getLz('menubar.options.reload')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LastFM -->
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
|
@ -1005,7 +1064,7 @@
|
|||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<button class="md-btn" id="lfmConnect" ref="lfmConnect"
|
||||
onclick="app.LastFMAuthenticate()">
|
||||
@click="app.LastFMAuthenticate()">
|
||||
{{$root.getLz('term.connect')}}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1036,7 +1095,8 @@
|
|||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.lastfm.enabledRemoveFeaturingArtists" switch/>
|
||||
<input type="checkbox" v-model="app.cfg.lastfm.enabledRemoveFeaturingArtists"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1125,6 +1185,20 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
Use MusicKit V3
|
||||
<small>Requires relaunch</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.advanced.experiments.includes('ampv3')"
|
||||
@click="app.cfg.advanced.experiments.includes('ampv3') ? removeExperiment('ampv3') : addExperiment('ampv3')"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.advanced.playlistTrackMapping')}}
|
||||
|
@ -1138,28 +1212,16 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
Collapsable Sidebar
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.advanced.experiments.includes('collapseSidebar')"
|
||||
@click="app.cfg.advanced.experiments.includes('collapseSidebar') ? removeExperiment('collapseSidebar') : addExperiment('collapseSidebar')"
|
||||
switch/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.experimental.compactUI')}}
|
||||
<small v-if="!!app.getThemeDirective('forceUI')">{{$root.getLz('term.themeManaged')}}</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<label>
|
||||
<input type="checkbox" v-model="app.cfg.advanced.experiments.includes('compactui')"
|
||||
@click="app.cfg.advanced.experiments.includes('compactui') ? removeExperiment('compactui') : addExperiment('compactui')"
|
||||
switch/>
|
||||
switch :disabled="!!app.getThemeDirective('forceUI')"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1187,7 +1249,8 @@
|
|||
<select class="md-select" @change="$root.setLz('');$root.setLzManual()"
|
||||
v-model="app.cfg.general.language">
|
||||
<optgroup :label="index" v-for="(categories, index) in getLanguages()">
|
||||
<option v-for="lang in categories" :value="lang.code">{{lang.nameNative}} ({{
|
||||
<option v-for="lang in categories" :value="lang.code">{{lang.nameNative}}
|
||||
({{
|
||||
lang.nameEnglish }})
|
||||
</option>
|
||||
</optgroup>
|
||||
|
@ -1211,9 +1274,10 @@
|
|||
</div>
|
||||
</b-tab>
|
||||
<!-- Connect Settings -->
|
||||
<!-- Not Prod Ready
|
||||
<b-tab :title="$root.getLz('settings.header.connect')">
|
||||
<div class="md-option-container">
|
||||
<!-- Cider Connect / Linking Settings -->
|
||||
<!!!!!-- Cider Connect / Linking Settings -!->
|
||||
<div class="md-option-header">
|
||||
<span>{{$root.getLz('settings.header.connect')}}</span>
|
||||
</div>
|
||||
|
@ -1295,6 +1359,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</b-tab>
|
||||
-->
|
||||
</b-tabs>
|
||||
</div>
|
||||
</script>
|
||||
|
@ -1393,8 +1458,7 @@
|
|||
if (app.cfg.audio.normalization === true) {
|
||||
CiderAudio.normalizerOn()
|
||||
}
|
||||
if (app.cfg.audio.spatial === true) {
|
||||
CiderAudio.spatialOn()
|
||||
if (app.cfg.audio.maikiwiAudio.spatial === true) {
|
||||
CiderAudio.hierarchical_loading();
|
||||
}
|
||||
}
|
||||
|
@ -1404,8 +1468,7 @@
|
|||
if (app.cfg.audio.normalization === true) {
|
||||
CiderAudio.normalizerOn()
|
||||
}
|
||||
if (app.cfg.audio.spatial === true) {
|
||||
CiderAudio.spatialOn()
|
||||
if (app.cfg.audio.maikiwiAudio.spatial === true) {
|
||||
CiderAudio.hierarchical_loading();
|
||||
}
|
||||
}
|
||||
|
@ -1421,7 +1484,6 @@
|
|||
}
|
||||
},
|
||||
changeAudioQuality: function () {
|
||||
1
|
||||
app.mk.bitrate = MusicKit.PlaybackBitrate[app.cfg.audio.quality];
|
||||
},
|
||||
toggleUserInfo: function () {
|
||||
|
@ -1455,6 +1517,9 @@
|
|||
logoutCC() {
|
||||
ipcRenderer.send('cc-logout')
|
||||
},
|
||||
reloadDiscordRPC() {
|
||||
ipcRenderer.send('reloadRPC')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -184,7 +184,7 @@
|
|||
redirect: 'follow'
|
||||
};
|
||||
|
||||
fetch("https://api.github.com/search/repositories?q=topic:cidermusictheme fork:true", requestOptions)
|
||||
fetch("https://api.github.com/search/repositories?q=topic:cidermusictheme fork:true&per_page=100", requestOptions)
|
||||
.then(response => response.text())
|
||||
.then(result => {
|
||||
let items = JSON.parse(result).items
|
||||
|
@ -194,4 +194,4 @@
|
|||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -9,6 +9,20 @@
|
|||
v-if="artistLoaded"
|
||||
:item="artist"
|
||||
></artist-chip>
|
||||
|
||||
<amp-chrome-player/>
|
||||
<!-- <amp-footer-player/> -->
|
||||
<hr>
|
||||
<amp-lcd-progress/>
|
||||
<hr>
|
||||
<amp-playback-controls-shuffle/>
|
||||
<apple-music-playback-controls theme="dark" />
|
||||
<apple-music-progress theme="dark"></apple-music-progress>
|
||||
<apple-music-volume theme="dark"></apple-music-volume>
|
||||
<amp-user-menu/>
|
||||
<amp-tv-overlay/>
|
||||
<amp-podcast-playback-controls/>
|
||||
<amp-lcd/>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
|
|
1
src/renderer/views/svg/external-link.svg
Normal file
1
src/renderer/views/svg/external-link.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>
|
After Width: | Height: | Size: 388 B |
Loading…
Add table
Add a link
Reference in a new issue