Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThis update removes the Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant RC as ReplyCompose Component
participant AI as generateAIResponse Function
participant API as OpenAI API
User->>RC: Clicks AI suggestion button
RC->>AI: Invokes handleAIButtonClick()
AI->>API: Sends POST request with prompt and thread content
API-->>AI: Returns AI-generated email reply
AI-->>RC: Sends back generated suggestion
RC->>User: Updates UI with AI suggestion options
Suggested reviewers
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
apps/mail/components/create/prosemirror.css (1)
223-223: Confirm the spacing and readability changes.A line was removed around paragraph or list styles. Ensure these adjustments, including the reduced margin and line-height, don’t negatively impact readability for users on various screen sizes.
apps/mail/app/api/ai-reply/route.ts (1)
16-16: Remove unused request parameters.
userNameanduserEmailare being destructured from the request body but never used. Consider removing them or incorporating them if needed.apps/mail/components/mail/reply-composer.tsx (3)
32-40: Consider implementing or removing the unused resizing logic.The
editorHeight,isResizing, and associated refs (resizeStartY,startHeight) are declared but never updated nor utilized inside the component. If a dynamic editor resizing feature is planned, handle the relevant mouse or touch events to adjust the editor height accordingly.
230-324: Add robust tests and modularize complex logic.The
createAIJsonContentfunction is fairly extensive:
- Consider dividing the signature detection and paragraph generation into smaller helper utilities for clarity and maintainability.
- Unit tests would help ensure that edge cases (multiple paragraphs, unusual signatures, no newline between paragraphs, etc.) are handled correctly.
Would you like assistance writing such tests or splitting out helpers?
422-449: Enhance rich text support if needed.Currently,
convertJSONToHTMLhandles plain text paragraphs. If the user wishes to preserve styling (bold, italic, lists, etc.), consider extending or replacing this logic with a robust ProseMirror or Markdown-to-HTML solution.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (5)
apps/mail/app/api/ai-reply/route.ts(1 hunks)apps/mail/components/create/editor.tsx(0 hunks)apps/mail/components/create/prosemirror.css(2 hunks)apps/mail/components/mail/reply-composer.tsx(6 hunks)package.json(1 hunks)
💤 Files with no reviewable changes (1)
- apps/mail/components/create/editor.tsx
🔇 Additional comments (11)
package.json (1)
39-41:Details
✅ Verification successful
Verify the newly introduced OpenAI dependency.
You've added
"openai": "^4.89.1"under dependencies. It's good practice to confirm that the chosen version is stable and free of known security or compatibility issues.Below is a script to check the latest published version on npm and query GitHub advisories for potential security issues:
🏁 Script executed:
#!/bin/bash # Check the latest published version of openai on npm npm info openai version # Search GitHub Security Advisories for openai (NPM ecosystem) gh api graphql -f query=' { securityVulnerabilities(first: 5, ecosystem: NPM, package: "openai") { nodes { advisory { summary severity publishedAt } vulnerableVersionRange firstPatchedVersion { identifier } } } }'Length of output: 372
OpenAI Dependency Verified – No Concerns Detected
The npm query shows the latest published version is 4.90.0, and since your dependency is set to
"^4.89.1", it will accommodate the minor update. Additionally, GitHub's security advisory check returned no vulnerabilities. This indicates the version range you chose is stable and safe.apps/mail/app/api/ai-reply/route.ts (1)
1-89: Overall implementation of the AI reply endpoint looks good.The error handling flow is well structured, and the OpenAI integration is straightforward. Apart from the unauthorized status code mismatch and unused parameters, the route logic is clear and consistent.
apps/mail/components/mail/reply-composer.tsx (9)
6-6: No major concerns with the new icon imports.
16-16: Importing JSONContent appears correct.
374-403: Good approach to asynchronous error handling.The try/catch pattern gracefully provides user feedback upon failures. Logging errors and displaying fallback messages help maintain a smooth user experience.
405-420: Verify overwriting existing user content in the editor.Accepting the AI suggestion completely replaces the editor content, potentially discarding user-authored text already present. Confirm whether this is the intended UX or if a more merged approach is preferred.
451-461: AI state reset and rejection look good.No issues noted. Cleanly resets all AI-related variables and re-initializes the editor.
527-533: Conditional AI notice is straightforward.The AI options banner is clearly visible and does not disrupt the rest of the UI.
541-550: Displaying AI suggestions with custom styling makes sense.Conditionally adding borders and a themed background for AI content is intuitive and enhances user awareness.
577-596: Spinner-based feedback is a nice UX touch.Users receive an immediate visual indicator while waiting for the AI draft to generate.
597-623: Accept/Reject controls are logically structured.The minimal button UI with toast feedback ensures users can either finalize or discard AI-generated replies swiftly.
| const generateAIResponse = async (): Promise<string> => { | ||
| try { | ||
| // Extract relevant information from the email thread for context | ||
| const latestEmail = emailData[emailData.length - 1]; | ||
| const originalSender = latestEmail?.sender?.name || 'the recipient'; | ||
|
|
||
| // Create a summary of the thread content for context | ||
| const threadContent = emailData | ||
| .map((email) => { | ||
| return ` | ||
| From: ${email.sender?.name || 'Unknown'} <${email.sender?.email || 'unknown@email.com'}> | ||
| Subject: ${email.subject || 'No Subject'} | ||
| Date: ${new Date(email.receivedOn || '').toLocaleString()} | ||
|
|
||
| ${email.decodedBody || 'No content'} | ||
| `; | ||
| }) | ||
| .join('\n---\n'); | ||
|
|
||
|
|
||
| // Call the AI API endpoint | ||
| const response = await fetch('/api/ai-reply', { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify({ | ||
| threadContent, | ||
| originalSender, | ||
| }), | ||
| }); | ||
|
|
||
| // Store the response data | ||
| const responseData = await response.json(); | ||
|
|
||
| console.log(responseData); | ||
|
|
||
| if (!response.ok) { | ||
| throw new Error(responseData.error || 'Failed to generate AI response'); | ||
| } | ||
|
|
||
| return responseData.reply; | ||
| } catch (error) { | ||
| console.error('Error generating AI response:', error); | ||
| throw error; | ||
| } | ||
| }; |
There was a problem hiding this comment.
Beware of possible PII leakage to external AI service.
Your code sends the raw email thread to the AI endpoint, including sender names/addresses and the full message body. Verify compliance with privacy policies, considering anonymizing or masking sensitive content. Ensure explicit user consent if needed.
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (8)
apps/mail/components/create/editor.tsx (1)
401-402: Consider relaxing the click area for focusing the editor
Currently, the code strictly checkse.target === containerRef.current. This might force the user to click only on the outer container to focus the editor. If you'd like to allow focusing by clicking anywhere inside the container, consider usingcontainerRef.current.contains(e.target).apps/mail/actions/ai-reply.ts (1)
6-29: Consider using a more accurate tokenizer
The rough estimate of tokens (characters/4) may not handle corner cases. Integrating a more precise token counting approach would help if token usage is critical in your application.apps/mail/lib/utils.ts (1)
246-341: Enhance signature detection for broader coverage
The sign-off detection logic focuses on a limited set of English patterns. If you plan to support other languages or custom sign-offs, consider expanding the detection regex or allowing user-defined sign-off patterns.apps/mail/components/mail/reply-composer.tsx (5)
339-353: Improve error handling with more specific error types.The error handling uses a catch-all approach with generic error messages. Consider using more specific error types or codes from the AI service to provide more actionable feedback to users.
- catch (error: any) { + catch (error: Error | unknown) { console.error('Error generating AI response:', error); let errorMessage = 'Failed to generate AI response. Please try again or compose manually.'; - if (error.message) { + if (error instanceof Error && error.message) { if (error.message.includes('OpenAI API')) { errorMessage = 'AI service is currently unavailable. Please try again later.'; } else if (error.message.includes('key is not configured')) { errorMessage = 'AI service is not properly configured. Please contact support.'; } }
352-352: Add telemetry for AI errors.Consider adding telemetry or logging for AI generation errors to help identify patterns and improve the service.
440-445: Consider adding a way to dismiss AI suggestions.The UI shows AI options with accept/reject buttons but doesn't provide a way to simply dismiss the suggestion banner without taking action.
{aiState.showOptions && ( <div className="flex items-center gap-2 px-2 py-1 bg-blue-50 dark:bg-blue-950 rounded-md text-xs"> <Sparkles className="h-3.5 w-3.5 text-[#016FFE]" /> <span className="text-[#016FFE] dark:text-[#016FFE]">AI reply suggestion. Review and edit before sending.</span> + <Button + variant="ghost" + size="icon" + className="ml-auto h-5 w-5" + onClick={(e) => { + e.preventDefault(); + aiDispatch({ type: 'SET_SHOW_OPTIONS', payload: false }); + }} + > + <X className="h-3 w-3" /> + </Button> </div> )}
311-331: Consider rate limiting or caching AI requests.The
handleAIButtonClickfunction directly calls the AI service without any rate limiting or caching. Consider implementing mechanisms to prevent abuse and improve performance.
456-459: Improve styling consistency.The conditional styling uses both string concatenation and the
cnutility. Consider usingcnconsistently for all conditional class combinations.className={cn( "sm:max-w-[600px] md:max-w-[2050px]", - aiState.showOptions ? "border border-blue-200 dark:border-blue-800 rounded-md bg-blue-50/30 dark:bg-blue-950/30 p-1" : "" + { + "border border-blue-200 dark:border-blue-800 rounded-md bg-blue-50/30 dark:bg-blue-950/30 p-1": aiState.showOptions + } )}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/mail/actions/ai-reply.ts(1 hunks)apps/mail/components/create/editor.tsx(1 hunks)apps/mail/components/mail/reply-composer.tsx(11 hunks)apps/mail/lib/utils.ts(1 hunks)
🔇 Additional comments (6)
apps/mail/actions/ai-reply.ts (2)
1-5: Good usage of the server directive
'use server'ensures the code runs server-side, aligning well with server-only logic.
31-100: Ensure secure usage of user data
Verify that the user-providedthreadContentandoriginalSenderdo not contain sensitive or personally identifiable data that might be inadvertently exposed. Be mindful not to log or leak theOPENAI_API_KEY.Would you like me to provide a script to check for potential PII in user input?
apps/mail/components/mail/reply-composer.tsx (4)
319-329: Beware of possible PII leakage to external AI service.Your code sends the raw email thread to the AI endpoint, including sender names/addresses and the full message body. Verify compliance with privacy policies, considering anonymizing or masking sensitive content. Ensure explicit user consent if needed.
101-108: Good use of reducer for composite state management.Using
useReducerinstead of multipleuseStatehooks improves code maintainability and state transitions clarity.
486-530: Well-implemented UI for AI suggestion workflow.The conditional rendering for AI suggestions with loading state, accept/reject options, and appropriate visual feedback is well implemented.
7-7:Details
✅ Verification successful
Check utility function imports.
The line imports multiple utility functions, including new ones like
convertJSONToHTMLandcreateAIJsonContent. Ensure these functions are properly implemented and exported from@/lib/utils.
🏁 Script executed:
#!/bin/bash # Check if the utility functions are properly implemented rg --type ts --type tsx "export function (convertJSONToHTML|createAIJsonContent)" -A 10Length of output: 117
The previous command errored out due to an unrecognized file type ("tsx"). Please run the above script to verify that
convertJSONToHTMLandcreateAIJsonContentare correctly implemented and exported from@/lib/utils. Once you confirm the results, we can decide if further refactoring or changes are needed.
🏁 Script executed:
#!/bin/bash # Re-run the utility function search with corrected file globs for TypeScript files rg -g "*.{ts,tsx}" "export function convertJSONToHTML" -A 10 rg -g "*.{ts,tsx}" "export function createAIJsonContent" -A 10Length of output: 249
The above commands will help verify whether the utility functions
convertJSONToHTMLandcreateAIJsonContentare implemented and properly exported from the@/lib/utilsmodule. Please run them and manually inspect the output to ensure the functions exist in the expected files (e.g.src/lib/utils.tsorsrc/lib/utils/index.ts).Ensure proper exports for utility functions in
@/lib/utils.
- The import statement now includes
convertJSONToHTMLandcreateAIJsonContent.- Please confirm these functions are exported in the utility file.
- Verify the export definitions using the commands above.
🏁 Script executed:
#!/bin/bash echo "Listing potential utility files matching '@/lib/utils':" fd -HI "utils\.(ts|tsx)$" echo "Searching for export definitions of convertJSONToHTML:" rg -g "*.{ts,tsx}" "(export (function|const|let|var).*convertJSONToHTML)" -A 5 echo "Searching for export definitions of createAIJsonContent:" rg -g "*.{ts,tsx}" "(export (function|const|let|var).*createAIJsonContent)" -A 5Length of output: 1709
Utility imports verification complete:
The utility functionsconvertJSONToHTMLandcreateAIJsonContentare correctly implemented and exported fromapps/mail/lib/utils.ts(as verified by searching the export definitions). Please double-check that the other imported functions (cleanEmailAddress,truncateFileName, andcn) remain properly implemented and exported.
|
|
||
| export const convertJSONToHTML = (json: any): string => { | ||
| if (!json) return ""; | ||
|
|
||
| // Handle different types | ||
| if (typeof json === "string") return json; | ||
| if (typeof json === "number" || typeof json === "boolean") return json.toString(); | ||
| if (json === null) return ""; | ||
|
|
||
| // Handle arrays | ||
| if (Array.isArray(json)) { | ||
| return json.map(item => convertJSONToHTML(item)).join(""); | ||
| } | ||
|
|
||
| // Handle objects (assuming they might have specific email content structure) | ||
| if (typeof json === "object") { | ||
| // Check if it's a text node | ||
| if (json.type === "text") { | ||
| let text = json.text || ""; | ||
|
|
||
| // Apply formatting if present | ||
| if (json.bold) text = `<strong>${text}</strong>`; | ||
| if (json.italic) text = `<em>${text}</em>`; | ||
| if (json.underline) text = `<u>${text}</u>`; | ||
| if (json.code) text = `<code>${text}</code>`; | ||
|
|
||
| return text; | ||
| } | ||
|
|
||
| // Handle paragraph | ||
| if (json.type === "paragraph") { | ||
| return `<p>${convertJSONToHTML(json.children)}</p>`; | ||
| } | ||
|
|
||
| // Handle headings | ||
| if (json.type?.startsWith("heading-")) { | ||
| const level = json.type.split("-")[1]; | ||
| return `<h${level}>${convertJSONToHTML(json.children)}</h${level}>`; | ||
| } | ||
|
|
||
| // Handle lists | ||
| if (json.type === "bulleted-list") { | ||
| return `<ul>${convertJSONToHTML(json.children)}</ul>`; | ||
| } | ||
|
|
||
| if (json.type === "numbered-list") { | ||
| return `<ol>${convertJSONToHTML(json.children)}</ol>`; | ||
| } | ||
|
|
||
| if (json.type === "list-item") { | ||
| return `<li>${convertJSONToHTML(json.children)}</li>`; | ||
| } | ||
|
|
||
| // Handle links | ||
| if (json.type === "link") { | ||
| return `<a href="${json.url}">${convertJSONToHTML(json.children)}</a>`; | ||
| } | ||
|
|
||
| // Handle images | ||
| if (json.type === "image") { | ||
| return `<img src="${json.url}" alt="${json.alt || ''}" />`; | ||
| } | ||
|
|
||
| // Handle blockquote | ||
| if (json.type === "block-quote") { | ||
| return `<blockquote>${convertJSONToHTML(json.children)}</blockquote>`; | ||
| } | ||
|
|
||
| // Handle code blocks | ||
| if (json.type === "code-block") { | ||
| return `<pre><code>${convertJSONToHTML(json.children)}</code></pre>`; | ||
| } | ||
|
|
||
| // If it has children property, process it | ||
| if (json.children) { | ||
| return convertJSONToHTML(json.children); | ||
| } | ||
|
|
||
| // Process all other properties | ||
| return Object.values(json).map(value => convertJSONToHTML(value)).join(""); | ||
| } | ||
|
|
||
| return ""; | ||
| }; |
There was a problem hiding this comment.
Sanitize user input to prevent XSS
When converting JSON to HTML, any raw text or user-provided URLs can introduce cross-site scripting vulnerabilities. Consider sanitizing or escaping these values before rendering.
- return text;
+ // Example pseudocode:
+ // const safeText = sanitizeHtml(text);
+ // return safeText;Committable suggestion skipped: line range outside the PR's diff.
| import type { JSONContent } from 'novel'; | ||
| import { useForm } from "react-hook-form"; | ||
| import type { z } from "zod"; | ||
| import { generateAIResponse } from '@/actions/ai-reply'; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify AI service integration security.
The code now imports and uses generateAIResponse from @/actions/ai-reply.ts. Ensure this server action implements proper security measures such as rate limiting, authentication, and API key protection.
🏁 Script executed:
#!/bin/bash
# Check the implementation of the AI reply generation function
fd "ai-reply.ts" --type f --exec cat {} \;Length of output: 3261
Security Review Update
The implementation correctly performs authentication (via session validation) and checks for the presence of the OpenAI API key. However, the server action does not appear to implement rate limiting. Please consider adding rate limiting (or other abuse mitigation techniques) to further secure the AI service integration.
|
|
||
| const formattedMessage = messageContent; | ||
| const formattedMessage = form.getValues('messageContent'); | ||
|
|
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Potential type mismatch for formattedMessage.
The form.getValues('messageContent') might not return the expected HTML string format needed by constructReplyBody depending on how the Editor component provides its output.
🏁 Script executed:
#!/bin/bash
# Search for the implementation of `convertJSONToHTML` function to understand the expected format
rg --type ts --type tsx "convertJSONToHTML" -A 5 -B 5Length of output: 81
🏁 Script executed:
#!/bin/bash
# Re-run the search for the implementation of `convertJSONToHTML` with added tsx type support.
rg --type-add 'tsx:*.tsx' --type-add 'ts:*.ts' "convertJSONToHTML" -A 10 -B 10 || trueLength of output: 8858
Enforce Consistent HTML Formatting for Message Content
It appears that form.getValues('messageContent') might not always yield an HTML string. In the AI suggestion flow, a JSON value is explicitly converted to HTML with convertJSONToHTML, but manual input from the Editor may return a raw JSON structure. Please ensure that every code path produces an HTML string before passing it to constructReplyBody.
• Verify whether the Editor component returns JSON or HTML for manual entries.
• If it returns JSON, convert it using convertJSONToHTML for consistency. For example:
const messageValue = form.getValues('messageContent');
const formattedMessage =
typeof messageValue === 'string' ? messageValue : convertJSONToHTML(messageValue);| import Editor from '@/components/create/editor'; | ||
| import { Button } from '@/components/ui/button'; |
There was a problem hiding this comment.
Function returns a mismatched type compared to form value.
The form.setValue('messageContent', htmlContent) in acceptAISuggestion (line 363) suggests that the form expects a string, but the onChange handler of the Editor component sets the form value directly from the Editor's output without conversion.
<Editor
key={composerState.editorKey}
onChange={(content) => {
- form.setValue('messageContent', content);
+ // Convert JSON content to HTML string for consistent type
+ form.setValue('messageContent', convertJSONToHTML(content));
}}
initialValue={composerState.editorInitialValue}
className={cn(
"sm:max-w-[600px] md:max-w-[2050px]",
aiState.showOptions ? "border border-blue-200 dark:border-blue-800 rounded-md bg-blue-50/30 dark:bg-blue-950/30 p-1" : ""
)}
placeholder={aiState.showOptions ? "AI-generated reply (you can edit)" : "Type your reply here..."}Committable suggestion skipped: line range outside the PR's diff.
* adjustable height * h1 h2 h3 working in reply composer * select dropdown for categories * feat(navbar): update item label based on auth status * feature/persist user settings (#513) * feat: persist setting (codycodes95) * feat: update settings to jsonb * feat: run migration * feat: save changes to db * fix: naming * feat: validate settings schema * feat: add i18n * fix: set i18n variables * fix: coderabbit comment * feat: improve function readability * feat: use hook * fix:update settings --------- Co-authored-by: Cody Partington <codythatsme@gmail.com> * remove unique status from email in schema * early access check added to schema * updated readme * add contributors * remove text-decoration * text-decoration * remove auto focus on search * ahuh * gg * i18n * check email for early access (#519) * check email for early access * one check * saving... * disable buttons * disable * fix * saving... * saving... * minor * New translations en.json (French) * New translations en.json (Spanish) * New translations en.json (Arabic) * New translations en.json (Catalan) * New translations en.json (Czech) * New translations en.json (German) * New translations en.json (Japanese) * New translations en.json (Korean) * New translations en.json (Polish) * New translations en.json (Portuguese) * New translations en.json (Russian) * New translations en.json (Turkish) * New translations en.json (Latvian) * New translations en.json (Hindi) * New translations en.json (French) * New translations en.json (Spanish) * New translations en.json (Arabic) * New translations en.json (Catalan) * New translations en.json (German) * New translations en.json (Japanese) * New translations en.json (Korean) * New translations en.json (Polish) * New translations en.json (Portuguese) * New translations en.json (Hindi) * reply and searchbar display * reply ai (#526) * reply ai * ai functionality * line height * adam fixes --------- Co-authored-by: user12224 <122770437+user12224@users.noreply.github.com> Co-authored-by: Nizzy <nizabizaher@gmail.com> * Autocompletions for reply and create * email avatars (#528) * added email avatars * fix small issue * small ui fix * color fix * reply ui * New translations en.json (Japanese) * New translations en.json (Korean) * no drop down * ui fix * wip performance * saving... * saving... * saving... * saving... * - updated phrases - added delay of 2 matching characters * Improved ai with custom prompt (#534) * ai * improved ai * improved-ai-with-custom-prompt * empty commit * removed new lines * empty commit * search * forwarding * search filter removed. all in ai now * saving... * fix double submit on command enter create email * saving... * saving... * turn search ai into a server action * fuix * show most recent email in thread * saving... * saving... * forward and reply in one compose button * saving... * New translations en.json (French) * New translations en.json (Spanish) * New translations en.json (Arabic) * New translations en.json (Catalan) * New translations en.json (Czech) * New translations en.json (German) * New translations en.json (Japanese) * New translations en.json (Korean) * New translations en.json (Polish) * New translations en.json (Portuguese) * New translations en.json (Russian) * New translations en.json (Turkish) * New translations en.json (Latvian) * New translations en.json (Hindi) * fix to height reply composer * posthog * remove github login for now * refresh * New translations en.json (French) * New translations en.json (Spanish) * New translations en.json (Arabic) * New translations en.json (Catalan) * New translations en.json (Czech) * New translations en.json (German) * New translations en.json (Japanese) * New translations en.json (Korean) * New translations en.json (Polish) * New translations en.json (Portuguese) * New translations en.json (Russian) * New translations en.json (Turkish) * New translations en.json (Latvian) * New translations en.json (Hindi) * revert * a * fix load more * fix load more * remove use memo from thread to not load when opening an email * fix switching accounts --------- Co-authored-by: Nizzy <nizabizaher@gmail.com> Co-authored-by: pietrodev07 <pietro.dev.07@gmail.com> Co-authored-by: Sergio JVA <60497216+sergio-jva@users.noreply.github.com> Co-authored-by: Cody Partington <codythatsme@gmail.com> Co-authored-by: Ahmet Kilinc <akx9@icloud.com> Co-authored-by: user12224 <122770437+user12224@users.noreply.github.com> Co-authored-by: nizzy <140507264+nizzyabi@users.noreply.github.com> Co-authored-by: [bot] <zero@ibra.rip> Co-authored-by: needle <122770437+needleXO@users.noreply.github.com>
* adjustable height * h1 h2 h3 working in reply composer * select dropdown for categories * feat(navbar): update item label based on auth status * feature/persist user settings (#513) * feat: persist setting (codycodes95) * feat: update settings to jsonb * feat: run migration * feat: save changes to db * fix: naming * feat: validate settings schema * feat: add i18n * fix: set i18n variables * fix: coderabbit comment * feat: improve function readability * feat: use hook * fix:update settings --------- Co-authored-by: Cody Partington <codythatsme@gmail.com> * remove unique status from email in schema * early access check added to schema * updated readme * add contributors * remove text-decoration * text-decoration * remove auto focus on search * ahuh * gg * i18n * check email for early access (#519) * check email for early access * one check * saving... * disable buttons * disable * fix * saving... * saving... * minor * New translations en.json (French) * New translations en.json (Spanish) * New translations en.json (Arabic) * New translations en.json (Catalan) * New translations en.json (Czech) * New translations en.json (German) * New translations en.json (Japanese) * New translations en.json (Korean) * New translations en.json (Polish) * New translations en.json (Portuguese) * New translations en.json (Russian) * New translations en.json (Turkish) * New translations en.json (Latvian) * New translations en.json (Hindi) * New translations en.json (French) * New translations en.json (Spanish) * New translations en.json (Arabic) * New translations en.json (Catalan) * New translations en.json (German) * New translations en.json (Japanese) * New translations en.json (Korean) * New translations en.json (Polish) * New translations en.json (Portuguese) * New translations en.json (Hindi) * reply and searchbar display * reply ai (#526) * reply ai * ai functionality * line height * adam fixes --------- Co-authored-by: user12224 <122770437+user12224@users.noreply.github.com> Co-authored-by: Nizzy <nizabizaher@gmail.com> * Autocompletions for reply and create * email avatars (#528) * added email avatars * fix small issue * small ui fix * color fix * reply ui * New translations en.json (Japanese) * New translations en.json (Korean) * no drop down * ui fix * wip performance * saving... * saving... * saving... * saving... * - updated phrases - added delay of 2 matching characters * Improved ai with custom prompt (#534) * ai * improved ai * improved-ai-with-custom-prompt * empty commit * removed new lines * empty commit * search * forwarding * search filter removed. all in ai now * saving... * fix double submit on command enter create email * saving... * saving... * turn search ai into a server action * fuix * show most recent email in thread * saving... * saving... * forward and reply in one compose button * saving... * New translations en.json (French) * New translations en.json (Spanish) * New translations en.json (Arabic) * New translations en.json (Catalan) * New translations en.json (Czech) * New translations en.json (German) * New translations en.json (Japanese) * New translations en.json (Korean) * New translations en.json (Polish) * New translations en.json (Portuguese) * New translations en.json (Russian) * New translations en.json (Turkish) * New translations en.json (Latvian) * New translations en.json (Hindi) * fix to height reply composer * posthog * remove github login for now * refresh * New translations en.json (French) * New translations en.json (Spanish) * New translations en.json (Arabic) * New translations en.json (Catalan) * New translations en.json (Czech) * New translations en.json (German) * New translations en.json (Japanese) * New translations en.json (Korean) * New translations en.json (Polish) * New translations en.json (Portuguese) * New translations en.json (Russian) * New translations en.json (Turkish) * New translations en.json (Latvian) * New translations en.json (Hindi) * revert * a * fix load more * fix load more * remove use memo from thread to not load when opening an email * fix switching accounts * navbar changed to login --------- Co-authored-by: Nizzy <nizabizaher@gmail.com> Co-authored-by: pietrodev07 <pietro.dev.07@gmail.com> Co-authored-by: Sergio JVA <60497216+sergio-jva@users.noreply.github.com> Co-authored-by: Cody Partington <codythatsme@gmail.com> Co-authored-by: Adam <x_1337@outlook.com> Co-authored-by: Ahmet Kilinc <akx9@icloud.com> Co-authored-by: user12224 <122770437+user12224@users.noreply.github.com> Co-authored-by: nizzy <140507264+nizzyabi@users.noreply.github.com> Co-authored-by: [bot] <zero@ibra.rip>
Summary by CodeRabbit
New Features
Refactor
Style