Commit a2a1e3e8 authored by Andreas Heimann's avatar Andreas Heimann

Translation pass, Clear Cache

parent e8f82ad7
...@@ -6838,6 +6838,11 @@ ...@@ -6838,6 +6838,11 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true "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": { "gaze": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
...@@ -6859,6 +6864,15 @@ ...@@ -6859,6 +6864,15 @@
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true "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": { "get-stdin": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
...@@ -12573,6 +12587,11 @@ ...@@ -12573,6 +12587,11 @@
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
"dev": true "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": { "tmp": {
"version": "0.0.33", "version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
"adm-zip": "^0.4.16", "adm-zip": "^0.4.16",
"axios": "^0.19.2", "axios": "^0.19.2",
"core-js": "^3.6.4", "core-js": "^3.6.4",
"get-folder-size": "^2.0.1",
"glob": "^7.1.6", "glob": "^7.1.6",
"md5-file": "^5.0.0", "md5-file": "^5.0.0",
"moment": "^2.27.0", "moment": "^2.27.0",
......
<template> <template>
<aside> <aside>
<nav class="items-left"> <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"> <div class="logo">
<router-link to="/startup"><img src="https://spinsha.re/assets/img/logo_colored_ondark.svg" alt="SpinShare Logo" /></router-link> <router-link to="/startup"><img src="https://spinsha.re/assets/img/logo_colored_ondark.svg" alt="SpinShare Logo" /></router-link>
</div> </div>
<router-link to="/startup" exact class="item" v-tooltip.down="'Frontpage'"><i class="mdi mdi-home-outline"></i></router-link> <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="'Search'"><i class="mdi mdi-magnify"></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="'Library'"><i class="mdi mdi-music-box-multiple-outline"></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="'Support'"><i class="mdi mdi-hand-heart"></i></div> <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>
<nav class="items-right"> <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="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="'Download Queue'"> <div v-on:click="showDownloadOverlay();" :class="'item ' + (downloadOverlayShown ? 'router-link-active' : '')" v-tooltip.down="$t('navigation.downloadqueue')">
<i class="mdi mdi-download-outline"></i> <i class="mdi mdi-download-outline"></i>
<span class="indicator" v-show="downloadQueueCount > 0">{{ downloadQueueCount }}</span> <span class="indicator" v-show="downloadQueueCount > 0">{{ downloadQueueCount }}</span>
</div> </div>
...@@ -22,33 +22,33 @@ ...@@ -22,33 +22,33 @@
<div class="user-actions"> <div class="user-actions">
<router-link :to="{ name: 'UserDetailCharts', params: { id: userData.id } }" class="user-action-item"> <router-link :to="{ name: 'UserDetailCharts', params: { id: userData.id } }" class="user-action-item">
<i class="mdi mdi-music"></i> <i class="mdi mdi-music"></i>
<span>My Charts</span> <span>{{ $t('navigation.mycharts') }}</span>
</router-link> </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> <i class="mdi mdi-playlist-music"></i>
<span>My Playlists</span> <span>{{ $t('navigation.myplaylists') }}</span>
</router-link> </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> <i class="mdi mdi-thumbs-up-down"></i>
<span>My Reviews</span> <span>{{ $t('navigation.myreviews') }}</span>
</router-link> </router-link>
<router-link :to="{ name: 'UserDetailSpinPlays', params: { id: userData.id } }" class="user-action-item"> <router-link :to="{ name: 'UserDetailSpinPlays', params: { id: userData.id } }" class="user-action-item">
<i class="mdi mdi-youtube"></i> <i class="mdi mdi-youtube"></i>
<span>My SpinPlays</span> <span>{{ $t('navigation.myspinplays') }}</span>
</router-link> </router-link>
<div class="user-action-spacer"></div> <div class="user-action-spacer"></div>
<router-link to="/settings" class="user-action-item"> <router-link to="/settings" class="user-action-item">
<i class="mdi mdi-cog"></i> <i class="mdi mdi-cog"></i>
<span>App-Settings</span> <span>{{ $t('navigation.appsettings') }}</span>
</router-link> </router-link>
<div v-on:click="openExternal('https://spinsha.re/settings')" class="user-action-item"> <div v-on:click="openExternal('https://spinsha.re/settings')" class="user-action-item">
<i class="mdi mdi-cog"></i> <i class="mdi mdi-cog"></i>
<span>Account-Settings</span> <span>{{ $t('navigation.accountsettings') }}</span>
</div> </div>
<div class="user-action-spacer"></div> <div class="user-action-spacer"></div>
<div v-on:click="userLogout()" class="user-action-item"> <div v-on:click="userLogout()" class="user-action-item">
<i class="mdi mdi-close-circle-outline"></i> <i class="mdi mdi-close-circle-outline"></i>
<span>Logout</span> <span>{{ $t('navigation.logout') }}</span>
</div> </div>
</div> </div>
</div> </div>
......
<template> <template>
<div class="song-item" v-on:auxclick="shortDownload($event)" v-on:contextmenu="showContextMenu($event)"> <router-link :to="{ name: 'PlaylistDetail', params: { id: id } }" class="playlist-item":style="'background-image: url(' + cover + ');'" v-on:contextmenu="showContextMenu($event)">
<router-link :to="{ name: 'SongDetail', params: { id: id } }"> <div class="shade" v-if="!isOfficial">
<div class="song-cover" :style="'background-image: url(' + cover + '), url(' + require('@/assets/img/defaultAlbumArt.jpg') + ');'"> <div class="content">
<div class="song-charter-info"> <div class="title">{{ title }}<span class="official-badge" v-if="isOfficial">OFFICIAL</span></div>
<div class="song-charter"><i class="mdi mdi-account-circle"></i><span>{{ charter }}</span></div> <div class="quickinfo">{{ songs.length }} Charts</div>
</div>
</div> </div>
<div class="song-metadata"> </div>
<div class="song-title">{{ title }}</div> </router-link>
<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>
</template> </template>
<script> <script>
...@@ -31,15 +19,8 @@ export default { ...@@ -31,15 +19,8 @@ export default {
'id', 'id',
'cover', 'cover',
'title', 'title',
'subtitle', 'isOfficial',
'artist', 'songs'
'charter',
'hasEasyDifficulty',
'hasNormalDifficulty',
'hasHardDifficulty',
'hasExtremeDifficulty',
'hasXDDifficulty',
'zip'
], ],
data: function() { data: function() {
return { return {
...@@ -59,9 +40,8 @@ export default { ...@@ -59,9 +40,8 @@ export default {
y: e.pageY, y: e.pageY,
items: [ items: [
{ icon: "eye", title: this.$t('contextmenu.open'), method: () => { this.$router.push({ name: 'SongDetail', params: { id: this.$props.id } }); } }, { 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: "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); } }, { 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(); } }
]}); ]});
} }
} }
...@@ -69,4 +49,62 @@ export default { ...@@ -69,4 +49,62 @@ export default {
</script> </script>
<style scoped lang="less"> <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> </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> <template>
<div class="song-row"> <div class="song-row">
<div class="song-list" v-if="!playlist"> <div class="song-list" v-if="playlist != 'true'">
<slot name="song-list"></slot> <slot name="song-list"></slot>
</div> </div>
<div class="song-list-playlist" v-if="playlist"> <div class="song-list-playlist" v-if="playlist == 'true'">
<slot name="song-list"></slot> <slot name="song-list"></slot>
</div> </div>
<div class="noresults"> <div class="noresults">
......
...@@ -2,11 +2,30 @@ ...@@ -2,11 +2,30 @@
"locale.translatedBy": "Übersetzung von thatanimeweirdo", "locale.translatedBy": "Übersetzung von thatanimeweirdo",
"locale.dateFormat": "DD.MM.YYYY", "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.staffpromo.action": "CHECK ES AUS",
"startup.tabs.frontpage": "Startseite", "startup.tabs.frontpage": "Startseite",
"startup.tabs.new": "Neu", "startup.tabs.new": "Neu",
"startup.tabs.hot": "Heiß", "startup.tabs.hot": "Heiß",
"startup.tabs.popular": "Populär",
"search.header": "Suche", "search.header": "Suche",
"search.input.placeholder": "Suche nach Songs, Tags & Profilen...", "search.input.placeholder": "Suche nach Songs, Tags & Profilen...",
...@@ -48,10 +67,21 @@ ...@@ -48,10 +67,21 @@
"songdetail.spinplays.noresults.explaination": "Komm doch später zurück, oder sende ein neues ein!", "songdetail.spinplays.noresults.explaination": "Komm doch später zurück, oder sende ein neues ein!",
"songdetail.playmodal.title": "Wähle eine Schwierigkeit", "songdetail.playmodal.title": "Wähle eine Schwierigkeit",
"songdetail.playmodal.actions.close": "Lieber doch nicht", "songdetail.playmodal.actions.close": "Lieber doch nicht",
"songdetail.stats.uploadDate": "Hochgeladen am",
"userdetail.uploaded.header": "Hochgeladene Songs", "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.uploaded.noresults": "Dieser Nutzer hat noch keine Songs hochgeladen.",
"userdetail.actions.reportButton": "Melden",
"userdetail.charts.noresults": "Dieser Nutzer hat noch keine Songs.", "userdetail.charts.noresults": "Dieser Nutzer hat noch keine Songs.",
"userdetail.reviews.noresults": "Dieser Nutzer hat noch keine Reviews.", "userdetail.reviews.noresults": "Dieser Nutzer hat noch keine Reviews.",
"userdetail.spinplays.noresults": "Dieser Nutzer hat noch keine SpinPlays hochgeladen.", "userdetail.spinplays.noresults": "Dieser Nutzer hat noch keine SpinPlays hochgeladen.",
...@@ -66,6 +96,8 @@ ...@@ -66,6 +96,8 @@
"settings.general.gameDirectory.label": "Spiel-Ordner", "settings.general.gameDirectory.label": "Spiel-Ordner",
"settings.general.gameDirectory.changeButton": "Ändern", "settings.general.gameDirectory.changeButton": "Ändern",
"settings.general.gameDirectory.resetButton": "Zurücksetzen", "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.label": "Downloadliste verstecken",
"settings.general.silentQueue.explaination": "Wenn aktiviert, wird die Downloadliste nicht mehr angezeigt, solltest du einen Song hinzufügen.", "settings.general.silentQueue.explaination": "Wenn aktiviert, wird die Downloadliste nicht mehr angezeigt, solltest du einen Song hinzufügen.",
...@@ -73,15 +105,9 @@ ...@@ -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.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.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.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.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.availableText": "Ein Update ist verfügbar.",
"update.latestText": "Du hast bereits die neueste Version.", "update.latestText": "Du hast bereits die neueste Version.",
...@@ -101,6 +127,9 @@ ...@@ -101,6 +127,9 @@
"contextmenu.open": "Öffnen", "contextmenu.open": "Öffnen",
"contextmenu.openInExplorer": "Im Explorer öffnen", "contextmenu.openInExplorer": "Im Explorer öffnen",
"contextmenu.openOnSpinShare": "Auf SpinShare ö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.previous": "VORHERIGE",
"songrow.navigation.next": "NÄCHSTE" "songrow.navigation.next": "NÄCHSTE"
......
...@@ -2,10 +2,29 @@ ...@@ -2,10 +2,29 @@
"locale.translatedBy": " ", "locale.translatedBy": " ",
"locale.dateFormat": "MM/DD/YYYY", "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.frontpage": "Frontpage",
"startup.tabs.new": "New", "startup.tabs.new": "New",
"startup.tabs.hot": "Hot", "startup.tabs.hot": "Hot",
"startup.tabs.popular": "Popular",
"startup.staffpromo.action": "CHECK IT OUT", "startup.staffpromo.action": "CHECK IT OUT",
"search.header": "Search", "search.header": "Search",
...@@ -48,10 +67,21 @@ ...@@ -48,10 +67,21 @@
"songdetail.showless": "Show less", "songdetail.showless": "Show less",
"songdetail.playmodal.title": "Chose a difficulty", "songdetail.playmodal.title": "Chose a difficulty",
"songdetail.playmodal.actions.close": "Nevermind", "songdetail.playmodal.actions.close": "Nevermind",
"songdetail.stats.uploadDate": "Upload Date",
"userdetail.uploaded.header": "Uploaded Songs", "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.uploaded.noresults": "This user did not upload any songs yet.",
"userdetail.actions.reportButton": "Report",
"userdetail.charts.noresults": "This user has no charts yet.", "userdetail.charts.noresults": "This user has no charts yet.",
"userdetail.reviews.noresults": "This user has no reviews yet.", "userdetail.reviews.noresults": "This user has no reviews yet.",
"userdetail.spinplays.noresults": "This user did not release any SpinPlays yet.", "userdetail.spinplays.noresults": "This user did not release any SpinPlays yet.",
...@@ -61,11 +91,13 @@ ...@@ -61,11 +91,13 @@
"settings.client.version.label": "Version", "settings.client.version.label": "Version",
"settings.client.update.label": "Update", "settings.client.update.label": "Update",
"settings.client.update.button": "Check for Updates", "settings.client.update.button": "Check for Updates",
"settings.general.header": "Language", "settings.general.header": "General",
"settings.general.selectLanguage.label": "Select Language", "settings.general.selectLanguage.label": "Select Language",
"settings.general.gameDirectory.label": "Game Directory", "settings.general.gameDirectory.label": "Game Directory",
"settings.general.gameDirectory.changeButton": "Change", "settings.general.gameDirectory.changeButton": "Change",
"settings.general.gameDirectory.resetButton": "Reset", "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.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.", "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 @@ ...@@ -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.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.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.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.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.availableText": "An update is available.",
"update.latestText": "You already have the latest version.", "update.latestText": "You already have the latest version.",
...@@ -101,6 +127,9 @@ ...@@ -101,6 +127,9 @@
"contextmenu.open": "Open", "contextmenu.open": "Open",
"contextmenu.openInExplorer": "Open in Explorer", "contextmenu.openInExplorer": "Open in Explorer",
"contextmenu.openOnSpinShare": "Open on SpinShare", "contextmenu.openOnSpinShare": "Open on SpinShare",
"contextmenu.preview.start": "Start Preview",
"contextmenu.preview.stop": "Stop Preview",
"contextmenu.report": "Report",
"songrow.navigation.previous": "PREVIOUS", "songrow.navigation.previous": "PREVIOUS",
"songrow.navigation.next": "NEXT" "songrow.navigation.next": "NEXT"
......
...@@ -101,6 +101,12 @@ class SSAPI { ...@@ -101,6 +101,12 @@ class SSAPI {
return this.getOpenData("user/" + _userId + "/charts", true); 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) { async getUserReviews(_userId) {
let apiPath = this.apiBase + "user/" + _userId + "/reviews"; let apiPath = this.apiBase + "user/" + _userId + "/reviews";
......
...@@ -16,6 +16,7 @@ import ViewUserDetail from '../views/UserDetail.vue'; ...@@ -16,6 +16,7 @@ import ViewUserDetail from '../views/UserDetail.vue';
import ViewUserDetailCharts from '../views/UserDetailCharts.vue'; import ViewUserDetailCharts from '../views/UserDetailCharts.vue';
import ViewUserDetailReviews from '../views/UserDetailReviews.vue'; import ViewUserDetailReviews from '../views/UserDetailReviews.vue';
import ViewUserDetailSpinPlays from '../views/UserDetailSpinPlays.vue'; import ViewUserDetailSpinPlays from '../views/UserDetailSpinPlays.vue';
import ViewUserDetailPlaylists from '../views/UserDetailPlaylists.vue';
import ViewPlaylistDetail from '../views/PlaylistDetail.vue'; import ViewPlaylistDetail from '../views/PlaylistDetail.vue';
import ViewSettings from '../views/Settings.vue'; import ViewSettings from '../views/Settings.vue';
import ViewTournament from '../views/Tournament.vue'; import ViewTournament from '../views/Tournament.vue';
...@@ -100,6 +101,12 @@ const routes = [{ ...@@ -100,6 +101,12 @@ const routes = [{
name: 'UserDetailReviews', name: 'UserDetailReviews',
component: ViewUserDetailReviews component: ViewUserDetailReviews
}, },
{
alias: '',
path: 'playlists',
name: 'UserDetailPlaylists',
component: ViewUserDetailPlaylists
},
{ {
alias: '', alias: '',
path: 'spinplays', path: 'spinplays',
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
</div> </div>
</header> </header>
<div class="error-content"> <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> </div>
</section> </section>
</template> </template>
......
...@@ -171,9 +171,6 @@ ...@@ -171,9 +171,6 @@
shell.openExternal(userSettings.get('gameDirectory')); shell.openExternal(userSettings.get('gameDirectory'));
}, },
install: function() {
this.$parent.$parent.$emit('install');
},
getSongDetail: async function(filePath) { getSongDetail: async function(filePath) {
let ssapi = new SSAPI(); let ssapi = new SSAPI();
let trackInfo = {}; let trackInfo = {};
......
...@@ -6,16 +6,16 @@ ...@@ -6,16 +6,16 @@
<div class="login-box" v-if="!hasValidToken && !apiLoginLoading"> <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="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" /> <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"> <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>
</div> </div>
</section> </section>
...@@ -58,10 +58,6 @@ ...@@ -58,10 +58,6 @@
}).catch(() => { }).catch(() => {
this.showLoginBox(); this.showLoginBox();
}); });
// Check if connect token is valid
// Show Login Startup if not
// Show Startup if yes
} }
}, },
methods: { methods: {
...@@ -81,7 +77,7 @@ ...@@ -81,7 +77,7 @@
switch (data.status) { switch (data.status) {
case 200: case 200:
// Successfull // Successful Token
userSettings.set("connectToken", data.data); userSettings.set("connectToken", data.data);
this.loadIntoProfile(); this.loadIntoProfile();
break; break;
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
<div class="cover" :style="'background-image: url(' + cover + ');'"> <div class="cover" :style="'background-image: url(' + cover + ');'">
<div class="shade" v-if="!isOfficial"> <div class="shade" v-if="!isOfficial">
<div class="content"> <div class="content">
<div class="title">{{ title }}<span class="official-badge" v-if="isOfficial">OFFICIAL</span></div> <div class="title">{{ title }}<span class="official-badge" v-if="isOfficial">{{ $t('playlistdetail.header.official') }}</span></div>
<div class="quickinfo">{{ songs.length }} Charts</div> <div class="quickinfo">{{ $t('playlistdetail.header.charts', {amountOfCharts: songs.length}) }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
</div> </div>
<div class="playlist-actions"> <div class="playlist-actions">
<div class="action-row"> <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"> <div class="icon">
<i class="mdi mdi-content-copy"></i> <i class="mdi mdi-content-copy"></i>
</div> </div>
</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"> <div class="icon">
<i class="mdi mdi-download"></i> <i class="mdi mdi-download"></i>
</div> </div>
...@@ -29,13 +29,13 @@ ...@@ -29,13 +29,13 @@
</div> </div>
</div> </div>
<div class="playlist-uploader" v-if="!isOfficial"> <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" /> <UserItem v-bind="user" />
</div> </div>
<div class="playlist-charters" v-if="songs.length > 0"> <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"> <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> </div>
</div> </div>
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
</template> </template>
</SongRow> </SongRow>
<div class="list-noresults" v-if="songs.length === 0"> <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>
</div> </div>
</section> </section>
...@@ -90,6 +90,7 @@ export default { ...@@ -90,6 +90,7 @@ export default {
isOfficial: false, isOfficial: false,
user: null, user: null,
songs: [], songs: [],
charters: []
} }
}, },
mounted: function() { mounted: function() {
...@@ -100,13 +101,17 @@ export default { ...@@ -100,13 +101,17 @@ export default {
ssapi.getPlaylistDetail(routeID).then((data) => { ssapi.getPlaylistDetail(routeID).then((data) => {
if(data.status == 200) { if(data.status == 200) {
this.$data.id = data.data.id; 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.title = data.data.title;
this.$data.description = data.data.description; this.$data.description = data.data.description;
this.$data.isOfficial = data.data.isOfficial; this.$data.isOfficial = data.data.isOfficial;
this.$data.user = data.data.user; this.$data.user = data.data.user;
this.$data.songs = data.data.songs; this.$data.songs = data.data.songs;
this.$data.songs.forEach((song) => {
this.$data.charters.push(song.charter);
});
this.$data.apiFinished = true; this.$data.apiFinished = true;
} else { } else {
this.$router.push({ name: 'Error', params: { errorCode: data.status } }); this.$router.push({ name: 'Error', params: { errorCode: data.status } });
...@@ -271,9 +276,21 @@ export default { ...@@ -271,9 +276,21 @@ export default {
&:hover { &:hover {
opacity: 0.6; 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> </style>
\ No newline at end of file
...@@ -57,6 +57,14 @@ ...@@ -57,6 +57,14 @@
</div> </div>
<div class="settings-hint">{{ $t('settings.general.silentQueue.explaination') }}</div> <div class="settings-hint">{{ $t('settings.general.silentQueue.explaination') }}</div>
</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> </div>
<!-- Botch --> <!-- Botch -->
<div class="settings-box"> <div class="settings-box">
...@@ -75,6 +83,7 @@ ...@@ -75,6 +83,7 @@
<script> <script>
import { remote } from 'electron'; import { remote } from 'electron';
const { app, dialog } = remote; const { app, dialog } = remote;
const getSize = require('get-folder-size');
import UserSettings from '@/modules/module.usersettings.js'; import UserSettings from '@/modules/module.usersettings.js';
import SSAPI from '@/modules/module.api.js'; import SSAPI from '@/modules/module.api.js';
...@@ -87,7 +96,8 @@ ...@@ -87,7 +96,8 @@
environment: "", environment: "",
settingLanguage: "", settingLanguage: "",
settingGameDirectory: "", settingGameDirectory: "",
settingSilentQueue: false settingSilentQueue: false,
cacheSize: 0,
} }
}, },
mounted: function() { mounted: function() {
...@@ -99,6 +109,10 @@ ...@@ -99,6 +109,10 @@
this.$data.settingLanguage = userSettings.get('language'); this.$data.settingLanguage = userSettings.get('language');
this.$data.settingGameDirectory = userSettings.get('gameDirectory'); this.$data.settingGameDirectory = userSettings.get('gameDirectory');
this.$data.settingSilentQueue = userSettings.get('silentQueue'); 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: { methods: {
SelectGameDirectory: function() { SelectGameDirectory: function() {
...@@ -140,6 +154,11 @@ ...@@ -140,6 +154,11 @@
this.$root.$emit('showUpdateOverlay', false); this.$root.$emit('showUpdateOverlay', false);
} }
}); });
},
ClearCache: function() {
remote.getCurrentWindow().webContents.session.clearCache(function(){
remote.getCurrentWindow().reload();
});
} }
} }
} }
...@@ -192,6 +211,11 @@ ...@@ -192,6 +211,11 @@
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-gap: 5px; grid-gap: 5px;
&.settings-input-onebutton {
grid-template-columns: 1fr auto;
align-items: center;
}
&.settings-input-twobuttons { &.settings-input-twobuttons {
grid-template-columns: 1fr auto auto; grid-template-columns: 1fr auto auto;
} }
......
...@@ -13,23 +13,23 @@ ...@@ -13,23 +13,23 @@
</div> </div>
</div> </div>
<div :class="'song-actions ' + (previewIsPlaying ? 'player-active' : '')"> <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"> <div class="icon">
<i class="mdi mdi-download"></i> <i class="mdi mdi-download"></i>
</div> </div>
</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"> <div class="icon">
<i class="mdi mdi-gamepad-variant"></i> <i class="mdi mdi-gamepad-variant"></i>
</div> </div>
</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"> <div class="icon">
<i class="mdi mdi-refresh"></i> <i class="mdi mdi-refresh"></i>
</div> </div>
</div> </div>
<div class="action-player"> <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-play" v-if="!previewIsPlaying"></i>
<i class="mdi mdi-stop" v-if="previewIsPlaying"></i> <i class="mdi mdi-stop" v-if="previewIsPlaying"></i>
</div> </div>
...@@ -37,12 +37,12 @@ ...@@ -37,12 +37,12 @@
<input type="range" min="0" max="100" value="50" v-model="previewVolume" class="playerVolume" v-on:input="UpdateVolume()" /> <input type="range" min="0" max="100" value="50" v-model="previewVolume" class="playerVolume" v-on:input="UpdateVolume()" />
</div> </div>
</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"> <div class="icon">
<i class="mdi mdi-content-copy"></i> <i class="mdi mdi-content-copy"></i>
</div> </div>
</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"> <div class="icon">
<i class="mdi mdi-flag-outline"></i> <i class="mdi mdi-flag-outline"></i>
</div> </div>
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
</div> </div>
</div> </div>
<div class="stat" v-if="uploadDate"> <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> <i class="mdi mdi-calendar-clock"></i>
</div> </div>
<div class="content"> <div class="content">
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
</div> </div>
</div> </div>
<div class="stat"> <div class="stat">
<div class="icon" v-tooltip="'Views'"> <div class="icon" v-tooltip="$t('songdetail.stats.views')">
<i class="mdi mdi-eye"></i> <i class="mdi mdi-eye"></i>
</div> </div>
<div class="content"> <div class="content">
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
</div> </div>
</div> </div>
<div class="stat"> <div class="stat">
<div class="icon" v-tooltip="'Downloads'"> <div class="icon" v-tooltip="$t('songdetail.stats.downloads')">
<i class="mdi mdi-download"></i> <i class="mdi mdi-download"></i>
</div> </div>
<div class="content"> <div class="content">
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
<div class="detail"> <div class="detail">
<div class="user-avatar" :style="'background-image: url(' + avatar + '), url(' + require('@/assets/img/defaultAvatar.jpg') + ');'"></div> <div class="user-avatar" :style="'background-image: url(' + avatar + '), url(' + require('@/assets/img/defaultAvatar.jpg') + ');'"></div>
<div class="user-data"> <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"> <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> </div>
</div> </div>
...@@ -16,9 +16,10 @@ ...@@ -16,9 +16,10 @@
</div> </div>
<div class="tabs"> <div class="tabs">
<router-link :to="{ name: 'UserDetailCharts', params: { id: id } }" class="tab" exact>Charts ({{ songs }})</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: 'UserDetailReviews', params: { id: id } }" class="tab" exact>Reviews ({{ reviews }})</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: 'UserDetailSpinPlays', params: { id: id } }" class="tab" exact>SpinPlays ({{ spinplays }})</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> </div>
</header> </header>
...@@ -56,11 +57,13 @@ ...@@ -56,11 +57,13 @@
apiFinished: false, apiFinished: false,
id: 0, id: 0,
username: "", username: "",
pronouns: "",
isVerified: false, isVerified: false,
isPatreon: false, isPatreon: false,
avatar: "", avatar: "",
cards: [], cards: [],
songs: 0, songs: 0,
playlists: 0,
reviews: 0, reviews: 0,
spinplays: 0, spinplays: 0,
showCardOverlay: false, showCardOverlay: false,
...@@ -74,11 +77,13 @@ ...@@ -74,11 +77,13 @@
if(data.status == 200) { if(data.status == 200) {
this.$data.id = data.data.id; this.$data.id = data.data.id;
this.$data.username = data.data.username; this.$data.username = data.data.username;
this.$data.pronouns = data.data.pronouns;
this.$data.isVerified = data.data.isVerified; this.$data.isVerified = data.data.isVerified;
this.$data.isPatreon = data.data.isPatreon; this.$data.isPatreon = data.data.isPatreon;
this.$data.avatar = data.data.avatar; this.$data.avatar = data.data.avatar;
this.$data.cards = data.data.cards; this.$data.cards = data.data.cards;
this.$data.songs = data.data.songs; this.$data.songs = data.data.songs;
this.$data.playlists = data.data.playlists;
this.$data.reviews = data.data.reviews; this.$data.reviews = data.data.reviews;
this.$data.spinplays = data.data.spinplays; this.$data.spinplays = data.data.spinplays;
this.$data.apiFinished = true; this.$data.apiFinished = true;
...@@ -167,6 +172,18 @@ ...@@ -167,6 +172,18 @@
& .user-name { & .user-name {
font-size: 22px; font-size: 22px;
margin-bottom: 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 { & .user-actions {
& .button { & .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