mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-04 16:14:07 +00:00
feat: lay out Mountain View's navigation like Gmail's, with a Labels section
This commit is contained in:
+30
-2
@@ -1047,10 +1047,38 @@ optgroup {
|
||||
border-end-end-radius: var(--mv-nav-radius);
|
||||
}
|
||||
|
||||
/* Compose: a 56px pill, which shrinks to a circle with the rail. */
|
||||
/* Selected and hovered rows fill the pill; a folder with unread mail reads
|
||||
bold, the way the message rows do. Icons are 20px with an 18px gap. */
|
||||
[data-interface-layout="mountain-view"] [data-mv-nav-row] {
|
||||
font-size: 0.875rem;
|
||||
color: var(--color-foreground);
|
||||
}
|
||||
[data-interface-layout="mountain-view"] [data-mv-nav-row]:hover {
|
||||
background-color: var(--mv-nav-hover);
|
||||
}
|
||||
[data-interface-layout="mountain-view"] [data-mv-nav-row][data-selected="true"] {
|
||||
background-color: var(--mv-nav-selected);
|
||||
color: var(--color-foreground);
|
||||
font-weight: 700;
|
||||
}
|
||||
[data-interface-layout="mountain-view"] [data-mv-nav-row][data-has-unread] {
|
||||
font-weight: 700;
|
||||
}
|
||||
[data-interface-layout="mountain-view"] [data-mv-nav-row] > button {
|
||||
gap: 18px;
|
||||
}
|
||||
[data-interface-layout="mountain-view"] [data-mv-nav-row] > button > span:first-child,
|
||||
[data-interface-layout="mountain-view"] [data-mv-nav-row] > button > span:first-child > svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* Compose: a 56px button with a 16px corner, which shrinks to a square with
|
||||
the rail. */
|
||||
[data-interface-layout="mountain-view"] [data-mv-compose] {
|
||||
height: var(--mv-compose-h);
|
||||
border-radius: var(--mv-nav-radius);
|
||||
border-radius: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* The account popover: a wide card with a very round corner, rather
|
||||
|
||||
@@ -2,10 +2,10 @@ import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import type { Mailbox } from '@/lib/jmap/types';
|
||||
|
||||
// Under Mountain View the sidebar is one flat list: inbox, sent and drafts,
|
||||
// then a single "More" that reveals the folders you made, the shared ones and
|
||||
// the labels. Outside Mountain View the "Folders" / "Tags" sections stay as they
|
||||
// are, headings and all.
|
||||
// Under Mountain View the sidebar is laid out the way Gmail's is: inbox, sent
|
||||
// and drafts, a "More" that reveals the other system folders, then a
|
||||
// "Labels" list of the folders you made and your tags. Outside Mountain View
|
||||
// the "Folders" / "Tags" sections stay as they are, headings and all.
|
||||
|
||||
vi.mock('@/components/plugins/plugin-slot', () => ({ PluginSlot: () => null }));
|
||||
vi.mock('@/components/tour/tour-provider', () => ({
|
||||
@@ -47,15 +47,27 @@ describe('Sidebar under Mountain View', () => {
|
||||
} as never);
|
||||
});
|
||||
|
||||
it('drops the Folders heading and holds the rest behind More', () => {
|
||||
it('drops the Folders heading and holds the system folders behind More', () => {
|
||||
render(<Sidebar mailboxes={mailboxes} selectedMailbox="inbox" mvShell />);
|
||||
|
||||
expect(screen.queryByText('folders')).toBeNull();
|
||||
expect(screen.getByText('show_more')).toBeInTheDocument();
|
||||
expect(folderRow('Receipts')).toBeNull();
|
||||
expect(folderRow('Trash')).toBeNull();
|
||||
// The labels heading goes with them: it shows only once expanded.
|
||||
});
|
||||
|
||||
it('lists your folders and tags under Labels, outside More', () => {
|
||||
const onCreateFolder = vi.fn();
|
||||
const { container } = render(
|
||||
<Sidebar mailboxes={mailboxes} selectedMailbox="inbox" mvShell onCreateFolder={onCreateFolder} />,
|
||||
);
|
||||
|
||||
expect(screen.getByText('labels')).toBeInTheDocument();
|
||||
expect(screen.queryByText('tags')).toBeNull();
|
||||
expect(container.querySelector('[data-mv-labels] [data-folder-name="Receipts"]')).not.toBeNull();
|
||||
expect(screen.getByText('Work')).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByLabelText('create_label'));
|
||||
expect(onCreateFolder).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('keeps the places mail actually goes in view', () => {
|
||||
@@ -83,16 +95,14 @@ describe('Sidebar under Mountain View', () => {
|
||||
expect(container.querySelector('[data-folder-name="mv-starred"]')).toBeNull();
|
||||
});
|
||||
|
||||
it('reveals the folders and the labels together, and takes them back', () => {
|
||||
it('reveals the system folders under More, and takes them back', () => {
|
||||
render(<Sidebar mailboxes={mailboxes} selectedMailbox="inbox" mvShell />);
|
||||
|
||||
fireEvent.click(screen.getByText('show_more'));
|
||||
expect(folderRow('Receipts')).not.toBeNull();
|
||||
expect(folderRow('Trash')).not.toBeNull();
|
||||
expect(screen.getByText('tags')).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByText('show_fewer'));
|
||||
expect(folderRow('Receipts')).toBeNull();
|
||||
expect(folderRow('Trash')).toBeNull();
|
||||
});
|
||||
|
||||
it('leaves the default layout its sections and every folder', () => {
|
||||
|
||||
@@ -32,7 +32,8 @@ import {
|
||||
Loader2,
|
||||
AlertTriangle,
|
||||
NotebookPen,
|
||||
PenSquare,
|
||||
Pencil,
|
||||
Plus,
|
||||
CalendarClock,
|
||||
BellOff,
|
||||
Mails,
|
||||
@@ -210,14 +211,33 @@ function getIconClass(isSelected: boolean, isVirtual: boolean, colorful: boolean
|
||||
function SidebarRowCounts({
|
||||
unread,
|
||||
total,
|
||||
role,
|
||||
onUnreadClick,
|
||||
}: {
|
||||
unread?: number;
|
||||
total?: number;
|
||||
role?: string | null;
|
||||
isSelected: boolean;
|
||||
onUnreadClick?: () => void;
|
||||
}) {
|
||||
const showFolderTotalCount = useSettingsStore(s => s.showFolderTotalCount);
|
||||
const mountainView = useSettingsStore(s => s.interfaceLayout === 'mountain-view');
|
||||
// Mountain View counts one thing per row: what is unread, or for Drafts,
|
||||
// how many there are, since a draft is never unread.
|
||||
if (mountainView) {
|
||||
const count = role === 'drafts' ? (total ?? 0) : (unread ?? 0);
|
||||
if (count === 0) return null;
|
||||
return (
|
||||
<span
|
||||
className={cn("ms-2 flex-shrink-0 text-xs tabular-nums", role === 'drafts' ? "text-muted-foreground" : "font-bold text-foreground")}
|
||||
data-testid="folder-counts"
|
||||
data-unread={unread ?? 0}
|
||||
data-total={role === 'drafts' ? count : 0}
|
||||
>
|
||||
{count.toLocaleString()}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
const unreadCount = unread ?? 0;
|
||||
const totalCount = showFolderTotalCount ? (total ?? 0) : 0;
|
||||
|
||||
@@ -336,6 +356,7 @@ function SidebarRow({
|
||||
data-mailbox-id={testMailboxId ?? undefined}
|
||||
data-shared={testShared ? 'true' : undefined}
|
||||
data-selected={isSelected ? 'true' : undefined}
|
||||
data-has-unread={(unread ?? 0) > 0 && testRole !== 'drafts' ? '' : undefined}
|
||||
style={{ paddingBlock: 'var(--density-sidebar-py)' }}
|
||||
className={cn(
|
||||
"group w-full flex items-center max-lg:min-h-[44px] text-sm transition-colors duration-150",
|
||||
@@ -396,6 +417,7 @@ function SidebarRow({
|
||||
<SidebarRowCounts
|
||||
unread={unread}
|
||||
total={total}
|
||||
role={testRole}
|
||||
isSelected={isSelected}
|
||||
onUnreadClick={onUnreadClick}
|
||||
/>
|
||||
@@ -922,7 +944,8 @@ export function Sidebar({
|
||||
const hideAccountSwitcher = useSettingsStore(s => s.hideAccountSwitcher) || isEmbedded;
|
||||
const enableUnifiedMailbox = useSettingsStore(s => s.enableUnifiedMailbox);
|
||||
const includeGroupInUnified = useSettingsStore(s => s.includeGroupInUnified);
|
||||
const colorfulSidebarIcons = useSettingsStore(s => s.colorfulSidebarIcons);
|
||||
// Mountain View draws its navigation icons in the text colour.
|
||||
const colorfulSidebarIcons = useSettingsStore(s => s.colorfulSidebarIcons) && !mvShell;
|
||||
const tagCounts = useEmailStore(s => s.tagCounts);
|
||||
const accounts = useAccountStore(s => s.accounts);
|
||||
const connectedAccounts = accounts.filter(a => a.isConnected);
|
||||
@@ -1045,6 +1068,11 @@ export function Sidebar({
|
||||
node.role === 'inbox' || node.role === 'sent' || node.role === 'drafts';
|
||||
const primaryTree = mvFlat ? ownTree.filter(isPrimaryFolder) : ownTree;
|
||||
const secondaryTree = mvFlat ? ownTree.filter((node) => !isPrimaryFolder(node)) : [];
|
||||
// Of those, the system folders (archive, spam, trash...) go behind "More",
|
||||
// and the folders the user made are listed with the tags under "Labels",
|
||||
// which is what they are to someone coming from Gmail.
|
||||
const moreTree = secondaryTree.filter((node) => !!node.role);
|
||||
const labelTree = secondaryTree.filter((node) => !node.role);
|
||||
// Everything under "More" is hidden together, so one flag covers the extra
|
||||
// folders, the shared accounts and the labels.
|
||||
const showSecondary = !mvFlat || moreExpanded;
|
||||
@@ -1107,7 +1135,7 @@ export function Sidebar({
|
||||
return (
|
||||
<SidebarRow
|
||||
key={key}
|
||||
icon={<CalendarClock className="w-4 h-4 flex-shrink-0 text-sky-600 dark:text-sky-400" />}
|
||||
icon={<CalendarClock className={cn("w-4 h-4 flex-shrink-0", mvShell ? "text-foreground/80" : "text-sky-600 dark:text-sky-400")} />}
|
||||
label={t('scheduled')}
|
||||
depth={account?.depth ?? 0}
|
||||
isSelected={!selectedKeyword && isScheduledSelected}
|
||||
@@ -1312,13 +1340,13 @@ export function Sidebar({
|
||||
data-mv-compose=""
|
||||
data-tour="compose-button"
|
||||
className={cn(
|
||||
"flex items-center bg-primary text-primary-foreground shadow-sm hover:shadow-md transition-shadow",
|
||||
"flex items-center bg-[var(--mv-compose-bg)] text-[var(--mv-compose-fg)] hover:shadow-md transition-shadow",
|
||||
isCollapsed ? "w-14 justify-center" : "gap-3 ps-4 pe-6"
|
||||
)}
|
||||
title={t("compose_hint")}
|
||||
aria-label={t("compose")}
|
||||
>
|
||||
<PenSquare className="w-5 h-5 flex-shrink-0" />
|
||||
<Pencil className="w-6 h-6 flex-shrink-0" />
|
||||
{!isCollapsed && <span className="text-sm font-medium">{t("compose")}</span>}
|
||||
</button>
|
||||
</div>
|
||||
@@ -1513,7 +1541,7 @@ export function Sidebar({
|
||||
isCollapsed={false}
|
||||
/>
|
||||
)}
|
||||
{mvFlat && moreExpanded && secondaryTree.map((node) => (
|
||||
{mvFlat && moreExpanded && moreTree.map((node) => (
|
||||
<MailboxTreeItem
|
||||
key={node.id}
|
||||
node={node}
|
||||
@@ -1534,6 +1562,39 @@ export function Sidebar({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{mvFlat && !useMultiAccount && (
|
||||
<div data-mv-labels="">
|
||||
<div className="flex items-center justify-between ps-[26px] pe-3 pt-4 pb-1">
|
||||
<span className="text-base font-medium text-foreground">{t("labels")}</span>
|
||||
{onCreateFolder && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onCreateFolder()}
|
||||
className="grid place-items-center w-8 h-8 rounded-full text-foreground hover:bg-[var(--mv-nav-hover)] transition-colors"
|
||||
title={t("create_label")}
|
||||
aria-label={t("create_label")}
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{labelTree.map((node) => (
|
||||
<MailboxTreeItem
|
||||
key={node.id}
|
||||
node={node}
|
||||
selectedMailbox={selectedKeyword ? "" : selectedMailbox}
|
||||
expandedFolders={expandedFolders}
|
||||
onMailboxSelect={onMailboxSelect}
|
||||
onToggleExpand={handleToggleExpand}
|
||||
isCollapsed={isCollapsed}
|
||||
onUnreadFilterClick={onUnreadFilterClick}
|
||||
colorful={colorfulSidebarIcons}
|
||||
onContextMenu={handleMailboxContextMenu}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!useMultiAccount && showSecondary && sharedAccounts.length > 0 && (
|
||||
<div>
|
||||
<SidebarSectionHeader
|
||||
@@ -1593,17 +1654,20 @@ export function Sidebar({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showSecondary && emailKeywords.length > 0 && (
|
||||
{(showSecondary || mvFlat) && emailKeywords.length > 0 && (
|
||||
<div data-tour="keyword-tags">
|
||||
<SidebarSectionHeader
|
||||
label={t("tags")}
|
||||
expanded={tagsExpanded}
|
||||
onToggle={toggleTags}
|
||||
onSettings={openKeywordSettings}
|
||||
settingsTitle={t('settings')}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
{((tagsExpanded && !isCollapsed) || isCollapsed) && (
|
||||
{/* Under Mountain View the tags continue the "Labels" list. */}
|
||||
{!mvFlat && (
|
||||
<SidebarSectionHeader
|
||||
label={t("tags")}
|
||||
expanded={tagsExpanded}
|
||||
onToggle={toggleTags}
|
||||
onSettings={openKeywordSettings}
|
||||
settingsTitle={t('settings')}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
)}
|
||||
{((tagsExpanded && !isCollapsed) || isCollapsed || mvFlat) && (
|
||||
<>
|
||||
{visibleTagTree.map((node) => (
|
||||
<TagItem
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "كل المميز بنجمة",
|
||||
"unified_all_mail": "كل البريد",
|
||||
"remove_account": "إزالة الحساب",
|
||||
"remove_account_confirm": "هل تريد إزالة {account} من هذا الجهاز؟ يمكنك إضافته مرة أخرى لاحقًا."
|
||||
"remove_account_confirm": "هل تريد إزالة {account} من هذا الجهاز؟ يمكنك إضافته مرة أخرى لاحقًا.",
|
||||
"labels": "التصنيفات",
|
||||
"create_label": "إنشاء تصنيف جديد"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "التطبيقات الافتراضية",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Tots els destacats",
|
||||
"unified_all_mail": "Tot el correu",
|
||||
"remove_account": "Elimina el compte",
|
||||
"remove_account_confirm": "Voleu eliminar {account} d'aquest dispositiu? El podreu tornar a afegir més endavant."
|
||||
"remove_account_confirm": "Voleu eliminar {account} d'aquest dispositiu? El podreu tornar a afegir més endavant.",
|
||||
"labels": "Etiquetes",
|
||||
"create_label": "Crea una etiqueta nova"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Aplicacions predeterminades",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Vše s hvězdičkou",
|
||||
"unified_all_mail": "Veškerá pošta",
|
||||
"remove_account": "Odebrat účet",
|
||||
"remove_account_confirm": "Odebrat účet {account} z tohoto zařízení? Později ho můžete znovu přidat."
|
||||
"remove_account_confirm": "Odebrat účet {account} z tohoto zařízení? Později ho můžete znovu přidat.",
|
||||
"labels": "Štítky",
|
||||
"create_label": "Vytvořit nový štítek"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Výchozí aplikace",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Alle med stjerne",
|
||||
"unified_all_mail": "Al post",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Etiketter",
|
||||
"create_label": "Opret ny etiket"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Standardapps",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Alle markierten",
|
||||
"unified_all_mail": "Alle Mails",
|
||||
"remove_account": "Konto entfernen",
|
||||
"remove_account_confirm": "{account} von diesem Gerät entfernen? Sie können das Konto später wieder hinzufügen."
|
||||
"remove_account_confirm": "{account} von diesem Gerät entfernen? Sie können das Konto später wieder hinzufügen.",
|
||||
"labels": "Labels",
|
||||
"create_label": "Neues Label erstellen"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Standard-Apps",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "All starred",
|
||||
"unified_all_mail": "All mail",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Labels",
|
||||
"create_label": "Create new label"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Default apps",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Todo destacado",
|
||||
"unified_all_mail": "Todo el correo",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Etiquetas",
|
||||
"create_label": "Crear etiqueta"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Aplicaciones predeterminadas",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "همه ستارهدارها",
|
||||
"unified_all_unread": "همه خواندهنشدهها",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "برچسبها",
|
||||
"create_label": "ایجاد برچسب جدید"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "برنامههای پیشفرض",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Tous les favoris",
|
||||
"unified_all_mail": "Tout le courrier",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Libellés",
|
||||
"create_label": "Créer un libellé"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Applications par défaut",
|
||||
|
||||
@@ -152,7 +152,9 @@
|
||||
"unified_all_starred": "הכל מסומנים",
|
||||
"unified_all_mail": "הכל דוא״ל",
|
||||
"remove_account": "הסרת חשבון",
|
||||
"remove_account_confirm": "להסיר את {account} מהמכשיר הזה? ניתן להוסיף אותו שוב מאוחר יותר."
|
||||
"remove_account_confirm": "להסיר את {account} מהמכשיר הזה? ניתן להוסיף אותו שוב מאוחר יותר.",
|
||||
"labels": "תוויות",
|
||||
"create_label": "יצירת תווית חדשה"
|
||||
},
|
||||
"sidebar_apps": {
|
||||
"modal_title": "אפליקציות בסרגל הצד",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Összes csillagozott",
|
||||
"unified_all_mail": "Összes levél",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Címkék",
|
||||
"create_label": "Új címke létrehozása"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Alapértelmezett alkalmazások",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Tutti gli speciali",
|
||||
"unified_all_mail": "Tutta la posta",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Etichette",
|
||||
"create_label": "Crea nuova etichetta"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "App predefinite",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "すべてのスター付き",
|
||||
"unified_all_mail": "すべてのメール",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "ラベル",
|
||||
"create_label": "新しいラベルを作成"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "既定のアプリ",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "모든 별표",
|
||||
"unified_all_mail": "모든 메일",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "라벨",
|
||||
"create_label": "새 라벨 만들기"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "기본 앱",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Visi ar zvaigzni",
|
||||
"unified_all_mail": "Visas vēstules",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Etiķetes",
|
||||
"create_label": "Izveidot jaunu etiķeti"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Noklusējuma lietotnes",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Бүх одтой",
|
||||
"unified_all_mail": "Бүх шуудан",
|
||||
"remove_account": "Бүртгэл устгах",
|
||||
"remove_account_confirm": "Энэ төхөөрөмжөөс {account}-г устгах уу? Та дараа дахин нэмж болно."
|
||||
"remove_account_confirm": "Энэ төхөөрөмжөөс {account}-г устгах уу? Та дараа дахин нэмж болно.",
|
||||
"labels": "Шошго",
|
||||
"create_label": "Шинэ шошго үүсгэх"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Өгөгдмөл програмууд",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Alle stjernemerkede",
|
||||
"unified_all_mail": "All e-post",
|
||||
"remove_account": "Fjern konto",
|
||||
"remove_account_confirm": "Vil du fjerne {account} fra denne enheten? Du kan legge den til igjen senere."
|
||||
"remove_account_confirm": "Vil du fjerne {account} fra denne enheten? Du kan legge den til igjen senere.",
|
||||
"labels": "Etiketter",
|
||||
"create_label": "Opprett ny etikett"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Standardapper",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Alle met ster",
|
||||
"unified_all_mail": "Alle e-mail",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Labels",
|
||||
"create_label": "Nieuw label maken"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Standaardapps",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Wszystkie oznaczone gwiazdką",
|
||||
"unified_all_mail": "Cała poczta",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Etykiety",
|
||||
"create_label": "Utwórz etykietę"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Aplikacje domyślne",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Tudo com estrela",
|
||||
"unified_all_mail": "Todo o correio",
|
||||
"remove_account": "Remover conta",
|
||||
"remove_account_confirm": "Remover {account} desse dispositivo? Você pode adicioná-la de volta depois."
|
||||
"remove_account_confirm": "Remover {account} desse dispositivo? Você pode adicioná-la de volta depois.",
|
||||
"labels": "Etiquetas",
|
||||
"create_label": "Criar etiqueta"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Aplicativos padrão",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Toate cu stea",
|
||||
"unified_all_mail": "Toată poșta",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Etichete",
|
||||
"create_label": "Creează o etichetă nouă"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Aplicații implicite",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Все помеченные",
|
||||
"unified_all_mail": "Вся почта",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Ярлыки",
|
||||
"create_label": "Создать ярлык"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Приложения по умолчанию",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Všetky s hviezdičkou",
|
||||
"unified_all_mail": "Všetka pošta",
|
||||
"remove_account": "Odstrániť účet",
|
||||
"remove_account_confirm": "Odstrániť {account} z tohto zariadenia? Neskôr ho môžete znova pridať."
|
||||
"remove_account_confirm": "Odstrániť {account} z tohto zariadenia? Neskôr ho môžete znova pridať.",
|
||||
"labels": "Štítky",
|
||||
"create_label": "Vytvoriť nový štítok"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Predvolené aplikácie",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Tüm yıldızlılar",
|
||||
"unified_all_mail": "Tüm postalar",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Etiketler",
|
||||
"create_label": "Yeni etiket oluştur"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Varsayılan uygulamalar",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "Усі позначені",
|
||||
"unified_all_mail": "Уся пошта",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "Мітки",
|
||||
"create_label": "Створити мітку"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "Програми за замовчуванням",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "全部已加星號",
|
||||
"unified_all_mail": "全部郵件",
|
||||
"remove_account": "移除帳號",
|
||||
"remove_account_confirm": "要從這部裝置移除 {account} 嗎?您稍後仍可重新新增。"
|
||||
"remove_account_confirm": "要從這部裝置移除 {account} 嗎?您稍後仍可重新新增。",
|
||||
"labels": "標籤",
|
||||
"create_label": "建立新標籤"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "預設應用程式",
|
||||
|
||||
@@ -153,7 +153,9 @@
|
||||
"unified_all_starred": "全部加星标",
|
||||
"unified_all_mail": "全部邮件",
|
||||
"remove_account": "Remove account",
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later."
|
||||
"remove_account_confirm": "Remove {account} from this device? You can add it back later.",
|
||||
"labels": "标签",
|
||||
"create_label": "新建标签"
|
||||
},
|
||||
"protocol_handlers": {
|
||||
"title": "默认应用",
|
||||
|
||||
Reference in New Issue
Block a user