Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚀feat: shared links #2659

Closed
wants to merge 30 commits into from
Closed

Conversation

ohneda
Copy link
Contributor

@ohneda ohneda commented May 10, 2024

Summary

I implemented a shared link feature similar to ChatGPT.

SCR-20240510-cubd

SCR-20240510-cufy

SCR-20240510-culz

I was aware of the discussions mentioned below, but I thought there might be a use case separate from exporting, so I decided to implement it.
#2095
#1883
If this feature is deemed unnecessary, please feel free to reject it.

Change Type

Please delete any irrelevant options.

  • New feature (non-breaking change which adds functionality)

Changes

  • Added Share to the conversation action list
  • Conversations with a shared link can be viewed by anyone without authentication at /share/${shareId}
  • Added "Shared links" to the Data section in Settings. You can view the list of shared links and delete them.

Specifications

The implementation largely follows the specifications of ChatGPT's SharedLink.
The shared messages become a snapshot at the time the shared link is created. Even if messages are added after the shared link is created, they will not be shared.
If you want to update the shared messages, click the Share button again and update the link.
The messages used in the UI are also the same as in ChatGPT. If they are inappropriate, I will modify them to use different messages.

Key modifications

  • Refactored the functions for adding, updating, and deleting cache in client/src/utils/convos.ts to make them more generic. These processes are also necessary for shared links.
    • Confirmed that all existing test cases pass.
  • Similarly, useNavScrolling needed to be used in the shared link table, so I introduced a generic type to make it more versatile.
  • Separated the JSX for Endpoints icons from client/src/components/Endpoints/Icon.tsx. This is to display the endpoint icons in shared link view that do not require authentication.
    • I confirmed that a similar client/src/components/Endpoints/EndpointIcon.tsx has already been created, but I wanted to use the same icons currently used in messages, so I made it a separate component. These may be inappropriate as duplicate code. If it's better to use EndpointIcon.tsx, I will refactor it.
  • I used lucide-react for icons representing links and copying, but if it's better to use the icons under components/svg, I will modify it.
  • The sharedlinks document in mongodb has two unused properties: isVisible and isAnonymous. isAnonymous was intended to share the user's icon and name when set to false, but it is not currently implemented.isVisible is also not currently used, but was added because it was an attribute of OpenAI API, but it might be better to remove it.
  • Since the messages are subject to change, translations of the messages have been added to each language, leaving the English translation.

Regarding the view components for shared links

I wanted to reuse the view components of messages as much as possible, but I had to create new components for parts that couldn't be reused, such as those requiring authentication.
Some places have duplicate code, but I didn't perform excessive refactoring to avoid potential conflicts with other commits.

Security concerns

I was careful not to include the conversation owner's information in the APIs used by views that do not require authentication.
However, I am not fully aware of the specifications of all endpoints, so there may be some oversights.
If you could point out any areas to double-check, I will conduct further verification.

Testing

I confirmed that the existing test cases pass for client/src/components/utils/convos.ts, which underwent a major refactoring.
I also added unit tests for client/src/components/utils/sharedLink.ts, which uses the newly introduced collection.ts.

I haven't added unit tests for the components, but I have manually verified the following:

  • A share button has been added to the conversation list in the navigation.
  • Clicking the share button displays the shared link dialog.
  • When the shared link dialog is displayed, a sharedlinks document with isPublic = false is created in mongodb.
  • Conversations with isPublic == false are not displayed even when accessing the shared link URL.
  • For conversations which don't have a shared link, the label of the share button is "Create link."
  • Clicking "Create link" updates the sharedlinks document in mongodb to isPublic = true.
  • Even if new messages are added to a conversation of a shared link, they are not displayed at the shared link URL.
  • For conversations with an existing shared link, the label of the share button is "Update link".
  • Clicking "Update link" updates the shared link messages to the latest state.
  • A "Shared links" section has been added to Settings -> Data controls.
  • Clicking the Manage button in Shared links displays a list of shared conversations.
  • If there are no shared conversations, "You have no shared links." is displayed.
  • Initially, 25 shared conversations are displayed.
  • If there are many shared conversations, they are scrolled.
  • After scrolling, the conversations are automatically paginated by 25.
  • On the right side of each row in the list of shared conversations, a delete button is displayed, and a Tooltip is shown on mouseover.
  • Clicking the delete button for a shared conversation immediately deletes it.

Checklist

Please delete any irrelevant options.

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

ohneda added 15 commits May 9, 2024 22:24
Added functions for retrieving, creating, updating, and deleting shared links and shared messages.
…reId

