1.1.5 - shuffle, discord, task bar icon, title bar fix

This commit is contained in:
exttex 2020-11-06 16:49:52 +01:00
parent 416d65f310
commit 9fab54951c
13 changed files with 544 additions and 424 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,4 +1,4 @@
const {app, BrowserWindow, ipcMain, Tray, Menu, session, dialog, shell} = require('electron'); const {app, BrowserWindow, ipcMain, Tray, Menu, session, dialog, shell, nativeTheme} = require('electron');
const {createServer} = require('./src/server'); const {createServer} = require('./src/server');
const path = require('path'); const path = require('path');
@ -39,6 +39,7 @@ async function createWindow() {
minHeight: 600, minHeight: 600,
resizable: true, resizable: true,
autoHideMenuBar: true, autoHideMenuBar: true,
frame: false,
icon: assetPath("icon.png"), icon: assetPath("icon.png"),
title: 'Freezer', title: 'Freezer',
webPreferences: { webPreferences: {
@ -87,7 +88,10 @@ app.on('ready', async () => {
createWindow(); createWindow();
//Create Tray //Create Tray
tray = new Tray(assetPath("icon-taskbar.png")); if (nativeTheme.shouldUseDarkColors)
tray = new Tray(assetPath("icon-taskbar-white.png"));
else
tray = new Tray(assetPath("icon-taskbar-black.png"));
tray.on('double-click', () => restoreWindow()); tray.on('double-click', () => restoreWindow());
tray.on('click', () => restoreWindow()); tray.on('click', () => restoreWindow());
@ -175,6 +179,16 @@ function setThumbarButtons() {
]); ]);
} }
//_ button in ui
ipcMain.on('minimize', () => {
win.minimize();
});
//X button in ui
ipcMain.on('close', () => {
win.close();
});
ipcMain.on('openUrl', (event, args) => { ipcMain.on('openUrl', (event, args) => {
shell.openExternal(args); shell.openExternal(args);
}); });

File diff suppressed because it is too large Load Diff

View File

