From 4653bb75dea6835e80d3c875af0600c580e61e39 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 9 Oct 2023 14:59:33 -0300 Subject: content, client, css: quick description: expand, link externally --- .../dependencies/generateArtTagGalleryPage.js | 16 ++- .../dependencies/generateGroupGalleryPage.js | 6 +- .../dependencies/generateQuickDescription.js | 151 +++++++++++++++++---- src/static/client2.js | 66 +++++++++ src/static/site4.css | 48 ++++++- src/strings-default.json | 11 +- 6 files changed, 254 insertions(+), 44 deletions(-) diff --git a/src/content/dependencies/generateArtTagGalleryPage.js b/src/content/dependencies/generateArtTagGalleryPage.js index 4304b95a..72badb73 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 49869c76..2f8c63bb 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 136769ac..c67dd1ec 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 4f4a7153..164b3bac 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 81546bbf..ea1c83a5 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 a955eef2..1ca6dfd0 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", -- cgit 1.3.0-6-gf8a5