intermittent commit
This commit is contained in:
@@ -11,8 +11,8 @@ import {
|
||||
type ApiSettings
|
||||
} from "@govoplan/core-webui";
|
||||
import {
|
||||
bootstrapMailbox,
|
||||
getMailboxMessage,
|
||||
listMailboxFolders,
|
||||
listMailboxMessages,
|
||||
listMailServerProfiles,
|
||||
type MailImapFolderResponse,
|
||||
@@ -50,6 +50,7 @@ export default function MailboxPage({ settings }: {settings: ApiSettings;}) {
|
||||
const messageListRequestRef = useRef(0);
|
||||
const messageDetailRequestRef = useRef(0);
|
||||
const mailboxPageCursorsRef = useRef<Record<string, string | null>>({});
|
||||
const skipNextMessageLoadRef = useRef(false);
|
||||
|
||||
const selectedProfile = profiles.find((profile) => profile.id === selectedProfileId) ?? null;
|
||||
const imapProfiles = useMemo(() => profiles.filter((profile) => profile.is_active && profile.imap), [profiles]);
|
||||
@@ -70,8 +71,15 @@ export default function MailboxPage({ settings }: {settings: ApiSettings;}) {
|
||||
useEffect(() => {void loadProfiles();}, [settings.apiBaseUrl, settings.apiKey, settings.accessToken]);
|
||||
useEffect(() => {selectedMessageKeyRef.current = selectedMessageKeyState;}, [selectedMessageKeyState]);
|
||||
useEffect(() => {if (messagePage > messagePageCount) setMessagePage(messagePageCount);}, [messagePage, messagePageCount]);
|
||||
useEffect(() => {if (selectedProfileId) void loadFolders(selectedProfileId);}, [selectedProfileId]);
|
||||
useEffect(() => {if (selectedProfileId && selectedFolder && foldersReady) void loadMessages(selectedProfileId, selectedFolder, messagePage, messagePageSize);}, [foldersReady, messagePage, messagePageSize, selectedProfileId, selectedFolder]);
|
||||
useEffect(() => {if (selectedProfileId) void loadMailboxBootstrap(selectedProfileId);}, [selectedProfileId]);
|
||||
useEffect(() => {
|
||||
if (!selectedProfileId || !selectedFolder || !foldersReady) return;
|
||||
if (skipNextMessageLoadRef.current) {
|
||||
skipNextMessageLoadRef.current = false;
|
||||
return;
|
||||
}
|
||||
void loadMessages(selectedProfileId, selectedFolder, messagePage, messagePageSize);
|
||||
}, [foldersReady, messagePage, messagePageSize, selectedProfileId, selectedFolder]);
|
||||
|
||||
useEffect(() => {
|
||||
const handlePreviewShortcut = (event: KeyboardEvent) => {
|
||||
@@ -130,6 +138,8 @@ export default function MailboxPage({ settings }: {settings: ApiSettings;}) {
|
||||
setSelectedMessage(null);
|
||||
setSelectedMessageKeyState("");
|
||||
setPendingMessageKey("");
|
||||
mailboxPageCursorsRef.current = {};
|
||||
skipNextMessageLoadRef.current = false;
|
||||
}
|
||||
} catch (err) {
|
||||
setError(errorText(err));
|
||||
@@ -138,52 +148,70 @@ export default function MailboxPage({ settings }: {settings: ApiSettings;}) {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadFolders(profileId = selectedProfileId) {
|
||||
async function loadMailboxBootstrap(profileId = selectedProfileId, refresh = false) {
|
||||
if (!profileId) return;
|
||||
const requestId = ++folderRequestRef.current;
|
||||
messageListRequestRef.current += 1;
|
||||
const folderRequestId = ++folderRequestRef.current;
|
||||
const messageRequestId = ++messageListRequestRef.current;
|
||||
messageDetailRequestRef.current += 1;
|
||||
setLoadingFolders(true);
|
||||
setLoadingMessages(true);
|
||||
setFoldersLoadedForProfile("");
|
||||
setMessageTotalCount(null);
|
||||
setMessagePage(1);
|
||||
setSelectedMessage(null);
|
||||
setSelectedMessageKeyState("");
|
||||
selectedMessageKeyRef.current = "";
|
||||
setPendingMessageKey("");
|
||||
setFolderError("");
|
||||
setMessageError("");
|
||||
setDetailError("");
|
||||
setError("");
|
||||
try {
|
||||
const response = await listMailboxFolders(settings, profileId);
|
||||
if (requestId !== folderRequestRef.current) return;
|
||||
if (!response.ok) throw new Error(response.message || "i18n:govoplan-mail.mailbox_folders_could_not_be_loaded.c3e3880e");
|
||||
const loaded = response.folders?.length ? response.folders : [{ name: "INBOX", flags: [] }];
|
||||
setFolders(loaded);
|
||||
setExpandedFolders(new Set());
|
||||
let nextFolder = selectedFolder;
|
||||
if (!nextFolder || !loaded.some((folder) => folder.name === nextFolder)) {
|
||||
nextFolder = loaded.some((folder) => folder.name === "INBOX") ? "INBOX" : response.detected_sent_folder || loaded[0]?.name || "INBOX";
|
||||
const response = await bootstrapMailbox(settings, profileId, selectedFolder || "INBOX", messagePageSize, 0, refresh);
|
||||
if (folderRequestId !== folderRequestRef.current || messageRequestId !== messageListRequestRef.current) return;
|
||||
if (!response.folders.ok) throw new Error(response.folders.message || "i18n:govoplan-mail.mailbox_folders_could_not_be_loaded.c3e3880e");
|
||||
const loadedFolders = response.folders.folders?.length ? response.folders.folders : [{ name: "INBOX", flags: [] }];
|
||||
const loadedMessages = response.messages.messages ?? [];
|
||||
const total = response.messages.total_count ?? loadedMessages.length;
|
||||
let nextFolder = response.folder || response.messages.folder || selectedFolder || "INBOX";
|
||||
if (!loadedFolders.some((folder) => folder.name === nextFolder)) {
|
||||
nextFolder = loadedFolders.some((folder) => folder.name === "INBOX") ? "INBOX" : response.folders.detected_sent_folder || loadedFolders[0]?.name || "INBOX";
|
||||
}
|
||||
const foldersWithCounts = loadedFolders.map((folder) => folder.name === nextFolder ? { ...folder, message_count: total } : folder);
|
||||
const cursorKey = mailboxCursorKey(profileId, nextFolder, messagePageSize);
|
||||
mailboxPageCursorsRef.current = {
|
||||
[`${cursorKey}:1`]: null,
|
||||
[`${cursorKey}:2`]: response.messages.next_cursor ?? null
|
||||
};
|
||||
skipNextMessageLoadRef.current = foldersLoadedForProfile !== profileId || nextFolder !== selectedFolder || messagePage !== 1;
|
||||
setFolders(foldersWithCounts);
|
||||
setExpandedFolders(new Set());
|
||||
setSelectedFolder(nextFolder);
|
||||
setFoldersLoadedForProfile(profileId);
|
||||
setMessages(loadedMessages);
|
||||
setMessageTotalCount(total);
|
||||
} catch (err) {
|
||||
if (requestId !== folderRequestRef.current) return;
|
||||
setFolderError(errorText(err));
|
||||
setError(errorText(err));
|
||||
if (folderRequestId !== folderRequestRef.current || messageRequestId !== messageListRequestRef.current) return;
|
||||
const message = errorText(err);
|
||||
skipNextMessageLoadRef.current = false;
|
||||
setFolderError(message);
|
||||
setMessageError(message);
|
||||
setError(message);
|
||||
setFolders([]);
|
||||
setFoldersLoadedForProfile("");
|
||||
setMessages([]);
|
||||
setMessageTotalCount(null);
|
||||
setSelectedMessage(null);
|
||||
setSelectedMessageKeyState("");
|
||||
selectedMessageKeyRef.current = "";
|
||||
setPendingMessageKey("");
|
||||
} finally {
|
||||
if (requestId === folderRequestRef.current) setLoadingFolders(false);
|
||||
if (folderRequestId === folderRequestRef.current) setLoadingFolders(false);
|
||||
if (messageRequestId === messageListRequestRef.current) setLoadingMessages(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadMessages(profileId = selectedProfileId, folder = selectedFolder, page = messagePage, pageSize = messagePageSize) {
|
||||
async function loadMessages(profileId = selectedProfileId, folder = selectedFolder, page = messagePage, pageSize = messagePageSize, refresh = false) {
|
||||
if (!profileId || !folder) return;
|
||||
const requestId = ++messageListRequestRef.current;
|
||||
const offset = (Math.max(1, page) - 1) * pageSize;
|
||||
@@ -194,12 +222,12 @@ export default function MailboxPage({ settings }: {settings: ApiSettings;}) {
|
||||
setDetailError("");
|
||||
setError("");
|
||||
try {
|
||||
const response = await listMailboxMessages(settings, profileId, folder, pageSize, offset, cursor);
|
||||
const response = await listMailboxMessages(settings, profileId, folder, pageSize, offset, cursor, refresh);
|
||||
if (requestId !== messageListRequestRef.current) return;
|
||||
const loaded = response.messages ?? [];
|
||||
const total = response.total_count ?? loaded.length;
|
||||
if (page <= 1) mailboxPageCursorsRef.current[`${cursorKey}:1`] = null;
|
||||
if (response.next_cursor) mailboxPageCursorsRef.current[`${cursorKey}:${page + 1}`] = response.next_cursor;
|
||||
mailboxPageCursorsRef.current[`${cursorKey}:${page + 1}`] = response.next_cursor ?? null;
|
||||
setMessages(loaded);
|
||||
setMessageTotalCount(total);
|
||||
setFolderMessageCount(folder, total);
|
||||
@@ -271,6 +299,8 @@ export default function MailboxPage({ settings }: {settings: ApiSettings;}) {
|
||||
setLoadingFolders(false);
|
||||
setLoadingMessages(false);
|
||||
setLoadingMessage(false);
|
||||
mailboxPageCursorsRef.current = {};
|
||||
skipNextMessageLoadRef.current = false;
|
||||
}
|
||||
|
||||
function openFolderNode(node: MailFolderNode) {
|
||||
@@ -365,11 +395,11 @@ export default function MailboxPage({ settings }: {settings: ApiSettings;}) {
|
||||
<RefreshCw size={16} aria-hidden="true" />
|
||||
i18n:govoplan-mail.profiles.0c2a9300
|
||||
</Button>
|
||||
<Button onClick={() => void loadFolders(selectedProfileId)} disabled={!selectedProfileId || loadingFolders} title="i18n:govoplan-mail.refresh_mailbox_folders.d9af9963">
|
||||
<Button onClick={() => void loadMailboxBootstrap(selectedProfileId, true)} disabled={!selectedProfileId || loadingFolders || loadingMessages} title="i18n:govoplan-mail.refresh_mailbox_folders.d9af9963">
|
||||
<RefreshCw size={16} aria-hidden="true" />
|
||||
i18n:govoplan-mail.folders.19adc47b
|
||||
</Button>
|
||||
<Button onClick={() => void loadMessages(selectedProfileId, selectedFolder, messagePage, messagePageSize)} disabled={!selectedProfileId || !selectedFolder || !foldersReady || loadingMessages} title="i18n:govoplan-mail.refresh_messages_in_the_current_folder.b6546a2c">
|
||||
<Button onClick={() => void loadMessages(selectedProfileId, selectedFolder, messagePage, messagePageSize, true)} disabled={!selectedProfileId || !selectedFolder || !foldersReady || loadingMessages} title="i18n:govoplan-mail.refresh_messages_in_the_current_folder.b6546a2c">
|
||||
<RefreshCw size={16} aria-hidden="true" />
|
||||
i18n:govoplan-mail.messages.f1702b46
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user