Skip to content

Commit 2147775

Browse files
authored
merge #61 - onboarding
Improve onboarding
2 parents cf2d953 + 05017bd commit 2147775

107 files changed

Lines changed: 4991 additions & 1277 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

TODO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@
3838
- hide "remove from playlist" option on system playlists
3939
- ADD QR CODE SOMEWHERE ON THE WEB
4040
- Add a "Rescan folders" item to the "Browse Library" section
41-
- Paginate playlist page
41+
- Paginate playlist page

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
"@vueuse/integrations": "^9.2.0",
1818
"@vueuse/motion": "^2.0.0",
1919
"axios": "^0.26.1",
20+
"blurhash": "^2.0.5",
2021
"fuse.js": "^6.6.2",
22+
"javascript-time-ago": "^2.6.2",
2123
"motion": "^10.15.5",
2224
"node-vibrant": "3.1.6",
2325
"pinia": "^2.0.17",

public/workers/sse-events.js

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
let eventSource = null
2+
let reconnectTimer = null
3+
let reconnectDelay = 1000
4+
let maxReconnectDelay = 30000
5+
let reconnectAttempts = 0
6+
let maxReconnectAttempts = 10
7+
let isConnected = false
8+
9+
const is_dev = location.port === '5173'
10+
const protocol = location.protocol.replace(':', '')
11+
const base_url = is_dev ? `${protocol}://${location.hostname}:1980` : location.origin
12+
const sse_url = base_url + '/events/stream'
13+
14+
function connect() {
15+
console.log('connect called')
16+
if (eventSource && eventSource.readyState !== EventSource.CLOSED) {
17+
return
18+
}
19+
20+
try {
21+
eventSource = new EventSource(sse_url, {
22+
withCredentials: true,
23+
})
24+
console.log('eventSource created')
25+
26+
eventSource.onopen = function (event) {
27+
isConnected = true
28+
reconnectAttempts = 0
29+
reconnectDelay = 1000
30+
31+
postMessage({
32+
type: 'connection',
33+
status: 'connected',
34+
timestamp: Date.now(),
35+
})
36+
}
37+
38+
eventSource.onmessage = function (event) {
39+
try {
40+
postMessage({
41+
type: 'message',
42+
data: JSON.parse(event.data),
43+
timestamp: Date.now(),
44+
})
45+
} catch (error) {
46+
postMessage({
47+
type: 'error',
48+
error: 'Failed to parse message data',
49+
rawData: event.data,
50+
timestamp: Date.now(),
51+
})
52+
}
53+
}
54+
55+
eventSource.onerror = function (event) {
56+
isConnected = false
57+
58+
postMessage({
59+
type: 'connection',
60+
status: 'error',
61+
readyState: eventSource.readyState,
62+
timestamp: Date.now(),
63+
})
64+
65+
if (eventSource.readyState === EventSource.CLOSED) {
66+
scheduleReconnect()
67+
}
68+
}
69+
} catch (error) {
70+
console.log('Failed to create EventSource', error)
71+
postMessage({
72+
type: 'error',
73+
error: 'Failed to create EventSource',
74+
message: error.message,
75+
timestamp: Date.now(),
76+
})
77+
scheduleReconnect()
78+
}
79+
}
80+
81+
function scheduleReconnect() {
82+
if (reconnectTimer) {
83+
clearTimeout(reconnectTimer)
84+
}
85+
86+
if (reconnectAttempts >= maxReconnectAttempts) {
87+
postMessage({
88+
type: 'connection',
89+
status: 'max_reconnect_attempts_reached',
90+
attempts: reconnectAttempts,
91+
timestamp: Date.now(),
92+
})
93+
return
94+
}
95+
96+
postMessage({
97+
type: 'connection',
98+
status: 'reconnecting',
99+
delay: reconnectDelay,
100+
attempt: reconnectAttempts + 1,
101+
timestamp: Date.now(),
102+
})
103+
104+
reconnectTimer = setTimeout(() => {
105+
reconnectAttempts++
106+
connect()
107+
reconnectDelay = Math.min(reconnectDelay * 2, maxReconnectDelay)
108+
}, reconnectDelay)
109+
}
110+
111+
function disconnect() {
112+
if (reconnectTimer) {
113+
clearTimeout(reconnectTimer)
114+
reconnectTimer = null
115+
}
116+
117+
if (eventSource) {
118+
eventSource.close()
119+
eventSource = null
120+
}
121+
122+
isConnected = false
123+
reconnectAttempts = 0
124+
reconnectDelay = 1000
125+
126+
postMessage({
127+
type: 'connection',
128+
status: 'disconnected',
129+
timestamp: Date.now(),
130+
})
131+
}
132+
133+
function getConnectionStatus() {
134+
postMessage({
135+
type: 'status',
136+
connected: isConnected,
137+
readyState: eventSource ? eventSource.readyState : null,
138+
reconnectAttempts: reconnectAttempts,
139+
timestamp: Date.now(),
140+
})
141+
}
142+
143+
onmessage = function (e) {
144+
const { command, options } = e.data
145+
console.log('command', command)
146+
console.log('options', options)
147+
148+
switch (command) {
149+
case 'connect':
150+
if (options && options.maxReconnectAttempts !== undefined) {
151+
maxReconnectAttempts = options.maxReconnectAttempts
152+
}
153+
if (options && options.reconnectDelay !== undefined) {
154+
reconnectDelay = options.reconnectDelay
155+
}
156+
if (options && options.maxReconnectDelay !== undefined) {
157+
maxReconnectDelay = options.maxReconnectDelay
158+
}
159+
connect()
160+
break
161+
162+
case 'disconnect':
163+
disconnect()
164+
break
165+
166+
case 'status':
167+
getConnectionStatus()
168+
break
169+
170+
case 'retry':
171+
if (!isConnected) {
172+
reconnectAttempts = 0
173+
reconnectDelay = 1000
174+
connect()
175+
}
176+
break
177+
178+
default:
179+
postMessage({
180+
type: 'error',
181+
error: 'Unknown command',
182+
command: command,
183+
timestamp: Date.now(),
184+
})
185+
}
186+
}
187+
188+
self.addEventListener('online', function () {
189+
postMessage({
190+
type: 'network',
191+
status: 'online',
192+
timestamp: Date.now(),
193+
})
194+
195+
if (!isConnected) {
196+
reconnectAttempts = 0
197+
reconnectDelay = 1000
198+
connect()
199+
}
200+
})
201+
202+
self.addEventListener('offline', function () {
203+
postMessage({
204+
type: 'network',
205+
status: 'offline',
206+
timestamp: Date.now(),
207+
})
208+
})

0 commit comments

Comments
 (0)