From 3a871cf43a11b87392d26320c736b516925da684 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Wed, 11 Oct 2023 14:32:28 -0300 Subject: implement flash act pages, rework flash sidebar layout --- .../dependencies/generateFlashActGalleryPage.js | 91 ++++++++ .../dependencies/generateFlashActNavAccent.js | 74 +++++++ .../dependencies/generateFlashActSidebar.js | 209 ++++++++++++++++++ src/content/dependencies/generateFlashIndexPage.js | 21 +- src/content/dependencies/generateFlashInfoPage.js | 17 +- src/content/dependencies/generateFlashNavAccent.js | 7 +- src/content/dependencies/generateFlashSidebar.js | 236 --------------------- src/content/dependencies/linkFlashAct.js | 14 ++ src/content/dependencies/listArtTagNetwork.js | 1 + 9 files changed, 405 insertions(+), 265 deletions(-) create mode 100644 src/content/dependencies/generateFlashActGalleryPage.js create mode 100644 src/content/dependencies/generateFlashActNavAccent.js create mode 100644 src/content/dependencies/generateFlashActSidebar.js delete mode 100644 src/content/dependencies/generateFlashSidebar.js create mode 100644 src/content/dependencies/linkFlashAct.js create mode 100644 src/content/dependencies/listArtTagNetwork.js (limited to 'src/content') diff --git a/src/content/dependencies/generateFlashActGalleryPage.js b/src/content/dependencies/generateFlashActGalleryPage.js new file mode 100644 index 00000000..8eea58bb --- /dev/null +++ b/src/content/dependencies/generateFlashActGalleryPage.js @@ -0,0 +1,91 @@ +import {stitchArrays} from '#sugar'; + +export default { + contentDependencies: [ + 'generateCoverGrid', + 'generateFlashActNavAccent', + 'generateFlashActSidebar', + 'generatePageLayout', + 'image', + 'linkFlash', + 'linkFlashIndex', + ], + + extraDependencies: ['html', 'language'], + + relations: (relation, act) => ({ + layout: + relation('generatePageLayout'), + + flashIndexLink: + relation('linkFlashIndex'), + + flashActNavAccent: + relation('generateFlashActNavAccent', act), + + sidebar: + relation('generateFlashActSidebar', act, null), + + coverGrid: + relation('generateCoverGrid'), + + coverGridImages: + act.flashes + .map(_flash => relation('image')), + + flashLinks: + act.flashes + .map(flash => relation('linkFlash', flash)), + }), + + data: (act) => ({ + name: act.name, + color: act.color, + + flashNames: + act.flashes.map(flash => flash.name), + + flashCoverPaths: + act.flashes.map(flash => + ['media.flashArt', flash.directory, flash.coverArtFileExtension]) + }), + + generate(data, relations, {html, language}) { + return relations.layout.slots({ + title: + language.$('flashPage.title', { + flash: new html.Tag(null, null, data.name), + }), + + color: data.color, + headingMode: 'static', + + mainClasses: ['flash-index'], + mainContent: [ + relations.coverGrid.slots({ + links: relations.flashLinks, + names: data.flashNames, + lazy: 6, + + images: + stitchArrays({ + image: relations.coverGridImages, + path: data.flashCoverPaths, + }).map(({image, path}) => + image.slot('path', path)), + }), + ], + + navLinkStyle: 'hierarchical', + navLinks: [ + {auto: 'home'}, + {html: relations.flashIndexLink}, + {auto: 'current'}, + ], + + navBottomRowContent: relations.flashActNavAccent, + + ...relations.sidebar, + }); + }, +}; diff --git a/src/content/dependencies/generateFlashActNavAccent.js b/src/content/dependencies/generateFlashActNavAccent.js new file mode 100644 index 00000000..98504385 --- /dev/null +++ b/src/content/dependencies/generateFlashActNavAccent.js @@ -0,0 +1,74 @@ +import {empty} from '#sugar'; + +export default { + contentDependencies: [ + 'generatePreviousNextLinks', + 'linkFlashAct', + ], + + extraDependencies: ['html', 'language', 'wikiData'], + + sprawl({flashActData}) { + return {flashActData}; + }, + + query(sprawl, flashAct) { + // Like with generateFlashNavAccent, don't sort chronologically here. + const flashActs = + sprawl.flashActData; + + const index = flashActs.indexOf(flashAct); + + const previousFlashAct = + (index > 0 + ? flashActs[index - 1] + : null); + + const nextFlashAct = + (index < flashActs.length - 1 + ? flashActs[index + 1] + : null); + + return {previousFlashAct, nextFlashAct}; + }, + + relations(relation, query) { + const relations = {}; + + if (query.previousFlashAct || query.nextFlashAct) { + relations.previousNextLinks = + relation('generatePreviousNextLinks'); + + relations.previousFlashActLink = + (query.previousFlashAct + ? relation('linkFlashAct', query.previousFlashAct) + : null); + + relations.nextFlashActLink = + (query.nextFlashAct + ? relation('linkFlashAct', query.nextFlashAct) + : null); + } + + return relations; + }, + + generate(relations, {html, language}) { + const {content: previousNextLinks = []} = + relations.previousNextLinks && + relations.previousNextLinks.slots({ + previousLink: relations.previousFlashActLink, + nextLink: relations.nextFlashActLink, + }); + + const allLinks = [ + ...previousNextLinks, + ].filter(Boolean); + + if (empty(allLinks)) { + return html.blank(); + } + + return `(${language.formatUnitList(allLinks)})`; + }, +}; diff --git a/src/content/dependencies/generateFlashActSidebar.js b/src/content/dependencies/generateFlashActSidebar.js new file mode 100644 index 00000000..ff5dc049 --- /dev/null +++ b/src/content/dependencies/generateFlashActSidebar.js @@ -0,0 +1,209 @@ +import find from '#find'; +import {stitchArrays} from '#sugar'; + +export default { + contentDependencies: ['linkFlash', 'linkFlashAct', 'linkFlashIndex'], + extraDependencies: ['getColors', 'html', 'language', 'wikiData'], + + // So help me Gog, the flash sidebar is heavily hard-coded. + + sprawl: ({flashActData}) => ({flashActData}), + + query(sprawl, act, flash) { + const findFlashAct = directory => + find.flashAct(directory, sprawl.flashActData, {mode: 'error'}); + + const sideFirstActs = [ + findFlashAct('flash-act:a1'), + findFlashAct('flash-act:a6a1'), + findFlashAct('flash-act:hiveswap'), + findFlashAct('flash-act:cool-and-new-web-comic'), + findFlashAct('flash-act:psycholonials'), + ]; + + const sideNames = [ + `Side 1 (Acts 1-5)`, + `Side 2 (Acts 6-7)`, + `Additional Canon`, + `Fan Adventures`, + `More Flashes & Games`, + ]; + + const sideColors = [ + '#4ac925', + '#3796c6', + '#f2a400', + '#c466ff', + '#32c7fe', + ]; + + const sideFirstActIndexes = + sideFirstActs + .map(act => sprawl.flashActData.indexOf(act)); + + const actSideIndexes = + sprawl.flashActData + .map((act, actIndex) => actIndex) + .map(actIndex => + sideFirstActIndexes + .findIndex((firstActIndex, i) => + i === sideFirstActs.length - 1 || + firstActIndex <= actIndex && + sideFirstActIndexes[i + 1] > actIndex)); + + const sideActs = + sideNames + .map((name, sideIndex) => + stitchArrays({ + act: sprawl.flashActData, + actSideIndex: actSideIndexes, + }).filter(({actSideIndex}) => actSideIndex === sideIndex) + .map(({act}) => act)); + + const currentActFlashes = + act.flashes; + + const currentFlashIndex = + currentActFlashes.indexOf(flash); + + const currentSideIndex = + actSideIndexes[sprawl.flashActData.indexOf(act)]; + + const currentSideActs = + sideActs[currentSideIndex]; + + const currentActIndex = + currentSideActs.indexOf(act); + + const visualNovelActs = [ + findFlashAct('flash-act:friendsim'), + findFlashAct('flash-act:pesterquest'), + findFlashAct('flash-act:psycholonials'), + ]; + + const gameSeriesActs = [ + findFlashAct('flash-act:hiveswap'), + ]; + + const listTerminology = + (visualNovelActs.includes(act) + ? 'volumesInThisGame' + : gameSeriesActs.includes(act) + ? 'gamesInThisSeries' + : act === findFlashAct('flash-act:other-fan-adventures') + ? 'flashesInThisSection' + : currentSideIndex <= 1 + ? 'flashesInThisAct' + : currentSideIndex === 3 + ? 'flashesInThisStory' + : 'entriesInThisSection'); + + return { + sideNames, + sideColors, + sideActs, + + currentSideIndex, + currentSideActs, + currentActIndex, + currentActFlashes, + currentFlashIndex, + + listTerminology, + }; + }, + + relations: (relation, query, sprawl, act, _flash) => ({ + currentActLink: + relation('linkFlashAct', act), + + flashIndexLink: + relation('linkFlashIndex'), + + sideActLinks: + query.sideActs + .map(acts => acts + .map(act => relation('linkFlashAct', act))), + + currentActFlashLinks: + act.flashes + .map(flash => relation('linkFlash', flash)), + }), + + data: (query, sprawl, act, flash) => ({ + isFlashActPage: !flash, + + sideColors: query.sideColors, + sideNames: query.sideNames, + + currentSideIndex: query.currentSideIndex, + currentActIndex: query.currentActIndex, + currentFlashIndex: query.currentFlashIndex, + + listTerminology: query.listTerminology, + }), + + generate(data, relations, {getColors, html, language}) { + const currentActBox = html.tags([ + html.tag('h1', relations.currentActLink), + + html.tag('details', + (data.isFlashActPage + ? {} + : {class: 'current', open: true}), + [ + html.tag('summary', + html.tag('span', {class: 'group-name'}, + language.$('flashSidebar.flashList', data.listTerminology))), + + html.tag('ul', + relations.currentActFlashLinks + .map((flashLink, index) => + html.tag('li', + {class: index === data.currentFlashIndex && 'current'}, + flashLink))), + ]), + ]); + + const sideMapBox = html.tags([ + html.tag('h1', relations.flashIndexLink), + + stitchArrays({ + sideName: data.sideNames, + sideColor: data.sideColors, + actLinks: relations.sideActLinks, + }).map(({sideName, sideColor, actLinks}, sideIndex) => + html.tag('details', { + class: sideIndex === data.currentSideIndex && 'current', + open: data.isFlashActPage && sideIndex === data.currentSideIndex, + style: sideColor && `--primary-color: ${getColors(sideColor).primary}` + }, [ + html.tag('summary', + html.tag('span', {class: 'group-name'}, + sideName)), + + html.tag('ul', + actLinks.map((actLink, actIndex) => + html.tag('li', + {class: + sideIndex === data.currentSideIndex && + actIndex === data.currentActIndex && + 'current'}, + actLink))), + ])), + ]); + + return { + leftSidebarMultiple: + (data.isFlashActPage + ? [ + {content: sideMapBox}, + {content: currentActBox}, + ] + : [ + {content: currentActBox}, + {content: sideMapBox}, + ]), + }; + }, +}; diff --git a/src/content/dependencies/generateFlashIndexPage.js b/src/content/dependencies/generateFlashIndexPage.js index 66588fdb..ad1dab94 100644 --- a/src/content/dependencies/generateFlashIndexPage.js +++ b/src/content/dependencies/generateFlashIndexPage.js @@ -7,6 +7,7 @@ export default { 'generatePageLayout', 'image', 'linkFlash', + 'linkFlashAct', ], extraDependencies: ['html', 'language', 'wikiData'], @@ -36,9 +37,9 @@ export default { query.flashActs .map(() => relation('generateColorStyleVariables')), - actFirstFlashLinks: + actLinks: query.flashActs - .map(act => relation('linkFlash', act.flashes[0])), + .map(act => relation('linkFlashAct', act)), actCoverGrids: query.flashActs @@ -58,7 +59,7 @@ export default { data: (query) => ({ jumpLinkAnchors: query.jumpActs - .map(act => act.anchor), + .map(act => act.directory), jumpLinkColors: query.jumpActs @@ -70,16 +71,12 @@ export default { actAnchors: query.flashActs - .map(act => act.anchor), + .map(act => act.directory), actColors: query.flashActs .map(act => act.color), - actNames: - query.flashActs - .map(act => act.name), - actCoverGridNames: query.flashActs .map(act => act.flashes @@ -118,10 +115,9 @@ export default { stitchArrays({ colorVariables: relations.actColorVariables, - firstFlashLink: relations.actFirstFlashLinks, + actLink: relations.actLinks, anchor: data.actAnchors, color: data.actColors, - name: data.actNames, coverGrid: relations.actCoverGrids, coverGridImages: relations.actCoverGridImages, @@ -132,8 +128,7 @@ export default { colorVariables, anchor, color, - name, - firstFlashLink, + actLink, coverGrid, coverGridImages, @@ -146,7 +141,7 @@ export default { id: anchor, style: colorVariables.slot('color', color).content, }, - firstFlashLink.slot('content', name)), + actLink), coverGrid.slots({ links: coverGridLinks, diff --git a/src/content/dependencies/generateFlashInfoPage.js b/src/content/dependencies/generateFlashInfoPage.js index 553d2f54..09c6b37c 100644 --- a/src/content/dependencies/generateFlashInfoPage.js +++ b/src/content/dependencies/generateFlashInfoPage.js @@ -4,13 +4,13 @@ export default { contentDependencies: [ 'generateContentHeading', 'generateContributionList', + 'generateFlashActSidebar', 'generateFlashCoverArtwork', 'generateFlashNavAccent', - 'generateFlashSidebar', 'generatePageLayout', 'generateTrackList', 'linkExternal', - 'linkFlashIndex', + 'linkFlashAct', ], extraDependencies: ['html', 'language'], @@ -41,7 +41,7 @@ export default { relation('generatePageLayout'); relations.sidebar = - relation('generateFlashSidebar', flash); + relation('generateFlashActSidebar', flash.act, flash); if (query.urls) { relations.externalLinks = @@ -59,8 +59,8 @@ export default { const nav = sections.nav = {}; - nav.flashIndexLink = - relation('linkFlashIndex'); + nav.flashActLink = + relation('linkFlashAct', flash.act); nav.flashNavAccent = relation('generateFlashNavAccent', flash); @@ -163,14 +163,11 @@ export default { navLinkStyle: 'hierarchical', navLinks: [ {auto: 'home'}, - {html: sec.nav.flashIndexLink}, + {html: sec.nav.flashActLink.slot('color', false)}, {auto: 'current'}, ], - navBottomRowContent: - sec.nav.flashNavAccent.slots({ - showFlashNavigation: true, - }), + navBottomRowContent: sec.nav.flashNavAccent, ...relations.sidebar, }); diff --git a/src/content/dependencies/generateFlashNavAccent.js b/src/content/dependencies/generateFlashNavAccent.js index 2c8205d3..57196d06 100644 --- a/src/content/dependencies/generateFlashNavAccent.js +++ b/src/content/dependencies/generateFlashNavAccent.js @@ -55,13 +55,8 @@ export default { return relations; }, - slots: { - showFlashNavigation: {type: 'boolean', default: false}, - }, - - generate(relations, slots, {html, language}) { + generate(relations, {html, language}) { const {content: previousNextLinks = []} = - slots.showFlashNavigation && relations.previousNextLinks && relations.previousNextLinks.slots({ previousLink: relations.previousFlashLink, diff --git a/src/content/dependencies/generateFlashSidebar.js b/src/content/dependencies/generateFlashSidebar.js deleted file mode 100644 index ba761922..00000000 --- a/src/content/dependencies/generateFlashSidebar.js +++ /dev/null @@ -1,236 +0,0 @@ -import {stitchArrays} from '#sugar'; - -export default { - contentDependencies: ['linkFlash', 'linkFlashIndex'], - extraDependencies: ['html', 'wikiData'], - - // So help me Gog, the flash sidebar is heavily hard-coded. - - sprawl: ({flashActData}) => ({flashActData}), - - query(sprawl, flash) { - const flashActs = - sprawl.flashActData.slice(); - - const act6 = - flashActs - .findIndex(act => act.name.startsWith('Act 6')); - - const postCanon = - flashActs - .findIndex(act => act.name.includes('Post Canon')); - - const outsideCanon = - postCanon + - flashActs - .slice(postCanon) - .findIndex(act => !act.name.includes('Post Canon')); - - const currentAct = flash.act; - - const actIndex = - flashActs - .indexOf(currentAct); - - const side = - (actIndex < 0 - ? 0 - : actIndex < act6 - ? 1 - : actIndex < outsideCanon - ? 2 - : 3); - - const sideActs = - flashActs - .filter((act, index) => - act.name.startsWith('Act 1') || - act.name.startsWith('Act 6 Act 1') || - act.name.startsWith('Hiveswap') || - index >= outsideCanon); - - const currentSideIndex = - sideActs - .findIndex(act => { - if (act.name.startsWith('Act 1')) { - return side === 1; - } else if (act.name.startsWith('Act 6 Act 1')) { - return side === 2; - } else if (act.name.startsWith('Hiveswap Act 1')) { - return side === 3; - } else { - return act === currentAct; - } - }) - - const sideNames = - sideActs - .map(act => { - if (act.name.startsWith('Act 1')) { - return `Side 1 (Acts 1-5)`; - } else if (act.name.startsWith('Act 6 Act 1')) { - return `Side 2 (Acts 6-7)`; - } else if (act.name.startsWith('Hiveswap Act 1')) { - return `Outside Canon (Misc. Games)`; - } else { - return act.name; - } - }); - - const sideColors = - sideActs - .map(act => { - if (act.name.startsWith('Act 1')) { - return '#4ac925'; - } else if (act.name.startsWith('Act 6 Act 1')) { - return '#1076a2'; - } else if (act.name.startsWith('Hiveswap Act 1')) { - return '#008282'; - } else { - return act.color; - } - }); - - const sideFirstFlashes = - sideActs - .map(act => act.flashes[0]); - - const scopeActs = - flashActs - .filter((act, index) => { - if (index < act6) { - return side === 1; - } else if (index < outsideCanon) { - return side === 2; - } else { - return false; - } - }); - - const currentScopeActIndex = - scopeActs.indexOf(currentAct); - - const scopeActNames = - scopeActs - .map(act => act.name); - - const scopeActFirstFlashes = - scopeActs - .map(act => act.flashes[0]); - - const currentActFlashes = - currentAct.flashes; - - const currentFlashIndex = - currentActFlashes - .indexOf(flash); - - return { - currentSideIndex, - sideNames, - sideColors, - sideFirstFlashes, - - currentScopeActIndex, - scopeActNames, - scopeActFirstFlashes, - - currentActFlashes, - currentFlashIndex, - }; - }, - - relations: (relation, query) => ({ - flashIndexLink: - relation('linkFlashIndex'), - - sideFirstFlashLinks: - query.sideFirstFlashes - .map(flash => relation('linkFlash', flash)), - - scopeActFirstFlashLinks: - query.scopeActFirstFlashes - .map(flash => relation('linkFlash', flash)), - - currentActFlashLinks: - query.currentActFlashes - .map(flash => relation('linkFlash', flash)), - }), - - data: (query) => ({ - currentSideIndex: query.currentSideIndex, - sideColors: query.sideColors, - sideNames: query.sideNames, - - currentScopeActIndex: query.currentScopeActIndex, - scopeActNames: query.scopeActNames, - - currentFlashIndex: query.currentFlashIndex, - }), - - generate(data, relations, {html}) { - const currentActFlashList = - html.tag('ul', - relations.currentActFlashLinks - .map((flashLink, index) => - html.tag('li', - {class: index === data.currentFlashIndex && 'current'}, - flashLink))); - - return { - leftSidebarContent: html.tags([ - html.tag('h1', relations.flashIndexLink), - - html.tag('dl', - stitchArrays({ - sideFirstFlashLink: relations.sideFirstFlashLinks, - sideColor: data.sideColors, - sideName: data.sideNames, - }).map(({sideFirstFlashLink, sideColor, sideName}, index) => [ - // Side acts are displayed whether part of Homestuck proper or - // not, and they're always the same regardless the current flash - // page. Scope acts, if applicable, and the list of flashes - // belonging to the current act, will be inserted after the - // heading of the current side. - html.tag('dt', - {class: [ - 'side', - index === data.currentSideIndex && 'current', - ]}, - sideFirstFlashLink.slots({ - color: sideColor, - content: sideName, - })), - - // Scope acts are only applicable when inside Homestuck proper. - // Hiveswap and all acts beyond are each considered to be its - // own "side". - index === data.currentSideIndex && - data.currentScopeActIndex !== -1 && - stitchArrays({ - scopeActFirstFlashLink: relations.scopeActFirstFlashLinks, - scopeActName: data.scopeActNames, - }).map(({scopeActFirstFlashLink, scopeActName}, index) => [ - html.tag('dt', - {class: index === data.currentScopeActIndex && 'current'}, - scopeActFirstFlashLink.slot('content', scopeActName)), - - // Inside Homestuck proper, the flash list of the current - // act should show after the heading for the relevant - // scope act. - index === data.currentScopeActIndex && - html.tag('dd', currentActFlashList), - ]), - - // Outside of Homestuck proper, the current act is represented - // by a side instead of a scope act, so place its flash list - // after the heading for the relevant side. - index === data.currentSideIndex && - data.currentScopeActIndex === -1 && - html.tag('dd', currentActFlashList), - ])), - - ]), - }; - }, -}; diff --git a/src/content/dependencies/linkFlashAct.js b/src/content/dependencies/linkFlashAct.js new file mode 100644 index 00000000..fbb819ed --- /dev/null +++ b/src/content/dependencies/linkFlashAct.js @@ -0,0 +1,14 @@ +export default { + contentDependencies: ['linkThing'], + extraDependencies: ['html'], + + relations: (relation, flashAct) => + ({link: relation('linkThing', 'localized.flashActGallery', flashAct)}), + + data: (flashAct) => + ({name: flashAct.name}), + + generate: (data, relations, {html}) => + relations.link + .slot('content', new html.Tag(null, null, data.name)), +}; diff --git a/src/content/dependencies/listArtTagNetwork.js b/src/content/dependencies/listArtTagNetwork.js new file mode 100644 index 00000000..b3a54747 --- /dev/null +++ b/src/content/dependencies/listArtTagNetwork.js @@ -0,0 +1 @@ +export default {generate() {}}; -- cgit 1.3.0-6-gf8a5