Skip to content

refactor(web): migrate NEED_REFRESH_APP_LIST_KEY to useLocalStorage/useSetLocalStorage#36908

Merged
lyzno1 merged 11 commits into
langgenius:mainfrom
ZongrongLi:main
Jun 2, 2026
Merged

refactor(web): migrate NEED_REFRESH_APP_LIST_KEY to useLocalStorage/useSetLocalStorage#36908
lyzno1 merged 11 commits into
langgenius:mainfrom
ZongrongLi:main

Conversation

@ZongrongLi
Copy link
Copy Markdown
Contributor

@ZongrongLi ZongrongLi commented Jun 1, 2026

Summary

Migrates all direct localStorage.getItem/setItem/removeItem calls for NEED_REFRESH_APP_LIST_KEY to useLocalStorage and useSetLocalStorage hooks from @/hooks/use-local-storage.

This is part of the broader refactor tracked in #36898 — one storage concern at a time.

Changes

9 source files touched, all using the same { raw: true } option for raw string storage:

Setter-only (useSetLocalStorage)

  • hooks/use-import-dsl.ts — 2 occurrences
  • app/components/app-sidebar/app-info/use-app-info-actions.ts
  • app/components/app/create-from-dsl-modal/index.tsx — 2 occurrences
  • app/components/app/create-app-modal/index.tsx
  • app/components/app/create-app-dialog/app-list/index.tsx
  • app/components/app/switch-app-modal/index.tsx
  • app/components/apps/app-card.tsx
  • app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/card-view.tsx

Getter + remover (useLocalStorage)

  • app/components/apps/list.tsx — migrated the getItem + removeItem check-and-clear pattern to useLocalStorage<string>(key, '0', { raw: true }), calling setNeedRefresh(null) to clear.

Checklist

  • TypeScript compiles with zero errors
  • All localStorage.*NEED_REFRESH_APP_LIST_KEY references in source files have been migrated

Part of #36898

…seSetLocalStorage

Replace direct localStorage.getItem/setItem/removeItem calls for
NEED_REFRESH_APP_LIST_KEY with the useLocalStorage and useSetLocalStorage
hooks from @/hooks/use-local-storage, following the pattern from
issue langgenius#36898.

Affected files (9):
- hooks/use-import-dsl.ts
- app/components/app-sidebar/app-info/use-app-info-actions.ts
- app/components/app/create-from-dsl-modal/index.tsx
- app/components/app/create-app-modal/index.tsx
- app/components/app/create-app-dialog/app-list/index.tsx
- app/components/app/switch-app-modal/index.tsx
- app/components/apps/app-card.tsx
- app/components/apps/list.tsx
- app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/card-view.tsx

All setItem calls use useSetLocalStorage<string>(key, { raw: true }).
list.tsx uses useLocalStorage<string>(key, '0', { raw: true }) for
the getItem + removeItem check-and-clear pattern.

Closes langgenius#36898
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. javascript refactor labels Jun 1, 2026
@github-actions github-actions Bot added the web This relates to changes on the web. label Jun 1, 2026
@lyzno1
Copy link
Copy Markdown
Member

lyzno1 commented Jun 2, 2026

I think this changes the behavior of NEED_REFRESH_APP_LIST_KEY in web/app/components/apps/list.tsx.

Before this PR, the app list only performed a one-shot check on mount:

if (localStorage.getItem(NEED_REFRESH_APP_LIST_KEY) === '1') {
  localStorage.removeItem(NEED_REFRESH_APP_LIST_KEY)
  refetch()
}

After the change, useLocalStorage turns the key into subscribed state:

const [needRefresh, setNeedRefresh] = useLocalStorage<string>(NEED_REFRESH_APP_LIST_KEY, '0', { raw: true })

That changes two things:

  1. When the key is missing, the hook writes the default '0' into localStorage. The old code did not write anything.
  2. The list now reacts to same-tab storage updates from useSetLocalStorage('1'), because the hook dispatches/subscribes to its custom storage event. The old code only checked the flag once on mount. In cases like app duplication from an already-mounted app list, this can add another refetch() path on top of the existing onRefresh={refetch} path.

The writer-side replacements with useSetLocalStorage(..., { raw: true }) look fine. The issue is only the reader migration in apps/list.tsx: this key is a one-shot refresh signal, not a persisted UI preference. To keep behavior equivalent, please keep the one-shot read/remove behavior here, or use a storage boundary that does not write a default value and does not subscribe to live updates.

autofix-ci Bot and others added 10 commits June 2, 2026 05:38
Keep the one-shot read/remove pattern for NEED_REFRESH_APP_LIST_KEY
in list.tsx — it's a refresh signal, not a persisted UI preference.
useLocalStorage writes default '0' and subscribes to live updates, which
adds an unintended refetch path on top of the existing onRefresh={refetch}.

Writer-side useSetLocalStorage replacements are kept as-is.

See: langgenius#36908 (comment)
- list.tsx: use useLocalStorage with undefined serverValue to avoid
  writing default '0', useEffect with [] deps for mount-only check
- Fix import sort: use-local-storage before relative imports
  and after @/context/* imports
@lyzno1 lyzno1 requested a review from zxhlyh as a code owner June 2, 2026 08:32
@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Jun 2, 2026
@lyzno1 lyzno1 enabled auto-merge June 2, 2026 08:33
@lyzno1 lyzno1 added this pull request to the merge queue Jun 2, 2026
Merged via the queue into langgenius:main with commit 99833f6 Jun 2, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer refactor size:M This PR changes 30-99 lines, ignoring generated files. web This relates to changes on the web.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants