From 178397c9af193b2cebd3f8552b1e725a7b432b48 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 10 Aug 2023 11:01:25 -0300 Subject: content: generateFlashInfoPage ...Except the sidebar, which will be some shenanigans. --- .../dependencies/generateAlbumCoverArtwork.js | 23 +--- .../dependencies/generateFlashCoverArtwork.js | 12 ++ src/content/dependencies/generateFlashInfoPage.js | 148 ++++++++++++++++++++- src/content/dependencies/generateFlashNavAccent.js | 79 +++++++++++ .../dependencies/generateTrackCoverArtwork.js | 27 ++-- src/content/dependencies/linkExternal.js | 39 +++++- 6 files changed, 282 insertions(+), 46 deletions(-) create mode 100644 src/content/dependencies/generateFlashCoverArtwork.js create mode 100644 src/content/dependencies/generateFlashNavAccent.js diff --git a/src/content/dependencies/generateAlbumCoverArtwork.js b/src/content/dependencies/generateAlbumCoverArtwork.js index f7e8630..cbec930 100644 --- a/src/content/dependencies/generateAlbumCoverArtwork.js +++ b/src/content/dependencies/generateAlbumCoverArtwork.js @@ -1,23 +1,12 @@ export default { contentDependencies: ['generateCoverArtwork'], - relations(relation, album) { - return { - coverArtwork: - relation('generateCoverArtwork', album.artTags), - }; - }, + relations: (relation, album) => + ({coverArtwork: relation('generateCoverArtwork', album.artTags)}), - data(album) { - return { - path: ['media.albumCover', album.directory, album.coverArtFileExtension], - }; - }, + data: (album) => + ({path: ['media.albumCover', album.directory, album.coverArtFileExtension]}), - generate(data, relations) { - return relations.coverArtwork - .slots({ - path: data.path, - }); - }, + generate: (data, relations) => + relations.coverArtwork.slot('path', data.path), }; diff --git a/src/content/dependencies/generateFlashCoverArtwork.js b/src/content/dependencies/generateFlashCoverArtwork.js new file mode 100644 index 0000000..374fa3f --- /dev/null +++ b/src/content/dependencies/generateFlashCoverArtwork.js @@ -0,0 +1,12 @@ +export default { + contentDependencies: ['generateCoverArtwork'], + + relations: (relation) => + ({coverArtwork: relation('generateCoverArtwork')}), + + data: (flash) => + ({path: ['media.flashArt', flash.directory, flash.coverArtFileExtension]}), + + generate: (data, relations) => + relations.coverArtwork.slot('path', data.path), +}; diff --git a/src/content/dependencies/generateFlashInfoPage.js b/src/content/dependencies/generateFlashInfoPage.js index 4316d7c..af92ddf 100644 --- a/src/content/dependencies/generateFlashInfoPage.js +++ b/src/content/dependencies/generateFlashInfoPage.js @@ -1,38 +1,172 @@ +import {empty} from '../../util/sugar.js'; + export default { - contentDependencies: ['generatePageLayout'], + contentDependencies: [ + 'generateContentHeading', + 'generateContributionList', + 'generateFlashCoverArtwork', + 'generateFlashNavAccent', + 'generatePageLayout', + 'generateTrackList', + 'linkExternal', + 'linkFlashIndex', + ], + extraDependencies: ['html', 'language'], - relations(relation) { + query(flash) { + const query = {}; + + if (flash.page || !empty(flash.urls)) { + query.urls = []; + + if (flash.page) { + query.urls.push(`https://homestuck.com/story/${flash.page}`); + } + + if (!empty(flash.urls)) { + query.urls.push(...flash.urls); + } + } + + return query; + }, + + relations(relation, query, flash) { const relations = {}; + const sections = relations.sections = {}; relations.layout = relation('generatePageLayout'); + if (query.urls) { + relations.externalLinks = + query.urls.map(url => relation('linkExternal', url)); + } + + // TODO: Flashes always have cover art (#175) + /* eslint-disable-next-line no-constant-condition */ + if (true) { + relations.cover = + relation('generateFlashCoverArtwork', flash); + } + + // Section: navigation bar + + const nav = sections.nav = {}; + + nav.flashIndexLink = + relation('linkFlashIndex'); + + nav.flashNavAccent = + relation('generateFlashNavAccent', flash); + + // Section: Featured tracks + + if (!empty(flash.featuredTracks)) { + const featuredTracks = sections.featuredTracks = {}; + + featuredTracks.heading = + relation('generateContentHeading'); + + featuredTracks.list = + relation('generateTrackList', flash.featuredTracks); + } + + // Section: Contributors + + if (!empty(flash.contributorContribs)) { + const contributors = sections.contributors = {}; + + contributors.heading = + relation('generateContentHeading'); + + contributors.list = + relation('generateContributionList', flash.contributorContribs); + } + return relations; }, - data(flash) { - return { - name: flash.name, - }; + data(query, flash) { + const data = {}; + + data.name = flash.name; + data.color = flash.color; + data.date = flash.date; + + return data; }, generate(data, relations, {html, language}) { + const {sections: sec} = relations; + return relations.layout.slots({ title: language.$('flashPage.title', { flash: data.name, }), + color: data.color, + headingMode: 'sticky', + + cover: + (relations.cover + ? relations.cover.slots({ + alt: language.$('misc.alt.flashArt'), + }) + : null), + mainContent: [ - html.tag('p', `Alright alright, this is a stub page! Coming soon!`), + html.tag('p', + language.$('releaseInfo.released', { + date: language.formatDate(data.date), + })), + + relations.externalLinks && + html.tag('p', + language.$('releaseInfo.playOn', { + links: + language.formatDisjunctionList( + relations.externalLinks + .map(link => link.slot('mode', 'flash'))), + })), + + sec.featuredTracks && [ + sec.featuredTracks.heading + .slots({ + id: 'features', + title: + language.$('releaseInfo.tracksFeatured', { + flash: html.tag('i', data.name), + }), + }), + + sec.featuredTracks.list, + ], + + sec.contributors && [ + sec.contributors.heading + .slots({ + id: 'contributors', + title: language.$('releaseInfo.contributors'), + }), + + sec.contributors.list, + ], ], navLinkStyle: 'hierarchical', navLinks: [ {auto: 'home'}, + {html: sec.nav.flashIndexLink}, {auto: 'current'}, ], + + navBottomRowContent: + sec.nav.flashNavAccent.slots({ + showFlashNavigation: true, + }), }); }, }; diff --git a/src/content/dependencies/generateFlashNavAccent.js b/src/content/dependencies/generateFlashNavAccent.js new file mode 100644 index 0000000..1e2d185 --- /dev/null +++ b/src/content/dependencies/generateFlashNavAccent.js @@ -0,0 +1,79 @@ +import {empty} from '../../util/sugar.js'; +import {sortFlashesChronologically} from '../../util/wiki-data.js'; + +export default { + contentDependencies: [ + 'generatePreviousNextLinks', + 'linkFlash', + ], + + extraDependencies: ['html', 'language', 'wikiData'], + + sprawl({flashData}) { + return {flashData}; + }, + + query(sprawl, flash) { + const flashes = + sortFlashesChronologically(sprawl.flashData.slice()); + + const index = flashes.indexOf(flash); + + const previousFlash = + (index > 0 + ? flashes[index - 1] + : null); + + const nextFlash = + (index < flashes.length - 1 + ? flashes[index + 1] + : null); + + return {previousFlash, nextFlash}; + }, + + relations(relation, query) { + const relations = {}; + + if (query.previousFlash || query.nextFlash) { + relations.previousNextLinks = + relation('generatePreviousNextLinks'); + + relations.previousFlashLink = + (query.previousFlash + ? relation('linkFlash', query.previousFlash) + : null); + + relations.nextFlashLink = + (query.nextFlash + ? relation('linkFlash', query.nextFlash) + : null); + } + + return relations; + }, + + slots: { + showFlashNavigation: {type: 'boolean', default: false}, + }, + + generate(relations, slots, {html, language}) { + const {content: previousNextLinks = []} = + slots.showFlashNavigation && + relations.previousNextLinks && + relations.previousNextLinks.slots({ + previousLink: relations.previousFlashLink, + nextLink: relations.nextFlashLink, + }); + + const allLinks = [ + ...previousNextLinks, + ].filter(Boolean); + + if (empty(allLinks)) { + return html.blank(); + } + + return `(${language.formatUnitList(allLinks)})`; + }, +}; diff --git a/src/content/dependencies/generateTrackCoverArtwork.js b/src/content/dependencies/generateTrackCoverArtwork.js index 757ad2d..ec0488e 100644 --- a/src/content/dependencies/generateTrackCoverArtwork.js +++ b/src/content/dependencies/generateTrackCoverArtwork.js @@ -1,29 +1,20 @@ export default { contentDependencies: ['generateCoverArtwork'], - relations(relation, track) { - return { - coverArtwork: + relations: (relation, track) => + ({coverArtwork: relation('generateCoverArtwork', (track.hasUniqueCoverArt ? track.artTags - : track.album.artTags)), - }; - }, + : track.album.artTags))}), - data(track) { - return { - path: + data: (track) => + ({path: (track.hasUniqueCoverArt ? ['media.trackCover', track.album.directory, track.directory, track.coverArtFileExtension] - : ['media.albumCover', track.album.directory, track.album.coverArtFileExtension]), - }; - }, + : ['media.albumCover', track.album.directory, track.album.coverArtFileExtension])}), - generate(data, relations) { - return relations.coverArtwork - .slots({ - path: data.path, - }); - }, + generate: (data, relations) => + relations.coverArtwork.slot('path', data.path), }; + diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js index 7c3d86a..73c656e 100644 --- a/src/content/dependencies/linkExternal.js +++ b/src/content/dependencies/linkExternal.js @@ -11,7 +11,7 @@ export default { slots: { mode: { - validate: v => v.is('generic', 'album'), + validate: v => v.is('generic', 'album', 'flash'), default: 'generic', }, }, @@ -19,15 +19,18 @@ export default { generate(data, slots, {html, language}) { let isLocal; let domain; + let pathname; try { - domain = new URL(data.url).hostname; + const url = new URL(data.url); + domain = url.hostname; + pathname = url.pathname; } catch (error) { // No support for relative local URLs yet, sorry! (I.e, local URLs must // be absolute relative to the domain name in order to work.) isLocal = true; } - const a = html.tag('a', + const link = html.tag('a', { href: data.url, class: 'nowrap', @@ -85,6 +88,34 @@ export default { : domain); - return a; + switch (slots.mode) { + case 'flash': { + const wrap = content => + html.tag('span', {class: 'nowrap'}, content); + + if (domain.includes('homestuck.com')) { + const match = pathname.match(/\/story\/(.*)\/?/); + if (match) { + if (isNaN(Number(match[1]))) { + return wrap(language.$('misc.external.flash.homestuck.secret', {link})); + } else { + return wrap(language.$('misc.external.flash.homestuck.page', { + link, + page: match[1], + })); + } + } + } else if (domain.includes('bgreco.net')) { + return wrap(language.$('misc.external.flash.bgreco', {link})); + } else if (domain.includes('youtu')) { + return wrap(language.$('misc.external.flash.youtube', {link})); + } + + return link; + } + + default: + return link; + } } }; -- cgit 1.3.0-6-gf8a5