mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-05 16:16:49 +00:00
fix: open a mail link from another program from the default account with no question, and drop "protocol link" from the account picker
This commit is contained in:
@@ -3,6 +3,7 @@ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import type { Mailbox } from '@/lib/jmap/types';
|
||||
import { useAuthStore } from '@/stores/auth-store';
|
||||
import { useAccountStore } from '@/stores/account-store';
|
||||
import { useEmailStore } from '@/stores/email-store';
|
||||
import { useSettingsStore } from '@/stores/settings-store';
|
||||
import { usePluginStore } from '@/stores/plugin-store';
|
||||
@@ -222,6 +223,29 @@ describe('a mail link from another program in the desktop app', () => {
|
||||
expect(screen.queryByText('stub composer')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('with two accounts it opens from the default one, in its own window, with no question', async () => {
|
||||
const client = useAuthStore.getState().client;
|
||||
useAuthStore.setState({ getAllConnectedClients: () => new Map([['login', client], ['second', client]]) as never });
|
||||
useAccountStore.setState({
|
||||
accounts: [
|
||||
{ id: 'login', email: 'me@example.com', isConnected: true, isDefault: false },
|
||||
{ id: 'second', email: 'work@example.com', isConnected: true, isDefault: true },
|
||||
],
|
||||
defaultAccountId: 'second',
|
||||
} as never);
|
||||
try {
|
||||
render(<MailApp />);
|
||||
await fromOs();
|
||||
await waitFor(() => expect(desktopWindows.handOver).toHaveBeenCalledTimes(1));
|
||||
expect(desktopWindows.open).toHaveBeenCalledWith('second');
|
||||
expect(screen.queryByText('select_account_title')).not.toBeInTheDocument();
|
||||
// The main window keeps the account it shows.
|
||||
expect(useAuthStore.getState().activeAccountId).toBe('login');
|
||||
} finally {
|
||||
useAccountStore.setState({ accounts: [], defaultAccountId: null } as never);
|
||||
}
|
||||
});
|
||||
|
||||
it('a link inside the app still opens here', async () => {
|
||||
render(<MailApp />);
|
||||
act(() => { requestInternalMailto('mailto:bob@example.com?subject=Hi'); });
|
||||
|
||||
@@ -156,7 +156,7 @@ import { mailTitleContext } from "@/lib/tab-title";
|
||||
import { usePluginStore } from "@/stores/plugin-store";
|
||||
import { AppTopBannerSlot } from "@/components/plugins/app-top-banner-slot";
|
||||
import { canDownload } from "@/lib/device-policy";
|
||||
import { consumePendingMailto, subscribeToPendingMailto } from "@/lib/protocol-handlers/session";
|
||||
import { consumePendingMailto, mailLinkAccountId, subscribeToPendingMailto } from "@/lib/protocol-handlers/session";
|
||||
import { setNotificationReplyOpener } from "@/lib/pwa-notify/page-actions";
|
||||
import { setMailLinkOpener } from "@/lib/desktop/mail-links";
|
||||
import { requestTabReply } from "@/lib/pwa-notify/tab-reply";
|
||||
@@ -1716,7 +1716,7 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
|
||||
// A mail link from another program, in the desktop app: a compose window of its own,
|
||||
// as Outlook and Thunderbird do, and the main window stays where it was. Plugins get
|
||||
// their say first. False when it has to open here instead.
|
||||
const openMailtoInWindow = useCallback(async (pending: DraftRequest): Promise<boolean> => {
|
||||
const openMailtoInWindow = useCallback(async (pending: DraftRequest, accountId?: string): Promise<boolean> => {
|
||||
if (!pending.fromOs || !hasDesktopWindows() || !popoutsAvailable()) return false;
|
||||
let prefill: ComposePrefill | null = null;
|
||||
if (emailHooks.onBeforeCompose.size > 0) {
|
||||
@@ -1729,7 +1729,8 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
|
||||
// A plugin said no: nothing opens, here or there.
|
||||
if (!prefill) return true;
|
||||
}
|
||||
const opened = openComposerWindow(useAuthStore.getState().activeAccountId);
|
||||
// The account the link goes out from, in its own window: the main window keeps the one it shows.
|
||||
const opened = openComposerWindow(accountId ?? useAuthStore.getState().activeAccountId);
|
||||
if (!opened) return false;
|
||||
void opened.handOver({
|
||||
mode: 'compose',
|
||||
@@ -1768,6 +1769,10 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
|
||||
}, [openMailtoInWindow, openMailtoHere]);
|
||||
|
||||
const openMailtoForAccount = useCallback(async (pending: DraftRequest, accountId: string) => {
|
||||
if (await openMailtoInWindow(pending, accountId)) {
|
||||
setPendingMailtoAccountChoice(null);
|
||||
return;
|
||||
}
|
||||
setIsProtocolAccountSwitching(true);
|
||||
try {
|
||||
if (useAuthStore.getState().activeAccountId !== accountId) {
|
||||
@@ -1778,7 +1783,7 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
|
||||
} finally {
|
||||
setIsProtocolAccountSwitching(false);
|
||||
}
|
||||
}, [openMailtoDraft, switchAccount]);
|
||||
}, [openMailtoDraft, openMailtoInWindow, switchAccount]);
|
||||
|
||||
// onMailtoIntercept: a plugin may stop a mailto: from opening the composer.
|
||||
const mailtoAllowed = useCallback(async (pending: ParsedMailto & { href?: string }): Promise<boolean> => {
|
||||
@@ -1791,17 +1796,10 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
|
||||
});
|
||||
}, []);
|
||||
|
||||
// A draft that comes from outside: which account it goes out from.
|
||||
// A draft that comes from outside goes out from the default account, as in Outlook and
|
||||
// Thunderbird, with no question: the composer's From changes it (desktop-p2-8).
|
||||
const routeOutsideDraft = useCallback(async (pending: DraftRequest): Promise<void> => {
|
||||
const protocolAccounts = getMailtoProtocolAccounts();
|
||||
if (protocolAccounts.length > 1) {
|
||||
// The question is asked in this window: bring it up.
|
||||
if (pending.fromOs) getDesktopBridge()?.windows?.focus?.();
|
||||
setPendingMailtoAccountChoice(pending);
|
||||
return;
|
||||
}
|
||||
|
||||
const accountId = protocolAccounts[0]?.id ?? activeAccountId;
|
||||
const accountId = mailLinkAccountId(getMailtoProtocolAccounts(), useAccountStore.getState().defaultAccountId, activeAccountId);
|
||||
if (accountId) {
|
||||
await openMailtoForAccount(pending, accountId);
|
||||
return;
|
||||
|
||||
@@ -167,7 +167,7 @@ export function ProtocolAccountPicker({
|
||||
{t("switching_account")}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-xs text-muted-foreground">{t("select_account_note")}</span>
|
||||
<span />
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -357,3 +357,14 @@ export function subscribeToPendingWebcal(callback: () => void): () => void {
|
||||
export function hasPendingWebcal(): boolean {
|
||||
return hasPending(WEBCAL_KEY, isParsedWebcal);
|
||||
}
|
||||
|
||||
/**
|
||||
* The account a mail link from outside goes out from, with no question: the one marked
|
||||
* default, else the one in use, as Outlook and Thunderbird do. The composer's From can
|
||||
* change it. Only signed-in accounts count.
|
||||
*/
|
||||
export function mailLinkAccountId(accounts: readonly { id: string }[], defaultId: string | null, activeId: string | null): string | null {
|
||||
if (defaultId && accounts.some((account) => account.id === defaultId)) return defaultId;
|
||||
if (activeId && accounts.some((account) => account.id === activeId)) return activeId;
|
||||
return accounts[0]?.id ?? activeId ?? null;
|
||||
}
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "اختر الحساب",
|
||||
"select_mailto_account": "اختر الحساب الذي سيفتح رابط البريد هذا.",
|
||||
"select_webcal_account": "اختر الحساب الذي سيفتح رابط التقويم هذا.",
|
||||
"select_account_note": "ينطبق هذا فقط على رابط البروتوكول هذا.",
|
||||
"detail_to": "إلى",
|
||||
"detail_subject": "الموضوع",
|
||||
"detail_no_subject": "بلا موضوع",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Trieu un compte",
|
||||
"select_mailto_account": "Trieu quin compte ha d'obrir aquest enllaç de correu.",
|
||||
"select_webcal_account": "Trieu quin compte ha d'obrir aquest enllaç de calendari.",
|
||||
"select_account_note": "Això només s'aplica a aquest enllaç de protocol.",
|
||||
"detail_to": "Per a",
|
||||
"detail_subject": "Assumpte",
|
||||
"detail_no_subject": "Sense assumpte",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Vybrat účet",
|
||||
"select_mailto_account": "Vyberte účet, ve kterém se má tento e-mailový odkaz otevřít.",
|
||||
"select_webcal_account": "Vyberte účet, ve kterém se má tento kalendářový odkaz otevřít.",
|
||||
"select_account_note": "Tato volba platí jen pro tento odkaz protokolu.",
|
||||
"detail_to": "Komu",
|
||||
"detail_subject": "Předmět",
|
||||
"detail_no_subject": "Bez předmětu",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Vælg konto",
|
||||
"select_mailto_account": "Vælg hvilken konto der skal åbne dette e-mail-link.",
|
||||
"select_webcal_account": "Vælg hvilken konto der skal åbne dette kalenderlink.",
|
||||
"select_account_note": "Dette gælder kun for dette protokollink.",
|
||||
"detail_to": "Til",
|
||||
"detail_subject": "Emne",
|
||||
"detail_no_subject": "Intet emne",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Account auswählen",
|
||||
"select_mailto_account": "Wählen Sie aus, mit welchem Account dieser E-Mail-Link geöffnet werden soll.",
|
||||
"select_webcal_account": "Wählen Sie aus, mit welchem Account dieser Kalender-Link geöffnet werden soll.",
|
||||
"select_account_note": "Diese Auswahl gilt nur für diesen Protokoll-Link.",
|
||||
"detail_to": "An",
|
||||
"detail_subject": "Betreff",
|
||||
"detail_no_subject": "Ohne Betreff",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Choose account",
|
||||
"select_mailto_account": "Choose which account should open this email link.",
|
||||
"select_webcal_account": "Choose which account should open this calendar link.",
|
||||
"select_account_note": "This only applies to this protocol link.",
|
||||
"detail_to": "To",
|
||||
"detail_subject": "Subject",
|
||||
"detail_no_subject": "No subject",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Elegir cuenta",
|
||||
"select_mailto_account": "Elige qué cuenta debe abrir este enlace de correo.",
|
||||
"select_webcal_account": "Elige qué cuenta debe abrir este enlace de calendario.",
|
||||
"select_account_note": "Esta selección solo se aplica a este enlace de protocolo.",
|
||||
"detail_to": "Para",
|
||||
"detail_subject": "Asunto",
|
||||
"detail_no_subject": "Sin asunto",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Vali konto",
|
||||
"select_mailto_account": "Vali, milline konto peaks selle e-posti lingi avama.",
|
||||
"select_webcal_account": "Vali, milline konto peaks selle kalendrilingi avama.",
|
||||
"select_account_note": "See kehtib ainult selle protokollilingi kohta.",
|
||||
"detail_to": "Kellele",
|
||||
"detail_subject": "Teema",
|
||||
"detail_no_subject": "Teema puudub",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "انتخاب حساب",
|
||||
"select_mailto_account": "انتخاب کنید کدام حساب این لینک ایمیل را باز کند.",
|
||||
"select_webcal_account": "انتخاب کنید کدام حساب این لینک تقویم را باز کند.",
|
||||
"select_account_note": "فقط برای این لینک پروتکل اعمال میشود.",
|
||||
"detail_to": "به",
|
||||
"detail_subject": "موضوع",
|
||||
"detail_no_subject": "بدون موضوع",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Choisir un compte",
|
||||
"select_mailto_account": "Choisissez le compte qui doit ouvrir ce lien e-mail.",
|
||||
"select_webcal_account": "Choisissez le compte qui doit ouvrir ce lien de calendrier.",
|
||||
"select_account_note": "Cette sélection s'applique uniquement à ce lien de protocole.",
|
||||
"detail_to": "À",
|
||||
"detail_subject": "Objet",
|
||||
"detail_no_subject": "Sans objet",
|
||||
|
||||
@@ -5461,7 +5461,6 @@
|
||||
"select_account_title": "בחר חשבון",
|
||||
"select_mailto_account": "בחר איזה חשבון צריך לפתוח קישור דוא״ל זה.",
|
||||
"select_webcal_account": "בחר איזה חשבון צריך לפתוח קישור לוח שנה זה.",
|
||||
"select_account_note": "זה חל רק על קישור פרוטוקול זה.",
|
||||
"detail_to": "אל",
|
||||
"detail_subject": "נושא",
|
||||
"detail_no_subject": "אין נושא",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Fiók kiválasztása",
|
||||
"select_mailto_account": "Válaszd ki, melyik fiók nyissa meg ezt az e-mail hivatkozást.",
|
||||
"select_webcal_account": "Válaszd ki, melyik fiók nyissa meg ezt a naptár hivatkozást.",
|
||||
"select_account_note": "Ez csak erre a protokoll hivatkozásra vonatkozik.",
|
||||
"detail_to": "Címzett",
|
||||
"detail_subject": "Tárgy",
|
||||
"detail_no_subject": "Nincs tárgy",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Scegli account",
|
||||
"select_mailto_account": "Scegli quale account deve aprire questo link e-mail.",
|
||||
"select_webcal_account": "Scegli quale account deve aprire questo link calendario.",
|
||||
"select_account_note": "Questa scelta si applica solo a questo link di protocollo.",
|
||||
"detail_to": "A",
|
||||
"detail_subject": "Oggetto",
|
||||
"detail_no_subject": "Senza oggetto",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "アカウントを選択",
|
||||
"select_mailto_account": "このメールリンクを開くアカウントを選択してください。",
|
||||
"select_webcal_account": "このカレンダーリンクを開くアカウントを選択してください。",
|
||||
"select_account_note": "この選択は、このプロトコル リンクにのみ適用されます。",
|
||||
"detail_to": "宛先",
|
||||
"detail_subject": "件名",
|
||||
"detail_no_subject": "件名なし",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "계정 선택",
|
||||
"select_mailto_account": "이 이메일 링크를 열 계정을 선택하세요.",
|
||||
"select_webcal_account": "이 캘린더 링크를 열 계정을 선택하세요.",
|
||||
"select_account_note": "이 선택은 이 프로토콜 링크에만 적용됩니다.",
|
||||
"detail_to": "받는 사람",
|
||||
"detail_subject": "제목",
|
||||
"detail_no_subject": "제목 없음",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Izvēlieties kontu",
|
||||
"select_mailto_account": "Izvēlieties, kurā kontā atvērt šo e-pasta saiti.",
|
||||
"select_webcal_account": "Izvēlieties, kurā kontā atvērt šo kalendāra saiti.",
|
||||
"select_account_note": "Šī izvēle attiecas tikai uz šo protokola saiti.",
|
||||
"detail_to": "Kam",
|
||||
"detail_subject": "Temats",
|
||||
"detail_no_subject": "Bez temata",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Бүртгэл сонгох",
|
||||
"select_mailto_account": "Энэ имэйлийн холбоосыг аль бүртгэлээр нээхийг сонгоно уу.",
|
||||
"select_webcal_account": "Энэ хуанлийн холбоосыг аль данс нээхийг сонгоно уу.",
|
||||
"select_account_note": "Энэ нь зөвхөн энэ протоколын холбоост хамаарна.",
|
||||
"detail_to": "Хэнд",
|
||||
"detail_subject": "Сэдэв",
|
||||
"detail_no_subject": "Сэдэв байхгүй",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Velg konto",
|
||||
"select_mailto_account": "Velg hvilken konto som skal åpne denne e-postlenken.",
|
||||
"select_webcal_account": "Velg hvilken konto som skal åpne denne kalenderlenken.",
|
||||
"select_account_note": "Dette gjelder bare denne lenken.",
|
||||
"detail_to": "Til",
|
||||
"detail_subject": "Emne",
|
||||
"detail_no_subject": "Uten emne",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Account kiezen",
|
||||
"select_mailto_account": "Kies welk account deze e-maillink moet openen.",
|
||||
"select_webcal_account": "Kies welk account deze kalenderlink moet openen.",
|
||||
"select_account_note": "Deze keuze geldt alleen voor deze protocol-link.",
|
||||
"detail_to": "Aan",
|
||||
"detail_subject": "Onderwerp",
|
||||
"detail_no_subject": "Geen onderwerp",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Wybierz konto",
|
||||
"select_mailto_account": "Wybierz konto, które ma otworzyć ten link e-mail.",
|
||||
"select_webcal_account": "Wybierz konto, które ma otworzyć ten link kalendarza.",
|
||||
"select_account_note": "Ten wybór dotyczy tylko tego linku protokołu.",
|
||||
"detail_to": "Do",
|
||||
"detail_subject": "Temat",
|
||||
"detail_no_subject": "Bez tematu",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Escolher conta",
|
||||
"select_mailto_account": "Escolha qual conta deve abrir este link de e-mail.",
|
||||
"select_webcal_account": "Escolha qual conta deve abrir este link de calendário.",
|
||||
"select_account_note": "Esta escolha se aplica apenas a este link de protocolo.",
|
||||
"detail_to": "Para",
|
||||
"detail_subject": "Assunto",
|
||||
"detail_no_subject": "Sem assunto",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Alegeți contul",
|
||||
"select_mailto_account": "Alegeți contul în care să se deschidă acest link de e-mail.",
|
||||
"select_webcal_account": "Alegeți contul care ar trebui să deschidă acest link către calendar.",
|
||||
"select_account_note": "Aceasta se aplică numai acestui link de protocol.",
|
||||
"detail_to": "Către",
|
||||
"detail_subject": "Subiect",
|
||||
"detail_no_subject": "Fără subiect",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Выберите аккаунт",
|
||||
"select_mailto_account": "Выберите, в каком аккаунте открыть эту ссылку электронной почты.",
|
||||
"select_webcal_account": "Выберите, в каком аккаунте открыть эту ссылку календаря.",
|
||||
"select_account_note": "Этот выбор применяется только к этой ссылке протокола.",
|
||||
"detail_to": "Кому",
|
||||
"detail_subject": "Тема",
|
||||
"detail_no_subject": "Без темы",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Vybrať účet",
|
||||
"select_mailto_account": "Vyberte účet, v ktorom sa má tento e-mailový odkaz otvoriť.",
|
||||
"select_webcal_account": "Vyberte účet, v ktorom sa má tento kalendárový odkaz otvoriť.",
|
||||
"select_account_note": "Toto platí iba pre tento odkaz protokolu.",
|
||||
"detail_to": "Komu",
|
||||
"detail_subject": "Predmet",
|
||||
"detail_no_subject": "Bez predmetu",
|
||||
|
||||
@@ -2701,7 +2701,6 @@
|
||||
"select_account_title": "เลือกบัญชี",
|
||||
"select_mailto_account": "เลือกบัญชีที่ต้องการให้เปิดลิงก์อีเมลนี้",
|
||||
"select_webcal_account": "เลือกบัญชีที่ต้องการให้เปิดลิงก์ปฏิทินนี้",
|
||||
"select_account_note": "การตั้งค่านี้มีผลเฉพาะกับลิงก์โปรโตคอลนี้เท่านั้น",
|
||||
"detail_to": "ถึง",
|
||||
"detail_subject": "เรื่อง",
|
||||
"detail_no_subject": "ไม่มีหัวข้อเรื่อง",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Hesap seç",
|
||||
"select_mailto_account": "Bu e-posta bağlantısını hangi hesabın açacağını seçin.",
|
||||
"select_webcal_account": "Bu takvim bağlantısını hangi hesabın açacağını seçin.",
|
||||
"select_account_note": "Bu seçim yalnızca bu protokol bağlantısı için geçerlidir.",
|
||||
"detail_to": "Kime",
|
||||
"detail_subject": "Konu",
|
||||
"detail_no_subject": "Konu yok",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Виберіть акаунт",
|
||||
"select_mailto_account": "Виберіть акаунт, у якому слід відкрити це посилання електронної пошти.",
|
||||
"select_webcal_account": "Виберіть акаунт, у якому слід відкрити це посилання календаря.",
|
||||
"select_account_note": "Цей вибір застосовується лише до цього посилання протоколу.",
|
||||
"detail_to": "Кому",
|
||||
"detail_subject": "Тема",
|
||||
"detail_no_subject": "Без теми",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "Chọn tài khoản",
|
||||
"select_mailto_account": "Chọn tài khoản nào sẽ mở liên kết email này.",
|
||||
"select_webcal_account": "Chọn tài khoản nào sẽ mở liên kết lịch này.",
|
||||
"select_account_note": "Điều này chỉ áp dụng cho liên kết giao thức này.",
|
||||
"detail_to": "Đến",
|
||||
"detail_subject": "Tiêu đề",
|
||||
"detail_no_subject": "Không có tiêu đề",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "選擇帳號",
|
||||
"select_mailto_account": "選擇用於開啟此電子郵件連結的帳號。",
|
||||
"select_webcal_account": "選擇用於開啟此行事曆連結的帳號。",
|
||||
"select_account_note": "此選擇僅適用於此協議連結。",
|
||||
"detail_to": "收件者",
|
||||
"detail_subject": "主題",
|
||||
"detail_no_subject": "無主題",
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
"select_account_title": "选择账户",
|
||||
"select_mailto_account": "选择用于打开此电子邮件链接的账户。",
|
||||
"select_webcal_account": "选择用于打开此日历链接的账户。",
|
||||
"select_account_note": "此选择仅适用于此协议链接。",
|
||||
"detail_to": "收件人",
|
||||
"detail_subject": "主题",
|
||||
"detail_no_subject": "无主题",
|
||||
|
||||
Reference in New Issue
Block a user