Revert "Develop > main"

This commit is contained in:
Core 2022-02-05 09:34:33 +00:00 committed by GitHub
parent d7d90fbc36
commit f843fe0ba7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
86 changed files with 6687 additions and 25151 deletions

View file

@ -1,163 +0,0 @@
<div id="app-content" :style="{'overflow': (chrome.contentAreaScrolling ? '' : 'hidden')}">
<div id="navigation-bar">
<button class="nav-item" @click="navigateBack()">
<%- include('../svg/chevron-left.svg') %>
</button>
<button class="nav-item" @click="navigateForward()">
<%- include('../svg/chevron-right.svg') %>
</button>
</div>
<!-- Podcasts -->
<transition name="wpfade">
<template v-if="page == 'podcasts'">
<apple-podcasts></apple-podcasts>
</template>
</transition>
<!-- Library - Library Videos -->
<transition name="wpfade">
<template v-if="page == 'library-videos'">
<cider-library-videos></cider-library-videos>
</template>
</transition>
<!-- Apple Setings Page -->
<transition name="wpfade">
<template v-if="page == 'apple-account-settings'">
<apple-account-settings></apple-account-settings>
</template>
</transition>
<!-- About -->
<transition name="wpfade">
<template v-if="page == 'about'">
<about-page></about-page>
</template>
</transition>
<!-- Artist Page -->
<transition name="wpfade">
<template v-if="page == 'artist-page' && artistPage.data.attributes">
<cider-artist :data="artistPage.data"></cider-artist>
</template>
</transition>
<transition name="wpfade">
<%- include('../pages/zoo') %>
</transition>
<transition name="wpfade">
<%- include('../pages/webview') %>
</transition>
<!-- Collection List -->
<transition name="wpfade">
<template v-if="page == 'collection-list'">
<cider-collection-list :data="collectionList.response" :type="collectionList.type"
:title="collectionList.title"></cider-collection-list>
</template>
</transition>
<!-- Home -->
<transition name="wpfade">
<template v-if="page == 'home'">
<cider-home></cider-home>
</template>
</transition>
<!-- Home -->
<transition name="wpfade">
<template v-if="page == 'artist-feed'">
<cider-artist-feed></cider-artist-feed>
</template>
</transition>
<!-- Playlist / Album page-->
<transition name="wpfade">
<template v-if="modals.showPlaylist">
<playlist-inline :data="showingPlaylist"></playlist-inline>
</template>
</transition>
<transition name="wpfade">
<template v-if="page.includes('playlist_')">
<cider-playlist :data="showingPlaylist"></cider-playlist>
</template>
</transition>
<transition name="wpfade">
<template v-if="page.includes('album_')">
<cider-playlist :data="showingPlaylist"></cider-playlist>
</template>
</transition>
<transition name="wpfade">
<template v-if="page.includes('recordLabel_')">
<cider-recordlabel :data="showingPlaylist"></cider-recordlabel>
</template>
</transition>
<transition name="wpfade">
<template v-if="page.includes('curator_')">
<cider-recordlabel :data="showingPlaylist"></cider-recordlabel>
</template>
</transition>
<!-- Browse -->
<transition v-on:enter="getBrowsePage(); console.log('browse')" name="wpfade">
<template v-if="page == 'browse'">
<cider-browse :data="browsepage"></cider-browse>
</template>
</transition>
<!-- Listen Now -->
<transition v-on:enter="getListenNow()" name="wpfade">
<template v-if="page == 'listen_now'" @created="console.log('listennow')">
<cider-listen-now :data="listennow"></cider-listen-now>
</template>
</transition>
<!-- Radio -->
<transition v-on:enter="getRadioStations()" name="wpfade">
<template v-if="page == 'radio'" @created="console.log('radio')">
<div class="content-inner">
<h1 class="header-text">{{$root.getLz('term.radio')}}</h1>
<h3>{{$root.getLz('term.recentStations')}}</h3>
<mediaitem-square :item="item" v-for="item in radio.personal"></mediaitem-square>
</div>
</template>
</transition>
<!-- Settings -->
<transition name="wpfade">
<template v-if="page == 'settings'">
<cider-settings></cider-settings>
</template>
</transition>
<!-- Search -->
<transition name="wpfade">
<template v-if="page == 'search'">
<cider-search :search="search"></cider-search>
</template>
</transition>
<!-- Library - Recently Added -->
<transition name="wpfade" v-on:enter="getLibraryAlbumsFull(null, 0); searchLibraryAlbums(0);">
<%- include('../pages/library-recentlyadded') %>');
</transition>
<!-- Library - Songs -->
<transition name="wpfade" v-on:enter="getLibrarySongsFull()">
<template v-if="page == 'library-songs'">
<cider-library-songs :data="library.songs"></cider-library-songs>
</template>
</transition>
<!-- Library - Albums -->
<transition name="wpfade" v-on:enter="getLibraryAlbumsFull(null, 1); searchLibraryAlbums(1);">
<%- include('../pages/library-albums') %>');
%>
</transition>
<!-- Library - Made For You -->
<transition name="wpfade" v-on:enter="getMadeForYou()">
<template v-if="page == 'library-madeforyou'">
<%- include('../pages/madeforyou') %>');
%>
</template>
</transition>
<!-- Library - Artists-->
<transition name="wpfade" v-on:enter="getLibraryArtistsFull(null, 0);">
<template v-if="page == 'library-artists'">
<%- include('../pages/library-artists') %>');
%>
</template>
</transition>
<transition name="wpfade">
<template v-if="page.includes('appleCurator')">
<cider-applecurator :data="appleCurator"></cider-applecurator>
</template>
</transition>
</div>

View file

@ -1,27 +0,0 @@
<div class="app-navigation" v-cloak>
<%- include("sidebar") %>
<%- include("app-content") %>
<transition name="drawertransition">
<div class="app-drawer"
v-if="drawer.open && drawer.panel == 'lyrics' && lyrics && lyrics != [] && lyrics.length > 0">
<div class="bgArtworkMaterial">
<div class="bg-artwork-container">
<img class="bg-artwork a" :src="$store.state.artwork.playerLCD">
<img class="bg-artwork b" :src="$store.state.artwork.playerLCD">
</div>
</div>
<lyrics-view v-if="drawer.panel == 'lyrics'" :time="lyriccurrenttime" :lyrics="lyrics"
:richlyrics="richlyrics"></lyrics-view>
<div v-if="drawer.panel == 'lyrics'" class="lyric-footer">
<button class="md-btn" @click="modularUITest(!fullscreenLyrics)">{{fullscreenLyrics ?
$root.getLz('term.defaultView'): $root.getLz('term.fullscreenView')}}
</button>
</div>
</div>
</transition>
<transition name="drawertransition">
<div class="app-drawer" v-if="drawer.open && drawer.panel == 'queue'">
<cider-queue ref="queue" v-if="drawer.panel == 'queue'"></cider-queue>
</div>
</transition>
</div>

View file

