Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 134 additions & 134 deletions apps/mail/app/api/driver/google.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/mail/app/api/driver/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export interface MailManager {
getScope(): string;
markAsRead(id: string[]): Promise<void>;
markAsUnread(id: string[]): Promise<void>;
normalizeIds(id: string[]): { normalizedIds: string[]; threadIds: string[] };
normalizeIds(id: string[]): { threadIds: string[] };
modifyLabels(
id: string[],
options: { addLabels: string[]; removeLabels: string[] },
Expand Down
21 changes: 15 additions & 6 deletions apps/mail/components/mail/mail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ListMinusIcon,
ArrowRightIcon,
Loader2,
Star,
} from 'lucide-react';
import {
Dialog,
Expand All @@ -33,12 +34,12 @@ import { useParams, useSearchParams } from 'next/navigation';
import { useMediaQuery } from '../../hooks/use-media-query';
import { useSearchValue } from '@/hooks/use-search-value';
import { SearchIcon } from '../icons/animated/search';
import type { MessageKey } from '@/config/navigation';
import { useMail } from '@/components/mail/use-mail';
import { SidebarToggle } from '../ui/sidebar-toggle';
import { Skeleton } from '@/components/ui/skeleton';
import { cn, defaultPageSize } from '@/lib/utils';
import { useThreads } from '@/hooks/use-threads';
import { MessageKey } from '@/config/navigation';
import { Button } from '@/components/ui/button';
import { useHotKey } from '@/hooks/use-hot-key';
import { useSession } from '@/lib/auth-client';
Expand Down Expand Up @@ -501,45 +502,53 @@ function BulkSelectActions() {

const categories = [
{
id:'Primary',
id: 'Primary',
name: 'common.mailCategories.primary',
searchValue: '',
icon: <Inbox className="h-4 w-4" />,
colors:
'border-0 bg-gray-200 text-gray-700 dark:bg-gray-800/50 dark:text-gray-400 dark:hover:bg-gray-800/70',
},
{
id:'Important',
id: 'Important',
name: 'common.mailCategories.important',
searchValue: 'is:important',
icon: <AlertTriangle className="h-4 w-4" />,
colors:
'border-0 text-amber-800 bg-amber-100 dark:bg-amber-900/20 dark:text-amber-500 dark:hover:bg-amber-900/30',
},
{
id:'Personal',
id: 'Personal',
name: 'common.mailCategories.personal',
searchValue: 'is:personal',
icon: <User className="h-4 w-4" />,
colors:
'border-0 text-green-800 bg-green-100 dark:bg-green-900/20 dark:text-green-500 dark:hover:bg-green-900/30',
},
{
id:'Updates',
id: 'Updates',
name: 'common.mailCategories.updates',
searchValue: 'is:updates',
icon: <Bell className="h-4 w-4" />,
colors:
'border-0 text-purple-800 bg-purple-100 dark:bg-purple-900/20 dark:text-purple-500 dark:hover:bg-purple-900/30',
},
{
id:'Promotions',
id: 'Promotions',
name: 'common.mailCategories.promotions',
searchValue: 'is:promotions',
icon: <Tag className="h-4 w-4 rotate-90" />,
colors:
'border-0 text-red-800 bg-red-100 dark:bg-red-900/20 dark:text-red-500 dark:hover:bg-red-900/30',
},
{
id: 'Favourites',
name: 'common.mailCategories.favourites',
searchValue: 'is:starred',
icon: <Star className="h-4 w-4 rotate-90" />,
colors:
'border-0 text-pink-800 bg-pink-100 dark:bg-pink-900/20 dark:text-pink-500 dark:hover:bg-pink-900/30',
},
];

function MailCategoryTabs({
Expand Down
41 changes: 38 additions & 3 deletions apps/mail/components/mail/thread-display.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { DropdownMenuContent, DropdownMenuItem } from '@/components/ui/dropdown-menu';
import { DropdownMenu, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { ArchiveX, Forward, ReplyAll } from 'lucide-react';
import { ArchiveX, Forward, ReplyAll, Star, StarOff } from 'lucide-react';
import { ScrollArea } from '@/components/ui/scroll-area';
import { useSearchParams } from 'next/navigation';

import { MoreVerticalIcon } from '../icons/animated/more-vertical';
import { useState, useEffect, useCallback, useRef } from 'react';
import { useThread, useThreads } from '@/hooks/use-threads';
import { ArchiveIcon } from '../icons/animated/archive';
import { ExpandIcon } from '../icons/animated/expand';
import { MailDisplaySkeleton } from './mail-skeleton';
import { ReplyIcon } from '../icons/animated/reply';
import { Button } from '@/components/ui/button';
import { useThread } from '@/hooks/use-threads';
import { modifyLabels } from '@/actions/mail';
import ThreadSubject from './thread-subject';
import { XIcon } from '../icons/animated/x';
import ReplyCompose from './reply-composer';
Expand All @@ -21,6 +22,7 @@ import { NotesPanel } from './note-panel';
import MailDisplay from './mail-display';
import { useMail } from './use-mail';
import { cn } from '@/lib/utils';
import { toast } from 'sonner';

interface ThreadDisplayProps {
mail?: any;
Expand Down Expand Up @@ -190,7 +192,8 @@ export function ThreadDisplay({ mail, onClose, isMobile }: ThreadDisplayProps) {
const threadIdParam = searchParams.get('threadId');
const threadId = mail ?? threadIdParam ?? '';
// Only fetch thread data if we have a valid threadId
const { data: emailData, isLoading } = useThread(threadId || null);
const { data: emailData, isLoading, mutate } = useThread(threadId ?? '');
const { mutate: mutateThreads } = useThreads('STARRED');
const [isMuted, setIsMuted] = useState(false);
const [isReplyOpen, setIsReplyOpen] = useState(false);
const [isFullscreen, setIsFullscreen] = useState(false);
Expand All @@ -208,6 +211,25 @@ export function ThreadDisplay({ mail, onClose, isMobile }: ThreadDisplayProps) {
onClose?.();
}, [onClose]);

const handleFavourites = async () => {
if (!emailData) return;
if (emailData[0]?.tags?.includes('STARRED')) {
toast.promise(modifyLabels({ threadId: [threadId], removeLabels: ['STARRED'] }), {
success: 'Removed from favourites.',
loading: 'Removing from favourites',
error: 'Failed to remove from favourites.',
});
} else {
toast.promise(modifyLabels({ threadId: [threadId], addLabels: ['STARRED'] }), {
success: 'Added to favourites.',
loading: 'Adding to favourites.',
error: 'Failed to add to favourites.',
});
}

await Promise.all([mutate(), mutateThreads()]);
};

useEffect(() => {
const handleEsc = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
Expand Down Expand Up @@ -260,6 +282,13 @@ export function ThreadDisplay({ mail, onClose, isMobile }: ThreadDisplayProps) {
className="relative top-0.5"
/>

<ThreadActionButton
icon={emailData[0]?.tags?.includes('STARRED') ? StarOff : Star}
label={t('common.threadDisplay.favourites')}
onClick={handleFavourites}
className="relative top-0.5"
/>

<ThreadActionButton
icon={ReplyIcon}
label={t('common.threadDisplay.reply')}
Expand Down Expand Up @@ -348,6 +377,12 @@ export function ThreadDisplay({ mail, onClose, isMobile }: ThreadDisplayProps) {
disabled={!emailData}
className="relative top-0.5"
/>
<ThreadActionButton
icon={emailData[0]?.tags?.includes('STARRED') ? StarOff : Star}
label={t('common.threadDisplay.favourites')}
onClick={handleFavourites}
className="relative top-0.5"
/>
<ThreadActionButton
icon={ReplyIcon}
label={t('common.threadDisplay.reply')}
Expand Down
3 changes: 2 additions & 1 deletion apps/mail/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@
"personal": "Personal",
"updates": "Updates",
"promotions": "Promotions",
"social": "Social"
"social": "Social",
"favourites": "Favourites"
},
"replyCompose": {
"replyTo": "Reply to",
Expand Down
3 changes: 2 additions & 1 deletion apps/mail/locales/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@
"personal": "Personal",
"updates": "Actualitzacions",
"promotions": "Promocions",
"social": "Social"
"social": "Social",
"favourites": "Preferits"
},
"replyCompose": {
"replyTo": "Respon a",
Expand Down
3 changes: 2 additions & 1 deletion apps/mail/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@
"personal": "Persönlich",
"updates": "Updates",
"promotions": "Werbung",
"social": "Sozial"
"social": "Sozial",
"favourites": "Favoriten"
},
"replyCompose": {
"replyTo": "Antwort an",
Expand Down
Loading