Skip to content

Add save to Readwise Reader integration to Hacker News extension#16749

Merged
raycastbot merged 15 commits intoraycast:mainfrom
russellyeo:ext/hacker-news
Mar 3, 2025
Merged

Add save to Readwise Reader integration to Hacker News extension#16749
raycastbot merged 15 commits intoraycast:mainfrom
russellyeo:ext/hacker-news

Conversation

@russellyeo
Copy link
Contributor

@russellyeo russellyeo commented Jan 31, 2025

Description

Added optional support for saving hacker news articles to Readwise Reader.

Features

  • Securely add your API key via preferences
  • A new Action "Save to Readwise Reader" becomes available after you have added your API key
  • Performing the action will save the URL to your Readwise Reader account via the Readwise Reader API
  • Previously saved articles will show up in the list with a SavedDocument icon

Screenshots

Screenshot 2025-01-31 at 22 02 50 Screenshot 2025-01-31 at 22 04 32 Screenshot 2025-01-31 at 22 03 34 Screenshot 2025-01-31 at 21 56 51

Checklist

- Add format script
- Remove force unwrap and unused imports
- Lint
- Add publish script
- Cache saved URLs and show an accessory
- Fix import
- Add documentation
- Only show the save to readwise reader option if the token is set
- Extract readwise logic to new file
- Add action to save article to readwise reader
- Automated add to contributors
- Initial commit
@raycastbot raycastbot added extension fix / improvement Label for PRs with extension's fix improvements extension: hacker-news Issues related to the hacker-news extension labels Jan 31, 2025
@raycastbot
Copy link
Collaborator

raycastbot commented Jan 31, 2025

Thank you for your contribution! 🎉

🔔 @thomaspaulmann @GastroGeek @sxn @itsnwa @andreaselia you might want to have a look.

You can use this guide to learn how to check out the Pull Request locally in order to test it.

Due to our current reduced availability, the initial review may take up to 10-15 business days

@pernielsentikaer pernielsentikaer self-assigned this Feb 14, 2025
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.

Looks like a nice update, could you check the suggestion I made 😊

Comment on lines +2 to +6

interface Preferences {
/** Readwise API token from https://readwise.io/access_token */
readwiseToken: string;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

You don't need to manually set preference types as this is autogenerated in raycast-env.d.tsx

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah cool! Thanks for the feedback

@pernielsentikaer
Copy link
Collaborator

Could you look into the merge conflicts too?

Also, we're testing @greptileai which also wants to do a review, could you look into that it finds if it makes sense?

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 adds Readwise Reader integration to the Hacker News extension, allowing users to save articles and see visual indicators for previously saved content.

