Skip to content

Commit fca5681

Browse files
authored
debounce root views (#28508)
* debounce devices load * debounce others
1 parent d1b0d5b commit fca5681

File tree

3 files changed

+147
-132
lines changed

3 files changed

+147
-132
lines changed

shared/constants/devices.tsx

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as React from 'react'
22
import * as Z from '@/util/zustand'
33
import * as C from '@/constants'
44
import * as T from './types'
5+
import debounce from 'lodash/debounce'
56

67
const initialStore: T.Devices.State = {
78
deviceMap: new Map(),
@@ -22,23 +23,27 @@ export const useState_ = Z.createZustand<State>(set => {
2223
clearBadges: () => {
2324
C.ignorePromise(T.RPCGen.deviceDismissDeviceChangeNotificationsRpcPromise())
2425
},
25-
load: () => {
26-
const f = async () => {
27-
const results = await T.RPCGen.deviceDeviceHistoryListRpcPromise(undefined, waitingKey)
28-
set(s => {
29-
C.updateImmerMap(
30-
s.deviceMap,
31-
new Map(
32-
results?.map(r => {
33-
const d = rpcDeviceToDevice(r)
34-
return [d.deviceID, d]
35-
})
26+
load: debounce(
27+
() => {
28+
const f = async () => {
29+
const results = await T.RPCGen.deviceDeviceHistoryListRpcPromise(undefined, waitingKey)
30+
set(s => {
31+
C.updateImmerMap(
32+
s.deviceMap,
33+
new Map(
34+
results?.map(r => {
35+
const d = rpcDeviceToDevice(r)
36+
return [d.deviceID, d]
37+
})
38+
)
3639
)
37-
)
38-
})
39-
}
40-
C.ignorePromise(f())
41-
},
40+
})
41+
}
42+
C.ignorePromise(f())
43+
},
44+
1000,
45+
{leading: true, trailing: false}
46+
),
4247
resetState: 'default',
4348
setBadges: b => {
4449
set(s => {

shared/constants/git.tsx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as C from '.'
22
import * as T from './types'
33
import * as dateFns from 'date-fns'
44
import * as Z from '@/util/zustand'
5+
import debounce from 'lodash/debounce'
56

67
const parseRepos = (results: ReadonlyArray<T.RPCGen.GitRepoResult>) => {
78
const errors: Array<Error> = []
@@ -96,15 +97,19 @@ export const useState_ = Z.createZustand<State>((set, get) => {
9697
C.ignorePromise(wrapper())
9798
}
9899

99-
const _load = async () => {
100-
const results = await T.RPCGen.gitGetAllGitMetadataRpcPromise(undefined, loadingWaitingKey)
101-
const {errors, repos} = parseRepos(results || [])
102-
const {setGlobalError} = C.useConfigState.getState().dispatch
103-
errors.forEach(e => setGlobalError(e))
104-
set(s => {
105-
s.idToInfo = repos
106-
})
107-
}
100+
const _load = debounce(
101+
async () => {
102+
const results = await T.RPCGen.gitGetAllGitMetadataRpcPromise(undefined, loadingWaitingKey)
103+
const {errors, repos} = parseRepos(results || [])
104+
const {setGlobalError} = C.useConfigState.getState().dispatch
105+
errors.forEach(e => setGlobalError(e))
106+
set(s => {
107+
s.idToInfo = repos
108+
})
109+
},
110+
1000,
111+
{leading: true, trailing: false}
112+
)
108113
const load = () => {
109114
C.ignorePromise(_load())
110115
}

shared/constants/people.tsx

Lines changed: 112 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as T from './types'
88
import type {IconType} from '@/common-adapters/icon.constants-gen' // do NOT pull in all of common-adapters
99
import {isMobile} from './platform'
1010
import type {e164ToDisplay as e164ToDisplayType} from '@/util/phone-numbers'
11+
import debounce from 'lodash/debounce'
1112

1213
// set this to true to have all todo items + a contact joined notification show up all the time
1314
const debugTodo = false as boolean
@@ -379,121 +380,125 @@ export const useState_ = Z.createZustand<State>((set, get) => {
379380
}
380381
C.ignorePromise(f())
381382
},
382-
loadPeople: (markViewed, numFollowSuggestionsWanted = defaultNumFollowSuggestions) => {
383-
const f = async () => {
384-
// more logging to understand why this fails so much
385-
logger.info(
386-
'getPeopleData: appFocused:',
387-
'loggedIn',
388-
C.useConfigState.getState().loggedIn,
389-
'action',
390-
{markViewed, numFollowSuggestionsWanted}
391-
)
392-
393-
try {
394-
const data = await T.RPCGen.homeHomeGetScreenRpcPromise(
395-
{markViewed, numFollowSuggestionsWanted},
396-
getPeopleDataWaitingKey
383+
loadPeople: debounce(
384+
(markViewed, numFollowSuggestionsWanted = defaultNumFollowSuggestions) => {
385+
const f = async () => {
386+
// more logging to understand why this fails so much
387+
logger.info(
388+
'getPeopleData: appFocused:',
389+
'loggedIn',
390+
C.useConfigState.getState().loggedIn,
391+
'action',
392+
{markViewed, numFollowSuggestionsWanted}
397393
)
398-
const {following, followers} = C.useFollowerState.getState()
399-
const oldItems: Array<T.People.PeopleScreenItem> = (data.items ?? [])
400-
.filter(item => !item.badged && item.data.t !== T.RPCGen.HomeScreenItemType.todo)
401-
.reduce(reduceRPCItemToPeopleItem, [])
402-
const newItems: Array<T.People.PeopleScreenItem> = (data.items ?? [])
403-
.filter(item => item.badged || item.data.t === T.RPCGen.HomeScreenItemType.todo)
404-
.reduce(reduceRPCItemToPeopleItem, [])
405394

406-
if (debugTodo) {
407-
const allTodos = Object.values(T.RPCGen.HomeScreenTodoType).reduce<
408-
Array<T.RPCGen.HomeScreenTodoType>
409-
>((arr, t) => {
410-
typeof t !== 'string' && arr.push(t)
411-
return arr
412-
}, [])
413-
allTodos.forEach(avdlType => {
414-
const todoType = todoTypeEnumToType[avdlType]
415-
if (newItems.some(t => t.type === 'todo' && t.todoType === todoType)) {
416-
return
417-
}
418-
const instructions = makeDescriptionForTodoItem({
419-
legacyEmailVisibility: 'user@example.com',
420-
t: avdlType,
421-
verifyAllEmail: 'user@example.com',
422-
verifyAllPhoneNumber: '+1555000111',
423-
})
424-
let metadata: T.People.TodoMetaEmail | T.People.TodoMetaPhone | undefined
425-
if (
426-
avdlType === T.RPCGen.HomeScreenTodoType.verifyAllEmail ||
427-
avdlType === T.RPCGen.HomeScreenTodoType.legacyEmailVisibility
428-
) {
429-
metadata = makeTodoMetaEmail({
430-
email: 'user@example.com',
431-
})
432-
} else if (avdlType === T.RPCGen.HomeScreenTodoType.verifyAllPhoneNumber) {
433-
metadata = makeTodoMetaPhone({
434-
phone: '+1555000111',
395+
try {
396+
const data = await T.RPCGen.homeHomeGetScreenRpcPromise(
397+
{markViewed, numFollowSuggestionsWanted},
398+
getPeopleDataWaitingKey
399+
)
400+
const {following, followers} = C.useFollowerState.getState()
401+
const oldItems: Array<T.People.PeopleScreenItem> = (data.items ?? [])
402+
.filter(item => !item.badged && item.data.t !== T.RPCGen.HomeScreenItemType.todo)
403+
.reduce(reduceRPCItemToPeopleItem, [])
404+
const newItems: Array<T.People.PeopleScreenItem> = (data.items ?? [])
405+
.filter(item => item.badged || item.data.t === T.RPCGen.HomeScreenItemType.todo)
406+
.reduce(reduceRPCItemToPeopleItem, [])
407+
408+
if (debugTodo) {
409+
const allTodos = Object.values(T.RPCGen.HomeScreenTodoType).reduce<
410+
Array<T.RPCGen.HomeScreenTodoType>
411+
>((arr, t) => {
412+
typeof t !== 'string' && arr.push(t)
413+
return arr
414+
}, [])
415+
allTodos.forEach(avdlType => {
416+
const todoType = todoTypeEnumToType[avdlType]
417+
if (newItems.some(t => t.type === 'todo' && t.todoType === todoType)) {
418+
return
419+
}
420+
const instructions = makeDescriptionForTodoItem({
421+
legacyEmailVisibility: 'user@example.com',
422+
t: avdlType,
423+
verifyAllEmail: 'user@example.com',
424+
verifyAllPhoneNumber: '+1555000111',
435425
})
436-
}
437-
newItems.push(
438-
makeTodo({
426+
let metadata: T.People.TodoMetaEmail | T.People.TodoMetaPhone | undefined
427+
if (
428+
avdlType === T.RPCGen.HomeScreenTodoType.verifyAllEmail ||
429+
avdlType === T.RPCGen.HomeScreenTodoType.legacyEmailVisibility
430+
) {
431+
metadata = makeTodoMetaEmail({
432+
email: 'user@example.com',
433+
})
434+
} else if (avdlType === T.RPCGen.HomeScreenTodoType.verifyAllPhoneNumber) {
435+
metadata = makeTodoMetaPhone({
436+
phone: '+1555000111',
437+
})
438+
}
439+
newItems.push(
440+
makeTodo({
441+
badged: true,
442+
confirmLabel: todoTypeToConfirmLabel[todoType],
443+
icon: todoTypeToIcon[todoType],
444+
instructions,
445+
metadata,
446+
todoType,
447+
type: 'todo',
448+
})
449+
)
450+
})
451+
newItems.unshift(
452+
makeFollowedNotificationItem({
439453
badged: true,
440-
confirmLabel: todoTypeToConfirmLabel[todoType],
441-
icon: todoTypeToIcon[todoType],
442-
instructions,
443-
metadata,
444-
todoType,
445-
type: 'todo',
454+
newFollows: [
455+
makeFollowedNotification({
456+
contactDescription: 'Danny Test -- dannytest39@keyba.se',
457+
username: 'dannytest39',
458+
}),
459+
],
460+
notificationTime: new Date(),
461+
type: 'contact',
446462
})
447463
)
448-
})
449-
newItems.unshift(
450-
makeFollowedNotificationItem({
451-
badged: true,
452-
newFollows: [
453-
makeFollowedNotification({
454-
contactDescription: 'Danny Test -- dannytest39@keyba.se',
455-
username: 'dannytest39',
456-
}),
457-
],
458-
notificationTime: new Date(),
459-
type: 'contact',
460-
})
461-
)
462-
}
464+
}
463465

464-
const followSuggestions = (data.followSuggestions ?? []).reduce<Array<T.People.FollowSuggestion>>(
465-
(list, suggestion) => {
466-
const followsMe = followers.has(suggestion.username)
467-
const iFollow = following.has(suggestion.username)
468-
list.push(
469-
makeFollowSuggestion({
470-
followsMe,
471-
fullName: suggestion.fullName,
472-
iFollow,
473-
username: suggestion.username,
474-
})
475-
)
476-
return list
477-
},
478-
[]
479-
)
466+
const followSuggestions = (data.followSuggestions ?? []).reduce<Array<T.People.FollowSuggestion>>(
467+
(list, suggestion) => {
468+
const followsMe = followers.has(suggestion.username)
469+
const iFollow = following.has(suggestion.username)
470+
list.push(
471+
makeFollowSuggestion({
472+
followsMe,
473+
fullName: suggestion.fullName,
474+
iFollow,
475+
username: suggestion.username,
476+
})
477+
)
478+
return list
479+
},
480+
[]
481+
)
480482

481-
set(s => {
482-
if (!isEqual(followSuggestions, s.followSuggestions)) {
483-
s.followSuggestions = followSuggestions
484-
}
485-
if (!isEqual(newItems, s.newItems)) {
486-
s.newItems = T.castDraft(newItems)
487-
}
488-
if (!isEqual(oldItems, s.oldItems)) {
489-
s.oldItems = T.castDraft(oldItems)
490-
}
491-
})
492-
// never throw black bars
493-
} catch {}
494-
}
495-
C.ignorePromise(f())
496-
},
483+
set(s => {
484+
if (!isEqual(followSuggestions, s.followSuggestions)) {
485+
s.followSuggestions = followSuggestions
486+
}
487+
if (!isEqual(newItems, s.newItems)) {
488+
s.newItems = T.castDraft(newItems)
489+
}
490+
if (!isEqual(oldItems, s.oldItems)) {
491+
s.oldItems = T.castDraft(oldItems)
492+
}
493+
})
494+
// never throw black bars
495+
} catch {}
496+
}
497+
C.ignorePromise(f())
498+
},
499+
1000,
500+
{leading: true, trailing: false}
501+
),
497502
markViewed: () => {
498503
const f = async () => {
499504
try {

0 commit comments

Comments
 (0)