-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHomePageComponent.kt
154 lines (133 loc) · 6.91 KB
/
HomePageComponent.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package com.adamratzman.layouts
import com.adamratzman.database.lastSpotifyAccessToken
import com.adamratzman.security.guardValidSpotifyApi
import com.adamratzman.spotify.webplayer.Player
import com.adamratzman.spotify.webplayer.PlayerInit
import com.adamratzman.spotify.webplayer.WebPlaybackInstance
import com.adamratzman.utils.UikitName.MarginAuto
import com.adamratzman.utils.UikitName.MarginMediumTop
import com.adamratzman.utils.UikitName.WidthTwoThirds
import com.adamratzman.utils.addLineBreak
import com.adamratzman.utils.labelWithBoldedValue
import com.adamratzman.utils.nameSetOf
import kotlinx.browser.localStorage
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import pl.treksoft.kvision.core.Container
import pl.treksoft.kvision.form.text.text
import pl.treksoft.kvision.html.Div
import pl.treksoft.kvision.html.button
import pl.treksoft.kvision.html.div
import pl.treksoft.kvision.html.h4
import pl.treksoft.kvision.html.h5
import pl.treksoft.kvision.html.p
class HomePageComponent(parent: Container) : SiteStatefulComponent(parent = parent, buildStatefulComponent = { state ->
guardValidSpotifyApi(state) { api ->
lateinit var playerDeviceId: String
div(classes = nameSetOf(MarginMediumTop, WidthTwoThirds, MarginAuto)) {
h4("Spotify api has been instantiated.")
GlobalScope.launch {
p("User: ${api.getUserId()}")
val playerStatus = h5("Registering online player.. (Disconnected)")
val player = Player(
object : PlayerInit {
override var name: String = "spotify-web-api-kotlin browser example player"
override var volume: Number? = 0.5f
override fun getOAuthToken(cb: (token: String) -> Unit) {
// cannot reference outer closures within an override fun! otherwise we'd just call api
cb(localStorage.getItem(lastSpotifyAccessToken)!!)
}
}
)
player.addListener("ready") { webPlaybackInstance: WebPlaybackInstance ->
playerDeviceId = webPlaybackInstance.device_id
playerStatus.content = "Registered online player (Ready! Device id: $playerDeviceId)"
}
player.connect().then {
playerStatus.content = "Registered online player (Not ready)"
}
val currentPlayerStateDiv = div()
GlobalScope.launch {
while (true) {
delay(500)
val newCurrentPlayerStateDiv = Div()
with(newCurrentPlayerStateDiv) {
val currentlyPlayingState = api.player.getCurrentlyPlaying()
when (currentlyPlayingState?.isPlaying) {
null -> labelWithBoldedValue("Player state: ", "not playing anything")
true -> {
labelWithBoldedValue("Player state: ", "playing")
}
false -> {
labelWithBoldedValue("Player state: ", "paused")
}
}
if (currentlyPlayingState?.isPlaying != null) {
player.getCurrentState().then { playbackState ->
val currentTrack = playbackState?.track_window?.current_track
if (currentTrack != null) {
labelWithBoldedValue(
"Current track playing through this browser: ",
"${currentTrack.name}, by ${currentTrack.artists.joinToString(", ") { it.name }}"
)
} else {
labelWithBoldedValue(
"Current track playing through this browser: ",
"unavailable/null"
)
}
}
}
val currentlyPlayingTrackInAccount = api.player.getCurrentlyPlaying()
val track = currentlyPlayingTrackInAccount?.track
if (track == null) {
labelWithBoldedValue(
"Current track playing through this account (not necessarily this device): ",
"none"
)
} else {
labelWithBoldedValue(
"Current track playing through this account (not necessarily this device): ",
"${track.name}, by ${track.artists.joinToString(", ") { it.name }}"
)
}
if (currentlyPlayingState != null) {
if (currentlyPlayingState.progressMs != null) {
labelWithBoldedValue(
"Progress: ",
"${currentlyPlayingState.progressMs!! / 1000} seconds"
)
}
}
delay(1000)
}
currentPlayerStateDiv.removeAll()
currentPlayerStateDiv.addAll(newCurrentPlayerStateDiv.getChildren())
}
}
val trackNameInput = text(label = "Enter a track to play")
button(text = "Search and play this track (using spotify-web-api-kotlin)") {
onClick {
trackNameInput.value?.let { trackQuery ->
GlobalScope.launch {
val track = api.search.searchTrack(trackQuery)[0]
api.player.startPlayback(
playableUrisToPlay = listOf(track.uri),
deviceId = playerDeviceId
)
}
}
}
}
addLineBreak()
addLineBreak()
button(text = "Toggle play - unpause/pause (if playing through this browser)") {
onClick {
player.togglePlay()
}
}
}
}
}
})