@ -1,144 +0,0 @@
<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'">
<div class="window-controls">
<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" 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}"></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0"
@click="mk.shuffleMode = 1"></button>
<button class="playback-button--small shuffle active" v-else
@click="mk.shuffleMode = 0"></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button previous" @click="prevButton()"></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button pause" @click="mk.pause()" v-if="mk.isPlaying"></button>
<button class="playback-button play" @click="mk.play()" v-else></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button next" @click="mk.skipToNextItem()"></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0"
@click="mk.repeatMode = 1"></button>
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
v-else-if="mk.repeatMode == 1"></button>
<button class="playback-button--small repeat active" @click="mk.repeatMode = 0"
v-else-if="mk.repeatMode == 2"></button>
</div>
</div>
<div class="app-chrome--center">
<div class="app-chrome-item playback-controls">
<template v-if="mkReady()">
<div class="app-playback-controls" @mouseover="chrome.progresshover = true"
@mouseleave="chrome.progresshover = false" @contextmenu="nowPlayingContextMenu">
<div class="artwork" @click="drawer.open = false; fullscreen(true)">
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
</div>
<div class="playback-info">
<div class="song-name" style="-webkit-box-orient: horizontal;"
:class="[isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') ? 'marquee' : '']"
:style="[mk.nowPlayingItem['attributes']['contentRating'] == 'explicit' || mk.nowPlayingItem['attributes']['lossless'] == true ? {'margin-left' : '23px'} : {'margin-left' : '0px'} ]">
{{ mk.nowPlayingItem["attributes"]["name"] }}
<div class="explicit-icon"
v-if="mk.nowPlayingItem['attributes']['contentRating'] == 'explicit'"
style="display: inline-block"></div>
<div class="lossless-icon"
v-if="mk.nowPlayingItem['attributes']['lossless'] == true"
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>
{{(mk.nowPlayingItem["attributes"]["albumName"]) ?
(mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
</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'} ]">
<p style="width: auto">{{ convertToMins(getSongProgress()) }}</p>
<p style="width: auto">{{ convertToMins(mk.currentPlaybackDuration) }}
</p>
</div>
<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);playerLCD.desiredDuration = 0;playerLCD.userInteraction = false"
:max="mk.currentPlaybackDuration" :value="getSongProgress()">
</div>
</div>
<template v-if="mk.nowPlayingItem['attributes']['playParams']">
<div class="actions">
<button class="lcdMenu" @click="nowPlayingContextMenu">
<div class="svg-icon"></div>
</button>
</div>
</template>
</div>
</template>
</div>
</div>
<div class="app-chrome--right">
<div class="app-chrome-item volume display--large">
<button class="volume-button--small volume" @click="muteButtonPressed()"
:class="{'active': this.cfg.audio.volume == 0}"></button>
<input type="range" class="" @wheel="volumeWheel" step="0.01" min="0" :max="cfg.audio.maxVolume"
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()">
</div>
<div class="app-chrome-item generic">
<button class="playback-button--small miniplayer"
@click="drawer.open = false; miniPlayer(true)"></button>
</div>
<div class="app-chrome-item generic">
<button class="playback-button--small queue" :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"
:class="{'active': drawer.panel == 'lyrics'}"
@click="invokeDrawer('lyrics')"></button>
</template>
</div>
<div class="app-chrome-item full-height" id="window-controls-container" v-if="chrome.windowControlPosition == 'right'">
<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" v-else @click="ipcRenderer.send('maximize')"></div>
<div class="close" @click="ipcRenderer.send('close')"></div>
</div>
</div>
</div>
</div>

View file

@ -1,71 +0,0 @@
<cider-menu-panel v-if="menuPanel.visible">
</cider-menu-panel>
<transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'fullscreen'">
<fullscreen-view :image="currentArtUrl.replace('50x50', '600x600')" :time="lyriccurrenttime"
:lyrics="lyrics" :richlyrics="richlyrics"></fullscreen-view>
</div>
</transition>
<transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'mini'">
<mini-view :image="currentArtUrl.replace('50x50', '600x600')" :time="lyriccurrenttime"
:lyrics="lyrics" :richlyrics="richlyrics"></mini-view>
</div>
</transition>
<transition name="wpfade">
<div class="bg-artwork-container" v-if="cfg.visual.window_background_style == 'artwork'"
:class="{noanimation: (!cfg.visual.bg_artwork_rotation || !animateBackground)}">
<img @load="chrome.artworkReady = true" class="bg-artwork a ">
<img class="bg-artwork b">
</div>
</transition>
<transition name="wpfade">
<div class="bg-artwork--placeholder"></div>
</transition>
<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-settings v-if="modals.audioSettings"></audio-settings>
</transition>
<transition name="modal">
<eq-view v-if="modals.equalizer"></eq-view>
</transition>
<transition name="modal">
<qrcode-modal v-if="modals.qrcode" :src="webremoteqr" :url="webremoteurl"></qrcode-modal>
</transition>
<div id="apple-music-video-container">
<div id="apple-music-video-player-controls">
<div id="player-exit" title="Close" @click="exitMV()">
<svg fill="white" xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21"
aria-role="presentation" focusable="false">
<path
d="M10.5 21C4.724 21 0 16.275 0 10.5S4.724 0 10.5 0 21 4.725 21 10.5 16.276 21 10.5 21zm-3.543-5.967a.96.96 0 00.693-.295l2.837-2.842 2.85 2.842c.167.167.41.295.693.295.552 0 1.001-.461 1.001-1.012 0-.281-.115-.512-.295-.704L11.899 10.5l2.85-2.855a.875.875 0 00.295-.68c0-.55-.45-.998-1.001-.998a.871.871 0 00-.668.295l-2.888 2.855-2.862-2.843a.891.891 0 00-.668-.281.99.99 0 00-1.001.986c0 .269.116.512.295.678L9.088 10.5l-2.837 2.843a.926.926 0 00-.295.678c0 .551.45 1.012 1.001 1.012z"
fill-rule="nonzero"/>
</svg>
</div>
<div id="captions">{{((lyricon) ? ((lyrics.length > 0 && lyrics[currentLyricsLine] &&
lyrics[currentLyricsLine].line ) ?
lyrics[currentLyricsLine].line.replace('lrcInstrumental','') : "") : '') + ((lyricon) ?
((lyrics.length
> 0 && lyrics[currentLyricsLine] && lyrics[currentLyricsLine].line ) ?
(lyrics[currentLyricsLine].translation ? ('\n\r' + lyrics[currentLyricsLine].translation) : ""): "")
:
'')}}
</div>
<div id="player-pip"
@click="document.querySelector('video#apple-music-video-player').requestPictureInPicture()"
title="Picture-in-Picture">
<%- include("../svg/pip.svg") %>
</div>
<div id="player-fullscreen"
@click="document.querySelector('video#apple-music-video-player').requestFullscreen()"
title="Fullscreen">
<%- include("../svg/fullscreen.svg") %>
</div>
</div>
<div id="apple-music-video-player"></div>
</div>

View file

@ -1,173 +0,0 @@
<div id="app-sidebar">
<div class="app-sidebar-header">
<div class="search-input-container">
<div class="search-input--icon"></div>
<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">
</div>
</div>
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
<div class="search-hints">
<button class="search-hint" v-for="hint in search.hints"
@click="search.term = hint;search.showHints = false;searchQuery(hint)">
{{ hint }}
</button>
</div>
</div>
<div class="app-sidebar-content">
<div class="app-sidebar-header-text">
{{$root.getLz('app.name')}}
</div>
<sidebar-library-item :name="$root.getLz('home.title')" svg-icon="./assets/feather/home.svg"
page="home">
</sidebar-library-item>
<div class="app-sidebar-header-text">
{{$root.getLz('term.appleMusic')}}
</div>
<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>
<div class="app-sidebar-header-text">
{{$root.getLz('term.library')}}
</div>
<sidebar-library-item :name="$root.getLz('term.recentlyAdded')"
svg-icon="./assets/feather/plus-circle.svg"
page="library-recentlyadded"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.songs')" svg-icon="./assets/feather/music.svg"
page="library-songs"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.albums')" svg-icon="./assets/feather/disc.svg"
page="library-albums"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.artists')" svg-icon="./assets/feather/user.svg"
page="library-artists"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.videos')" svg-icon="./assets/feather/video.svg"
page="library-videos"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.podcasts')" svg-icon="./assets/feather/mic.svg"
page="podcasts">
</sidebar-library-item>
<div class="app-sidebar-header-text" @contextmenu="playlistHeaderContextMenu">
{{ $root.getLz('term.playlists') }}
</div>
<sidebar-playlist v-for="item in getPlaylistFolderChildren('p.playlistsroot')" :item="item">
</sidebar-playlist>
</div>
<transition name="wpfade">
<div class="usermenu-container" v-if="chrome.menuOpened">
<div class="usermenu-body">
<button class="app-sidebar-button" style="width:100%">
<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>
<button class="usermenu-item" @click="appRoute('remote-pair')">
<div class="row nopadding">
<div class="col nopadding">
<span class="usermenu-item-icon"><%- include("../svg/smartphone.svg") %></span>
<span class="usermenu-item-name">{{$root.getLz('action.showWebRemoteQR')}}</span>
</div>
</div>
</button>
<button class="usermenu-item" v-if="cfg.advanced.AudioContext"
@click="modals.audioSettings = true">
<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" @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 display--small">
<div class="app-playback-controls " v-if="mkReady()"
@contextmenu="nowPlayingContextMenu">
<div class="control-buttons">
<div class="app-chrome-item">
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0"
@click="mk.shuffleMode = 1"></button>
<button class="playback-button--small shuffle active" v-else
@click="mk.shuffleMode = 0"></button>
</div>
<div class="app-chrome-item">
<button class="playback-button previous" @click="prevButton()"></button>
</div>
<div class="app-chrome-item">
<button class="playback-button pause" @click="mk.pause()"
v-if="mk.isPlaying"></button>
<button class="playback-button play" @click="mk.play()" v-else></button>
</div>
<div class="app-chrome-item">
<button class="playback-button next" @click="mk.skipToNextItem()"></button>
</div>
<div class="app-chrome-item">
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0"
@click="mk.repeatMode = 1"></button>
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
v-else-if="mk.repeatMode == 1"></button>
<button class="playback-button--small repeat active"
@click="mk.repeatMode = 0" v-else-if="mk.repeatMode == 2"></button>
</div>
</div>
<div class="app-chrome-item volume">
<div class="input-container">
<button class="volume-button--small volume" @click="muteButtonPressed()"
:class="{'active': this.cfg.audio.volume == 0}"></button>
<input type="range" class="" @wheel="volumeWheel" step="0.01" min="0"
:max="cfg.audio.maxVolume"
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'"
@change="checkMuteChange()">
</div>
</div>
</div>
</div>
<div class="app-sidebar-notification backgroundNotification"
v-if="library.backgroundNotification.show">
<div class="message">{{ library.backgroundNotification.message }} ({{
library.backgroundNotification.progress }} / {{ library.backgroundNotification.total }})
</div>
</div>
</div>

View file

@ -258,14 +258,14 @@
items: {
"new": {
"icon": "./assets/feather/plus.svg",
"name": app.getLz('action.newpreset'),
name: "New Preset...",
action: () => {
this.addPreset()
}
},
"delete": {
"icon": "./assets/feather/x-circle.svg",
"name": app.getLz('action.deletepreset'),
name: "Delete Preset",
action: () => {
this.deletePreset()
}
@ -316,13 +316,13 @@
},
deletePreset() {
let presets = this.$root.cfg.audio.equalizer.presets
bootbox.confirm(app.getLz('term.deletepreset.warn'), (result) => {
bootbox.confirm("Are you sure you want to delete this preset?", (result) => {
if (result) {
this.changePreset("default")
// find the preset by id (preset) and remove it
let index = presets.findIndex(p => p.preset == this.preset)
presets.splice(index, 1)
notyf.success(app.getLz('term.deletedpreset'))
notyf.success("Removed preset")
}
})
},
@ -367,7 +367,7 @@
},
addPreset() {
let self = this
bootbox.prompt(app.getLz('term.newpreset.name'), (res) => {
bootbox.prompt("New EQ Preset Name", (res) => {
if (res) {
let eqSettings = Clone(app.cfg.audio.equalizer)
let newPreset = new self.eqPreset()
@ -379,7 +379,7 @@
newPreset.mix = eqSettings.mix
newPreset.vibrantBass = eqSettings.vibrantBass
app.cfg.audio.equalizer.presets.push(newPreset)
notyf.success(app.getLz('term.addedpreset'))
notyf.success("Added Preset")
self.changePreset(newPreset.preset)
}
})

View file

@ -3,9 +3,9 @@
<div class="background">
<div class="bgArtworkMaterial">
<div class="bg-artwork-container">
<img v-if="(app.cfg.visual.bg_artwork_rotation && app.animateBackground)" class="bg-artwork a" :src="image.replace('600x600','30x30') ?? ''">
<img v-if="(app.cfg.visual.bg_artwork_rotation && app.animateBackground)" class="bg-artwork b" :src="image.replace('600x600','30x30') ?? ''">
<img v-if="!(app.cfg.visual.bg_artwork_rotation && app.animateBackground)" class="bg-artwork no-animation" :src="image.replace('600x600','30x30') ?? ''">
<img v-if="(app.cfg.visual.bg_artwork_rotation || app.animateBackground)" class="bg-artwork a" :src="image.replace('600x600','30x30') ?? ''">
<img v-if="(app.cfg.visual.bg_artwork_rotation || app.animateBackground)" class="bg-artwork b" :src="image.replace('600x600','30x30') ?? ''">
<img v-if="!(app.cfg.visual.bg_artwork_rotation || app.animateBackground)" class="bg-artwork no-animation" :src="image.replace('600x600','30x30') ?? ''">
</div>
</div>
</div>

View file

@ -8,10 +8,7 @@
<button class="autoplay" :style="{'background': app.mk.autoplayEnabled ? 'var(--keyColor)' : ''}" @click="app.mk.autoplayEnabled = !app.mk.autoplayEnabled"> <img class="infinity"></button>
</div>
</div>
<div class="queue-body" v-if="page == 'history'">
<mediaitem-list-item :show-library-status="false" v-for="item in history" :item="item"></mediaitem-list-item>
</div>
<div class="queue-body" v-if="page == 'queue'">
<div class="queue-body">
<draggable v-model="queueItems" @start="drag=true" @end="drag=false;move()">
<template v-for="(queueItem, position) in queueItems">
<div v-if="position <= queuePosition" style="display: none;">{{ position }}</div>
@ -36,11 +33,7 @@
</draggable>
</div>
<div class="queue-footer">
<div class="btn-group" style="width:100%;">
<button class="md-btn md-btn-small" :class="{'md-btn-primary': (page == 'queue')}" @click="page = 'queue'">{{app.getLz('term.queue')}}</button>
<button class="md-btn md-btn-small" :class="{'md-btn-primary': (page == 'history')}" @click="getHistory();page = 'history'">{{app.getLz('term.history')}}</button>
</div>
<button class="md-btn md-btn-small" style="width:100%;margin-top:6px;" v-if="queueItems.length > 1" @click="app.mk.clearQueue();updateQueue()">{{app.getLz('term.clearAll')}}</button>
<button class="md-btn" style="width:100%;" v-if="queueItems.length > 1" @click="app.mk.clearQueue();updateQueue()">{{app.getLz('term.clearAll')}}</button>
</div>
</div>
</script>
@ -56,8 +49,6 @@
queueItems: [],
selected: -1,
selectedItems: [],
history: [],
page: "queue",
app: this.$root
}
},
@ -65,10 +56,6 @@
this.updateQueue()
},
methods: {
async getHistory() {
let history = await app.mk.api.v3.music(`/v1/me/recent/played/tracks`)
this.history = history.data.data
},
select(e, position) {
if(e.ctrlKey || e.shiftKey) {
if(this.selectedItems.indexOf(position) == -1) {

View file

@ -16,7 +16,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>Cider</title>
<link rel="stylesheet/less" type="text/css" href="style.less"/>
<link rel="stylesheet/less" type="text/css" id="userTheme" href="themes/default.less"/>
<script src="./js/less.js"></script>
<script src="<%- (env.dev ? "./js/vue.js" : "./js/vue.dev.js") %>"></script>
<script src="./js/vuex.min.js"></script>
@ -37,16 +36,667 @@
<div id="app" :class="getAppClasses()">
<transition name="fsModeSwitch">
<div id="app-main" v-show="appMode == 'player'">
<%- include('app/chrome-top'); %>
<%- include('app/app-navigation'); %>
<div class="mv-chrome" v-if="chrome.topChromeVisible == false"></div>
<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'">
<div class="window-controls">
<div class="close" @click="closeWindow()"></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" v-else @click="ipcRenderer.send('maximize')"></div>
</div>
</div>
<div class="app-chrome-item full-height" v-else>
<div class="app-title"></div>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0"
@click="mk.shuffleMode = 1"></button>
<button class="playback-button--small shuffle active" v-else
@click="mk.shuffleMode = 0"></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button previous" @click="prevButton()"></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button pause" @click="mk.pause()" v-if="mk.isPlaying"></button>
<button class="playback-button play" @click="mk.play()" v-else></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button next" @click="mk.skipToNextItem()"></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0"
@click="mk.repeatMode = 1"></button>
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
v-else-if="mk.repeatMode == 1"></button>
<button class="playback-button--small repeat active" @click="mk.repeatMode = 0"
v-else-if="mk.repeatMode == 2"></button>
</div>
</div>
<div class="app-chrome--center">
<div class="app-chrome-item playback-controls">
<template v-if="mkReady()">
<div class="app-playback-controls" @mouseover="chrome.progresshover = true"
@mouseleave="chrome.progresshover = false" @contextmenu="nowPlayingContextMenu">
<div class="artwork" @click="drawer.open = false; fullscreen(true)">
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
</div>
<div class="playback-info">
<div class="song-name" style="-webkit-box-orient: horizontal;"
:class="[isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') ? 'marquee' : '']"
:style="[mk.nowPlayingItem['attributes']['contentRating'] == 'explicit' ? {'margin-left' : '23px'} : {'margin-left' : '0px'} ]">
{{ 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>
{{(mk.nowPlayingItem["attributes"]["albumName"]) ?
(mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
</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'} ]">
<p style="width: auto">{{ convertToMins(getSongProgress()) }}</p>
<p style="width: auto">{{ convertToMins(mk.currentPlaybackDuration) }}
</p>
</div>
<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);playerLCD.desiredDuration = 0;playerLCD.userInteraction = false"
:max="mk.currentPlaybackDuration" :value="getSongProgress()">
</div>
</div>
<template v-if="mk.nowPlayingItem['attributes']['playParams']">
<div class="actions">
<button class="lcdMenu" @click="nowPlayingContextMenu">
<div class="svg-icon"></div>
</button>
</div>
</template>
</div>
</template>
</div>
</div>
<div class="app-chrome--right">
<div class="app-chrome-item volume display--large">
<button class="volume-button--small volume" @click="muteButtonPressed()"
:class="{'active': this.cfg.audio.volume == 0}"></button>
<input type="range" class="" @wheel="volumeWheel" step="0.01" min="0" :max="cfg.audio.maxVolume"
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'" @change="checkMuteChange()">
</div>
<div class="app-chrome-item generic" v-if="false">
<button class="playback-button--small">
<%- include("svg/cast.svg") %>
</button>
</div>
<div class="app-chrome-item generic">
<button class="playback-button--small miniplayer"
@click="drawer.open = false; miniPlayer(true)"></button>
</div>
<div class="app-chrome-item generic">
<button class="playback-button--small queue" :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"
:class="{'active': drawer.panel == 'lyrics'}"
@click="invokeDrawer('lyrics')"></button>
</template>
</div>
<div class="app-chrome-item full-height" v-if="chrome.windowControlPosition == 'right'">
<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" v-else @click="ipcRenderer.send('maximize')"></div>
<div class="close" @click="closeWindow()"></div>
</div>
</div>
</div>
</div>
<div class="app-navigation" v-cloak>
<div id="app-sidebar">
<div class="app-sidebar-header">
<div class="search-input-container">
<div class="search-input--icon"></div>
<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">
</div>
</div>
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
<div class="search-hints">
<button class="search-hint" v-for="hint in search.hints"
@click="search.term = hint;search.showHints = false;searchQuery(hint)">
{{ hint }}
</button>
</div>
</div>
<div class="app-sidebar-content">
<div class="app-sidebar-header-text">
Cider
</div>
<sidebar-library-item :name="$root.getLz('home.title')" svg-icon="./assets/feather/home.svg" page="home">
</sidebar-library-item>
<div class="app-sidebar-header-text">
{{$root.getLz('term.appleMusic')}}
</div>
<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>
<div class="app-sidebar-header-text">
{{$root.getLz('term.library')}}
</div>
<sidebar-library-item :name="$root.getLz('term.recentlyAdded')" svg-icon="./assets/feather/plus-circle.svg"
page="library-recentlyadded"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.songs')" svg-icon="./assets/feather/music.svg"
page="library-songs"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.albums')" svg-icon="./assets/feather/disc.svg"
page="library-albums"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.artists')" svg-icon="./assets/feather/user.svg"
page="library-artists"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.videos')" svg-icon="./assets/feather/video.svg" page="library-videos"></sidebar-library-item>
<sidebar-library-item :name="$root.getLz('term.podcasts')" svg-icon="./assets/feather/mic.svg" page="podcasts">
</sidebar-library-item>
<div class="app-sidebar-header-text" @contextmenu="playlistHeaderContextMenu">
{{ $root.getLz('term.playlists') }}
</div>
<sidebar-playlist v-for="item in getPlaylistFolderChildren('p.playlistsroot')" :item="item">
</sidebar-playlist>
</div>
<transition name="wpfade">
<div class="usermenu-container" v-if="chrome.menuOpened">
<div class="usermenu-body">
<button class="usermenu-item" @click="showWebRemoteQR()">
<div class="row nopadding">
<div class="col nopadding">
<span class="usermenu-item-icon"><%- include("./svg/smartphone.svg") %></span>
<span class="usermenu-item-name">{{$root.getLz('action.showWebRemoteQR')}}</span>
</div>
</div>
</button>
<button class="usermenu-item" v-if="cfg.advanced.AudioContext"
@click="modals.audioSettings = true">
<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" @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">
<div class="app-playback-controls display--small" v-if="mkReady()"
@contextmenu="nowPlayingContextMenu">
<div class="control-buttons">
<div class="app-chrome-item">
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0"
@click="mk.shuffleMode = 1"></button>
<button class="playback-button--small shuffle active" v-else
@click="mk.shuffleMode = 0"></button>
</div>
<div class="app-chrome-item">
<button class="playback-button previous" @click="prevButton()"></button>
</div>
<div class="app-chrome-item">
<button class="playback-button pause" @click="mk.pause()"
v-if="mk.isPlaying"></button>
<button class="playback-button play" @click="mk.play()" v-else></button>
</div>
<div class="app-chrome-item">
<button class="playback-button next" @click="mk.skipToNextItem()"></button>
</div>
<div class="app-chrome-item">
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0"
@click="mk.repeatMode = 1"></button>
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
v-else-if="mk.repeatMode == 1"></button>
<button class="playback-button--small repeat active"
@click="mk.repeatMode = 0" v-else-if="mk.repeatMode == 2"></button>
</div>
</div>
<div class="app-chrome-item volume">
<div class="input-container">
<button class="volume-button--small volume" @click="muteButtonPressed()"
:class="{'active': this.cfg.audio.volume == 0}"></button>
<input type="range" class="" @wheel="volumeWheel" step="0.01" min="0" :max="cfg.audio.maxVolume"
v-model="mk.volume" v-if="typeof mk.volume != 'undefined'"
@change="checkMuteChange()">
</div>
</div>
</div>
<button class="app-sidebar-button" style="width:100%" :class="{active: chrome.menuOpened}"
@blur="setTimeout(()=>{chrome.menuOpened = false}, 100)"
@click="(chrome.userinfo.id) ? chrome.menuOpened = !chrome.menuOpened : false">
<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()">
Sign In
</div>
</template>
</div>
<div class="sidebar-user-text" v-else>
Cider
</div>
</button>
</div>
<div class="app-sidebar-notification backgroundNotification"
v-if="library.backgroundNotification.show">
<div class="message">{{ library.backgroundNotification.message }} ({{
library.backgroundNotification.progress }} / {{ library.backgroundNotification.total }})
</div>
</div>
</div>
<div id="app-content">
<div id="navigation-bar">
<button class="nav-item" @click="navigateBack()">
<%- include('svg/chevron-left.svg') %>
</button>
<button class="nav-item" @click="navigateForward()">
<%- include('svg/chevron-right.svg') %>
</button>
</div>
<!-- Podcasts -->
<transition name="wpfade">
<template v-if="page == 'podcasts'">
<apple-podcasts></apple-podcasts>
</template>
</transition>
<!-- Library - Library Videos -->
<transition name="wpfade" >
<template v-if="page == 'library-videos'">
<cider-library-videos></cider-library-videos>
</template>
</transition>
<!-- Apple Setings Page -->
<transition name="wpfade">
<template v-if="page == 'apple-account-settings'">
<apple-account-settings></apple-account-settings>
</template>
</transition>
<!-- About -->
<transition name="wpfade">
<template v-if="page == 'about'">
<about-page></about-page>
</template>
</transition>
<!-- Artist Page -->
<transition name="wpfade">
<template v-if="page == 'artist-page' && artistPage.data.attributes">
<cider-artist :data="artistPage.data"></cider-artist>
</template>
</transition>
<transition name="wpfade">
<%- include('pages/zoo') %>
</transition>
<transition name="wpfade">
<%- include('pages/webview') %>
</transition>
<!-- Collection List -->
<transition name="wpfade">
<template v-if="page == 'collection-list'">
<cider-collection-list :data="collectionList.response" :type="collectionList.type"
:title="collectionList.title"></cider-collection-list>
</template>
</transition>
<!-- Home -->
<transition name="wpfade">
<template v-if="page == 'home'">
<cider-home></cider-home>
</template>
</transition>
<!-- Home -->
<transition name="wpfade">
<template v-if="page == 'artist-feed'">
<cider-artist-feed></cider-artist-feed>
</template>
</transition>
<!-- Playlist / Album page-->
<transition name="wpfade">
<template v-if="page.includes('playlist_')">
<cider-playlist :data="showingPlaylist"></cider-playlist>
</template>
</transition>
<transition name="wpfade">
<template v-if="page.includes('album_')">
<cider-playlist :data="showingPlaylist"></cider-playlist>
</template>
</transition>
<transition name="wpfade">
<template v-if="page.includes('recordLabel_')">
<cider-recordlabel :data="showingPlaylist"></cider-recordlabel>
</template>
</transition>
<transition name="wpfade">
<template v-if="page.includes('curator_')">
<cider-recordlabel :data="showingPlaylist"></cider-recordlabel>
</template>
</transition>
<!-- Browse -->
<transition v-on:enter="getBrowsePage(); console.log('browse')" name="wpfade">
<template v-if="page == 'browse'">
<!-- <div class="content-inner">
<button id="apple-music-authorize" class="md-btn md-btn-primary" @click="init()">Start
MusicKit
</button>
<button id="apple-music-unauthorize" class="md-btn md-btn-primary"
@click="unauthorize()">
Stop
MusicKit
</button>
<br>
<template v-if="mk.nowPlayingItem">
currentPlaybackProgress: {{ app.mk.currentPlaybackProgress }}
<br>
currentPlaybackDuration: {{ app.mk.currentPlaybackDuration }}
</template>
<div><input type="text" v-model="quickPlayQuery">
<button @click="quickPlay(quickPlayQuery)">Play</button>
</div>
<h1 class="header-text">{{$root.getLz('term.browse')}}</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, urna eu
tincidunt
consectetur, nisl nunc euismod nisi, eu porttitor nisl nisi euismod nisi.
</p>
<div class="media-item--small">
<div class="artwork">
</div>
<div class="text">
Text
</div>
<div class="subtext">
Subtext
</div>
</div>
<br>
<br>
<h1 class="header-text">{{$root.getLz('term.listenNow')}}</h1>
<div class="winbox">
<div class="fancy">990kbps</div>
<div class="">
<button class="md-btn md-btn-primary">Audio Quality Settings</button>
</div>
</div>
<button class="md-btn" @click="drawertest = !drawertest">Toggle Drawer</button>
<button class="md-btn">Button</button>
<button class="md-btn md-btn-primary">Button</button>
</div> -->
<cider-browse :data="browsepage"></cider-browse>
</template>
</transition>
<!-- Listen Now -->
<transition v-on:enter="getListenNow()" name="wpfade">
<template v-if="page == 'listen_now'" @created="console.log('listennow')">
<cider-listen-now :data="listennow"></cider-listen-now>
</template>
</transition>
<!-- Radio -->
<transition v-on:enter="getRadioStations()" name="wpfade">
<template v-if="page == 'radio'" @created="console.log('radio')">
<div class="content-inner">
<h1 class="header-text">{{$root.getLz('term.radio')}}</h1>
<h3>{{$root.getLz('term.recentStations')}}</h3>
<mediaitem-square :item="item" v-for="item in radio.personal"></mediaitem-square>
</div>
</template>
</transition>
<!-- Settings -->
<transition name="wpfade">
<template v-if="page == 'settings'">
<cider-settings></cider-settings>
</template>
</transition>
<!-- Search -->
<transition name="wpfade">
<template v-if="page == 'search'">
<cider-search :search="search"></cider-search>
</template>
</transition>
<!-- Library - Recently Added -->
<transition name="wpfade" v-on:enter="getLibraryAlbumsFull(null, 0); searchLibraryAlbums(0);">
<%- include('pages/library-recentlyadded') %>');
</transition>
<!-- Library - Songs -->
<transition name="wpfade" v-on:enter="getLibrarySongsFull()">
<template v-if="page == 'library-songs'">
<cider-library-songs :data="library.songs"></cider-library-songs>
</template>
</transition>
<!-- Library - Albums -->
<transition name="wpfade" v-on:enter="getLibraryAlbumsFull(null, 1); searchLibraryAlbums(1);">
<%- include('pages/library-albums') %>');
%>
</transition>
<!-- Library - Made For You -->
<transition name="wpfade" v-on:enter="getMadeForYou()">
<template v-if="page == 'library-madeforyou'">
<%- include('pages/madeforyou') %>');
%>
</template>
</transition>
<!-- Library - Artists-->
<transition name="wpfade" v-on:enter="getLibraryArtistsFull(null, 0);">
<template v-if="page == 'library-artists'">
<%- include('pages/library-artists') %>');
%>
</template>
</transition>
<transition name="wpfade">
<template v-if="page.includes('appleCurator')">
<cider-applecurator :data="appleCurator"></cider-applecurator>
</template>
</transition>
</div>
<transition name="drawertransition">
<div class="app-drawer"
v-if="drawer.open && drawer.panel == 'lyrics' && lyrics && lyrics != [] && lyrics.length > 0">
<div class="bgArtworkMaterial">
<div class="bg-artwork-container">
<img class="bg-artwork a" :src="$store.state.artwork.playerLCD">
<img class="bg-artwork b" :src="$store.state.artwork.playerLCD">
</div>
</div>
<lyrics-view v-if="drawer.panel == 'lyrics'" :time="lyriccurrenttime" :lyrics="lyrics"
:richlyrics="richlyrics"></lyrics-view>
<div v-if="drawer.panel == 'lyrics'" class="lyric-footer">
<button class="md-btn" @click="modularUITest(!fullscreenLyrics)">{{fullscreenLyrics ?
$root.getLz('term.defaultView'): $root.getLz('term.fullscreenView')}}
</button>
</div>
</div>
</transition>
<transition name="drawertransition">
<div class="app-drawer" v-if="drawer.open && drawer.panel == 'queue'">
<cider-queue ref="queue" v-if="drawer.panel == 'queue'"></cider-queue>
</div>
</transition>
</div>
</div>
</transition>
<%- include('app/panels'); %>
<cider-menu-panel v-if="menuPanel.visible">
</cider-menu-panel>
<transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'fullscreen'">
<fullscreen-view :image="currentArtUrl.replace('50x50', '600x600')" :time="lyriccurrenttime"
:lyrics="lyrics" :richlyrics="richlyrics"></fullscreen-view>
</div>
</transition>
<transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'mini'">
<mini-view :image="currentArtUrl.replace('50x50', '600x600')" :time="lyriccurrenttime"
:lyrics="lyrics" :richlyrics="richlyrics"></mini-view>
</div>
</transition>
<transition name="wpfade">
<div class="bg-artwork-container" v-if="cfg.visual.window_background_style == 'artwork'"
:class="{noanimation: (!cfg.visual.bg_artwork_rotation || !animateBackground)}">
<img @load="chrome.artworkReady = true" class="bg-artwork a ">
<img class="bg-artwork b">
</div>
</transition>
<transition name="wpfade">
<div class="bg-artwork--placeholder"></div>
</transition>
<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-settings v-if="modals.audioSettings"></audio-settings>
</transition>
<transition name="modal">
<eq-view v-if="modals.equalizer"></eq-view>
</transition>
<transition name="modal">
<qrcode-modal v-if="modals.qrcode" :src="webremoteqr" :url="webremoteurl"></qrcode-modal>
</transition>
<div id="apple-music-video-container">
<div id="apple-music-video-player-controls">
<div id="player-exit" title="Close" @click="exitMV()">
<svg fill="white" xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21"
aria-role="presentation" focusable="false">
<path
d="M10.5 21C4.724 21 0 16.275 0 10.5S4.724 0 10.5 0 21 4.725 21 10.5 16.276 21 10.5 21zm-3.543-5.967a.96.96 0 00.693-.295l2.837-2.842 2.85 2.842c.167.167.41.295.693.295.552 0 1.001-.461 1.001-1.012 0-.281-.115-.512-.295-.704L11.899 10.5l2.85-2.855a.875.875 0 00.295-.68c0-.55-.45-.998-1.001-.998a.871.871 0 00-.668.295l-2.888 2.855-2.862-2.843a.891.891 0 00-.668-.281.99.99 0 00-1.001.986c0 .269.116.512.295.678L9.088 10.5l-2.837 2.843a.926.926 0 00-.295.678c0 .551.45 1.012 1.001 1.012z"
fill-rule="nonzero"/>
</svg>
</div>
<div id="captions">{{((lyricon) ? ((lyrics.length > 0 && lyrics[currentLyricsLine] &&
lyrics[currentLyricsLine].line ) ?
lyrics[currentLyricsLine].line.replace('lrcInstrumental','') : "") : '') + ((lyricon) ?
((lyrics.length
> 0 && lyrics[currentLyricsLine] && lyrics[currentLyricsLine].line ) ?
(lyrics[currentLyricsLine].translation ? ('\n\r' + lyrics[currentLyricsLine].translation) : ""): "")
:
'')}}
</div>
<div id="player-pip"
@click="document.querySelector('video#apple-music-video-player').requestPictureInPicture()"
title="Picture-in-Picture">
<%- include("svg/pip.svg") %>
</div>
<div id="player-fullscreen"
@click="document.querySelector('video#apple-music-video-player').requestFullscreen()"
title="Fullscreen">
<%- include("svg/fullscreen.svg") %>
</div>
</div>
<div id="apple-music-video-player"></div>
</div>
</div>
<% for(var i=0; i < Object.keys(env.components).length ; i++) {%>
<%- include(env.components[i]); %>
<% } %>
<!-- Apple Settings Page -->
<%- include('pages/podcasts') %>
<!-- Apple Settings Page -->
<%- include('pages/apple-account-settings') %>
<!-- Library - Songs -->
<%- include('pages/library-songs') %>
<!-- Media Item Artwork-->
<%- include("components/mediaitem-artwork"); %>
<!-- Browse -->
<%- include('pages/browse') %>
<!-- Settings -->
<%- include('pages/settings') %>
<!-- Listen Now -->
<%- include('pages/listen_now') %>
<!-- Home -->
<%- include('pages/home') %>
<!-- Artist Feed -->
<%- include('pages/artist-feed') %>
<!-- Playlists / Albums -->
<%- include('pages/cider-playlist') %>
<!-- Record Label -->
<%- include('pages/recordLabel') %>
<!-- Collection List -->
<%- include('pages/collection-list') %>
<!-- Apple Curator -->
<%- include('pages/apple-curator') %>
<!-- Artist Page -->
<%- include('pages/artist') %>
<!-- Search -->
<%- include('pages/search') %>
<!-- About -->
<%- include('pages/about') %>
<%- include('pages/library-videos') %>
<script type="text/x-template"
id="am-musiccovershelf">
@ -63,6 +713,83 @@
</button>
</script>
<!-- Artwork Material -->
<%- include('components/artwork-material') %>
<!-- Menu Panel -->
<%- include('components/menu-panel') %>
<!-- Playlist Listing -->
<%- include('components/sidebar-playlist')
%>
<!-- Spatial Properties -->
<%- include('components/spatial-properties')
%>
<!-- Audio Settings -->
<%- include('components/audio-settings')
%>
<!-- QRCode Modal -->
<%- include('components/qrcode-modal')
%>
<!-- Equalizer -->
<%- include('components/equalizer')
%>
<!-- Add to playlist -->
<%- include('components/add-to-playlist')
%>
<!-- Queue -->
<%- include('components/queue')
%>
<!-- Queue Item -->
<%- include('components/queue-item')
%>
<!-- Horizontal MediaItem Scroller -->
<%- include('components/mediaitem-scroller-horizontal')
%>
<!-- Horizontal MediaItem Scroller (Large) -->
<%- include('components/mediaitem-scroller-horizontal-large')
%>
<!-- Horizontal MediaItem Scroller (SP : Special) -->
<%- include('components/mediaitem-scroller-horizontal-sp')
%>
<!-- Horizontal MediaItem Scroller (MV) -->
<%- include('components/mediaitem-scroller-horizontal-mvview')
%>
<!-- MediaItem List Item -->
<%- include('components/mediaitem-list-item')
%>
<!-- MediaItem Horizontal Rectangle -->
<%- include('components/mediaitem-hrect')
%>
<!-- MediaItem Square -->
<%- include('components/mediaitem-square')
%>
<!-- MediaItem Square SP -->
<%- include('components/mediaitem-square-sp')
%>
<!-- MediaItem MusicVideo -->
<%- include('components/mediaitem-mvview')
%>
<!-- MediaItem MusicVideo -->
<%- include('components/libraryartist-item')
%>
<%- include('components/listennow-child')
%>
<!-- MediaItem MusicVideo SP -->
<%- include('components/mediaitem-mvview-sp')
%>
<!-- Animated Artwork View -->
<%- include('components/animatedartwork-view')
%>
<!-- Lyrics View -->
<%- include('components/lyrics-view')
%>
<!-- Fullscreen View -->
<%- include('components/fullscreen')
%>
<!-- Miniplayer View -->
<%- include('components/miniplayer')
%>
<script
src="musickit.js?v=1"></script>
<script>

View file

@ -15,7 +15,6 @@
<button onclick="window.open('https://opencollective.com/ciderapp')" class="md-btn sponsorBtn"><img src="./assets/open_collective.svg"/>Open Collective</button>
<h3>{{$root.getLz('term.socials')}}</h3>
<button onclick="window.open('https://discord.gg/applemusic')" class="md-btn sponsorBtn"><img src="./assets/discord.svg"/>{{$root.getLz('term.discord')}}</button>
<button onclick="window.open('https://twitter.com/UseCider')" class="md-btn sponsorBtn"><img style="width: 20.5px;" src="./assets/twitter.svg"/>Twitter</button>
</div>
<div class="col">

View file

@ -3,14 +3,7 @@
<div v-if="page == 'main'">
<div class="row">
<div class="col">
<div class="row nopadding">
<div class="col nopadding">
<h3>{{app.getLz('home.recentlyPlayed')}}</h3>
</div>
<div class="col-auto nopadding flex-center">
<button class="cd-btn-seeall" @click="seeAllHistory()">{{app.getLz('term.seeAll')}}</button>
</div>
</div>
<h3>{{app.getLz('home.recentlyPlayed')}}</h3>
<div class="well artistfeed-well">
<template v-if="isSectionReady('recentlyPlayed')">
<mediaitem-list-item v-for="item in recentlyPlayed.limit(6)"
@ -111,10 +104,6 @@
await this.getFavorites()
},
methods: {
async seeAllHistory() {
let hist = await app.mk.api.v3.music(`/v1/me/recent/played/tracks`)
app.showCollection(hist.data, app.getLz('term.history'))
},
isSectionReady(section) {
return this.sectionsReady.includes(section)
},

View file

@ -1,555 +0,0 @@
<script type="text/x-template" id="playlist-inline">
<div class="content-inner playlist-page inline-playlist" @click.self="$root.resetState()">
<div class="playlist-inner" v-if="data != [] && data.attributes != null">
<div class="close-btn" title="Close" @click="$root.resetState()">
<svg fill="white" xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21"
aria-role="presentation" focusable="false">
<path
d="M10.5 21C4.724 21 0 16.275 0 10.5S4.724 0 10.5 0 21 4.725 21 10.5 16.276 21 10.5 21zm-3.543-5.967a.96.96 0 00.693-.295l2.837-2.842 2.85 2.842c.167.167.41.295.693.295.552 0 1.001-.461 1.001-1.012 0-.281-.115-.512-.295-.704L11.899 10.5l2.85-2.855a.875.875 0 00.295-.68c0-.55-.45-.998-1.001-.998a.871.871 0 00-.668.295l-2.888 2.855-2.862-2.843a.891.891 0 00-.668-.281.99.99 0 00-1.001.986c0 .269.116.512.295.678L9.088 10.5l-2.837 2.843a.926.926 0 00-.295.678c0 .551.45 1.012 1.001 1.012z"
fill-rule="nonzero"/>
</svg>
</div>
<template v-if="app.playlists.loadingState == 0">
<div class="content-inner centered">
<div class="spinner"></div>
</div>
</template>
<template v-if="app.playlists.loadingState == 1">
<div class="playlist-display"
:style="{
'--bgColor': (data.attributes.artwork != null && data.attributes.artwork['bgColor'] != null) ? ('#' + data.attributes.artwork.bgColor) : '',
'--textColor': (data.attributes.artwork != null && data.attributes.artwork['textColor1'] != null) ? ('#' + data.attributes.artwork.textColor1) : ''
}">
<div class="playlistInfo">
<div class="row">
<div class="col-auto flex-center">
<div style="width: 260px;height:260px;">
<mediaitem-artwork
shadow="large"
:video-priority="true"
:url="(data.attributes != null && data.attributes.artwork != null) ? data.attributes.artwork.url : ((data.relationships != null && data.relationships.tracks.data.length > 0 && data.relationships.tracks.data[0].attributes != null) ? ((data.relationships.tracks.data[0].attributes.artwork != null)? data.relationships.tracks.data[0].attributes.artwork.url : ''):'')"
:video="(data.attributes != null && data.attributes.editorialVideo != null) ? (data.attributes.editorialVideo.motionDetailSquare ? data.attributes.editorialVideo.motionDetailSquare.video : (data.attributes.editorialVideo.motionSquareVideo1x1 ? data.attributes.editorialVideo.motionSquareVideo1x1.video : '')) : '' "
size="260"
></mediaitem-artwork>
</div>
</div>
<div class="col playlist-info">
<template v-if="!editorialNotesExpanded">
<div>
<div class="playlist-name" @click="editPlaylistName()" v-show="!nameEditing">
{{data.attributes ? (data.attributes.name ??
(data.attributes.title ?? '') ?? '') : ''}}
</div>
<div class="playlist-name" v-show="nameEditing"><input type="text"
spellcheck="false"
class="nameEdit"
v-model="data.attributes.name"
@blur="editPlaylist"
@change="editPlaylist"
@keydown.enter="editPlaylist"/>
</div>
<div class="playlist-artist item-navigate"
v-if="getArtistName(data) != ''"
@click="data.attributes && data.attributes.artistName ? app.searchAndNavigate(data,'artist') : ''">
{{getArtistName(data)}}
</div>
<div class="playlist-desc"
v-if="data.attributes.description && (data.attributes.description.standard || data.attributes.description.short)">
<div v-if="data.attributes.description.short" class="content"
v-html="data.attributes.description.short"></div>
<div v-else-if="data.attributes.description.standard" class="content"
v-html="data.attributes.description.standard"></div>
<button v-if="data.attributes.description.short" class="more-btn"
@click="editorialNotesExpanded = !editorialNotesExpanded">
{{app.getLz('term.showMore')}}
</button>
</div>
</div>
</template>
<template v-if="editorialNotesExpanded">
<div class="playlist-desc-expanded">
<div class="content"
v-html="((data.attributes.editorialNotes) ? (data.attributes.editorialNotes.standard ?? (data.attributes.editorialNotes.short ?? '') ) : (data.attributes.description ? (data.attributes.description.standard ?? (data.attributes.description.short ?? '')) : ''))"></div>
<button class="more-btn"
@click="editorialNotesExpanded = !editorialNotesExpanded">
{{app.getLz('term.showLess')}}
</button>
</div>
</template>
<div class="playlist-controls" v-observe-visibility="{callback: isHeaderVisible}">
<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')}}
</button>
<button class="md-btn md-btn-primary md-btn-icon" style="min-width: 100px;"
@click="app.mk.shuffleMode = 1;play()"><img class="md-ico-shuffle">
{{app.getLz('term.shuffle')}}
</button>
<button class="md-btn md-btn-icon" style="min-width: 180px;"
v-if="inLibrary!=null && confirm!=true"
@click="confirmButton()"><img
:class="(!inLibrary) ? 'md-ico-add' : 'md-ico-remove'">
{{ (!inLibrary) ? app.getLz('action.addToLibrary') :
app.getLz("action.removeFromLibrary") }}
</button>
<button class="md-btn md-btn-icon" style="min-width: 180px;" v-if="confirm==true"
@click="(!inLibrary) ? addToLibrary(data.attributes.playParams.id.toString()) : removeFromLibrary(data.attributes.playParams.id.toString()) ">
<img :class="(!inLibrary) ? 'md-ico-add' : 'md-ico-remove'">
{{app.getLz('term.confirm')}}
</button>
<button class="more-btn-round" style="float:right;" @click="menu">
<div class="svg-icon"></div>
</button>
</div>
</div>
</div>
</div>
<div class="artworkContainer" v-if="data.attributes.artwork != null">
<artwork-material :url="data.attributes.artwork.url" size="260" images="1"></artwork-material>
</div>
</div>
<div class="floating-header"
:style="{opacity: (headerVisible ? 0 : 1),'pointer-events': (headerVisible ? 'none' : '')}">
<div class="row">
<div class="col">
<h3>{{data.attributes ? (data.attributes.name ??
(data.attributes.title ?? '') ?? '') : ''}}</h3>
</div>
<div class="col-auto flex-center">
<div>
<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')}}
</button>
<button class="md-btn md-btn-primary md-btn-icon" style="min-width: 100px;"
@click="app.mk.shuffleMode = 1;play()"><img class="md-ico-shuffle">
{{app.getLz('term.shuffle')}}
</button>
<button class="md-btn md-btn-icon" style="min-width: 180px;"
v-if="inLibrary!=null && confirm!=true"
@click="confirmButton()"><img
:class="(!inLibrary) ? 'md-ico-add' : 'md-ico-remove'">
{{ (!inLibrary) ? app.getLz('action.addToLibrary') :
app.getLz("action.removeFromLibrary") }}
</button>
<button class="md-btn md-btn-icon" style="min-width: 180px;" v-if="confirm==true"
@click="(!inLibrary) ? addToLibrary(data.attributes.playParams.id.toString()) : removeFromLibrary(data.attributes.playParams.id.toString()) ">
<img :class="(!inLibrary) ? 'md-ico-add' : 'md-ico-remove'">
{{app.getLz('term.confirm')}}
</button>
</div>
</div>
<div class="col-auto flex-center">
<button class="more-btn-round" style="float:right;" @click="menu">
<div class="svg-icon"></div>
</button>
</div>
</div>
</div>
<div class="playlist-body">
<div class="well">
<div style="width:100%">
<draggable :sort="data.attributes.canEdit && data.type == 'library-playlists'"
v-model="data.relationships.tracks.data" @start="drag=true"
@end="drag=false;put()">
<mediaitem-list-item :item="item" :parent="getItemParent(data)" :index="index"
:showIndex="true"
:showIndexPlaylist="(data.attributes.playParams.kind ?? data.type ?? '').includes('playlist')"
:context-ext="buildContextMenu()"
v-for="(item,index) in data.relationships.tracks.data"></mediaitem-list-item>
</draggable>
</div>
</div>
<div class="friends-info" v-if="itemBadges.length != 0">
<div class="well">
<div class="badge-container">
<div class="socialBadge"
:title="`${badge.attributes.name} - @${badge.attributes.handle}`"
v-for="badge in itemBadges">
<mediaitem-artwork
:url="badge.attributes.artwork.url"
:size="60"></mediaitem-artwork>
</div>
</div>
</div>
</div>
<div class="playlist-time">
{{getFormattedDate()}}
</div>
<div class="playlist-time total">{{app.getTotalTime()}}</div>
<div class="playlist-time item-navigate" @click="app.searchAndNavigate(data,'recordLabel') "
style="width: 50%;">
{{data.attributes.copyright}}
</div>
<template
v-if="(data.attributes?.playParams?.kind ?? data.type ?? '').includes('album') && data.relationships.catalog != null && data.relationships.catalog != null && data.relationships.catalog.data.length > 0">
<div class="playlist-time showExtended item-navigate" style="color:#fa586a; font-weight: bold"
@click="app.routeView(data.relationships.catalog.data[0])">
{{$root.getLz("action.showAlbum")}}
</div>
</template>
<hr>
<template v-if="typeof data.meta != 'undefined'">
<div v-for="view in data.meta.views.order" v-if="data.views[view].data.length != 0">
<div class="row">
<div class="col">
<h3>{{ data.views[view].attributes.title }}</h3>
</div>
</div>
<div>
<mediaitem-scroller-horizontal
:items="data.views[view].data"></mediaitem-scroller-horizontal>
</div>
</div>
</template>
</div>
</template>
</div>
<div class="playlist-inner" v-else>
<div class="close-btn" title="Close" @click="$root.resetState()">
<svg fill="white" xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21"
aria-role="presentation" focusable="false">
<path
d="M10.5 21C4.724 21 0 16.275 0 10.5S4.724 0 10.5 0 21 4.725 21 10.5 16.276 21 10.5 21zm-3.543-5.967a.96.96 0 00.693-.295l2.837-2.842 2.85 2.842c.167.167.41.295.693.295.552 0 1.001-.461 1.001-1.012 0-.281-.115-.512-.295-.704L11.899 10.5l2.85-2.855a.875.875 0 00.295-.68c0-.55-.45-.998-1.001-.998a.871.871 0 00-.668.295l-2.888 2.855-2.862-2.843a.891.891 0 00-.668-.281.99.99 0 00-1.001.986c0 .269.116.512.295.678L9.088 10.5l-2.837 2.843a.926.926 0 00-.295.678c0 .551.45 1.012 1.001 1.012z"
fill-rule="nonzero"/>
</svg>
</div>
<template v-if="app.playlists.loadingState == 0">
<div class="content-inner centered">
<div class="spinner"></div>
</div>
</template>
</div>
</div>
</script>
<script>
Vue.component('playlist-inline', {
template: "#playlist-inline",
props: ["data"],
data: function () {
return {
editorialNotesExpanded: false,
drag: false,
nameEditing: false,
inLibrary: null,
confirm: false,
app: this.$root,
itemBadges: [],
badgesRequested: false,
headerVisible: true
}
},
mounted: function () {
this.$nextTick(function () {
this.isInLibrary()
})
},
watch: {
data: function () {
this.isInLibrary()
this.getBadges()
}
},
methods: {
isHeaderVisible(visible) {
this.headerVisible = visible
},
getBadges() {
return
if (this.badgesRequested) {
return
}
this.badgesRequested = true
this.itemBadges = []
let self = this
var id = 0
try {
id = this.data.attributes.playParams.id
} catch (e) {
id = this.data.id
}
this.$root.getSocialBadges((badges) => {
let friends = badges[id]
if (friends) {
friends.forEach(function (friend) {
self.app.mk.api.v3.music(`/v1/social/${app.mk.storefrontId}/social-profiles/${friend}`).then(data => {
self.itemBadges.push(data.data.data[0])
})
})
}
})
},
confirmButton() {
// Return button to normal state after 3 seconds
this.confirm = true
setTimeout(() => this.confirm = false, 3000);
},
getArtistName(data) {
console.log(data.attributes)
if (data.attributes.artistName) {
return data.attributes.artistName
} else if (data.attributes.artist) {
return data.attributes.artist.attributes.name
} else if (data.attributes.curatorName) {
return data.attributes.curatorName
} else {
return ""
}
},
async isInLibrary() {
if (this.data.type && !this.data.type.includes("library")) {
// please keep using vars here
const params = {
"fields[playlists]": "inLibrary",
"fields[albums]": "inLibrary",
"relate": "library"
};
const res = await app.mkapi(this.data.attributes.playParams.kind ?? this.data.type, this.data.attributes.playParams.isLibrary ?? false, this.data.attributes.playParams.id ?? this.data.id, params);
this.inLibrary = (res.data.data[0] && res.data.data[0].attributes && res.data.data[0].attributes.inLibrary) ? res.data.data[0].attributes.inLibrary : false
console.log(res)
} else {
this.inLibrary = true
}
},
editPlaylist() {
this.app.editPlaylist(this.data.id, this.data.attributes.name);
this.app.playlists.listing.forEach(playlist => {
if (playlist.id === this.data.id) {
playlist.attributes.name = this.data.attributes.name
}
})
this.nameEditing = false
},
addToLibrary(id) {
app.mk.addToLibrary(id)
this.inLibrary = true
this.confirm = false
},
async removeFromLibrary(id) {
const params = {"fields[somgs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library"};
var id = this.data.id ?? this.data.attributes.playParams.id
const res = await app.mkapi(this.data.attributes.playParams.kind ?? this.data.type, this.data.attributes.playParams.isLibrary ?? false, this.data.attributes.playParams.id ?? this.data.id, params);
if (res.data.data[0] && res.data.data[0].relationships && res.data.data[0].relationships.library && res.data.data[0].relationships.library.data && res.data.data[0].relationships.library.data.length > 0) {
id = res.data.data[0].relationships.library.data[0].id
}
let kind = this.data.attributes.playParams.kind ?? this.data.type ?? '';
const truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
app.mk.api.v3.music(`v1/me/library/${truekind}/${id.toString()}`, {},
{
fetchOptions: {
method: "DELETE"
}
})
this.inLibrary = false
this.confirm = false
},
editPlaylistName() {
if (this.data.attributes.canEdit && this.data.type === "library-playlists") {
this.nameEditing = true
setTimeout(() => {
document.querySelector(".nameEdit").focus()
}, 100)
}
},
buildContextMenu(index) {
let self = this
if (!this.data.attributes.canEdit) {
return
}
return {
normal: [
{
name: app.getLz('action.removeFromPlaylist'),
action: () => {
self.remove()
}
},
],
multiple: [
{
name: app.getLz('action.removeFromPlaylist'),
action: () => {
self.remove()
}
},
]
}
},
async put() {
if (!this.data.attributes.canEdit) {
return
}
console.log('sds', this.convert())
await app.mk.api.v3.music(
`/v1/me/library/playlists/${this.data.attributes.playParams.id}/tracks`,
{},
{
fetchOptions: {
method: "PUT",
body: JSON.stringify({
data: this.convert()
})
}
}
)
},
async remove() {
if (!this.data.attributes.canEdit) {
return
}
// for each app.selectedMediaItems splice the items from the playlist
for (let i = 0; i < app.selectedMediaItems.length; i++) {
let item = app.selectedMediaItems[i]
let index = this.data.relationships.tracks.data.findIndex(x => x.id == item.id)
if (index > -1) {
this.data.relationships.tracks.data.splice(index, 1)
}
}
await this.put()
},
convert() {
let pl_tracks = []
for (let i = 0; i < this.data.relationships.tracks.data.length; i++) {
pl_tracks.push({
id: this.data.relationships.tracks.data[i].id,
type: this.data.relationships.tracks.data[i].type
})
}
return pl_tracks
},
getRecursive(url) {
app.apiCall(app.musicBaseUrl + "/v1/me/library/playlists/p.V7VYlrDso6kkYY/tracks?offset=100", res => {
this.data.relationships.tracks.data = this.data.relationships.tracks.data.concat(res.data.data)
if (res.data.next) {
this.getRecursive(res.data.next)
}
})
},
menu(event) {
app.showMenuPanel({
items: {
"share": {
name: app.getLz('term.share'),
icon: "./assets/feather/share.svg",
action: () => {
let route = ""
switch (this.data.type) {
case 'albums':
route = `/v1/catalog/${app.mk.storefrontId}/albums/${this.data.id}`
break;
case 'playlists':
route = `/v1/catalog/${app.mk.storefrontId}/playlists/${this.data.id}`
break;
case "library-playlists":
route = `/v1/me/library/playlists/${this.data.id}/catalog`
break
case "library-albums":
route = `/v1/me/library/albums/${this.data.id}/catalog`
break
}
if (route === '') {
return
}
app.mk.api.v3.music(route).then(res => {
console.log(res.data.data[0].attributes.url)
app.copyToClipboard(res.data.data[0].attributes.url)
})
}
}
}
}, event)
},
getItemParent: function (data) {
kind = data.attributes.playParams.kind;
id = data.attributes.playParams.id;
return `${kind}:${id}`
},
getFormattedDate: function () {
let date = (this.data.attributes.releaseDate ?? (this.data.attributes.lastModifiedDate ?? (this.data.attributes.dateAdded ?? '')))
let prefix = '';
if (date == null || date === "") return "";
switch (date) {
case this.data.attributes.releaseDate:
prefix = this.app.getLz('term.time.released') + ' '
break;
case this.data.attributes.lastModifiedDate:
prefix = this.app.getLz('term.time.updated') + ' '
break;
case this.data.attributes.dateAdded:
prefix = this.app.getLz('term.time.added') + ' '
break;
}
let month, year;
try {
const releaseDate = new Date(date);
// month = new Intl.DateTimeFormat(this.app.cfg.general.language.replace('_','-'), {month: 'long'}).format(releaseDate);
// date = releaseDate.getDate();
// year = releaseDate.getFullYear();
let formatted = ''
try {
formatted = new Intl.DateTimeFormat(this.app.cfg.general.language?.replace('_', '-') ?? 'en-US', {
day: 'numeric',
month: 'long',
year: 'numeric'
}).format(releaseDate);
} catch (e) {
// use the format in json instead
if (this.app.getLz('date.format') != null) {
formatted = new this.app.getLz('date.format').replace("${d}", releaseDate.getDate()).replace("${m}", releaseDate.getMonth()).replace("${y}", releaseDate.getFullYear());
} else {
formatted = new Intl.DateTimeFormat('en-US', {
day: 'numeric',
month: 'long',
year: 'numeric'
}).format(releaseDate);
}
}
return prefix + formatted
} catch (e) {
return ""
}
},
play() {
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
const id = this.data.attributes.playParams.id ?? this.data.id;
//console.log("1")
const kind = this.data.attributes.playParams.kind ?? this.data.type ?? '';
//console.log("1")
const truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
let query = (this.data ?? app.showingPlaylist).relationships.tracks.data.map(item => new MusicKit.MediaItem(item));
app.mk.stop().then(function () {
app.mk.setQueue({[truekind]: [id]}).then(function () {
app.mk.play().then(function () {
if (query.length > 100) {
let u = query.slice(100);
if (app.mk.shuffleMode == 1) {
shuffleArray(u)
}
app.mk.queue.append(u)
}
})
})
})
}
}
})
</script>

View file

@ -87,7 +87,7 @@
<button class="md-btn md-btn-block meta-btn" @click="openUrl(selected.attributes.websiteUrl)">{{$root.getLz('podcast.website')}}</button>
</div>
<div class="col">
<button class="md-btn md-btn-block meta-btn" @click="$root.share(selected.attributes.websiteUrl)">{{$root.getLz('action.share')}}</button>
<button class="md-btn md-btn-block meta-btn">{{$root.getLz('action.share')}}</button>
</div>
</div>
</div>

View file

@ -1,21 +0,0 @@
<script type="text/x-template" id="remote-pair">
<div style="display:flex;width:100%;height:100%;padding-top: var(--navigationBarHeight);position:absolute;top:0;left:0;">
<webview id="foo" src="https://music.apple.com/includes/commerce/account/settings?product=music&isFullscreen=true&isModal=false" style="display:inline-flex; width:100%;"></webview>
</div>
</script>
<script>
Vue.component('apple-account-settings', {
template: '#apple-account-settings',
async mounted() {
ipcRenderer.send('get-remote-pair-url')
ipcRenderer.on('send-remote-pair-url', (event, url) => {
this.url = url
app.webview.src = url
document.getElementById('foo').src = url;
})
},
methods: {
}
});
</script>

View file

@ -4,7 +4,7 @@
<div class="row">
<div class="col-sm" style="width: auto;" v-if="getTopResult()">
<template>
<h3>{{app.getLz('term.topResult')}}</h3>
<h3>Top Result</h3>
<mediaitem-square :item="getTopResult()"></mediaitem-square>
</template>
</div>
@ -15,7 +15,7 @@
<div class="col" v-if="search.results.song">
<div class="row">
<div class="col">
<h3>{{app.getLz('term.songs')}}</h3>
<h3>Songs</h3>
</div>
<div class="col-auto flex-center"
@click="app.showSearchView(app.search.term, 'song', app.friendlyTypes('song'))"
@ -41,7 +41,8 @@
</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')}}
@click="app.showSearchView(app.search.term, section, app.friendlyTypes(section))">See
All
</button>
</div>
</div>
@ -58,7 +59,7 @@
<template v-if="search.resultsSocial.playlist">
<div class="row">
<div class="col">
<h3>{{app.getLz('term.sharedPlaylists')}}</h3>
<h3>Shared Playlists</h3>
</div>
<div class="col-auto flex-center" v-if="search.resultsSocial.playlist.data.length >= 10">
<button class="cd-btn-seeall"
@ -72,7 +73,7 @@
<template v-if="search.resultsSocial.profile">
<div class="row">
<div class="col">
<h3>{{app.getLz('term.people')}}</h3>
<h3>People</h3>
</div>
<div class="col-auto flex-center" v-if="search.resultsSocial.profile.data.length >= 10">
<button class="cd-btn-seeall"

View file

@ -6,9 +6,6 @@
</div>
<div class="settings-option-body">
<div class="md-option-line">
<div class="md-option-segment">
{{$root.getLz('term.accountSettings')}}
</div>
<div class="md-option-segment md-option-segment_auto">
<button class="md-btn" @click="app.appRoute('apple-account-settings')">
{{$root.getLz('term.accountSettings')}}
@ -35,8 +32,7 @@
<div class="md-option-segment md-option-segment_auto">
<select class="md-select" style="width:180px;" v-model="app.cfg.audio.quality"
v-on:change="changeAudioQuality">
<!-- // <option value="9216">{{$root.getLz('settings.header.audio.quality.hireslossless')}}</option> -->
<option value="2304">{{$root.getLz('settings.header.audio.quality.lossless')}}</option>
<!-- // <option value="990">Extreme</option> -->
<option value="256">{{$root.getLz('settings.header.audio.quality.high')}}</option>
<option value="64">{{$root.getLz('settings.header.audio.quality.low')}}</option>
<option value="auto">{{$root.getLz('settings.header.audio.quality.auto')}}</option>
@ -62,16 +58,6 @@
switch/>
</div>
</div>
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext">
<div class="md-option-segment">
{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.decryptLLPW')}}
<br>
<small>{{$root.getLz('settings.option.audio.enableAdvancedFunctionality.decryptLLPW.description')}}</small>
</div>
<div class="md-option-segment md-option-segment_auto">
<input type="checkbox" v-model="app.cfg.advanced.decryptLLPW" switch/>
</div>
</div>
<div class="md-option-line" v-show="app.cfg.advanced.AudioContext">
<div class="md-option-segment">
{{$root.getLz('term.equalizer')}}
@ -108,18 +94,6 @@
<span>{{$root.getLz('settings.header.visual')}}</span>
</div>
<div class="settings-option-body">
<div class="md-option-line">
<div class="md-option-segment">
{{$root.getLz('settings.header.visual.theme')}}
</div>
<div class="md-option-segment md-option-segment_auto">
<select class="md-select" @change="$root.setTheme($root.cfg.visual.theme)" v-model="$root.cfg.visual.theme">
<option value="default.less">{{$root.getLz('settings.option.visual.theme.default')}}</option>
<option value="dark.less">{{$root.getLz('settings.option.visual.theme.dark')}}</option>
<option v-for="theme in themes" :value="theme">{{ theme }}</option>
</select>
</div>
</div>
<div class="md-option-line">
<div class="md-option-segment">
{{$root.getLz('settings.option.visual.windowBackgroundStyle')}}
@ -607,15 +581,6 @@
</div>
</div>
<div class="md-option-line">
<div class="md-option-segment">
{{$root.getLz('settings.option.experimental.inline_playlists')}}
</div>
<div class="md-option-segment md-option-segment_auto">
<input type="checkbox" v-model="app.cfg.advanced.experiments.includes('inline-playlists')" @click="app.cfg.advanced.experiments.includes('inline-playlists') ? removeExperiment('inline-playlists') : addExperiment('inline-playlists')" switch/>
</div>
</div>
<div class="md-option-line">
<div class="md-option-segment">
{{$root.getLz('term.language')}}
@ -649,23 +614,22 @@
</button>
</div>
</div>
<div class="md-option-line">
<div class="md-option-segment">
{{$root.getLz('settings.option.experimental.copy_log')}}
</div>
<div class="md-option-segment md-option-segment_auto">
<button class="md-btn" @click="copyLogs">
{{$root.getLz('action.copy')}}
</button>
</div>
</div>
</div>
<div style="opacity: 0.5; pointer-events: none">
<div class="md-option-header">
<span>{{$root.getLz('settings.header.unfinished')}}</span>
</div>
<div class="settings-option-body">
<div class="md-option-line">
<div class="md-option-segment">
Theme
</div>
<div class="md-option-segment md-option-segment_auto">
<select class="md-select">
<option value="0">Cider</option>
</select>
</div>
</div>
<div class="md-option-line">
<div class="md-option-segment">
Theme Options
@ -727,8 +691,7 @@
props: [],
data: function () {
return {
app: this.$root,
themes: ipcRenderer.sendSync("get-themes")
app: this.$root
}
},
mounted: function () {
@ -741,10 +704,6 @@
}
},
methods: {
copyLogs() {
ipcRenderer.send('fetch-log')
notyf.success(app.getLz('term.share.success'));
},
getLanguages: function () {
let langs = this.$root.lzListing
let categories = {
@ -779,7 +738,6 @@
CiderAudio.spatialOn()
}
} else {
app.cfg.advanced.decryptLLPW = false;
CiderAudio.off();
}
},