diff options
| author | (quasar) nebula <qznebula@protonmail.com> | 2026-05-11 19:06:52 -0300 |
|---|---|---|
| committer | (quasar) nebula <qznebula@protonmail.com> | 2026-05-11 19:10:31 -0300 |
| commit | 1af00437b5f4397b0338ca1a64cf36e8c26cfb68 (patch) | |
| tree | 1693c6d71e1736c1788e7a2186ccad6d3d61d15a | |
| parent | 657e1c1e447ad8939d2ad9286af00be52975f791 (diff) | |
content, css, data: Track.nameDetail
| -rw-r--r-- | src/content/dependencies/generateAlbumSidebarTrackSection.js | 37 | ||||
| -rw-r--r-- | src/content/dependencies/generateAlbumTrackListItem.js | 1 | ||||
| -rw-r--r-- | src/content/dependencies/generatePageLayout.js | 87 | ||||
| -rw-r--r-- | src/content/dependencies/generatePageTitleText.js | 27 | ||||
| -rw-r--r-- | src/content/dependencies/generateTrackInfoPage.js | 6 | ||||
| -rw-r--r-- | src/content/dependencies/generateTrackList.js | 6 | ||||
| -rw-r--r-- | src/content/dependencies/generateTrackListItem.js | 17 | ||||
| -rw-r--r-- | src/content/dependencies/generateTrackNavLinks.js | 25 | ||||
| -rw-r--r-- | src/data/things/Track.js | 3 | ||||
| -rw-r--r-- | src/static/css/miscellany.css | 5 | ||||
| -rw-r--r-- | src/static/css/page.css | 14 | ||||
| -rw-r--r-- | src/strings-default.yaml | 44 |
12 files changed, 221 insertions, 51 deletions
diff --git a/src/content/dependencies/generateAlbumSidebarTrackSection.js b/src/content/dependencies/generateAlbumSidebarTrackSection.js index 3ceab866..97941698 100644 --- a/src/content/dependencies/generateAlbumSidebarTrackSection.js +++ b/src/content/dependencies/generateAlbumSidebarTrackSection.js @@ -40,6 +40,10 @@ export default { trackSection.tracks .map(track => track.directory); + data.trackNameDetails = + trackSection.tracks + .map(track => track.nameDetail); + data.tracksAreMissingCommentary = trackSection.tracks .map(track => empty(track.commentary)); @@ -83,11 +87,13 @@ export default { stitchArrays({ trackLink: relations.trackLinks, directory: data.trackDirectories, + nameDetail: data.trackNameDetails, isCurrentTrack: data.tracksAreCurrentTrack, missingCommentary: data.tracksAreMissingCommentary, }).map(({ trackLink, directory, + nameDetail, isCurrentTrack, missingCommentary, }) => @@ -100,18 +106,25 @@ export default { missingCommentary && {class: 'no-commentary'}, - language.$(capsule, 'item', { - track: - (slots.mode === 'commentary' && missingCommentary - ? trackLink.slots({ - linkless: true, - }) - : slots.anchor - ? trackLink.slots({ - anchor: true, - hash: directory, - }) - : trackLink), + language.encapsulate(capsule, 'item', workingCapsule => { + const workingOptions = {track: trackLink}; + + if (slots.mode === 'commentary' && missingCommentary) { + trackLink.setSlots({linkless: true}); + } else if (slots.anchor) { + trackLink.setSlots({anchor: true, hash: directory}); + } + + if (nameDetail) { + workingCapsule += '.withDetail'; + workingOptions.detailAccent = + html.tag('span', {class: 'name-detail'}, + language.$(capsule, 'item.withDetail.accent', { + detail: language.sanitize(nameDetail), + })); + } + + return language.$(workingCapsule, workingOptions); }))); const list = diff --git a/src/content/dependencies/generateAlbumTrackListItem.js b/src/content/dependencies/generateAlbumTrackListItem.js index 68722a83..e72d49b8 100644 --- a/src/content/dependencies/generateAlbumTrackListItem.js +++ b/src/content/dependencies/generateAlbumTrackListItem.js @@ -41,6 +41,7 @@ export default { generate: (data, relations, slots) => relations.item.slots({ showArtists: 'auto', + showDetail: true, showDuration: (slots.collapseDurationScope === 'track' diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js index 300d256d..00e6422b 100644 --- a/src/content/dependencies/generatePageLayout.js +++ b/src/content/dependencies/generatePageLayout.js @@ -62,6 +62,11 @@ export default { mutable: false, }, + titleDetail: { + type: 'html', + mutable: false, + }, + showWikiNameInTitle: { validate: v => v.is(true, false, 'auto'), default: 'auto', @@ -274,40 +279,73 @@ export default { } })(); - const titleContentsHTML = - (html.isBlank(slots.title) - ? null - - : (!html.isBlank(slots.additionalNames) && - !html.resolve(slots.additionalNames, {slots: ['alwaysVisible']}) - .getSlotValue('alwaysVisible')) + const headingNamePart = + (() => { + if (html.isBlank(slots.title)) { + return html.blank(); + } + + if (!html.isBlank(slots.additionalNames)) { + const box = html.resolve(slots.additionalNames, {slots: ['alwaysVisible']}); + if (!box.getSlotValue('alwaysVisible')) { + return ( + html.tag('a', + {href: '#additional-names-box'}, + {title: language.$('misc.additionalNames.tooltip').toString()}, + language.sanitize(slots.title)) + ); + } + } + + return language.sanitize(slots.title); + })(); + + const headingContents = + language.encapsulate('misc.pageHeading', capsule => + language.encapsulate(capsule, workingCapsule => { + const workingOptions = { + [language.onlyIfOptions]: ['title'], + }; + + workingOptions.title = headingNamePart; + + if (!html.isBlank(slots.titleDetail)) { + workingCapsule += '.withDetail'; + workingOptions.detailAccent = + html.tag('span', {class: 'name-detail'}, + language.$(capsule, 'withDetail.accent', { + detail: slots.titleDetail, + })); + } - ? html.tag('a', { - href: '#additional-names-box', - title: language.$('misc.additionalNames.tooltip').toString(), - }, language.sanitize(slots.title)) + return language.$(workingCapsule, workingOptions); + })); - : language.sanitize(slots.title)); + const headingHTML = + (() => { + if (html.isBlank(headingContents)) { + return html.blank(); + } - const titleHTML = - (html.isBlank(slots.title) - ? null - : slots.headingMode === 'sticky' - ? [ + if (slots.headingMode === 'sticky') { + return [ relations.stickyHeadingContainer.slots({ - title: titleContentsHTML, + title: headingContents, cover: primaryCover, }), relations.stickyHeadingContainer.clone().slots({ rootAttributes: {inert: true}, }), - ] - : html.tag('h1', titleContentsHTML)); + ]; + } + + return html.tag('h1', headingContents); + })(); // TODO: There could be neat interactions with the sticky heading here, // but for now subtitle is totally separate. - const subtitleHTML = + const subheadingHTML = (html.isBlank(slots.subtitle) ? null : html.tag('h2', {class: 'page-subtitle'}, @@ -327,11 +365,11 @@ export default { html.tag('main', {id: 'content'}, {class: slots.mainClasses}, - !html.isBlank(subtitleHTML) && + !html.isBlank(subheadingHTML) && {class: 'has-subtitle'}, [ - titleHTML, + headingHTML, html.tag('div', {id: 'artwork-column'}, {[html.onlyIfContent]: true}, @@ -339,7 +377,7 @@ export default { slots.artworkColumnContent), - subtitleHTML, + subheadingHTML, slots.additionalNames, @@ -632,6 +670,7 @@ export default { relations.titleText.setSlots({ title: slots.title, + detail: slots.titleDetail, showWikiNameInTitle: slots.showWikiNameInTitle, subtitle: slots.subtitle, }); diff --git a/src/content/dependencies/generatePageTitleText.js b/src/content/dependencies/generatePageTitleText.js index 5482ca91..112112e6 100644 --- a/src/content/dependencies/generatePageTitleText.js +++ b/src/content/dependencies/generatePageTitleText.js @@ -14,6 +14,11 @@ export default { mutable: false, }, + detail: { + type: 'html', + mutable: false, + }, + showWikiNameInTitle: { validate: v => v.is(true, false, 'auto'), default: 'auto', @@ -38,9 +43,18 @@ export default { // so we wrap the title in a tag and pass it off as good to go. workingOptions.title = html.tags([ -striptags(slots.title.toString()), + striptags(slots.title.toString()), ]); + if (!html.isBlank(slots.detail)) { + // Same shenanigans here, as far as wrapping striptags goes. + workingCapsule += '.withDetail'; + workingOptions.detail = + html.tags([ + striptags(slots.detail.toString()), + ]); + } + if (!html.isBlank(slots.subtitle)) { // Same shenanigans here, as far as wrapping striptags goes. workingCapsule += '.withSubtitle'; @@ -52,10 +66,13 @@ striptags(slots.title.toString()), const showWikiName = (slots.showWikiNameInTitle === true -? true + ? true + : slots.showWikiNameInTitle === 'auto' -? html.isBlank(slots.subtitle) -: false); + ? html.isBlank(slots.subtitle) && + html.isBlank(slots.detail) + + : false); if (showWikiName) { workingCapsule += '.withWikiName'; @@ -64,4 +81,4 @@ striptags(slots.title.toString()), return language.$(workingCapsule, workingOptions); }), -}; \ No newline at end of file +}; diff --git a/src/content/dependencies/generateTrackInfoPage.js b/src/content/dependencies/generateTrackInfoPage.js index daba1ead..1d768cfc 100644 --- a/src/content/dependencies/generateTrackInfoPage.js +++ b/src/content/dependencies/generateTrackInfoPage.js @@ -143,6 +143,9 @@ export default { name: track.name, + nameDetail: + track.nameDetail, + color: track.color, @@ -167,6 +170,9 @@ export default { track: relations.name, }), + titleDetail: + language.sanitize(data.nameDetail), + headingMode: 'sticky', additionalNames: relations.additionalNamesBox, diff --git a/src/content/dependencies/generateTrackList.js b/src/content/dependencies/generateTrackList.js index c259c914..ddd3db8e 100644 --- a/src/content/dependencies/generateTrackList.js +++ b/src/content/dependencies/generateTrackList.js @@ -11,6 +11,11 @@ export default { default: 'auto', }, + showDetail: { + type: 'boolean', + default: true, + }, + showDuration: { type: 'boolean', default: false, @@ -29,6 +34,7 @@ export default { relations.items.map(item => item.slots({ showArtists: slots.showArtists, + showDetail: slots.showDetail, showDuration: slots.showDuration, colorMode: slots.colorMode, }))), diff --git a/src/content/dependencies/generateTrackListItem.js b/src/content/dependencies/generateTrackListItem.js index 383f0025..c1f6ff93 100644 --- a/src/content/dependencies/generateTrackListItem.js +++ b/src/content/dependencies/generateTrackListItem.js @@ -28,6 +28,9 @@ export default { date: track.date, + detail: + track.nameDetail, + duration: track.duration ?? 0, @@ -43,6 +46,11 @@ export default { default: 'auto', }, + showDetail: { + type: 'boolean', + default: false, + }, + // If true and the track doesn't have a duration, a missing-duration cue // will be displayed instead. showDuration: { @@ -116,6 +124,15 @@ export default { relations.trackLink .slot('color', slots.colorMode === 'track'); + if (data.detail && slots.showDetail) { + workingCapsule += '.withDetail'; + workingOptions.detailAccent = + html.tag('span', {class: 'name-detail'}, + language.$(itemCapsule, 'withDetail', 'accent', { + detail: language.sanitize(data.detail), + })); + } + const artists = language.encapsulate(itemCapsule, 'artists', artistsCapsule => { const chosenCredit = diff --git a/src/content/dependencies/generateTrackNavLinks.js b/src/content/dependencies/generateTrackNavLinks.js index d18e6cad..ec9f2130 100644 --- a/src/content/dependencies/generateTrackNavLinks.js +++ b/src/content/dependencies/generateTrackNavLinks.js @@ -16,6 +16,9 @@ export default { trackNumber: track.trackNumber, + + nameDetail: + track.nameDetail, }), slots: { @@ -54,17 +57,21 @@ export default { }), accent: - html.tag('a', - {[html.onlyIfContent]: true}, + language.formatUnitList([ + language.sanitize(data.nameDetail), + + html.tag('a', + {[html.onlyIfContent]: true}, - {href: ''}, - {class: 'current'}, + {href: ''}, + {class: 'current'}, - (slots.currentExtra === 'referenced-art' - ? language.$('referencedArtworksPage.subtitle') - : slots.currentExtra === 'referencing-art' - ? language.$('referencingArtworksPage.subtitle') - : null)), + (slots.currentExtra === 'referenced-art' + ? language.$('referencedArtworksPage.subtitle') + : slots.currentExtra === 'referencing-art' + ? language.$('referencingArtworksPage.subtitle') + : null)), + ]), }, ]), }; diff --git a/src/data/things/Track.js b/src/data/things/Track.js index 87383b55..79877edb 100644 --- a/src/data/things/Track.js +++ b/src/data/things/Track.js @@ -144,6 +144,8 @@ export class Track extends Thing { exposeConstant(V('normal')), ], + nameDetail: simpleString(), + directory: directory({ suffix: 'directorySuffix', }), @@ -944,6 +946,7 @@ export class Track extends Thing { 'Track Text': {property: 'nameText'}, 'Name Style': {property: 'nameStyle'}, + 'Name Detail': {property: 'nameDetail'}, 'Directory': {property: 'directory'}, 'Suffix Directory': {property: 'suffixDirectoryFromAlbum'}, diff --git a/src/static/css/miscellany.css b/src/static/css/miscellany.css index bbdd3a23..eb085693 100644 --- a/src/static/css/miscellany.css +++ b/src/static/css/miscellany.css @@ -69,6 +69,11 @@ color: var(--primary-color); } + .name-detail { + display: inline-block; + font-weight: normal; + } + .other-group-accent, .rerelease-line { opacity: 0.7; diff --git a/src/static/css/page.css b/src/static/css/page.css index fdd15358..7d5784f3 100644 --- a/src/static/css/page.css +++ b/src/static/css/page.css @@ -660,6 +660,14 @@ margin-bottom: 3px; } + .sidebar li .name-detail { + opacity: 0.85; + } + + .sidebar li.current .name-detail { + opacity: 1; + } + .sidebar > details.current summary { font-weight: 800; } @@ -789,6 +797,12 @@ font-size: 1.5em; } + #content h1 .name-detail { + opacity: 0.8; + margin-left: 0.5ch; + font-weight: inherit; + } + #content li { margin-bottom: 4px; } diff --git a/src/strings-default.yaml b/src/strings-default.yaml index da970b98..84fd1dc8 100644 --- a/src/strings-default.yaml +++ b/src/strings-default.yaml @@ -476,6 +476,12 @@ trackList: missing: "_:__" missing.info: "no duration provided; treated as zero seconds long" + withDetail: >- + {TRACK} {DETAIL_ACCENT} + + withDetail.accent: >- + ({DETAIL}) + withArtists: >- {TRACK} {ARTISTS} @@ -484,9 +490,18 @@ trackList: featuring: "feat. {ARTISTS}" by.featuring: "by {ARTISTS} feat. {FEATURING}" + withAccent.withDetail: >- + {ACCENT} {TRACK} {DETAIL_ACCENT} + withAccent.withArtists: >- {ACCENT} {TRACK} {ARTISTS} + withDetail.withArtists: >- + {TRACK} {DETAIL_ACCENT} {ARTISTS} + + withAccent.withDetail.withArtists: >- + {ACCENT} {TRACK} {DETAIL_ACCENT} {ARTISTS} + rerelease: >- {TRACK} (rerelease) @@ -866,22 +881,47 @@ misc: rollingWindow: "Rolling Window" # pageTitle: - # Title set under the page's <title> HTML element, which is + # Text set under the page's <title> HTML element, which is # displayed in the browser tab bar, bookmarks list, etc. pageTitle: _: >- {TITLE} + withDetail: >- + {TITLE} ({DETAIL}) + withSubtitle: >- {TITLE} - {SUBTITLE} withWikiName: >- {TITLE} | {WIKI_NAME} + withDetail.withSubtitle: >- + {TITLE} ({DETAIL}) - {SUBTITLE} + + withDetail.withWikiName: >- + {TITLE} ({DETAIL}) | {WIKI_NAME} + withSubtitle.withWikiName: >- {TITLE} - {SUBTITLE} | {WIKI_NAME} + withDetail.withSubtitle.withWikiName: >- + {TITLE} ({DETAIL}) - {SUBTITLE} | {WIKI_NAME} + + # pageHeading: + # Text set inside the page's <h1> HTML element, which is + # displayed at the top of the content area. + + pageHeading: + _: >- + {TITLE} + + withDetail: >- + {TITLE} {DETAIL_ACCENT} + + withDetail.accent: "({DETAIL})" + # search: # Strings to do with the search bar! @@ -1194,6 +1234,8 @@ homepage: albumSidebar: trackList: item: "{TRACK}" + item.withDetail: "{TRACK} {DETAIL_ACCENT}" + item.withDetail.accent: "({DETAIL})" # fallbackSectionName: # If an album's track list isn't sectioned, the track list here |