mirror of
https://github.com/flectar/mail.git
synced 2026-11-11 17:57:54 +00:00
818 lines
41 KiB
Plaintext
818 lines
41 KiB
Plaintext
import { ScrollFade } from "scroll-fade.slint";
|
|
import { ListView, VerticalBox } from "std-widgets.slint";
|
|
import { MailProfileRow, SidebarRow, SidebarRowKind } from "../models.slint";
|
|
import { SidebarItem, SidebarSectionHeader } from "sidebar-controls.slint";
|
|
import { SidebarStyle } from "sidebar-row.slint";
|
|
import { Button } from "button.slint";
|
|
import { IconButton, LineEdit } from "controls.slint";
|
|
import { ProfileSwitcher } from "profile-switcher.slint";
|
|
import {
|
|
CollapsibleWorkspaceSidebar,
|
|
WorkspaceMiniHeading,
|
|
} from "workspace-layout.slint";
|
|
import { LayoutMetrics, MailIconPalette, MotionSettings } from "../design-system.slint";
|
|
import { LocalMailUi } from "../local-mail.slint";
|
|
import { Updates } from "../updates.slint";
|
|
import { TypeScale } from "../typography.slint";
|
|
|
|
// The profile switcher across a sidebar, as tall as its buttons.
|
|
component SidebarProfileSwitcher inherits Rectangle {
|
|
in property <[MailProfileRow]> profiles;
|
|
in property <MailProfileRow> active;
|
|
in property <int> account-count;
|
|
callback choose(string);
|
|
callback create-profile();
|
|
callback manage-profiles();
|
|
|
|
height: LayoutMetrics.sidebar-action-height;
|
|
|
|
ProfileSwitcher {
|
|
x: 0px;
|
|
y: 0px;
|
|
height: parent.height;
|
|
fill-width: true;
|
|
widest: parent.width;
|
|
profiles: root.profiles;
|
|
active: root.active;
|
|
account-count: root.account-count;
|
|
choose(id) => { root.choose(id); }
|
|
create-profile => { root.create-profile(); }
|
|
manage-profiles => { root.manage-profiles(); }
|
|
}
|
|
}
|
|
|
|
// A newer release is out: a quiet line at the foot of the sidebar that leads
|
|
// to its page, until the user puts it away (src/updates.rs).
|
|
component UpdateNotice inherits Rectangle {
|
|
in property <bool> touch-mode;
|
|
in property <color> background-color;
|
|
in property <color> hover-background;
|
|
in property <color> accent-color;
|
|
in property <color> title-color;
|
|
in property <color> muted-color;
|
|
|
|
height: max(root.touch-mode ? 52px : 44px, labels.preferred-height + 14px);
|
|
border-radius: 8px;
|
|
background: open.has-hover ? root.hover-background : root.background-color;
|
|
|
|
Image {
|
|
x: 12px;
|
|
y: (parent.height - self.height) / 2;
|
|
width: LayoutMetrics.icon-size;
|
|
height: LayoutMetrics.icon-size;
|
|
source: @image-url("../icons/lucide/outline/download.svg");
|
|
colorize: root.accent-color;
|
|
image-fit: contain;
|
|
accessible-role: none;
|
|
}
|
|
labels := VerticalLayout {
|
|
x: 12px + LayoutMetrics.icon-size + 10px;
|
|
width: parent.width - self.x - 38px;
|
|
alignment: center;
|
|
Text {
|
|
text: @tr("New version available");
|
|
color: root.title-color;
|
|
font-size: TypeScale.caption;
|
|
font-weight: 600;
|
|
overflow: elide;
|
|
}
|
|
Text {
|
|
text: @tr("Version {}", Updates.version);
|
|
color: root.muted-color;
|
|
font-size: TypeScale.caption;
|
|
overflow: elide;
|
|
}
|
|
}
|
|
open := TouchArea {
|
|
width: parent.width - 38px;
|
|
accessible-role: button;
|
|
accessible-label: @tr("Flectar Mail {} is out. Open its release page.", Updates.version);
|
|
accessible-action-default => { Updates.open-release(); }
|
|
mouse-cursor: pointer;
|
|
clicked => { Updates.open-release(); }
|
|
}
|
|
IconButton {
|
|
x: parent.width - 34px;
|
|
y: (parent.height - self.height) / 2;
|
|
width: 28px;
|
|
height: 28px;
|
|
icon: @image-url("../icons/lucide/outline/x.svg");
|
|
icon-size: 12px;
|
|
icon-color: root.muted-color;
|
|
hover-background: root.hover-background;
|
|
tooltip-text: @tr("Hide until the next version");
|
|
clicked => { Updates.dismiss(); }
|
|
}
|
|
}
|
|
|
|
export component MailSidebar inherits CollapsibleWorkspaceSidebar {
|
|
in property <bool> touch-mode: false;
|
|
in property <[SidebarRow]> rows: [];
|
|
in-out property <length> scroll-y: 0px;
|
|
in-out property <string> filter-query: "";
|
|
private property <bool> filter-open: root.filter-query != "";
|
|
in property <string> unified-count;
|
|
in property <bool> sync-in-progress: false;
|
|
in property <string> selected-scope;
|
|
in property <bool> monochrome-icons: false;
|
|
in property <color> background-color;
|
|
in property <color> hover-background;
|
|
in property <color> selection-background;
|
|
in property <color> accent-color;
|
|
in property <color> title-color;
|
|
in property <color> body-color;
|
|
in property <color> muted-color;
|
|
// Without the tab bar, the profile pill heads the sidebar once there
|
|
// are profiles to choose from.
|
|
in property <bool> show-profiles: false;
|
|
in property <[MailProfileRow]> profiles: [];
|
|
in property <MailProfileRow> active-profile;
|
|
in property <int> account-count;
|
|
callback select-scope(string);
|
|
callback compose;
|
|
callback manage-accounts;
|
|
callback sync-account(int);
|
|
callback choose-profile(string);
|
|
callback create-profile();
|
|
callback manage-profiles();
|
|
callback toggle-folder(int, bool);
|
|
callback toggle-section(string, bool);
|
|
callback filter-folders(string);
|
|
callback request-create-folder(int, int, string);
|
|
callback request-create-label(int, string, int, string);
|
|
callback request-rename-folder(int, string);
|
|
callback request-delete-folder(int, string);
|
|
callback request-empty-trash(int);
|
|
callback request-rename-label(int, string, color, string, bool);
|
|
callback request-delete-label(int, string, string, bool, bool);
|
|
|
|
surface-color: root.background-color;
|
|
clip: true;
|
|
|
|
// Account rows hold a name and an address; both keep their 12px design
|
|
// and grow with the platform font.
|
|
private property <length> account-row-height: 10px
|
|
+ max(20px, account-name-probe.preferred-height)
|
|
+ max(15px, account-detail-probe.preferred-height);
|
|
account-name-probe := Text { visible: false; text: "Ag"; font-size: SidebarStyle.label-size; font-weight: SidebarStyle.selected-weight; }
|
|
account-detail-probe := Text { visible: false; text: "Ag"; font-size: TypeScale.caption; }
|
|
|
|
if !root.collapsed: VerticalBox {
|
|
x: LayoutMetrics.sidebar-inset;
|
|
y: LayoutMetrics.sidebar-action-top;
|
|
width: parent.width - 2 * LayoutMetrics.sidebar-inset;
|
|
height: parent.height - LayoutMetrics.sidebar-action-top;
|
|
padding: 0px;
|
|
spacing: 8px;
|
|
|
|
// The phone drawer opens on the profile, once there are profiles.
|
|
if root.show-profiles && root.touch-mode && root.profiles.length > 0 : SidebarProfileSwitcher {
|
|
width: parent.width;
|
|
profiles: root.profiles;
|
|
active: root.active-profile;
|
|
account-count: root.account-count;
|
|
choose(id) => { root.choose-profile(id); }
|
|
create-profile => { root.create-profile(); }
|
|
manage-profiles => { root.manage-profiles(); }
|
|
}
|
|
|
|
// With only local mail, nothing could send; adding an account comes
|
|
// first.
|
|
Button {
|
|
height: LayoutMetrics.sidebar-action-height;
|
|
horizontal-stretch: 1;
|
|
text: LocalMailUi.can-send ? @tr("New email") : @tr("Add an account");
|
|
icon: LocalMailUi.can-send ? @image-url("../icons/lucide/filled/compose.svg") : @image-url("../icons/lucide/filled/person-add.svg");
|
|
has-icon: true;
|
|
primary: true;
|
|
clicked => {
|
|
if LocalMailUi.can-send {
|
|
root.compose();
|
|
} else {
|
|
root.manage-accounts();
|
|
}
|
|
}
|
|
}
|
|
|
|
// A desktop sidebar stands in for the top bar's pill, which is always
|
|
// there, below the sidebar's main action.
|
|
if root.show-profiles && !root.touch-mode : SidebarProfileSwitcher {
|
|
width: parent.width;
|
|
profiles: root.profiles;
|
|
active: root.active-profile;
|
|
account-count: root.account-count;
|
|
choose(id) => { root.choose-profile(id); }
|
|
create-profile => { root.create-profile(); }
|
|
manage-profiles => { root.manage-profiles(); }
|
|
}
|
|
|
|
|
|
Rectangle {
|
|
height: 32px;
|
|
horizontal-stretch: 1;
|
|
background: transparent;
|
|
|
|
Rectangle {
|
|
visible: !root.filter-open;
|
|
x: 0px;
|
|
width: parent.width - 36px;
|
|
height: parent.height;
|
|
border-radius: 6px;
|
|
background: find-hit.has-hover ? root.hover-background : transparent;
|
|
|
|
Image {
|
|
x: 13px - self.width / 2;
|
|
y: (parent.height - self.height) / 2;
|
|
width: LayoutMetrics.icon-size;
|
|
height: LayoutMetrics.icon-size;
|
|
source: @image-url("../icons/lucide/outline/search.svg");
|
|
colorize: root.muted-color;
|
|
image-fit: contain;
|
|
accessible-role: none;
|
|
}
|
|
|
|
Text {
|
|
x: 28px;
|
|
width: parent.width - 28px;
|
|
height: parent.height;
|
|
text: @tr("Find folder or label");
|
|
color: root.muted-color;
|
|
font-size: TypeScale.caption;
|
|
vertical-alignment: center;
|
|
overflow: elide;
|
|
}
|
|
|
|
find-hit := TouchArea {
|
|
accessible-role: button;
|
|
accessible-label: @tr("Find folder or label");
|
|
accessible-action-default => {
|
|
root.filter-open = true;
|
|
filter-field.focus();
|
|
}
|
|
clicked => {
|
|
root.filter-open = true;
|
|
filter-field.focus();
|
|
}
|
|
mouse-cursor: pointer;
|
|
}
|
|
}
|
|
|
|
filter-field := LineEdit {
|
|
visible: root.filter-open;
|
|
x: 0px;
|
|
width: parent.width - 36px;
|
|
height: parent.height;
|
|
text <=> root.filter-query;
|
|
placeholder-text: @tr("Find folder or label");
|
|
input-label: @tr("Find folder or label");
|
|
show-leading-icon: true;
|
|
leading-icon: @image-url("../icons/lucide/outline/search.svg");
|
|
leading-icon-color: root.muted-color;
|
|
trailing-content-width: 32px;
|
|
edited(value) => { root.filter-folders(value); }
|
|
}
|
|
|
|
IconButton {
|
|
visible: root.filter-open;
|
|
x: parent.width - 68px;
|
|
width: 32px;
|
|
height: 32px;
|
|
icon: @image-url("../icons/lucide/outline/x.svg");
|
|
icon-size: 14px;
|
|
icon-color: root.muted-color;
|
|
hover-background: root.hover-background;
|
|
tooltip-text: @tr("Clear folder filter");
|
|
clicked => {
|
|
root.filter-query = "";
|
|
root.filter-open = false;
|
|
root.filter-folders("");
|
|
}
|
|
}
|
|
|
|
IconButton {
|
|
x: parent.width - 32px;
|
|
width: 32px;
|
|
height: 32px;
|
|
icon: @image-url("../icons/lucide/outline/plus.svg");
|
|
icon-size: 16px;
|
|
icon-color: root.muted-color;
|
|
hover-background: root.hover-background;
|
|
tooltip-text: @tr("Add account");
|
|
clicked => { root.manage-accounts(); }
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
vertical-stretch: 1;
|
|
width: parent.width;
|
|
background: transparent;
|
|
|
|
mailbox-scroll := ListView {
|
|
// Keep a direct ListView repeater; Slint does not
|
|
// virtualize through a wrapper or inherited ListView.
|
|
content-width: self.visible-width;
|
|
horizontal-scrollbar-policy: always-off;
|
|
x: 0px;
|
|
y: 0px;
|
|
width: parent.width;
|
|
height: parent.height;
|
|
content-y <=> root.scroll-y;
|
|
|
|
mouse-drag-pan-enabled: root.touch-mode;
|
|
|
|
// The repeater must be a direct ListView child: nesting it in
|
|
// a layout disables virtualization. Rust supplies only expanded rows.
|
|
for entry in root.rows: Rectangle {
|
|
private property <bool> reveal-ready: !entry.reveal_row;
|
|
width: max(0px, mailbox-scroll.visible-width - LayoutMetrics.sidebar-scrollbar-gutter);
|
|
height: !entry.show_row || (entry.reveal_row && !self.reveal-ready && MotionSettings.enabled) ? 0px
|
|
: entry.kind == SidebarRowKind.unified-heading ? 21px
|
|
: entry.kind == SidebarRowKind.accounts-heading ? 25px
|
|
: entry.kind == SidebarRowKind.account ? (entry.mailbox.detail == "" ? 35px : root.account-row-height)
|
|
: entry.kind == SidebarRowKind.unified-section || entry.kind == SidebarRowKind.unified-inbox ? 35px
|
|
: entry.kind == SidebarRowKind.folder && entry.mailbox.label == "Inbox" ? 35px
|
|
: 31px;
|
|
background: transparent;
|
|
clip: true;
|
|
animate height { duration: 230ms; easing: spring(0); enabled: MotionSettings.enabled; }
|
|
|
|
Timer {
|
|
interval: 16ms;
|
|
running: entry.reveal_row && !parent.reveal-ready && MotionSettings.enabled;
|
|
triggered => { parent.reveal-ready = true; }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.unified-heading: WorkspaceMiniHeading {
|
|
x: 0px;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("ALL ACCOUNTS");
|
|
label-color: root.muted-color;
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.unified-section: SidebarSectionHeader {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("All Inboxes");
|
|
icon: @image-url("../icons/lucide/filled/stack.svg");
|
|
sidebar-background: root.background-color;
|
|
hover-background: root.hover-background;
|
|
body-color: root.title-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.monochrome-icons ? root.body-color : MailIconPalette.inbox;
|
|
open: entry.open;
|
|
toggled(open) => { root.toggle-section(entry.key, open); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.unified-inbox: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("Inbox");
|
|
count: root.unified-count;
|
|
scope: "Unified Inbox";
|
|
account-id: 0;
|
|
folder-id: -1;
|
|
mail-drop-enabled: true;
|
|
icon: @image-url("../icons/lucide/filled/inbox-flectar.svg");
|
|
selected: root.selected-scope == "Unified Inbox";
|
|
row-height: 32px;
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.monochrome-icons ? (root.selected-scope == "Unified Inbox" ? root.accent-color : root.muted-color) : MailIconPalette.inbox;
|
|
clicked(scope) => { root.select-scope(scope); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.unified-mailbox: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: entry.mailbox.label;
|
|
count: entry.mailbox.count;
|
|
scope: entry.mailbox.scope;
|
|
account-id: entry.mailbox.account_id;
|
|
can-empty-trash: entry.mailbox.scope == "Unified Trash";
|
|
folder-id: entry.mailbox.folder_id;
|
|
mail-drop-enabled: entry.mailbox.scope == "Unified Starred"
|
|
|| entry.mailbox.scope == "Unified Archive"
|
|
|| entry.mailbox.scope == "Unified Spam"
|
|
|| entry.mailbox.scope == "Unified Trash";
|
|
mail-drop-copies: entry.mailbox.scope == "Unified Starred";
|
|
icon: entry.mailbox.scope == "Unified Starred" ? @image-url("../icons/lucide/filled/star.svg")
|
|
: entry.mailbox.scope == "Unified Sent" ? @image-url("../icons/lucide/filled/paper-airplane.svg")
|
|
: entry.mailbox.scope == "Unified Spam" ? @image-url("../icons/lucide/filled/alert.svg")
|
|
: entry.mailbox.scope == "Unified Trash" ? @image-url("../icons/lucide/filled/trash.svg")
|
|
: entry.mailbox.scope == "Unified Archive" ? @image-url("../icons/lucide/filled/archive.svg")
|
|
: @image-url("../icons/lucide/filled/draft.svg");
|
|
selected: entry.mailbox.scope == root.selected-scope;
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.monochrome-icons ? (entry.mailbox.scope == root.selected-scope ? root.accent-color : root.muted-color)
|
|
: entry.mailbox.scope == "Unified Starred" ? MailIconPalette.starred
|
|
: entry.mailbox.scope == "Unified Sent" ? MailIconPalette.sent
|
|
: entry.mailbox.scope == "Unified Spam" ? MailIconPalette.spam
|
|
: entry.mailbox.scope == "Unified Trash" ? MailIconPalette.trash
|
|
: entry.mailbox.scope == "Unified Archive" ? MailIconPalette.archive
|
|
: MailIconPalette.drafts;
|
|
clicked(scope) => { root.select-scope(scope); }
|
|
empty-trash(account-id) => { root.request-empty-trash(account-id); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.categories-section: SidebarSectionHeader {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("Categories");
|
|
label-font-weight: 500;
|
|
folder-row-style: true;
|
|
sidebar-background: root.background-color;
|
|
hover-background: root.hover-background;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon: @image-url("../icons/lucide/filled/tag.svg");
|
|
icon-color: root.monochrome-icons ? root.body-color : MailIconPalette.inbox;
|
|
open: entry.open;
|
|
toggled(open) => { root.toggle-section(entry.key, open); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.important: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("Important");
|
|
count: entry.mailbox.count;
|
|
left-padding: SidebarStyle.icon-left + SidebarStyle.branch-indent;
|
|
scope: "Important";
|
|
mail-drop-enabled: true;
|
|
icon: @image-url("../icons/lucide/filled/tag.svg");
|
|
selected: root.selected-scope == "Important";
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.monochrome-icons ? (root.selected-scope == "Important" ? root.accent-color : root.muted-color) : MailIconPalette.inbox;
|
|
clicked(scope) => { root.select-scope(scope); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.other: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("Other");
|
|
count: entry.mailbox.count;
|
|
left-padding: SidebarStyle.icon-left + SidebarStyle.branch-indent;
|
|
scope: "Other";
|
|
mail-drop-enabled: true;
|
|
icon: @image-url("../icons/lucide/filled/tag.svg");
|
|
selected: root.selected-scope == "Other";
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.monochrome-icons ? (root.selected-scope == "Other" ? root.accent-color : root.muted-color) : MailIconPalette.other;
|
|
clicked(scope) => { root.select-scope(scope); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.category: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: entry.label.name;
|
|
count: entry.label.count;
|
|
label-has-emoji: entry.label.name_has_emoji;
|
|
left-padding: SidebarStyle.icon-left + SidebarStyle.branch-indent;
|
|
scope: "Category:" + entry.label.id;
|
|
mail-drop-enabled: true;
|
|
icon: @image-url("../icons/lucide/filled/tag.svg");
|
|
selected: root.selected-scope == "Category:" + entry.label.id;
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.monochrome-icons
|
|
? (root.selected-scope == "Category:" + entry.label.id ? root.accent-color : root.muted-color)
|
|
: entry.label.color;
|
|
clicked(scope) => { root.select-scope(scope); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.global-labels-section: SidebarSectionHeader {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("Labels");
|
|
label-font-weight: 500;
|
|
folder-row-style: true;
|
|
sidebar-background: root.background-color;
|
|
hover-background: root.hover-background;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon: @image-url("../icons/lucide/filled/tag.svg");
|
|
icon-color: root.monochrome-icons ? root.body-color : MailIconPalette.folders;
|
|
open: entry.open;
|
|
toggled(open) => { root.toggle-section(entry.key, open); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.global-label: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: entry.label.name;
|
|
accessible-name: @tr("Global label {}", entry.label.name);
|
|
count: entry.label.count;
|
|
label-has-emoji: entry.label.name_has_emoji;
|
|
left-padding: SidebarStyle.icon-left + SidebarStyle.branch-indent;
|
|
label-id: entry.label.id;
|
|
editable-color: entry.label.color;
|
|
scope: "GlobalLabel:" + entry.label.id;
|
|
label-manageable: true;
|
|
label-is-global: true;
|
|
mail-drop-enabled: true;
|
|
mail-drop-copies: true;
|
|
icon: @image-url("../icons/lucide/filled/tag.svg");
|
|
selected: root.selected-scope == "GlobalLabel:" + entry.label.id;
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.monochrome-icons
|
|
? (root.selected-scope == "GlobalLabel:" + entry.label.id ? root.accent-color : root.muted-color)
|
|
: entry.label.color;
|
|
clicked(scope) => { root.select-scope(scope); }
|
|
rename-label(id, name, color, account, global) => { root.request-rename-label(id, name, color, account, global); }
|
|
delete-label(id, name, account, global, has-children) => {
|
|
root.request-delete-label(id, name, account, global, has-children);
|
|
}
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.accounts-heading: WorkspaceMiniHeading {
|
|
x: 0px;
|
|
y: 0px;
|
|
width: parent.width;
|
|
height: 22px;
|
|
label: @tr("ACCOUNTS");
|
|
label-color: root.muted-color;
|
|
vertical-alignment: bottom;
|
|
}
|
|
|
|
// Local mail is listed like an account, under its own
|
|
// name and a folders icon.
|
|
if entry.kind == SidebarRowKind.account: SidebarSectionHeader {
|
|
private property <bool> local: entry.mailbox.account_id == LocalMailUi.account-id;
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: self.local ? @tr("On this device") : entry.mailbox.label;
|
|
detail: entry.mailbox.detail;
|
|
avatar: entry.mailbox.avatar;
|
|
avatar-image: entry.mailbox.avatar_image;
|
|
has-avatar-image: entry.mailbox.has_avatar;
|
|
has-avatar: !self.local;
|
|
count: entry.mailbox.count;
|
|
icon: @image-url("../icons/lucide/filled/folders.svg");
|
|
sidebar-background: root.background-color;
|
|
hover-background: root.hover-background;
|
|
body-color: root.title-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: self.local && !root.monochrome-icons ? MailIconPalette.folders : root.body-color;
|
|
open: entry.open;
|
|
// Mail on this device has no server or settings page.
|
|
account-menu: !self.local;
|
|
can-check-mail: !root.sync-in-progress;
|
|
toggled(open) => { root.toggle-section(entry.key, open); }
|
|
check-mail => { root.sync-account(entry.mailbox.account_id); }
|
|
account-settings => { root.manage-accounts(); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.folder: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
|
|
label: entry.mailbox.label;
|
|
label-has-emoji: entry.mailbox.label_has_emoji;
|
|
count: entry.mailbox.count;
|
|
scope: entry.mailbox.scope;
|
|
account-id: entry.mailbox.account_id;
|
|
folder-id: entry.mailbox.folder_id;
|
|
has-children: entry.mailbox.has_children;
|
|
expanded: entry.mailbox.expanded;
|
|
folder-menu-enabled: entry.mailbox.folder_id >= 0
|
|
&& !(entry.mailbox.is_standard && entry.mailbox.label == "Trash")
|
|
&& (entry.mailbox.can_create_children
|
|
|| (!entry.mailbox.is_standard && entry.mailbox.can_rename)
|
|
|| (!entry.mailbox.is_standard && entry.mailbox.can_delete));
|
|
can-create-child: entry.mailbox.can_create_children;
|
|
can-rename: !entry.mailbox.is_standard && entry.mailbox.can_rename;
|
|
can-delete: !entry.mailbox.is_standard && entry.mailbox.can_delete;
|
|
can-empty-trash: entry.mailbox.is_standard
|
|
&& entry.mailbox.label == "Trash"
|
|
&& entry.mailbox.folder_id >= 0;
|
|
mail-drop-enabled: entry.mailbox.is_selectable
|
|
&& ((entry.mailbox.folder_id >= 0
|
|
&& entry.mailbox.label != "Sent"
|
|
&& entry.mailbox.label != "Drafts")
|
|
|| entry.mailbox.label == "Starred");
|
|
mail-drop-copies: entry.mailbox.label == "Starred";
|
|
left-padding: SidebarStyle.icon-left + entry.mailbox.depth * SidebarStyle.branch-indent;
|
|
icon: entry.mailbox.label == "Inbox" ? @image-url("../icons/lucide/filled/inbox-flectar.svg")
|
|
: entry.mailbox.label == "Starred" ? @image-url("../icons/lucide/filled/star.svg")
|
|
: entry.mailbox.label == "Sent" ? @image-url("../icons/lucide/filled/paper-airplane.svg")
|
|
: entry.mailbox.label == "Archive" ? @image-url("../icons/lucide/filled/archive.svg")
|
|
: entry.mailbox.label == "Spam" ? @image-url("../icons/lucide/filled/alert.svg")
|
|
: entry.mailbox.label == "Trash" ? @image-url("../icons/lucide/filled/trash.svg")
|
|
: entry.mailbox.label == "Drafts" ? @image-url("../icons/lucide/filled/draft.svg")
|
|
: entry.mailbox.scope == root.selected-scope ? @image-url("../icons/lucide/filled/folder-open.svg")
|
|
: @image-url("../icons/lucide/filled/file-directory.svg");
|
|
selected: entry.mailbox.scope == root.selected-scope;
|
|
row-height: entry.mailbox.label == "Inbox" ? 32px : 28px;
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.monochrome-icons ? (entry.mailbox.scope == root.selected-scope ? root.accent-color : root.muted-color)
|
|
: entry.mailbox.label == "Inbox" ? MailIconPalette.inbox
|
|
: entry.mailbox.label == "Starred" ? MailIconPalette.starred
|
|
: entry.mailbox.label == "Sent" ? MailIconPalette.sent
|
|
: entry.mailbox.label == "Archive" ? MailIconPalette.archive
|
|
: entry.mailbox.label == "Spam" ? MailIconPalette.spam
|
|
: entry.mailbox.label == "Trash" ? MailIconPalette.trash
|
|
: entry.mailbox.label == "Drafts" ? MailIconPalette.drafts
|
|
: entry.mailbox.has_custom_color ? entry.mailbox.color
|
|
: MailIconPalette.folders;
|
|
clicked(scope) => {
|
|
if (entry.mailbox.is_selectable || entry.mailbox.is_standard) {
|
|
root.select-scope(scope);
|
|
} else if (entry.mailbox.has_children) {
|
|
root.toggle-folder(entry.mailbox.folder_id, !entry.mailbox.expanded);
|
|
}
|
|
}
|
|
toggled(folder-id, expanded) => { root.toggle-folder(folder-id, expanded); }
|
|
new-subfolder(account-id, folder-id, name) => {
|
|
root.request-create-folder(account-id, folder-id, name);
|
|
}
|
|
rename-folder(folder-id, name) => { root.request-rename-folder(folder-id, name); }
|
|
delete-folder(folder-id, name) => { root.request-delete-folder(folder-id, name); }
|
|
empty-trash(account-id) => { root.request-empty-trash(account-id); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.account-labels-section: SidebarSectionHeader {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("Labels");
|
|
label-font-weight: 500;
|
|
folder-row-style: true;
|
|
sidebar-background: root.background-color;
|
|
hover-background: root.hover-background;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon: @image-url("../icons/lucide/filled/tag.svg");
|
|
icon-color: root.monochrome-icons ? root.body-color : MailIconPalette.folders;
|
|
open: entry.open;
|
|
toggled(open) => { root.toggle-section(entry.key, open); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.account-label: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: entry.label.display_name;
|
|
label-path: entry.label.name;
|
|
accessible-name: @tr("{} label, {} account", entry.label.name, entry.label.account_name);
|
|
count: entry.label.count;
|
|
label-has-emoji: entry.label.name_has_emoji;
|
|
left-padding: SidebarStyle.icon-left + SidebarStyle.branch-indent
|
|
+ entry.label.depth * SidebarStyle.branch-indent;
|
|
label-id: entry.label.id;
|
|
has-children: entry.label.has_children;
|
|
expanded: entry.label.expanded;
|
|
label-tree-node: true;
|
|
editable-color: entry.label.color;
|
|
scope: "AccountLabel:" + entry.label.id;
|
|
account-id: entry.label.account_id;
|
|
label-manageable: true;
|
|
label-can-create-child: entry.label.can_create_children;
|
|
label-account-name: entry.label.account_name;
|
|
mail-drop-enabled: true;
|
|
mail-drop-copies: true;
|
|
icon: @image-url("../icons/lucide/filled/tag.svg");
|
|
selected: root.selected-scope == "AccountLabel:" + entry.label.id;
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.monochrome-icons
|
|
? (root.selected-scope == "AccountLabel:" + entry.label.id ? root.accent-color : root.muted-color)
|
|
: entry.label.color;
|
|
clicked(scope) => { root.select-scope(scope); }
|
|
toggled(label-id, expanded) => { root.toggle-section(entry.key, expanded); }
|
|
new-child-label(account-id, label-id, path, account) => {
|
|
root.request-create-label(account-id, account, label-id, path);
|
|
}
|
|
rename-label(id, name, color, account, global) => { root.request-rename-label(id, name, color, account, global); }
|
|
delete-label(id, name, account, global, has-children) => {
|
|
root.request-delete-label(id, name, account, global, has-children);
|
|
}
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.new-folder: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("New folder");
|
|
scope: "";
|
|
icon: @image-url("../icons/lucide/outline/plus.svg");
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.muted-color;
|
|
clicked(scope) => { root.request-create-folder(entry.mailbox.account_id, -1, ""); }
|
|
}
|
|
|
|
if entry.kind == SidebarRowKind.new-label: SidebarItem {
|
|
x: 0px;
|
|
interactive: entry.show_row;
|
|
y: 0px;
|
|
width: parent.width;
|
|
label: @tr("New label");
|
|
scope: "";
|
|
left-padding: SidebarStyle.icon-left + SidebarStyle.branch-indent;
|
|
icon: @image-url("../icons/lucide/outline/plus.svg");
|
|
sidebar-background: root.background-color;
|
|
selection-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
icon-color: root.muted-color;
|
|
clicked(scope) => { root.request-create-label(entry.mailbox.account_id, entry.mailbox.context, -1, ""); }
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if root.filter-query != "" && root.rows.length == 0 : Text {
|
|
x: 12px;
|
|
y: 12px;
|
|
width: parent.width - 24px;
|
|
text: @tr("No folders found");
|
|
color: root.muted-color;
|
|
font-size: TypeScale.caption;
|
|
horizontal-alignment: center;
|
|
wrap: word-wrap;
|
|
}
|
|
|
|
ScrollFade {
|
|
x: mailbox-scroll.x;
|
|
y: mailbox-scroll.y;
|
|
width: mailbox-scroll.visible-width;
|
|
height: mailbox-scroll.visible-height;
|
|
surface-color: root.background-color;
|
|
content-y: mailbox-scroll.content-y;
|
|
content-height: mailbox-scroll.content-height;
|
|
visible-height: mailbox-scroll.visible-height;
|
|
}
|
|
}
|
|
|
|
if Updates.offered && Updates.enabled && Updates.version != "" && !Updates.dismissed : VerticalLayout {
|
|
padding-bottom: 10px;
|
|
UpdateNotice {
|
|
touch-mode: root.touch-mode;
|
|
background-color: root.hover-background;
|
|
hover-background: root.selection-background;
|
|
accent-color: root.accent-color;
|
|
title-color: root.title-color;
|
|
muted-color: root.muted-color;
|
|
}
|
|
}
|
|
}
|
|
}
|