Commit a2a1e3e8 authored by Andreas Heimann's avatar Andreas Heimann

Translation pass, Clear Cache

parent e8f82ad7
......@@ -6838,6 +6838,11 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"gar": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/gar/-/gar-1.0.4.tgz",
"integrity": "sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w=="
},
"gaze": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
......@@ -6859,6 +6864,15 @@
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"get-folder-size": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-2.0.1.tgz",
"integrity": "sha512-+CEb+GDCM7tkOS2wdMKTn9vU7DgnKUTuDlehkNJKNSovdCOVxs14OfKCk4cvSaR3za4gj+OBdl9opPN9xrJ0zA==",
"requires": {
"gar": "^1.0.4",
"tiny-each-async": "2.0.3"
}
},
"get-stdin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
......@@ -12573,6 +12587,11 @@
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
"dev": true
},
"tiny-each-async": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tiny-each-async/-/tiny-each-async-2.0.3.tgz",
"integrity": "sha1-jru/1tYpXxNwAD+7NxYq/loKUdE="
},
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
......
<template>
<aside>
<nav class="items-left">
<div class="item" v-tooltip.down="'Back'" v-on:click="navigateBack()"><i class="mdi mdi-arrow-left"></i></div>
<div class="item" v-tooltip.down="$t('navigation.back')" v-on:click="navigateBack()"><i class="mdi mdi-arrow-left"></i></div>
<div class="logo">
<router-link to="/startup"><img src="https://spinsha.re/assets/img/logo_colored_ondark.svg" alt="SpinShare Logo" /></router-link>
</div>
<router-link to="/startup" exact class="item" v-tooltip.down="'Frontpage'"><i class="mdi mdi-home-outline"></i></router-link>
<router-link to="/search" class="item" v-tooltip.down="'Search'"><i class="mdi mdi-magnify"></i></router-link>
<router-link to="/library" class="item" v-tooltip.down="'Library'"><i class="mdi mdi-music-box-multiple-outline"></i></router-link>
<div v-on:click="openExternal('https://spinsha.re/support');" class="item" v-tooltip.down="'Support'"><i class="mdi mdi-hand-heart"></i></div>
<router-link to="/startup" exact class="item" v-tooltip.down="$t('navigation.dashboard')"><i class="mdi mdi-home-outline"></i></router-link>
<router-link to="/search" class="item" v-tooltip.down="$t('navigation.search')"><i class="mdi mdi-magnify"></i></router-link>
<router-link to="/library" class="item" v-tooltip.down="$t('navigation.library')"><i class="mdi mdi-music-box-multiple-outline"></i></router-link>
<div v-on:click="openExternal('https://spinsha.re/support');" class="item" v-tooltip.down="$t('navigation.support')"><i class="mdi mdi-hand-heart"></i></div>
</nav>
<nav class="items-right">
<div v-on:click="openExternal('steam://run/1058830');" class="item" v-tooltip.down="'Start SpinRhythm XD'"><i class="mdi mdi-play-outline"></i></div>
<div v-on:click="showDownloadOverlay();" :class="'item ' + (downloadOverlayShown ? 'router-link-active' : '')" v-tooltip.down="'Download Queue'">
<div v-on:click="openExternal('steam://run/1058830');" class="item" v-tooltip.down="$t('navigation.startspinrhythm')"><i class="mdi mdi-play-outline"></i></div>
<div v-on:click="showDownloadOverlay();" :class="'item ' + (downloadOverlayShown ? 'router-link-active' : '')" v-tooltip.down="$t('navigation.downloadqueue')">
<i class="mdi mdi-download-outline"></i>
<span class="indicator" v-show="downloadQueueCount > 0">{{ downloadQueueCount }}</span>
</div>
......@@ -22,33 +22,33 @@
<div class="user-actions">
<router-link :to="{ name: 'UserDetailCharts', params: { id: userData.id } }" class="user-action-item">
<i class="mdi mdi-music"></i>
<span>My Charts</span>
<span>{{ $t('navigation.mycharts') }}</span>
</router-link>
<router-link :to="{ name: 'UserDetailReviews', params: { id: userData.id } }" class="user-action-item">
<router-link :to="{ name: 'UserDetailPlaylists', params: { id: userData.id } }" class="user-action-item">
<i class="mdi mdi-playlist-music"></i>
<span>My Playlists</span>
<span>{{ $t('navigation.myplaylists') }}</span>
</router-link>
<router-link :to="{ name: 'UserDetailSpinPlays', params: { id: userData.id } }" class="user-action-item">
<router-link :to="{ name: 'UserDetailReviews', params: { id: userData.id } }" class="user-action-item">
<i class="mdi mdi-thumbs-up-down"></i>
<span>My Reviews</span>
<span>{{ $t('navigation.myreviews') }}</span>
</router-link>
<router-link :to="{ name: 'UserDetailSpinPlays', params: { id: userData.id } }" class="user-action-item">
<i class="mdi mdi-youtube"></i>
<span>My SpinPlays</span>
<span>{{ $t('navigation.myspinplays') }}</span>
</router-link>
<div class="user-action-spacer"></div>
<router-link to="/settings" class="user-action-item">
<i class="mdi mdi-cog"></i>
<span>App-Settings</span>
<span>{{ $t('navigation.appsettings') }}</span>
</router-link>
<div v-on:click="openExternal('https://spinsha.re/settings')" class="user-action-item">
<i class="mdi mdi-cog"></i>
<span>Account-Settings</span>
<span>{{ $t('navigation.accountsettings') }}</span>
</div>
<div class="user-action-spacer"></div>
<div v-on:click="userLogout()" class="user-action-item">
<i class="mdi mdi-close-circle-outline"></i>
<span>Logout</span>
<span>{{ $t('navigation.logout') }}</span>
</div>
</div>
</div>
......
<template>
<div class="song-item" v-on:auxclick="shortDownload($event)" v-on:contextmenu="showContextMenu($event)">
<router-link :to="{ name: 'SongDetail', params: { id: id } }">
<div class="song-cover" :style="'background-image: url(' + cover + '), url(' + require('@/assets/img/defaultAlbumArt.jpg') + ');'">
<div class="song-charter-info">
<div class="song-charter"><i class="mdi mdi-account-circle"></i><span>{{ charter }}</span></div>
</div>
<router-link :to="{ name: 'PlaylistDetail', params: { id: id } }" class="playlist-item":style="'background-image: url(' + cover + ');'" v-on:contextmenu="showContextMenu($event)">
<div class="shade" v-if="!isOfficial">
<div class="content">
<div class="title">{{ title }}<span class="official-badge" v-if="isOfficial">OFFICIAL</span></div>
<div class="quickinfo">{{ songs.length }} Charts</div>
</div>
<div class="song-metadata">
<div class="song-title">{{ title }}</div>
<div class="song-artist">{{ artist }}</div>
<div class="song-difficulties">
<div :class="hasEasyDifficulty ? 'difficulty active' : 'difficulty'"><span>E</span></div>
<div :class="hasNormalDifficulty ? 'difficulty active' : 'difficulty'"><span>N</span></div>
<div :class="hasHardDifficulty ? 'difficulty active' : 'difficulty'"><span>H</span></div>
<div :class="hasExtremeDifficulty ? 'difficulty active' : 'difficulty'"><span>EX</span></div>
<div :class="hasXDDifficulty ? 'difficulty active' : 'difficulty'"><span>XD</span></div>
</div>
</div>
</router-link>
</div>
</div>
</router-link>
</template>
<script>
......@@ -31,15 +19,8 @@ export default {
'id',
'cover',
'title',
'subtitle',
'artist',
'charter',
'hasEasyDifficulty',
'hasNormalDifficulty',
'hasHardDifficulty',
'hasExtremeDifficulty',
'hasXDDifficulty',
'zip'
'isOfficial',
'songs'
],
data: function() {
return {
......@@ -59,9 +40,8 @@ export default {
y: e.pageY,
items: [
{ icon: "eye", title: this.$t('contextmenu.open'), method: () => { this.$router.push({ name: 'SongDetail', params: { id: this.$props.id } }); } },
{ icon: "earth", title: this.$t('contextmenu.openOnSpinShare'), method: () => { shell.openExternal("https://spinsha.re/song/" + this.$props.id); } },
{ icon: "link", title: this.$t('contextmenu.copyLink'), method: () => { clipboard.writeText('https://spinsha.re/playlist/' + this.$props.id); } },
{ icon: "download", title: this.$t('contextmenu.download'), method: () => { this.download(); } }
{ icon: "earth", title: this.$t('contextmenu.openOnSpinShare'), method: () => { shell.openExternal("https://spinsha.re/playlist/" + this.$props.id); } },
{ icon: "link", title: this.$t('contextmenu.copyLink'), method: () => { clipboard.writeText('https://spinsha.re/playlist/' + this.$props.id); } }
]});
}
}
......@@ -69,4 +49,62 @@ export default {
</script>
<style scoped lang="less">
.playlist-item {
height: 200px;
background: rgba(255,255,255,0.1);
background-position: center;
background-size: cover;
border-radius: 6px;
color: #fff;
text-decoration: none;
transition: 0.2s ease all;
& .shade {
width: 100%;
height: 100%;
background: rgba(0,0,0, 0.4);
transition: 0.2s ease all;
display: flex;
justify-content: center;
align-items: center;
& .content {
text-align: center;
text-shadow: 0 4px 18px rgba(0, 0, 0, 0.6);
& .title {
font-size: 32px;
margin-bottom: 5px;
font-family: 'Oswald', sans-serif;
& .official-badge {
display: inline-block;
font-family: 'Open Sans', sans-serif;
font-weight: bold;
font-size: 10px;
padding: 2px 8px;
border-radius: 4px;
background: #fff;
color: #000;
text-shadow: 0px 0px 0px transparent;
margin-left: 10px;
transform: translateY(-8px);
}
}
& .quickinfo {
font-size: 18px;
opacity: 0.6;
}
}
}
&:hover {
cursor: pointer;
box-shadow: 0px 4px 20px 5px rgba(0, 0, 0, 0.4);
& .shade {
opacity: 0;
}
}
}
</style>
<template>
<div class="playlist-row">
<div class="playlist-list">
<slot name="playlist-list"></slot>
</div>
</div>
</template>
<script>
export default {
name: 'PlaylistRow'
}
</script>
<style scoped lang="less">
.playlist-row {
display: grid;
grid-template-rows: auto 1fr;
grid-gap: 5px;
& .playlist-list {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 15px;
}
}
</style>
<template>
<div class="song-row">
<div class="song-list" v-if="!playlist">
<div class="song-list" v-if="playlist != 'true'">
<slot name="song-list"></slot>
</div>
<div class="song-list-playlist" v-if="playlist">
<div class="song-list-playlist" v-if="playlist == 'true'">
<slot name="song-list"></slot>
</div>
<div class="noresults">
......
......@@ -2,11 +2,30 @@
"locale.translatedBy": "Übersetzung von thatanimeweirdo",
"locale.dateFormat": "DD.MM.YYYY",
"navigation.back": "Zurück",
"navigation.dashboard": "Dashboard",
"navigation.search": "Suche",
"navigation.library": "Sammlung",
"navigation.support": "Support",
"navigation.startspinrhythm": "SpinRhythm XD starten",
"navigation.downloadqueue": "Download Warteschlange",
"navigation.mycharts": "Meine Charts",
"navigation.myplaylists": "Meine Playlisten",
"navigation.myreviews": "Meine Reviews",
"navigation.myspinplays": "Meine SpinPlays",
"navigation.appsettings": "App-Einstellungen",
"navigation.accountsettings": "Account-Einstellungen",
"navigation.logout": "Logout",
"login.explaination": "Um den SpinShare Client nutzen zu können, benötigst du ein aktives SpinShare Nutzerprofil. Gebe deinen Connect-Code ein, um dich einzuloggen. Diesen findest du auf spinsha.re in den Einstellungen unter dem \"Connect\" Tab.",
"login.error.code": "Der ConnectCode ist falsch oder nicht mehr gültig. Versuche es erneut!",
"login.error.server": "Die SpinShare-Server können nicht erreicht werden. Bitte versuche es später erneut!",
"login.action.connect": "Verbinden",
"startup.staffpromo.action": "CHECK ES AUS",
"startup.tabs.frontpage": "Startseite",
"startup.tabs.new": "Neu",
"startup.tabs.hot": "Heiß",
"startup.tabs.popular": "Populär",
"search.header": "Suche",
"search.input.placeholder": "Suche nach Songs, Tags & Profilen...",
......@@ -48,10 +67,21 @@
"songdetail.spinplays.noresults.explaination": "Komm doch später zurück, oder sende ein neues ein!",
"songdetail.playmodal.title": "Wähle eine Schwierigkeit",
"songdetail.playmodal.actions.close": "Lieber doch nicht",
"userdetail.uploaded.header": "Hochgeladene Songs",
"songdetail.stats.uploadDate": "Hochgeladen am",
"songdetail.stats.views": "Aufrufe",
"songdetail.stats.downloads": "Downloads",
"playlistdetail.header.official": "OFFIZIELL",
"playlistdetail.header.charts": "{amountOfCharts} Charts",
"playlistdetail.detail.createdby": "Erstellt von",
"playlistdetail.detail.withchartsby": "Mit Charts von",
"playlistdetail.list.noresults": "Diese Playlist ist leer.",
"userdetail.tabs.charts": "Charts ({charts})",
"userdetail.tabs.playlists": "Playlisten ({playlists})",
"userdetail.tabs.reviews": "Reviews ({reviews})",
"userdetail.tabs.spinplays": "SpinPlays ({spinplays})",
"userdetail.uploaded.noresults": "Dieser Nutzer hat noch keine Songs hochgeladen.",
"userdetail.actions.reportButton": "Melden",
"userdetail.charts.noresults": "Dieser Nutzer hat noch keine Songs.",
"userdetail.reviews.noresults": "Dieser Nutzer hat noch keine Reviews.",
"userdetail.spinplays.noresults": "Dieser Nutzer hat noch keine SpinPlays hochgeladen.",
......@@ -66,6 +96,8 @@
"settings.general.gameDirectory.label": "Spiel-Ordner",
"settings.general.gameDirectory.changeButton": "Ändern",
"settings.general.gameDirectory.resetButton": "Zurücksetzen",
"settings.general.clientcache.label": "Client Cache",
"settings.general.clientcache.clearButton": "Leeren",
"settings.general.silentQueue.label": "Downloadliste verstecken",
"settings.general.silentQueue.explaination": "Wenn aktiviert, wird die Downloadliste nicht mehr angezeigt, solltest du einen Song hinzufügen.",
......@@ -73,15 +105,9 @@
"connectionerror.server.text": "Bitte überprüfe deine Internetverbindung oder versuche es später erneut. Du kannst weiterhin deine Audiothek nutzen und lokale .zip Backups installieren.",
"connectionerror.notfound.title": "404 - Nicht gefunden",
"connectionerror.notfound.text": "Entschuldigung, das konnten wir nicht finden. Es wurde entweder gelöscht oder war ohnehin nie verfügbar.",
"connectionerror.tryagain": "Erneut versuchen",
"download.queue.header": "Download Warteschlange",
"download.status.downloading": "Herunterladen",
"download.status.extracting": "Auspacken",
"download.status.extractingFailed": "Konnte den Song nicht auspacken!",
"download.status.installing": "Installieren",
"download.status.installingFailed": "Konnte den Song nicht installieren!",
"download.status.done": "Fertig",
"download.closeButton": "Schließen",
"update.availableText": "Ein Update ist verfügbar.",
"update.latestText": "Du hast bereits die neueste Version.",
......@@ -101,6 +127,9 @@
"contextmenu.open": "Öffnen",
"contextmenu.openInExplorer": "Im Explorer öffnen",
"contextmenu.openOnSpinShare": "Auf SpinShare öffnen",
"contextmenu.preview.start": "Vorschau starten",
"contextmenu.preview.stop": "Vorschau beenden",
"contextmenu.report": "Melden",
"songrow.navigation.previous": "VORHERIGE",
"songrow.navigation.next": "NÄCHSTE"
......
......@@ -2,10 +2,29 @@
"locale.translatedBy": " ",
"locale.dateFormat": "MM/DD/YYYY",
"navigation.back": "Back",
"navigation.dashboard": "Dashboard",
"navigation.search": "Search",
"navigation.library": "Library",
"navigation.support": "Support",
"navigation.startspinrhythm": "Start SpinRhythm XD",
"navigation.downloadqueue": "Download Queue",
"navigation.mycharts": "My Charts",
"navigation.myplaylists": "My Playlists",
"navigation.myreviews": "My Reviews",
"navigation.myspinplays": "My SpinPlays",
"navigation.appsettings": "App-Settings",
"navigation.accountsettings": "Account-Settings",
"navigation.logout": "Logout",
"login.explaination": "To use the SpinShare client, you need an active SpinShare user profile. Insert your connect code to log into your account. You can find your connect code in your account settings under the \"Connect\" tab.",
"login.error.code": "The connect code is wrong or expired. Please try again!",
"login.error.server": "Couldn't reach the SpinShare server. Please try again later!",
"login.action.connect": "Connect",
"startup.tabs.frontpage": "Frontpage",
"startup.tabs.new": "New",
"startup.tabs.hot": "Hot",
"startup.tabs.popular": "Popular",
"startup.staffpromo.action": "CHECK IT OUT",
"search.header": "Search",
......@@ -48,10 +67,21 @@
"songdetail.showless": "Show less",
"songdetail.playmodal.title": "Chose a difficulty",
"songdetail.playmodal.actions.close": "Nevermind",
"userdetail.uploaded.header": "Uploaded Songs",
"songdetail.stats.uploadDate": "Upload Date",
"songdetail.stats.views": "Views",
"songdetail.stats.downloads": "Downloads",
"playlistdetail.header.official": "OFFICIAL",
"playlistdetail.header.charts": "{amountOfCharts} Charts",
"playlistdetail.detail.createdby": "Created by",
"playlistdetail.detail.withchartsby": "With Charts by",
"playlistdetail.list.noresults": "This playlist is empty.",
"userdetail.tabs.charts": "Charts ({charts})",
"userdetail.tabs.playlists": "Playlists ({playlists})",
"userdetail.tabs.reviews": "Reviews ({reviews})",
"userdetail.tabs.spinplays": "SpinPlays ({spinplays})",
"userdetail.uploaded.noresults": "This user did not upload any songs yet.",
"userdetail.actions.reportButton": "Report",
"userdetail.charts.noresults": "This user has no charts yet.",
"userdetail.reviews.noresults": "This user has no reviews yet.",
"userdetail.spinplays.noresults": "This user did not release any SpinPlays yet.",
......@@ -61,11 +91,13 @@
"settings.client.version.label": "Version",
"settings.client.update.label": "Update",
"settings.client.update.button": "Check for Updates",
"settings.general.header": "Language",
"settings.general.header": "General",
"settings.general.selectLanguage.label": "Select Language",
"settings.general.gameDirectory.label": "Game Directory",
"settings.general.gameDirectory.changeButton": "Change",
"settings.general.gameDirectory.resetButton": "Reset",
"settings.general.clientcache.label": "Client Cache",
"settings.general.clientcache.clearButton": "Clear",
"settings.general.silentQueue.label": "Silent Queue",
"settings.general.silentQueue.explaination": "The download queue will not open after adding a chart to the queue with the silent queue enabled.",
......@@ -73,15 +105,9 @@
"connectionerror.server.text": "Please check your internet connection or try again later. You can still access your library and install local .zip backups.",
"connectionerror.notfound.title": "404 - Not Found",
"connectionerror.notfound.text": "Sorry, we couldn't find that. It was either removed or never available in the first place.",
"connectionerror.tryagain": "Try again",
"download.queue.header": "Download Queue",
"download.status.downloading": "Downloading",
"download.status.extracting": "Extracting",
"download.status.extractingFailed": "Could not extract song!",
"download.status.installing": "Installing",
"download.status.installingFailed": "Could not install song!",
"download.status.done": "Done",
"download.closeButton": "Close",
"update.availableText": "An update is available.",
"update.latestText": "You already have the latest version.",
......@@ -101,6 +127,9 @@
"contextmenu.open": "Open",
"contextmenu.openInExplorer": "Open in Explorer",
"contextmenu.openOnSpinShare": "Open on SpinShare",
"contextmenu.preview.start": "Start Preview",
"contextmenu.preview.stop": "Stop Preview",
"contextmenu.report": "Report",
"songrow.navigation.previous": "PREVIOUS",
"songrow.navigation.next": "NEXT"
......
......@@ -101,6 +101,12 @@ class SSAPI {
return this.getOpenData("user/" + _userId + "/charts", true);
}
async getUserPlaylists(_userId) {
let apiPath = this.apiBase + "user/" + _userId + "/playlists";
return this.getOpenData("user/" + _userId + "/playlists", true);
}
async getUserReviews(_userId) {
let apiPath = this.apiBase + "user/" + _userId + "/reviews";
......
......@@ -16,6 +16,7 @@ import ViewUserDetail from '../views/UserDetail.vue';
import ViewUserDetailCharts from '../views/UserDetailCharts.vue';
import ViewUserDetailReviews from '../views/UserDetailReviews.vue';
import ViewUserDetailSpinPlays from '../views/UserDetailSpinPlays.vue';
import ViewUserDetailPlaylists from '../views/UserDetailPlaylists.vue';
import ViewPlaylistDetail from '../views/PlaylistDetail.vue';
import ViewSettings from '../views/Settings.vue';
import ViewTournament from '../views/Tournament.vue';
......@@ -100,6 +101,12 @@ const routes = [{
name: 'UserDetailReviews',
component: ViewUserDetailReviews
},
{
alias: '',
path: 'playlists',
name: 'UserDetailPlaylists',
component: ViewUserDetailPlaylists
},
{
alias: '',
path: 'spinplays',
......
......@@ -7,7 +7,7 @@
</div>
</header>
<div class="error-content">
<div class="button" v-on:click="retry()">Try again</div>
<div class="button" v-on:click="retry()">{{ $t('connectionerror.tryagain') }}</div>
</div>
</section>
</template>
......
......@@ -171,9 +171,6 @@
shell.openExternal(userSettings.get('gameDirectory'));
},
install: function() {
this.$parent.$parent.$emit('install');
},
getSongDetail: async function(filePath) {
let ssapi = new SSAPI();
let trackInfo = {};
......
......@@ -6,16 +6,16 @@
<div class="login-box" v-if="!hasValidToken && !apiLoginLoading">
<div class="logo"><img src="https://spinsha.re/assets/img/logo_colored_ondark.svg" alt="SpinShare Logo" /></div>
<div class="explaination">To use the SpinShare client, you need an active SpinShare user profile. Insert your connect code to log into your account. You can find your connect code in your account settings under the "Connect" tab.</div>
<div class="explaination">{{ $t('login.explaination') }}</div>
<input type="text" maxlength="6" class="connectcodeInput" placeholder="000000" v-model="connectCode" />
<div class="error" v-if="apiLoginCodeError">The connect code is wrong or expired. Please try again!</div>
<div class="error" v-if="apiLoginCodeError">{{ $t('login.error.code') }}</div>
<div class="error" v-if="apiLoginServerError">Couldn't reach the SpinShare server. Please try again later!</div>
<div class="error" v-if="apiLoginServerError">{{ $t('login.error.server') }}</div>
<div class="actions">
<button class="button" v-on:click="connect()" :disabled="!canConnect">Connect</button>
<button class="button" v-on:click="connect()" :disabled="!canConnect">{{ $t('login.action.connect') }}</button>
</div>
</div>
</section>
......@@ -58,10 +58,6 @@
}).catch(() => {
this.showLoginBox();
});
// Check if connect token is valid
// Show Login Startup if not
// Show Startup if yes
}
},
methods: {
......@@ -81,7 +77,7 @@
switch (data.status) {
case 200:
// Successfull
// Successful Token
userSettings.set("connectToken", data.data);
this.loadIntoProfile();
break;
......
......@@ -4,8 +4,8 @@
<div class="cover" :style="'background-image: url(' + cover + ');'">
<div class="shade" v-if="!isOfficial">
<div class="content">
<div class="title">{{ title }}<span class="official-badge" v-if="isOfficial">OFFICIAL</span></div>
<div class="quickinfo">{{ songs.length }} Charts</div>
<div class="title">{{ title }}<span class="official-badge" v-if="isOfficial">{{ $t('playlistdetail.header.official') }}</span></div>
<div class="quickinfo">{{ $t('playlistdetail.header.charts', {amountOfCharts: songs.length}) }}</div>
</div>
</div>
</div>
......@@ -16,12 +16,12 @@
</div>
<div class="playlist-actions">
<div class="action-row">
<div v-on:click="CopyLink()" class="action">
<div v-on:click="CopyLink()" class="action" v-tooltip.down="$t('contextmenu.copyLink')">
<div class="icon">
<i class="mdi mdi-content-copy"></i>
</div>
</div>
<div v-on:click="AddToQueue()" class="action">
<div v-on:click="AddToQueue()" class="action" v-tooltip.down="$t('contextmenu.download')">
<div class="icon">
<i class="mdi mdi-download"></i>
</div>
......@@ -29,13 +29,13 @@
</div>
</div>
<div class="playlist-uploader" v-if="!isOfficial">
<div class="label">Created by</div>
<div class="label">{{ $t('playlistdetail.detail.createdby') }}</div>
<UserItem v-bind="user" />
</div>
<div class="playlist-charters" v-if="songs.length > 0">
<div class="label">With Charts by</div>
<div class="label">{{ $t('playlistdetail.detail.withchartsby') }}</div>
<div class="charters">
charters
<router-link :to="{ name: 'Search', params: { searchQuery: charter } }" v-for="charter in charters" class="username">{{ charter }}</router-link>
</div>
</div>
</div>
......@@ -49,7 +49,7 @@
</template>
</SongRow>
<div class="list-noresults" v-if="songs.length === 0">
<div class="noresults-text">This playlist is empty.</div>
<div class="noresults-text">{{ $t('playlistdetail.list.noresults') }}</div>
</div>
</div>
</section>
......@@ -90,6 +90,7 @@ export default {
isOfficial: false,
user: null,
songs: [],
charters: []
}
},
mounted: function() {
......@@ -100,13 +101,17 @@ export default {
ssapi.getPlaylistDetail(routeID).then((data) => {
if(data.status == 200) {
this.$data.id = data.data.id;
this.$data.cover = data.data.paths.cover;
this.$data.cover = data.data.cover;
this.$data.title = data.data.title;
this.$data.description = data.data.description;
this.$data.isOfficial = data.data.isOfficial;
this.$data.user = data.data.user;
this.$data.songs = data.data.songs;
this.$data.songs.forEach((song) => {
this.$data.charters.push(song.charter);
});
this.$data.apiFinished = true;
} else {
this.$router.push({ name: 'Error', params: { errorCode: data.status } });
......@@ -271,9 +276,21 @@ export default {
&:hover {
opacity: 0.6;
}
&:not(:last-child):after {
content: ", ";
}
}
}
}
}
}
.list-noresults {
background: rgba(255,255,255,0.1);
border-radius: 6px;
padding: 25px;
opacity: 0.6;
text-align: center;
align-self: start;
}
</style>
\ No newline at end of file
......@@ -57,6 +57,14 @@
</div>
<div class="settings-hint">{{ $t('settings.general.silentQueue.explaination') }}</div>
</div>
<div class="settings-item">
<div class="settings-label">{{ $t('settings.general.clientcache.label') }}</div>
<div class="settings-input settings-input-onebutton">
<span>{{ cacheSize }} MB used.</span>
<button v-on:click="ClearCache()">{{ $t('settings.general.clientcache.clearButton') }}</button>
</div>
</div>
</div>
<!-- Botch -->
<div class="settings-box">
......@@ -75,6 +83,7 @@
<script>
import { remote } from 'electron';
const { app, dialog } = remote;
const getSize = require('get-folder-size');
import UserSettings from '@/modules/module.usersettings.js';
import SSAPI from '@/modules/module.api.js';
......@@ -87,7 +96,8 @@
environment: "",
settingLanguage: "",
settingGameDirectory: "",
settingSilentQueue: false
settingSilentQueue: false,
cacheSize: 0,
}
},
mounted: function() {
......@@ -99,6 +109,10 @@
this.$data.settingLanguage = userSettings.get('language');
this.$data.settingGameDirectory = userSettings.get('gameDirectory');
this.$data.settingSilentQueue = userSettings.get('silentQueue');
console.log(getSize(remote.app.getPath('userData') + '/Cache', (error, size) => {
this.$data.cacheSize = (size / 1000 / 1000).toFixed(2);
}));
},
methods: {
SelectGameDirectory: function() {
......@@ -140,6 +154,11 @@
this.$root.$emit('showUpdateOverlay', false);
}
});
},
ClearCache: function() {
remote.getCurrentWindow().webContents.session.clearCache(function(){
remote.getCurrentWindow().reload();
});
}
}
}
......@@ -192,6 +211,11 @@
grid-template-columns: 1fr;
grid-gap: 5px;
&.settings-input-onebutton {
grid-template-columns: 1fr auto;
align-items: center;
}
&.settings-input-twobuttons {
grid-template-columns: 1fr auto auto;
}
......
......@@ -13,23 +13,23 @@
</div>
</div>
<div :class="'song-actions ' + (previewIsPlaying ? 'player-active' : '')">
<div v-on:click="AddToQueue()" class="action" v-if="!isInstalled" v-tooltip="'Download'">
<div v-on:click="AddToQueue()" class="action" v-if="!isInstalled" v-tooltip="$t('contextmenu.download')">
<div class="icon">
<i class="mdi mdi-download"></i>
</div>
</div>
<div v-on:click="ShowPlayOverlay()" class="action" v-if="isInstalled" v-tooltip="'Play'">
<div v-on:click="ShowPlayOverlay()" class="action" v-if="isInstalled" v-tooltip="$t('contextmenu.play')">
<div class="icon">
<i class="mdi mdi-gamepad-variant"></i>
</div>
</div>
<div v-on:click="AddToQueue()" class="action" v-if="isInstalled" v-tooltip="'Redownload'">
<div v-on:click="AddToQueue()" class="action" v-if="isInstalled" v-tooltip="$t('contextmenu.download')">
<div class="icon">
<i class="mdi mdi-refresh"></i>
</div>
</div>
<div class="action-player">
<div class="icon" v-on:click="TogglePreview()" v-tooltip="previewIsPlaying ? 'Stop Preview' : 'Play Preview'">
<div class="icon" v-on:click="TogglePreview()" v-tooltip="previewIsPlaying ? $t('contextmenu.preview.stop') : $t('contextmenu.preview.start')">
<i class="mdi mdi-play" v-if="!previewIsPlaying"></i>
<i class="mdi mdi-stop" v-if="previewIsPlaying"></i>
</div>
......@@ -37,12 +37,12 @@
<input type="range" min="0" max="100" value="50" v-model="previewVolume" class="playerVolume" v-on:input="UpdateVolume()" />
</div>
</div>
<div v-on:click="CopyLink()" class="action" v-tooltip="'Copy Link'">
<div v-on:click="CopyLink()" class="action" v-tooltip="$t('contextmenu.copyLink')">
<div class="icon">
<i class="mdi mdi-content-copy"></i>
</div>
</div>
<div v-on:click="OpenReport()" class="action" v-tooltip="'Report'">
<div v-on:click="OpenReport()" class="action" v-tooltip="$t('contextmenu.report')">
<div class="icon">
<i class="mdi mdi-flag-outline"></i>
</div>
......@@ -62,7 +62,7 @@
</div>
</div>
<div class="stat" v-if="uploadDate">
<div class="icon" v-tooltip="'Upload Date'">
<div class="icon" v-tooltip="$t('songdetail.stats.uploadDate')">
<i class="mdi mdi-calendar-clock"></i>
</div>
<div class="content">
......@@ -70,7 +70,7 @@
</div>
</div>
<div class="stat">
<div class="icon" v-tooltip="'Views'">
<div class="icon" v-tooltip="$t('songdetail.stats.views')">
<i class="mdi mdi-eye"></i>
</div>
<div class="content">
......@@ -78,7 +78,7 @@
</div>
</div>
<div class="stat">
<div class="icon" v-tooltip="'Downloads'">
<div class="icon" v-tooltip="$t('songdetail.stats.downloads')">
<i class="mdi mdi-download"></i>
</div>
<div class="content">
......
......@@ -4,9 +4,9 @@
<div class="detail">
<div class="user-avatar" :style="'background-image: url(' + avatar + '), url(' + require('@/assets/img/defaultAvatar.jpg') + ');'"></div>
<div class="user-data">
<div class="user-name">{{ username }} <i class="mdi mdi-patreon" v-if="isVerified"></i></div>
<div class="user-name"><span v-if="pronouns != ''">{{ pronouns }}</span> {{ username }} <i class="mdi mdi-patreon" v-if="isVerified"></i></div>
<div class="user-actions">
<button class="button" v-on:click="OpenReport()">{{ $t('userdetail.actions.reportButton') }}</button>
<button class="button" v-on:click="OpenReport()">{{ $t('contextmenu.report') }}</button>
</div>
</div>
</div>
......@@ -16,9 +16,10 @@
</div>
<div class="tabs">
<router-link :to="{ name: 'UserDetailCharts', params: { id: id } }" class="tab" exact>Charts ({{ songs }})</router-link>
<router-link :to="{ name: 'UserDetailReviews', params: { id: id } }" class="tab" exact>Reviews ({{ reviews }})</router-link>
<router-link :to="{ name: 'UserDetailSpinPlays', params: { id: id } }" class="tab" exact>SpinPlays ({{ spinplays }})</router-link>
<router-link :to="{ name: 'UserDetailCharts', params: { id: id } }" class="tab" exact>{{ $t('userdetail.tabs.charts', {charts: songs}) }}</router-link>
<router-link :to="{ name: 'UserDetailPlaylists', params: { id: id } }" class="tab" exact>{{ $t('userdetail.tabs.playlists', {playlists: playlists}) }}</router-link>
<router-link :to="{ name: 'UserDetailReviews', params: { id: id } }" class="tab" exact>{{ $t('userdetail.tabs.reviews', {reviews: reviews}) }}</router-link>
<router-link :to="{ name: 'UserDetailSpinPlays', params: { id: id } }" class="tab" exact>{{ $t('userdetail.tabs.spinplays', {spinplays: spinplays}) }}</router-link>
</div>
</header>
......@@ -56,11 +57,13 @@
apiFinished: false,
id: 0,
username: "",
pronouns: "",
isVerified: false,
isPatreon: false,
avatar: "",
cards: [],
songs: 0,
playlists: 0,
reviews: 0,
spinplays: 0,
showCardOverlay: false,
......@@ -74,11 +77,13 @@
if(data.status == 200) {
this.$data.id = data.data.id;
this.$data.username = data.data.username;
this.$data.pronouns = data.data.pronouns;
this.$data.isVerified = data.data.isVerified;
this.$data.isPatreon = data.data.isPatreon;
this.$data.avatar = data.data.avatar;
this.$data.cards = data.data.cards;
this.$data.songs = data.data.songs;
this.$data.playlists = data.data.playlists;
this.$data.reviews = data.data.reviews;
this.$data.spinplays = data.data.spinplays;
this.$data.apiFinished = true;
......@@ -167,6 +172,18 @@
& .user-name {
font-size: 22px;
margin-bottom: 22px;
& span {
display: inline-block;
background: rgba(255,255,255,0.2);
color: #fff;
font-size: 8px;
font-weight: bold;
padding: 4px 6px;
border-radius: 2px;
transform: translateY(-3px);
margin-right: 5px;
}
}
& .user-actions {
& .button {
......
<template>
<section class="section-userdetail-playlists">
<PlaylistRow
v-if="apiFinished && playlists.length > 0">
<template v-slot:playlist-list>
<PlaylistItem
v-for="playlist in playlists"
v-bind:key="playlist.id"
v-bind="playlist" />
</template>
</PlaylistRow>
<div class="playlist-list-noresults" v-if="apiFinished && playlists.length == 0">
<div class="noresults-text">{{ this.$t('userdetail.playlists.noresults') }}</div>
</div>
<Loading v-if="!apiFinished" style="padding: 50px 0px;" />
</section>
</template>
<script>
import { remote } from 'electron';
const { clipboard, shell } = remote;
import SSAPI from '@/modules/module.api.js';
import PlaylistRow from '@/components/Playlist/PlaylistRow.vue';
import PlaylistItem from '@/components/Playlist/PlaylistItem.vue';
import Loading from '@/components/Loading.vue';
export default {
name: 'UserDetailPlaylists',
components: {
PlaylistRow,
PlaylistItem,
Loading,
},
data: function() {
return {
apiFinished: false,
playlists: [],
}
},
mounted: function() {
let ssapi = new SSAPI();
ssapi.getUserPlaylists(this.$route.params.id).then((data) => {
if(data.status == 200) {
this.$data.playlists = data.data;
this.$data.apiFinished = true;
console.log(data.data);
} else {
this.$router.push({ name: 'Error', params: { errorCode: data.status } });
}
});
},
methods: {
}
}
</script>
<style scoped lang="less">
.section-userdetail-playlists {
padding: 50px;
& .playlist-list-noresults {
display: block;
background: rgba(255,255,255,0.1);
border-radius: 6px;
padding: 25px;
opacity: 0.6;
text-align: center;
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment