diff options
| author | (quasar) nebula <qznebula@protonmail.com> | 2026-01-26 13:27:30 -0400 |
|---|---|---|
| committer | (quasar) nebula <qznebula@protonmail.com> | 2026-01-26 13:46:59 -0400 |
| commit | 5c19b69f94b1ef913b114853264917f7eda627ed (patch) | |
| tree | 040ee5d23b9d669a61b3643ccbbb908b3f594f13 /src/data/things/homepage-layout/HomepageLayout.js | |
| parent | ca4e9b3fd53f91e1cd95c8aa20496177ec39d669 (diff) | |
data: split homepage-layout.js
Diffstat (limited to 'src/data/things/homepage-layout/HomepageLayout.js')
| -rw-r--r-- | src/data/things/homepage-layout/HomepageLayout.js | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/data/things/homepage-layout/HomepageLayout.js b/src/data/things/homepage-layout/HomepageLayout.js new file mode 100644 index 00000000..e144bf80 --- /dev/null +++ b/src/data/things/homepage-layout/HomepageLayout.js @@ -0,0 +1,128 @@ +const HOMEPAGE_LAYOUT_DATA_FILE = 'homepage.yaml'; + +import {V} from '#composite'; +import Thing from '#thing'; +import {empty} from '#sugar'; +import {isStringNonEmpty, validateArrayItems} from '#validators'; + +import {exposeConstant} from '#composite/control-flow'; +import {contentString, thingList} from '#composite/wiki-properties'; + +export class HomepageLayout extends Thing { + static [Thing.friendlyName] = `Homepage Layout`; + static [Thing.wikiData] = 'homepageLayout'; + static [Thing.oneInstancePerWiki] = true; + + static [Thing.getPropertyDescriptors] = ({HomepageLayoutSection}) => ({ + // Update & expose + + sidebarContent: contentString(), + + navbarLinks: { + flags: {update: true, expose: true}, + update: {validate: validateArrayItems(isStringNonEmpty)}, + expose: {transform: value => value ?? []}, + }, + + sections: thingList(V(HomepageLayoutSection)), + + // Expose only + + isHomepageLayout: exposeConstant(V(true)), + }); + + static [Thing.yamlDocumentSpec] = { + fields: { + 'Homepage': {ignore: true}, + + 'Sidebar Content': {property: 'sidebarContent'}, + 'Navbar Links': {property: 'navbarLinks'}, + }, + }; + + static [Thing.getYamlLoadingSpec] = ({ + documentModes: {allInOne}, + thingConstructors: { + HomepageLayout, + HomepageLayoutActionsRow, + HomepageLayoutAlbumCarouselRow, + HomepageLayoutAlbumGridRow, + HomepageLayoutRow, + HomepageLayoutSection, + }, + }) => ({ + title: `Process homepage layout file`, + file: HOMEPAGE_LAYOUT_DATA_FILE, + + documentMode: allInOne, + documentThing: document => { + if (document['Homepage']) { + return HomepageLayout; + } + + if (document['Section']) { + return HomepageLayoutSection; + } + + if (document['Row']) { + switch (document['Row']) { + case 'actions': + return HomepageLayoutActionsRow; + case 'album carousel': + return HomepageLayoutAlbumCarouselRow; + case 'album grid': + return HomepageLayoutAlbumGridRow; + default: + throw new TypeError(`Unrecognized row type ${document['Row']}`); + } + } + + return null; + }, + + connect(results) { + if (!empty(results) && !(results[0] instanceof HomepageLayout)) { + throw new Error(`Expected 'Homepage' document at top of homepage layout file`); + } + + const homepageLayout = results[0]; + const sections = []; + + let currentSection = null; + let currentSectionRows = []; + + const closeCurrentSection = () => { + if (currentSection) { + for (const row of currentSectionRows) { + row.section = currentSection; + } + + currentSection.rows = currentSectionRows; + sections.push(currentSection); + + currentSection = null; + currentSectionRows = []; + } + }; + + for (const entry of results.slice(1)) { + if (entry instanceof HomepageLayout) { + throw new Error(`Expected only one 'Homepage' document in total`); + } else if (entry instanceof HomepageLayoutSection) { + closeCurrentSection(); + currentSection = entry; + } else if (entry instanceof HomepageLayoutRow) { + if (currentSection) { + currentSectionRows.push(entry); + } else { + throw new Error(`Expected a 'Section' document to add following rows into`); + } + } + } + + closeCurrentSection(); + + homepageLayout.sections = sections; + }, + }); +} |