fix: double file_list at start if you are logged in, sometimes

Massimo Melina committed Jan 15, 2022 at 18:59 UTC 9389c68648f5f2177d19a4d9209710df94aff176
3 files changed +42 -41
frontend/src/login.ts
+2
@@ -46,7 +46,9 @@ export async function login(username:string, password:string) {
46 }
47 finally { stopWorking() }
48 }
49 +
50 apiCall('refresh_session').then(sessionRefresher, ()=>{})
51 + .finally(()=> state.restoringSession=false)
52
53 function sessionRefresher({ exp, username }:{ exp:string, username:string }) {
54 state.username = username
frontend/src/state.ts
+2
@@ -14,6 +14,7 @@ export const state = proxy<{
14 invertOrder: boolean,
15 foldersFirst: boolean,
16 theme: string,
17 + restoringSession: boolean,
18 }>({
19 iconsClass: '',
20 username: '',
@@ -24,6 +25,7 @@ export const state = proxy<{
25 invertOrder: false,
26 foldersFirst: true,
27 theme: '',
28 + restoringSession: true,
29 })
30
31 export function useSnapState() {
frontend/src/useFetchList.ts
+38 -41
@@ -21,9 +21,9 @@ export default function useFetchList() {
21 }, [sortBy, invertOrder, foldersFirst])
22
23 useEffect(()=>{
24 - const loc = window.location
24 + if (snap.restoringSession) return // we need this to avoid double file_list just after session is restored at start (happens on slow connections)
25 if (!desiredPath.endsWith('/')) { // useful only in dev, while accessing the frontend directly without passing by the main server
26 - loc.href = loc.href + '/'
26 + window.location.href = window.location.href + '/'
27 return
28 }
29 const previous = lastPath.current
@@ -37,47 +37,44 @@ export default function useFetchList() {
37 return
38 }
39
40 - ;(async ()=>{
41 - const API = 'file_list'
42 - const baseParams = { path:desiredPath, search, sse:true, omit:'c' }
43 - let list: DirList = []
44 - setList(list)
45 - setLoading(true)
46 - setError(undefined)
40 + const API = 'file_list'
41 + const baseParams = { path:desiredPath, search, sse:true, omit:'c' }
42 + let list: DirList = []
43 + setList(list)
44 + setLoading(true)
45 + // buffering entries is necessary against burst of events that will hang the browser
46
48 - // buffering entries is necessary against burst of events that will hang the browser
49 - const buffer: DirList = []
50 - const flush = () => {
51 - const chunk = buffer.splice(0, Infinity)
52 - if (chunk.length)
53 - setList(list = sort([...list, ...chunk.map(precalculate)]))
54 - }
55 - const timer = setInterval(flush, 1000)
56 - const src = apiEvents(API, baseParams, (type, data) => {
57 - switch (type) {
58 - case 'error':
59 - state.stopSearch?.()
60 - return setError(Error(JSON.stringify(data)))
61 - case 'closed':
62 - flush()
63 - state.stopSearch?.()
64 - return setLoading(false)
65 - case 'msg':
66 - if (src?.readyState === src?.CLOSED)
67 - return state.stopSearch?.()
68 - buffer.push(data.entry)
69 - }
70 - })
71 - state.stopSearch = ()=>{
72 - buffer.length = 0
73 - setLoading(false)
74 - clearInterval(timer)
75 - state.stopSearch = undefined
76 - src.close()
47 + setError(undefined)
48 + const buffer: DirList = []
49 + const flush = () => {
50 + const chunk = buffer.splice(0, Infinity)
51 + if (chunk.length)
52 + setList(list = sort([...list, ...chunk.map(precalculate)]))
53 + }
54 + const timer = setInterval(flush, 1000)
55 + const src = apiEvents(API, baseParams, (type, data) => {
56 + switch (type) {
57 + case 'error':
58 + state.stopSearch?.()
59 + return setError(Error(JSON.stringify(data)))
60 + case 'closed':
61 + flush()
62 + state.stopSearch?.()
63 + return setLoading(false)
64 + case 'msg':
65 + if (src?.readyState === src?.CLOSED)
66 + return state.stopSearch?.()
67 + buffer.push(data.entry)
68 }
78 -
79 - })()
80 - }, [desiredPath, search, snap.username, forcer])
69 + })
70 + state.stopSearch = ()=>{
71 + buffer.length = 0
72 + setLoading(false)
73 + clearInterval(timer)
74 + state.stopSearch = undefined
75 + src.close()
76 + }
77 + }, [desiredPath, search, snap.restoringSession, snap.username, forcer])
78 return {
79 list, loading, error,
80 reload() {