fix(ui): explain pending OTS on tap, render the stamp glyph and pill icons larger

Tapping the pending OTS pill now shows a toast explaining that the
attestation is waiting to be stamped into the Bitcoin blockchain (new
ots_info_pending_description). The OpenTimestamps glyph gets a
near-full-em content box — its fine outline read much lighter than
Material's solid shapes at the standard 80..880 bounds — and HeaderPill
icons go from 11dp to 13dp.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgEpNtwnetPhETXQSdq4b5
This commit is contained in:
Claude
2026-07-14 14:15:56 +00:00
parent 568aa9b005
commit 500de62841
5 changed files with 24 additions and 17 deletions
@@ -75,11 +75,18 @@ fun DisplayOts(
},
whenPending = {
// The stamp icon plus an ellipsis: attestation requested, not yet
// anchored. The content description carries the words.
// anchored. The content description carries the words; tapping
// explains what is being waited on.
HeaderPill(
symbol = MaterialSymbols.OpenTimestamps,
text = "",
contentDescription = stringRes(R.string.timestamp_pending_short),
onClick = {
accountViewModel.toastManager.toast(
R.string.ots_info_title,
R.string.ots_info_pending_description,
)
},
)
},
)
+1
View File
@@ -3021,6 +3021,7 @@
<string name="ots_info_title">Timestamp Proof</string>
<string name="ots_info_description">There\'s proof this post was signed sometime before %1$s. The proof was stamped in the Bitcoin blockchain at that date and time.</string>
<string name="ots_info_pending_description">A timestamp proof for this post has been requested and is waiting to be stamped in the Bitcoin blockchain. It usually completes within a few hours.</string>
<string name="edit_article">Edit Article</string>
<string name="edit_post">Edit Post</string>
@@ -70,7 +70,7 @@ fun HeaderPill(
symbol = symbol,
contentDescription = contentDescription,
tint = iconTint ?: MaterialTheme.colorScheme.placeholderText,
modifier = Modifier.size(11.dp),
modifier = Modifier.size(13.dp),
)
Text(
text = text,
@@ -30,18 +30,17 @@ 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.
# codepoint -> (glyph name, traced SVG, content-box fractions). 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.
#
# Material's own solid shapes draw inside 80..880 of a 960 upm em; a glyph
# with fine outlines (like the OpenTimestamps stamp) reads much lighter at
# the same bounds, so it gets a near-full-em box to appear the same size.
CUSTOM = {
0xF8F0: ("opentimestamps", os.path.join(HERE, "custom", "opentimestamps.svg")),
0xF8F0: ("opentimestamps", os.path.join(HERE, "custom", "opentimestamps.svg"), 20 / 960, 940 / 960),
}
# 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:
@@ -54,15 +53,15 @@ def draw_svg(paths, pen):
parse_path(d, pen)
def build_glyph(paths, upm):
def build_glyph(paths, upm, box_min_frac, box_max_frac):
# 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
# Uniform scale into the 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
@@ -79,8 +78,8 @@ def main(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)
for codepoint, (name, svg_file, box_min_frac, box_max_frac) in sorted(CUSTOM.items()):
glyph = build_glyph(svg_path_data(svg_file), upm, box_min_frac, box_max_frac)
if name not in order:
order.append(name)