mirror of
https://github.com/flectar/mail.git
synced 2026-11-11 17:57:54 +00:00
2676 lines
158 KiB
Plaintext
2676 lines
158 KiB
Plaintext
export { AccountMailPreferences, SignatureChoice } from "components/account-mail-preferences.slint";
|
||
import { OpenPgpReader } from "components/account-mail-preferences.slint";
|
||
import { MailAttachments } from "models.slint";
|
||
import { AttachmentPreviewDialog } from "dialogs/attachment-preview-dialog.slint";
|
||
export { MailAttachments, MailAttachment } from "models.slint";
|
||
export { ZoomApi } from "components/zoom-controls.slint";
|
||
export { RendererSettings } from "renderer-settings.slint";
|
||
export { WindowChrome } from "window-chrome.slint";
|
||
export { AppIcon, AppIconVariant } from "app-icon.slint";
|
||
export { DefaultEmailApp } from "default-email-app.slint";
|
||
export { SystemNotifications } from "system-notifications.slint";
|
||
export { Updates } from "updates.slint";
|
||
export { Notice } from "notice.slint";
|
||
export { Unsubscribe } from "unsubscribe.slint";
|
||
export { BlockSender } from "block-sender.slint";
|
||
import { AppIcon, AppIconVariant } from "app-icon.slint";
|
||
import { WindowChrome, WindowControls, WindowDragArea } from "window-chrome.slint";
|
||
// Bundled once at compile time and used throughout the application chrome.
|
||
// Rust registers the separate Noto Emoji face before constructing this window.
|
||
import "../resources/fonts/google-sans-flex/GoogleSansFlex-VariableFont_GRAD,ROND,opsz,slnt,wdth,wght.ttf";
|
||
|
||
import { Palette } from "std-widgets.slint";
|
||
import { TypeScale } from "typography.slint";
|
||
export { AppTheme, MotionSettings, ThemeUtilities } from "design-system.slint";
|
||
import { AppTheme, LayoutMetrics } from "design-system.slint";
|
||
import { Button } from "components/button.slint";
|
||
import { LoadingSkeletonBlock } from "components/loading-skeleton.slint";
|
||
import { AccountRow, CalendarAgendaRow, CalendarAgendaFilterRow, CalendarDay, CalendarEventRow, CalendarSourceRow, CalendarWeekDay, ComposeAttachment, ComposeContact, ComposeEditorTile, ContactSidebarRow, ContactRow, ContactSyncState, ContactValueRow, EmailLink, EmailRow, EmailTemplateRow, EmailTile, LocalizedMessage, MailListEntry, MailProfileRow, ProfileMemberRow, SidebarRow, MailLabelRow, StorageUsageRow, ThreadMessageRow } from "models.slint";
|
||
export { EmailReader, ReaderCaret, ReaderImage, ReaderItem, MailDragApi } from "models.slint";
|
||
export { MailListNavigation, MailNavigationTarget } from "models.slint";
|
||
export { ThreadMessageRow, StorageUsageRow } from "models.slint";
|
||
export { CalendarAgendaNavigation } from "components/calendar-agenda.slint";
|
||
export { KeyboardKeys, KeyChord } from "components/kbd.slint";
|
||
import { FunctionalCalendarView } from "components/calendar.slint";
|
||
import { CompactProductNav, ProductRail, WindowTopBar } from "components/workspace-navigation.slint";
|
||
export { TabsUi, TabRow } from "components/workspace-navigation.slint";
|
||
import { TabsUi } from "components/workspace-navigation.slint";
|
||
import { TabOverview } from "components/tab-overview.slint";
|
||
import { WorkspaceFrame } from "components/workspace-layout.slint";
|
||
import { CalendarEventDialog } from "dialogs/calendar-event-dialog.slint";
|
||
import { ComposeDialog } from "dialogs/compose-dialog.slint";
|
||
import { NoticeToast } from "components/notice-toast.slint";
|
||
import { Notice } from "notice.slint";
|
||
import { UnsubscribeDialog } from "dialogs/unsubscribe-dialog.slint";
|
||
import { Unsubscribe } from "unsubscribe.slint";
|
||
import { BlockSenderDialog } from "dialogs/block-sender-dialog.slint";
|
||
import { BlockSender } from "block-sender.slint";
|
||
import { BoundComposer, ComposerUi } from "components/composer-ui.slint";
|
||
import { ComposerText } from "components/composer-fields.slint";
|
||
export { ComposerUi } from "components/composer-ui.slint";
|
||
import { FolderDialog } from "dialogs/folder-dialog.slint";
|
||
export { MovePickerUi, MoveTargetRow } from "dialogs/move-dialog.slint";
|
||
import { MoveDialog, MovePickerUi } from "dialogs/move-dialog.slint";
|
||
import { ConfirmationDialog } from "components/confirmation-dialog.slint";
|
||
import { SettingsDialog } from "dialogs/settings-dialog.slint";
|
||
import { AccountImport, ImportDialog } from "dialogs/import-dialog.slint";
|
||
export { LocalMailUi } from "local-mail.slint";
|
||
export { Numbers } from "numbers.slint";
|
||
import { LocalMailUi } from "local-mail.slint";
|
||
export { AccountImport, ImportAccountRow, ImportFailureRow, ImportFindingRow, ImportMailRow, ImportProfileRow } from "dialogs/import-dialog.slint";
|
||
export { ThemeDraft } from "components/theme-editor.slint";
|
||
import { ThemeDraft } from "components/theme-editor.slint";
|
||
import { MailView } from "views/mail-view.slint";
|
||
export { MessageColors } from "message-colors.slint";
|
||
export { FilesUi, FileRow, OperationRow } from "views/files-view.slint";
|
||
import { FilesView, FilesUi } from "views/files-view.slint";
|
||
import { ContactsView } from "views/contacts-view.slint";
|
||
import { OnboardingView } from "views/onboarding-view.slint";
|
||
|
||
// Rust view-models call this global for the date vocabulary and status text
|
||
// that must be materialized before it enters a Slint model. Keeping the
|
||
// translations here makes those strings part of the same bundled catalog as
|
||
// the declarative UI.
|
||
export global I18n {
|
||
// Date vocabulary and patterns for src/date_format.rs. Patterns use CLDR
|
||
// date field symbols: y year, M month (MMM abbreviated, MMMM full),
|
||
// LLLL standalone month, d day, E weekday (EEEE full), a AM/PM, h and H
|
||
// 12- and 24-hour hours, m minutes. Text in single quotes is literal.
|
||
pure callback date-month(int, string) -> string;
|
||
pure callback date-weekday(int, bool) -> string;
|
||
pure callback date-day-period(bool) -> string;
|
||
pure callback date-yesterday() -> string;
|
||
pure callback date-pattern(string) -> string;
|
||
pure callback date-range(string, string) -> string;
|
||
pure callback date-at-time(string, string) -> string;
|
||
pure callback calendar-all-day() -> string;
|
||
pure callback untitled-event() -> string;
|
||
pure callback no-contact-history() -> string;
|
||
pure callback contact-history-available() -> string;
|
||
pure callback new-contact-entry() -> string;
|
||
pure callback no-connected-account() -> string;
|
||
pure callback interaction-count(int) -> string;
|
||
// Words of new-mail notifications (src/notifications.rs).
|
||
pure callback notification-new-message() -> string;
|
||
pure callback notification-no-subject() -> string;
|
||
pure callback notification-new-messages(int) -> string;
|
||
pure callback notification-more-senders(string, int) -> string;
|
||
pure callback notification-open() -> string;
|
||
pure callback notification-mark-read() -> string;
|
||
pure callback notification-archive() -> string;
|
||
pure callback notification-delete() -> string;
|
||
pure callback notification-new-mail-channel() -> string;
|
||
pure callback notification-quiet-mail-channel() -> string;
|
||
// What a screen reader says for the count on the app icon.
|
||
pure callback notification-unread-count(int) -> string;
|
||
// The line a desktop shows for the app while it runs with its window
|
||
// closed (GNOME's Background Apps).
|
||
pure callback background-status() -> string;
|
||
pure callback last-contacted(string) -> string;
|
||
pure callback loading-local-data() -> string;
|
||
pure callback local-data-ready() -> string;
|
||
pure callback local-data-unavailable(string) -> string;
|
||
pure callback could-not-display-local-mail(string) -> string;
|
||
pure callback ui-message(string, string, string, string) -> string;
|
||
pure callback ui-message-settings(string, string, string, string) -> string;
|
||
pure callback ui-message-system(string, string, string, string) -> string;
|
||
pure callback ui-message-account(string, string, string, string) -> string;
|
||
pure callback ui-message-data(string, string, string, string) -> string;
|
||
pure callback ui-message-list(string, string, string, string) -> string;
|
||
pure callback ui-message-contacts(string, string, string, string) -> string;
|
||
pure callback ui-message-calendar(string, string, string, string) -> string;
|
||
pure callback ui-message-startup(string, string, string, string) -> string;
|
||
pure callback ui-message-sync(string, string, string, string) -> string;
|
||
pure callback ui-message-actions(string, string, string, string) -> string;
|
||
pure callback ui-message-compose(string, string, string, string) -> string;
|
||
pure callback ui-message-oauth(string, string, string, string) -> string;
|
||
|
||
date-month(month, form) => {
|
||
if (form == "abbreviated") {
|
||
if (month == 1) { return @tr("abbreviated month in a date" => "Jan"); }
|
||
if (month == 2) { return @tr("abbreviated month in a date" => "Feb"); }
|
||
if (month == 3) { return @tr("abbreviated month in a date" => "Mar"); }
|
||
if (month == 4) { return @tr("abbreviated month in a date" => "Apr"); }
|
||
if (month == 5) { return @tr("abbreviated month in a date" => "May"); }
|
||
if (month == 6) { return @tr("abbreviated month in a date" => "Jun"); }
|
||
if (month == 7) { return @tr("abbreviated month in a date" => "Jul"); }
|
||
if (month == 8) { return @tr("abbreviated month in a date" => "Aug"); }
|
||
if (month == 9) { return @tr("abbreviated month in a date" => "Sep"); }
|
||
if (month == 10) { return @tr("abbreviated month in a date" => "Oct"); }
|
||
if (month == 11) { return @tr("abbreviated month in a date" => "Nov"); }
|
||
if (month == 12) { return @tr("abbreviated month in a date" => "Dec"); }
|
||
}
|
||
if (form == "wide") {
|
||
if (month == 1) { return @tr("month in a date" => "January"); }
|
||
if (month == 2) { return @tr("month in a date" => "February"); }
|
||
if (month == 3) { return @tr("month in a date" => "March"); }
|
||
if (month == 4) { return @tr("month in a date" => "April"); }
|
||
if (month == 5) { return @tr("month in a date" => "May"); }
|
||
if (month == 6) { return @tr("month in a date" => "June"); }
|
||
if (month == 7) { return @tr("month in a date" => "July"); }
|
||
if (month == 8) { return @tr("month in a date" => "August"); }
|
||
if (month == 9) { return @tr("month in a date" => "September"); }
|
||
if (month == 10) { return @tr("month in a date" => "October"); }
|
||
if (month == 11) { return @tr("month in a date" => "November"); }
|
||
if (month == 12) { return @tr("month in a date" => "December"); }
|
||
}
|
||
if (month == 1) { return @tr("month on its own" => "January"); }
|
||
if (month == 2) { return @tr("month on its own" => "February"); }
|
||
if (month == 3) { return @tr("month on its own" => "March"); }
|
||
if (month == 4) { return @tr("month on its own" => "April"); }
|
||
if (month == 5) { return @tr("month on its own" => "May"); }
|
||
if (month == 6) { return @tr("month on its own" => "June"); }
|
||
if (month == 7) { return @tr("month on its own" => "July"); }
|
||
if (month == 8) { return @tr("month on its own" => "August"); }
|
||
if (month == 9) { return @tr("month on its own" => "September"); }
|
||
if (month == 10) { return @tr("month on its own" => "October"); }
|
||
if (month == 11) { return @tr("month on its own" => "November"); }
|
||
if (month == 12) { return @tr("month on its own" => "December"); }
|
||
return "";
|
||
}
|
||
|
||
date-weekday(day, abbreviated) => {
|
||
if (day == 0) { return abbreviated ? @tr("Mon") : @tr("Monday"); }
|
||
if (day == 1) { return abbreviated ? @tr("Tue") : @tr("Tuesday"); }
|
||
if (day == 2) { return abbreviated ? @tr("Wed") : @tr("Wednesday"); }
|
||
if (day == 3) { return abbreviated ? @tr("Thu") : @tr("Thursday"); }
|
||
if (day == 4) { return abbreviated ? @tr("Fri") : @tr("Friday"); }
|
||
if (day == 5) { return abbreviated ? @tr("Sat") : @tr("Saturday"); }
|
||
return abbreviated ? @tr("Sun") : @tr("Sunday");
|
||
}
|
||
|
||
date-day-period(pm) => {
|
||
return pm ? @tr("time of day" => "PM") : @tr("time of day" => "AM");
|
||
}
|
||
|
||
date-yesterday() => { return @tr("Yesterday"); }
|
||
|
||
date-pattern(key) => {
|
||
if (key == "short-day-month") { return @tr("date pattern (CLDR): day and month of recent mail in lists" => "MMM d"); }
|
||
if (key == "short-date") { return @tr("date pattern (CLDR): date of older mail in lists, keep it short" => "MMM d, y"); }
|
||
if (key == "date") { return @tr("date pattern (CLDR): a date on its own" => "MMM d, y"); }
|
||
if (key == "weekday-date") { return @tr("date pattern (CLDR): a date with its weekday" => "EEE, MMM d, y"); }
|
||
if (key == "weekday-day-month") { return @tr("date pattern (CLDR): day heading in the agenda" => "EEEE, MMMM d"); }
|
||
if (key == "month-year") { return @tr("date pattern (CLDR): month heading, LLLL is the month name on its own" => "LLLL y"); }
|
||
if (key == "same-month-start") { return @tr("date pattern (CLDR): first date of a range within one month" => "MMMM d"); }
|
||
if (key == "same-month-end") { return @tr("date pattern (CLDR): last date of a range within one month" => "d, y"); }
|
||
if (key == "same-year-start") { return @tr("date pattern (CLDR): first date of a range within one year" => "MMM d"); }
|
||
if (key == "same-year-end") { return @tr("date pattern (CLDR): last date of a range within one year" => "MMM d, y"); }
|
||
if (key == "time-24") { return @tr("time pattern (CLDR): 24-hour clock" => "HH:mm"); }
|
||
if (key == "time-12") { return @tr("time pattern (CLDR): 12-hour clock, a is AM or PM" => "h:mm a"); }
|
||
return @tr("time pattern (CLDR): whole hour on a 12-hour clock" => "h a");
|
||
}
|
||
|
||
date-range(start, end) => { return @tr("date range" => "{0} – {1}", start, end); }
|
||
date-at-time(date, time) => { return @tr("date and time" => "{0} at {1}", date, time); }
|
||
|
||
calendar-all-day() => { return @tr("All day"); }
|
||
untitled-event() => { return @tr("(untitled event)"); }
|
||
no-contact-history() => { return @tr("No conversation history"); }
|
||
contact-history-available() => { return @tr("Conversation history available"); }
|
||
new-contact-entry() => { return @tr("New address-book entry"); }
|
||
no-connected-account() => { return @tr("No connected account"); }
|
||
interaction-count(count) => {
|
||
return @tr("{n} interaction" | "{n} interactions" % count);
|
||
}
|
||
notification-new-message() => { return @tr("New message"); }
|
||
notification-no-subject() => { return @tr("(No subject)"); }
|
||
notification-new-messages(count) => {
|
||
return @tr("{n} new message" | "{n} new messages" % count);
|
||
}
|
||
notification-more-senders(senders, count) => {
|
||
return @tr("the first senders of new mail, then how many others"
|
||
=> "{0} and {n} more" | "{0} and {n} more" % count, senders);
|
||
}
|
||
notification-open() => { return @tr("Open"); }
|
||
notification-mark-read() => { return @tr("Mark as read"); }
|
||
notification-unread-count(count) => {
|
||
return @tr("{n} unread message" | "{n} unread messages" % count);
|
||
}
|
||
notification-archive() => { return @tr("Archive"); }
|
||
notification-delete() => { return @tr("Delete"); }
|
||
// The names of Android's notification channels for new mail, which its
|
||
// notification settings list: mail that may play a sound, and the rest.
|
||
notification-new-mail-channel() => { return @tr("New mail"); }
|
||
notification-quiet-mail-channel() => { return @tr("New mail without sound"); }
|
||
background-status() => { return @tr("Checking for new mail"); }
|
||
last-contacted(date) => { return @tr("Last contacted {}", date); }
|
||
loading-local-data() => { return @tr("Loading local data…"); }
|
||
local-data-ready() => { return @tr("Local data ready."); }
|
||
local-data-unavailable(error) => { return @tr("Local data is unavailable: {}", error); }
|
||
could-not-display-local-mail(error) => { return @tr("Could not display local mail: {}", error); }
|
||
ui-message(key, argument, second-argument, third-argument) => {
|
||
if (key == "") { return ""; }
|
||
// Every Rust-originated UI message is selected here from a stable key.
|
||
// Never translate `key` dynamically: explicit @tr expressions keep the
|
||
// complete source catalog available to extraction and translators. The
|
||
// bounded groups avoid a deeply recursive expression in the compiler.
|
||
let settings = root.ui-message-settings(key, argument, second-argument, third-argument);
|
||
if (settings != "") { return settings; }
|
||
let system = root.ui-message-system(key, argument, second-argument, third-argument);
|
||
if (system != "") { return system; }
|
||
let account = root.ui-message-account(key, argument, second-argument, third-argument);
|
||
if (account != "") { return account; }
|
||
let data = root.ui-message-data(key, argument, second-argument, third-argument);
|
||
if (data != "") { return data; }
|
||
let list = root.ui-message-list(key, argument, second-argument, third-argument);
|
||
if (list != "") { return list; }
|
||
let contacts = root.ui-message-contacts(key, argument, second-argument, third-argument);
|
||
if (contacts != "") { return contacts; }
|
||
let calendar = root.ui-message-calendar(key, argument, second-argument, third-argument);
|
||
if (calendar != "") { return calendar; }
|
||
let startup = root.ui-message-startup(key, argument, second-argument, third-argument);
|
||
if (startup != "") { return startup; }
|
||
let sync = root.ui-message-sync(key, argument, second-argument, third-argument);
|
||
if (sync != "") { return sync; }
|
||
let actions = root.ui-message-actions(key, argument, second-argument, third-argument);
|
||
if (actions != "") { return actions; }
|
||
let compose = root.ui-message-compose(key, argument, second-argument, third-argument);
|
||
if (compose != "") { return compose; }
|
||
let oauth = root.ui-message-oauth(key, argument, second-argument, third-argument);
|
||
if (oauth != "") { return oauth; }
|
||
return @tr("An unexpected interface message occurred.");
|
||
}
|
||
|
||
ui-message-settings(key, argument, second-argument, third-argument) => {
|
||
if (key == "Notification preferences are active for this session.") { return @tr("Notification preferences are active for this session."); }
|
||
if (key == "Notification preferences saved.") { return @tr("Notification preferences saved."); }
|
||
if (key == "Update preference saved.") { return @tr("Update preference saved."); }
|
||
if (key == "Undo send preference saved.") { return @tr("Undo send preference saved."); }
|
||
if (key == "Could not save notifications: {}") { return @tr("Could not save notifications: {}", argument); }
|
||
if (key == "Could not save the update preference: {}") { return @tr("Could not save the update preference: {}", argument); }
|
||
if (key == "Could not save the undo send preference: {}") { return @tr("Could not save the undo send preference: {}", argument); }
|
||
if (key == "Sync interval is active for this session.") { return @tr("Sync interval is active for this session."); }
|
||
if (key == "Sync interval set to {} minutes.") { return @tr("Sync interval set to {} minutes.", argument); }
|
||
if (key == "Could not save sync interval: {}") { return @tr("Could not save sync interval: {}", argument); }
|
||
if (key == "Message-opening preference updated for this session.") { return @tr("Message-opening preference updated for this session."); }
|
||
if (key == "Message-opening preference saved.") { return @tr("Message-opening preference saved."); }
|
||
if (key == "Could not save message-opening preference: {}") { return @tr("Could not save message-opening preference: {}", argument); }
|
||
if (key == "Contact suggestion preferences are active for this session.") { return @tr("Contact suggestion preferences are active for this session."); }
|
||
if (key == "Contact suggestion preferences saved.") { return @tr("Contact suggestion preferences saved."); }
|
||
if (key == "Could not save contact suggestion preferences: {}") { return @tr("Could not save contact suggestion preferences: {}", argument); }
|
||
if (key == "Contact storage is still starting. Try again shortly.") { return @tr("Contact storage is still starting. Try again shortly."); }
|
||
if (key == "Cleared {} suggested people.") { return @tr("Cleared {} suggested people.", argument); }
|
||
if (key == "Could not clear suggested people: {}") { return @tr("Could not clear suggested people: {}", argument); }
|
||
if (key == "Theme updated for this session.") { return @tr("Theme updated for this session."); }
|
||
if (key == "Theme preference saved.") { return @tr("Theme preference saved."); }
|
||
if (key == "Message appearance updated for this session.") { return @tr("Message appearance updated for this session."); }
|
||
if (key == "Message appearance preference saved.") { return @tr("Message appearance preference saved."); }
|
||
if (key == "Could not save message appearance: {}") { return @tr("Could not save message appearance: {}", argument); }
|
||
if (key == "Could not save theme: {}") { return @tr("Could not save theme: {}", argument); }
|
||
if (key == "Theme palette updated for this session.") { return @tr("Theme palette updated for this session."); }
|
||
if (key == "Theme palette saved.") { return @tr("Theme palette saved."); }
|
||
if (key == "Could not save theme palette: {}") { return @tr("Could not save theme palette: {}", argument); }
|
||
if (key == "Custom theme updated for this session.") { return @tr("Custom theme updated for this session."); }
|
||
if (key == "Custom theme saved.") { return @tr("Custom theme saved."); }
|
||
if (key == "Download location saved.") { return @tr("Download location saved."); }
|
||
if (key == "Download location is saved once an account is set up.") { return @tr("Download location is saved once an account is set up."); }
|
||
if (key == "Could not save the download location: {}") { return @tr("Could not save the download location: {}", argument); }
|
||
if (key == "Choose download location") { return @tr("Choose download location"); }
|
||
if (key == "Could not save custom theme: {}") { return @tr("Could not save custom theme: {}", argument); }
|
||
if (key == "Language updated for this session.") { return @tr("Language updated for this session."); }
|
||
if (key == "Language preference saved.") { return @tr("Language preference saved."); }
|
||
if (key == "Could not save language: {}") { return @tr("Could not save language: {}", argument); }
|
||
if (key == "Time format updated for this session.") { return @tr("Time format updated for this session."); }
|
||
if (key == "Time format preference saved.") { return @tr("Time format preference saved."); }
|
||
if (key == "Could not save time format: {}") { return @tr("Could not save time format: {}", argument); }
|
||
if (key == "Sidebar icon style updated for this session.") { return @tr("Sidebar icon style updated for this session."); }
|
||
if (key == "Sidebar icon preference saved.") { return @tr("Sidebar icon preference saved."); }
|
||
if (key == "Could not save sidebar icon preference: {}") { return @tr("Could not save sidebar icon preference: {}", argument); }
|
||
if (key == "App icon updated for this session.") { return @tr("App icon updated for this session."); }
|
||
if (key == "App icon saved.") { return @tr("App icon saved."); }
|
||
if (key == "Could not save app icon: {}") { return @tr("Could not save app icon: {}", argument); }
|
||
if (key == "Avatar preference updated for this session.") { return @tr("Avatar preference updated for this session."); }
|
||
if (key == "Avatar preference saved.") { return @tr("Avatar preference saved."); }
|
||
if (key == "Could not save avatar preference: {}") { return @tr("Could not save avatar preference: {}", argument); }
|
||
if (key == "Window frame updated for this session.") { return @tr("Window frame updated for this session."); }
|
||
if (key == "Window frame preference saved.") { return @tr("Window frame preference saved."); }
|
||
if (key == "Could not save window frame preference: {}") { return @tr("Could not save window frame preference: {}", argument); }
|
||
if (key == "Tabs preference updated for this session.") { return @tr("Tabs preference updated for this session."); }
|
||
if (key == "Tabs preference saved.") { return @tr("Tabs preference saved."); }
|
||
if (key == "Could not save tabs preference: {}") { return @tr("Could not save tabs preference: {}", argument); }
|
||
if (key == "Could not save spelling preference: {}") { return @tr("Could not save spelling preference: {}", argument); }
|
||
if (key == "At most {} tabs can be open. Close a tab to open another.") { return @tr("At most {} tabs can be open. Close a tab to open another.", argument); }
|
||
if (key == "Mail grouping is active for this session.") { return @tr("Mail grouping is active for this session."); }
|
||
if (key == "Mail grouping preference saved.") { return @tr("Mail grouping preference saved."); }
|
||
if (key == "Could not save mail grouping preference: {}") { return @tr("Could not save mail grouping preference: {}", argument); }
|
||
if (key == "Conversation view updated for this session.") { return @tr("Conversation view updated for this session."); }
|
||
if (key == "Conversation view preference saved.") { return @tr("Conversation view preference saved."); }
|
||
if (key == "Could not save conversation view preference: {}") { return @tr("Could not save conversation view preference: {}", argument); }
|
||
if (key == "Profile changes require local mail data.") { return @tr("Profile changes require local mail data."); }
|
||
if (key == "Profile saved.") { return @tr("Profile saved."); }
|
||
if (key == "Could not save profile: {}") { return @tr("Could not save profile: {}", argument); }
|
||
if (key == "Account profile updated.") { return @tr("Account profile updated."); }
|
||
if (key == "Account color changes require local mail data.") { return @tr("Account color changes require local mail data."); }
|
||
if (key == "Account color updated.") { return @tr("Account color updated."); }
|
||
if (key == "Could not update account color: {}") { return @tr("Could not update account color: {}", argument); }
|
||
if (key == "Could not update account profile: {}") { return @tr("Could not update account profile: {}", argument); }
|
||
if (key == "Profile deleted.") { return @tr("Profile deleted."); }
|
||
if (key == "Could not delete profile: {}") { return @tr("Could not delete profile: {}", argument); }
|
||
if (key == "Could not switch profile: {}") { return @tr("Could not switch profile: {}", argument); }
|
||
if (key == "Marker preference is active for this session.") { return @tr("Marker preference is active for this session."); }
|
||
if (key == "Mail-list marker preference saved.") { return @tr("Mail-list marker preference saved."); }
|
||
if (key == "Could not save mail-list marker preference: {}") { return @tr("Could not save mail-list marker preference: {}", argument); }
|
||
if (key == "Workspace layout updated for this session.") { return @tr("Workspace layout updated for this session."); }
|
||
if (key == "Workspace layout preference saved.") { return @tr("Workspace layout preference saved."); }
|
||
if (key == "Could not save workspace layout: {}") { return @tr("Could not save workspace layout: {}", argument); }
|
||
if (key == "Could not save list pane width: {}") { return @tr("Could not save list pane width: {}", argument); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-system(key, argument, second-argument, third-argument) => {
|
||
if (key == "Opened {}") { return @tr("Opened {}", argument); }
|
||
if (key == "Could not open link: {}") { return @tr("Could not open link: {}", argument); }
|
||
if (key == "This email link is too long to open.") { return @tr("This email link is too long to open."); }
|
||
if (key == "The email link will open when you close this message.") { return @tr("The email link will open when you close this message."); }
|
||
if (key == "The message you were writing was saved to Drafts.") { return @tr("The message you were writing was saved to Drafts."); }
|
||
if (key == "Files from links are never attached for you. Attach them yourself if you trust them: {}") { return @tr("Files from links are never attached for you. Attach them yourself if you trust them: {}", argument); }
|
||
if (key == "Copied HTML source") { return @tr("Copied HTML source"); }
|
||
if (key == "Copied HTML source. Paste it into the issue.") { return @tr("Copied HTML source. Paste it into the issue."); }
|
||
if (key == "Saved HTML source. Attach the file to the issue.") { return @tr("Saved HTML source. Attach the file to the issue."); }
|
||
if (key == "Could not save HTML source: {}") { return @tr("Could not save HTML source: {}", argument); }
|
||
if (key == "Copied selected text") { return @tr("Copied selected text"); }
|
||
if (key == "Copied email text") { return @tr("Copied email text"); }
|
||
if (key == "Copied link") { return @tr("Copied link"); }
|
||
if (key == "Blitz software selection render failed: {}") { return @tr("Blitz software selection render failed: {}", argument); }
|
||
if (key == "Blitz software tile render failed: {}") { return @tr("Blitz software tile render failed: {}", argument); }
|
||
if (key == "Message ready.") { return @tr("Message ready."); }
|
||
if (key == "System tray behavior is unavailable in this package.") { return @tr("System tray behavior is unavailable in this package."); }
|
||
if (key == "Close-to-tray is active for this session.") { return @tr("Close-to-tray is active for this session."); }
|
||
if (key == "Saving close behavior…") { return @tr("Saving close behavior…"); }
|
||
if (key == "Closing the window will now keep Flectar Mail in the tray.") { return @tr("Closing the window will now keep Flectar Mail in the tray."); }
|
||
if (key == "Closing the window will now quit Flectar Mail.") { return @tr("Closing the window will now quit Flectar Mail."); }
|
||
if (key == "Closing the window will now keep Flectar Mail running in the background.") { return @tr("Closing the window will now keep Flectar Mail running in the background."); }
|
||
if (key == "Your desktop did not allow Flectar Mail to run in the background.") { return @tr("Your desktop did not allow Flectar Mail to run in the background."); }
|
||
if (key == "Could not save close behavior: {}") { return @tr("Could not save close behavior: {}", argument); }
|
||
if (key == "Flectar Mail will start when you sign in.") { return @tr("Flectar Mail will start when you sign in."); }
|
||
if (key == "Flectar Mail is now your default email app.") { return @tr("Flectar Mail is now your default email app."); }
|
||
if (key == "Choose Flectar Mail for MAILTO in Windows Settings to finish.") { return @tr("Choose Flectar Mail for MAILTO in Windows Settings to finish."); }
|
||
if (key == "Windows no longer offers this copy for email links.") { return @tr("Windows no longer offers this copy for email links."); }
|
||
if (key == "Could not change the default email app: {}") { return @tr("Could not change the default email app: {}", argument); }
|
||
if (key == "Flectar Mail will no longer start when you sign in.") { return @tr("Flectar Mail will no longer start when you sign in."); }
|
||
if (key == "Could not change startup behavior: {}") { return @tr("Could not change startup behavior: {}", argument); }
|
||
if (key == "Allow Flectar Mail under Login Items in System Settings to finish.") { return @tr("Allow Flectar Mail under Login Items in System Settings to finish."); }
|
||
if (key == "Turn on Flectar Mail under Startup apps in Windows Settings to finish.") { return @tr("Turn on Flectar Mail under Startup apps in Windows Settings to finish."); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-account(key, argument, second-argument, third-argument) => {
|
||
if (key == "Database snapshot exported to {}.") { return @tr("Database snapshot exported to {}.", argument); }
|
||
if (key == "Choose where to export the mail") { return @tr("Choose where to export the mail"); }
|
||
if (key == "Exporting mail…") { return @tr("Exporting mail…"); }
|
||
if (key == "Mail exported to {}.") { return @tr("Mail exported to {}.", argument); }
|
||
if (key == "Mail exported to {}. Some messages could not be found on this device or the mail server.") { return @tr("Mail exported to {}. Some messages could not be found on this device or the mail server.", argument); }
|
||
if (key == "Could not export mail: {}") { return @tr("Could not export mail: {}", argument); }
|
||
if (key == "Could not export database snapshot: {}") { return @tr("Could not export database snapshot: {}", argument); }
|
||
if (key == "Account order saved.") { return @tr("Account order saved."); }
|
||
if (key == "Could not save account order: {}") { return @tr("Could not save account order: {}", argument); }
|
||
if (key == "Mail history updated. Background sync is adjusting now.") { return @tr("Mail history updated. Background sync is adjusting now."); }
|
||
if (key == "Account removed from this device.") { return @tr("Account removed from this device."); }
|
||
if (key == "Account removed. Mail refresh will retry.") { return @tr("Account removed. Mail refresh will retry."); }
|
||
if (key == "Account removed; local cleanup needs a retry: {}") { return @tr("Account removed; local cleanup needs a retry: {}", argument); }
|
||
if (key == "Could not remove account: {}") { return @tr("Could not remove account: {}", argument); }
|
||
if (key == "Removing account…") { return @tr("Removing account…"); }
|
||
if (key == "Deleting mail on this device…") { return @tr("Deleting mail on this device…"); }
|
||
if (key == "Mail on this device deleted.") { return @tr("Mail on this device deleted."); }
|
||
if (key == "Mail on this device deleted. Mail refresh will retry.") { return @tr("Mail on this device deleted. Mail refresh will retry."); }
|
||
if (key == "Mail on this device deleted; local cleanup needs a retry: {}") { return @tr("Mail on this device deleted; local cleanup needs a retry: {}", argument); }
|
||
if (key == "Could not delete mail on this device: {}") { return @tr("Could not delete mail on this device: {}", argument); }
|
||
if (key == "Synchronizing account…") { return @tr("Synchronizing account…"); }
|
||
if (key == "Could not update mail history: {}") { return @tr("Could not update mail history: {}", argument); }
|
||
if (key == "Connected {}. Initial sync is running in the background.") { return @tr("Connected {}. Initial sync is running in the background.", argument); }
|
||
if (key == "Account setup failed: {}") { return @tr("Account setup failed: {}", argument); }
|
||
if (key == "OAuth failed: {}") { return @tr("OAuth failed: {}", argument); }
|
||
if (key == "Reconnected {}. Synchronization is resuming.") { return @tr("Reconnected {}. Synchronization is resuming.", argument); }
|
||
if (key == "Reconnection failed: {}") { return @tr("Reconnection failed: {}", argument); }
|
||
if (key == "Calendar connected and initial sync started.") { return @tr("Calendar connected and initial sync started."); }
|
||
if (key == "Could not connect calendar: {}") { return @tr("Could not connect calendar: {}", argument); }
|
||
if (key == "Calendar sync enabled.") { return @tr("Calendar sync enabled."); }
|
||
if (key == "Calendar sync paused.") { return @tr("Calendar sync paused."); }
|
||
if (key == "Could not update calendar sync: {}") { return @tr("Could not update calendar sync: {}", argument); }
|
||
if (key == "CalDAV connected and initial sync started.") { return @tr("CalDAV connected and initial sync started."); }
|
||
if (key == "Could not connect CalDAV: {}") { return @tr("Could not connect CalDAV: {}", argument); }
|
||
if (key == "Calendar removed.") { return @tr("Calendar removed."); }
|
||
if (key == "Could not remove calendar: {}") { return @tr("Could not remove calendar: {}", argument); }
|
||
if (key == "CardDAV connected and initial sync started.") { return @tr("CardDAV connected and initial sync started."); }
|
||
if (key == "Could not connect CardDAV: {}") { return @tr("Could not connect CardDAV: {}", argument); }
|
||
if (key == "CardDAV sync enabled.") { return @tr("CardDAV sync enabled."); }
|
||
if (key == "CardDAV sync paused.") { return @tr("CardDAV sync paused."); }
|
||
if (key == "Could not update CardDAV sync: {}") { return @tr("Could not update CardDAV sync: {}", argument); }
|
||
if (key == "CardDAV disconnected.") { return @tr("CardDAV disconnected."); }
|
||
if (key == "Could not disconnect CardDAV: {}") { return @tr("Could not disconnect CardDAV: {}", argument); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-data(key, argument, second-argument, third-argument) => {
|
||
if (key == "Connect an account before creating a backup.") { return @tr("Connect an account before creating a backup."); }
|
||
if (key == "Export Flectar Mail account backup") { return @tr("Export Flectar Mail account backup"); }
|
||
if (key == "Flectar Mail backup") { return @tr("Flectar Mail backup"); }
|
||
if (key == "Import accounts and mail") { return @tr("Import accounts and mail"); }
|
||
if (key == "Choose a Thunderbird profile or a folder of mail") { return @tr("Choose a Thunderbird profile or a folder of mail"); }
|
||
if (key == "Imported messages") { return @tr("Imported messages"); }
|
||
if (key == "Choose where to export the database snapshot") { return @tr("Choose where to export the database snapshot"); }
|
||
if (key == "Backup exported. Passwords and OAuth tokens were not included.") { return @tr("Backup exported. Passwords and OAuth tokens were not included."); }
|
||
if (key == "Could not export backup: {}") { return @tr("Could not export backup: {}", argument); }
|
||
if (key == "Local data storage is unavailable. Retry startup.") { return @tr("Local data storage is unavailable. Retry startup."); }
|
||
if (key == "Creating verified database snapshot…") { return @tr("Creating verified database snapshot…"); }
|
||
if (key == "All local Flectar Mail data was deleted.") { return @tr("All local Flectar Mail data was deleted."); }
|
||
if (key == "Could not delete all local data: {}") { return @tr("Could not delete all local data: {}", argument); }
|
||
if (key == "Deleting local accounts and cached data…") { return @tr("Deleting local accounts and cached data…"); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-list(key, argument, second-argument, third-argument) => {
|
||
if (key == "Background mail refresh failed: {}") { return @tr("Background mail refresh failed: {}", argument); }
|
||
if (key == "No conversations in this folder") { return @tr("No conversations in this folder"); }
|
||
if (key == "No conversations match this search") { return @tr("No conversations match this search"); }
|
||
if (key == "Mail core is ready for account synchronization and message actions.") { return @tr("Mail core is ready for account synchronization and message actions."); }
|
||
if (key == "Large message rendered in compatibility mode.") { return @tr("Large message rendered in compatibility mode."); }
|
||
if (key == "Software email render failed: {}") { return @tr("Software email render failed: {}", argument); }
|
||
if (key == "Rendered with software fallback after GPU error: {}") { return @tr("Rendered with software fallback after GPU error: {}", argument); }
|
||
if (key == "Blitz render failed (GPU: {}; software: {})") { return @tr("Blitz render failed (GPU: {}; software: {})", argument, second-argument); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-contacts(key, argument, second-argument, third-argument) => {
|
||
if (key == "Enter a name, email address, or phone number, then save.") { return @tr("Enter a name, email address, or phone number, then save."); }
|
||
if (key == "Could not save: contact storage is unavailable.") { return @tr("Could not save: contact storage is unavailable."); }
|
||
if (key == "Could not save contact: {}") { return @tr("Could not save contact: {}", argument); }
|
||
if (key == "Contact saved.") { return @tr("Contact saved."); }
|
||
if (key == "Saved to contacts.") { return @tr("Saved to contacts."); }
|
||
if (key == "Could not delete: contact storage is unavailable.") { return @tr("Could not delete: contact storage is unavailable."); }
|
||
if (key == "Could not delete contact: {}") { return @tr("Could not delete contact: {}", argument); }
|
||
if (key == "Contact deleted.") { return @tr("Contact deleted."); }
|
||
if (key == "Could not load contacts: {}") { return @tr("Could not load contacts: {}", argument); }
|
||
if (key == "Local contact storage is still starting…") { return @tr("Local contact storage is still starting…"); }
|
||
if (key == "Loading contacts…") { return @tr("Loading contacts…"); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-calendar(key, argument, second-argument, third-argument) => {
|
||
if (key == "Local calendar") { return @tr("Local calendar"); }
|
||
if (key == "Calendar") { return @tr("Calendar"); }
|
||
if (key == "Could not load calendar: {}") { return @tr("Could not load calendar: {}", argument); }
|
||
if (key == "Calendar shown and syncing.") { return @tr("Calendar shown and syncing."); }
|
||
if (key == "Calendar hidden and sync paused.") { return @tr("Calendar hidden and sync paused."); }
|
||
if (key == "Calendar update failed: {}") { return @tr("Calendar update failed: {}", argument); }
|
||
if (key == "Only events created in Flectar Mail can be edited.") { return @tr("Only events created in Flectar Mail can be edited."); }
|
||
if (key == "Only events created in Flectar Mail can be deleted.") { return @tr("Only events created in Flectar Mail can be deleted."); }
|
||
if (key == "Calendar storage is unavailable.") { return @tr("Calendar storage is unavailable."); }
|
||
if (key == "Could not delete event: {}") { return @tr("Could not delete event: {}", argument); }
|
||
if (key == "Event deleted, but refresh failed: {}") { return @tr("Event deleted, but refresh failed: {}", argument); }
|
||
if (key == "Event deleted.") { return @tr("Event deleted."); }
|
||
if (key == "Use YYYY-MM-DD for the date and a time such as {}.") { return @tr("Use YYYY-MM-DD for the date and a time such as {}.", argument); }
|
||
if (key == "Event duration must be a number of minutes.") { return @tr("Event duration must be a number of minutes."); }
|
||
if (key == "Add a title and choose a duration from 15 to 1440 minutes.") { return @tr("Add a title and choose a duration from 15 to 1440 minutes."); }
|
||
if (key == "That local time does not exist in the current time zone.") { return @tr("That local time does not exist in the current time zone."); }
|
||
if (key == "Could not save event: {}") { return @tr("Could not save event: {}", argument); }
|
||
if (key == "Event saved, but refresh failed: {}") { return @tr("Event saved, but refresh failed: {}", argument); }
|
||
if (key == "Event saved. Provider sync will run when enabled.") { return @tr("Event saved. Provider sync will run when enabled."); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-startup(key, argument, second-argument, third-argument) => {
|
||
if (key == "Email resource render failed: {}") { return @tr("Email resource render failed: {}", argument); }
|
||
if (key == "Message refresh failed: {}") { return @tr("Message refresh failed: {}", argument); }
|
||
if (key == "Message load failed: {}") { return @tr("Message load failed: {}", argument); }
|
||
if (key == "Your local mailbox could not be opened. No account operation was started. Retry, or copy the diagnostics for support.") { return @tr("Your local mailbox could not be opened. No account operation was started. Retry, or copy the diagnostics for support."); }
|
||
if (key == "Local storage startup failed.") { return @tr("Local storage startup failed."); }
|
||
if (key == "Loading local data…") { return @tr("Loading local data…"); }
|
||
if (key == "Local data ready.") { return @tr("Local data ready."); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-sync(key, argument, second-argument, third-argument) => {
|
||
if (key == "Could not identify the dragged account.") { return @tr("Could not identify the dragged account."); }
|
||
if (key == "Account ordering requires local mail data.") { return @tr("Account ordering requires local mail data."); }
|
||
if (key == "Could not find the account to reorder.") { return @tr("Could not find the account to reorder."); }
|
||
if (key == "Saving account order…") { return @tr("Saving account order…"); }
|
||
if (key == "Sent copy settings require local mail data.") { return @tr("Sent copy settings require local mail data."); }
|
||
if (key == "Updating Sent copy settings…") { return @tr("Updating Sent copy settings…"); }
|
||
if (key == "Sent copy settings updated.") { return @tr("Sent copy settings updated."); }
|
||
if (key == "Could not update Sent copy settings: {}") { return @tr("Could not update Sent copy settings: {}", argument); }
|
||
if (key == "Server mail settings require local mail data.") { return @tr("Server mail settings require local mail data."); }
|
||
if (key == "Updating server mail settings…") { return @tr("Updating server mail settings…"); }
|
||
if (key == "Server mail settings updated.") { return @tr("Server mail settings updated."); }
|
||
if (key == "Could not update server mail settings: {}") { return @tr("Could not update server mail settings: {}", argument); }
|
||
if (key == "Mail history requires local mail data.") { return @tr("Mail history requires local mail data."); }
|
||
if (key == "Updating mail history…") { return @tr("Updating mail history…"); }
|
||
if (key == "Remote images are unavailable in this minimal build.") { return @tr("Remote images are unavailable in this minimal build."); }
|
||
if (key == "Could not save remote-image setting: {}") { return @tr("Could not save remote-image setting: {}", argument); }
|
||
if (key == "Remote sender icons unavailable: {}") { return @tr("Remote sender icons unavailable: {}", argument); }
|
||
if (key == "Remote images unavailable: {}") { return @tr("Remote images unavailable: {}", argument); }
|
||
if (key == "Remote body images and sender favicons enabled.") { return @tr("Remote body images and sender favicons enabled."); }
|
||
if (key == "Remote images blocked.") { return @tr("Remote images blocked."); }
|
||
if (key == "Could not refresh message images: {}") { return @tr("Could not refresh message images: {}", argument); }
|
||
if (key == "Remote-image loading is disabled.") { return @tr("Remote-image loading is disabled."); }
|
||
if (key == "Could not load message images: {}") { return @tr("Could not load message images: {}", argument); }
|
||
if (key == "Sync finished, refresh failed: {}") { return @tr("Sync finished, refresh failed: {}", argument); }
|
||
if (key == "Sync complete.") { return @tr("Sync complete."); }
|
||
if (key == "Sync failed: {}") { return @tr("Sync failed: {}", argument); }
|
||
if (key == "Local mail data is unavailable; preview data is read-only.") { return @tr("Local mail data is unavailable; preview data is read-only."); }
|
||
if (key == "Synchronizing accounts…") { return @tr("Synchronizing accounts…"); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-actions(key, argument, second-argument, third-argument) => {
|
||
if (key == "Message action completed.") { return @tr("Message action completed."); }
|
||
if (key == "Permanent deletion queued. Mail will disappear after the server confirms.") { return @tr("Permanent deletion queued. Mail will disappear after the server confirms."); }
|
||
if (key == "Message action failed: {}") { return @tr("Message action failed: {}", argument); }
|
||
if (key == "Message action failed: message is no longer available") { return @tr("Message action failed: message is no longer available"); }
|
||
if (key == "Label added.") { return @tr("Label added."); }
|
||
if (key == "Label removed.") { return @tr("Label removed."); }
|
||
if (key == "Label created and added.") { return @tr("Label created and added."); }
|
||
if (key == "Label created.") { return @tr("Label created."); }
|
||
if (key == "Label updated.") { return @tr("Label updated."); }
|
||
if (key == "Label deleted.") { return @tr("Label deleted."); }
|
||
if (key == "No other folder to move this mail to.") { return @tr("No other folder to move this mail to."); }
|
||
if (key == "Could not move mail: {}") { return @tr("Could not move mail: {}", argument); }
|
||
if (key == "No folder to copy this mail to.") { return @tr("No folder to copy this mail to."); }
|
||
if (key == "Attaching the original's files…") { return @tr("Attaching the original's files…"); }
|
||
if (key == "Could not attach the original's files: {}") { return @tr("Could not attach the original's files: {}", argument); }
|
||
if (key == "Some of the original's files are over the 25 MB limit for attachments.") { return @tr("Some of the original's files are over the 25 MB limit for attachments."); }
|
||
if (key == "Could not copy mail: {}") { return @tr("Could not copy mail: {}", argument); }
|
||
if (key == "Moving mail to the other account…") { return @tr("Moving mail to the other account…"); }
|
||
if (key == "Copying mail to the other account…") { return @tr("Copying mail to the other account…"); }
|
||
if (key == "{} conversations archived.") { return @tr("Conversation archived." | "{0} conversations archived." % round(argument.to-float()), argument); }
|
||
if (key == "{} messages archived.") { return @tr("Message archived." | "{0} messages archived." % round(argument.to-float()), argument); }
|
||
if (key == "{} conversations moved to Trash.") { return @tr("Conversation moved to Trash." | "{0} conversations moved to Trash." % round(argument.to-float()), argument); }
|
||
if (key == "{} messages moved to Trash.") { return @tr("Message moved to Trash." | "{0} messages moved to Trash." % round(argument.to-float()), argument); }
|
||
if (key == "{} conversations marked as spam.") { return @tr("Conversation marked as spam." | "{0} conversations marked as spam." % round(argument.to-float()), argument); }
|
||
if (key == "{} messages marked as spam.") { return @tr("Message marked as spam." | "{0} messages marked as spam." % round(argument.to-float()), argument); }
|
||
if (key == "{} conversations moved.") { return @tr("Conversation moved." | "{0} conversations moved." % round(argument.to-float()), argument); }
|
||
if (key == "{} messages moved.") { return @tr("Message moved." | "{0} messages moved." % round(argument.to-float()), argument); }
|
||
if (key == "{} conversations marked as read.") { return @tr("Conversation marked as read." | "{0} conversations marked as read." % round(argument.to-float()), argument); }
|
||
if (key == "{} messages marked as read.") { return @tr("Message marked as read." | "{0} messages marked as read." % round(argument.to-float()), argument); }
|
||
if (key == "{} conversations marked as unread.") { return @tr("Conversation marked as unread." | "{0} conversations marked as unread." % round(argument.to-float()), argument); }
|
||
if (key == "{} messages marked as unread.") { return @tr("Message marked as unread." | "{0} messages marked as unread." % round(argument.to-float()), argument); }
|
||
if (key == "{} conversations starred.") { return @tr("Conversation starred." | "{0} conversations starred." % round(argument.to-float()), argument); }
|
||
if (key == "{} messages starred.") { return @tr("Message starred." | "{0} messages starred." % round(argument.to-float()), argument); }
|
||
if (key == "{} conversations unstarred.") { return @tr("Conversation unstarred." | "{0} conversations unstarred." % round(argument.to-float()), argument); }
|
||
if (key == "{} messages unstarred.") { return @tr("Message unstarred." | "{0} messages unstarred." % round(argument.to-float()), argument); }
|
||
if (key == "This can no longer be undone.") { return @tr("This can no longer be undone."); }
|
||
if (key == "Could not undo: {}") { return @tr("Could not undo: {}", argument); }
|
||
if (key == "This message names no way to unsubscribe.") { return @tr("This message names no way to unsubscribe."); }
|
||
if (key == "Could not unsubscribe: {}") { return @tr("Could not unsubscribe: {}", argument); }
|
||
if (key == "Unsubscribed from {}.") { return @tr("Unsubscribed from {}.", argument); }
|
||
if (key == "Unsubscribe request sent to {}.") { return @tr("Unsubscribe request sent to {}.", argument); }
|
||
if (key == "Blocked {}.") { return @tr("Blocked {}.", argument); }
|
||
if (key == "Unblocked {}.") { return @tr("Unblocked {}.", argument); }
|
||
if (key == "Could not block: {}") { return @tr("Could not block: {}", argument); }
|
||
if (key == "Could not unblock: {}") { return @tr("Could not unblock: {}", argument); }
|
||
if (key == "Moved {} messages to the other account.") { return @tr("Moved one message to the other account." | "Moved {0} messages to the other account." % round(argument.to-float()), argument); }
|
||
if (key == "Copied {} messages to the other account.") { return @tr("Copied one message to the other account." | "Copied {0} messages to the other account." % round(argument.to-float()), argument); }
|
||
if (key == "Moved or copied {} messages to the other account.") { return @tr("Moved or copied one message to the other account." | "Moved or copied {0} messages to the other account." % round(argument.to-float()), argument); }
|
||
if (key == "The other account had {} messages already.") { return @tr("The other account had that message already." | "The other account had those {0} messages already." % round(argument.to-float()), argument); }
|
||
if (key == "Could not move or copy {} messages: {}") { return @tr("Could not move or copy one message: {1}" | "Could not move or copy {0} messages: {1}" % round(argument.to-float()), argument, second-argument); }
|
||
if (key == "Could not update label: {}") { return @tr("Could not update label: {}", argument); }
|
||
if (key == "Could not save label: {}") { return @tr("Could not save label: {}", argument); }
|
||
if (key == "Could not delete label: {}") { return @tr("Could not delete label: {}", argument); }
|
||
if (key == "Folder created.") { return @tr("Folder created."); }
|
||
if (key == "Folder renamed.") { return @tr("Folder renamed."); }
|
||
if (key == "Folder deleted.") { return @tr("Folder deleted."); }
|
||
if (key == "Could not create folder: {}") { return @tr("Could not create folder: {}", argument); }
|
||
if (key == "Could not rename folder: {}") { return @tr("Could not rename folder: {}", argument); }
|
||
if (key == "Could not delete folder: {}") { return @tr("Could not delete folder: {}", argument); }
|
||
if (key == "Could not close preview: {}") { return @tr("Could not close preview: {}", argument); }
|
||
if (key == "Opened the system print view.") { return @tr("Opened the system print view."); }
|
||
if (key == "Could not print message: {}") { return @tr("Could not print message: {}", argument); }
|
||
if (key == "Opened the message in your browser.") { return @tr("Opened the message in your browser."); }
|
||
if (key == "Could not open message in browser: {}") { return @tr("Could not open message in browser: {}", argument); }
|
||
if (key == "Connect an account before replying or forwarding.") { return @tr("Connect an account before replying or forwarding."); }
|
||
if (key == "Choose a message first.") { return @tr("Choose a message first."); }
|
||
if (key == "Only drafts can be reopened for editing.") { return @tr("Only drafts can be reopened for editing."); }
|
||
if (key == "Could not open draft: {}") { return @tr("Could not open draft: {}", argument); }
|
||
if (key == "Could not open draft: invalid account identifier") { return @tr("Could not open draft: invalid account identifier"); }
|
||
if (key == "Connected account") { return @tr("Connected account"); }
|
||
if (key == "Could not open composer: {}") { return @tr("Could not open composer: {}", argument); }
|
||
if (key == "Add an account to send mail.") { return @tr("Add an account to send mail."); }
|
||
if (key == "On this device") { return @tr("On this device"); }
|
||
if (key == "Could not open composer: invalid account identifier") { return @tr("Could not open composer: invalid account identifier"); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-compose(key, argument, second-argument, third-argument) => {
|
||
// Reply and forward quotation headers, written into the draft.
|
||
if (key == "On {}, {} wrote:") { return @tr("On {}, {} wrote:", argument, second-argument); }
|
||
if (key == "{} wrote:") { return @tr("{} wrote:", argument); }
|
||
if (key == "Forwarded message") { return @tr("Forwarded message"); }
|
||
if (key == "From: {}") { return @tr("forwarded message header" => "From: {}", argument); }
|
||
if (key == "Date: {}") { return @tr("forwarded message header" => "Date: {}", argument); }
|
||
if (key == "Subject: {}") { return @tr("forwarded message header" => "Subject: {}", argument); }
|
||
if (key == "To: {}") { return @tr("forwarded message header" => "To: {}", argument); }
|
||
if (key == "Attach files to this email") { return @tr("Attach files to this email"); }
|
||
if (key == "Could not add attachments: {}") { return @tr("Could not add attachments: {}", argument); }
|
||
if (key == "Could not show the quoted message: {}") { return @tr("Could not show the quoted message: {}", argument); }
|
||
if (key == "Added 1 attachment.") { return @tr("Added 1 attachment."); }
|
||
if (key == "Added {} attachments.") { return @tr("Added {} attachments.", argument); }
|
||
if (key == "Attachments added: {}. Skipped: {} (duplicate, unreadable, or over the 25 MB total limit).") { return @tr("Attachments added: {}. Skipped: {} (duplicate, unreadable, or over the 25 MB total limit).", argument, second-argument); }
|
||
if (key == "Attachment removed.") { return @tr("Attachment removed."); }
|
||
if (key == "Choose the account this message should be sent from.") { return @tr("Choose the account this message should be sent from."); }
|
||
if (key == "Choose a verified sender identity for this message.") { return @tr("Choose a verified sender identity for this message."); }
|
||
if (key == "Connect an account before saving or sending mail.") { return @tr("Connect an account before saving or sending mail."); }
|
||
if (key == "Message queued for delivery (action {}).") { return @tr("Message queued for delivery (action {}).", argument); }
|
||
if (key == "Sending message…") { return @tr("Sending message…"); }
|
||
if (key == "This message has already been sent.") { return @tr("This message has already been sent."); }
|
||
if (key == "Could not take the message back: {}") { return @tr("Could not take the message back: {}", argument); }
|
||
if (key == "Message sent.") { return @tr("Message sent."); }
|
||
if (key == "Message was not sent: {} Your draft is preserved.") { return @tr("Message was not sent: {} Your draft is preserved.", argument); }
|
||
if (key == "Draft saved locally (#{}).") { return @tr("Draft saved locally (#{}).", argument); }
|
||
if (key == "Compose failed: {}") { return @tr("Compose failed: {}", argument); }
|
||
if (key == "Could not open the message in its own window.") { return @tr("Could not open the message in its own window."); }
|
||
if (key == "Could not open the message in its own window, so it was saved to Drafts.") { return @tr("Could not open the message in its own window, so it was saved to Drafts."); }
|
||
if (key == "Connect an account before managing email templates.") { return @tr("Connect an account before managing email templates."); }
|
||
if (key == "Could not load email templates: {}") { return @tr("Could not load email templates: {}", argument); }
|
||
if (key == "Enter a template name.") { return @tr("Enter a template name."); }
|
||
if (key == "Add a subject or message to the template.") { return @tr("Add a subject or message to the template."); }
|
||
if (key == "Email template saved.") { return @tr("Email template saved."); }
|
||
if (key == "Could not save email template: {}") { return @tr("Could not save email template: {}", argument); }
|
||
if (key == "Email template deleted.") { return @tr("Email template deleted."); }
|
||
if (key == "Could not delete email template: {}") { return @tr("Could not delete email template: {}", argument); }
|
||
if (key == "Email template is no longer available.") { return @tr("Email template is no longer available."); }
|
||
if (key == "Email template inserted.") { return @tr("Email template inserted."); }
|
||
if (key == "Email template inserted, but its usage could not be saved: {}") { return @tr("Email template inserted, but its usage could not be saved: {}", argument); }
|
||
if (key == "Choose a supported account type and connection security.") { return @tr("Choose a supported account type and connection security."); }
|
||
if (key == "IMAP port must be between 1 and 65535.") { return @tr("IMAP port must be between 1 and 65535."); }
|
||
if (key == "POP3 port must be between 1 and 65535.") { return @tr("POP3 port must be between 1 and 65535."); }
|
||
if (key == "SMTP port must be between 1 and 65535.") { return @tr("SMTP port must be between 1 and 65535."); }
|
||
if (key == "Local mail data is unavailable. Retry startup.") { return @tr("Local mail data is unavailable. Retry startup."); }
|
||
if (key == "Discovering JMAP and checking capabilities…") { return @tr("Discovering JMAP and checking capabilities…"); }
|
||
if (key == "Certificate imported. Connect to verify the server.") { return @tr("Certificate imported. Connect to verify the server."); }
|
||
if (key == "Could not load account preferences: {}") { return @tr("Could not load account preferences: {}", argument); }
|
||
if (key == "Your edited signature was preserved. Choose No signature to keep it as message text before inserting another.") { return @tr("Your edited signature was preserved. Choose No signature to keep it as message text before inserting another."); }
|
||
if (key == "Certificate import failed: {}") { return @tr("Certificate import failed: {}", argument); }
|
||
if (key == "Testing IMAP and SMTP connections…") { return @tr("Testing IMAP and SMTP connections…"); }
|
||
if (key == "Testing POP3 and SMTP connections…") { return @tr("Testing POP3 and SMTP connections…"); }
|
||
return "";
|
||
}
|
||
|
||
ui-message-oauth(key, argument, second-argument, third-argument) => {
|
||
if (key == "Another browser authorization is already in progress; finish it or choose Cancel.") { return @tr("Another browser authorization is already in progress; finish it or choose Cancel."); }
|
||
if (key == "Add app keys in Sign-in settings to enable this provider.") { return @tr("Add app keys in Sign-in settings to enable this provider."); }
|
||
if (key == "Choose Gmail or Outlook OAuth.") { return @tr("Choose Gmail or Outlook OAuth."); }
|
||
if (key == "Complete sign-in in your browser, or choose Cancel here.") { return @tr("Complete sign-in in your browser, or choose Cancel here."); }
|
||
if (key == "Cancelling browser sign-in…") { return @tr("Cancelling browser sign-in…"); }
|
||
if (key == "Finishing browser sign-in…") { return @tr("Finishing browser sign-in…"); }
|
||
if (key == "Could not use that browser address: {}") { return @tr("Could not use that browser address: {}", argument); }
|
||
if (key == "Calendar core is unavailable.") { return @tr("Calendar core is unavailable."); }
|
||
if (key == "Account no longer exists.") { return @tr("Account no longer exists."); }
|
||
if (key == "Authorize calendar access in your browser.") { return @tr("Authorize calendar access in your browser."); }
|
||
if (key == "OAuth app keys saved.") { return @tr("OAuth app keys saved."); }
|
||
if (key == "{} OAuth settings saved.") { return @tr("{} OAuth settings saved.", argument); }
|
||
if (key == "OAuth settings failed: {}") { return @tr("OAuth settings failed: {}", argument); }
|
||
if (key == "Mail refresh failed: {}") { return @tr("Mail refresh failed: {}", argument); }
|
||
if (key == "Mail filter failed: {}") { return @tr("Mail filter failed: {}", argument); }
|
||
if (key == "Mail pagination failed: {}") { return @tr("Mail pagination failed: {}", argument); }
|
||
if (key == "Could not mark message as read: {}") { return @tr("Could not mark message as read: {}", argument); }
|
||
if (key == "Loading message…") { return @tr("Loading message…"); }
|
||
return "";
|
||
}
|
||
}
|
||
|
||
// Everything a composer window copies from the main window's look.
|
||
struct Appearance {
|
||
mode: string,
|
||
preset: string,
|
||
icon: AppIconVariant,
|
||
light_primary: color,
|
||
light_page: color,
|
||
light_surface: color,
|
||
light_text: color,
|
||
light_border: color,
|
||
dark_primary: color,
|
||
dark_page: color,
|
||
dark_surface: color,
|
||
dark_text: color,
|
||
dark_border: color,
|
||
}
|
||
|
||
// A message moved into its own window on the desktop. Each window has its
|
||
// own ComposerUi, so several messages can be open at once while the main
|
||
// window stays free to read mail or start another.
|
||
export component ComposerWindow inherits Window {
|
||
// "light", "dark" or "system": the main window's theme-mode.
|
||
in property <string> theme: "system";
|
||
in property <bool> attachment-picker-supported: true;
|
||
// The window's close button asks the composer, which protects a
|
||
// message with content behind its discard confirmation.
|
||
callback request-close();
|
||
// Minimized: the composer keeps no pixels until it is shown again.
|
||
in-out property <bool> render-suspended: false;
|
||
|
||
title: ComposerUi.subject != "" ? ComposerUi.subject : ComposerText.mode-title(ComposerUi.mode);
|
||
icon: AppIcon.window-image(AppIcon.variant);
|
||
default-font-family: "Google Sans Flex";
|
||
preferred-width: 760px;
|
||
preferred-height: 720px;
|
||
min-width: 420px;
|
||
min-height: 480px;
|
||
background: AppTheme.surface;
|
||
|
||
init => { root.apply-theme(); }
|
||
changed theme => { root.apply-theme(); }
|
||
request-close => { composer.back-requested(); }
|
||
|
||
function apply-theme() {
|
||
Palette.color-scheme = root.theme == "dark" ? ColorScheme.dark
|
||
: root.theme == "light" ? ColorScheme.light
|
||
: ColorScheme.unknown;
|
||
}
|
||
|
||
composer := BoundComposer {
|
||
width: parent.width;
|
||
height: parent.height;
|
||
windowed: true;
|
||
attachment-picker-supported: root.attachment-picker-supported;
|
||
notice: I18n.ui-message(ComposerUi.message.key, ComposerUi.message.argument, ComposerUi.message.second_argument, ComposerUi.message.third_argument);
|
||
}
|
||
}
|
||
|
||
export component AppWindow inherits Window {
|
||
title: @tr("Flectar Mail");
|
||
icon: AppIcon.window-image(AppIcon.variant);
|
||
// Windows keeps its native frame and macOS its traffic lights in the
|
||
// integrated frame; only Linux removes the window manager's decorations.
|
||
no-frame: WindowChrome.integrated && WindowChrome.platform == "linux";
|
||
resize-border-width: root.client-frame ? 6px : 0px;
|
||
default-font-family: "Google Sans Flex";
|
||
preferred-width: 1320px;
|
||
preferred-height: 800px;
|
||
min-width: 320px;
|
||
min-height: 320px;
|
||
background: root.page-bg;
|
||
|
||
callback select_email(int);
|
||
callback select_thread_message(int);
|
||
callback search_changed(string);
|
||
callback set_search_filter(string);
|
||
callback select_scope(string);
|
||
callback toggle_folder(int, bool);
|
||
callback toggle_sidebar_section(string, bool);
|
||
callback filter_folders(string);
|
||
callback create_folder(int, int, string);
|
||
callback rename_folder(int, string);
|
||
callback delete_folder(int);
|
||
callback load_more();
|
||
callback toggle_settings();
|
||
callback sync_mail();
|
||
callback sync_account(int);
|
||
// F5: the accounts whose mail the view shows.
|
||
callback check_mail_in_view();
|
||
callback delete_account(int);
|
||
callback message_action(string);
|
||
callback message_action_for_email(int, string);
|
||
callback bulk_message_action(string);
|
||
callback toggle_mail_group(string);
|
||
callback empty_trash(int);
|
||
callback set_email_checked(int, bool);
|
||
callback set_all_emails_checked(bool);
|
||
callback toggle_mail_label(int, bool);
|
||
callback save_mail_label(int, int, string, color, bool, int);
|
||
callback delete_mail_label(int);
|
||
callback search_mail_labels(string);
|
||
callback compose_message_action(string);
|
||
callback close_preview();
|
||
callback print_message();
|
||
callback open_message_in_browser();
|
||
callback save_theme(string);
|
||
callback save_theme_preset(string);
|
||
callback save_custom_theme(color, color, color, color, color, color, color, color, color, color) -> bool;
|
||
callback save_avatar_visibility(bool);
|
||
callback save_show_tabs(bool);
|
||
callback save_spelling_enabled(bool);
|
||
callback save_conversation_view(bool);
|
||
callback save_group_mail_by_date(bool);
|
||
callback choose_download_directory();
|
||
callback clear_download_directory();
|
||
// Save a profile's name and color, with the checked `profile_members`
|
||
// as its accounts.
|
||
callback save_mail_profile(string, string, color) -> string;
|
||
callback prepare_profile_members(string, int);
|
||
callback assign_account_profile(int, string);
|
||
callback save_account_color(int, color, bool);
|
||
callback delete_mail_profile(string);
|
||
// Show only this profile's accounts in the mail view; empty shows all.
|
||
callback select_mail_profile(string);
|
||
// Rust: the active profile or its accounts changed.
|
||
callback mail_profile_changed();
|
||
callback save_account_markers_visibility(bool);
|
||
callback save_workspace_layout(string);
|
||
callback save_workspace_list_pane_width(length);
|
||
callback save_language(string);
|
||
callback save_time_format(string);
|
||
callback save_sidebar_icon_style(bool);
|
||
callback save_notification_settings(bool, bool, string);
|
||
callback save_unread_badge(bool);
|
||
callback save_sync_interval(int);
|
||
callback save_undo_send(int);
|
||
callback save_mark_read_on_open(bool);
|
||
callback save_contact_discovery_settings(bool, bool, bool, bool);
|
||
callback clear_contact_suggestions() -> bool;
|
||
callback set_close_to_tray(bool);
|
||
callback set_launch_at_login(bool);
|
||
// A new message, to the recipients given, if any.
|
||
callback open_compose(string);
|
||
callback add_password_account(string, string, string, string, string, string, string, string, string);
|
||
callback suggest_account_settings(string);
|
||
callback start_oauth(string);
|
||
callback reauth_account(int);
|
||
callback cancel_oauth();
|
||
callback save_oauth_app(string, string, string);
|
||
callback save_oauth_apps(string, string, string);
|
||
pure callback make_account_transfer(string) -> data-transfer;
|
||
pure callback read_account_transfer(data-transfer) -> string;
|
||
pure callback settings-search-matches(string, string) -> bool;
|
||
callback reorder_account(string, int, bool);
|
||
callback save_account_mail_history(int, string);
|
||
callback save_account_sent_copy_policy(int, string);
|
||
callback save_account_keep_on_server(int, string);
|
||
callback connect_account_calendar(int);
|
||
// (account, connection or -1 for a new one, url, username, password)
|
||
callback connect_caldav(int, int, string, string, string);
|
||
callback set_calendar_connection_enabled(int, bool);
|
||
callback remove_calendar_connection(int);
|
||
callback connect_carddav(int, string, string, string);
|
||
callback set_account_carddav_enabled(int, bool);
|
||
callback disconnect_carddav(int);
|
||
callback export_account_backup();
|
||
callback import_accounts();
|
||
callback export_database_snapshot();
|
||
callback export_device_mail(int);
|
||
callback delete_all_data();
|
||
callback load_storage_usage();
|
||
callback cancel_storage_usage();
|
||
callback open_email_link(string);
|
||
callback copy_email_status(string);
|
||
callback report_rendering_issue();
|
||
callback email-pointer-event(float, float, string, bool, bool, bool, bool);
|
||
callback email-scroll(float, float);
|
||
callback email-key-event(string, bool, bool, bool, bool, bool, bool);
|
||
callback select-email-text();
|
||
callback set-remote-images(bool);
|
||
callback load-remote-images-for-message();
|
||
callback calendar-navigate(string, int);
|
||
callback calendar-select-date(string);
|
||
callback calendar-set-view(string);
|
||
callback calendar-set-source-enabled(int, bool);
|
||
callback calendar-toggle-agenda-filter(int, bool);
|
||
callback calendar-clear-agenda-filters();
|
||
callback calendar-today();
|
||
callback calendar-open-editor();
|
||
callback calendar-edit-event(int);
|
||
callback calendar-delete-event(int);
|
||
callback calendar-save-event(string, string, string, string, int);
|
||
callback select-contact(int);
|
||
callback search-contacts(string);
|
||
callback select-contact-scope(string);
|
||
callback toggle-contact-section(string, bool);
|
||
callback new-contact();
|
||
callback resolve-contact-conflict(bool);
|
||
pure callback usable-contact-email(string) -> bool;
|
||
usable-contact-email(email) => { false }
|
||
callback add-contact-value(string);
|
||
callback prefer-contact-value(string,int);
|
||
callback remove-contact-value(string,int);
|
||
callback save-contact(int, string, string, string, string, string, string, string, string, bool);
|
||
callback delete-contact(int);
|
||
callback load-contacts();
|
||
callback load-more-contacts();
|
||
callback system-back-requested() -> bool;
|
||
callback retry-startup();
|
||
|
||
// Host-internal wakeups. Background work only schedules these when data is
|
||
// ready; Rust drains the corresponding bounded channel on Slint's thread.
|
||
callback drain-startup-updates();
|
||
callback drain-core-updates();
|
||
callback drain-mail-list-updates();
|
||
callback drain-mail-metadata-updates();
|
||
callback drain-folder-updates();
|
||
callback drain-message-load-updates();
|
||
callback drain-read-updates();
|
||
callback drain-navigation-updates();
|
||
callback drain-action-updates();
|
||
callback drain-favicon-updates();
|
||
callback drain-profile-avatar-updates();
|
||
callback drain-ui-task-updates();
|
||
callback drain-sync-updates();
|
||
callback drain-data-reset-updates();
|
||
callback drain-contact-load-updates();
|
||
callback drain-compose-send-updates();
|
||
// A quoted message in a composer finished loading an image.
|
||
callback refresh-composer-quotes();
|
||
callback refresh-email-resources();
|
||
// Calendar connections changed state while Settings shows them.
|
||
callback reload-calendar-connections();
|
||
// The language or the time format changed how dates are written.
|
||
callback date-formats-changed();
|
||
|
||
in property <[EmailRow]> emails: [];
|
||
in property <[MailListEntry]> mail_list_entries: [];
|
||
in property <[ThreadMessageRow]> thread_messages: [];
|
||
in property <int> selected_thread_index: 0;
|
||
in property <[SidebarRow]> sidebar_rows: [];
|
||
in-out property <string> folder_filter_query: "";
|
||
in property <[MailLabelRow]> mail_labels: [];
|
||
in property <[MailLabelRow]> mail_label_results: [];
|
||
in property <int> selected_mail_label_count: 0;
|
||
in property <bool> selected_account_uses_labels: false;
|
||
in property <[AccountRow]> connected_accounts: [];
|
||
in property <bool> has_device_mail: false;
|
||
in property <bool> mail_export_running: false;
|
||
in property <LocalizedMessage> mail-export-message;
|
||
in property <[MailProfileRow]> mail_profiles: [];
|
||
in property <[ProfileMemberRow]> profile_members: [];
|
||
// The profile the mail view shows; an empty id means every account.
|
||
in property <MailProfileRow> active_mail_profile;
|
||
// Set to open Settings' profile editor for a new profile.
|
||
in-out property <bool> new_profile_requested: false;
|
||
// The saved visible page can paint before the core is safe to use. Keep
|
||
// that presentation milestone separate from startup-ready, which guards
|
||
// every callback that can touch local storage.
|
||
in property <bool> startup_hydrated: false;
|
||
private property <int> compose-back-request: 0;
|
||
in property <bool> render-suspended: false;
|
||
callback suspend-rendering(bool);
|
||
in property <bool> startup_ready: false;
|
||
in property <bool> startup_failed: false;
|
||
in property <LocalizedMessage> startup-message;
|
||
property <string> startup_error: I18n.ui-message(root.startup-message.key, root.startup-message.argument, root.startup-message.second_argument, root.startup-message.third_argument);
|
||
in property <string> startup_diagnostic_id: "";
|
||
in property <string> diagnostics_text: "";
|
||
in property <[CalendarDay]> calendar_month_days: [];
|
||
in property <[CalendarWeekDay]> calendar_week_days: [];
|
||
in property <[CalendarEventRow]> calendar_events: [];
|
||
in property <[CalendarAgendaRow]> calendar_agenda_rows: [];
|
||
in property <[CalendarAgendaFilterRow]> calendar_agenda_filters: [];
|
||
in property <int> calendar_agenda_filter_count: 0;
|
||
in property <int> calendar_agenda_event_count: 0;
|
||
in property <float> calendar_agenda_anchor: 0;
|
||
in property <int> calendar_agenda_scroll_request: 0;
|
||
in property <string> calendar_timezone: "";
|
||
in property <[CalendarSourceRow]> calendar_sources: [];
|
||
in property <[ContactRow]> contacts: [];
|
||
in-out property <[ContactValueRow]> contact-emails;
|
||
in-out property <[ContactValueRow]> contact-phones;
|
||
in property <bool> contact-read-only;
|
||
in property <string> contact-source;
|
||
in property <ContactSyncState> contact-sync;
|
||
in property <string> contact-sync-detail;
|
||
in property <image> contact-photo;
|
||
in property <bool> contact-has-photo;
|
||
in property <[ContactSidebarRow]> contact_sidebar_rows: [];
|
||
in-out property <string> contact_scope: "All contacts";
|
||
in-out property <string> contact_search_query: "";
|
||
in property <bool> contact_can_load_more: false;
|
||
in property <bool> contact_loading_more: false;
|
||
in property <int> contact_list_revision: 0;
|
||
in property <LocalizedMessage> contact-save-message;
|
||
property <string> contact_save_status: I18n.ui-message(root.contact-save-message.key, root.contact-save-message.argument, root.contact-save-message.second_argument, root.contact-save-message.third_argument);
|
||
in property <bool> contact_has_selection: false;
|
||
in-out property <int> contact_id: -1;
|
||
in-out property <string> contact_name: "";
|
||
in-out property <string> contact_company: "";
|
||
in-out property <string> contact_job_title: "";
|
||
in-out property <string> contact_website: "";
|
||
in-out property <string> contact_birthday: "";
|
||
in-out property <string> contact_address: "";
|
||
in-out property <string> contact_notes: "";
|
||
in-out property <string> contact_tags: "";
|
||
in-out property <bool> contact_favorite: false;
|
||
in property <bool> contact_is_suggested: false;
|
||
in property <string> contact_initials: "?";
|
||
in property <string> contact_interactions: "";
|
||
in property <string> contact_last_interacted: "";
|
||
in property <int> contact_total_count: 0;
|
||
in property <int> contact_favorite_count: 0;
|
||
in property <int> contact_suggestion_count: 0;
|
||
in property <string> calendar_month_title: "";
|
||
in property <string> calendar_period_title: "";
|
||
in property <string> calendar_week_label: "";
|
||
in property <string> calendar_selected_date: "";
|
||
in property <string> calendar_selected_date_label: "";
|
||
in property <[string]> calendar_hour_labels: ["08:00", "09:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00"];
|
||
in property <bool> calendar_selected_date_has_events: false;
|
||
in-out property <bool> calendar_sidebar_collapsed: false;
|
||
in-out property <string> calendar_view_mode: "week";
|
||
in-out property <bool> calendar_editor_open: false;
|
||
in-out property <bool> calendar_event_editing: false;
|
||
in-out property <string> calendar_event_title: "";
|
||
in-out property <string> calendar_event_date: "";
|
||
in-out property <string> calendar_event_time: "09:00";
|
||
in-out property <string> calendar_event_duration: "60";
|
||
in-out property <int> calendar_event_color: 0;
|
||
in property <string> selected_scope: "Unified Inbox";
|
||
in property <string> selected_scope_title: "Unified Inbox";
|
||
in property <bool> trash_view: false;
|
||
in-out property <bool> mail_sidebar_collapsed: false;
|
||
in-out property <bool> contacts_sidebar_collapsed: false;
|
||
in property <string> unified_count: "";
|
||
in-out property <string> search_query: "";
|
||
in property <string> search_filter: "All mail";
|
||
in property <string> selected_sender: "";
|
||
in property <string> selected_address: "";
|
||
in property <string> selected_subject: "";
|
||
in property <string> selected_time: "";
|
||
in property <string> selected_to: "";
|
||
in property <string> selected_label: "";
|
||
in property <bool> selected_is_draft: false;
|
||
in property <string> selected_initials: "?";
|
||
in property <image> selected_favicon;
|
||
in property <bool> selected_has_favicon: false;
|
||
in property <LocalizedMessage> render-message;
|
||
property <string> render_status: I18n.ui-message(root.render-message.key, root.render-message.argument, root.render-message.second_argument, root.render-message.third_argument);
|
||
in property <string> selected_plain_text: "";
|
||
in property <string> selected_source: "";
|
||
in property <string> selected_text: "";
|
||
in property <bool> has_selection: false;
|
||
in property <string> clipboard_request: "";
|
||
in property <int> clipboard_request_id: 0;
|
||
in property <LocalizedMessage> sync-message;
|
||
property <string> sync_status: I18n.ui-message(root.sync-message.key, root.sync-message.argument, root.sync-message.second_argument, root.sync-message.third_argument);
|
||
in property <bool> sync_in_progress: false;
|
||
in property <[EmailTile]> email_tiles: [];
|
||
in property <[EmailLink]> email_links: [];
|
||
// The renderer reports the total laid-out content height while retaining
|
||
// only viewport-adjacent raster tiles.
|
||
in-out property <float> email-content-aspect: 900 / 520;
|
||
in-out property <bool> source_mode: false;
|
||
in-out property <bool> rendering_info_open: false;
|
||
in property <bool> can_load_more: false;
|
||
in property <bool> mail_loading_more: false;
|
||
in property <bool> mail_page_loading: false;
|
||
in property <int> mail_list_revision: 0;
|
||
in property <int> mail_selection_count: 0;
|
||
in property <bool> has_selected: true;
|
||
in property <int> previous_email_id: -1;
|
||
in property <int> next_email_id: -1;
|
||
in property <bool> selected_starred: false;
|
||
in property <bool> selected_unread: false;
|
||
in property <string> selected_sender_verification: "";
|
||
in-out property <bool> text_mode: false;
|
||
// The Rust renderer reads these bindings during Slint's WGPU rendering
|
||
// callback and reflows Blitz at the current logical viewport size.
|
||
in-out property <length> email-viewport-width: 0px;
|
||
in-out property <length> email-viewport-height: 0px;
|
||
in-out property <length> email-scroll-document-height: 0px;
|
||
in-out property <length> email-scroll-y: 0px;
|
||
in-out property <bool> settings_open: false;
|
||
changed settings_open => {
|
||
root.product-changed(root.active_view);
|
||
// Hiding Settings destroys the dialog before its own change handlers
|
||
// run, so an unsaved palette and open forms are discarded here. The
|
||
// dialog's private state starts over when it is created again.
|
||
if root.settings_open {
|
||
root.settings-shown();
|
||
} else {
|
||
ThemeDraft.revert();
|
||
root.account_form_open = false;
|
||
root.account_password = "";
|
||
root.caldav_account_id = -1;
|
||
root.caldav_connection_id = -1;
|
||
root.caldav_password = "";
|
||
root.carddav_account_id = -1;
|
||
root.carddav_password = "";
|
||
root.carddav_manage_existing = false;
|
||
}
|
||
TabsUi.navigated();
|
||
}
|
||
// Settings appeared, whichever way it was opened.
|
||
callback settings-shown();
|
||
in-out property <string> active_view: "mail";
|
||
callback product-changed(string);
|
||
private property <string> mail-compact-page: "list";
|
||
private property <bool> mail-folders-open: false;
|
||
private property <bool> contacts-detail-visible: false;
|
||
// A tab shown in a single-pane layout opens on its list or its reader.
|
||
private property <int> tab-shown: TabsUi.shown;
|
||
changed tab-shown => {
|
||
root.mail-compact-page = TabsUi.shown-conversation ? "message" : "list";
|
||
root.mail-folders-open = false;
|
||
root.contacts-detail-visible = false;
|
||
}
|
||
changed active_view => {
|
||
if root.active_view != "mail" { MailAttachments.command("close", ""); }
|
||
root.product-changed(root.active_view);
|
||
TabsUi.navigated();
|
||
}
|
||
in-out property <string> settings_tab: "General";
|
||
changed settings_tab => { TabsUi.navigated(); }
|
||
// The active tab saves where the mail view is once it settles.
|
||
changed selected_scope => { TabsUi.navigated(); }
|
||
changed search_query => { TabsUi.navigated(); }
|
||
changed search_filter => { TabsUi.navigated(); }
|
||
changed has_selected => { TabsUi.navigated(); }
|
||
changed selected_subject => { TabsUi.navigated(); }
|
||
changed calendar_selected_date => { TabsUi.navigated(); }
|
||
changed calendar_view_mode => { TabsUi.navigated(); }
|
||
// Own scan lifetime here: the conditional SettingsDialog is destroyed on
|
||
// close, so its own change handlers cannot reliably cancel a running scan.
|
||
private property <bool> storage-page-open: root.settings_open && root.settings_tab == "Data";
|
||
changed storage-page-open => {
|
||
if root.storage-page-open { root.load_storage_usage(); }
|
||
else { root.cancel_storage_usage(); }
|
||
}
|
||
in property <bool> storage_loading: false;
|
||
in property <bool> storage_loaded: false;
|
||
in property <string> storage_total: "";
|
||
in property <string> storage_error: "";
|
||
in property <[StorageUsageRow]> storage_usage: [];
|
||
in-out property <string> theme_mode: "system";
|
||
in-out property <bool> show_avatars: true;
|
||
// Show tabs: the desktop tab strip, or the compact tab switcher.
|
||
in-out property <bool> show_tabs: true;
|
||
// Spelling: whether this platform checks it, whether the user wants it, and whether any
|
||
// dictionary is installed to check with.
|
||
in property <bool> spelling_available: false;
|
||
in-out property <bool> spelling_enabled: true;
|
||
in property <bool> spelling_installed: true;
|
||
// Whose spell checker this platform uses: "hunspell", "windows" or "macos".
|
||
in property <string> spelling_system: "";
|
||
in-out property <bool> group_mail_by_date: true;
|
||
// Group replies into conversations; off lists each message on its own.
|
||
in-out property <bool> conversation_view: true;
|
||
in-out property <bool> show_account_markers: false;
|
||
in-out property <string> workspace_layout: "default";
|
||
in-out property <length> workspace_list_pane_width: LayoutMetrics.list-pane-width;
|
||
in-out property <string> language_mode: "system";
|
||
// "automatic" follows the regional clock; "12h" and "24h" fix it.
|
||
in-out property <string> time_format: "automatic";
|
||
in property <string> time_format_sample: "13:30";
|
||
in-out property <bool> monochrome_sidebar_icons: false;
|
||
in-out property <bool> notifications_enabled: true;
|
||
in-out property <bool> notification_sound_enabled: true;
|
||
in-out property <bool> unread_badge_enabled: true;
|
||
in-out property <string> notification_scope: "important";
|
||
in-out property <int> sync_interval_minutes: 5;
|
||
in-out property <int> undo_send_seconds: 10;
|
||
in-out property <bool> mark_read_on_open: true;
|
||
in-out property <bool> collect_outgoing_contacts: true;
|
||
in-out property <bool> collect_incoming_contacts: false;
|
||
in-out property <bool> contact_suggest_all_accounts: false;
|
||
in-out property <bool> suggest_learned_contacts: true;
|
||
in-out property <bool> close_to_tray: false;
|
||
in-out property <bool> launch_at_login: false;
|
||
in property <bool> launch_at_login_available: false;
|
||
// False where closing to the background shows no tray icon (the Flatpak).
|
||
in property <bool> tray_supported: true;
|
||
in-out property <bool> account_setup_in_progress: false;
|
||
in-out property <bool> account_form_open: false;
|
||
in-out property <bool> oauth_in_progress: false;
|
||
in property <bool> remote-images-available: true;
|
||
in-out property <bool> remote-images-enabled: false;
|
||
in property <bool> remote-images-blocked: false;
|
||
// The account a new message is written from: one the mail view shows.
|
||
in-out property <int> compose_account_id: -1;
|
||
in-out property <string> compose_from_label: @tr("No connected account");
|
||
in-out property <string> account_email: "";
|
||
in-out property <string> account_username: "";
|
||
in-out property <string> account_password: "";
|
||
in-out property <string> account_protocol: "imap";
|
||
in-out property <string> jmap_url: "";
|
||
in-out property <bool> connect_calendar_on_add: true;
|
||
in-out property <int> caldav_account_id: -1;
|
||
in-out property <int> caldav_connection_id: -1;
|
||
in-out property <string> caldav_url: "";
|
||
in-out property <string> caldav_username: "";
|
||
in-out property <string> caldav_password: "";
|
||
in property <bool> caldav_connecting: false;
|
||
in-out property <int> carddav_account_id: -1;
|
||
in-out property <string> carddav_url: "";
|
||
in-out property <string> carddav_username: "";
|
||
in-out property <string> carddav_password: "";
|
||
in-out property <bool> carddav_manage_existing: false;
|
||
in-out property <string> incoming_security: "tls";
|
||
in-out property <string> smtp_security: "tls";
|
||
in-out property <string> trusted_certificate_pem;
|
||
in property <string> oauth_authorization_url;
|
||
in property <bool> oauth_browser_error;
|
||
callback retry_oauth_browser();
|
||
callback copy_oauth_link();
|
||
callback submit_oauth_redirect(string);
|
||
callback copy_oauth_authorization_url();
|
||
copy_oauth_authorization_url => {
|
||
if root.oauth_in_progress && root.oauth_authorization_url != "" {
|
||
oauth-clipboard.text = root.oauth_authorization_url;
|
||
oauth-clipboard.select-all();
|
||
oauth-clipboard.copy();
|
||
}
|
||
}
|
||
oauth-clipboard := TextInput {
|
||
x: -10000px; y: -10000px; width: 1px; height: 1px;
|
||
visible: false; enabled: false; read-only: true;
|
||
accessible-role: none;
|
||
}
|
||
|
||
callback import_mail_certificate();
|
||
in-out property <string> incoming_host: "";
|
||
in-out property <string> incoming_port: "993";
|
||
in-out property <string> smtp_host: "";
|
||
in-out property <string> smtp_port: "465";
|
||
in-out property <string> google_client_id: "";
|
||
in-out property <string> google_client_secret: "";
|
||
in-out property <string> ms_client_id: "";
|
||
// The download folder as shown: its host path inside Flatpak. Empty is the default.
|
||
in-out property <string> download_directory: "";
|
||
// Only desktop hosts pick a filesystem directory; mobile hosts export
|
||
// through their own document provider and hide the setting.
|
||
in-out property <bool> download_directory_available: false;
|
||
in-out property <bool> custom_oauth_open: false;
|
||
in property <bool> custom_oauth_configured: false;
|
||
in property <bool> google_oauth_available: false;
|
||
in property <bool> microsoft_oauth_available: false;
|
||
in-out property <bool> oauth_setup_open: false;
|
||
in property <bool> oauth_settings_saving: false;
|
||
in-out property <string> oauth_settings_error: "";
|
||
in property <bool> google_oauth_bundled: false;
|
||
in property <bool> microsoft_oauth_bundled: false;
|
||
// Android/iOS must use their native print frameworks; until those hosts
|
||
// provide one, do not expose the desktop file:// printing fallback.
|
||
in property <bool> print_supported: true;
|
||
in property <bool> document_apis_supported: true;
|
||
in property <string> app-version: "";
|
||
// The host switches this to the UI language's translation of the policy.
|
||
in property <string> privacy-policy-url: "https://flectar.com/mail/privacy/";
|
||
|
||
// Neutral, low-chrome surfaces keep the message content visually primary.
|
||
// Interactive controls come from Slint's desktop widget set.
|
||
private property <bool> dark-mode: root.theme_mode == "dark" ? true
|
||
: root.theme_mode == "light" ? false
|
||
: Palette.color-scheme == ColorScheme.dark;
|
||
private property <color> page-bg: AppTheme.page-bg;
|
||
private property <color> surface: AppTheme.surface;
|
||
private property <color> surface-raised: AppTheme.surface-raised;
|
||
private property <color> sidebar-bg: AppTheme.sidebar-bg;
|
||
private property <color> control-bg: AppTheme.control-bg;
|
||
private property <color> muted-control-bg: AppTheme.muted-control-bg;
|
||
private property <color> accent: AppTheme.accent;
|
||
private property <color> accent-soft: AppTheme.accent-soft;
|
||
private property <color> accent-pale: AppTheme.accent-pale;
|
||
private property <color> selected-row: AppTheme.selected-row;
|
||
private property <color> avatar-bg: AppTheme.avatar-bg;
|
||
private property <color> avatar-selected-bg: AppTheme.avatar-selected-bg;
|
||
private property <color> border: AppTheme.border;
|
||
private property <color> border-subtle: AppTheme.border-subtle;
|
||
private property <color> title-color: AppTheme.title;
|
||
private property <color> heading: AppTheme.heading;
|
||
private property <color> body-text: AppTheme.body;
|
||
private property <color> secondary-text: AppTheme.secondary;
|
||
private property <color> muted-text: AppTheme.muted;
|
||
private property <color> faint-text: AppTheme.faint;
|
||
// Mail to show: an account's, or mail imported to this device alone.
|
||
private property <bool> has-mail: root.connected_accounts.length > 0 || LocalMailUi.account-id >= 0;
|
||
// This content-driven breakpoint is the smallest width that can hold the
|
||
// rail, folders, message list, and a useful reading pane simultaneously.
|
||
private property <bool> compact-layout: root.width - root.safe-area-insets.left - root.safe-area-insets.right < 980px;
|
||
// In the integrated frame the window controls sit over the top corners
|
||
// and toolbars reserve room for them, so content keeps the full window.
|
||
// Desktop windows with accounts show a top bar above the product rail,
|
||
// holding the profile pill and the tabs; in the integrated frame it also
|
||
// holds the window controls. Compact layouts navigate from the bottom bar.
|
||
// With tabs turned off, only the integrated frame keeps the bar, for its
|
||
// window controls; the system frame drops it and the mail sidebar takes
|
||
// the profile switcher.
|
||
private property <bool> tabs-on: root.show_tabs && root.has-mail;
|
||
private property <bool> top-bar: !root.compact-layout && root.has-mail
|
||
&& (root.tabs-on || WindowChrome.controls-visible);
|
||
changed tabs-on => { root.sync-window-chrome(); }
|
||
// A tone apart from the workspace, so the active tab can open into it.
|
||
private property <color> tab-strip-bg: AppTheme.sidebar-tint.mix(AppTheme.title, 0.94);
|
||
changed top-bar => { root.sync-window-chrome(); }
|
||
private property <length> content-x: root.safe-area-insets.left;
|
||
private property <length> content-y: root.safe-area-insets.top + (root.top-bar ? WindowChrome.band-height : 0px);
|
||
private property <length> content-width: root.width - root.safe-area-insets.left - root.safe-area-insets.right;
|
||
private property <length> content-height: root.height - root.content-y - root.safe-area-insets.bottom;
|
||
// Linux draws the whole frame, so it also provides the resize border and
|
||
// window outline that the window manager would otherwise draw.
|
||
private property <bool> client-frame: root.no-frame && !root.maximized && !root.full-screen;
|
||
private property <bool> compact-primary-nav-visible: root.compact-layout
|
||
&& !ComposerUi.open && !root.calendar_editor_open
|
||
&& !(root.active_view == "mail" && root.mail-compact-page == "message")
|
||
&& !(root.active_view == "mail" && root.mail-folders-open)
|
||
&& !(root.active_view == "contacts" && root.contacts-detail-visible)
|
||
&& !(root.active_view == "files" && FilesUi.preview-open);
|
||
private property <length> compact-primary-nav-height: LayoutMetrics.compact-navigation-height;
|
||
private property <bool> folder-dialog-open: false;
|
||
private property <bool> trash-delete-open: false;
|
||
private property <string> trash-delete-kind: "";
|
||
private property <int> trash-delete-id: -1;
|
||
|
||
function confirm-trash-deletion(kind: string, id: int) {
|
||
root.trash-delete-kind = kind;
|
||
root.trash-delete-id = id;
|
||
root.trash-delete-open = true;
|
||
}
|
||
private property <string> folder-dialog-item-kind: "folder";
|
||
private property <string> folder-dialog-mode: "create";
|
||
private property <int> folder-dialog-account-id: -1;
|
||
private property <int> folder-dialog-folder-id: -1;
|
||
private property <int> folder-dialog-parent-id: -1;
|
||
private property <string> folder-dialog-parent-name: "";
|
||
private property <int> folder-dialog-parent-label-id: -1;
|
||
private property <string> folder-dialog-parent-label-path: "";
|
||
private property <bool> folder-dialog-has-descendants: false;
|
||
private property <string> folder-dialog-name: "";
|
||
private property <color> folder-dialog-label-color: transparent;
|
||
|
||
function open-folder-create(account-id: int, parent-id: int, parent-name: string) {
|
||
root.folder-dialog-item-kind = "folder";
|
||
root.folder-dialog-mode = "create";
|
||
root.folder-dialog-account-id = account-id;
|
||
root.folder-dialog-parent-id = parent-id;
|
||
root.folder-dialog-parent-label-id = -1;
|
||
root.folder-dialog-parent-label-path = "";
|
||
root.folder-dialog-has-descendants = false;
|
||
root.folder-dialog-parent-name = parent-name;
|
||
root.folder-dialog-name = "";
|
||
root.folder-dialog-open = true;
|
||
}
|
||
|
||
function open-label-create(account-id: int, account-name: string, parent-label-id: int, parent-path: string) {
|
||
root.folder-dialog-item-kind = "label";
|
||
root.folder-dialog-mode = "create";
|
||
root.folder-dialog-account-id = account-id;
|
||
root.folder-dialog-folder-id = -1;
|
||
root.folder-dialog-parent-label-id = parent-label-id;
|
||
root.folder-dialog-parent-label-path = parent-path;
|
||
root.folder-dialog-has-descendants = false;
|
||
root.folder-dialog-parent-name = parent-path == "" ? account-name : parent-path;
|
||
root.folder-dialog-name = "";
|
||
// Gmail accepts a fixed provider palette; this blue is supported
|
||
// remotely and remains a sensible local default for other accounts.
|
||
root.folder-dialog-label-color = #4a86e8;
|
||
root.folder-dialog-open = true;
|
||
}
|
||
|
||
function open-folder-rename(folder-id: int, name: string) {
|
||
root.folder-dialog-item-kind = "folder";
|
||
root.folder-dialog-mode = "rename";
|
||
root.folder-dialog-folder-id = folder-id;
|
||
root.folder-dialog-parent-label-id = -1;
|
||
root.folder-dialog-parent-label-path = "";
|
||
root.folder-dialog-has-descendants = false;
|
||
root.folder-dialog-parent-name = "";
|
||
root.folder-dialog-name = name;
|
||
root.folder-dialog-open = true;
|
||
}
|
||
|
||
function open-folder-delete(folder-id: int, name: string) {
|
||
root.folder-dialog-item-kind = "folder";
|
||
root.folder-dialog-mode = "delete";
|
||
root.folder-dialog-folder-id = folder-id;
|
||
root.folder-dialog-parent-label-id = -1;
|
||
root.folder-dialog-parent-label-path = "";
|
||
root.folder-dialog-has-descendants = false;
|
||
root.folder-dialog-parent-name = "";
|
||
root.folder-dialog-name = name;
|
||
root.folder-dialog-open = true;
|
||
}
|
||
|
||
function open-label-rename(label-id: int, name: string, color: color, account: string, global: bool) {
|
||
root.folder-dialog-item-kind = "label";
|
||
root.folder-dialog-mode = "rename";
|
||
root.folder-dialog-folder-id = label-id;
|
||
root.folder-dialog-parent-label-id = -1;
|
||
root.folder-dialog-parent-label-path = "";
|
||
root.folder-dialog-has-descendants = false;
|
||
root.folder-dialog-parent-name = global ? @tr("Global Labels (local only)") : account;
|
||
root.folder-dialog-name = name;
|
||
root.folder-dialog-label-color = color;
|
||
root.folder-dialog-open = true;
|
||
}
|
||
|
||
function open-label-delete(label-id: int, name: string, account: string, global: bool, has-descendants: bool) {
|
||
root.folder-dialog-item-kind = "label";
|
||
root.folder-dialog-mode = "delete";
|
||
root.folder-dialog-folder-id = label-id;
|
||
root.folder-dialog-parent-label-id = -1;
|
||
root.folder-dialog-parent-label-path = "";
|
||
root.folder-dialog-has-descendants = has-descendants;
|
||
root.folder-dialog-parent-name = global ? @tr("Global Labels (local only)") : account;
|
||
root.folder-dialog-name = name;
|
||
root.folder-dialog-open = true;
|
||
}
|
||
|
||
system-back-requested => {
|
||
// The import dialog covers everything; accounts being written cannot
|
||
// be abandoned, so back waits for that step to finish.
|
||
if AccountImport.open {
|
||
if AccountImport.stage != "importing" { AccountImport.close(); }
|
||
return true;
|
||
}
|
||
if MailAttachments.open { MailAttachments.command("close", ""); return true; }
|
||
if root.active_view == "files" && FilesUi.transfers-open {FilesUi.transfers-open=false;return true;}
|
||
if root.active_view == "files" && FilesUi.dialog != "" { FilesUi.dialog = ""; return true; }
|
||
if root.active_view == "files" && FilesUi.setup-open { FilesUi.setup-open = false; return true; }
|
||
if root.active_view == "files" && FilesUi.navigation-open { FilesUi.navigation-open = false; return true; }
|
||
if root.active_view == "files" && FilesUi.preview-open { FilesUi.preview-open = false; if FilesUi.busy { FilesUi.command("cancel", "", ""); } FilesUi.command("release-preview", "", ""); return true; }
|
||
if root.active_view == "files" && FilesUi.can-up && !FilesUi.busy { FilesUi.command("up", "", ""); return true; }
|
||
if (root.folder-dialog-open) {
|
||
root.folder-dialog-open = false;
|
||
return true;
|
||
}
|
||
if (root.trash-delete-open) {
|
||
root.trash-delete-open = false;
|
||
return true;
|
||
}
|
||
if (!root.compact-layout) {
|
||
return false;
|
||
}
|
||
if TabsUi.overview-open {
|
||
TabsUi.overview-open = false;
|
||
return true;
|
||
}
|
||
if (ComposerUi.open) {
|
||
root.compose-back-request += 1;
|
||
return true;
|
||
}
|
||
if (root.calendar_editor_open) {
|
||
root.calendar_editor_open = false;
|
||
return true;
|
||
}
|
||
if (root.settings_open) {
|
||
root.settings_open = false;
|
||
return true;
|
||
}
|
||
if (root.active_view == "mail" && root.mail-folders-open) {
|
||
root.mail-folders-open = false;
|
||
return true;
|
||
}
|
||
if (root.active_view == "mail" && root.mail-compact-page == "message") {
|
||
root.mail-compact-page = "list";
|
||
root.close_preview();
|
||
return true;
|
||
}
|
||
if (root.active_view == "contacts" && root.contacts-detail-visible) {
|
||
root.contacts-detail-visible = false;
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
private property <bool> composer-open: ComposerUi.open;
|
||
changed composer-open => {
|
||
if (!root.composer-open) {
|
||
root.compose-back-request = 0;
|
||
ComposerUi.editor-scroll-y = 0px;
|
||
ComposerUi.editor-preedit-text = "";
|
||
}
|
||
}
|
||
|
||
changed theme-mode => {
|
||
Palette.color-scheme = root.theme-mode == "dark" ? ColorScheme.dark
|
||
: root.theme-mode == "light" ? ColorScheme.light
|
||
: ColorScheme.unknown;
|
||
}
|
||
|
||
// Composer windows have their own globals and follow this window's
|
||
// appearance through Rust.
|
||
callback appearance-changed();
|
||
private property <Appearance> appearance: {
|
||
mode: root.theme-mode, preset: AppTheme.preset, icon: AppIcon.variant,
|
||
light_primary: AppTheme.custom-light-primary, light_page: AppTheme.custom-light-page-bg,
|
||
light_surface: AppTheme.custom-light-surface, light_text: AppTheme.custom-light-text,
|
||
light_border: AppTheme.custom-light-border, dark_primary: AppTheme.custom-dark-primary,
|
||
dark_page: AppTheme.custom-dark-page-bg, dark_surface: AppTheme.custom-dark-surface,
|
||
dark_text: AppTheme.custom-dark-text, dark_border: AppTheme.custom-dark-border,
|
||
};
|
||
changed appearance => { root.appearance-changed(); }
|
||
|
||
changed width => { root.sync-window-chrome(); }
|
||
changed full-screen => { root.sync-window-chrome(); }
|
||
changed compact-layout => { root.sync-window-chrome(); }
|
||
private property <length> chrome-band: WindowChrome.band-height;
|
||
private property <length> chrome-trailing: WindowChrome.trailing-width;
|
||
changed chrome-band => { WindowChrome.geometry-changed(); }
|
||
changed chrome-trailing => { WindowChrome.geometry-changed(); }
|
||
|
||
function sync-window-chrome() {
|
||
WindowChrome.window-width = root.width;
|
||
WindowChrome.full-screen = root.full-screen;
|
||
WindowChrome.compact = root.compact-layout;
|
||
WindowChrome.top-bar = root.top-bar;
|
||
AppTheme.top-bar = root.top-bar;
|
||
TabsUi.enabled = root.tabs-on;
|
||
TabsUi.compact = root.compact-layout;
|
||
if !root.compact-layout || !root.tabs-on {
|
||
TabsUi.overview-open = false;
|
||
}
|
||
}
|
||
|
||
// Seeds WindowChrome once; the handlers above keep it current. A child
|
||
// element runs this so AppWindow's own init stays free for tooling.
|
||
Rectangle {
|
||
width: 0px;
|
||
height: 0px;
|
||
init => { root.sync-window-chrome(); }
|
||
}
|
||
|
||
// Toolbar rows sit above this band; wherever they have no interactive
|
||
// content, input falls through to it and moves the window.
|
||
if WindowChrome.controls-visible : WindowDragArea {
|
||
x: root.content-x;
|
||
y: root.safe-area-insets.top;
|
||
width: root.content-width;
|
||
height: WindowChrome.band-height;
|
||
}
|
||
|
||
// Account discovery is asynchronous. Paint a small initial view while
|
||
// neither the cached mailbox nor the onboarding decision is available.
|
||
if !root.startup_ready && !root.startup_failed && !root.has-mail : Rectangle {
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
background: root.page-bg;
|
||
accessible-role: groupbox;
|
||
accessible-label: I18n.loading-local-data();
|
||
|
||
VerticalLayout {
|
||
width: max(240px, self.preferred-width).min(parent.width - 32px);
|
||
height: 92px;
|
||
x: (parent.width - self.width) / 2;
|
||
y: (parent.height - self.height) / 2;
|
||
spacing: 12px;
|
||
Text {
|
||
text: "Flectar Mail";
|
||
color: root.title-color;
|
||
font-size: TypeScale.heading;
|
||
font-weight: 600;
|
||
horizontal-alignment: center;
|
||
}
|
||
Text {
|
||
text: I18n.loading-local-data();
|
||
color: root.muted-text;
|
||
font-size: TypeScale.body;
|
||
horizontal-alignment: center;
|
||
}
|
||
LoadingSkeletonBlock {
|
||
height: 4px;
|
||
radius: 2px;
|
||
base-color: root.border;
|
||
highlight-color: root.accent;
|
||
}
|
||
}
|
||
}
|
||
|
||
if root.has-mail : Rectangle {
|
||
// Do not construct the mailbox on a fresh profile. `visible: false`
|
||
// retains the entire tree, and constructing it before the account
|
||
// query touches code and assets that onboarding never needs.
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
background: root.page-bg;
|
||
|
||
product-rail := ProductRail {
|
||
visible: !root.compact-layout;
|
||
x: 0px;
|
||
y: 0px;
|
||
width: LayoutMetrics.product-rail-width;
|
||
height: parent.height;
|
||
active-view <=> root.active_view;
|
||
settings-active: root.settings_open;
|
||
background-color: root.sidebar-bg;
|
||
divider-color: root.border;
|
||
accent-color: root.accent;
|
||
accent-background: root.accent-soft;
|
||
title-color: root.title-color;
|
||
muted-color: root.muted-text;
|
||
open-settings => { root.toggle_settings(); }
|
||
select-view(view) => {
|
||
root.active_view = view;
|
||
root.settings_open = false;
|
||
|
||
}
|
||
}
|
||
|
||
if root.active_view == "mail" : WorkspaceFrame {
|
||
compact: root.compact-layout;
|
||
reserve-compact-navigation: root.compact-primary-nav-visible;
|
||
available-width: parent.width;
|
||
available-height: parent.height;
|
||
|
||
MailView {
|
||
changed email-viewport-width => { root.email-viewport-width = self.email-viewport-width; }
|
||
changed email-viewport-height => { root.email-viewport-height = self.email-viewport-height; }
|
||
changed email-scroll-document-height => { root.email-scroll-document-height = self.email-scroll-document-height; }
|
||
compact-page <=> root.mail-compact-page;
|
||
folders-open <=> root.mail-folders-open;
|
||
loading: !root.startup_hydrated || root.mail_page_loading;
|
||
x: 0px;
|
||
y: 0px;
|
||
width: parent.width;
|
||
height: parent.height;
|
||
available-width: parent.width;
|
||
compact: root.compact-layout;
|
||
layout-mode: root.workspace_layout;
|
||
list-pane-width <=> root.workspace_list_pane_width;
|
||
list-pane-width-committed(width) => { root.save_workspace_list_pane_width(width); }
|
||
show-avatars: root.show_avatars;
|
||
emails: root.emails;
|
||
list_entries: root.mail_list_entries;
|
||
group_mail_by_date: root.group_mail_by_date;
|
||
thread_messages: root.thread_messages;
|
||
selected_thread_index: root.selected_thread_index;
|
||
sidebar_rows: root.sidebar_rows;
|
||
mail_profiles: root.mail_profiles;
|
||
profiles-in-sidebar: !root.top-bar && !root.compact-layout;
|
||
active_mail_profile: root.active_mail_profile;
|
||
account_count: root.connected_accounts.length;
|
||
select_mail_profile(id) => { root.select_mail_profile(id); }
|
||
create_mail_profile => {
|
||
root.settings_tab = "Accounts";
|
||
root.settings_open = true;
|
||
root.new_profile_requested = true;
|
||
}
|
||
folder_filter_query <=> root.folder_filter_query;
|
||
mail_labels: root.mail_labels;
|
||
mail_label_results: root.mail_label_results;
|
||
selected_mail_label_count: root.selected_mail_label_count;
|
||
selected_account_uses_labels: root.selected_account_uses_labels;
|
||
email_tiles: root.email_tiles;
|
||
email_links: root.email_links;
|
||
active_view: root.active_view;
|
||
selected_scope: root.selected_scope;
|
||
selected_scope_title: root.selected_scope_title;
|
||
trash_view: root.trash_view;
|
||
unified_count: root.unified_count;
|
||
search_query <=> root.search_query;
|
||
search_filter: root.search_filter;
|
||
selected_sender: root.selected_sender;
|
||
selected_address: root.selected_address;
|
||
selected_subject: root.selected_subject;
|
||
selected_time: root.selected_time;
|
||
selected_to: root.selected_to;
|
||
selected_label: root.selected_label;
|
||
selected_is_draft: root.selected_is_draft;
|
||
selected_initials: root.selected_initials;
|
||
selected_favicon: root.selected_favicon;
|
||
selected_has_favicon: root.selected_has_favicon;
|
||
selected_plain_text: root.selected_plain_text;
|
||
selected_source: root.selected_source;
|
||
selected_text: root.selected_text;
|
||
has_selection: root.has_selection;
|
||
clipboard_request: root.clipboard_request;
|
||
clipboard_request_id: root.clipboard_request_id;
|
||
sync_in_progress: root.sync_in_progress;
|
||
can_load_more: root.can_load_more;
|
||
loading_more: root.mail_loading_more;
|
||
list_content_revision: root.mail_list_revision;
|
||
selection-count: root.mail_selection_count;
|
||
has_selected: root.startup_ready && root.has_selected;
|
||
previous-email-id: root.previous_email_id;
|
||
next-email-id: root.next_email_id;
|
||
selected_starred: root.selected_starred;
|
||
selected_unread: root.selected_unread;
|
||
selected_sender_verification: root.selected_sender_verification;
|
||
remote-images-blocked: root.remote-images-blocked;
|
||
monochrome_sidebar_icons: root.monochrome_sidebar_icons;
|
||
print_supported: root.print_supported;
|
||
mail_sidebar_collapsed <=> root.mail_sidebar_collapsed;
|
||
text_mode <=> root.text_mode;
|
||
source_mode <=> root.source_mode;
|
||
rendering_info_open <=> root.rendering_info_open;
|
||
email-content-aspect <=> root.email-content-aspect;
|
||
email-scroll-y <=> root.email-scroll-y;
|
||
settings_open <=> root.settings_open;
|
||
settings_tab <=> root.settings_tab;
|
||
accent: root.accent;
|
||
accent-soft: root.accent-soft;
|
||
avatar-bg: root.avatar-bg;
|
||
avatar-selected-bg: root.avatar-selected-bg;
|
||
body-text: root.body-text;
|
||
border: root.border;
|
||
border-subtle: root.border-subtle;
|
||
control-bg: root.control-bg;
|
||
faint-text: root.faint-text;
|
||
heading: root.heading;
|
||
muted-control-bg: root.muted-control-bg;
|
||
muted-text: root.muted-text;
|
||
secondary-text: root.secondary-text;
|
||
selected-row: root.selected-row;
|
||
sidebar-bg: root.sidebar-bg;
|
||
surface: root.surface;
|
||
surface-raised: root.surface-raised;
|
||
title-color: root.title-color;
|
||
select_email(id) => { root.select_email(id); }
|
||
select_thread_message(index) => { root.select_thread_message(index); }
|
||
search_changed(query) => { root.search_changed(query); }
|
||
set_search_filter(filter) => { root.set_search_filter(filter); }
|
||
select_scope(scope) => { root.select_scope(scope); }
|
||
toggle_sidebar_section(key, open) => { root.toggle_sidebar_section(key, open); }
|
||
toggle_folder(id, expanded) => { root.toggle_folder(id, expanded); }
|
||
filter_folders(query) => { root.filter_folders(query); }
|
||
request_folder_create(account-id, parent-id, parent-name) => { root.open-folder-create(account-id, parent-id, parent-name); }
|
||
request_label_create(account-id, account-name, parent-id, parent-path) => {
|
||
root.open-label-create(account-id, account-name, parent-id, parent-path);
|
||
}
|
||
request_folder_rename(id, name) => { root.open-folder-rename(id, name); }
|
||
request_folder_delete(id, name) => { root.open-folder-delete(id, name); }
|
||
request_label_rename(id, name, color, account, global) => { root.open-label-rename(id, name, color, account, global); }
|
||
request_label_delete(id, name, account, global, has-descendants) => {
|
||
root.open-label-delete(id, name, account, global, has-descendants);
|
||
}
|
||
load_more => { root.load_more(); }
|
||
sync_mail => { root.sync_mail(); }
|
||
sync_account(account-id) => { root.sync_account(account-id); }
|
||
check_mail_in_view => { root.check_mail_in_view(); }
|
||
message_action(action) => {
|
||
if action == "delete_permanently" { root.confirm-trash-deletion("selected", -1); }
|
||
else { root.message_action(action); }
|
||
}
|
||
message_action_for_email(id, action) => {
|
||
if action == "delete_permanently" { root.confirm-trash-deletion("row", id); }
|
||
else { root.message_action_for_email(id, action); }
|
||
}
|
||
bulk_message_action(action) => {
|
||
if action == "delete_permanently" { root.confirm-trash-deletion("bulk", -1); }
|
||
else { root.bulk_message_action(action); }
|
||
}
|
||
toggle_mail_group(key) => { root.toggle_mail_group(key); }
|
||
request_empty_trash(account-id) => { root.confirm-trash-deletion("empty", account-id); }
|
||
set_email_checked(id, checked) => { root.set_email_checked(id, checked); }
|
||
set_all_emails_checked(checked) => { root.set_all_emails_checked(checked); }
|
||
toggle_mail_label(id, applied) => { root.toggle_mail_label(id, applied); }
|
||
save_mail_label(id, account-id, name, color, global, parent-id) => {
|
||
root.save_mail_label(id, account-id, name, color, global, parent-id);
|
||
}
|
||
search_mail_labels(query) => { root.search_mail_labels(query); }
|
||
compose_message_action(action) => { root.compose_message_action(action); }
|
||
close_preview => { root.close_preview(); }
|
||
print_message => { root.print_message(); }
|
||
open_message_in_browser => { root.open_message_in_browser(); }
|
||
open_compose => { root.open_compose(""); }
|
||
open_email_link(url) => { root.open_email_link(url); }
|
||
copy_email_status(status) => { root.copy_email_status(status); }
|
||
report_rendering_issue => { root.report_rendering_issue(); }
|
||
email-pointer-event(x, y, kind, control, shift, alt, meta) => {
|
||
root.email-pointer-event(x, y, kind, control, shift, alt, meta);
|
||
}
|
||
email-scroll(offset, viewport-height) => { root.email-scroll(offset, viewport-height); }
|
||
email-key-event(text, pressed, repeat, control, shift, alt, meta) => {
|
||
root.email-key-event(text, pressed, repeat, control, shift, alt, meta);
|
||
}
|
||
select-email-text => { root.select-email-text(); }
|
||
load-remote-images-for-message => { root.load-remote-images-for-message(); }
|
||
}
|
||
}
|
||
|
||
if root.active_view == "calendar" : WorkspaceFrame {
|
||
compact: root.compact-layout;
|
||
reserve-compact-navigation: root.compact-primary-nav-visible;
|
||
available-width: parent.width;
|
||
available-height: parent.height;
|
||
|
||
FunctionalCalendarView {
|
||
active: root.active_view == "calendar";
|
||
x: 0px;
|
||
y: 0px;
|
||
width: parent.width;
|
||
height: parent.height;
|
||
compact: root.compact-layout;
|
||
sidebar-collapsed <=> root.calendar_sidebar_collapsed;
|
||
dark-mode: root.dark-mode;
|
||
month-days: root.calendar_month_days;
|
||
week-days: root.calendar_week_days;
|
||
events: root.calendar_events;
|
||
agenda-rows: root.calendar_agenda_rows;
|
||
agenda-filters: root.calendar_agenda_filters;
|
||
agenda-filter-count: root.calendar_agenda_filter_count;
|
||
agenda-event-count: root.calendar_agenda_event_count;
|
||
agenda-anchor: root.calendar_agenda_anchor;
|
||
agenda-scroll-request: root.calendar_agenda_scroll_request;
|
||
timezone: root.calendar_timezone;
|
||
sources: root.calendar_sources;
|
||
month-title: root.calendar_month_title;
|
||
period-title: root.calendar_period_title;
|
||
week-label: root.calendar_week_label;
|
||
selected-date: root.calendar_selected_date;
|
||
selected-date-label: root.calendar_selected_date_label;
|
||
hour-labels: root.calendar_hour_labels;
|
||
selected-date-has-events: root.calendar_selected_date_has_events;
|
||
view-mode: root.calendar_view_mode;
|
||
background-color: root.page-bg;
|
||
sidebar-color: root.sidebar-bg;
|
||
surface-color: root.surface;
|
||
ui-border-color: root.border;
|
||
subtle-border-color: root.border-subtle;
|
||
title-color: root.title-color;
|
||
body-color: root.body-text;
|
||
secondary-color: root.secondary-text;
|
||
muted-color: root.muted-text;
|
||
control-color: root.control-bg;
|
||
control-hover-color: root.muted-control-bg;
|
||
accent-color: root.accent;
|
||
accent-background: root.accent-soft;
|
||
navigate(scope, direction) => { root.calendar-navigate(scope, direction); }
|
||
select-date(date) => { root.calendar-select-date(date); }
|
||
set-view(mode) => { root.calendar-set-view(mode); }
|
||
set-source-enabled(calendar-id, enabled) => { root.calendar-set-source-enabled(calendar-id, enabled); }
|
||
toggle-agenda-filter(id, checked) => { root.calendar-toggle-agenda-filter(id, checked); }
|
||
clear-agenda-filters => { root.calendar-clear-agenda-filters(); }
|
||
today => { root.calendar-today(); }
|
||
new-event => { root.calendar-open-editor(); }
|
||
edit-event(event-id) => { root.calendar-edit-event(event-id); }
|
||
delete-event(event-id) => { root.calendar-delete-event(event-id); }
|
||
open-link(url) => { root.open_email_link(url); }
|
||
}
|
||
}
|
||
|
||
if root.active_view == "contacts" : WorkspaceFrame {
|
||
compact: root.compact-layout;
|
||
reserve-compact-navigation: root.compact-primary-nav-visible;
|
||
available-width: parent.width;
|
||
available-height: parent.height;
|
||
|
||
ContactsView {
|
||
detail-page-visible <=> root.contacts-detail-visible;
|
||
active: root.active_view == "contacts";
|
||
x: 0px;
|
||
y: 0px;
|
||
width: parent.width;
|
||
height: parent.height;
|
||
available-width: parent.width;
|
||
compact: root.compact-layout;
|
||
layout-mode: root.workspace_layout;
|
||
list-pane-width <=> root.workspace_list_pane_width;
|
||
list-pane-width-committed(width) => { root.save_workspace_list_pane_width(width); }
|
||
dark-mode: root.dark-mode;
|
||
sidebar-collapsed <=> root.contacts_sidebar_collapsed;
|
||
contacts: root.contacts;
|
||
sidebar-rows: root.contact_sidebar_rows;
|
||
toggle-section(key, open) => { root.toggle-contact-section(key, open); }
|
||
query <=> root.contact_search_query;
|
||
filter: root.contact_scope == "Favorites" ? "favorites"
|
||
: root.contact_scope == "Suggestions" ? "suggestions" : "all";
|
||
selected-scope: root.contact_scope;
|
||
status: root.contact_save_status;
|
||
can-load-more: root.contact_can_load_more;
|
||
loading-more: root.contact_loading_more;
|
||
content-revision: root.contact_list_revision;
|
||
total-count: root.contact_total_count;
|
||
favorite-count: root.contact_favorite_count;
|
||
suggestion-count: root.contact_suggestion_count;
|
||
has-selected: root.contact_has_selection;
|
||
selected-id <=> root.contact_id;
|
||
edit-name <=> root.contact_name;
|
||
edit-company <=> root.contact_company;
|
||
edit-job-title <=> root.contact_job_title;
|
||
edit-website <=> root.contact_website;
|
||
edit-birthday <=> root.contact_birthday;
|
||
edit-postal-address <=> root.contact_address;
|
||
edit-notes <=> root.contact_notes;
|
||
edit-tags <=> root.contact_tags;
|
||
edit-favorite <=> root.contact_favorite;
|
||
is-suggested: root.contact_is_suggested;
|
||
edit-initials: root.contact_initials;
|
||
email-values <=> root.contact-emails;
|
||
phone-values <=> root.contact-phones;
|
||
add-value(kind) => { root.add-contact-value(kind); }
|
||
prefer-value(kind,index) => { root.prefer-contact-value(kind,index); }
|
||
remove-value(kind,index) => { root.remove-contact-value(kind,index); }
|
||
read-only: root.contact-read-only;
|
||
source-name: root.contact-source;
|
||
sync: root.contact-sync;
|
||
sync-detail: root.contact-sync-detail;
|
||
photo: root.contact-photo;
|
||
has-photo: root.contact-has-photo;
|
||
resolve-conflict(keep-local) => { root.resolve-contact-conflict(keep-local); }
|
||
interaction-label: root.contact_interactions + (root.contact_last_interacted != "" ? " · " + root.contact_last_interacted : "");
|
||
accent: root.accent;
|
||
accent-soft: root.accent-soft;
|
||
avatar-bg: root.avatar-bg;
|
||
body-text: root.body-text;
|
||
border: root.border;
|
||
border-subtle: root.border-subtle;
|
||
control-bg: root.control-bg;
|
||
heading: root.heading;
|
||
muted-control-bg: root.muted-control-bg;
|
||
muted-text: root.muted-text;
|
||
secondary-text: root.secondary-text;
|
||
selected-row: root.selected-row;
|
||
sidebar-bg: root.sidebar-bg;
|
||
surface: root.surface;
|
||
surface-raised: root.surface-raised;
|
||
title-color: root.title-color;
|
||
select-contact(id) => { root.select-contact(id); }
|
||
search(query) => { root.search-contacts(query); }
|
||
refresh => { root.load-contacts(); }
|
||
load-more => { root.load-more-contacts(); }
|
||
select-filter(filter) => {
|
||
root.select-contact-scope(filter == "favorites" ? "Favorites"
|
||
: filter == "suggestions" ? "Suggestions"
|
||
: filter == "all" ? "All contacts" : filter);
|
||
}
|
||
new-contact => { root.new-contact(); }
|
||
save-contact(id, name, company, job-title, website, birthday, address, notes, tags, favorite) => {
|
||
root.save-contact(
|
||
id, name, company, job-title, website, birthday, address, notes, tags, favorite
|
||
);
|
||
}
|
||
delete-contact(id) => { root.delete-contact(id); }
|
||
usable-email(email) => { root.usable-contact-email(email) }
|
||
compose-to-contact(email) => {
|
||
if root.usable-contact-email(email) {
|
||
root.open_compose(email);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if root.active_view == "files" : WorkspaceFrame {
|
||
compact: root.compact-layout;
|
||
reserve-compact-navigation: root.compact-primary-nav-visible;
|
||
available-width: parent.width;
|
||
available-height: parent.height;
|
||
files-view := FilesView {
|
||
active: root.active_view == "files";
|
||
width: parent.width;
|
||
height: parent.height;
|
||
available-width: parent.width;
|
||
compact: root.compact-layout;
|
||
layout-mode: root.workspace_layout;
|
||
list-pane-width <=> root.workspace_list_pane_width;
|
||
account-model: root.connected_accounts;
|
||
list-pane-width-committed(width) => { root.save_workspace_list_pane_width(width); }
|
||
}
|
||
}
|
||
|
||
CompactProductNav {
|
||
// Keep compact navigation mounted so entering/leaving a detail
|
||
// screen can slide it instead of popping it in and out.
|
||
visible: root.compact-layout
|
||
&& (root.compact-primary-nav-visible || self.opacity > 0);
|
||
x: 0px;
|
||
y: root.compact-primary-nav-visible
|
||
? parent.height - root.compact-primary-nav-height
|
||
: parent.height;
|
||
width: parent.width;
|
||
height: root.compact-primary-nav-height;
|
||
opacity: root.compact-primary-nav-visible ? 1 : 0;
|
||
interactive: root.compact-primary-nav-visible;
|
||
animate y { duration: 240ms; easing: spring(0); }
|
||
animate opacity { duration: 160ms; easing: ease-out; }
|
||
active-view <=> root.active_view;
|
||
settings-active: root.settings_open;
|
||
background-color: root.sidebar-bg;
|
||
divider-color: root.border;
|
||
accent-color: root.accent;
|
||
accent-background: root.accent-soft;
|
||
muted-color: root.muted-text;
|
||
open-settings => { root.toggle_settings(); }
|
||
select-view(view) => {
|
||
root.active_view = view;
|
||
root.settings_open = false;
|
||
|
||
}
|
||
}
|
||
|
||
// Over the compact layout and its navigation, below the dialogs.
|
||
if TabsUi.enabled && TabsUi.compact && TabsUi.overview-open : TabOverview {
|
||
x: 0px;
|
||
y: 0px;
|
||
width: parent.width;
|
||
height: parent.height;
|
||
live-workspace: root.settings_open ? "settings" : root.active_view;
|
||
live-title: root.settings_open || root.active_view != "mail" ? ""
|
||
: root.has_selected && root.selected_subject != "" ? root.selected_subject
|
||
: root.selected_scope_title;
|
||
}
|
||
|
||
if root.calendar_editor_open : CalendarEventDialog {
|
||
compact: root.compact-layout;
|
||
x: 0px;
|
||
y: 0px;
|
||
width: parent.width;
|
||
height: parent.height;
|
||
dark-mode: root.dark-mode;
|
||
accent: root.accent;
|
||
border: root.border;
|
||
border-subtle: root.border-subtle;
|
||
control-bg: root.control-bg;
|
||
muted-text: root.muted-text;
|
||
surface: root.surface;
|
||
title-color: root.title-color;
|
||
calendar_editor_open <=> root.calendar_editor_open;
|
||
calendar_event_editing: root.calendar_event_editing;
|
||
calendar_event_title <=> root.calendar_event_title;
|
||
calendar_event_date <=> root.calendar_event_date;
|
||
calendar_event_time <=> root.calendar_event_time;
|
||
time-placeholder: root.time_format_sample;
|
||
calendar_event_duration <=> root.calendar_event_duration;
|
||
calendar_event_color <=> root.calendar_event_color;
|
||
calendar-save-event(title, date, time, duration, color) => {
|
||
root.calendar-save-event(title, date, time, duration, color);
|
||
}
|
||
}
|
||
|
||
if root.settings_open : WorkspaceFrame {
|
||
compact: root.compact-layout;
|
||
reserve-compact-navigation: root.compact-primary-nav-visible;
|
||
available-width: parent.width;
|
||
available-height: parent.height;
|
||
|
||
SettingsDialog {
|
||
compact: root.compact-layout;
|
||
x: 0px;
|
||
y: 0px;
|
||
width: parent.width;
|
||
height: parent.height;
|
||
connected_accounts: root.connected_accounts;
|
||
has_device_mail: root.has_device_mail;
|
||
mail_export_running: root.mail_export_running;
|
||
mail_export_status: I18n.ui-message(root.mail-export-message.key, root.mail-export-message.argument, root.mail-export-message.second_argument, root.mail-export-message.third_argument);
|
||
mail_profiles: root.mail_profiles;
|
||
profile_members: root.profile_members;
|
||
new-profile-requested <=> root.new_profile_requested;
|
||
custom_oauth_configured: root.custom_oauth_configured;
|
||
google_oauth_available: root.google_oauth_available;
|
||
microsoft_oauth_available: root.microsoft_oauth_available;
|
||
google_oauth_bundled: root.google_oauth_bundled;
|
||
microsoft_oauth_bundled: root.microsoft_oauth_bundled;
|
||
remote-images-available: root.remote-images-available;
|
||
account-transfer-supported: root.document_apis_supported;
|
||
sync_in_progress: root.sync_in_progress;
|
||
account_setup_in_progress: root.account_setup_in_progress;
|
||
account_form_open <=> root.account_form_open;
|
||
oauth_in_progress: root.oauth_in_progress;
|
||
oauth_settings_saving: root.oauth_settings_saving;
|
||
sync_status: root.sync_status;
|
||
app-version: root.app-version;
|
||
privacy-policy-url: root.privacy-policy-url;
|
||
storage_loading: root.storage_loading;
|
||
storage_loaded: root.storage_loaded;
|
||
storage_total: root.storage_total;
|
||
storage_error: root.storage_error;
|
||
storage_usage: root.storage_usage;
|
||
accent: root.accent;
|
||
accent-soft: root.accent-soft;
|
||
body-text: root.body-text;
|
||
border-subtle: root.border-subtle;
|
||
faint-text: root.faint-text;
|
||
heading: root.heading;
|
||
muted-text: root.muted-text;
|
||
page-bg: root.page-bg;
|
||
secondary-text: root.secondary-text;
|
||
// Under the tab strip, the sidebar shares the pages' raised
|
||
// surface, so the Settings tab opens into one color.
|
||
sidebar-bg: root.top-bar ? root.surface-raised : root.sidebar-bg;
|
||
surface: root.surface;
|
||
surface-raised: root.surface-raised;
|
||
title-color: root.title-color;
|
||
settings_open <=> root.settings_open;
|
||
settings_tab <=> root.settings_tab;
|
||
theme_mode <=> root.theme_mode;
|
||
show_avatars <=> root.show_avatars;
|
||
show_tabs <=> root.show_tabs;
|
||
spelling_available: root.spelling_available;
|
||
spelling_enabled <=> root.spelling_enabled;
|
||
spelling_installed: root.spelling_installed;
|
||
spelling_system: root.spelling_system;
|
||
group_mail_by_date <=> root.group_mail_by_date;
|
||
conversation_view <=> root.conversation_view;
|
||
show_account_markers <=> root.show_account_markers;
|
||
workspace_layout <=> root.workspace_layout;
|
||
language_mode <=> root.language_mode;
|
||
time_format <=> root.time_format;
|
||
time_format_sample: root.time_format_sample;
|
||
monochrome_sidebar_icons <=> root.monochrome_sidebar_icons;
|
||
notifications_enabled <=> root.notifications_enabled;
|
||
notification_sound_enabled <=> root.notification_sound_enabled;
|
||
unread_badge_enabled <=> root.unread_badge_enabled;
|
||
notification_scope <=> root.notification_scope;
|
||
sync_interval_minutes <=> root.sync_interval_minutes;
|
||
undo_send_seconds <=> root.undo_send_seconds;
|
||
mark_read_on_open <=> root.mark_read_on_open;
|
||
collect_outgoing_contacts <=> root.collect_outgoing_contacts;
|
||
collect_incoming_contacts <=> root.collect_incoming_contacts;
|
||
contact_suggest_all_accounts <=> root.contact_suggest_all_accounts;
|
||
suggest_learned_contacts <=> root.suggest_learned_contacts;
|
||
close_to_tray <=> root.close_to_tray;
|
||
launch_at_login <=> root.launch_at_login;
|
||
launch_at_login_available: root.launch_at_login_available;
|
||
tray_supported: root.tray_supported;
|
||
remote-images-enabled <=> root.remote-images-enabled;
|
||
account_email <=> root.account_email;
|
||
account_username <=> root.account_username;
|
||
account_password <=> root.account_password;
|
||
account_protocol <=> root.account_protocol;
|
||
jmap_url <=> root.jmap_url;
|
||
connect_calendar_on_add <=> root.connect_calendar_on_add;
|
||
caldav_account_id <=> root.caldav_account_id;
|
||
caldav_url <=> root.caldav_url;
|
||
caldav_username <=> root.caldav_username;
|
||
caldav_password <=> root.caldav_password;
|
||
caldav_connection_id <=> root.caldav_connection_id;
|
||
caldav_connecting: root.caldav_connecting;
|
||
carddav_account_id <=> root.carddav_account_id;
|
||
carddav_url <=> root.carddav_url;
|
||
carddav_username <=> root.carddav_username;
|
||
carddav_password <=> root.carddav_password;
|
||
carddav_manage_existing <=> root.carddav_manage_existing;
|
||
incoming_security <=> root.incoming_security;
|
||
smtp_security <=> root.smtp_security;
|
||
trusted_certificate_pem <=> root.trusted_certificate_pem;
|
||
oauth_authorization_url: root.oauth_authorization_url;
|
||
oauth_browser_error: root.oauth_browser_error;
|
||
retry_oauth_browser => { root.retry_oauth_browser(); }
|
||
copy_oauth_link => { root.copy_oauth_link(); }
|
||
submit_oauth_redirect(address) => { root.submit_oauth_redirect(address); }
|
||
import_mail_certificate => { root.import_mail_certificate(); }
|
||
incoming_host <=> root.incoming_host;
|
||
incoming_port <=> root.incoming_port;
|
||
smtp_host <=> root.smtp_host;
|
||
smtp_port <=> root.smtp_port;
|
||
google_client_id <=> root.google_client_id;
|
||
google_client_secret <=> root.google_client_secret;
|
||
ms_client_id <=> root.ms_client_id;
|
||
custom_oauth_open <=> root.custom_oauth_open;
|
||
save_theme(mode) => { root.save_theme(mode); }
|
||
save_theme_preset(preset) => { root.save_theme_preset(preset); }
|
||
download_directory <=> root.download_directory;
|
||
download_directory_available <=> root.download_directory_available;
|
||
choose_download_directory => { root.choose_download_directory(); }
|
||
clear_download_directory => { root.clear_download_directory(); }
|
||
save_custom_theme(
|
||
light-primary,
|
||
light-page,
|
||
light-surface,
|
||
light-text,
|
||
light-border,
|
||
dark-primary,
|
||
dark-page,
|
||
dark-surface,
|
||
dark-text,
|
||
dark-border,
|
||
) => {
|
||
return root.save_custom_theme(
|
||
light-primary,
|
||
light-page,
|
||
light-surface,
|
||
light-text,
|
||
light-border,
|
||
dark-primary,
|
||
dark-page,
|
||
dark-surface,
|
||
dark-text,
|
||
dark-border,
|
||
);
|
||
}
|
||
save_avatar_visibility(enabled) => { root.save_avatar_visibility(enabled); }
|
||
save_show_tabs(enabled) => { root.save_show_tabs(enabled); }
|
||
save_spelling_enabled(enabled) => { root.save_spelling_enabled(enabled); }
|
||
prepare_profile_members(profile-id, account-id) => {
|
||
root.prepare_profile_members(profile-id, account-id);
|
||
}
|
||
save_mail_profile(profile-id, name, color) => {
|
||
return root.save_mail_profile(profile-id, name, color);
|
||
}
|
||
assign_account_profile(account-id, profile-id) => {
|
||
root.assign_account_profile(account-id, profile-id);
|
||
}
|
||
save_account_color(account-id, color, generated) => {
|
||
root.save_account_color(account-id, color, generated);
|
||
}
|
||
delete_mail_profile(profile-id) => { root.delete_mail_profile(profile-id); }
|
||
save_account_markers_visibility(enabled) => {
|
||
root.save_account_markers_visibility(enabled);
|
||
}
|
||
save_workspace_layout(mode) => { root.save_workspace_layout(mode); }
|
||
save_language(language) => { root.save_language(language); }
|
||
save_time_format(format) => { root.save_time_format(format); }
|
||
save_sidebar_icon_style(monochrome) => { root.save_sidebar_icon_style(monochrome); }
|
||
save_notification_settings(enabled, sound-enabled, scope) => {
|
||
root.save_notification_settings(enabled, sound-enabled, scope);
|
||
}
|
||
save_unread_badge(enabled) => { root.save_unread_badge(enabled); }
|
||
save_sync_interval(minutes) => { root.save_sync_interval(minutes); }
|
||
save_undo_send(seconds) => { root.save_undo_send(seconds); }
|
||
save_mark_read_on_open(enabled) => { root.save_mark_read_on_open(enabled); }
|
||
save_group_mail_by_date(enabled) => { root.save_group_mail_by_date(enabled); }
|
||
save_conversation_view(enabled) => { root.save_conversation_view(enabled); }
|
||
save_contact_discovery_settings(outgoing, incoming, all-accounts, suggest) => {
|
||
root.save_contact_discovery_settings(outgoing, incoming, all-accounts, suggest);
|
||
}
|
||
clear_contact_suggestions => { return root.clear_contact_suggestions(); }
|
||
set_close_to_tray(enabled) => { root.set_close_to_tray(enabled); }
|
||
set_launch_at_login(enabled) => { root.set_launch_at_login(enabled); }
|
||
sync_mail => { root.sync_mail(); }
|
||
sync_account(account-id) => { root.sync_account(account-id); }
|
||
delete_account(account-id) => { root.delete_account(account-id); }
|
||
add_password_account(protocol, email, username, password, jmap-url, incoming-host, incoming-port, smtp-host, smtp-port) => {
|
||
root.add_password_account(protocol, email, username, password, jmap-url, incoming-host, incoming-port, smtp-host, smtp-port);
|
||
}
|
||
suggest_account_settings(email) => { root.suggest_account_settings(email); }
|
||
start_oauth(provider) => { root.start_oauth(provider); }
|
||
reauth_account(account-id) => { root.reauth_account(account-id); }
|
||
cancel_oauth => { root.cancel_oauth(); }
|
||
save_oauth_app(google-id, google-secret, microsoft-id) => {
|
||
root.save_oauth_app(google-id, google-secret, microsoft-id);
|
||
}
|
||
set-remote-images(enabled) => { root.set-remote-images(enabled); }
|
||
make_account_transfer(value) => root.make_account_transfer(value);
|
||
read_account_transfer(value) => root.read_account_transfer(value);
|
||
settings-search-matches(haystack, query) => root.settings-search-matches(haystack, query);
|
||
reorder_account(source, target, after) => { root.reorder_account(source, target, after); }
|
||
save_account_mail_history(account-id, value) => { root.save_account_mail_history(account-id, value); }
|
||
save_account_sent_copy_policy(account-id, value) => { root.save_account_sent_copy_policy(account-id, value); }
|
||
save_account_keep_on_server(account-id, value) => { root.save_account_keep_on_server(account-id, value); }
|
||
connect_account_calendar(account-id) => { root.connect_account_calendar(account-id); }
|
||
connect_caldav(account-id, connection-id, url, username, password) => { root.connect_caldav(account-id, connection-id, url, username, password); }
|
||
set_calendar_connection_enabled(connection-id, enabled) => { root.set_calendar_connection_enabled(connection-id, enabled); }
|
||
remove_calendar_connection(connection-id) => { root.remove_calendar_connection(connection-id); }
|
||
connect_carddav(account-id, url, username, password) => { root.connect_carddav(account-id, url, username, password); }
|
||
set_account_carddav_enabled(account-id, enabled) => { root.set_account_carddav_enabled(account-id, enabled); }
|
||
disconnect_carddav(account-id) => { root.disconnect_carddav(account-id); }
|
||
export_account_backup => { root.export_account_backup(); }
|
||
import_accounts => { root.import_accounts(); }
|
||
export_database_snapshot => { root.export_database_snapshot(); }
|
||
export_device_mail(account-id) => { root.export_device_mail(account-id); }
|
||
delete_all_data => { root.delete_all_data(); }
|
||
load_storage_usage => { root.load_storage_usage(); }
|
||
open-link(url) => { root.open_email_link(url); }
|
||
}
|
||
}
|
||
|
||
// A message on its way out, with a way to take it back. A phone's
|
||
// composer covers the window, so it waits for that to close.
|
||
if Notice.shown && !(root.compact-layout && ComposerUi.open) : NoticeToast {
|
||
text: I18n.ui-message(Notice.message.key, Notice.message.argument, Notice.message.second_argument, Notice.message.third_argument);
|
||
width: min(parent.width - 32px, min(560px, max(320px, self.preferred-width)));
|
||
x: (parent.width - self.width) / 2;
|
||
// Above the phone's navigation, and above the compose button
|
||
// where it shows.
|
||
y: parent.height - self.height - 20px
|
||
- (root.compact-primary-nav-visible ? root.compact-primary-nav-height : 0px)
|
||
- (root.active_view == "mail" && (root.compact-layout || root.mail_sidebar_collapsed)
|
||
? LayoutMetrics.touch-target + 12px : 0px);
|
||
z: 9000;
|
||
}
|
||
|
||
if ComposerUi.open : ComposeDialog {
|
||
|
||
in property <int> back-request: root.compose-back-request;
|
||
changed back-request => { if (self.back-request > 0) { self.back-requested(); } }
|
||
compact: root.compact-layout;
|
||
attachment-picker-supported: root.document_apis_supported;
|
||
notice: I18n.ui-message(ComposerUi.message.key, ComposerUi.message.argument, ComposerUi.message.second_argument, ComposerUi.message.third_argument);
|
||
x: 0px;
|
||
y: 0px;
|
||
width: parent.width;
|
||
height: parent.height;
|
||
}
|
||
|
||
// The rail width comes from the shared workspace geometry. Its hover label is
|
||
// rendered here, above the adjacent workspace, so it can extend right
|
||
// of the icon without being clipped by the rail component.
|
||
Rectangle {
|
||
visible: !root.compact-layout && product-rail.tooltip-text != "";
|
||
x: LayoutMetrics.product-rail-width + 6px;
|
||
y: product-rail.tooltip-y;
|
||
width: rail-tooltip-label.preferred-width + 16px;
|
||
height: 28px;
|
||
border-radius: 5px;
|
||
background: #292929;
|
||
z: 10000;
|
||
|
||
rail-tooltip-label := Text {
|
||
text: product-rail.tooltip-text;
|
||
color: white;
|
||
font-size: TypeScale.secondary;
|
||
horizontal-alignment: center;
|
||
vertical-alignment: center;
|
||
}
|
||
}
|
||
}
|
||
|
||
if Unsubscribe.stage != "" : UnsubscribeDialog {
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
z: 16000;
|
||
}
|
||
|
||
if BlockSender.stage != "" : BlockSenderDialog {
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
z: 16000;
|
||
}
|
||
|
||
if root.trash-delete-open : ConfirmationDialog {
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
z: 16000;
|
||
open <=> root.trash-delete-open;
|
||
title: root.trash-delete-kind == "empty" ? @tr("Empty Trash?") : @tr("Delete permanently?");
|
||
subject: "";
|
||
description: root.trash-delete-kind == "empty"
|
||
? root.trash-delete-id == 0 || (root.trash-delete-id < 0 && root.selected_scope == "Unified Trash")
|
||
? @tr("Permanently delete all messages in Trash across every connected account?")
|
||
: @tr("Permanently delete all messages in this account’s Trash?")
|
||
: root.trash-delete-kind == "bulk"
|
||
? @tr("Permanently delete the selected conversations from Trash?")
|
||
: @tr("Permanently delete this conversation from Trash?");
|
||
detail: @tr("This action cannot be undone.");
|
||
confirm-label: root.trash-delete-kind == "empty" ? @tr("Empty Trash") : @tr("Delete permanently");
|
||
icon: @image-url("icons/lucide/outline/trash.svg");
|
||
surface: root.surface;
|
||
dialog-border-color: root.border;
|
||
title-color: root.title-color;
|
||
body-color: root.body-text;
|
||
muted-color: root.muted-text;
|
||
confirmed => {
|
||
if root.trash-delete-kind == "empty" { root.empty_trash(root.trash-delete-id); }
|
||
else if root.trash-delete-kind == "bulk" { root.bulk_message_action("delete_permanently"); }
|
||
else if root.trash-delete-kind == "row" { root.message_action_for_email(root.trash-delete-id, "delete_permanently"); }
|
||
else { root.message_action("delete_permanently"); }
|
||
}
|
||
}
|
||
|
||
if AccountImport.open : ImportDialog {
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
z: 15500;
|
||
compact: root.compact-layout;
|
||
open-accounts => {
|
||
root.settings_tab = "Accounts";
|
||
root.settings_open = true;
|
||
}
|
||
show-mail => {
|
||
root.active_view = "mail";
|
||
root.settings_open = false;
|
||
}
|
||
}
|
||
|
||
if MovePickerUi.open : MoveDialog {
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
z: 15000;
|
||
compact: root.compact-layout;
|
||
}
|
||
|
||
if root.folder-dialog-open : FolderDialog {
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
z: 15000;
|
||
mode: root.folder-dialog-mode;
|
||
item-kind: root.folder-dialog-item-kind;
|
||
name <=> root.folder-dialog-name;
|
||
parent-name: root.folder-dialog-parent-name;
|
||
has-descendants: root.folder-dialog-has-descendants;
|
||
surface-color: root.surface;
|
||
raised-color: root.control-bg;
|
||
ui-border-color: root.border;
|
||
accent-color: root.accent;
|
||
title-color: root.title-color;
|
||
body-color: root.body-text;
|
||
muted-color: root.muted-text;
|
||
cancel => { root.folder-dialog-open = false; }
|
||
submit(name) => {
|
||
root.folder-dialog-open = false;
|
||
if (root.folder-dialog-item-kind == "label") {
|
||
root.save_mail_label(
|
||
root.folder-dialog-folder-id,
|
||
root.folder-dialog-account-id,
|
||
name,
|
||
root.folder-dialog-label-color,
|
||
false,
|
||
root.folder-dialog-parent-label-id,
|
||
);
|
||
if (root.folder-dialog-parent-label-id >= 0) {
|
||
root.toggle_sidebar_section(
|
||
"gmail-label:" + root.folder-dialog-account-id + ":" + root.folder-dialog-parent-label-id,
|
||
true,
|
||
);
|
||
}
|
||
} else if (root.folder-dialog-mode == "create") {
|
||
root.create-folder(root.folder-dialog-account-id, root.folder-dialog-parent-id, name);
|
||
} else {
|
||
root.rename-folder(root.folder-dialog-folder-id, name);
|
||
}
|
||
}
|
||
confirm-delete => {
|
||
root.folder-dialog-open = false;
|
||
if (root.folder-dialog-item-kind == "label") {
|
||
root.delete_mail_label(root.folder-dialog-folder-id);
|
||
} else {
|
||
root.delete-folder(root.folder-dialog-folder-id);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Slint conditional elements are instantiated lazily. The comparatively
|
||
// large onboarding form is unnecessary on normal launches with an account.
|
||
if root.startup_ready && !root.has-mail : OnboardingView {
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
startup-ready: root.startup_ready;
|
||
account-setup-in-progress: root.account_setup_in_progress;
|
||
oauth-in-progress: root.oauth_in_progress;
|
||
oauth-settings-saving: root.oauth_settings_saving;
|
||
oauth-settings-error <=> root.oauth_settings_error;
|
||
google-available: root.google_oauth_available;
|
||
microsoft-available: root.microsoft_oauth_available;
|
||
google-bundled: root.google_oauth_bundled;
|
||
microsoft-bundled: root.microsoft_oauth_bundled;
|
||
google-client-id: root.google_client_id;
|
||
google-client-secret: root.google_client_secret;
|
||
ms-client-id: root.ms_client_id;
|
||
oauth-setup-open <=> root.oauth_setup_open;
|
||
save-oauth-apps(google-id, google-secret, microsoft-id) => {
|
||
root.save_oauth_apps(google-id, google-secret, microsoft-id);
|
||
}
|
||
status: root.sync_status;
|
||
page-bg: root.page-bg;
|
||
surface: root.surface;
|
||
hover-surface: root.muted-control-bg;
|
||
title-color: root.title-color;
|
||
body-text: root.body-text;
|
||
muted-text: root.muted-text;
|
||
ui-border: root.border;
|
||
account-email <=> root.account_email;
|
||
account-password <=> root.account_password;
|
||
account-protocol <=> root.account_protocol;
|
||
jmap-url <=> root.jmap_url;
|
||
incoming-security <=> root.incoming_security;
|
||
smtp-security <=> root.smtp_security;
|
||
trusted-certificate-pem <=> root.trusted_certificate_pem;
|
||
account-username <=> root.account_username;
|
||
oauth-authorization-url: root.oauth_authorization_url;
|
||
oauth-browser-error: root.oauth_browser_error;
|
||
retry-oauth-browser => { root.retry_oauth_browser(); }
|
||
copy-oauth-link => { root.copy_oauth_link(); }
|
||
submit-oauth-redirect(address) => { root.submit_oauth_redirect(address); }
|
||
import-mail-certificate => { root.import_mail_certificate(); }
|
||
incoming-host <=> root.incoming_host;
|
||
incoming-port <=> root.incoming_port;
|
||
smtp-host <=> root.smtp_host;
|
||
smtp-port <=> root.smtp_port;
|
||
add-password-account(protocol, email, username, password, jmap-url, incoming-host, incoming-port, smtp-host, smtp-port) => {
|
||
root.add_password_account(protocol, email, username, password, jmap-url, incoming-host, incoming-port, smtp-host, smtp-port);
|
||
}
|
||
suggest-account-settings(email) => { root.suggest_account_settings(email); }
|
||
start-oauth(provider) => {
|
||
root.connect_calendar_on_add = false;
|
||
root.start_oauth(provider);
|
||
}
|
||
cancel-oauth => { root.cancel_oauth(); }
|
||
import-accounts => { root.import_accounts(); }
|
||
privacy-policy-url: root.privacy-policy-url;
|
||
open-link(url) => { root.open_email_link(url); }
|
||
}
|
||
|
||
// Keep the progressively painted shell inert until its callbacks have a
|
||
// core behind them. This disappears as soon as the first page lands.
|
||
if !root.startup_ready : TouchArea {
|
||
x: 0px;
|
||
y: 0px;
|
||
width: parent.width;
|
||
height: parent.height;
|
||
z: 20000;
|
||
}
|
||
|
||
if root.startup_failed : Rectangle {
|
||
x: root.content-x;
|
||
y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
background: root.page-bg;
|
||
z: 30000;
|
||
|
||
startup-card := Rectangle {
|
||
width: 460px.min(parent.width - 32px);
|
||
height: 330px.min(parent.height - 32px);
|
||
private property <bool> cramped: parent.height < 420px;
|
||
x: (parent.width - self.width) / 2;
|
||
y: (parent.height - self.height) / 2;
|
||
border-radius: 12px;
|
||
border-width: 1px;
|
||
border-color: root.border;
|
||
background: root.surface;
|
||
accessible-role: groupbox;
|
||
accessible-label: @tr("Mailbox startup failed");
|
||
|
||
VerticalLayout {
|
||
padding: parent.cramped ? 12px : 24px;
|
||
spacing: parent.cramped ? 8px : 12px;
|
||
Text {
|
||
text: @tr("Flectar Mail could not open local storage");
|
||
color: root.title-color;
|
||
font-size: TypeScale.heading;
|
||
font-weight: 700;
|
||
wrap: word-wrap;
|
||
}
|
||
Text {
|
||
text: root.startup_error;
|
||
color: root.body-text;
|
||
font-size: TypeScale.body;
|
||
wrap: word-wrap;
|
||
}
|
||
Text {
|
||
text: @tr("Diagnostic ID: {}", root.startup_diagnostic_id);
|
||
color: root.muted-text;
|
||
font-size: TypeScale.secondary;
|
||
accessible-label: @tr("Diagnostic ID {}", root.startup_diagnostic_id);
|
||
}
|
||
Rectangle { vertical-stretch: 1; }
|
||
Button {
|
||
height: root.content-height < 420px ? 44px : 48px;
|
||
text: @tr("Retry");
|
||
primary: true;
|
||
clicked => {
|
||
root.retry-startup();
|
||
}
|
||
}
|
||
Button {
|
||
height: root.content-height < 420px ? 44px : 48px;
|
||
text: @tr("Copy diagnostics");
|
||
clicked => {
|
||
diagnostic-copy.text = root.diagnostics_text;
|
||
diagnostic-copy.select-all();
|
||
diagnostic-copy.copy();
|
||
}
|
||
}
|
||
}
|
||
|
||
// Slint's native text input is the cross-platform clipboard bridge.
|
||
diagnostic-copy := TextInput {
|
||
width: 1px;
|
||
height: 1px;
|
||
opacity: 0;
|
||
}
|
||
}
|
||
}
|
||
AttachmentPreviewDialog {
|
||
x: root.content-x; y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
compact: root.compact-layout;
|
||
}
|
||
|
||
// Below the tab strip and inside the safe area, like the dialogs.
|
||
OpenPgpReader {
|
||
x: root.content-x; y: root.content-y;
|
||
width: root.content-width;
|
||
height: root.content-height;
|
||
}
|
||
|
||
// Keep the startup shell movable while its input is blocked.
|
||
if WindowChrome.controls-visible && !root.startup_ready : WindowDragArea {
|
||
x: root.content-x;
|
||
y: root.safe-area-insets.top;
|
||
width: root.content-width;
|
||
height: WindowChrome.band-height;
|
||
z: 20001;
|
||
}
|
||
|
||
// Above every layer, including startup and modal overlays, so the window
|
||
// can always be minimized, maximized and closed.
|
||
if root.top-bar : WindowTopBar {
|
||
x: root.content-x;
|
||
y: root.safe-area-insets.top;
|
||
width: root.content-width;
|
||
height: WindowChrome.band-height;
|
||
z: 40000;
|
||
// The active tab follows Settings, the workspace, and in Mail the
|
||
// open conversation or mailbox.
|
||
live-workspace: root.settings_open ? "settings" : root.active_view;
|
||
live-title: root.settings_open || root.active_view != "mail" ? ""
|
||
: root.has_selected && root.selected_subject != "" ? root.selected_subject
|
||
: root.selected_scope_title;
|
||
background-color: root.tab-strip-bg;
|
||
// The active tab opens into what lies under the strip: the raised
|
||
// surface across Settings, the plain one across every workspace.
|
||
active-tab-background: root.settings_open ? root.surface-raised : root.surface;
|
||
hover-background: AppTheme.sidebar-tint.mix(AppTheme.title, 0.90);
|
||
divider-color: root.border;
|
||
title-color: root.title-color;
|
||
text-color: root.secondary-text;
|
||
accent-color: root.accent;
|
||
profiles: root.mail_profiles;
|
||
active-profile: root.active_mail_profile;
|
||
account-count: root.connected_accounts.length;
|
||
choose-profile(id) => { root.select_mail_profile(id); }
|
||
create-profile => {
|
||
root.settings_tab = "Accounts";
|
||
root.settings_open = true;
|
||
root.new_profile_requested = true;
|
||
}
|
||
manage-profiles => {
|
||
root.settings_tab = "Accounts";
|
||
root.settings_open = true;
|
||
}
|
||
}
|
||
|
||
if WindowChrome.controls-visible : WindowControls {
|
||
x: root.content-x;
|
||
y: root.safe-area-insets.top;
|
||
width: root.content-width;
|
||
height: WindowChrome.band-height;
|
||
z: 50000;
|
||
maximized: root.maximized;
|
||
foreground: root.title-color;
|
||
background-color: root.top-bar ? root.tab-strip-bg : AppTheme.surface;
|
||
}
|
||
|
||
if root.client-frame : Rectangle {
|
||
z: 50001;
|
||
border-width: 1px;
|
||
border-color: AppTheme.control-border;
|
||
}
|
||
}
|