« get me outta code hell

content, client, css: quick description: expand, link externally - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-10-09 14:59:33 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-10-09 14:59:33 -0300
commit4653bb75dea6835e80d3c875af0600c580e61e39 (patch)
treee7e20d72baae4708e438c3eb122397d4d20cfd43
parent62d4080a957eb49810804ef8f33b01a08216bd34 (diff)
content, client, css: quick description: expand, link externally
-rw-r--r--src/content/dependencies/generateArtTagGalleryPage.js16
-rw-r--r--src/content/dependencies/generateGroupGalleryPage.js6
-rw-r--r--src/content/dependencies/generateQuickDescription.js151
-rw-r--r--src/static/client2.js66
-rw-r--r--src/static/site4.css48
-rw-r--r--src/strings-default.json11
6 files changed, 254 insertions, 44 deletions
diff --git a/src/content/dependencies/generateArtTagGalleryPage.js b/src/content/dependencies/generateArtTagGalleryPage.js
index 4304b95..72badb7 100644
--- a/src/content/dependencies/generateArtTagGalleryPage.js
+++ b/src/content/dependencies/generateArtTagGalleryPage.js
@@ -9,8 +9,8 @@ export default {
     'generateQuickDescription',
     'image',
     'linkAlbum',
-    'linkArtTagInfo',
     'linkArtTagGallery',
+    'linkExternal',
     'linkTrack',
   ],
 
