diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayOts.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayOts.kt
index 319293d69c..ea62ebdb9d 100644
--- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayOts.kt
+++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayOts.kt
@@ -61,8 +61,8 @@ fun DisplayOts(
}
HeaderPill(
- symbol = MaterialSymbols.CheckCircle,
- text = stringRes(R.string.existed_since, timeStr),
+ symbol = MaterialSymbols.OpenTimestamps,
+ text = timeStr,
contentDescription = stringRes(R.string.ots_info_title),
onClick = {
accountViewModel.toastManager.toast(
@@ -75,8 +75,8 @@ fun DisplayOts(
},
whenPending = {
HeaderPill(
- symbol = MaterialSymbols.Schedule,
- text = stringRes(id = R.string.timestamp_pending_short),
+ symbol = MaterialSymbols.OpenTimestamps,
+ text = stringRes(id = R.string.pending),
contentDescription = stringRes(R.string.ots_info_title),
)
},
diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml
index a3ef6e6b7d..71c5cba0c2 100644
--- a/amethyst/src/main/res/values/strings.xml
+++ b/amethyst/src/main/res/values/strings.xml
@@ -45,6 +45,7 @@
Timestamp itTimestamp: Pending ConfirmationsOTS: Pending
+ PendingRequest DeletionBlock / Report
diff --git a/commons/src/commonMain/composeResources/font/material_symbols_outlined.ttf b/commons/src/commonMain/composeResources/font/material_symbols_outlined.ttf
index 01bd58472e..fde397e9ef 100644
Binary files a/commons/src/commonMain/composeResources/font/material_symbols_outlined.ttf and b/commons/src/commonMain/composeResources/font/material_symbols_outlined.ttf differ
diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/icons/symbols/MaterialSymbols.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/icons/symbols/MaterialSymbols.kt
index a038c5603d..7ef5919971 100644
--- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/icons/symbols/MaterialSymbols.kt
+++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/icons/symbols/MaterialSymbols.kt
@@ -167,6 +167,12 @@ object MaterialSymbols {
val Numbers = MaterialSymbol("\uEAC7")
val OpenInBrowser = MaterialSymbol("\uE89D")
val OpenInFull = MaterialSymbol("\uF1CE")
+
+ // Custom glyph (not part of Google's Material Symbols): the OpenTimestamps
+ // stamp logo, baked into the subset font by
+ // tools/material-symbols-subset/add_custom_glyphs.py from custom/opentimestamps.svg.
+ val OpenTimestamps = MaterialSymbol("\uF8F0")
+
val Paid = MaterialSymbol("\uF041")
val PanTool = MaterialSymbol("\uE925")
val Pause = MaterialSymbol("\uE034")
diff --git a/tools/material-symbols-subset/README.md b/tools/material-symbols-subset/README.md
index c6f689020b..9db8fea879 100644
--- a/tools/material-symbols-subset/README.md
+++ b/tools/material-symbols-subset/README.md
@@ -54,3 +54,15 @@ Commit the regenerated `.ttf` alongside the `MaterialSymbols.kt` change.
glyph and OpenType feature not reachable from those codepoints, and rewrites
`name`, `cmap`, and `GSUB` tables accordingly. The Compose resource pipeline
treats the result as a normal TTF — no code changes needed.
+
+## Custom glyphs
+
+`custom/` holds traced SVG outlines for icons the upstream font will never
+carry (third-party logos — currently the OpenTimestamps stamp).
+`add_custom_glyphs.py` bakes them into the subset TTF at end-of-PUA
+codepoints (U+F8F0 and up); `subset.sh` runs it automatically after
+`pyftsubset`, so regenerating the subset keeps them. To add one: trace the
+logo to a single-color SVG (potrace output works as-is), drop it in
+`custom/`, register it in the `CUSTOM` map in `add_custom_glyphs.py`, add the
+matching `MaterialSymbol("\uF8Fx")` to `MaterialSymbols.kt`, and rerun
+`subset.sh` (or `add_custom_glyphs.py ` to patch the existing font).
diff --git a/tools/material-symbols-subset/add_custom_glyphs.py b/tools/material-symbols-subset/add_custom_glyphs.py
new file mode 100644
index 0000000000..158c98e438
--- /dev/null
+++ b/tools/material-symbols-subset/add_custom_glyphs.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python3
+"""Append custom (non-Material) glyphs to the subset Material Symbols font.
+
+Some icons Amethyst needs are third-party logos that Google's Material
+Symbols font will never carry (e.g. the OpenTimestamps stamp). Their traced
+SVG outlines live in `custom/` and this script bakes them into the subset
+TTF at private-use codepoints, so `MaterialSymbols.kt` can reference them
+exactly like any Material glyph.
+
+subset.sh runs this automatically after pyftsubset; it can also be run
+directly against an existing font:
+
+ python3 add_custom_glyphs.py
+
+The SVGs are potrace output: the raw path coordinates are y-up already (the
+file's group transform re-flips them for SVG display), so they map into font
+space with a plain uniform scale + translate.
+"""
+
+import os
+import re
+import sys
+
+from fontTools.pens.boundsPen import BoundsPen
+from fontTools.pens.cu2quPen import Cu2QuPen
+from fontTools.pens.transformPen import TransformPen
+from fontTools.pens.ttGlyphPen import TTGlyphPen
+from fontTools.svgLib.path import parse_path
+from fontTools.ttLib import TTFont
+
+HERE = os.path.dirname(os.path.abspath(__file__))
+
+# codepoint -> (glyph name, traced SVG). Keep codepoints at the very end of
+# the BMP private-use area (U+F8xx tail) to stay clear of the range Material
+# Symbols actually allocates.
+CUSTOM = {
+ 0xF8F0: ("opentimestamps", os.path.join(HERE, "custom", "opentimestamps.svg")),
+}
+
+# Fit content into the same square Material Symbols draw in (its check_circle
+# glyph spans 80..880 in a 960 upm font). Scaled to the font's real upm.
+BOX_MIN_FRAC = 80 / 960
+BOX_MAX_FRAC = 880 / 960
+
+
+def svg_path_data(svg_file):
+ with open(svg_file, "r", encoding="utf-8") as f:
+ svg = f.read()
+ return re.findall(r']*\bd="([^"]+)"', svg)
+
+
+def draw_svg(paths, pen):
+ for d in paths:
+ parse_path(d, pen)
+
+
+def build_glyph(paths, upm):
+ # First pass: raw outline bounds.
+ bounds = BoundsPen(None)
+ draw_svg(paths, bounds)
+ x_min, y_min, x_max, y_max = bounds.bounds
+
+ # Uniform scale into the Material content box, centered on both axes.
+ box_min = BOX_MIN_FRAC * upm
+ box_max = BOX_MAX_FRAC * upm
+ box = box_max - box_min
+ scale = box / max(x_max - x_min, y_max - y_min)
+ tx = box_min + (box - (x_max - x_min) * scale) / 2 - x_min * scale
+ ty = box_min + (box - (y_max - y_min) * scale) / 2 - y_min * scale
+
+ tt_pen = TTGlyphPen(None)
+ quad_pen = Cu2QuPen(tt_pen, max_err=1.0)
+ draw_svg(paths, TransformPen(quad_pen, (scale, 0, 0, scale, tx, ty)))
+ return tt_pen.glyph()
+
+
+def main(font_path):
+ font = TTFont(font_path)
+ upm = font["head"].unitsPerEm
+ order = font.getGlyphOrder()
+
+ for codepoint, (name, svg_file) in sorted(CUSTOM.items()):
+ glyph = build_glyph(svg_path_data(svg_file), upm)
+
+ if name not in order:
+ order.append(name)
+ font.setGlyphOrder(order)
+ font["glyf"][name] = glyph
+ glyph.recalcBounds(font["glyf"])
+ font["hmtx"][name] = (upm, glyph.xMin)
+ for table in font["cmap"].tables:
+ if table.isUnicode():
+ table.cmap[codepoint] = name
+ print(f"Added {name} at U+{codepoint:04X}")
+
+ font["maxp"].numGlyphs = len(order)
+ font.save(font_path)
+ print(f"Wrote {font_path}")
+
+
+if __name__ == "__main__":
+ if len(sys.argv) != 2:
+ sys.exit(__doc__)
+ main(sys.argv[1])
diff --git a/tools/material-symbols-subset/custom/opentimestamps.svg b/tools/material-symbols-subset/custom/opentimestamps.svg
new file mode 100644
index 0000000000..054387593f
--- /dev/null
+++ b/tools/material-symbols-subset/custom/opentimestamps.svg
@@ -0,0 +1,130 @@
+
+
+
diff --git a/tools/material-symbols-subset/subset.sh b/tools/material-symbols-subset/subset.sh
index 0689a78aec..640964d342 100755
--- a/tools/material-symbols-subset/subset.sh
+++ b/tools/material-symbols-subset/subset.sh
@@ -59,4 +59,8 @@ pyftsubset "$SOURCE_TTF" \
--glyph-names \
--symbol-cmap
+# Bake in the custom (non-Material) glyphs from custom/ — third-party logos
+# like OpenTimestamps that the upstream font will never carry.
+python3 "$REPO_ROOT/tools/material-symbols-subset/add_custom_glyphs.py" "$TARGET"
+
echo "Wrote $TARGET ($(du -h "$TARGET" | cut -f1))"