@ -10,28 +10,28 @@
"watch": "vue-cli-service build --watch" "watch": "vue-cli-service build --watch"
}, },
"dependencies": { "dependencies": {
"@mdi/font": "^5.5.55", "@mdi/font": "^5.8.55",
"axios": "^0.19.2", "axios": "^0.19.2",
"roboto-fontface": "*", "roboto-fontface": "*",
"vue": "^2.6.11", "vue": "^2.6.12",
"vue-esc": "^3.0.1", "vue-esc": "^3.0.1",
"vue-i18n": "^8.17.3", "vue-i18n": "^8.17.3",
"vue-router": "^3.2.0", "vue-router": "^3.4.9",
"vue-socket.io": "^3.0.10", "vue-socket.io": "^3.0.10",
"vuetify": "^2.2.11" "vuetify": "^2.3.16"
}, },
"devDependencies": { "devDependencies": {
"@intlify/vue-i18n-loader": "^1.0.0", "@intlify/vue-i18n-loader": "^1.0.0",
"@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-eslint": "^4.5.8",
"@vue/cli-plugin-router": "~4.5.0", "@vue/cli-plugin-router": "^4.5.8",
"@vue/cli-service": "~4.5.0", "@vue/cli-service": "^4.5.8",
"eslint": "^6.7.2", "eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2", "eslint-plugin-vue": "^6.2.2",
"sass": "^1.19.0", "sass": "^1.29.0",
"sass-loader": "^8.0.0", "sass-loader": "^8.0.0",
"vue-cli-plugin-i18n": "~1.0.1", "vue-cli-plugin-i18n": "~1.0.1",
"vue-cli-plugin-vuetify": "~2.0.7", "vue-cli-plugin-vuetify": "~2.0.7",
"vue-template-compiler": "^2.6.11", "vue-template-compiler": "^2.6.12",
"vuetify-loader": "^1.3.0" "vuetify-loader": "^1.3.0"
}, },
"eslintConfig": { "eslintConfig": {

View File

@ -1,6 +1,21 @@
<template> <template>
<div>
<v-app v-esc='closePlayer'> <v-app v-esc='closePlayer'>
<v-system-bar
:color='$root.settings.lightTheme ? "#f5f5f5" : "#121212"'
app
class='topbar'
v-if='$root.settings.electron'
height='28'>
<v-spacer></v-spacer>
<span>Freezer <span v-if='version'>v{{version}}</span></span>
<v-spacer></v-spacer>
<v-icon class='topbarbutton mx-2' @click='minimize'>mdi-window-minimize</v-icon>
<v-icon @click='exitApp' class='topbarbutton mx-2'>mdi-close</v-icon>
</v-system-bar>
<!-- Fullscreen player overlay --> <!-- Fullscreen player overlay -->
<v-overlay :value='showPlayer' opacity='1.00' z-index="100"> <v-overlay :value='showPlayer' opacity='1.00' z-index="100">
<FullscreenPlayer @close='closePlayer' @volumeChange='volume = $root.volume'></FullscreenPlayer> <FullscreenPlayer @close='closePlayer' @volumeChange='volume = $root.volume'></FullscreenPlayer>
@ -263,6 +278,7 @@
</v-snackbar> </v-snackbar>
</v-app> </v-app>
</div>
</template> </template>
<style lang='scss'> <style lang='scss'>
@ -278,6 +294,13 @@
.seekbar .v-progress-linear__determinate { .seekbar .v-progress-linear__determinate {
transition: none !important; transition: none !important;
} }
.topbar {
-webkit-app-region: drag;
z-index: 6969;
}
.topbarbutton {
-webkit-app-region: no-drag;
}
</style> </style>
<script> <script>
@ -299,8 +322,8 @@ export default {
suggestions: [], suggestions: [],
preventDoubleEnter: false, preventDoubleEnter: false,
cancelSuggestions: false, cancelSuggestions: false,
globalSnackbar: false,
globalSnackbar: false version: null,
} }
}, },
methods: { methods: {
@ -375,6 +398,16 @@ export default {
}, },
seek(val) { seek(val) {
this.$root.seek(Math.round((val / 100) * this.$root.duration())); this.$root.seek(Math.round((val / 100) * this.$root.duration()));
},
async exitApp() {
await this.$root.saveSettings();
await this.$root.savePlaybackInfo();
const {ipcRenderer} = window.require('electron');
ipcRenderer.send('close');
},
minimize() {
const {ipcRenderer} = window.require('electron');
ipcRenderer.send('minimize');
} }
}, },
computed: { computed: {
@ -419,6 +452,10 @@ export default {
if (!this.$root.authorized) { if (!this.$root.authorized) {
this.$router.push('/login'); this.$router.push('/login');
} }
this.$axios.get('/about').then((res) => {
this.version = res.data.version;
});
}, },
watch: { watch: {
volume() { volume() {

View File

@ -127,6 +127,6 @@
"Removed from library!": "Dihapus dari koleksi!", "Removed from library!": "Dihapus dari koleksi!",
"Removed from playlist!": "Dihapus dari daftar putar!", "Removed from playlist!": "Dihapus dari daftar putar!",
"Playlist deleted!": "Daftar putar dihapus!", "Playlist deleted!": "Daftar putar dihapus!",
"Delete": "Delete", "Delete": "Hapus",
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?" "Are you sure you want to delete this playlist?": "Apakah kamu yakin ingin menghapus daftar putar ini?"
} }

View File

@ -8,18 +8,18 @@
"Artists": "Umelci", "Artists": "Umelci",
"More": "Viac", "More": "Viac",
"Settings": "Nastavenia", "Settings": "Nastavenia",
"Downloads": "K stiahnutiu", "Downloads": "Na stiahnutie",
"Search or paste Deezer URL. Use / to quickly focus.": "Vyhľadať alebo vložiť Deezer URL. Použite \"/\" pre rýchly náhľad.", "Search or paste Deezer URL. Use / to quickly focus.": "Vyhľadať alebo vložiť Deezer URL. Použite \"/\" pre rýchly náhľad.",
"Play": "Prehrať", "Play": "Prehrať",
"Add to library": "Pridať do knižnice", "Add to library": "Pridať do knižnice",
"Download": "Stiahnuť", "Download": "Stiahnuť",
"fans": "fanúšikovia", "fans": "fanúšikov",
"tracks": "skladby", "tracks": "skladieb",
"Quality": "Kvalita", "Quality": "Kvalita",
"Estimated size:": "Odhadovaná veľkosť:", "Estimated size:": "Odhadovaná veľkosť:",
"Start downloading": "Začať sťahovať", "Start downloading": "Začať sťahovať",
"Cancel": "Zrušiť", "Cancel": "Zrušiť",
"Stream logging is disabled!": "Zaznamenávanie streamu je zakázané!", "Stream logging is disabled!": "Zaznamenávanie histórie pre Deezer je zakázané!",
"Enable it in settings for history to work properly.": "Povoliť v nastaveniach pre správne fungovanie histórie.", "Enable it in settings for history to work properly.": "Povoliť v nastaveniach pre správne fungovanie histórie.",
"History": "História", "History": "História",
"Create new playlist": "Vytvoriť nový playlist", "Create new playlist": "Vytvoriť nový playlist",
@ -35,7 +35,7 @@
"Add to playlist": "Pridať do playlistu", "Add to playlist": "Pridať do playlistu",
"Create new": "Vytvoriť nový", "Create new": "Vytvoriť nový",
"Remove": "Odstrániť", "Remove": "Odstrániť",
"Play next": "Prehrať ďalšie", "Play next": "Prehrať ako ďalšie",
"Add to queue": "Pridať do poradia", "Add to queue": "Pridať do poradia",
"Remove from library": "Odstrániť z knižnice", "Remove from library": "Odstrániť z knižnice",
"Remove from playlist": "Odstrániť z playlistu", "Remove from playlist": "Odstrániť z playlistu",
@ -59,11 +59,11 @@
"Show folder": "Zobraziť priečinok", "Show folder": "Zobraziť priečinok",
"Clear queue": "Vyčistiť poradie", "Clear queue": "Vyčistiť poradie",
"Playing from": "Prehráva sa", "Playing from": "Prehráva sa",
"Info": "Info", "Info": "Informácie",
"Lyrics": "Texty", "Lyrics": "Texty",
"Track number": "Číslo skladby", "Track number": "Číslo skladby",
"Disk number": "Číslo disku", "Disk number": "Číslo disku",
"Explicit": "Výslovné", "Explicit": "Pre dospelých",
"Source": "Zdroj", "Source": "Zdroj",
"ID": "ID", "ID": "ID",
"Error logging in!": "Chyba prihlásenia!", "Error logging in!": "Chyba prihlásenia!",
@ -93,8 +93,8 @@
"UI": "Používateľské rozhranie", "UI": "Používateľské rozhranie",
"Show autocomplete in search": "Automatické dopĺňanie pri vyhľadávaní", "Show autocomplete in search": "Automatické dopĺňanie pri vyhľadávaní",
"Integrations": "Integrácia", "Integrations": "Integrácia",
"This allows listening history, flow and recommendations to work properly.": "Umožňuje správne fungovanie histórie, flow a odporúčaní počúvania.", "This allows listening history, flow and recommendations to work properly.": "Umožňuje správne fungovanie histórie, flow a odporúčaných skladieb.",
"Log track listens to Deezer": "Zaznamenávia počúvania pre Deezer", "Log track listens to Deezer": "Zaznamenávanie histórie pre Deezer",
"Connect your LastFM account to allow scrobbling.": "Pripojte sa na váš LastFM účet pre použitie scrobblingu.", "Connect your LastFM account to allow scrobbling.": "Pripojte sa na váš LastFM účet pre použitie scrobblingu.",
"Login with LastFM": "Prihlásiť s LastFM", "Login with LastFM": "Prihlásiť s LastFM",
"Disconnect LastFM": "Odpojiť od LastFM", "Disconnect LastFM": "Odpojiť od LastFM",
@ -128,5 +128,5 @@
"Removed from playlist!": "Odstránené z playlistu!", "Removed from playlist!": "Odstránené z playlistu!",
"Playlist deleted!": "Playlist odstránený!", "Playlist deleted!": "Playlist odstránený!",
"Delete": "Odstrániť", "Delete": "Odstrániť",
"Are you sure you want to delete this playlist?": "Naozaj chcete odstrániť tento zoznam skladieb?" "Are you sure you want to delete this playlist?": "Naozaj chcete odstrániť tento playlist?"
} }

View File

@ -127,6 +127,6 @@
"Removed from library!": "Видалено з бібліотеки!", "Removed from library!": "Видалено з бібліотеки!",
"Removed from playlist!": "Видалено з плейлиста!", "Removed from playlist!": "Видалено з плейлиста!",
"Playlist deleted!": "Плейлист видалено!", "Playlist deleted!": "Плейлист видалено!",
"Delete": "Delete", "Delete": "Видалити",
"Are you sure you want to delete this playlist?": "Are you sure you want to delete this playlist?" "Are you sure you want to delete this playlist?": "Ви впевнені, що хочете видалити цей плейлист?"
} }