Adds a new hook `useGetSharedMessages` which fetches shared messages based on the provided shareId.
The GET /api/share/${shareId} is exposed to the public, so authentication is not required. Other paths require authentication.
Introduces generic functions for manipulating react-query cache entries, marking a refinement in how query cache data is managed. It aims to enhance the flexibility and reusability of the cache interaction patterns within our application.

- Replaced specific index names with more generic terms in queries.ts, enhancing consistency across data handling functions.
- Introduced new utility functions in collection.ts for adding, updating, and deleting data entries in an InfiniteData<TCollection>. These utility functions (`addData`, `updateData`, `deleteData`, `findPage`) are designed to be re-usable across different data types and collections.
- Adapted existing conversation utility functions in convos.ts to leverage these new generic utilities.
implemented new utility functions to handle additions, updates, and deletions in the shared link cache list.
- Added a share button in each conversation in the conversation list.
- Implemented functionality where clicking the share button triggers a POST request to the API.
- The API checks if a share link was already created for the conversation today; if so, it returns the existing link.
- If no link was created for today, the API will create a new share link and return it.
- Each click on the share button results in a new API request, following the specification similar to ChatGPT's share link feature.
- Modified `useNavScrolling` to accept a generic type parameter `TData`, allowing it to be used with different data structures besides `ConversationListResponse`.
- Updated instances in `Nav.tsx` and `ArchivedChatsTable.tsx` to explicitly specify `ConversationListResponse` as the type argument when invoking `useNavScrolling`.
…ality in settings

- Integrated a delete button for each shared link in the table, allowing users to remove links as needed.
- Modified the useGetSharedMessages hook to return not only a list of TMessage but also the TSharedLink itself.
- This change was necessary to support displaying the title and date in the Shared Message UI, which requires data from TSharedLink.
…ut authentication

- Implemented a new UI component to display shared conversations, designed to be accessible without requiring authentication.
- Reused components from the authenticated Messages module where possible. Copied and adapted components that could not be directly reused to fit the non-authenticated context.
Translate labels only. Messages remain in English as they are possibly subject to change.
@ohneda ohneda changed the title Feature/shared link 🚀feat: shared links May 10, 2024
@danny-avila danny-avila added this to the v0.7.3 milestone May 10, 2024
@danny-avila
Copy link
Owner

danny-avila commented May 10, 2024

Thanks so much for this. I'm planning to cut a release today so I will include this as part of v0.7.3

Also this was recently added in the header. i would like to keep it as one icon so maybe a share icon, with a dropdown similar to the one for conversations that gives share/export options?

image

@ohneda
Copy link
Contributor Author

ohneda commented May 11, 2024

@danny-avila Thanks for checking this out. That sounds like a good idea. How does this look? Do you have any ideas for icons?
SCR-20240510-rhug

@danny-avila
Copy link
Owner

@danny-avila Thanks for checking this out. That sounds like a good idea. How does this look? Do you have any ideas for icons?

Looks good! it can be this icon for the main button:
image

The export icon is fine, and the share icon can be this: https://lucide.dev/icons/share-2

* moved icon and popover to arguments so that EditMenuButton can be reused.
* modified so that when a ShareButton is closed, the parent DropdownMenu is also closed.
* More accurate naming of the dropdown menu.
* When the export button is closed, the parent dropdown menu is also closed.
@ohneda
Copy link
Contributor Author

ohneda commented May 14, 2024

@danny-avila I changed the Export button in the message view to a dropdown menu that now displays both the Export and Share buttons. Please feel free to let me know if any other areas need to be improved or adjusted.

dropdown.mov

* display error message when API is down
* add loading animation to Login form while fetching data
* optimize startupConfig to fetch data only on initial render to prevent unnecessary API calls
@danny-avila
Copy link
Owner

Checking this out now, will resolve the conflict. Similar to the other PR, may close and open a new one.

@danny-avila
Copy link
Owner

would like to support branching here, looking into it

image
image

@ohneda
Copy link
Contributor Author

ohneda commented May 17, 2024

Hey, the conflict is resolved.

would like to support branching here, looking into it

Does this mean you want to fork messages shared by others?

@danny-avila
Copy link
Owner

Hey, the conflict is resolved.

would like to support branching here, looking into it

Does this mean you want to fork messages shared by others?

No there can be message branches in a conversation, and I saw they were actually included in the response data but with no ability to view them. You had most of the logic built out so adding this feature was easy!

@danny-avila danny-avila mentioned this pull request May 17, 2024
7 tasks
@danny-avila
Copy link
Owner

Closing for #2772

@ohneda ohneda deleted the feature/shared-link branch May 22, 2024 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

None yet

2 participants