Skip to content

デバイスカード内の値を保持する - #47

Merged
0suu merged 1 commit into
mainfrom
34-エアコンカード内で選んだ項目がアプリ再起動でリセットされないようにする
Apr 13, 2026

Hidden character warning

The head ref may contain hidden characters: "34-\u30a8\u30a2\u30b3\u30f3\u30ab\u30fc\u30c9\u5185\u3067\u9078\u3093\u3060\u9805\u76ee\u304c\u30a2\u30d7\u30ea\u518d\u8d77\u52d5\u3067\u30ea\u30bb\u30c3\u30c8\u3055\u308c\u306a\u3044\u3088\u3046\u306b\u3059\u308b"
Merged

デバイスカード内の値を保持する#47
0suu merged 1 commit into
mainfrom
34-エアコンカード内で選んだ項目がアプリ再起動でリセットされないようにする

Conversation

@0suu

@0suu 0suu commented Apr 13, 2026

Copy link
Copy Markdown
Owner

No description provided.

@0suu

0suu commented Apr 13, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying switchbotcontroller with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6982181
Status: ✅  Deploy successful!
Preview URL: https://31c993ec.switchbotcontroller.pages.dev
Branch Preview URL: https://34.switchbotcontroller.pages.dev

View logs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6982181add

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +67 to +71
const nextValue = resolveInitialValue(storedValue, defaultValueRef.current);
latestStateRef.current = nextValue;
lastPersistedRef.current = nextValue;
hydratedRef.current = true;
setState(nextValue);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve local edits when hydration finishes

Hydration unconditionally applies the stored/default draft after electronStore.get returns, so if a user changes a control before that async read completes, their new value is overwritten by nextValue. On slower IPC/disk paths this causes visible snap-back to stale values right after opening a device card; guard this update so hydration does not clobber state that has already been edited locally.

Useful? React with 👍 / 👎.

Comment on lines +97 to +99
const valueToPersist = latestStateRef.current;
lastPersistedRef.current = valueToPersist;
void persistDeviceControlState(storageKey, valueToPersist);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark drafts persisted only after successful writes

The debounce path updates lastPersistedRef before attempting the async store write, so a failed electronStore.set is still treated as persisted and later effects skip retries because state appears in sync. In environments with transient write failures (e.g., permission/disk issues), this silently drops the latest draft until the user makes another change.

Useful? React with 👍 / 👎.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a mechanism to persist device control states as drafts using a new usePersistedDeviceControlState hook. The hook is integrated into various control components and uses an Electron store with a 250ms debounce for updates. Feedback points out that using JSON.stringify for equality checks is inefficient and potentially fragile, and that resetting state to defaults during hydration causes UI flickering. Additionally, the reliability of persisting data in the useEffect cleanup function was questioned.

Comment on lines +24 to +25
const isEqualValue = (left: unknown, right: unknown) =>
JSON.stringify(left) === JSON.stringify(right);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using JSON.stringify for deep equality checks is generally considered an anti-pattern in JavaScript/TypeScript. It is computationally expensive and fragile because property order in objects is not guaranteed to be stable (though it often is in modern engines). If the order of keys in the persisted object differs from the default object, this check will fail, leading to unnecessary writes to the store. Consider using a simple shallow equality check for flat objects or a dedicated deep equality utility.

useEffect(() => {
let cancelled = false;
hydratedRef.current = false;
setState(defaultValueRef.current);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Calling setState(defaultValueRef.current) immediately when the storageKey changes causes the UI to reset to default values before the persisted state is loaded from the store. This results in a visible "flash" of default values (e.g., a slider jumping from 50% to 80%). Consider maintaining the previous state until the new state is hydrated, or exposing a hydrated flag from the hook so the component can show a loading state or skeleton.

if (isEqualValue(latestStateRef.current, lastPersistedRef.current)) return;
const valueToPersist = latestStateRef.current;
lastPersistedRef.current = valueToPersist;
void persistDeviceControlState(keyAtMount, valueToPersist);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Executing an asynchronous operation (persistDeviceControlState) inside a useEffect cleanup function is risky. While it works for component navigation, if the application is shutting down, there is no guarantee that the IPC call will complete before the process terminates. Since this is for "draft" values, the impact is low, but it's worth noting that critical data should be persisted more reliably.

@0suu
0suu merged commit 0f01ca0 into main Apr 13, 2026
9 checks passed
@0suu
0suu deleted the 34-エアコンカード内で選んだ項目がアプリ再起動でリセットされないようにする branch April 13, 2026 11:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

エアコンカード内で選んだ項目がアプリ再起動でリセットされないようにする

1 participant