mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-30 15:48:36 +00:00
Desktop has no system emoji keyboard, so there was no way to type an emoji there. The composer's emoji button now opens a picker with the Unicode palette (categories, name search, skin tones) next to the existing NIP-30 custom emoji tab, in the note, comment, DM, public chat, Concord and Nest composers. - commons/unicodeEmoji: UnicodeEmojiCatalog parses the palette and searches it. - commonsUI: the palette file (Unicode emoji-test.txt up to Emoji 15.0, built by tools/emoji-data/generate.py) and the picker. Cells draw in the system's color emoji font on desktop, since Skia's fallback picks monochrome DejaVu Sans on Linux. - The reaction choices screen gets the picker in its field and is now registered in the shared nav host, so desktop can open it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEZ92TehbWvUhrJfrX2kie
98 lines
3.5 KiB
Python
98 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Builds the Unicode emoji palette that the shared emoji picker reads.
|
|
|
|
Input is Unicode's emoji-test.txt (UTS #51), which lists every RGI emoji in
|
|
CLDR keyboard order, by group. Output is a small tab-separated file under
|
|
commonsUI's compose resources:
|
|
|
|
#<license header lines>
|
|
@<group name>
|
|
<emoji>\t<name>[\t<5 skin-tone variants, space separated>]
|
|
|
|
Only fully-qualified emoji up to --max-version are kept, so the palette does not
|
|
offer glyphs the desktop's system emoji font (Segoe UI Emoji, Apple Color Emoji,
|
|
Noto Color Emoji) is still too old to draw. Skin-tone variants are folded into
|
|
their base emoji: an entry carries the five uniform-tone variants
|
|
("<name>: light skin tone", ...) when all five exist, and every other tone
|
|
combination is left out. The Component group (bare skin tones, hair) is dropped.
|
|
|
|
Usage:
|
|
curl -sSO https://unicode.org/Public/emoji/latest/emoji-test.txt
|
|
python3 tools/emoji-data/generate.py emoji-test.txt \
|
|
commonsUI/src/commonMain/composeResources/files/emoji/emoji.tsv
|
|
"""
|
|
|
|
import argparse
|
|
import re
|
|
|
|
TONES = ["light", "medium-light", "medium", "medium-dark", "dark"]
|
|
LINE = re.compile(r"^([0-9A-F ]+?)\s*;\s*([a-z-]+)\s*#\s*(\S+)\s+E(\d+\.\d+)\s+(.+)$")
|
|
|
|
LICENSE = [
|
|
"Generated by tools/emoji-data/generate.py from Unicode emoji-test.txt, version {version}.",
|
|
"Copyright (c) 1991-2026 Unicode, Inc. Distributed under the Unicode License v3:",
|
|
"https://www.unicode.org/license.txt",
|
|
]
|
|
|
|
|
|
def version_key(v):
|
|
major, minor = v.split(".")
|
|
return (int(major), int(minor))
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("source")
|
|
parser.add_argument("output")
|
|
parser.add_argument("--max-version", default="15.0")
|
|
args = parser.parse_args()
|
|
max_version = version_key(args.max_version)
|
|
|
|
groups = [] # [(name, [(emoji, name)])]
|
|
by_name = {} # name -> emoji, for the tone lookup
|
|
source_version = "?"
|
|
group = None
|
|
|
|
with open(args.source, encoding="utf-8") as f:
|
|
for raw in f:
|
|
line = raw.rstrip("\n")
|
|
if line.startswith("# Version:"):
|
|
source_version = line.split(":", 1)[1].strip()
|
|
continue
|
|
if line.startswith("# group:"):
|
|
name = line.split(":", 1)[1].strip()
|
|
group = None if name == "Component" else (name, [])
|
|
if group:
|
|
groups.append(group)
|
|
continue
|
|
m = LINE.match(line)
|
|
if not m or group is None:
|
|
continue
|
|
_, status, emoji, version, name = m.groups()
|
|
if status != "fully-qualified" or version_key(version) > max_version:
|
|
continue
|
|
by_name[name] = emoji
|
|
group[1].append((emoji, name))
|
|
|
|
out = ["# " + l.format(version=source_version) for l in LICENSE]
|
|
count = 0
|
|
for group_name, entries in groups:
|
|
out.append("@" + group_name)
|
|
for emoji, name in entries:
|
|
if " skin tone" in name:
|
|
continue # folded into its base entry below, or dropped
|
|
tones = [by_name.get(f"{name}: {t} skin tone") for t in TONES]
|
|
row = [emoji, name]
|
|
if all(tones):
|
|
row.append(" ".join(tones))
|
|
out.append("\t".join(row))
|
|
count += 1
|
|
|
|
with open(args.output, "w", encoding="utf-8") as f:
|
|
f.write("\n".join(out) + "\n")
|
|
print(f"wrote {count} emoji in {len(groups)} groups to {args.output}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|