@@ -44,12 +44,15 @@ export default {
     relations.navLinks =
       relation('generateArtTagNavLinks', artTag);
 
-    relations.infoPageLink =
-      relation('linkArtTagInfo', artTag);
-
     relations.quickDescription =
       relation('generateQuickDescription', artTag);
 
+    if (!empty(artTag.extraReadingURLs)) {
+      relations.extraReadingLinks =
+        artTag.extraReadingURLs
+          .map(url => relation('linkExternal', url));
+    }
+
     if (!empty(artTag.directAncestorArtTags)) {
       relations.ancestorLinks =
         artTag.directAncestorArtTags
@@ -124,8 +127,9 @@ export default {
 
         mainClasses: ['top-index'],
         mainContent: [
-          relations.quickDescription
-            .slot('infoPageLink', relations.infoPageLink),
+          relations.quickDescription.slots({
+            extraReadingLinks: relations.extraReadingLinks ?? null,
+          }),
 
           html.tag('p', {class: 'quick-info'},
             (data.numArtworks === 0
diff --git a/src/content/dependencies/generateGroupGalleryPage.js b/src/content/dependencies/generateGroupGalleryPage.js
index 49869c7..2f8c63b 100644
--- a/src/content/dependencies/generateGroupGalleryPage.js
+++ b/src/content/dependencies/generateGroupGalleryPage.js
@@ -75,9 +75,6 @@ export default {
     relations.quickDescription =
       relation('generateQuickDescription', group);
 
-    relations.quickDescriptionInfoLink =
-      relation('linkGroup', group);
-
     relations.coverGrid =
       relation('generateCoverGrid');
 
@@ -151,8 +148,7 @@ export default {
                     image.slot('path', path)),
             }),
 
-          relations.quickDescription
-            .slot('infoPageLink', relations.quickDescriptionInfoLink),
+          relations.quickDescription,
 
           html.tag('p',
             {class: 'quick-info'},
diff --git a/src/content/dependencies/generateQuickDescription.js b/src/content/dependencies/generateQuickDescription.js
index 136769a..c67dd1e 100644
--- a/src/content/dependencies/generateQuickDescription.js
+++ b/src/content/dependencies/generateQuickDescription.js
@@ -2,40 +2,131 @@ export default {
   contentDependencies: ['transformContent'],
   extraDependencies: ['html', 'language'],
 
-  relations: (relation, thing) =>
-    ({description:
-        (thing.descriptionShort || thing.description
-          ? relation('transformContent',
-              thing.descriptionShort ?? thing.description)
-          : null)}),
-
-  data: (thing) =>
-    ({hasLongerDescription:
-        thing.description &&
-        thing.descriptionShort &&
-        thing.descriptionShort !== thing.description}),
+  query: (thing) => ({
+    hasDescription:
+      !!thing.description,
+
+    hasLongerDescription:
+      thing.description &&
+      thing.descriptionShort &&
+      thing.descriptionShort !== thing.description,
+  }),
+
+  relations: (relation, query, thing) => ({
+    description:
+      (query.hasLongerDescription || !thing.description
+        ? null
+        : relation('transformContent', thing.description)),
+
+    descriptionShort:
+      (query.hasLongerDescription
+        ? relation('transformContent', thing.descriptionShort)
+        : null),
+
+    descriptionLong:
+      (query.hasLongerDescription
+        ? relation('transformContent', thing.description)
+        : null),
+  }),
+
+  data: (query) => ({
+    hasDescription: query.hasDescription,
+    hasLongerDescription: query.hasLongerDescription,
+  }),
 
   slots: {
-    infoPageLink: {type: 'html'},
+    extraReadingLinks: {validate: v => v.sparseArrayOf(v.isHTML)},
   },
 
   generate(data, relations, slots, {html, language}) {
-    return html.tag('p',
-      {
-        [html.joinChildren]: html.tag('br'),
+    const prefix = 'misc.quickDescription';
+
+    const actionsWithoutLongerDescription =
+      (data.hasLongerDescription
+        ? null
+     : slots.extraReadingLinks
+        ? language.$(prefix, 'readMore', {
+            links:
+              language.formatDisjunctionList(slots.extraReadingLinks),
+          })
+        : null);
+
+    const wrapExpandCollapseLink = (expandCollapse, content) =>
+      html.tag('a',
+        {href: '#', class: `${expandCollapse}-link`},
+        content);
+
+    const actionsWhenCollapsed =
+      (!data.hasLongerDescription
+        ? null
+     : slots.extraReadingLinks
+        ? language.$(prefix, 'expandDescription.orReadMore', {
+            links:
+              language.formatDisjunctionList(slots.extraReadingLinks),
+            expand:
+              wrapExpandCollapseLink('expand',
+                language.$(prefix, 'expandDescription.orReadMore.expand')),
+          })
+        : language.$(prefix, 'expandDescription', {
+            expand:
+              wrapExpandCollapseLink('expand',
+                language.$(prefix, 'expandDescription.expand')),
+          }));
+
+    const actionsWhenExpanded =
+      (!data.hasLongerDescription
+        ? null
+      : slots.extraReadingLinks
+        ? language.$(prefix, 'collapseDescription.orReadMore', {
+            links:
+              language.formatDisjunctionList(slots.extraReadingLinks),
+            collapse:
+              wrapExpandCollapseLink('collapse',
+                language.$(prefix, 'collapseDescription.orReadMore.collapse')),
+          })
+        : language.$(prefix, 'collapseDescription', {
+            collapse:
+              wrapExpandCollapseLink('collapse',
+                language.$(prefix, 'collapseDescription.collapse')),
+          }));
+
+    const wrapActions = (classes, children) =>
+      html.tag('p',
+        {[html.onlyIfContent]: true, class: [
+          'quick-description-actions',
+          ...classes]},
+        children);
+
+    const wrapContent = (classes, content) =>
+      html.tag('div',
+        {[html.onlyIfContent]: true, class: classes},
+        content?.slot('mode', 'multiline'));
+
+    return (
+      html.tag('div', {
         [html.onlyIfContent]: true,
-        class:' quick-info',
-      },
-      [
-        relations.description?.slot('mode', 'inline'),
-
-        data.hasLongerDescription &&
-        slots.infoPageLink &&
-          language.$('misc.quickDescription.moreInfo', {
-            link:
-              slots.infoPageLink
-                .slot('content', language.$('misc.quickDescription.moreInfo.link')),
-          }),
-      ]);
-  },
+        class: [
+          'quick-description',
+
+          data.hasLongerDescription &&
+            'collapsed',
+
+          !data.hasLongerDescription &&
+          !slots.extraReadingLinks &&
+            'has-content-only',
+
+          !data.hasDescription &&
+          slots.extraReadingLinks &&
+            'has-external-links-only',
+        ],
+      }, [
+        wrapContent(['description-content'], relations.description),
+        wrapContent(['description-content', 'short'], relations.descriptionShort),
+        wrapContent(['description-content', 'long'], relations.descriptionLong),
+
+        wrapActions([], actionsWithoutLongerDescription),
+        wrapActions(['when-collapsed'], actionsWhenCollapsed),
+        wrapActions(['when-expanded'], actionsWhenExpanded),
+      ]));
+  }
 };
diff --git a/src/static/client2.js b/src/static/client2.js
index 4f4a715..164b3ba 100644
--- a/src/static/client2.js
+++ b/src/static/client2.js
@@ -1209,6 +1209,72 @@ for (const info of groupContributionsTableInfo) {
   });
 }
 
+// Quick description --------------------------------------
+
+const quickDescriptionInfo = clientInfo.quickDescriptionInfo = {
+  quickDescriptionContainers: null,
+
+  quickDescriptionsAreExpandable: null,
+
+  expandDescriptionLinks: null,
+  collapseDescriptionLinks: null,
+};
+
+function getQuickDescriptionReferences() {
+  const info = quickDescriptionInfo;
+
+  info.quickDescriptionContainers =
+    Array.from(document.querySelectorAll('#content .quick-description'));
+
+  info.quickDescriptionsAreExpandable =
+    info.quickDescriptionContainers
+      .map(container =>
+        container.querySelector('.quick-description-actions.when-expanded'));
+
+  info.expandDescriptionLinks =
+    info.quickDescriptionContainers
+      .map(container =>
+        container.querySelector('.quick-description-actions .expand-link'));
+
+  info.collapseDescriptionLinks =
+    info.quickDescriptionContainers
+      .map(container =>
+        container.querySelector('.quick-description-actions .collapse-link'));
+}
+
+function addQuickDescriptionListeners() {
+  const info = quickDescriptionInfo;
+
+  for (const {
+    isExpandable,
+    container,
+    expandLink,
+    collapseLink,
+  } of stitchArrays({
+    isExpandable: info.quickDescriptionsAreExpandable,
+    container: info.quickDescriptionContainers,
+    expandLink: info.expandDescriptionLinks,
+    collapseLink: info.collapseDescriptionLinks,
+  })) {
+    if (!isExpandable) continue;
+
+    expandLink.addEventListener('click', event => {
+      event.preventDefault();
+      container.classList.add('expanded');
+      container.classList.remove('collapsed');
+    });
+
+    collapseLink.addEventListener('click', event => {
+      event.preventDefault();
+      container.classList.add('collapsed');
+      container.classList.remove('expanded');
+    });
+  }
+}
+
+clientSteps.getPageReferences.push(getQuickDescriptionReferences);
+clientSteps.addPageListeners.push(addQuickDescriptionListeners);
+
 // Sticky commentary sidebar ------------------------------
 
 const albumCommentarySidebarInfo = clientInfo.albumCommentarySidebarInfo = {
diff --git a/src/static/site4.css b/src/static/site4.css
index 81546bb..ea1c83a 100644
--- a/src/static/site4.css
+++ b/src/static/site4.css
@@ -665,10 +665,56 @@ ul.quick-info li:not(:last-child)::after {
   font-weight: 800;
 }
 
-.carousel-container + .quick-info {
+.carousel-container + .quick-info,
+.carousel-container + .quick-description {
   margin-top: 25px;
 }
 
+.quick-description:not(.has-external-links-only) {
+  margin-left: 8%;
+  margin-right: 8%;
+  padding-left: 4%;
+  padding-right: 4%;
+  padding-top: 0.25em;
+  padding-bottom: 0.75em;
+  border-left: 1px solid var(--dim-color);
+  border-right: 1px solid var(--dim-color);
+  line-height: 1.25em;
+}
+
+.quick-description.has-external-links-only {
+  padding-left: 12%;
+  padding-right: 12%;
+}
+
+.quick-description.has-content-only {
+  padding-bottom: 0.5em;
+}
+
+.quick-description p {
+  text-align: center;
+}
+
+.quick-description .description-content.long hr ~ p {
+  text-align: left;
+}
+
+.quick-description > .description-content :first-child {
+  margin-top: 0;
+}
+
+.quick-description > .quick-description-actions,
+.quick-description.has-content-only .description-content :last-child {
+  margin-bottom: 0;
+}
+
+.quick-description:not(.collapsed) .description-content.short,
+.quick-description:not(.collapsed) .quick-description-actions.when-collapsed,
+.quick-description:not(.expanded) .description-content.long,
+.quick-description:not(.expanded) .quick-description-actions.when-expanded {
+  display: none;
+}
+
 #intro-menu {
   margin: 24px 0;
   padding: 10px;
diff --git a/src/strings-default.json b/src/strings-default.json
index a955eef..1ca6dfd 100644
--- a/src/strings-default.json
+++ b/src/strings-default.json
@@ -215,8 +215,15 @@
   "misc.nav.gallery": "Gallery",
   "misc.pageTitle": "{TITLE}",
   "misc.pageTitle.withWikiName": "{TITLE} | {WIKI_NAME}",
-  "misc.quickDescription.moreInfo": "({LINK})",
-  "misc.quickDescription.moreInfo.link": "More info...",
+  "misc.quickDescription.expandDescription": "({EXPAND})",
+  "misc.quickDescription.expandDescription.expand": "Expand description...",
+  "misc.quickDescription.collapseDescription": "({COLLAPSE})",
+  "misc.quickDescription.collapseDescription.collapse": "Collapse description",
+  "misc.quickDescription.readMore": "Read more on {LINKS}.",
+  "misc.quickDescription.expandDescription.orReadMore": "({EXPAND}, or read more on {LINKS})",
+  "misc.quickDescription.expandDescription.orReadMore.expand": "Expand description",
+  "misc.quickDescription.collapseDescription.orReadMore": "({COLLAPSE}, or read more on {LINKS})",
+  "misc.quickDescription.collapseDescription.orReadMore.collapse": "Collapse description",
   "misc.skippers.skipTo": "Skip to:",
   "misc.skippers.content": "Content",
   "misc.skippers.sidebar": "Sidebar",