Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Desktop Client
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
SpinShare
Desktop Client
Commits
ef025358
Commit
ef025358
authored
Dec 04, 2020
by
Andreas Heimann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
removed popular tab, implemented userprofile, implemented new search api syntax
parent
61ec76cf
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
119 additions
and
123 deletions
+119
-123
package-lock.json
package-lock.json
+8
-8
src/App.vue
src/App.vue
+0
-2
src/components/Navigation/Navigation.vue
src/components/Navigation/Navigation.vue
+70
-1
src/modules/module.api.js
src/modules/module.api.js
+20
-18
src/router/index.js
src/router/index.js
+5
-8
src/views/Login.vue
src/views/Login.vue
+12
-2
src/views/Search.vue
src/views/Search.vue
+2
-2
src/views/Startup.vue
src/views/Startup.vue
+2
-3
src/views/StartupPopularSongs.vue
src/views/StartupPopularSongs.vue
+0
-79
No files found.
package-lock.json
View file @
ef025358
{
{
"name"
:
"spinshare-client"
,
"name"
:
"spinshare-client"
,
"version"
:
"2.
4
.0"
,
"version"
:
"2.
5
.0"
,
"lockfileVersion"
:
1
,
"lockfileVersion"
:
1
,
"requires"
:
true
,
"requires"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
...
@@ -9002,9 +9002,9 @@
...
@@ -9002,9 +9002,9 @@
}
}
},
},
"node-forge"
:
{
"node-forge"
:
{
"version"
:
"0.
9
.0"
,
"version"
:
"0.
10
.0"
,
"resolved"
:
"https://registry.npmjs.org/node-forge/-/node-forge-0.
9
.0.tgz"
,
"resolved"
:
"https://registry.npmjs.org/node-forge/-/node-forge-0.
10
.0.tgz"
,
"integrity"
:
"sha512-
7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ
=="
,
"integrity"
:
"sha512-
PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA
=="
,
"dev"
:
true
"dev"
:
true
},
},
"node-ipc"
:
{
"node-ipc"
:
{
...
@@ -11281,12 +11281,12 @@
...
@@ -11281,12 +11281,12 @@
"dev"
:
true
"dev"
:
true
},
},
"selfsigned"
:
{
"selfsigned"
:
{
"version"
:
"1.10.
7
"
,
"version"
:
"1.10.
8
"
,
"resolved"
:
"https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.
7
.tgz"
,
"resolved"
:
"https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.
8
.tgz"
,
"integrity"
:
"sha512-
8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA
=="
,
"integrity"
:
"sha512-
2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w
=="
,
"dev"
:
true
,
"dev"
:
true
,
"requires"
:
{
"requires"
:
{
"node-forge"
:
"
0.9
.0"
"node-forge"
:
"
^0.10
.0"
}
}
},
},
"semver"
:
{
"semver"
:
{
...
...
src/App.vue
View file @
ef025358
...
@@ -21,8 +21,6 @@
...
@@ -21,8 +21,6 @@
import
{
remote
,
ipcRenderer
}
from
'
electron
'
;
import
{
remote
,
ipcRenderer
}
from
'
electron
'
;
const
{
app
,
dialog
}
=
remote
;
const
{
app
,
dialog
}
=
remote
;
import
fs
from
'
fs
'
;
import
glob
from
'
glob
'
;
import
path
from
'
path
'
;
import
path
from
'
path
'
;
import
UserSettings
from
'
@/modules/module.usersettings.js
'
;
import
UserSettings
from
'
@/modules/module.usersettings.js
'
;
...
...
src/components/Navigation/Navigation.vue
View file @
ef025358
...
@@ -17,7 +17,41 @@
...
@@ -17,7 +17,41 @@
<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>
<router-link
to=
"/settings"
class=
"item"
v-tooltip.down=
"'Settings'"
><i
class=
"mdi mdi-cog-outline"
></i></router-link>
<div
class=
"item item-user"
tabindex=
"0"
v-if=
"userData != null"
>
<div
class=
"user-avatar"
:style=
"'background-image: url(' + userData.avatar + ');'"
></div>
<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>
</router-link>
<router-link
:to=
"
{ name: 'UserDetailReviews', params: { id: userData.id } }" class="user-action-item">
<i
class=
"mdi mdi-playlist-music"
></i>
<span>
My Playlists
</span>
</router-link>
<router-link
:to=
"
{ name: 'UserDetailSpinPlays', params: { id: userData.id } }" class="user-action-item">
<i
class=
"mdi mdi-thumbs-up-down"
></i>
<span>
My Reviews
</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>
</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>
</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>
</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>
</div>
</div>
</div>
</nav>
</nav>
</aside>
</aside>
</
template
>
</
template
>
...
@@ -26,12 +60,33 @@
...
@@ -26,12 +60,33 @@
import
{
remote
}
from
'
electron
'
;
import
{
remote
}
from
'
electron
'
;
const
{
shell
}
=
remote
;
const
{
shell
}
=
remote
;
import
SSAPI
from
'
@/modules/module.api.js
'
;
import
UserSettings
from
'
@/modules/module.usersettings.js
'
;
export
default
{
export
default
{
name
:
'
Navigation
'
,
name
:
'
Navigation
'
,
props
:
[
props
:
[
'
downloadQueueCount
'
,
'
downloadQueueCount
'
,
'
downloadOverlayShown
'
'
downloadOverlayShown
'
],
],
data
:
function
()
{
return
{
userData
:
{}
}
},
mounted
:
function
()
{
let
userSettings
=
new
UserSettings
();
if
(
!
userSettings
.
get
(
"
connectProfile
"
))
{
this
.
$router
.
replace
({
name
:
'
Login
'
});
}
this
.
$data
.
userData
=
userSettings
.
get
(
"
connectProfile
"
);
this
.
$root
.
$on
(
"
LoadIntoProfile
"
,
(
data
)
=>
{
this
.
$data
.
userData
=
data
;
});
},
methods
:
{
methods
:
{
navigateBack
:
function
()
{
navigateBack
:
function
()
{
this
.
$router
.
back
();
this
.
$router
.
back
();
...
@@ -41,6 +96,13 @@
...
@@ -41,6 +96,13 @@
},
},
openExternal
:
function
(
url
)
{
openExternal
:
function
(
url
)
{
shell
.
openExternal
(
url
);
shell
.
openExternal
(
url
);
},
userLogout
:
function
()
{
let
userSettings
=
new
UserSettings
();
userSettings
.
set
(
"
connectProfile
"
,
null
);
userSettings
.
set
(
"
connectToken
"
,
null
);
window
.
location
.
reload
();
}
}
}
}
}
}
...
@@ -237,6 +299,7 @@
...
@@ -237,6 +299,7 @@
position: absolute;
position: absolute;
top: 70px;
top: 70px;
right: 10px;
right: 10px;
overflow: hidden;
border-radius: 4px;
border-radius: 4px;
background: #000;
background: #000;
box-shadow: 0px 4px 12px rgba(0,0,0,0.6);
box-shadow: 0px 4px 12px rgba(0,0,0,0.6);
...
@@ -264,6 +327,12 @@
...
@@ -264,6 +327,12 @@
background: rgba(255,255,255,0.1);
background: rgba(255,255,255,0.1);
}
}
}
}
& .user-action-spacer {
margin: 5px 15px;
height: 1px;
width: auto;
background: rgba(255,255,255,0.2);
}
&:after {
&:after {
bottom: 100%;
bottom: 100%;
...
...
src/modules/module.api.js
View file @
ef025358
...
@@ -132,22 +132,6 @@ class SSAPI {
...
@@ -132,22 +132,6 @@ class SSAPI {
});
});
}
}
async
getPopularSongs
(
_offset
)
{
let
apiPath
=
this
.
apiBase
+
"
songs/popular/
"
+
_offset
;
let
supportedVersion
=
this
.
supportedVersion
;
return
axios
.
get
(
apiPath
)
.
then
(
function
(
response
)
{
if
(
response
.
data
.
version
!==
supportedVersion
)
{
throw
new
Error
(
"
Client is outdated!
"
);
}
return
response
.
data
.
data
;
}).
catch
(
function
(
error
)
{
throw
new
Error
(
error
);
});
}
async
getSongDetail
(
_songId
)
{
async
getSongDetail
(
_songId
)
{
let
apiPath
=
this
.
apiBase
+
"
song/
"
+
_songId
;
let
apiPath
=
this
.
apiBase
+
"
song/
"
+
_songId
;
let
supportedVersion
=
this
.
supportedVersion
;
let
supportedVersion
=
this
.
supportedVersion
;
...
@@ -277,10 +261,12 @@ class SSAPI {
...
@@ -277,10 +261,12 @@ class SSAPI {
}
}
async
search
(
_searchQuery
)
{
async
search
(
_searchQuery
)
{
let
apiPath
=
this
.
apiBase
+
"
search
/
"
+
_searchQuery
;
let
apiPath
=
this
.
apiBase
+
"
search
"
;
let
supportedVersion
=
this
.
supportedVersion
;
let
supportedVersion
=
this
.
supportedVersion
;
return
axios
.
get
(
apiPath
)
return
axios
.
get
(
apiPath
,
{
searchQuery
:
_searchQuery
})
.
then
(
function
(
response
)
{
.
then
(
function
(
response
)
{
if
(
response
.
data
.
version
!==
supportedVersion
)
{
if
(
response
.
data
.
version
!==
supportedVersion
)
{
throw
new
Error
(
"
Client is outdated!
"
);
throw
new
Error
(
"
Client is outdated!
"
);
...
@@ -346,6 +332,22 @@ class SSAPI {
...
@@ -346,6 +332,22 @@ class SSAPI {
throw
new
Error
(
error
);
throw
new
Error
(
error
);
});
});
}
}
async
getConnectProfile
(
connectToken
)
{
let
apiPath
=
this
.
apiBase
+
"
connect/profile/?connectToken=
"
+
connectToken
;
let
supportedVersion
=
this
.
supportedVersion
;
return
axios
.
get
(
apiPath
)
.
then
(
function
(
response
)
{
if
(
response
.
data
.
version
!==
supportedVersion
)
{
throw
new
Error
(
"
Client is outdated!
"
);
}
return
response
.
data
.
data
;
}).
catch
(
function
(
error
)
{
throw
new
Error
(
error
);
});
}
}
}
module
.
exports
=
SSAPI
;
module
.
exports
=
SSAPI
;
src/router/index.js
View file @
ef025358
...
@@ -7,7 +7,6 @@ import ViewStartup from '../views/Startup.vue';
...
@@ -7,7 +7,6 @@ import ViewStartup from '../views/Startup.vue';
import
ViewStartupFrontpage
from
'
../views/StartupFrontpage.vue
'
;
import
ViewStartupFrontpage
from
'
../views/StartupFrontpage.vue
'
;
import
ViewStartupNewSongs
from
'
../views/StartupNewSongs.vue
'
;
import
ViewStartupNewSongs
from
'
../views/StartupNewSongs.vue
'
;
import
ViewStartupHotSongs
from
'
../views/StartupHotSongs.vue
'
;
import
ViewStartupHotSongs
from
'
../views/StartupHotSongs.vue
'
;
import
ViewStartupPopularSongs
from
'
../views/StartupPopularSongs.vue
'
;
import
ViewSearch
from
'
../views/Search.vue
'
;
import
ViewSearch
from
'
../views/Search.vue
'
;
import
ViewLibrary
from
'
../views/Library.vue
'
;
import
ViewLibrary
from
'
../views/Library.vue
'
;
import
ViewSongDetail
from
'
../views/SongDetail.vue
'
;
import
ViewSongDetail
from
'
../views/SongDetail.vue
'
;
...
@@ -30,11 +29,14 @@ const routes = [{
...
@@ -30,11 +29,14 @@ const routes = [{
component
:
ViewLogin
component
:
ViewLogin
},
{
},
{
path
:
'
/startup
'
,
path
:
'
/startup
'
,
name
:
'
Startup
'
,
component
:
ViewStartup
,
component
:
ViewStartup
,
name
:
'
ViewStartup
'
,
redirect
:
{
name
:
'
StartupFrontpage
'
},
children
:
[
children
:
[
{
{
path
:
''
,
path
:
'
/frontpage
'
,
name
:
'
StartupFrontpage
'
,
name
:
'
StartupFrontpage
'
,
component
:
ViewStartupFrontpage
component
:
ViewStartupFrontpage
},
},
...
@@ -47,11 +49,6 @@ const routes = [{
...
@@ -47,11 +49,6 @@ const routes = [{
path
:
'
/hot
'
,
path
:
'
/hot
'
,
name
:
'
StartupHot
'
,
name
:
'
StartupHot
'
,
component
:
ViewStartupHotSongs
component
:
ViewStartupHotSongs
},
{
path
:
'
/popular
'
,
name
:
'
StartupPopular
'
,
component
:
ViewStartupPopularSongs
}
}
]
]
},
{
},
{
...
...
src/views/Login.vue
View file @
ef025358
...
@@ -51,7 +51,7 @@
...
@@ -51,7 +51,7 @@
}
else
{
}
else
{
ssapi
.
validateConnectToken
(
userSettings
.
get
(
"
connectToken
"
)).
then
((
data
)
=>
{
ssapi
.
validateConnectToken
(
userSettings
.
get
(
"
connectToken
"
)).
then
((
data
)
=>
{
if
(
data
)
{
if
(
data
)
{
this
.
$router
.
replace
({
name
:
'
StartupFrontpage
'
}
);
this
.
loadIntoProfile
(
);
}
else
{
}
else
{
this
.
showLoginBox
();
this
.
showLoginBox
();
}
}
...
@@ -80,7 +80,7 @@
...
@@ -80,7 +80,7 @@
case
200
:
case
200
:
// Successfull
// Successfull
userSettings
.
set
(
"
connectToken
"
,
data
.
data
);
userSettings
.
set
(
"
connectToken
"
,
data
.
data
);
this
.
$router
.
replace
({
name
:
'
StartupFrontpage
'
}
);
this
.
loadIntoProfile
(
);
break
;
break
;
case
403
:
case
403
:
case
404
:
case
404
:
...
@@ -98,6 +98,16 @@
...
@@ -98,6 +98,16 @@
this
.
$data
.
apiLoginLoading
=
false
;
this
.
$data
.
apiLoginLoading
=
false
;
this
.
$data
.
apiLoginCodeError
=
false
;
this
.
$data
.
apiLoginCodeError
=
false
;
this
.
$data
.
apiLoginServerError
=
false
;
this
.
$data
.
apiLoginServerError
=
false
;
},
loadIntoProfile
:
function
()
{
let
ssapi
=
new
SSAPI
();
let
userSettings
=
new
UserSettings
();
ssapi
.
getConnectProfile
(
userSettings
.
get
(
"
connectToken
"
)).
then
((
data
)
=>
{
userSettings
.
set
(
"
connectProfile
"
,
data
);
this
.
$root
.
$emit
(
"
LoadIntoProfile
"
,
data
);
this
.
$router
.
replace
({
name
:
'
StartupFrontpage
'
});
});
}
}
},
},
watch
:
{
watch
:
{
...
...
src/views/Search.vue
View file @
ef025358
...
@@ -97,9 +97,9 @@
...
@@ -97,9 +97,9 @@
let
ssapi
=
new
SSAPI
();
let
ssapi
=
new
SSAPI
();
this
.
$data
.
apiFinished
=
false
;
this
.
$data
.
apiFinished
=
false
;
if
(
this
.
$data
.
searchQuery
!=
""
)
{
if
(
this
.
$data
.
searchQuery
!=
=
""
)
{
ssapi
.
search
(
this
.
$data
.
searchQuery
).
then
((
data
)
=>
{
ssapi
.
search
(
this
.
$data
.
searchQuery
).
then
((
data
)
=>
{
if
(
data
.
status
==
200
)
{
if
(
data
.
status
==
=
200
)
{
this
.
$data
.
searchResultsUsers
=
data
.
data
.
users
;
this
.
$data
.
searchResultsUsers
=
data
.
data
.
users
;
this
.
$data
.
searchResultsSongs
=
data
.
data
.
songs
;
this
.
$data
.
searchResultsSongs
=
data
.
data
.
songs
;
...
...
src/views/Startup.vue
View file @
ef025358
...
@@ -2,10 +2,9 @@
...
@@ -2,10 +2,9 @@
<section
class=
"section-startup"
>
<section
class=
"section-startup"
>
<header>
<header>
<div
class=
"tabs"
>
<div
class=
"tabs"
>
<router-link
to=
"/"
class=
"tab"
><span>
{{
$t
(
'
startup.tabs.frontpage
'
)
}}
</span></router-link>
<router-link
to=
"/
frontpage
"
class=
"tab"
><span>
{{
$t
(
'
startup.tabs.frontpage
'
)
}}
</span></router-link>
<router-link
to=
"/new"
class=
"tab"
><span>
{{
$t
(
'
startup.tabs.new
'
)
}}
</span></router-link>
<router-link
to=
"/new"
class=
"tab"
><span>
{{
$t
(
'
startup.tabs.new
'
)
}}
</span></router-link>
<router-link
to=
"/hot"
class=
"tab"
><span>
{{
$t
(
'
startup.tabs.hot
'
)
}}
</span></router-link>
<router-link
to=
"/hot"
class=
"tab"
><span>
{{
$t
(
'
startup.tabs.hot
'
)
}}
</span></router-link>
<router-link
to=
"/popular"
class=
"tab"
><span>
{{
$t
(
'
startup.tabs.popular
'
)
}}
</span></router-link>
</div>
</div>
</header>
</header>
...
@@ -49,7 +48,7 @@
...
@@ -49,7 +48,7 @@
background: #272c2e;
background: #272c2e;
color: rgba(255,255,255,0.75);
color: rgba(255,255,255,0.75);
}
}
&.router-link-exact-active {
&.router-link-exact-active
, &.router-link-active
{
opacity: 1;
opacity: 1;
color: rgba(255,255,255,1);
color: rgba(255,255,255,1);
background: #212629;
background: #212629;
...
...
src/views/StartupPopularSongs.vue
deleted
100644 → 0
View file @
61ec76cf
<
template
>
<SongRow>
<template
v-slot:controls
>
<div
:class=
"'button ' + (popularSongsOffset == 0 ? 'button-disabled' : '')"
v-on:click=
"popularPrevious()"
><i
class=
"mdi mdi-chevron-left"
></i>
{{
$t
(
'
songrow.navigation.previous
'
)
}}
</div>
<div
:class=
"'button ' + (popularSongs.length
<
11
?
'
button-disabled
'
:
'')"
v-on:click=
"popularNext()"
>
{{
$t
(
'
songrow.navigation.next
'
)
}}
<i
class=
"mdi mdi-chevron-right"
></i></div>
</
template
>
<
template
v-slot:song-list
>
<SongItemPlaceholder
v-if=
"isPopularSongsLoading"
v-for=
"n in 12"
v-bind:key=
"n"
/>
<SongItem
v-if=
"!isPopularSongsLoading"
v-for=
"song in popularSongs"
v-bind:key=
"song.id"
v-bind=
"song"
/>
</
template
>
</SongRow>
</template>
<
script
>
import
SSAPI
from
'
@/modules/module.api.js
'
;
import
SongRow
from
'
@/components/Song/SongRow.vue
'
;
import
SongItem
from
'
@/components/Song/SongItem.vue
'
;
import
SongItemPlaceholder
from
'
@/components/Song/SongItemPlaceholder.vue
'
;
export
default
{
name
:
'
Startup
'
,
data
:
function
()
{
return
{
isPopularSongsLoading
:
true
,
popularSongsOffset
:
0
,
popularSongs
:
[]
}
},
mounted
:
function
()
{
let
ssapi
=
new
SSAPI
();
ssapi
.
getPopularSongs
(
this
.
$data
.
popularSongsOffset
).
then
((
data
)
=>
{
this
.
$data
.
isPopularSongsLoading
=
false
;
this
.
$data
.
popularSongs
=
data
;
});
},
components
:
{
SongRow
,
SongItem
,
SongItemPlaceholder
},
methods
:
{
popularNext
:
function
()
{
if
(
this
.
$data
.
popularSongs
.
length
>
11
)
{
this
.
$data
.
popularSongsOffset
++
;
this
.
updatePopular
();
}
},
popularPrevious
:
function
()
{
if
(
this
.
$data
.
popularSongsOffset
>
0
)
{
this
.
$data
.
popularSongsOffset
--
;
this
.
updatePopular
();
}
},
updatePopular
:
function
()
{
let
ssapi
=
new
SSAPI
();
this
.
$data
.
isPopularSongsLoading
=
true
;
ssapi
.
getPopularSongs
(
this
.
$data
.
popularSongsOffset
).
then
((
data
)
=>
{
this
.
$data
.
isPopularSongsLoading
=
false
;
this
.
$data
.
popularSongs
=
data
;
});
}
}
}
</
script
>
<
style
scoped
lang=
"less"
>
.song-row {
padding: 50px;
}
</
style
>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment