From 6c9afe90b8d8cefc1d0976b27d98284186dd7b95 Mon Sep 17 00:00:00 2001 From: gravel Date: Thu, 18 May 2023 14:17:10 +0000 Subject: [PATCH] Add tags to modal, fix layout --- output/index.css | 60 +++++++++++-- output/js/constants.js | 5 +- output/main.js | 30 ++++++- php/utils/servers-rooms.php | 1 + php/utils/tags.php | 23 ++++- sites/+components/qr_modals.php | 121 ++++++++++++++------------ sites/+components/tbl_communities.php | 6 +- 7 files changed, 172 insertions(+), 74 deletions(-) diff --git a/output/index.css b/output/index.css index 6828af2..fe12cd3 100644 --- a/output/index.css +++ b/output/index.css @@ -113,7 +113,7 @@ html:not(.js) .js-only { /* box-shadow: 0.05em 0.05em 0.1em 0 #4444;*/ } -#tbl_communities .room-label { +#tbl_communities .room-label, #details-modal .room-label { color: black; } @@ -424,9 +424,9 @@ label[for=toggle-show-room-ids]::after { #details-modal-contents { display: flex; - position: relative; - flex-direction: row; + flex-direction: column; padding: 3em; + box-sizing: border-box; } #details-modal-close { @@ -440,6 +440,11 @@ label[for=toggle-show-room-ids]::after { text-align: center; } +#details-modal-pane { + display: flex; + flex-direction: row; +} + #details-modal-start { display: flex; flex-direction: column; @@ -463,10 +468,16 @@ label[for=toggle-show-room-ids]::after { font-style: italic; } +#details-modal-start #details-modal-language-flag:empty::after { + content: "Unknown"; + font-style: italic; +} + #details-modal-end #details-modal-qr-code { + aspect-ratio: 1; width: 20em; height: 20em; - margin-bottom: 1em; + margin: 1em; } #details-modal-end #details-modal-qr-code-label { @@ -480,6 +491,10 @@ label[for=toggle-show-room-ids]::after { padding: var(--cell-padding-small); } +#details-modal-qr-code-label-name { + display: block; +} + /* */ /* The snackbar - position it at the bottom and in the middle of the screen */ #copy-snackbar { @@ -554,15 +569,44 @@ label[for=toggle-show-room-ids]::after { } } +@media (max-width: 950px) { + #details-modal-pane { + flex-direction: column; + } + + #details-modal-end { + align-items: start; + } + + #details-modal #details-modal-qr-code { + width: 12.5em; + height: 12.5em; + } + + #details-modal-qr-code-label-name { + display: inline; + } + + #details-modal-language, #details-modal-users { + display: inline-block; + text-align: center; + } + + #details-modal-room-info > * { + margin-block: 0.5em; + } + + #details-modal-language::after { + content: "•"; + margin-inline: 1em; + } +} + @media (max-width: 500px) { :root { /* ! For when descriptions don't wrap and 100vw doesn't work. */ --dynamic-columns-width: 15rem; } - - #details-modal-contents { - flex-direction: column; - } } /* Animations to fade the snackbar in and out */ diff --git a/output/js/constants.js b/output/js/constants.js index 8d5c300..b631b8e 100644 --- a/output/js/constants.js +++ b/output/js/constants.js @@ -19,13 +19,15 @@ export const dom = { join_link: row.querySelector('.td_join_url a[href]').getAttribute('href'), hostname: row.getAttribute(ATTRIBUTES.ROW.HOSTNAME), public_key: row.getAttribute(ATTRIBUTES.ROW.PUBLIC_KEY), - staff: row.getAttribute(ATTRIBUTES.ROW.STAFF_DATA) + staff: row.getAttribute(ATTRIBUTES.ROW.STAFF_DATA), + tags: row.getAttribute(ATTRIBUTES.ROW.TAGS) }; }, meta_timestamp: () => document.querySelector('meta[name=timestamp]'), last_checked: () => document.getElementById("last_checked_value"), /** @return {HTMLDialogElement | null} */ details_modal: () => document.getElementById('details-modal'), + details_modal_tag_container: () => document.getElementById('details-modal-room-tags'), details_modal_qr_code: () => document.getElementById('details-modal-qr-code'), join_urls: () => document.getElementsByClassName("join_url_container"), servers_hidden: () => document.getElementById("servers_hidden"), @@ -56,6 +58,7 @@ export const COMPARISON = { export const ATTRIBUTES = { ROW: { + TAGS: 'data-tags', IDENTIFIER: 'data-identifier', PUBLIC_KEY: 'data-pubkey', HOSTNAME: 'data-hostname', diff --git a/output/main.js b/output/main.js index f8412f1..4390e70 100644 --- a/output/main.js +++ b/output/main.js @@ -75,6 +75,13 @@ function onLoad() { preloadQRCodes(); } +const tagBody = ({text, type, description}) => element.span({ + // todo: truncate + textContent: text, + className: `room-label room-label-${type} badge`, + title: description +}); + function displayQRModal(communityID) { const modal = dom.details_modal(); @@ -109,6 +116,14 @@ function displayQRModal(communityID) { } } + const tagContainer = dom.details_modal_tag_container(); + + tagContainer.innerHTML = ""; + + tagContainer.append( + ...JSON.parse(rowInfo.tags).map(tag => tagBody(tag)) + ); + dom.details_modal_qr_code().src = communityQRCodeURL(communityID); modal.showModal(); @@ -123,10 +138,19 @@ function addQRModalHandlers() { if (!rows) throw new Error("Rows not found"); for (const row of rows) { const communityID = row.getAttribute(ATTRIBUTES.ROW.IDENTIFIER); - row.querySelector('.td_qr_code').addEventListener( + for (const cell of ['.td_qr_code', '.td_description', '.td_language', '.td_users']) { + row.querySelector(cell).addEventListener( + 'click', + () => displayQRModal(communityID) + ); + } + row.addEventListener( 'click', - () => displayQRModal(communityID) - ); + (e) => { + if (e.target != row) { return; } + displayQRModal(communityID); + } + ) row.querySelector('.td_name').addEventListener( 'click', (e) => { diff --git a/php/utils/servers-rooms.php b/php/utils/servers-rooms.php index 493c670..d08cf07 100644 --- a/php/utils/servers-rooms.php +++ b/php/utils/servers-rooms.php @@ -110,6 +110,7 @@ function jsonSerialize(): array { $details = get_object_vars($this); unset($details['server']); + $details['tags'] = CommunityTag::cacheable_room_tags($details['tags']); return $details; } diff --git a/php/utils/tags.php b/php/utils/tags.php index 68af00e..190a92d 100644 --- a/php/utils/tags.php +++ b/php/utils/tags.php @@ -34,10 +34,25 @@ } public function jsonSerialize(): mixed { - if ($this->type != TagType::USER_TAG) { - throw new LogicException("Should not serialize derived tags."); - } - return $this->text; + // Only used for passing to DOM + $details = get_object_vars($this); + $details['text'] = html_sanitize($details['text']); + $details['description'] = html_sanitize($details['description']); + $details['type'] = $this->get_tag_type(); + return $details; + } + + /** + * @param \CommunityTag[] $tags + * @return string[] + */ + public static function cacheable_room_tags(array $tags) { + return array_map( + 'CommunityTag::__toString', + array_filter($tags, function(\CommunityTag $tag) { + return $tag->type == TagType::USER_TAG; + }) + ); } private static function preprocess_tag(?string $tag) { diff --git a/sites/+components/qr_modals.php b/sites/+components/qr_modals.php index bd7c67a..ad6768c 100644 --- a/sites/+components/qr_modals.php +++ b/sites/+components/qr_modals.php @@ -5,70 +5,79 @@
- × -
-
-

- -

-

- Description: - -

- -
-

- Language: -

-

- Users: -

-

- Server: + × +

+
+ +
+

+

+

+

+ +
+

-

- - - -

+

+

+ Language: +

+

+ Users: +

+

+ Server: + +

+
+
+ +
+ +
+ Scan QR code in Session to join + '' +
-
- +
+ Copy join link + + + +

diff --git a/sites/+components/tbl_communities.php b/sites/+components/tbl_communities.php index d3adb86..2418ef4 100644 --- a/sites/+components/tbl_communities.php +++ b/sites/+components/tbl_communities.php @@ -66,6 +66,7 @@ $hostname = html_sanitize($hostname); $staff_json = json_encode(array_map('html_sanitize', $room->get_staff())); + $tags_json = json_encode($room->get_room_tags()); ?> @@ -90,14 +92,14 @@ $name ?> -get_room_tags() as $tag): ?> +get_room_tags() as $tag): if (CommunityTag::is_showcased_tag($tag->text)): ?> text, 16) ?> - +