mirror of
https://github.com/flectar/mail.git
synced 2026-11-11 17:57:54 +00:00
103 lines
4.0 KiB
Plaintext
103 lines
4.0 KiB
Plaintext
import { TypeScale } from "../typography.slint";
|
|
|
|
// A single avatar primitive for people, accounts, and sender brands. The
|
|
// caller owns the image data; this component owns circular clipping, fallback
|
|
// initials, sizing, and consistent image sampling across the application.
|
|
export component Avatar inherits Rectangle {
|
|
in property <image> source;
|
|
in property <bool> has-source: false;
|
|
in property <string> fallback: "?";
|
|
in property <length> size: 40px;
|
|
in property <color> background-color: #f1f1ef;
|
|
in property <color> foreground-color: #4b4c49;
|
|
// Optional stable palette slot for people without stored photos. Callers
|
|
// derive the slot from an identity key; Avatar owns the theme-aware muted
|
|
// palette so fallback styling is not duplicated across contact surfaces.
|
|
in property <int> color-tone: -1;
|
|
in property <bool> dark-mode: false;
|
|
in property <color> avatar-border-color: transparent;
|
|
in property <length> avatar-border-width: 0px;
|
|
in property <ImageFit> image-fit: cover;
|
|
private property <color> tone-background: root.dark-mode
|
|
? (root.color-tone == 0 ? #293631
|
|
: root.color-tone == 1 ? #332f3b
|
|
: root.color-tone == 2 ? #382f2b
|
|
: root.color-tone == 3 ? #29353b
|
|
: root.color-tone == 4 ? #383529
|
|
: #2e372c)
|
|
: (root.color-tone == 0 ? #dfe8e3
|
|
: root.color-tone == 1 ? #e5e1ec
|
|
: root.color-tone == 2 ? #e9e1dc
|
|
: root.color-tone == 3 ? #dce6ea
|
|
: root.color-tone == 4 ? #e9e5d9
|
|
: #e0e7dd);
|
|
private property <color> tone-foreground: root.dark-mode
|
|
? (root.color-tone == 0 ? #a8c4b7
|
|
: root.color-tone == 1 ? #c0b3d0
|
|
: root.color-tone == 2 ? #cdb3a5
|
|
: root.color-tone == 3 ? #a9c0ca
|
|
: root.color-tone == 4 ? #c9c09e
|
|
: #b0c6aa)
|
|
: (root.color-tone == 0 ? #455c51
|
|
: root.color-tone == 1 ? #594e68
|
|
: root.color-tone == 2 ? #675045
|
|
: root.color-tone == 3 ? #405a66
|
|
: root.color-tone == 4 ? #635b40
|
|
: #4a6145);
|
|
// Initials keep at least the caption size, but shrink to fit the circle
|
|
// where the platform font makes them wider than a small avatar.
|
|
private property <length> initials-size: max(TypeScale.caption, root.size * 0.29);
|
|
|
|
width: root.size;
|
|
height: root.size;
|
|
border-radius: root.size / 2;
|
|
// Downloaded rasters carry their own antialiased circular alpha mask.
|
|
// Keeping the source surface transparent prevents opaque square corners
|
|
// from showing through on software-rendered views.
|
|
background: root.has-source ? transparent
|
|
: root.color-tone >= 0 ? root.tone-background
|
|
: root.background-color;
|
|
clip: true;
|
|
|
|
if root.has-source : Image {
|
|
width: parent.width;
|
|
height: parent.height;
|
|
source: root.source;
|
|
image-fit: root.image-fit;
|
|
image-rendering: smooth;
|
|
horizontal-alignment: center;
|
|
vertical-alignment: center;
|
|
accessible-role: none;
|
|
}
|
|
|
|
if !root.has-source : Rectangle {
|
|
initials-measure := Text {
|
|
visible: false;
|
|
text: root.fallback;
|
|
font-size: root.initials-size;
|
|
font-weight: 700;
|
|
}
|
|
Text {
|
|
width: parent.width;
|
|
height: parent.height;
|
|
text: root.fallback;
|
|
color: root.color-tone >= 0 ? root.tone-foreground : root.foreground-color;
|
|
font-size: root.initials-size * min(1, (root.size - 1px) / max(1px, initials-measure.preferred-width));
|
|
font-weight: 700;
|
|
horizontal-alignment: center;
|
|
vertical-alignment: center;
|
|
overflow: elide;
|
|
}
|
|
}
|
|
|
|
// Draw the outline after the image so full-bleed photos cannot cover it.
|
|
Rectangle {
|
|
width: parent.width;
|
|
height: parent.height;
|
|
border-radius: root.size / 2;
|
|
border-width: root.avatar-border-width;
|
|
border-color: root.avatar-border-color;
|
|
background: transparent;
|
|
}
|
|
}
|