Skip to content

Update 1bookmark extension#18163

Merged
raycastbot merged 4 commits intoraycast:mainfrom
1bookmark-bot:ext/1bookmark
Mar 28, 2025
Merged

Update 1bookmark extension#18163
raycastbot merged 4 commits intoraycast:mainfrom
1bookmark-bot:ext/1bookmark

Conversation

@1bookmark-bot
Copy link
Contributor

@1bookmark-bot 1bookmark-bot commented Mar 26, 2025

Description

  • 💻 Remove jotai which causes unnecessary re-renders in raycast environment.
  • 💻 Fix some infinite re-render issue.

Screencast

This is not a UI change.

Checklist

@raycastbot raycastbot added extension fix / improvement Label for PRs with extension's fix improvements extension: 1bookmark Issues related to the 1bookmark extension OP is author The OP of the PR is the author of the extension labels Mar 26, 2025
@raycastbot
Copy link
Collaborator

Thank you for the update! 🎉

You can expect an initial review within five business days.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

This PR updates the 1bookmark extension by removing jotai dependency and implementing performance optimizations to prevent unnecessary re-renders in the Raycast environment.

  • Replaced jotai atoms with useCachedState from @raycast/utils across multiple components for more efficient state management
  • Added new useLoggedOutStatus hook to centralize authentication state and cache clearing logic
  • Introduced useTags hook with proper caching to optimize tag data fetching and management
  • Implemented extensive memoization using useMemo in browser bookmark hooks to prevent unnecessary recalculations
  • Extracted TRPC client setup and error handling into separate utility files for better code organization

The changes appear well-structured and follow Raycast's guidelines, focusing on performance optimization while maintaining functionality.

24 file(s) reviewed, 6 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines +229 to +231
const folders = useMemo(() => {
return root.filter((item) => containerIds.includes(item.parentID ?? "")).flatMap((item) => getFolders(root, item));
}, [root, containerIds]);
Copy link
Contributor

Choose a reason for hiding this comment

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

style: The folders calculation depends on root.filter() result but root itself is already memoized. Consider moving the filter operation inside the root useMemo to reduce the number of memoized values.

Choose a reason for hiding this comment

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

This code review is not a good suggestion. Here's why:

Separation of Concerns

  • root is responsible for simply fetching all bookmark items.
  • folders is responsible for creating the folder structure for the current profile using containerIds.
  • Separating these two logics improves code readability and maintainability.

Dependency Management

  • root only depends on container.
  • folders depends on both root and containerIds.
  • If we include filtering in root, it would make root depend on containerIds as well, making dependencies more complex.

Reusability

  • The current structure allows root to provide pure bookmark items that can be used without filtering in other places if needed.
  • If we include filtering in root, we would have to use filtered results even when filtering is not needed.

Performance

  • root is only recalculated when container changes.
  • folders is only recalculated when either root or containerIds changes.
  • The current structure provides more efficient memoization.

Therefore, maintaining the current code is a better choice. The code review suggestion seems to be focused on reducing code lines, but it could actually harm the code's structure and maintainability.

Comment on lines 41 to 45
useEffect(() => {
if (!r.data) return;

cache.set("bookmarks", JSON.stringify(r.data));
setCached(r.data);
}, [r.data]);
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: Missing dependency array items. setCached should be included in the useEffect dependencies to prevent stale closure issues.

Suggested change
useEffect(() => {
if (!r.data) return;
cache.set("bookmarks", JSON.stringify(r.data));
setCached(r.data);
}, [r.data]);
useEffect(() => {
if (!r.data) return;
setCached(r.data);
}, [r.data, setCached]);

Choose a reason for hiding this comment

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

I applied the code you suggested.

Comment on lines +4 to +5
import { RouterOutputs, trpc } from "@/utils/trpc.util";
import { cache } from "../views/MyAccount";
Copy link
Contributor

Choose a reason for hiding this comment

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

style: importing cache from a view file (MyAccount) could create circular dependencies - consider moving cache to a separate utils file

Choose a reason for hiding this comment

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

I don't think it's important because I only use it in MyAccount and here. I'll consider it when I use it in more places.

Comment on lines +47 to +50
if (now.getTime() - signOutDate.getTime() < 1000) {
setAfter1Sec(false);
setTimeout(() => setAfter1Sec(true), 1000);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: potential race condition with multiple setTimeouts - consider using a ref to track and clear previous timeout

Choose a reason for hiding this comment

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

I applied the code you suggested.

Comment on lines +67 to +68
// eslint-disable-next-line @typescript-eslint/no-explicit-any
headers: headers as any,
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Unsafe type assertion to 'any'. Consider defining proper types for the headers object.

Choose a reason for hiding this comment

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

I don't have a good idea right now, so I'll improve it next time.

@raycast raycast deleted a comment from greptile-apps bot Mar 27, 2025
@pernielsentikaer
Copy link
Collaborator

Hi @1bookmark-bot👋

Thanks for your contribution 🔥

Can you check greptile feedback?

@pernielsentikaer pernielsentikaer self-assigned this Mar 27, 2025
@b6pzeusbc54tvhw5jgpyw8pwz2x6gs
Copy link
Contributor

@pernielsentikaer I checked all the reviews. Thank you always!😄

Copy link
Collaborator

@pernielsentikaer pernielsentikaer left a comment

Choose a reason for hiding this comment

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

Hi 👋

Looks good to me, approved 🔥

@raycastbot raycastbot merged commit e5f0f58 into raycast:main Mar 28, 2025
2 checks passed
@github-actions
Copy link
Contributor

Published to the Raycast Store:
https://raycast.com/onebookmark/1bookmark

@raycastbot
Copy link
Collaborator

🎉 🎉 🎉

Such a great contribution deserves a reward, but unfortunately we couldn't find your Raycast account based on your GitHub username (@1bookmark-bot).
Please link your GitHub account to your Raycast account to receive your credits and soon be able to exchange them for some swag.

@1bookmark-bot 1bookmark-bot deleted the ext/1bookmark branch March 30, 2025 06:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extension fix / improvement Label for PRs with extension's fix improvements extension: 1bookmark Issues related to the 1bookmark extension OP is author The OP of the PR is the author of the extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants