From 067eefecb276f33292c2298586af85ed43590d12 Mon Sep 17 00:00:00 2001 From: gravel Date: Sun, 12 Nov 2023 12:05:07 +0000 Subject: [PATCH] Detect #lang: tags --- for-sogops.md | 10 ++++++ php/servers/servers-rooms.php | 67 +++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/for-sogops.md b/for-sogops.md index 9958142..77094ca 100644 --- a/for-sogops.md +++ b/for-sogops.md @@ -16,6 +16,16 @@ Due to the lack of progress on the [issue of built-in Community tags](https://gi The obvious benefit is searchability. However, tags such as `#nsfw` or `#test` also help us automatically hide parts of the Community display. +#### Language tags + +Mark your Community with a language emoji by adding a tag of the form `#lang:CODE` at the end of your Community description. + +You can use any two-letter country code, or use any of the following codes: + +- `lang:any` or `lang:all` for 🌐, +- `lang:en` for 🇬🇧, and +- `lang:zh` for 🇨🇳. + ### Server-wide icons You may notice the Host column groups Communities by their host SOGS, and some SOGS are easily recognizable by a unified icon. If you also want your Communities to be linked by a recognizable icon, the requirements are easy: diff --git a/php/servers/servers-rooms.php b/php/servers/servers-rooms.php index ee11067..97c7539 100644 --- a/php/servers/servers-rooms.php +++ b/php/servers/servers-rooms.php @@ -118,6 +118,14 @@ */ private array $tags = []; + /** + * @var string $language_flag; + * Flag emoji as derived from specifying tags. + * + * Custom attribute. + */ + private ?string $language_flag; + private function __construct(CommunityServer $server, array $details) { $this->server = $server; $this->active_users = $details['active_users']; @@ -154,6 +162,14 @@ $room_identifier = $this->get_room_identifier(); $server_pubkey = $this->server->get_pubkey(); + if (isset($this->language_flag)) { + return $this->language_flag; + } + + // Latter only applies to fetching stage + // where the language flag is serialized into JSON. + // Later stages deserialize the property and detect it above. + if (isset($languages[$room_identifier])) { return $languages[$room_identifier]; } elseif (isset($languages[$server_pubkey])) { @@ -234,7 +250,10 @@ $room = new CommunityRoom($server, $details); $has_tags = isset($details['tags']); if ($has_tags) { - $room->tags = $details['tags']; + $room->add_tags($details['tags']); + } + if (isset($details['language_flag'])) { + $room->language_flag = $details['language_flag']; } return $room; } @@ -367,7 +386,48 @@ * @param string[] $tags */ public function add_tags(array $tags) { - $this->tags = [...$this->tags, ...$tags]; + foreach ($tags as $tag) { + if (!$this->parse_language_tag($tag)) { + $this->tags[] = $tag; + } + } + } + + /** + * Apply language from tag and return true if language tag, return false otherwise. + * @param string $tag + * @return bool + */ + private function parse_language_tag(string $tag): bool { + $matches = []; + + if (preg_match("/^lang:([a-z]+)$/", $tag, $matches) != 1) { + return false; + } + + if (isset($this->language_flag)) { + log_warning("Language is already $this->language_flag, parsing $tag"); + return true; + } + + $lang = $matches[1]; + if ($lang == "any" || $lang == "all") { + $this->language_flag = "🌐"; + } elseif ($lang == "en") { + $this->language_flag = "🇬🇧"; + } elseif ($lang == "zh") { + $this->language_flag = "🇨🇳"; + } elseif (strlen($lang) == 2) { + $chars = str_split($lang); + $flag_chars = array_map(function(string $char) { + return mb_chr(ord($char) - ord("a") + mb_ord("🇦")); + }, $chars); + $this->language_flag = implode($flag_chars); + } else { + return false; // Invalid language flag + } + + return true; } /** @@ -1306,7 +1366,7 @@ log_info("Fetching pubkey from $preview_url"); $room_view_response = yield from FetchingCoroutine ::from_url($preview_url) - ->retryable($has_pubkey || $FAST_FETCH_MODE ? 1 : 5) + ->retryable(($has_pubkey || $FAST_FETCH_MODE) ? 1 : 5) ->run(); $room_view = $room_view_response @@ -1318,6 +1378,7 @@ return $has_pubkey; } + $links = parse_join_links($room_view); $link = $links[0];