  • Added new readwise.ts module with API integration for saving articles to Readwise Reader and caching saved URLs
  • Added preferences.ts with utility functions to securely handle the Readwise API token
  • Modified utils.ts to show a visual indicator (SaveDocument icon) for previously saved articles
  • Added a new preference for the Readwise API token in package.json as a password type for security
  • In CHANGELOG.md, the new entry is correctly placed at the top with {PR_MERGE_DATE} which will be automatically replaced with the current date upon merging

💡 (1/5) You can manually trigger the bot by mentioning @greptileai in a comment!

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

<Action
icon={Icon.SaveDocument}
title="Save to Readwise Reader"
onAction={() => saveToReadwise(props.item.link || "")}
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Consider wrapping this in a try/catch block or using showFailureToast from @raycast/utils to handle errors more elegantly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Super cool that the bot knows about the components in the Raycast libraries!

The saveToReadwise function does do error handling internally and shows a success/error toast message, but I guess it would be better software design to separate the API action and the UI. I'll do that now.

Comment on lines +23 to +28
export function getReadwiseToken(): string {
const preferences = getPreferenceValues();
if (!preferences.readwiseToken) {
throw new Error("Readwise API token not configured");
}
return preferences.readwiseToken;
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Consider adding a try/catch block here similar to hasReadwiseToken() to handle potential exceptions from getPreferenceValues().

Copy link
Collaborator

Choose a reason for hiding this comment

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

You can add since we have raycast-env.d.ts available 😊

@pernielsentikaer
Copy link
Collaborator

did you add the readwiseToken in preferences?

@pernielsentikaer
Copy link
Collaborator

@greptileai can you check again 🙂

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

(updates since last review)

This PR adds Readwise Reader integration to the Hacker News extension, allowing users to save articles and displaying visual indicators for previously saved content.

  • The launchCommand function in frontpage.tsx should be wrapped in a try/catch block for better error handling
  • The showToast error handling in readwise.ts could be simplified using showFailureToast from @raycast/utils
  • The getReadwiseToken() function in preferences.ts lacks the same try/catch error handling that hasReadwiseToken() has
  • Consider adding a subtitle to the command in package.json to indicate it's from Hacker News, since there are multiple commands

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

@pernielsentikaer
Copy link
Collaborator

Can you show me a screencast of with and without the Readwise token? I don't have a token to test with 🫠

@russellyeo
Copy link
Contributor Author

russellyeo commented Mar 1, 2025

@pernielsentikaer Thanks for fixing the changelog and preferences!

I reviewed the feedback from the bot and made a couple of improvements to the code:

  • Moved the success/failure toast logic into the frontpage component for better separation of concerns (UI in one file, API request in another)
  • Changed getReadwiseToken() to return an optional string (string | undefined) instead of throwing an error, and updated usages to handle the undefined case appropriately

I also made an improvement to ensure the saved icon appears immediately by loading the saved URLs into useState and refreshing it after successful saves.

Overall the bot is pretty cool, but it seems to have made up some things (there's no launchCommand function in the code?) and some suggestions weren't that useful. However, it did make me think about other code smells in the same area, so it was still useful feedback!

Edit: The next batch of suggestions were great

@russellyeo
Copy link
Contributor Author

Here's a screencast of the changes in action 🙂

output.mp4

@russellyeo
Copy link
Contributor Author

@greptileai can you review again please? 🙂

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

(updates since last review)

The PR now includes improved error handling and state management for the Readwise Reader integration in the Hacker News extension.

  • The frontpage.tsx now properly manages saved URLs state with useState and useEffect hooks to load cached URLs when the component mounts
  • Added a dedicated handleSaveToReadwise function that handles API responses and updates the UI accordingly
  • The StoryListItem component now accepts savedUrls and onSave props to properly display saved status and handle save actions
  • The getAccessories function in utils.ts has been enhanced with an optional isSaved parameter for more flexible saved status display

4 file(s) reviewed, 2 comment(s)
Edit PR Review Bot Settings | Greptile

onSave: (url: string) => Promise<void>;
}) {
// Check if this item is in the savedUrls array
const isSaved = props.item.link ? (props.savedUrls.includes(props.item.link) || isUrlSaved(props.item.link)) : false;
Copy link
Contributor

Choose a reason for hiding this comment

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

style: This line calls both savedUrls.includes(props.item.link) and isUrlSaved(props.item.link), which seems redundant since isUrlSaved already checks the cache. Consider simplifying this logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah fair point, probably good enough to check the local state only

Comment on lines +110 to +114
const urls = getSavedUrls();
if (!urls.includes(url)) {
urls.push(url);
cache.set(CACHE_KEY, JSON.stringify(urls));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Consider adding error handling for JSON.stringify or cache.set operations in case they fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, added

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 🔥

In the next version, we can always configure it to delete the oldest one when it reaches the limit, I suppose

@russellyeo
Copy link
Contributor Author

Thanks for the review @pernielsentikaer 🙏🏻

Is there anything I need to do to get the PR merged?

@pernielsentikaer
Copy link
Collaborator

No 🙂

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

github-actions bot commented Mar 3, 2025

Published to the Raycast Store:
https://raycast.com/thomas/hacker-news

@raycastbot
Copy link
Collaborator

🎉 🎉 🎉

We've rewarded your Raycast account with some credits. You will soon be able to exchange them for some swag.

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: hacker-news Issues related to the hacker-news extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants