feat(mail): complete Quick Access message launches
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Activity, ChevronRight, Database, Home, Mail, MailOpen, Paperclip, RefreshCw, Search, X } from "lucide-react";
|
||||
import { useLocation } from "react-router";
|
||||
import { ToolbarGroup, ActionToolbar,
|
||||
ActionBlockerHint,
|
||||
Button,
|
||||
@@ -30,6 +31,7 @@ import {
|
||||
"../../api/mail";
|
||||
import { buildMailboxFolderTree, findFolderNodeId, folderAncestorIds, type MailFolderNode } from "./mailboxFolders";
|
||||
import { isMailboxMessageRead, mailboxSyncState, type MailboxSyncProvenance } from "./mailboxDisplay";
|
||||
import { mailboxLaunchFolder, parseMailboxLaunch, type MailboxLaunch } from "./mailboxLaunch";
|
||||
|
||||
const MAILBOX_DOCUMENTATION = {
|
||||
topicId: "mail.workflow.read-mailbox",
|
||||
@@ -38,6 +40,7 @@ const MAILBOX_DOCUMENTATION = {
|
||||
|
||||
export default function MailboxPage({ settings, auth }: { settings: ApiSettings; auth: AuthInfo }) {
|
||||
const navigate = useGuardedNavigate();
|
||||
const location = useLocation();
|
||||
const [profiles, setProfiles] = useState<MailServerProfile[]>([]);
|
||||
const [selectedProfileId, setSelectedProfileId] = useState("");
|
||||
const [folders, setFolders] = useState<MailImapFolderResponse[]>([]);
|
||||
@@ -67,6 +70,7 @@ export default function MailboxPage({ settings, auth }: { settings: ApiSettings;
|
||||
const messageDetailRequestRef = useRef(0);
|
||||
const mailboxPageCursorsRef = useRef<Record<string, string | null>>({});
|
||||
const skipNextMessageLoadRef = useRef(false);
|
||||
const launchRequestRef = useRef<MailboxLaunch | null>(parseMailboxLaunch(location.search));
|
||||
|
||||
const selectedProfile = profiles.find((profile) => profile.id === selectedProfileId) ?? null;
|
||||
const imapProfiles = useMemo(() => profiles.filter((profile) => profile.is_active && profile.imap), [profiles]);
|
||||
@@ -99,6 +103,21 @@ export default function MailboxPage({ settings, auth }: { settings: ApiSettings;
|
||||
: "";
|
||||
|
||||
useEffect(() => {void loadProfiles();}, [settings.apiBaseUrl, settings.apiKey, settings.accessToken]);
|
||||
useEffect(() => {
|
||||
const request = parseMailboxLaunch(location.search);
|
||||
launchRequestRef.current = request;
|
||||
if (!profiles.length || (!request.profileId && !request.folder && !request.folderRole && !request.messageUid)) return;
|
||||
const usable = profiles.filter((profile) => profile.is_active && profile.imap);
|
||||
const targetProfileId = request.profileId && usable.some((profile) => profile.id === request.profileId)
|
||||
? request.profileId
|
||||
: selectedProfileId || usable[0]?.id || "";
|
||||
if (!targetProfileId) return;
|
||||
if (targetProfileId !== selectedProfileId) {
|
||||
selectProfile(targetProfileId);
|
||||
return;
|
||||
}
|
||||
void loadMailboxBootstrap(targetProfileId);
|
||||
}, [location.search]);
|
||||
useEffect(() => {selectedMessageKeyRef.current = selectedMessageKeyState;}, [selectedMessageKeyState]);
|
||||
useEffect(() => {if (messagePage > messagePageCount) setMessagePage(messagePageCount);}, [messagePage, messagePageCount]);
|
||||
useEffect(() => {if (selectedProfileId) void loadMailboxBootstrap(selectedProfileId);}, [selectedProfileId]);
|
||||
@@ -111,6 +130,19 @@ export default function MailboxPage({ settings, auth }: { settings: ApiSettings;
|
||||
void loadMessages(selectedProfileId, selectedFolder, messagePage, messagePageSize);
|
||||
}, [foldersReady, messagePage, messagePageSize, selectedProfileId, selectedFolder]);
|
||||
|
||||
useEffect(() => {
|
||||
const request = launchRequestRef.current;
|
||||
if (!request || !foldersReady || loadingMessages) return;
|
||||
const targetProfileMatches = !request.profileId || request.profileId === selectedProfileId;
|
||||
const targetFolder = mailboxLaunchFolder(request, selectedProfile);
|
||||
if (!targetProfileMatches || (targetFolder && targetFolder !== selectedFolder)) return;
|
||||
const target = request.messageUid
|
||||
? messages.find((message) => message.uid === request.messageUid)
|
||||
: null;
|
||||
launchRequestRef.current = null;
|
||||
if (target) void openMessage(target);
|
||||
}, [foldersReady, loadingMessages, messages, selectedFolder, selectedProfile, selectedProfileId]);
|
||||
|
||||
useEffect(() => {
|
||||
const handlePreviewShortcut = (event: KeyboardEvent) => {
|
||||
if (isEditableTarget(event.target)) return;
|
||||
@@ -158,8 +190,15 @@ export default function MailboxPage({ settings, auth }: { settings: ApiSettings;
|
||||
try {
|
||||
const loaded = await listMailServerProfiles(settings);
|
||||
const usable = loaded.filter((profile) => profile.is_active && profile.imap);
|
||||
const requestedProfileId = parseMailboxLaunch(location.search).profileId;
|
||||
setProfiles(loaded);
|
||||
setSelectedProfileId((current) => current && usable.some((profile) => profile.id === current) ? current : usable[0]?.id ?? "");
|
||||
setSelectedProfileId((current) =>
|
||||
requestedProfileId && usable.some((profile) => profile.id === requestedProfileId)
|
||||
? requestedProfileId
|
||||
: current && usable.some((profile) => profile.id === current)
|
||||
? current
|
||||
: usable[0]?.id ?? ""
|
||||
);
|
||||
if (usable.length === 0) {
|
||||
setFolders([]);
|
||||
setFoldersLoadedForProfile("");
|
||||
@@ -182,9 +221,13 @@ export default function MailboxPage({ settings, auth }: { settings: ApiSettings;
|
||||
async function loadMailboxBootstrap(profileId = selectedProfileId, refresh = false) {
|
||||
if (!profileId) return;
|
||||
const profileInbox = profiles.find((profile) => profile.id === profileId)?.imap?.folder_mappings?.inbox || "";
|
||||
const requestedFolder = foldersLoadedForProfile === profileId && selectedFolder
|
||||
const requestedLaunch = launchRequestRef.current;
|
||||
const requestedLaunchFolder = requestedLaunch && (!requestedLaunch.profileId || requestedLaunch.profileId === profileId)
|
||||
? mailboxLaunchFolder(requestedLaunch, profiles.find((profile) => profile.id === profileId) ?? null)
|
||||
: null;
|
||||
const requestedFolder = requestedLaunchFolder || (foldersLoadedForProfile === profileId && selectedFolder
|
||||
? selectedFolder
|
||||
: profileInbox || "INBOX";
|
||||
: profileInbox || "INBOX");
|
||||
const folderRequestId = ++folderRequestRef.current;
|
||||
const messageRequestId = ++messageListRequestRef.current;
|
||||
messageDetailRequestRef.current += 1;
|
||||
|
||||
Reference in New Issue
Block a user