mirror of
https://github.com/flectar/mail.git
synced 2026-11-12 02:05:59 +00:00
371 lines
14 KiB
Plaintext
371 lines
14 KiB
Plaintext
import { ListView, VerticalBox } from "std-widgets.slint";
|
|
import { EmailTemplateRow } from "../models.slint";
|
|
import { Button } from "button.slint";
|
|
import { ConfirmationDialog } from "confirmation-dialog.slint";
|
|
import { IconButton, LineEdit, TextEdit } from "controls.slint";
|
|
import { TypeScale } from "../typography.slint";
|
|
|
|
export component EmailTemplates inherits Rectangle {
|
|
in-out property <bool> open: false;
|
|
in property <bool> compact: false;
|
|
in property <[EmailTemplateRow]> templates: [];
|
|
in property <string> draft-subject: "";
|
|
in property <string> draft-body: "";
|
|
in property <string> notice: "";
|
|
in property <bool> notice-is-error: false;
|
|
in property <color> surface-color;
|
|
in property <color> raised-color;
|
|
in property <color> ui-border-color;
|
|
in property <color> hover-color;
|
|
in property <color> title-color;
|
|
in property <color> body-color;
|
|
in property <color> muted-color;
|
|
in property <color> accent-color;
|
|
callback refresh;
|
|
callback use-template(int) -> bool;
|
|
callback save-template(int, string, string, string, string) -> bool;
|
|
callback delete-template(int) -> bool;
|
|
|
|
private property <bool> editing: false;
|
|
private property <int> edit-id: -1;
|
|
private property <string> edit-name: "";
|
|
private property <string> edit-shortcut: "";
|
|
private property <string> edit-subject: "";
|
|
private property <string> edit-body: "";
|
|
private property <bool> delete-open: false;
|
|
private property <int> delete-id: -1;
|
|
private property <string> delete-name: "";
|
|
|
|
function close-dialog() {
|
|
root.editing = false;
|
|
root.delete-open = false;
|
|
root.open = false;
|
|
}
|
|
|
|
function new-template() {
|
|
root.edit-id = -1;
|
|
root.edit-name = "";
|
|
root.edit-shortcut = "";
|
|
root.edit-subject = root.draft-subject;
|
|
root.edit-body = root.draft-body;
|
|
root.editing = true;
|
|
}
|
|
|
|
function edit-template(index: int) {
|
|
root.edit-id = root.templates[index].id;
|
|
root.edit-name = root.templates[index].name;
|
|
root.edit-shortcut = root.templates[index].shortcut;
|
|
root.edit-subject = root.templates[index].subject;
|
|
root.edit-body = root.templates[index].body_text;
|
|
root.editing = true;
|
|
}
|
|
|
|
changed open => {
|
|
if root.open {
|
|
root.editing = false;
|
|
root.delete-open = false;
|
|
root.refresh();
|
|
template-focus.focus();
|
|
}
|
|
}
|
|
|
|
changed delete-open => {
|
|
if !root.delete-open && root.open {
|
|
template-focus.focus();
|
|
}
|
|
}
|
|
|
|
visible: root.open;
|
|
background: #00000066;
|
|
z: 7000;
|
|
accessible-role: groupbox;
|
|
accessible-label: @tr("Email templates");
|
|
|
|
TouchArea { enabled: root.open; }
|
|
|
|
panel := Rectangle {
|
|
x: root.compact ? 0px : (parent.width - self.width) / 2;
|
|
y: root.compact ? 0px : (parent.height - self.height) / 2;
|
|
width: root.compact ? parent.width : min(620px, parent.width - 32px);
|
|
height: root.compact ? parent.height : min(560px, parent.height - 32px);
|
|
border-radius: root.compact ? 0px : 12px;
|
|
border-width: root.compact ? 0px : 1px;
|
|
border-color: root.ui-border-color;
|
|
background: root.surface-color;
|
|
clip: true;
|
|
|
|
template-focus := FocusScope {
|
|
width: parent.width;
|
|
height: parent.height;
|
|
capture-key-pressed(event) => {
|
|
if event.text == Key.Escape && !root.delete-open {
|
|
if root.editing {
|
|
root.editing = false;
|
|
} else {
|
|
root.close-dialog();
|
|
}
|
|
return accept;
|
|
}
|
|
reject
|
|
}
|
|
|
|
header := Rectangle {
|
|
x: 0px;
|
|
y: 0px;
|
|
width: parent.width;
|
|
height: 56px;
|
|
background: root.raised-color;
|
|
border-width: 1px;
|
|
border-color: root.ui-border-color;
|
|
|
|
Text {
|
|
x: 20px;
|
|
width: parent.width - 76px;
|
|
height: parent.height;
|
|
text: root.editing
|
|
? (root.edit-id < 0 ? @tr("New email template") : @tr("Edit email template"))
|
|
: @tr("Email templates");
|
|
color: root.title-color;
|
|
font-size: TypeScale.heading;
|
|
font-weight: 700;
|
|
vertical-alignment: center;
|
|
overflow: elide;
|
|
}
|
|
|
|
IconButton {
|
|
x: parent.width - 48px;
|
|
y: 8px;
|
|
width: 40px;
|
|
height: 40px;
|
|
icon: @image-url("../icons/lucide/outline/x.svg");
|
|
icon-color: root.muted-color;
|
|
hover-background: root.hover-color;
|
|
tooltip-text: @tr("Close");
|
|
clicked => { root.close-dialog(); }
|
|
}
|
|
}
|
|
|
|
if !root.editing : Rectangle {
|
|
x: 0px;
|
|
y: header.height;
|
|
width: parent.width;
|
|
height: parent.height - header.height;
|
|
|
|
Button {
|
|
x: 16px;
|
|
y: 14px;
|
|
width: 144px;
|
|
height: 34px;
|
|
text: @tr("New template");
|
|
icon: @image-url("../icons/lucide/outline/plus.svg");
|
|
has-icon: true;
|
|
primary: true;
|
|
clicked => { root.new-template(); }
|
|
}
|
|
|
|
if root.notice != "" : Text {
|
|
x: 160px;
|
|
y: 14px;
|
|
width: max(0px, parent.width - 176px);
|
|
height: 34px;
|
|
text: root.notice;
|
|
color: root.notice-is-error ? #d04a43 : root.accent-color;
|
|
font-size: TypeScale.caption;
|
|
vertical-alignment: center;
|
|
overflow: elide;
|
|
}
|
|
|
|
if root.templates.length == 0 : Text {
|
|
x: 20px;
|
|
y: 82px;
|
|
width: parent.width - 40px;
|
|
text: @tr("No email templates yet");
|
|
color: root.muted-color;
|
|
font-size: TypeScale.body;
|
|
horizontal-alignment: center;
|
|
wrap: word-wrap;
|
|
}
|
|
|
|
templates-list := ListView {
|
|
x: 12px;
|
|
y: 60px;
|
|
width: parent.width - 24px;
|
|
height: parent.height - 72px;
|
|
content-width: self.visible-width;
|
|
horizontal-scrollbar-policy: always-off;
|
|
mouse-drag-pan-enabled: root.compact;
|
|
|
|
for template[index] in root.templates : Rectangle {
|
|
width: max(0px, templates-list.visible-width - 12px);
|
|
height: template-detail.y + template-detail.height + 12px;
|
|
border-radius: 7px;
|
|
background: template-hit.has-hover ? root.hover-color : transparent;
|
|
|
|
template-name := Text {
|
|
x: 10px;
|
|
y: 9px;
|
|
width: max(0px, parent.width - 162px);
|
|
height: max(22px, self.preferred-height);
|
|
text: template.name;
|
|
color: root.title-color;
|
|
font-size: TypeScale.body;
|
|
font-weight: 600;
|
|
overflow: elide;
|
|
}
|
|
|
|
template-detail := Text {
|
|
x: 10px;
|
|
y: template-name.y + template-name.height + 1px;
|
|
width: max(0px, parent.width - 162px);
|
|
height: max(20px, self.preferred-height);
|
|
text: template.shortcut == ""
|
|
? (template.subject == "" ? @tr("No subject") : template.subject)
|
|
: "/" + template.shortcut + (template.subject == "" ? "" : " · " + template.subject);
|
|
color: root.muted-color;
|
|
font-size: TypeScale.caption;
|
|
overflow: elide;
|
|
}
|
|
|
|
template-hit := TouchArea {
|
|
x: 0px;
|
|
width: max(0px, parent.width - 144px);
|
|
height: parent.height;
|
|
accessible-role: button;
|
|
accessible-label: @tr("Insert template {}", template.name);
|
|
accessible-action-default => {
|
|
if root.use-template(template.id) { root.close-dialog(); }
|
|
}
|
|
clicked => {
|
|
if root.use-template(template.id) { root.close-dialog(); }
|
|
}
|
|
mouse-cursor: pointer;
|
|
}
|
|
|
|
Button {
|
|
x: parent.width - 136px;
|
|
y: 15px;
|
|
width: 68px;
|
|
height: 34px;
|
|
text: @tr("Insert");
|
|
clicked => {
|
|
if root.use-template(template.id) { root.close-dialog(); }
|
|
}
|
|
}
|
|
|
|
IconButton {
|
|
x: parent.width - 66px;
|
|
y: 16px;
|
|
icon: @image-url("../icons/lucide/outline/compose.svg");
|
|
icon-color: root.muted-color;
|
|
hover-background: root.hover-color;
|
|
tooltip-text: @tr("Edit template");
|
|
clicked => { root.edit-template(index); }
|
|
}
|
|
|
|
IconButton {
|
|
x: parent.width - 32px;
|
|
y: 16px;
|
|
icon: @image-url("../icons/lucide/outline/trash.svg");
|
|
icon-color: root.muted-color;
|
|
hover-background: root.hover-color;
|
|
tooltip-text: @tr("Delete template");
|
|
clicked => {
|
|
root.delete-id = template.id;
|
|
root.delete-name = template.name;
|
|
root.delete-open = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if root.editing : VerticalBox {
|
|
x: 18px;
|
|
y: header.height + 14px;
|
|
width: parent.width - 36px;
|
|
height: parent.height - header.height - 28px;
|
|
padding: 0px;
|
|
spacing: 8px;
|
|
|
|
LineEdit {
|
|
height: 36px;
|
|
text <=> root.edit-name;
|
|
input-label: @tr("Template name");
|
|
placeholder-text: @tr("Template name");
|
|
}
|
|
LineEdit {
|
|
height: 36px;
|
|
text <=> root.edit-shortcut;
|
|
input-label: @tr("Shortcut (optional)");
|
|
placeholder-text: @tr("Shortcut (optional)");
|
|
}
|
|
LineEdit {
|
|
height: 36px;
|
|
text <=> root.edit-subject;
|
|
input-label: @tr("Subject (optional)");
|
|
placeholder-text: @tr("Subject (optional)");
|
|
}
|
|
TextEdit {
|
|
vertical-stretch: 1;
|
|
min-height: 70px;
|
|
text <=> root.edit-body;
|
|
placeholder-text: @tr("Template message");
|
|
}
|
|
|
|
if root.notice != "" : Text {
|
|
height: max(22px, self.preferred-height);
|
|
text: root.notice;
|
|
color: root.notice-is-error ? #d04a43 : root.accent-color;
|
|
font-size: TypeScale.caption;
|
|
overflow: elide;
|
|
}
|
|
|
|
HorizontalLayout {
|
|
height: 34px;
|
|
spacing: 8px;
|
|
Rectangle { horizontal-stretch: 1; }
|
|
Button {
|
|
text: @tr("Cancel");
|
|
clicked => { root.editing = false; }
|
|
}
|
|
Button {
|
|
text: @tr("Save template");
|
|
primary: true;
|
|
enabled: root.edit-name != "" && (root.edit-subject != "" || root.edit-body != "");
|
|
clicked => {
|
|
if root.save-template(
|
|
root.edit-id,
|
|
root.edit-name,
|
|
root.edit-shortcut,
|
|
root.edit-subject,
|
|
root.edit-body,
|
|
) {
|
|
root.editing = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ConfirmationDialog {
|
|
x: 0px;
|
|
y: 0px;
|
|
width: parent.width;
|
|
height: parent.height;
|
|
open <=> root.delete-open;
|
|
title: @tr("Delete email template?");
|
|
subject: root.delete-name;
|
|
description: @tr("Delete this template from this device?");
|
|
confirm-label: @tr("Delete");
|
|
icon: @image-url("../icons/lucide/outline/trash.svg");
|
|
surface: root.surface-color;
|
|
dialog-border-color: root.ui-border-color;
|
|
title-color: root.title-color;
|
|
body-color: root.body-color;
|
|
muted-color: root.muted-color;
|
|
confirmed => { root.delete-template(root.delete-id); }
|
|
}
|
|
}
|