View File

@ -91,7 +91,6 @@ new Vue({
//Repeat & Shuffle //Repeat & Shuffle
//0 - normal, 1 - repeat list, 2 - repeat track //0 - normal, 1 - repeat list, 2 - repeat track
repeat: 0, repeat: 0,
shuffle: false,
//Library cache //Library cache
libraryTracks: [], libraryTracks: [],
@ -137,6 +136,7 @@ new Vue({
if (!this.audio || isNaN(t) || !t) return; if (!this.audio || isNaN(t) || !t) return;
//ms -> s //ms -> s
this.audio.currentTime = (t / 1000); this.audio.currentTime = (t / 1000);
this.position = t;
this.updateState(); this.updateState();
}, },
@ -174,12 +174,6 @@ new Vue({
}, },
//Skip wrapper with shuffle //Skip wrapper with shuffle
skipNext() { skipNext() {
if (this.shuffle) {
let index = Math.round(Math.random()*this.queue.data.length) - this.queue.index;
this.skip(index);
this.savePlaybackInfo();
return;
}
this.skip(1); this.skip(1);
this.savePlaybackInfo(); this.savePlaybackInfo();
}, },
@ -265,6 +259,7 @@ new Vue({
oldAudio.pause(); oldAudio.pause();
this.resetGapless(); this.resetGapless();
this.updateState();
//Save //Save
await this.savePlaybackInfo(); await this.savePlaybackInfo();
@ -285,14 +280,7 @@ new Vue({
if (this.repeat == 2) { if (this.repeat == 2) {
this.seek(0); this.seek(0);
this.audio.play(); this.audio.play();
return; this.updateState();
}
//Shuffle
if (this.shuffle) {
let index = Math.round(Math.random()*this.queue.data.length) - this.queue.index;
this.skip(index);
this.savePlaybackInfo();
return; return;
} }
@ -302,26 +290,6 @@ new Vue({
return; return;
} }
//Load gapless
if (this.gapless.promise || this.gapless.audio) {
this.state = 3;
if (this.gapless.promise) await this.gapless.promise;
this.audio = this.gapless.audio;
this.playbackInfo = this.gapless.info;
this.track = this.gapless.track;
this.queue.index++;
this.resetGapless();
this.configureAudio();
//Play
this.state = 2;
this.audio.play();
this.updateMediaSession();
await this.savePlaybackInfo();
return;
}
//End of queue //End of queue
if (this.queue.index+1 == this.queue.data.length) { if (this.queue.index+1 == this.queue.data.length) {
this.state = 1; this.state = 1;
@ -393,23 +361,16 @@ new Vue({
async loadGapless() { async loadGapless() {
if (this.loaders != 0 || this.gapless.promise || this.gapless.audio) return; if (this.loaders != 0 || this.gapless.promise || this.gapless.audio) return;
//Shuffle //Repeat list
if (this.shuffle) { if (this.repeat == 1 && this.queue.index == this.queue.data.length - 1) {
let index = Math.round(Math.random()*this.queue.data.length) - this.queue.index; this.gapless.track = this.queue.data[0];
this.gapless.track = this.queue.data[index]; this.gapless.index = 0;
this.gapless.index = index;
} else { } else {
//Repeat list //Last song
if (this.repeat == 1 && this.queue.index == this.queue.data.length - 1) { if (this.queue.index+1 >= this.queue.data.length) return;
this.gapless.track = this.queue.data[0]; //Next song
this.gapless.index = 0; this.gapless.track = this.queue.data[this.queue.index + 1];
} else { this.gapless.index = this.queue.index + 1;
//Last song
if (this.queue.index+1 >= this.queue.data.length) return;
//Next song
this.gapless.track = this.queue.data[this.queue.index + 1];
this.gapless.index = this.queue.index + 1;
}
} }
//Save promise //Save promise
@ -458,7 +419,6 @@ new Vue({
queue: this.queue, queue: this.queue,
position: this.position, position: this.position,
track: this.track, track: this.track,
shuffle: this.shuffle,
repeat: this.repeat repeat: this.repeat
} }
await this.$axios.post('/playback', data); await this.$axios.post('/playback', data);
@ -538,7 +498,6 @@ new Vue({
if (pd.data != {}) { if (pd.data != {}) {
if (pd.data.queue) this.queue = pd.data.queue; if (pd.data.queue) this.queue = pd.data.queue;
if (pd.data.track) this.track = pd.data.track; if (pd.data.track) this.track = pd.data.track;
if (pd.data.shuffle) this.shuffle = pd.data.shuffle;
if (pd.data.repeat) this.repeat = pd.data.repeat; if (pd.data.repeat) this.repeat = pd.data.repeat;
this.playTrack(this.track).then(() => { this.playTrack(this.track).then(() => {
this.seek(pd.data.position); this.seek(pd.data.position);

View File

@ -1,5 +1,5 @@
<template> <template>
<div class='main pa-0'> <div class='pa-0' :class='{electron: $root.settings.electron, notop: !$root.settings.electron}'>
<v-app-bar dense> <v-app-bar dense>
<v-btn icon @click='close'> <v-btn icon @click='close'>
@ -77,9 +77,8 @@
<v-icon color='primary' v-if='$root.repeat == 1'>mdi-repeat</v-icon> <v-icon color='primary' v-if='$root.repeat == 1'>mdi-repeat</v-icon>
<v-icon color='primary' v-if='$root.repeat == 2'>mdi-repeat-once</v-icon> <v-icon color='primary' v-if='$root.repeat == 2'>mdi-repeat-once</v-icon>
</v-btn> </v-btn>
<v-btn icon @click='$root.shuffle = !$root.shuffle'> <v-btn icon @click='shuffle'>
<v-icon v-if='!$root.shuffle'>mdi-shuffle</v-icon> <v-icon v-if='!$root.shuffle'>mdi-shuffle</v-icon>
<v-icon v-if='$root.shuffle' color='primary'>mdi-shuffle</v-icon>
</v-btn> </v-btn>
<v-btn icon @click='addLibrary'> <v-btn icon @click='addLibrary'>
@ -205,9 +204,18 @@
<style scoped> <style scoped>
.main { .main {
width: 100vw; width: 100vw;
}
.notop {
height: 100vh; height: 100vh;
} }
.electron {
height: calc(100vh - 28px);
margin-top: 28px;
}
@media screen and (max-height: 864px) { @media screen and (max-height: 864px) {
.imagescale { .imagescale {
max-height: 50vh; max-height: 50vh;
@ -294,6 +302,15 @@ export default {
return; return;
} }
this.$root.repeat += 1; this.$root.repeat += 1;
},
shuffle() {
//Shuffle
for (let i=this.$root.queue.data.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[this.$root.queue.data[i], this.$root.queue.data[j]] = [this.$root.queue.data[j], this.$root.queue.data[i]];
}
//Update index
this.$root.queue.index = this.$root.queue.data.findIndex(t => t.id == this.$root.track.id);
} }
}, },
mounted() { mounted() {

View File

@ -1,7 +1,7 @@
{ {
"name": "freezer", "name": "freezer",
"private": true, "private": true,
"version": "1.1.4", "version": "1.1.5",
"description": "", "description": "",
"main": "background.js", "main": "background.js",
"scripts": { "scripts": {

View File

@ -1,7 +1,7 @@
{ {
"name": "freezer", "name": "freezer",
"private": true, "private": true,
"version": "1.1.4", "version": "1.1.5",
"description": "", "description": "",
"scripts": { "scripts": {
"pack": "electron-builder --dir", "pack": "electron-builder --dir",