Skip to content

Commit aa15837

Browse files
authored
fix: avoid rapid polling while fetching teams in selector (hoppscotch#5485)
1 parent 53e8b28 commit aa15837

File tree

7 files changed

+55
-24
lines changed

7 files changed

+55
-24
lines changed

packages/hoppscotch-common/src/components/app/Header.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,15 +203,15 @@
203203
class="!focus-visible:text-blue-600 !hover:text-blue-600 h-8 rounded border border-blue-600/25 bg-blue-500/10 pr-8 !text-blue-500 hover:border-blue-600/20 hover:bg-blue-600/20 focus-visible:border-blue-600/20 focus-visible:bg-blue-600/20"
204204
/>
205205
</HoppSmartSelectWrapper>
206-
<template #content="{ hide }">
206+
<template #content="{ hide, state }">
207207
<div
208208
ref="accountActions"
209209
class="flex flex-col focus:outline-none"
210210
tabindex="0"
211211
@keyup.escape="hide()"
212212
@click="hide()"
213213
>
214-
<WorkspaceSelector />
214+
<WorkspaceSelector :state="state" />
215215
</div>
216216
</template>
217217
</tippy>

packages/hoppscotch-common/src/components/workspace/Selector.vue

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div ref="rootEl">
2+
<div class="flex flex-col">
33
<div class="flex flex-col">
44
<div class="flex flex-col">
55
<HoppSmartItem
@@ -81,6 +81,7 @@
8181
/>
8282
</div>
8383
</template>
84+
8485
<script setup lang="ts">
8586
import { computed, ref, watch } from "vue"
8687
import { useReadonlyStream } from "~/composables/stream"
@@ -96,11 +97,16 @@ import { useLocalState } from "~/newstore/localstate"
9697
import { defineActionHandler, invokeAction } from "~/helpers/actions"
9798
import { WorkspaceService } from "~/services/workspace.service"
9899
import { useService } from "dioc/vue"
99-
import { useElementVisibility, useIntervalFn } from "@vueuse/core"
100+
import { useIntervalFn, watchDebounced } from "@vueuse/core"
101+
import { TippyState } from "~/modules/tippy"
100102
101103
const t = useI18n()
102104
const colorMode = useColorMode()
103105
106+
const props = defineProps<{
107+
state: TippyState | null
108+
}>()
109+
104110
const showModalAdd = ref(false)
105111
106112
const currentUser = useReadonlyStream(
@@ -116,27 +122,35 @@ const teamListAdapterError = useReadonlyStream(teamListadapter.error$, null)
116122
const REMEMBERED_TEAM_ID = useLocalState("REMEMBERED_TEAM_ID")
117123
const teamListFetched = ref(false)
118124
119-
const rootEl = ref<HTMLElement>()
120-
const elVisible = useElementVisibility(rootEl)
121-
122-
const { pause: pauseListPoll, resume: resumeListPoll } = useIntervalFn(() => {
123-
if (teamListadapter.isInitialized) {
124-
teamListadapter.fetchList()
125-
}
126-
}, 10000)
127-
128-
watch(
129-
elVisible,
125+
const {
126+
pause: pauseListPoll,
127+
resume: resumeListPoll,
128+
isActive: isListPolling,
129+
} = useIntervalFn(
130130
() => {
131-
if (elVisible.value) {
131+
if (teamListadapter.isInitialized) {
132132
teamListadapter.fetchList()
133+
}
134+
},
135+
10000,
136+
{ immediate: false }
137+
)
133138
134-
resumeListPoll()
139+
// A debounced watcher to avoid rapid polling when component is mounted.
140+
// only poll when the component is visible and pause when not visible.
141+
watchDebounced(
142+
() => props.state?.isVisible,
143+
(isVisible) => {
144+
if (isVisible) {
145+
if (!isListPolling.value) {
146+
teamListadapter.fetchList()
147+
resumeListPoll()
148+
}
135149
} else {
136150
pauseListPoll()
137151
}
138152
},
139-
{ immediate: true }
153+
{ debounce: 200 }
140154
)
141155
142156
watch(myTeams, (teams) => {

packages/hoppscotch-common/src/helpers/import-export/import/hopp.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
getDefaultRESTRequest,
66
translateToNewRESTCollection,
77
HoppGQLRequest,
8-
translateToNewGQLCollection
8+
translateToNewGQLCollection,
99
} from "@hoppscotch/data"
1010
import * as A from "fp-ts/Array"
1111
import * as O from "fp-ts/Option"

packages/hoppscotch-common/src/modules/tippy.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ import "tippy.js/animations/scale-subtle.css"
66
import "tippy.js/dist/border.css"
77
import "tippy.js/dist/svg-arrow.css"
88

9+
export type TippyState = {
10+
isEnabled: boolean
11+
isVisible: boolean
12+
isDestroyed: boolean
13+
isMounted: boolean
14+
isShown: boolean
15+
}
16+
917
export default <HoppModule>{
1018
onVueAppInit(app) {
1119
app.use(VueTippy)

packages/hoppscotch-common/src/newstore/collections.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
HoppRESTHeaders,
99
HoppRESTRequest,
1010
makeCollection,
11-
GQLHeader
11+
GQLHeader,
1212
} from "@hoppscotch/data"
1313
import { cloneDeep } from "lodash-es"
1414
import { pluck } from "rxjs/operators"

packages/hoppscotch-common/src/platform/std/kernel-interceptors/agent/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { Service } from "dioc"
22
import { markRaw } from "vue"
3-
import {
4-
body,
5-
relayRequestToNativeAdapter,
3+
import {
4+
body,
5+
relayRequestToNativeAdapter,
66
RelayRequest,
77
RelayResponse,
8-
RelayCapabilities
8+
RelayCapabilities,
99
} from "@hoppscotch/kernel"
1010
import * as E from "fp-ts/Either"
1111
import { pipe } from "fp-ts/function"

packages/hoppscotch-common/src/services/team-collection.service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,15 @@ export class TeamCollectionsService extends Service<void> {
10591059
collections.forEach((coll) => this.entityIDs.add(`collection-${coll.id}`))
10601060
requests.forEach((req) => this.entityIDs.add(`request-${req.id}`))
10611061

1062+
this.collections.value = [...tree]
1063+
} catch (error) {
1064+
console.error(`Error expanding collection ${collectionID}:`, error)
1065+
1066+
// Set empty arrays instead of leaving as null to prevent future expansion attempts
1067+
// This prevents the infinite loop by ensuring the collection is marked as expanded
1068+
collection.children = []
1069+
collection.requests = []
1070+
10621071
this.collections.value = [...tree]
10631072
} finally {
10641073
this.loadingCollections.value = this.loadingCollections.value.filter(

0 commit comments

Comments
 (0)