Merge remote-tracking branch 'swiftfork/main'
# Conflicts: # src/renderer/views/components/add-to-playlist.ejs
This commit is contained in:
commit
bde33c4324
175 changed files with 35181 additions and 23240 deletions
37
src/renderer/views/components/artwork-material.ejs
Normal file
37
src/renderer/views/components/artwork-material.ejs
Normal file
|
@ -0,0 +1,37 @@
|
|||
<script type="text/x-template" id="artwork-material">
|
||||
<div class="artworkMaterial">
|
||||
<img :src="src" v-for="image in images"/>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('artwork-material', {
|
||||
template: '#artwork-material',
|
||||
data: function () {
|
||||
return {
|
||||
src: ""
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.src = app.getMediaItemArtwork(this.url, this.size)
|
||||
},
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: '32'
|
||||
},
|
||||
images: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: '2'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
});
|
||||
</script>
|
82
src/renderer/views/components/cider-modal.ejs
Normal file
82
src/renderer/views/components/cider-modal.ejs
Normal file
|
@ -0,0 +1,82 @@
|
|||
<script type="text/x-template" id="add-to-playlist">
|
||||
<template>
|
||||
<div class="modal-fullscreen modal-generic" @click.self="app.resetState()" @contextmenu.self="app.resetState()">
|
||||
<div class="modal-window">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">{{app.getLz('action.addToLibrary')}}</div>
|
||||
<button class="close-btn" @click="app.resetState()"></button>
|
||||
</div>
|
||||
<div class="modal-content">
|
||||
<button class="playlist-item"
|
||||
:class="{ focused: playlist.id == focused }"
|
||||
@click="addToPlaylist(playlist.id)" style="width:100%;" v-for="playlist in playlistSorted" v-if="playlist.attributes.canEdit && playlist.type != 'library-playlist-folders'">
|
||||
<div class="icon"><%- include("../svg/playlist.svg") %></div>
|
||||
<div class="name">{{ playlist.attributes.name }}</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-search">
|
||||
<div class="search-input-container" style="width:100%;margin: 16px 0;">
|
||||
<div class="search-input--icon"></div>
|
||||
<input type="search"
|
||||
ref="searchInput"
|
||||
style="width:100%;"
|
||||
spellcheck="false"
|
||||
:placeholder="app.getLz('term.search') + '...'"
|
||||
v-model="searchQuery"
|
||||
@input="search()"
|
||||
class="search-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('add-to-playlist', {
|
||||
template: '#add-to-playlist',
|
||||
data: function () {
|
||||
return {
|
||||
playlistSorted: [],
|
||||
searchQuery: "",
|
||||
focused: "",
|
||||
app: this.$root,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
playlists: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.search()
|
||||
this.$refs.searchInput.focus()
|
||||
this.$refs.searchInput.addEventListener('keydown', (e) => {
|
||||
if (e.keyCode == 13) {
|
||||
if (this.focused != "") {
|
||||
this.addToPlaylist(this.focused)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
addToPlaylist(id) {
|
||||
app.addSelectedToPlaylist(id)
|
||||
},
|
||||
search() {
|
||||
this.focused = ""
|
||||
if (this.searchQuery == "") {
|
||||
this.playlistSorted = this.playlists
|
||||
} else {
|
||||
this.playlistSorted = this.playlists.filter(playlist => {
|
||||
return playlist.attributes.name.toLowerCase().indexOf(this.searchQuery.toLowerCase()) > -1
|
||||
})
|
||||
if (this.playlistSorted.length == 1) {
|
||||
this.focused = this.playlistSorted[0].id
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
390
src/renderer/views/components/equalizer.ejs
Normal file
390
src/renderer/views/components/equalizer.ejs
Normal file
|
@ -0,0 +1,390 @@
|
|||
<script type="text/x-template" id="eq-view">
|
||||
<div class="modal-fullscreen equalizer-panel">
|
||||
<div class="modal-window" >
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">{{$root.getLz('term.equalizer')}}</div>
|
||||
<button class="close-btn" @click="close()"></button>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<select class="md-select" style="width:220px;text-align:center;margin-right:16.75em" v-model="$root.cfg.audio.equalizer.preset" v-on:change="changePreset($root.cfg.audio.equalizer.preset)">
|
||||
<optgroup label="User Presets">
|
||||
<option v-for="preset in $root.cfg.audio.equalizer.presets" :value="preset.preset">{{preset.name}}</option>
|
||||
</optgroup>
|
||||
<optgroup label="Default Presets">
|
||||
<option v-for="preset in defaultPresets" :value="preset.preset">{{preset.name}}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-content">
|
||||
<!-- BANDS = [60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000]; -->
|
||||
<div class="inputs-container">
|
||||
<div class="input-container mini">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.preamp" @change="changePreamp()">
|
||||
<input tabindex="0" type="range" class="eq-slider mini" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.preamp" @change="changePreamp()">
|
||||
Preamp
|
||||
</div>
|
||||
<div class="input-container mini">
|
||||
{{$root.cfg.audio.equalizer.mix}}
|
||||
<input tabindex="0" type="range" class="eq-slider mini" orient="vertical" min="0" max="2" step="0.1" v-model="$root.cfg.audio.equalizer.mix" @change="changeMix()">
|
||||
Mix
|
||||
</div>
|
||||
<div class="input-container header mini">
|
||||
Gain
|
||||
<input type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" >
|
||||
<div class="freq-header">Freq</div>
|
||||
<div>Q</div>
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[0]" @change="changeGain(0)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[0]" @change="changeGain(0)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="22" max="44" step="2" v-model="$root.cfg.audio.equalizer.frequencies[0]" @change="changeFreq(0)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[0]" @change="changeQ(0)">
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[1]" @change="changeGain(1)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[1]" @change="changeGain(1)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="44" max="88" step="4" v-model="$root.cfg.audio.equalizer.frequencies[1]" @change="changeFreq(1)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[1]" @change="changeQ(1)">
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[2]" @change="changeGain(2)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[2]" @change="changeGain(2)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="88" max="177" step="8" v-model="$root.cfg.audio.equalizer.frequencies[2]" @change="changeFreq(2)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[2]" @change="changeQ(2)">
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[3]" @change="changeGain(3)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[3]" @change="changeGain(3)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="177" max="355" step="16" v-model="$root.cfg.audio.equalizer.frequencies[3]" @change="changeFreq(3)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[3]" @change="changeQ(3)">
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[4]" @change="changeGain(4)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[4]" @change="changeGain(4)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="355" max="710" step="32" v-model="$root.cfg.audio.equalizer.frequencies[4]" @change="changeFreq(4)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[4]" @change="changeQ(4)">
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[5]" @change="changeGain(5)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[5]" @change="changeGain(5)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="710" max="1420" step="64" v-model="$root.cfg.audio.equalizer.frequencies[5]" @change="changeFreq(5)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[5]" @change="changeQ(5)">
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[6]" @change="changeGain(6)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[6]" @change="changeGain(6)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="1420" max="2840" step="128" v-model="$root.cfg.audio.equalizer.frequencies[6]" @change="changeFreq(6)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[6]" @change="changeQ(6)">
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[7]" @change="changeGain(7)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[7]" @change="changeGain(7)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="2840" max="5680" step="256" v-model="$root.cfg.audio.equalizer.frequencies[7]" @change="changeFreq(7)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[7]" @change="changeQ(7)">
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[8]" @change="changeGain(8)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[8]" @change="changeGain(8)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="5680" max="11360" step="512" v-model="$root.cfg.audio.equalizer.frequencies[8]" @change="changeFreq(8)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[8]" @change="changeQ(8)">
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input tabindex="0" type="number" class="eq-freq" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[9]" @change="changeGain(9)">
|
||||
<input tabindex="0" type="range" class="eq-slider" orient="vertical" min="-12" max="12" step="0.1" v-model="$root.cfg.audio.equalizer.gain[9]" @change="changeGain(9)">
|
||||
<input type="number" class="eq-freq" orient="vertical" min="11360" max="22720" step="1024" v-model="$root.cfg.audio.equalizer.frequencies[9]" @change="changeFreq(9)">
|
||||
<input type="number" class="eq-q" orient="vertical" min="0" max="5" step="0.1" v-model="$root.cfg.audio.equalizer.Q[9]" @change="changeQ(9)">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-lowercontent">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button class="md-btn" style="width:100%" @click="resetGain()">{{$root.getLz('term.reset')}}</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="md-btn" style="width:100%" @click="presetOptions($event)">{{$root.getLz('term.menu')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('eq-view', {
|
||||
template: '#eq-view',
|
||||
data: function () {
|
||||
return {
|
||||
// app: this.$root,
|
||||
eqPreset: function () {
|
||||
this.preset = uuidv4()
|
||||
this.name = ""
|
||||
this.frequencies = []
|
||||
this.gain = []
|
||||
this.Q = []
|
||||
this.preamp = 0
|
||||
this.mix = 1
|
||||
this.userGenerated = true
|
||||
},
|
||||
defaultPresets: [{
|
||||
'preset': 'warmth',
|
||||
'name': 'Warmth',
|
||||
'frequencies': [32, 75, 125, 197, 500, 1000, 2000, 3040, 8000, 16000],
|
||||
'gain': [0, 2.1, 0, 0.8, 0, 0, 0, -1.5, 0, 0],
|
||||
'Q': [1, 0.7, 1, 1.5, 1, 1, 1, 2, 1, 1],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
}, {
|
||||
'preset': 'boostBrightness',
|
||||
'name': 'Boost Brightness',
|
||||
'frequencies': [32, 63, 125, 250, 466, 1000, 2000, 4000, 8000, 20000],
|
||||
'gain': [0, 0, 0, 0, -2, 0, 0, 0, 0, 10],
|
||||
'Q': [1, 1, 1, 1, 0.6, 1, 1, 1, 1, 0.1],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
}, {
|
||||
'preset': 'acoustic',
|
||||
'name': 'Acoustic',
|
||||
'frequencies': [32, 75, 125, 220, 700, 1000, 2000, 4000, 10000, 16000],
|
||||
'gain': [0, -8, 0, -0.1, -3, 0, 0, 0, 4, 0],
|
||||
'Q': [1, 0.2, 1, 2.0, 1.4, 1, 1, 1, 0.1, 1],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
}, {
|
||||
'preset': 'clearVocal',
|
||||
'name': 'Clear Vocal',
|
||||
'frequencies': [20, 63, 125, 250, 400, 1000, 2000, 4000, 8000, 20000],
|
||||
'gain': [-22, 0, 0, 0, -3, 0, 1.8, 0, 0, 3.5],
|
||||
'Q': [0.3, 1, 1, 1, 2.0, 1, 0.7, 1, 1, 0.8],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
}, {
|
||||
'preset': 'instrumentClarity',
|
||||
'name': 'Instrument Clarity',
|
||||
'frequencies': [20, 63, 155, 250, 500, 1000, 2000, 5000, 11000, 16000],
|
||||
'gain': [-15, 0, -3, 0, 0, 0, 0, 3.1, 0, 0],
|
||||
'Q': [0.5, 1, 2, 1, 1, 1, 1, 1.5, 0.1, 1],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
}, {
|
||||
'preset': 'reduceHarshness',
|
||||
'name': 'Reduce Harshness',
|
||||
'frequencies': [32, 63, 125, 250, 500, 1128, 2000, 4057, 8000, 16000],
|
||||
'gain': [0, 0, 0, 0, 0, 2, 0, -6.4, 0, 0],
|
||||
'Q': [1, 1, 1, 1, 1, 2, 1, 1, 1, 1],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
}, {
|
||||
'preset': 'smileyFace',
|
||||
'name': 'Smiley Face',
|
||||
'frequencies': [35, 63, 125, 250, 500, 800, 2000, 4000, 8000, 20000],
|
||||
'gain': [5, 0, 0, 0, 0, -5, 0, 0, 0, 5],
|
||||
'Q': [0.1, 1, 1, 1, 1, 0.6, 1, 1, 1, 0.2],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
},
|
||||
{
|
||||
'preset': 'bassBoostCrystal',
|
||||
'name': 'Crystal Bass Boost',
|
||||
'frequencies': [45.53,88.06,116.18,161.3,247.05,295.6,365.79,495.13,716.85,960.76],
|
||||
'gain': [-0.36,4.07,-1.3,1.92,0.77,-0.53,-1.33,0.44,0.46,-0.5],
|
||||
'Q': [1.768,0.625,5,8.409,10,16.82,5.946,7.071,20,10],
|
||||
'preamp': -2,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
},
|
||||
{
|
||||
'preset': 'bassBoostSurgical',
|
||||
'name': 'Surgical Bass Boost',
|
||||
'frequencies': [32, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000],
|
||||
'gain': [2.7, 2.2, 1.6, 1.4, 0.6, 0, 0, 0, 0, 0],
|
||||
'Q': [1.4, 1.4, 1.4, 1.4, 1.4, 1, 1, 1, 1, 1],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
}, {
|
||||
'preset': 'bassBoostClassic',
|
||||
'name': 'Classic Bass Boost',
|
||||
'frequencies': [32, 63, 160, 250, 500, 1000, 2000, 3500, 8000, 20000],
|
||||
'gain': [2.7, 2.2, 1.6, 1.4, 0.6, 0, 0, 0, 0, 0],
|
||||
'Q': [0.7, 0.7, 0.7, 0.7, 0.7, 1, 1, 1, 1, 1],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
'userGenerated': false
|
||||
}]
|
||||
}
|
||||
},
|
||||
props: ["src", "url"],
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
presetOptions(event) {
|
||||
let menu = {
|
||||
items: {
|
||||
"new": {
|
||||
"icon": "./assets/feather/plus.svg",
|
||||
name: "New Preset...",
|
||||
action: () => {
|
||||
this.addPreset()
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"icon": "./assets/feather/x-circle.svg",
|
||||
name: "Delete Preset",
|
||||
action: () => {
|
||||
this.deletePreset()
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
"icon": "./assets/feather/share.svg",
|
||||
"name": app.getLz('action.import'),
|
||||
"action": function () {
|
||||
notyf.error("Not implemented yet")
|
||||
}
|
||||
},
|
||||
"export": {
|
||||
"icon": "./assets/feather/share.svg",
|
||||
"name": app.getLz('action.export'),
|
||||
"action": function () {
|
||||
notyf.error("Not implemented yet")
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.$root.cfg.audio.equalizer.userGenerated) {
|
||||
delete menu.items.delete
|
||||
}
|
||||
|
||||
app.showMenuPanel(menu, event)
|
||||
},
|
||||
sharePreset(event) {
|
||||
let menu = {
|
||||
items: [
|
||||
{
|
||||
"icon": "./assets/feather/share.svg",
|
||||
"name": app.getLz('action.import'),
|
||||
"action": function () {
|
||||
notyf.error("Not implemented yet")
|
||||
}
|
||||
},
|
||||
{
|
||||
"icon": "./assets/feather/share.svg",
|
||||
"name": app.getLz('action.export'),
|
||||
"action": function () {
|
||||
notyf.error("Not implemented yet")
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
app.showMenuPanel(menu, event)
|
||||
},
|
||||
deletePreset() {
|
||||
let presets = this.$root.cfg.audio.equalizer.presets
|
||||
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("Removed preset")
|
||||
}
|
||||
})
|
||||
},
|
||||
close() {
|
||||
app.resetState()
|
||||
},
|
||||
changePreamp() {
|
||||
CiderAudio.audioNodes.preampNode.gain.value = app.cfg.audio.equalizer.preamp;
|
||||
},
|
||||
changeMix() {
|
||||
for (var i = 0; i < 10; i++) {
|
||||
CiderAudio.audioNodes.audioBands[i].gain.value = app.cfg.audio.equalizer.gain[i] * app.cfg.audio.equalizer.mix
|
||||
}
|
||||
},
|
||||
changeGain(i) {
|
||||
CiderAudio.audioNodes.audioBands[i].gain.value = app.cfg.audio.equalizer.gain[i] * app.cfg.audio.equalizer.mix
|
||||
},
|
||||
changeFreq(i) {
|
||||
CiderAudio.audioNodes.audioBands[i].frequency.value = app.cfg.audio.equalizer.frequencies[i]
|
||||
},
|
||||
changeQ(i) {
|
||||
CiderAudio.audioNodes.audioBands[i].Q.value = app.cfg.audio.equalizer.Q[i]
|
||||
},
|
||||
resetGain() {
|
||||
this.applyPreset({
|
||||
'frequencies': [32, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000],
|
||||
'gain': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
'Q': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
'preamp': 0,
|
||||
'mix': 1,
|
||||
})
|
||||
if (app.cfg.audio.equalizer.userGenerated) {
|
||||
this.saveSelectedPreset()
|
||||
}
|
||||
},
|
||||
addPreset() {
|
||||
let self = this
|
||||
bootbox.prompt("New EQ Preset Name", (res) => {
|
||||
if (res) {
|
||||
let eqSettings = Clone(app.cfg.audio.equalizer)
|
||||
let newPreset = new self.eqPreset()
|
||||
newPreset.name = res
|
||||
newPreset.frequencies = eqSettings.frequencies
|
||||
newPreset.gain = eqSettings.gain
|
||||
newPreset.Q = eqSettings.Q
|
||||
newPreset.preamp = eqSettings.preamp
|
||||
newPreset.mix = eqSettings.mix
|
||||
app.cfg.audio.equalizer.presets.push(newPreset)
|
||||
notyf.success("Added Preset")
|
||||
self.changePreset(newPreset.preset)
|
||||
}
|
||||
})
|
||||
},
|
||||
saveSelectedPreset() {
|
||||
// Save the current settings to the selected preset
|
||||
let self = this
|
||||
//let preset = app.cfg.audio.equalizer.presets[app.cfg.audio.equalizer.preset]
|
||||
// find the preset by its id (preset)
|
||||
let preset = app.cfg.audio.equalizer.presets.find(p => p.preset == app.cfg.audio.equalizer.preset)
|
||||
preset.frequencies = app.cfg.audio.equalizer.frequencies
|
||||
preset.gain = app.cfg.audio.equalizer.gain
|
||||
preset.Q = app.cfg.audio.equalizer.Q
|
||||
preset.preamp = app.cfg.audio.equalizer.preamp
|
||||
preset.mix = app.cfg.audio.equalizer.mix
|
||||
notyf.success("Saved Preset")
|
||||
},
|
||||
applyPreset(preset) {
|
||||
Object.assign(this.$root.cfg.audio.equalizer, preset)
|
||||
this.changePreamp()
|
||||
for (var i = 0; i < 10; i++) {
|
||||
this.changeGain(i)
|
||||
this.changeFreq(i)
|
||||
this.changeQ(i)
|
||||
}
|
||||
},
|
||||
changePreset(id) {
|
||||
let userPresets = app.cfg.audio.equalizer.presets
|
||||
let defaultPresets = Clone(this.defaultPresets)
|
||||
|
||||
let presets = defaultPresets.concat(userPresets)
|
||||
console.log(presets)
|
||||
let preset = presets.find(p => p.preset == id)
|
||||
|
||||
console.log(preset)
|
||||
|
||||
if (preset) {
|
||||
this.applyPreset(preset)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -26,7 +26,7 @@
|
|||
{{ app.mk.nowPlayingItem["attributes"]["name"] }}
|
||||
</div>
|
||||
<div
|
||||
style="display: inline-block; -webkit-box-orient: horizontal; white-space: nowrap; margin-top: 0.25vh;">
|
||||
style="display: inline-block; -webkit-box-orient: horizontal; white-space: nowrap; margin-top: 0.25vh; overflow: hidden;">
|
||||
<div class="item-navigate song-artist" style="display: inline-block;"
|
||||
@click="app.getNowPlayingItemDetailed(`artist`)">
|
||||
{{ app.mk.nowPlayingItem["attributes"]["artistName"] }}
|
||||
|
@ -71,17 +71,17 @@
|
|||
<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 active" @click="app.mk.repeatMode = 2"
|
||||
<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 repeatOne" @click="app.mk.repeatMode = 0"
|
||||
<button class="playback-button--small repeat active" @click="app.mk.repeatMode = 0"
|
||||
v-else-if="app.mk.repeatMode == 2"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-chrome-item volume display--large">
|
||||
<div class="app-chrome-item volume-icon"></div>
|
||||
<div class="input-container">
|
||||
<input type="range" class="slider" @wheel="app.volumeWheel" step="0.01" min="0" max="1" v-model="app.mk.volume"
|
||||
v-if="typeof app.mk.volume != 'undefined'">
|
||||
<button class="volume-button--small volume" @click="app.muteButtonPressed()" :class="{'active': app.cfg.audio.volume == 0}"></button>
|
||||
<input type="range" class="slider" @wheel="app.volumeWheel" step="0.01" min="0" :max="$root.cfg.audio.maxVolume" v-model="app.mk.volume"
|
||||
v-if="typeof app.mk.volume != 'undefined'" @change="app.checkMuteChange()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,28 +2,20 @@
|
|||
<div v-observe-visibility="{callback: visibilityChanged}"
|
||||
@click="select"
|
||||
class="cd-mediaitem-list-item"
|
||||
:class="{'mediaitem-selected': app.select_hasMediaItem(guid)}">
|
||||
:class="{'mediaitem-selected': app.select_hasMediaItem(guid)}"
|
||||
@contextmenu="contextMenu">
|
||||
<template v-if="isVisible">
|
||||
<div class="artwork" v-if="showArtwork == true">
|
||||
<mediaitem-artwork
|
||||
:url="getArtwork()"
|
||||
size="50"
|
||||
:type="item.type"></mediaitem-artwork>
|
||||
<button class="overlay-play" @click="select"></button>
|
||||
</div>
|
||||
<div class="info-rect" :style="{'padding-left': (showArtwork ? '' : '16px')}"
|
||||
@dblclick="app.routeView(item)">
|
||||
<div class="title text-overflow-elipsis">
|
||||
{{ item.attributes.name }}
|
||||
</div>
|
||||
<div class="subtitle text-overflow-elipsis" style="-webkit-box-orient: horizontal;">
|
||||
<template v-if="item.attributes.name">
|
||||
<div class="artist item-navigate text-overflow-elipsis"
|
||||
@click="select">
|
||||
{{ item.attributes.artistName }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -62,22 +54,19 @@
|
|||
return minutes + ":" + (seconds < 10 ? '0' : '') + seconds;
|
||||
},
|
||||
getDataType() {
|
||||
if (this.item.attributes.playParams.isLibrary) {
|
||||
return this.item.type
|
||||
} else {
|
||||
return this.item.attributes.playParams.kind
|
||||
}
|
||||
return this.item.type
|
||||
},
|
||||
async select(e) {
|
||||
let u = this.item
|
||||
let u1 = await app.mk.api.library.artistRelationship(u.id,"albums",
|
||||
{platform: "web",
|
||||
"include[library-albums]": "artists,tracks",
|
||||
"include[library-artists]": "catalog",
|
||||
"fields[artists]": "url",
|
||||
"includeOnly": "catalog,artists"}
|
||||
)
|
||||
app.showCollection({data : Object.assign({},u1)}, u.attributes.name?? '', '');
|
||||
let u1 = await app.mk.api.v3.music(`/v1/me/library/artists/${u.id}/albums`, {
|
||||
"platform": "web",
|
||||
"include[library-albums]": "artists,tracks",
|
||||
"include[library-artists]": "catalog",
|
||||
"fields[artists]": "url",
|
||||
"includeOnly": "catalog,artists"
|
||||
})
|
||||
app.showCollection({data : Object.assign({},u1.data.data)}, u.attributes.name?? '', '');
|
||||
app.select_selectMediaItem(u.id, this.getDataType(), this.index, this.guid, true)
|
||||
},
|
||||
getArtwork(){
|
||||
let u = ""
|
||||
|
@ -87,80 +76,38 @@
|
|||
return u;
|
||||
},
|
||||
contextMenu(event) {
|
||||
|
||||
let self = this
|
||||
let data_type = this.getDataType()
|
||||
let item_id = this.item.attributes.playParams.id ?? this.item.id
|
||||
let isLibrary = this.item.attributes.playParams.isLibrary ?? false
|
||||
|
||||
let item = self.item
|
||||
item.attributes.artistName = item.attributes.name;
|
||||
|
||||
let useMenu = "normal"
|
||||
if (app.selectedMediaItems.length <= 1) {
|
||||
app.selectedMediaItems = []
|
||||
app.select_selectMediaItem(item_id, data_type, this.index, this.guid, isLibrary)
|
||||
app.select_selectMediaItem(this.item.id, data_type, this.index, this.guid, true)
|
||||
} else {
|
||||
useMenu = "multiple"
|
||||
}
|
||||
|
||||
let menus = {
|
||||
multiple: {
|
||||
items: [
|
||||
{
|
||||
"name": "Add to Playlist...",
|
||||
"action": function () {
|
||||
app.promptAddToPlaylist()
|
||||
}
|
||||
},
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks next`,
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
app.selectedMediaItems.forEach(item => {
|
||||
if (!itemsToPlay[item.kind]) {
|
||||
itemsToPlay[item.kind] = []
|
||||
}
|
||||
itemsToPlay[item.kind].push(item.id)
|
||||
})
|
||||
// loop through itemsToPlay
|
||||
for (let kind in itemsToPlay) {
|
||||
let ids = itemsToPlay[kind]
|
||||
if (ids.length > 0) {
|
||||
app.mk.playNext({[kind + "s"]: itemsToPlay[kind]})
|
||||
}
|
||||
}
|
||||
console.log(itemsToPlay)
|
||||
app.selectedMediaItems = []
|
||||
}
|
||||
},
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks later`,
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
app.selectedMediaItems.forEach(item => {
|
||||
if (!itemsToPlay[item.kind]) {
|
||||
itemsToPlay[item.kind] = []
|
||||
}
|
||||
itemsToPlay[item.kind].push(item.id)
|
||||
})
|
||||
// loop through itemsToPlay
|
||||
for (let kind in itemsToPlay) {
|
||||
let ids = itemsToPlay[kind]
|
||||
if (ids.length > 0) {
|
||||
app.mk.playLater({[kind + "s"]: itemsToPlay[kind]})
|
||||
}
|
||||
}
|
||||
app.selectedMediaItems = []
|
||||
}
|
||||
},
|
||||
]
|
||||
items: [] //
|
||||
},
|
||||
normal: {
|
||||
items: [
|
||||
{
|
||||
"name": "Add to Playlist...",
|
||||
"name": app.getLz('action.goToArtist'),
|
||||
"icon": "./assets/feather/user.svg",
|
||||
"action": function () {
|
||||
app.promptAddToPlaylist()
|
||||
app.searchAndNavigate(self.item, 'artist')
|
||||
console.log(self.item)
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Start Radio",
|
||||
"icon": "./assets/feather/radio.svg",
|
||||
"name": app.getLz('action.startRadio'),
|
||||
"action": function () {
|
||||
app.mk.setStationQueue({song: self.item.attributes.playParams.id ?? self.item.id}).then(() => {
|
||||
app.mk.play()
|
||||
|
@ -169,31 +116,15 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"name": "Play Next",
|
||||
"icon": "./assets/feather/share.svg",
|
||||
"name": app.getLz('action.share'),
|
||||
"action": function () {
|
||||
app.mk.playNext({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id})
|
||||
app.mk.queue._reindex()
|
||||
app.selectedMediaItems = []
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Play Later",
|
||||
"action": function () {
|
||||
app.mk.playLater({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id})
|
||||
app.mk.queue._reindex()
|
||||
app.selectedMediaItems = []
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Go to Artist",
|
||||
"action": function () {
|
||||
app.searchAndNavigate(self.item, 'artist')
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Go to Album",
|
||||
"action": function () {
|
||||
app.searchAndNavigate(self.item, 'album')
|
||||
if (!self.item.attributes.url && self.item.relationships){
|
||||
if (self.item.relationships.catalog){
|
||||
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.copyToClipboard((u.data.data.length && u.data.data.length > 0)? u.data.data[0].attributes.url : u.data.data.attributes.url)})
|
||||
}
|
||||
} else {
|
||||
self.app.copyToClipboard(self.item.attributes.url)}
|
||||
}
|
||||
},
|
||||
]
|
||||
|
@ -208,7 +139,9 @@
|
|||
menus.multiple.items = menus.multiple.items.concat(this.contextExt.multiple)
|
||||
}
|
||||
}
|
||||
CiderContextMenu.Create(event, menus[useMenu])
|
||||
//CiderContextMenu.Create(event, menus[useMenu]); // Depreciated Context Menu
|
||||
app.showMenuPanel(menus[useMenu], event);
|
||||
|
||||
},
|
||||
visibilityChanged: function (isVisible, entry) {
|
||||
this.isVisible = isVisible
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<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')" >See All</button>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="recom.attributes.display.kind == 'MusicCoverShelf'">
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
</template>
|
||||
<template v-else>
|
||||
<div class="no-lyrics">
|
||||
Loading... / Lyrics not found./ Instrumental.</div>
|
||||
{{app.getLz('term.noLyrics')}}</div>
|
||||
</template>
|
||||
</div>
|
||||
</script>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script type="text/x-template" id="mediaitem-artwork">
|
||||
<div class="mediaitem-artwork" :class="[{'rounded': (type == 'artists')}, classes]" :key="url"
|
||||
v-observe-visibility="{callback: visibilityChanged}">
|
||||
<div class="mediaitem-artwork" :class="[{'rounded': (type == 'artists')}, classes]" :key="url">
|
||||
<img :src="app.getMediaItemArtwork(url, size, width)"
|
||||
decoding="async" loading="lazy"
|
||||
decoding="async"
|
||||
:style="{background: bgcolor}"
|
||||
class="mediaitem-artwork--img">
|
||||
<div v-if="video && isVisible && getVideoPriority()" class="animatedartwork-view-box">
|
||||
<div v-if="video && getVideoPriority()" class="animatedartwork-view-box">
|
||||
<animatedartwork-view :priority="getVideoPriority()" :video="video"></animatedartwork-view>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -22,6 +22,10 @@
|
|||
type: [String, Number],
|
||||
required: false
|
||||
},
|
||||
bgcolor: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
default: ''
|
||||
|
@ -88,9 +92,6 @@
|
|||
width: this.size + 'px',
|
||||
height: this.size + 'px'
|
||||
};
|
||||
},
|
||||
visibilityChanged: function (isVisible, entry) {
|
||||
this.isVisible = isVisible
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
0
src/renderer/views/components/mediaitem-info.ejs
Normal file
0
src/renderer/views/components/mediaitem-info.ejs
Normal file
|
@ -14,17 +14,26 @@
|
|||
@mouseleave="showInLibrary = false"
|
||||
:class="[{'mediaitem-selected': app.select_hasMediaItem(guid)}, addClasses]">
|
||||
<template v-if="isVisible">
|
||||
<div class="isLibrary" :style="{opacity: (showInLibrary ? 1 : 0)}" v-if="showLibraryStatus == true">
|
||||
<button @click="addToLibrary()"
|
||||
v-if="!addedToLibrary">
|
||||
<div class="svg-icon" :style="{'--color': 'var(--keyColor)', '--url': 'url(./assets/feather/plus.svg)'}"></div>
|
||||
</button>
|
||||
<button v-else style="opacity:0;">❤️</button>
|
||||
<div class="isLibrary"" v-if="showLibraryStatus == true">
|
||||
<div v-if="showInLibrary" :style="{display: (showInLibrary ? 'block' : 'none'), 'margin-left':'11px'}">
|
||||
<button @click="addToLibrary()" v-if="!addedToLibrary">
|
||||
<div class="svg-icon" :style="{'--color': 'var(--keyColor)', '--url': 'url(./assets/feather/plus.svg)'}"></div>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="!(app.mk.isPlaying && (((app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.id ) == item.attributes.playParams.id) || (app.mk.nowPlayingItem.id == item.id ))) && showIndex" :style="{display: ((showIndex && !showInLibrary) ? 'block' : 'none'), 'margin-left':'11px'}">
|
||||
<div>
|
||||
<div>{{ (item.attributes && !showIndexPlaylist) ? (item.attributes.trackNumber ?? '') : ((index * 1 + 1 ) ?? '')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="app.mk.isPlaying && (((app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.id ) == item.attributes.playParams.id) || (app.mk.nowPlayingItem.id == item.id))" :style="{display: (showInLibrary ? 'none' : 'block')}">
|
||||
<div class="loadbar-sound"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="artwork" v-if="showArtwork == true">
|
||||
<mediaitem-artwork
|
||||
:url="item.attributes.artwork ? item.attributes.artwork.url : ''"
|
||||
:size="48"
|
||||
:bgcolor="getBgColor()"
|
||||
:type="item.type"></mediaitem-artwork>
|
||||
<button class="overlay-play" @click="playTrack()"><%- include("../svg/play.svg") %></button>
|
||||
</div>
|
||||
|
@ -88,6 +97,8 @@
|
|||
'show-library-status': {type: Boolean, default: true},
|
||||
'show-meta-data': {type: Boolean, default: false},
|
||||
'show-duration': {type: Boolean, default: true},
|
||||
'showIndex': {type: Boolean, required: false},
|
||||
'showIndexPlaylist': {type: Boolean, required: false},
|
||||
'contextExt': {type: Object, required: false},
|
||||
'class-list': {type: String, required: false, default: ""},
|
||||
},
|
||||
|
@ -99,6 +110,10 @@
|
|||
this.getClasses()
|
||||
},
|
||||
methods: {
|
||||
getBgColor() {
|
||||
let color = `#${(this.item.attributes.artwork != null && this.item.attributes.artwork.bgColor != null) ? (this.item.attributes.artwork.bgColor) : ``}`
|
||||
return color
|
||||
},
|
||||
async checkLibrary() {
|
||||
if(this.addedToLibrary) {return this.addedToLibrary}
|
||||
if(this.item.type.includes("library-playlists") || this.item.type.includes("station")) {
|
||||
|
@ -223,14 +238,14 @@
|
|||
multiple: {
|
||||
items: [
|
||||
{
|
||||
"name": "Add to Playlist...",
|
||||
"name": app.getLz('action.addToPlaylist'),
|
||||
"icon": "./assets/feather/plus.svg",
|
||||
"action": function () {
|
||||
app.promptAddToPlaylist()
|
||||
}
|
||||
},
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks next`,
|
||||
name: app.getLz('action.playTracksNext').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||
"icon": "./assets/arrow-bend-up.svg",
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
|
@ -252,7 +267,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks later`,
|
||||
name: app.getLz('action.playTracksLater').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||
"icon": "./assets/arrow-bend-down.svg",
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
|
@ -279,7 +294,7 @@
|
|||
{
|
||||
"icon": "./assets/feather/heart.svg",
|
||||
"id": "love",
|
||||
"name": "Love",
|
||||
"name": this.app.getLz('action.love'),
|
||||
"hidden": false,
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
|
@ -290,7 +305,7 @@
|
|||
"icon": "./assets/feather/heart.svg",
|
||||
"id": "unlove",
|
||||
"active": true,
|
||||
"name": "Unlove",
|
||||
"name": this.app.getLz('action.unload'),
|
||||
"hidden": true,
|
||||
"action": function () {
|
||||
app.unlove(self.item)
|
||||
|
@ -299,7 +314,7 @@
|
|||
{
|
||||
"icon": "./assets/feather/thumbs-down.svg",
|
||||
"id": "dislike",
|
||||
"name": "Dislike",
|
||||
"name": this.app.getLz('action.dislike'),
|
||||
"hidden": false,
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
|
@ -309,7 +324,7 @@
|
|||
{
|
||||
"icon": "./assets/feather/thumbs-down.svg",
|
||||
"id": "undo_dislike",
|
||||
"name": "Undo dislike",
|
||||
"name": this.app.getLz('action.undoDislike'),
|
||||
"active": true,
|
||||
"hidden": true,
|
||||
"action": function () {
|
||||
|
@ -321,7 +336,7 @@
|
|||
{
|
||||
"id": "addToLibrary",
|
||||
"icon": "./assets/feather/plus.svg",
|
||||
"name": "Add to library",
|
||||
"name": this.app.getLz('action.addToLibrary'),
|
||||
"hidden": false,
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
|
@ -331,7 +346,7 @@
|
|||
{
|
||||
"id": "removeFromLibrary",
|
||||
"icon": "./assets/feather/x-circle.svg",
|
||||
"name": "Remove from library",
|
||||
"name": app.getLz('action.removeFromLibrary'),
|
||||
"hidden": true,
|
||||
"action": function () {
|
||||
self.removeFromLibrary()
|
||||
|
@ -339,13 +354,13 @@
|
|||
},
|
||||
{
|
||||
"icon": "./assets/feather/list.svg",
|
||||
"name": "Add to Playlist...",
|
||||
"name": app.getLz('action.addToPlaylist'),
|
||||
"action": function () {
|
||||
app.promptAddToPlaylist()
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Play Next",
|
||||
"name": app.getLz('action.playNext'),
|
||||
"icon": "./assets/arrow-bend-up.svg",
|
||||
"action": function () {
|
||||
app.mk.playNext({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id})
|
||||
|
@ -354,7 +369,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"name": "Play Later",
|
||||
"name": app.getLz('action.playLater'),
|
||||
"icon": "./assets/arrow-bend-down.svg",
|
||||
"action": function () {
|
||||
app.mk.playLater({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id})
|
||||
|
@ -364,7 +379,7 @@
|
|||
},
|
||||
{
|
||||
"icon": "./assets/feather/radio.svg",
|
||||
"name": "Start Radio",
|
||||
"name": app.getLz('action.startRadio'),
|
||||
"action": function () {
|
||||
app.mk.setStationQueue({song: self.item.attributes.playParams.id ?? self.item.id}).then(() => {
|
||||
app.mk.play()
|
||||
|
@ -374,25 +389,25 @@
|
|||
},
|
||||
{
|
||||
"icon": "./assets/feather/user.svg",
|
||||
"name": "Go to Artist",
|
||||
"name": app.getLz('action.goToArtist'),
|
||||
"action": function () {
|
||||
app.searchAndNavigate(self.item, 'artist')
|
||||
}
|
||||
},
|
||||
{
|
||||
"icon": "./assets/feather/disc.svg",
|
||||
"name": "Go to Album",
|
||||
"name": app.getLz('action.goToAlbum'),
|
||||
"action": function () {
|
||||
app.searchAndNavigate(self.item, 'album')
|
||||
}
|
||||
},
|
||||
{
|
||||
"icon": "./assets/feather/share.svg",
|
||||
"name": "Share",
|
||||
"name": app.getLz('action.share'),
|
||||
"action": function () {
|
||||
if (!self.item.attributes.url && self.item.relationships){
|
||||
if (self.item.relationships.catalog){
|
||||
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.copyToClipboard((u.length && u.length > 0)? u[0].attributes.url : u.attributes.url)})
|
||||
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.copyToClipboard((u.data.data.length && u.data.data.length > 0)? u.data.data[0].attributes.url : u.data.data.attributes.url)})
|
||||
}
|
||||
}else {
|
||||
self.app.copyToClipboard(self.item.attributes.url)}
|
||||
|
@ -502,22 +517,21 @@
|
|||
app.mk.setQueue({[truekind]: [item.attributes.playParams.id ?? item.id]}).then(function () {
|
||||
app.mk.play().then(function (){
|
||||
var playlistId = id
|
||||
function getPlaylist(id, params, isLibrary){
|
||||
function getPlaylist(id, isLibrary){
|
||||
if (isLibrary){
|
||||
return app.mk.api.library.playlist(id, params)
|
||||
} else { return app.mk.api.playlist(id, params)}
|
||||
return this.app.mk.api.v3.music(`/v1/me/library/playlists/${id}`)
|
||||
} else { return this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`)}
|
||||
}
|
||||
try {
|
||||
|
||||
getPlaylist(id, params, isLibrary).then(res => {
|
||||
getPlaylist(id, isLibrary).then(res => {
|
||||
//let query = res.relationships.tracks.data.map(item => new MusicKit.MediaItem(item));
|
||||
//if (app.mk.shuffleMode == 1){shuffleArray(query); }
|
||||
// console.log(query)
|
||||
// app.mk.queue.append(query)
|
||||
if (!res.relationships.tracks.next) {
|
||||
if (!res.data.relationships.tracks.next) {
|
||||
return
|
||||
} else {
|
||||
getPlaylistTracks(res.relationships.tracks.next)
|
||||
getPlaylistTracks(res.data.relationships.tracks.next)
|
||||
}
|
||||
|
||||
function getPlaylistTracks(next) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script type="text/x-template" id="mediaitem-scroller-horizontal">
|
||||
<template>
|
||||
<div class="cd-hmedia-scroller" :class="kind">
|
||||
<slot></slot>
|
||||
<mediaitem-square :kind="kind" :item="item"
|
||||
v-for="item in items"></mediaitem-square>
|
||||
</div>
|
||||
|
@ -13,7 +14,7 @@
|
|||
props: {
|
||||
'items': {
|
||||
type: Array,
|
||||
required: true
|
||||
required: false
|
||||
},
|
||||
'kind': {
|
||||
type: String,
|
||||
|
|
|
@ -122,7 +122,11 @@
|
|||
}
|
||||
let kind = this.item.attributes.playParams.kind ?? this.item.type ?? '';
|
||||
var truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
|
||||
app.mk.api.library.remove({[truekind]: id})
|
||||
app.mk.api.v3.music(`v1/me/library/${truekind}/${id.toString()}`,{},
|
||||
{
|
||||
fetchOptions: {
|
||||
method: "DELETE"
|
||||
}})
|
||||
this.addedToLibrary = true
|
||||
},
|
||||
async contextMenu(event) {
|
||||
|
@ -140,7 +144,7 @@
|
|||
multiple: {
|
||||
items: [
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks next`,
|
||||
name: this.$root.getLz('action.playTracksNext').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
app.selectedMediaItems.forEach(item => {
|
||||
|
@ -161,7 +165,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks later`,
|
||||
name: app.getLz('action.playTracksLater').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
app.selectedMediaItems.forEach(item => {
|
||||
|
@ -225,7 +229,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"name": "Share",
|
||||
"name": this.$root.getLz('term.share'),
|
||||
"action": function () {
|
||||
self.app.copyToClipboard(self.item.attributes.url)
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
if (this.item.type && !this.item.type.includes("library")) {
|
||||
var params = {"fields[playlists]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library", "extend": this.revisedRandId()}
|
||||
var res = await app.mkapi(this.item.attributes.playParams.kind ?? this.item.type, this.item.attributes.playParams.isLibrary ?? false, this.item.attributes.playParams.id ?? this.item.id, params);
|
||||
res = res.data.data[0]
|
||||
this.addedToLibrary = (res && res.attributes && res.attributes.inLibrary) ? res.attributes.inLibrary : false
|
||||
} else {
|
||||
this.addedToLibrary = true
|
||||
|
@ -105,12 +106,17 @@
|
|||
var params = {"fields[playlists]": "inLibrary","fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library", "extend": this.revisedRandId()}
|
||||
var id = this.item.id ?? this.item.attributes.playParams.id
|
||||
var res = await app.mkapi(this.item.attributes.playParams.kind ?? this.item.type, this.item.attributes.playParams.isLibrary ?? false, this.item.attributes.playParams.id ?? this.item.id, params);
|
||||
res = res.data.data[0]
|
||||
if (res && res.relationships && res.relationships.library && res.relationships.library.data && res.relationships.library.data.length > 0) {
|
||||
id = res.relationships.library.data[0].id
|
||||
}
|
||||
let kind = this.item.attributes.playParams.kind ?? this.item.type ?? '';
|
||||
var truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
|
||||
app.mk.api.library.remove({[truekind]: id})
|
||||
app.mk.api.v3.music(`v1/me/library/${truekind}/${id.toString()}`,{},
|
||||
{
|
||||
fetchOptions: {
|
||||
method: "DELETE"
|
||||
}})
|
||||
this.addedToLibrary = true
|
||||
},
|
||||
subtitleSearchNavigate(item) {
|
||||
|
@ -152,7 +158,7 @@
|
|||
multiple: {
|
||||
items: [
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks next`,
|
||||
name: app.getLz('action.playTracksNext').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
app.selectedMediaItems.forEach(item => {
|
||||
|
@ -173,7 +179,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks later`,
|
||||
name: app.getLz('action.playTracksLater').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
app.selectedMediaItems.forEach(item => {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
:video="(item.attributes != null && item.attributes.editorialVideo != null) ? (item.attributes.editorialVideo.motionDetailSquare ? item.attributes.editorialVideo.motionDetailSquare.video : (item.attributes.editorialVideo.motionSquareVideo1x1 ? item.attributes.editorialVideo.motionSquareVideo1x1.video : '')) : '' "
|
||||
:size="size"
|
||||
shadow="subtle"
|
||||
:bgcolor="getBgColor()"
|
||||
:type="item.type"></mediaitem-artwork>
|
||||
</div>
|
||||
<button class="menu-btn" v-if="!nomenu.includes(item.type)"
|
||||
|
@ -75,22 +76,8 @@
|
|||
},
|
||||
methods: {
|
||||
getBgColor() {
|
||||
let color = `#${(this.item.attributes.artwork != null && this.item.attributes.artwork.bgColor != null) ? (this.item.attributes.artwork.bgColor) : `333333`}`
|
||||
let c = color.substring(1); // strip #
|
||||
var rgb = parseInt(c, 16); // convert rrggbb to decimal
|
||||
var r = (rgb >> 16) & 0xff; // extract red
|
||||
var g = (rgb >> 8) & 0xff; // extract green
|
||||
var b = (rgb >> 0) & 0xff; // extract blue
|
||||
|
||||
var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
|
||||
|
||||
if (luma > 140) {
|
||||
return "#aaaaaa"
|
||||
}else{
|
||||
return color
|
||||
}
|
||||
|
||||
|
||||
let color = `#${(this.item.attributes.artwork != null && this.item.attributes.artwork.bgColor != null) ? (this.item.attributes.artwork.bgColor) : ``}`
|
||||
return color
|
||||
},
|
||||
getSubtitle() {
|
||||
if(this.kind == 'card') {
|
||||
|
@ -145,8 +132,8 @@
|
|||
let friends = this.badges[id]
|
||||
if (friends) {
|
||||
friends.forEach(function (friend) {
|
||||
self.app.mk.api.socialProfile(friend).then(data => {
|
||||
self.itemBadges.push(data)
|
||||
self.app.mk.api.v3.music(`/v1/social/${app.mk.storefrontId}/social-profiles/${friend}`).then(data => {
|
||||
self.itemBadges.push(data.data.data[0])
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -164,6 +151,7 @@
|
|||
"extend": this.revisedRandId()
|
||||
}
|
||||
var res = await app.mkapi(this.item.attributes.playParams.kind ?? this.item.type, this.item.attributes.playParams.isLibrary ?? false, this.item.attributes.playParams.id ?? this.item.id, params);
|
||||
res = res.data.data[0]
|
||||
this.addedToLibrary = (res && res.attributes && res.attributes.inLibrary) ? res.attributes.inLibrary : false
|
||||
} else {
|
||||
this.addedToLibrary = true
|
||||
|
@ -179,12 +167,17 @@
|
|||
}
|
||||
var id = this.item.id ?? this.item.attributes.playParams.id
|
||||
var res = await app.mkapi(this.item.attributes.playParams.kind ?? this.item.type, this.item.attributes.playParams.isLibrary ?? false, this.item.attributes.playParams.id ?? this.item.id, params);
|
||||
res= res.data.data[0]
|
||||
if (res && res.relationships && res.relationships.library && res.relationships.library.data && res.relationships.library.data.length > 0) {
|
||||
id = res.relationships.library.data[0].id
|
||||
}
|
||||
let kind = this.item.attributes.playParams.kind ?? this.item.type ?? '';
|
||||
var truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
|
||||
app.mk.api.library.remove({[truekind]: id})
|
||||
app.mk.api.v3.music(`v1/me/library/${truekind}/${id.toString()}`,{},
|
||||
{
|
||||
fetchOptions: {
|
||||
method: "DELETE"
|
||||
}})
|
||||
this.addedToLibrary = true
|
||||
},
|
||||
uuidv4() {
|
||||
|
@ -229,6 +222,7 @@
|
|||
case "music-videos":
|
||||
case "uploadedVideo":
|
||||
case "uploaded-videos":
|
||||
case "library-music-videos":
|
||||
return "mediaitem-video";
|
||||
break;
|
||||
}
|
||||
|
@ -257,7 +251,7 @@
|
|||
multiple: {
|
||||
items: [
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks next`,
|
||||
name: app.getLz('action.playTracksNext').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||
"icon": "./assets/arrow-bend-up.svg",
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
|
@ -279,7 +273,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
name: `Play ${app.selectedMediaItems.length} tracks later`,
|
||||
name: app.getLz('action.playTracksLater').replace("${app.selectedMediaItems.length}", app.selectedMediaItems.length),
|
||||
"icon": "./assets/arrow-bend-down.svg",
|
||||
action: () => {
|
||||
let itemsToPlay = {}
|
||||
|
@ -306,7 +300,7 @@
|
|||
{
|
||||
"icon": "./assets/feather/heart.svg",
|
||||
"id": "love",
|
||||
"name": "Love",
|
||||
"name": app.getLz('action.love'),
|
||||
"hidden": false,
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
|
@ -317,7 +311,7 @@
|
|||
"icon": "./assets/feather/heart.svg",
|
||||
"id": "unlove",
|
||||
"active": true,
|
||||
"name": "Unlove",
|
||||
"name": app.getLz('action.unlove'),
|
||||
"hidden": true,
|
||||
"action": function () {
|
||||
app.unlove(self.item)
|
||||
|
@ -326,7 +320,7 @@
|
|||
{
|
||||
"icon": "./assets/feather/thumbs-down.svg",
|
||||
"id": "dislike",
|
||||
"name": "Dislike",
|
||||
"name": app.getLz('action.dislike'),
|
||||
"hidden": false,
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
|
@ -336,7 +330,7 @@
|
|||
{
|
||||
"icon": "./assets/feather/thumbs-down.svg",
|
||||
"id": "undo_dislike",
|
||||
"name": "Undo dislike",
|
||||
"name": app.getLz('action.undoDislike'),
|
||||
"active": true,
|
||||
"hidden": true,
|
||||
"action": function () {
|
||||
|
@ -348,7 +342,7 @@
|
|||
{
|
||||
"icon": "./assets/feather/list.svg",
|
||||
"id": "addToPlaylist",
|
||||
"name": "Add to Playlist...",
|
||||
"name": app.getLz('action.addToPlaylist'),
|
||||
"action": function () {
|
||||
app.promptAddToPlaylist()
|
||||
}
|
||||
|
@ -356,7 +350,7 @@
|
|||
{
|
||||
"id": "addToLibrary",
|
||||
"icon": "./assets/feather/plus.svg",
|
||||
"name": "Add to library",
|
||||
"name": app.getLz('action.addToLibrary'),
|
||||
"hidden": false,
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
|
@ -369,7 +363,7 @@
|
|||
{
|
||||
"id": "removeFromLibrary",
|
||||
"icon": "./assets/feather/x-circle.svg",
|
||||
"name": "Remove from library",
|
||||
"name": app.getLz('action.removeFromLibrary'),
|
||||
"hidden": true,
|
||||
"action": async function () {
|
||||
console.log("remove");
|
||||
|
@ -380,7 +374,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"name": "Play Next",
|
||||
"name": app.getLz('action.playNext'),
|
||||
"icon": "./assets/arrow-bend-up.svg",
|
||||
"action": function () {
|
||||
app.mk.playNext({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id})
|
||||
|
@ -389,7 +383,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"name": "Play Later",
|
||||
"name": app.getLz('action.playLater'),
|
||||
"icon": "./assets/arrow-bend-down.svg",
|
||||
"action": function () {
|
||||
app.mk.playLater({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id})
|
||||
|
@ -399,9 +393,14 @@
|
|||
},
|
||||
{
|
||||
"icon": "./assets/feather/share.svg",
|
||||
"name": "Share",
|
||||
"name": app.getLz('action.share'),
|
||||
"action": function () {
|
||||
self.app.copyToClipboard(self.item.attributes.url)
|
||||
if (!self.item.attributes.url && self.item.relationships){
|
||||
if (self.item.relationships.catalog){
|
||||
app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.copyToClipboard((u.data.data.length && u.data.data.length > 0)? u.data.data[0].attributes.url : u.data.data.attributes.url)})
|
||||
}
|
||||
}else {
|
||||
self.app.copyToClipboard(self.item.attributes.url)}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
163
src/renderer/views/components/miniplayer.ejs
Normal file
163
src/renderer/views/components/miniplayer.ejs
Normal file
|
@ -0,0 +1,163 @@
|
|||
<script type="text/x-template" id="mini-view">
|
||||
<div class="mini-view" tabindex="0">
|
||||
<div class="background">
|
||||
</div>
|
||||
<div class="player-pin" title="Pin to Top" @click="app.pinMiniPlayer()">
|
||||
<span id="mini-pin">📌</span>
|
||||
</div>
|
||||
<div class="player-exit" title="Close" @click="app.miniPlayer(false)">
|
||||
<svg fill="#323232e3" 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 class="col artwork-col">
|
||||
<div class="artwork" @click="app.miniPlayer(false)">
|
||||
<mediaitem-artwork
|
||||
:size="600"
|
||||
:url="image ?? ''"
|
||||
></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="controls-parents">
|
||||
<template v-if="app.mkReady()">
|
||||
<div class="app-playback-controls" @mouseover="app.chrome.progresshover = true"
|
||||
@mouseleave="app.chrome.progresshover = false" @contextmenu="app.nowPlayingContextMenu">
|
||||
<div class="playback-info">
|
||||
<div class="song-name">
|
||||
{{ app.mk.nowPlayingItem["attributes"]["name"] }}
|
||||
</div>
|
||||
<div
|
||||
style="display: inline-block; -webkit-box-orient: horizontal; white-space: nowrap; margin-top: 0.25vh; overflow: hidden; margin-bottom: 5px;">
|
||||
<div class="item-navigate song-artist" style="display: inline-block;"
|
||||
@click="app.getNowPlayingItemDetailed(`artist`)">
|
||||
{{ app.mk.nowPlayingItem["attributes"]["artistName"] }}
|
||||
</div>
|
||||
<div class="song-artist item-navigate" style="display: inline-block;"
|
||||
@click="app.getNowPlayingItemDetailed('album')">
|
||||
{{ (app.mk.nowPlayingItem["attributes"]["albumName"]) ? (" — " +
|
||||
app.mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="song-progress">
|
||||
<div class="song-duration" style="justify-content: space-between; height: 1px; margin-bottom: 1px;"
|
||||
:style="[app.chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]">
|
||||
<p style="width: auto">{{ app.convertToMins(app.getSongProgress()) }}</p>
|
||||
<p style="width: auto">{{ app.convertToMins(app.mk.currentPlaybackDuration) }}</p>
|
||||
</div>
|
||||
|
||||
<input type="range" step="0.01" min="0" :style="app.progressBarStyle()"
|
||||
@input="app.playerLCD.desiredDuration = $event.target.value;app.playerLCD.userInteraction = true"
|
||||
@mouseup="app.mk.seekToTime($event.target.value);app.playerLCD.desiredDuration = 0;app.playerLCD.userInteraction = false"
|
||||
:max="app.mk.currentPlaybackDuration" :value="app.getSongProgress()">
|
||||
</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.mk.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>
|
||||
<div class="app-chrome-item volume display--large">
|
||||
<div class="input-container">
|
||||
<button class="volume-button--small volume" @click="app.muteButtonPressed()" :class="{'active': app.cfg.audio.volume == 0}"></button>
|
||||
<input type="range" class="slider" @wheel="app.volumeWheel" step="0.01" min="0" max="1" v-model="app.mk.volume"
|
||||
v-if="typeof app.mk.volume != 'undefined'" @change="app.checkMuteChange()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="row fs-row">
|
||||
|
||||
<div class="col right-col" v-if="tabMode != ''">
|
||||
<div class="fs-info">
|
||||
<div>Name</div>
|
||||
<div>Name</div>
|
||||
<div>Name</div>
|
||||
</div>
|
||||
<div class="lyrics-col" v-if="tabMode == 'lyrics'">
|
||||
<lyrics-view :yoffset="120" :time="time" :lyrics="lyrics"
|
||||
:richlyrics="richlyrics"></lyrics-view>
|
||||
</div>
|
||||
<div class="queue-col" v-if="tabMode == 'queue'">
|
||||
<cider-queue v-if="tabMode == 'queue'" ref="queue" ></cider-queue>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- <div class="tab-toggles">
|
||||
<div class="lyrics" :class="{active: tabMode == 'lyrics'}" @click="tabMode = (tabMode == 'lyrics') ? '' : 'lyrics'"></div>
|
||||
<div class="queue" :class="{active: tabMode == 'queue'}" @click="tabMode = (tabMode == 'queue') ? '' :'queue'"></div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('mini-view', {
|
||||
template: '#mini-view',
|
||||
props: {
|
||||
time: {
|
||||
type: Number,
|
||||
required: false
|
||||
},
|
||||
lyrics: {
|
||||
type: Array,
|
||||
required: false
|
||||
},
|
||||
richlyrics: {
|
||||
type: Array,
|
||||
required: false
|
||||
},
|
||||
image: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
app: this.$root,
|
||||
tabMode: "",
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
window.addEventListener('keyup', this.onEscapeKeyUp);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('keyup', this.onEscapeKeyUp)
|
||||
},
|
||||
methods: {
|
||||
onEscapeKeyUp(event) {
|
||||
if (event.which === 27) {
|
||||
app.miniPlayer(false);
|
||||
console.log('js')
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
34
src/renderer/views/components/qrcode-modal.ejs
Normal file
34
src/renderer/views/components/qrcode-modal.ejs
Normal file
|
@ -0,0 +1,34 @@
|
|||
<script type="text/x-template" id="qrcode-modal">
|
||||
<div class="modal-fullscreen spatialproperties-panel">
|
||||
<div class="modal-window" >
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">{{`Web Remote QR : ` + url }}</div>
|
||||
<button class="close-btn" @click="close()"></button>
|
||||
</div>
|
||||
<div class="modal-content">
|
||||
<img class="qrimg" :src="src"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('qrcode-modal', {
|
||||
template: '#qrcode-modal',
|
||||
data: function () {
|
||||
return {
|
||||
app: this.$root,
|
||||
|
||||
}
|
||||
},
|
||||
props: ["src","url"],
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
app.resetState()
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -48,7 +48,7 @@
|
|||
let self = this
|
||||
CiderContextMenu.Create(event, {
|
||||
items: [{
|
||||
"name": "Remove from queue",
|
||||
"name": $root.getLz('action.removeFromQueue'),
|
||||
"action": function () {
|
||||
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
<div class="queue-panel">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3 class="queue-header-text">Queue</h3>
|
||||
<h3 class="queue-header-text">{{app.getLz('term.queue')}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center">
|
||||
<button class="autoplay" :style="{'background': app.mk.autoplayEnabled ? 'var(--keyColor)' : ''}" @click="app.mk.autoplayEnabled = !app.mk.autoplayEnabled">∞</button>
|
||||
<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">
|
||||
|
@ -33,7 +33,7 @@
|
|||
</draggable>
|
||||
</div>
|
||||
<div class="queue-footer">
|
||||
<button class="md-btn" style="width:100%;" v-if="queueItems.length > 1" @click="app.mk.clearQueue();updateQueue()">Clear All</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>
|
||||
|
@ -76,7 +76,7 @@
|
|||
let menus = {
|
||||
single: {
|
||||
items: [{
|
||||
"name": "Remove from queue",
|
||||
"name": app.getLz('action.removeFromQueue'),
|
||||
"action": function () {
|
||||
self.queueItems.splice(position, 1)
|
||||
app.mk.queue._queueItems = self.queueItems;
|
||||
|
@ -84,7 +84,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"name": "Start Radio",
|
||||
"name": app.getLz('action.startRadio'),
|
||||
"action": function () {
|
||||
app.mk.setStationQueue({
|
||||
song: item.attributes.playParams.id ?? item.id
|
||||
|
@ -97,7 +97,7 @@
|
|||
},
|
||||
multiple: {
|
||||
items: [{
|
||||
"name": `Remove ${self.selectedItems.length} tracks from queue`,
|
||||
"name": app.getLz('action.removeTracks'),
|
||||
"action": function () {
|
||||
// add property to items to be removed
|
||||
self.selectedItems.forEach(function (item) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
@dragover="dragOver"
|
||||
@drop="onDrop"
|
||||
:href="item.href"
|
||||
@click='item.type != "library-playlist-folders" ? openPlaylist(item) : getPlaylistChildren(item)'>
|
||||
@click='clickEvent()'>
|
||||
<template v-if="!renaming">
|
||||
<div class="sidebar-icon" v-html="icon"></div> {{ item.attributes.name }}
|
||||
</template>
|
||||
|
@ -15,7 +15,7 @@
|
|||
</button>
|
||||
<div class="folder-body" v-if="item.type === 'library-playlist-folders' && folderOpened">
|
||||
<template v-if="children.length != 0">
|
||||
<sidebar-playlist v-for="item in children" :item="item" :key="item.id"></sidebar-playlist>
|
||||
<sidebar-playlist v-for="item in children" :playlist-select="playlistSelect" :item="item" :key="item.id"></sidebar-playlist>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="spinner"></div>
|
||||
|
@ -31,6 +31,10 @@
|
|||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
playlistSelect: {
|
||||
type: Function,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
|
@ -50,6 +54,17 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
clickEvent() {
|
||||
if(this.item.type != "library-playlist-folders") {
|
||||
if(this.playlistSelect) {
|
||||
this.playlistSelect(this.item)
|
||||
}else{
|
||||
this.openPlaylist(this.item)
|
||||
}
|
||||
}else{
|
||||
this.getPlaylistChildren(this.item)
|
||||
}
|
||||
},
|
||||
rename() {
|
||||
this.renaming = false
|
||||
|
||||
|
@ -105,7 +120,7 @@
|
|||
let menu = {
|
||||
items: {
|
||||
"moveToParent": {
|
||||
name: "Move to top",
|
||||
name: this.$root.getLz('action.moveToTop'),
|
||||
action: () => {
|
||||
let self = this
|
||||
this.move(this.item, {
|
||||
|
@ -116,7 +131,7 @@
|
|||
}
|
||||
},
|
||||
"rename": {
|
||||
name: "Rename",
|
||||
name: this.$root.getLz('action.rename'),
|
||||
action: () => {
|
||||
this.renaming = true
|
||||
setTimeout(()=>{
|
||||
|
@ -126,13 +141,13 @@
|
|||
}
|
||||
},
|
||||
"deleteFromPlaylist": {
|
||||
name: "Delete from library",
|
||||
name: this.$root.getLz('action.removeFromLibrary'),
|
||||
action: () => {
|
||||
this.$root.deletePlaylist(playlist_id)
|
||||
}
|
||||
},
|
||||
"addToFavorites": {
|
||||
name: "Add to favorites",
|
||||
name: this.$root.getLz('action.addToFavorites'),
|
||||
disabled: true,
|
||||
hidden: true,
|
||||
action: () => {
|
||||
|
@ -181,7 +196,9 @@
|
|||
this.children = []
|
||||
this.getChildren()
|
||||
this.toggleFolder()
|
||||
this.$root.mk.api.library.playlistFolderChildren(item.id).then(children => {
|
||||
|
||||
this.$root.mk.api.v3.music(`v1/me/library/playlist-folders/${item.id}/children`).then(data => {
|
||||
let children = data.data.data;
|
||||
children.forEach(child => {
|
||||
if(!self.$root.playlists.listing.find(listing => listing.id == child.id)) {
|
||||
child.parent = self.item.id
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
<div class="modal-fullscreen spatialproperties-panel">
|
||||
<div class="modal-window" v-if="ready">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">Spatial Properties</div>
|
||||
<div class="modal-title">{{$root.getLz('spatial.spatialProperties')}}</div>
|
||||
<button class="close-btn" @click="close()"></button>
|
||||
</div>
|
||||
<div class="modal-content">
|
||||
<template v-if="roomEditType == 'dimensions'">
|
||||
<div class="row">
|
||||
<div class="col"><h3>Room Dimensions</h3></div>
|
||||
<div class="col"><h3>{{$root.getLz('spatial.roomDimensions')}}</h3></div>
|
||||
<div class="col-auto flex-center">
|
||||
<button class="md-btn" @click="roomEditType = 'positions'">Set Positions</button>
|
||||
<button class="md-btn" @click="roomEditType = 'positions'">{{$root.getLz('spatial.setPositions')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Width
|
||||
{{$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%;"
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Height
|
||||
{{$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%;"
|
||||
|
@ -46,7 +46,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Depth
|
||||
{{$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%;"
|
||||
|
@ -58,7 +58,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<label v-if="!app.cfg.audio.normalization">
|
||||
Gain
|
||||
{{$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>
|
||||
|
@ -73,9 +73,9 @@
|
|||
</template>
|
||||
<template v-if="roomEditType == 'positions'">
|
||||
<div class="row">
|
||||
<div class="col"><h3>Room Positions</h3></div>
|
||||
<div class="col"><h3>{{$root.getLz('spatial.roomPositions')}}</h3></div>
|
||||
<div class="col-auto flex-center">
|
||||
<button class="md-btn" @click="roomEditType = 'dimensions'">Set Dimensions</button>
|
||||
<button class="md-btn" @click="roomEditType = 'dimensions'">{{$root.getLz('spatial.setDimensions')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -83,7 +83,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
X (Listener)
|
||||
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%;"
|
||||
|
@ -97,7 +97,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Y (Listener)
|
||||
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%;"
|
||||
|
@ -111,7 +111,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Z (Listener)
|
||||
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%;"
|
||||
|
@ -125,7 +125,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
X (Audio Source)
|
||||
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%;"
|
||||
|
@ -139,7 +139,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Y (Audio Source)
|
||||
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%;"
|
||||
|
@ -153,7 +153,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-3 flex-center">
|
||||
Z (Audio Source)
|
||||
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%;"
|
||||
|
@ -179,13 +179,13 @@
|
|||
</template>
|
||||
|
||||
<div class="row">
|
||||
<div class="col"><h3>Room Materials</h3></div>
|
||||
<div class="col"><h3>{{$root.getLz('spatial.roomMaterials')}}</h3></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"></div>
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
Up
|
||||
{{$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>
|
||||
|
@ -197,7 +197,7 @@
|
|||
<div class="row">
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
Left
|
||||
{{$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>
|
||||
|
@ -206,14 +206,14 @@
|
|||
</div>
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
Front
|
||||
{{$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>
|
||||
Back
|
||||
{{$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>
|
||||
|
@ -222,7 +222,7 @@
|
|||
</div>
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
Right
|
||||
{{$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>
|
||||
|
@ -234,7 +234,7 @@
|
|||
<div class="col"></div>
|
||||
<div class="col flex-center">
|
||||
<label>
|
||||
Down
|
||||
{{$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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue