From db8f05dfb49e0774ff8cc17252facde6248d455a Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 14 Apr 2023 00:53:55 -0300 Subject: quick tweaks for site release (limit 4 icons per artist) --- src/misc-templates.js | 7 +++---- src/static/site3.css | 4 ++-- src/upd8.js | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/misc-templates.js b/src/misc-templates.js index 867193c7..b7c64597 100644 --- a/src/misc-templates.js +++ b/src/misc-templates.js @@ -104,9 +104,9 @@ function unbound_getArtistString(artists, { class: 'icons' }, language.formatUnitList( - urls.map(url => iconifyURL(url, {language})))); + urls.slice(0, 4).map(url => iconifyURL(url, {language})))); - return ( + return html.tag('span', {class: 'nowrap'}, (hasContribPart ? (hasExternalPart ? language.$('misc.artistLink.withContribution.withExternalLinks', { @@ -125,8 +125,7 @@ function unbound_getArtistString(artists, { }) : language.$('misc.artistLink', { artist: artistLink, - }))) - ); + })))); })); } diff --git a/src/static/site3.css b/src/static/site3.css index 80624758..3ebe782d 100644 --- a/src/static/site3.css +++ b/src/static/site3.css @@ -1537,12 +1537,12 @@ html[data-language-code="preview-en"][data-url-key="localized.home"] #content z-index: 2; } - html[data-url-key="localized.home"] .layout-columns.has-one-sidebar .grid-listing > .grid-item:not(:nth-child(n+10)) { + html[data-url-key="localized.home"] .layout-columns.has-one-sidebar .grid-listing > .grid-item:not(:nth-child(n+7)) { flex-basis: 23%; margin: 15px; } - html[data-url-key="localized.home"] .layout-columns.has-one-sidebar .grid-listing > .grid-item:nth-child(n+10) { + html[data-url-key="localized.home"] .layout-columns.has-one-sidebar .grid-listing > .grid-item:nth-child(n+7) { flex-basis: 18%; margin: 10px; } diff --git a/src/upd8.js b/src/upd8.js index 9fff67cc..9f54b3bb 100755 --- a/src/upd8.js +++ b/src/upd8.js @@ -87,7 +87,7 @@ import FileSizePreloader from './file-size-preloader.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const CACHEBUST = 19; +const CACHEBUST = 20; let COMMIT; try { -- cgit 1.3.0-6-gf8a5 From 7233eeffbbb5fe02113ea7e18322eaeec520f79e Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 27 Apr 2023 15:19:16 -0300 Subject: fix sticky heading not handling CW'd covers properly --- src/misc-templates.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc-templates.js b/src/misc-templates.js index b7c64597..39f597eb 100644 --- a/src/misc-templates.js +++ b/src/misc-templates.js @@ -979,7 +979,7 @@ function unbound_generateStickyHeadingContainer({ { class: [ 'content-sticky-heading-cover', - coverArtTags .some(tag => !tag.isContentWarning) && + coverArtTags.some(tag => tag.isContentWarning) && 'content-sticky-heading-cover-needs-reveal', ], }, -- cgit 1.3.0-6-gf8a5 From 878a96cb223783ef1b100fdb3bb9d795404c44f5 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 27 Apr 2023 15:39:55 -0300 Subject: sort art galleries reverse-chronologically (again) Fixes #170. --- src/page/artist.js | 2 +- src/util/wiki-data.js | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/page/artist.js b/src/page/artist.js index 87859c89..29e4aba6 100644 --- a/src/page/artist.js +++ b/src/page/artist.js @@ -40,7 +40,7 @@ export function write(artist, {wikiData}) { ...(artist.albumsAsCoverArtist ?? []), ...(artist.tracksAsCoverArtist ?? []), ], - {getDate: (o) => o.coverArtDate}); + {latestFirst: true, getDate: (o) => o.coverArtDate}); const commentaryThings = sortAlbumsTracksChronologically([ ...(artist.albumsAsCommentator ?? []), diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js index 0eb86a1e..5a0e241a 100644 --- a/src/util/wiki-data.js +++ b/src/util/wiki-data.js @@ -316,6 +316,7 @@ export function sortChronologically(data, { // // This function also works for data lists which contain only tracks. export function sortAlbumsTracksChronologically(data, { + latestFirst = false, getDate, } = {}) { // Sort albums before tracks... @@ -333,7 +334,18 @@ export function sortAlbumsTracksChronologically(data, { // released on the same date, they'll still be grouped together by album, // and tracks within an album will retain their relative positioning (i.e. // stay in the same order as part of the album's track listing). - sortByDate(data, {getDate}); + + if (latestFirst) { + // Like in sortChronologically, double reverse: Since we reverse after + // sorting by date, also reverse before, so that items with the same date + // are flipped relative to each other twice - that maintains the original + // relative ordering! + data.reverse(); + sortByDate(data, {getDate}); + data.reverse(); + } else { + sortByDate(data, {getDate}); + } return data; } -- cgit 1.3.0-6-gf8a5 From 7e0dfb0f797b6dabad4a4491ef8e7333cc199926 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 27 Apr 2023 16:03:04 -0300 Subject: data: track: null coverArtistContribs if hasTrackArt false Fixes #178. This commit also cleans up the documentation for the utility used here, dynamicInheritContribs. These are the only two uses of that utility at all but like, code comments very rarely hurt and d'accord are probably even more useful here lol --- src/data/things/thing.js | 26 +++++++++++++++++++++----- src/data/things/track.js | 2 ++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/data/things/thing.js b/src/data/things/thing.js index 5ab15c0e..9c59436e 100644 --- a/src/data/things/thing.js +++ b/src/data/things/thing.js @@ -262,26 +262,42 @@ export default class Thing extends CacheableObject { // Dynamically inherit a contribution list from some other object, if it // hasn't been overridden on this object. This is handy for solo albums // where all tracks have the same artist, for example. - // - // Note: The arguments of this function aren't currently final! The final - // format will look more like (contribsByRef, parentContribsByRef), e.g. - // ('artistContribsByRef', '@album/artistContribsByRef'). dynamicInheritContribs: ( + // If this property is explicitly false, the contribution list returned + // will always be empty. + nullerProperty, + + // Property holding contributions on the current object. contribsByRefProperty, + + // Property holding corresponding "default" contributions on the parent + // object, which will fallen back to if the object doesn't have its own + // contribs. parentContribsByRefProperty, + + // Data array to search in and "find" function to locate parent object + // (which will be passed the child object and the wiki data array). thingDataProperty, findFn ) => ({ flags: {expose: true}, expose: { - dependencies: [contribsByRefProperty, thingDataProperty, 'artistData'], + dependencies: [ + contribsByRefProperty, + thingDataProperty, + nullerProperty, + 'artistData', + ].filter(Boolean), + compute({ [Thing.instance]: thing, + [nullerProperty]: nuller, [contribsByRefProperty]: contribsByRef, [thingDataProperty]: thingData, artistData, }) { if (!artistData) return []; + if (nuller === false) return []; const refs = contribsByRef ?? findFn(thing, thingData, {mode: 'quiet'})?.[parentContribsByRefProperty]; diff --git a/src/data/things/track.js b/src/data/things/track.js index 1c2013a2..00585c1e 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -245,6 +245,7 @@ export class Track extends Thing { }, artistContribs: Thing.common.dynamicInheritContribs( + null, 'artistContribsByRef', 'artistContribsByRef', 'albumData', @@ -254,6 +255,7 @@ export class Track extends Thing { contributorContribs: Thing.common.dynamicContribs('contributorContribsByRef'), coverArtistContribs: Thing.common.dynamicInheritContribs( + 'hasCoverArt', 'coverArtistContribsByRef', 'trackCoverArtistContribsByRef', 'albumData', -- cgit 1.3.0-6-gf8a5 From 3a322d96666b8da2b615ffd1c245f3a2f3d0cd90 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 27 Apr 2023 16:16:53 -0300 Subject: data: refactor sortByDate to handle latestFirst directly Fixes #180. This enables sortByDate to keep dateless items at the end even when sorting with latest first, and conveniently reduces the ops since there's no need for .reverse() before and after the sort anymore. It also cleans logic by deduplicating latest-first code in compositional sort functions using sortByDate. --- src/util/wiki-data.js | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js index 5a0e241a..7a3f4144 100644 --- a/src/util/wiki-data.js +++ b/src/util/wiki-data.js @@ -181,6 +181,7 @@ export function sortByName(data, { } export function sortByDate(data, { + latestFirst = false, getDate = (o) => o.date, } = {}) { return data.sort((a, b) => { @@ -191,7 +192,7 @@ export function sortByDate(data, { // together in the same array. If that's the case, we put all items // without dates at the end. if (ad && bd) { - return ad - bd; + return (latestFirst ? bd - ad : ad - bd); } else if (ad) { return -1; } else if (bd) { @@ -292,18 +293,8 @@ export function sortChronologically(data, { getName, getDate, } = {}) { - if (latestFirst) { - // Double reverse: Since we reverse after sorting by date, also reverse - // after sorting A-Z, so the second reverse restores A-Z relative - // positioning (for entries with the same date). - sortAlphabetically(data, {getDirectory, getName}); - data.reverse(); - sortByDate(data, {getDate}); - data.reverse(); - } else { - sortAlphabetically(data, {getDirectory, getName}); - sortByDate(data, {getDate}); - } + sortAlphabetically(data, {getDirectory, getName}); + sortByDate(data, {latestFirst, getDate}); return data; } @@ -334,18 +325,7 @@ export function sortAlbumsTracksChronologically(data, { // released on the same date, they'll still be grouped together by album, // and tracks within an album will retain their relative positioning (i.e. // stay in the same order as part of the album's track listing). - - if (latestFirst) { - // Like in sortChronologically, double reverse: Since we reverse after - // sorting by date, also reverse before, so that items with the same date - // are flipped relative to each other twice - that maintains the original - // relative ordering! - data.reverse(); - sortByDate(data, {getDate}); - data.reverse(); - } else { - sortByDate(data, {getDate}); - } + sortByDate(data, {latestFirst, getDate}); return data; } -- cgit 1.3.0-6-gf8a5 From 6128ba16c1b5c4c6095e0ddba0977817cce4bc6e Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 27 Apr 2023 16:55:06 -0300 Subject: data: new sortByPositionInFlash act function Fixes #168. This refactors the duplicated logic with sortByPositionInAlbum into a new template, sortByPositionInParent. --- src/data/yaml.js | 2 ++ src/listing-spec.js | 3 +- src/misc-templates.js | 3 ++ src/page/artist.js | 4 +-- src/page/track.js | 4 +-- src/util/wiki-data.js | 83 ++++++++++++++++++++++++++++++++++++++++----------- 6 files changed, 77 insertions(+), 22 deletions(-) diff --git a/src/data/yaml.js b/src/data/yaml.js index 1b1195ea..de0b506b 100644 --- a/src/data/yaml.js +++ b/src/data/yaml.js @@ -24,6 +24,7 @@ import { sortAlbumsTracksChronologically, sortAlphabetically, sortChronologically, + sortFlashesChronologically, } from '../util/wiki-data.js'; import find, {bindFind} from '../util/find.js'; @@ -1155,6 +1156,7 @@ export function sortWikiDataArrays(wikiData) { Object.assign(wikiData, { albumData: sortChronologically(wikiData.albumData.slice()), trackData: sortAlbumsTracksChronologically(wikiData.trackData.slice()), + flashData: sortFlashesChronologically(wikiData.flashData.slice()), }); // Re-link data arrays, so that every object has the new, sorted versions. diff --git a/src/listing-spec.js b/src/listing-spec.js index 08799f2f..36637ee0 100644 --- a/src/listing-spec.js +++ b/src/listing-spec.js @@ -12,6 +12,7 @@ import { sortAlphabetically, sortByDate, sortChronologically, + sortFlashesChronologically, } from './util/wiki-data.js'; const listingSpec = []; @@ -775,7 +776,7 @@ listingSpec.push({ wikiInfo.enableFlashesAndGames, data: ({wikiData: {flashData}}) => - sortChronologically(flashData.slice()) + sortFlashesChronologically(flashData.slice()) .map(flash => ({ flash, tracks: flash.featuredTracks, diff --git a/src/misc-templates.js b/src/misc-templates.js index 39f597eb..8f3f0166 100644 --- a/src/misc-templates.js +++ b/src/misc-templates.js @@ -16,6 +16,7 @@ import { getTotalDuration, sortAlbumsTracksChronologically, sortChronologically, + sortFlashesChronologically, } from './util/wiki-data.js'; const BANDCAMP_DOMAINS = ['bc.s3m.us', 'music.solatrux.com']; @@ -165,6 +166,8 @@ function unbound_generateChronologyLinks(currentThing, { const things = ( thingsUnsorted.every(t => t instanceof T.Album || t instanceof T.Track) ? sortAlbumsTracksChronologically(...args) + : thingsUnsorted.every(t => t instanceof T.Flash) + ? sortFlashesChronologically(...args) : sortChronologically(...args)); if (things.length === 0) return ''; diff --git a/src/page/artist.js b/src/page/artist.js index 29e4aba6..4ef44d32 100644 --- a/src/page/artist.js +++ b/src/page/artist.js @@ -12,7 +12,7 @@ import { chunkByProperties, getTotalDuration, sortAlbumsTracksChronologically, - sortChronologically, + sortFlashesChronologically, } from '../util/wiki-data.js'; export const description = `per-artist info & artwork gallery pages`; @@ -129,7 +129,7 @@ export function write(artist, {wikiData}) { let flashes, flashListChunks; if (wikiInfo.enableFlashesAndGames) { - flashes = sortChronologically(artist.flashesAsContributor.slice()); + flashes = sortFlashesChronologically(artist.flashesAsContributor.slice()); flashListChunks = chunkByProperties( flashes.map((flash) => ({ act: flash.act, diff --git a/src/page/track.js b/src/page/track.js index 7f0d1cf2..b6b03f35 100644 --- a/src/page/track.js +++ b/src/page/track.js @@ -16,7 +16,7 @@ import { import { getTrackCover, getAlbumListTag, - sortChronologically, + sortFlashesChronologically, } from '../util/wiki-data.js'; export const description = `per-track info pages`; @@ -42,7 +42,7 @@ export function write(track, {wikiData}) { let flashesThatFeature; if (wikiInfo.enableFlashesAndGames) { - flashesThatFeature = sortChronologically( + flashesThatFeature = sortFlashesChronologically( [track, ...otherReleases].flatMap((track) => track.featuredInFlashes.map((flash) => ({ flash, diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js index 7a3f4144..2a8f12ca 100644 --- a/src/util/wiki-data.js +++ b/src/util/wiki-data.js @@ -207,35 +207,52 @@ export function sortByDate(data, { }); } -export function sortByPositionInAlbum(data) { +export function sortByPositionInParent(data, { + getParent, + getChildren, +}) { return data.sort((a, b) => { - const aa = a.album; - const ba = b.album; + const parentA = getParent(a); + const parentB = getParent(b); - // Don't change the sort when the two tracks are from separate albums. - // This function doesn't change the order of albums or try to "merge" - // two separated chunks of tracks from the same album together. - if (aa !== ba) { + // Don't change the sort when the two items are from separate parents. + // This function doesn't change the order of parents or try to "merge" + // two separated chunks of items from the same parent together. + if (parentA !== parentB) { return 0; } - // Don't change the sort when only one (or neither) item is actually - // a track (i.e. has an album). - if (!aa || !ba) { + // Don't change the sort when either (or both) of the items doesn't + // even have a parent (e.g. it's the passed data is a mixed array of + // children and parents). + if (!parentA || !parentB) { return 0; } - const ai = aa.tracks.indexOf(a); - const bi = ba.tracks.indexOf(b); + const indexA = getChildren(parentA).indexOf(a); + const indexB = getChildren(parentB).indexOf(b); - // There's no reason this two-way reference (a track's album and the - // album's track list) should be broken, but if for any reason it is, - // don't change the sort. - if (ai === -1 || bi === -1) { + // If the getParent/getChildren relationship doesn't go both ways for + // some reason, don't change the sort. + if (indexA === -1 || indexB === -1) { return 0; } - return ai - bi; + return indexA - indexB; + }); +} + +export function sortByPositionInAlbum(data) { + return sortByPositionInParent(data, { + getParent: track => track.album, + getChildren: album => album.tracks, + }); +} + +export function sortByPositionInFlashAct(data) { + return sortByPositionInParent(data, { + getParent: flash => flash.act, + getChildren: act => act.flashes, }); } @@ -330,6 +347,38 @@ export function sortAlbumsTracksChronologically(data, { return data; } +export function sortFlashesChronologically(data, { + latestFirst = false, + getDate, +} = {}) { + // Flash acts don't actually have any identifying properties because they + // don't have dedicated pages (yet), so don't have a directory. Make up a + // fake key identifying them so flashes can be grouped together. + const flashActs = new Set(data.map(flash => flash.act)); + const flashActIdentifiers = new Map(); + + let counter = 0; + for (const act of flashActs) { + flashActIdentifiers.set(act, ++counter); + } + + // Group flashes by act... + data.sort((a, b) => { + return flashActIdentifiers.get(a.act) - flashActIdentifiers.get(b.act); + }); + + // Sort flashes by position in act... + sortByPositionInFlashAct(data); + + // ...and finally sort by date. If flashes from more than one act were + // released on the same date, they'll still be grouped together by act, + // and flashes within an act will retain their relative positioning (i.e. + // stay in the same order as the act's flash listing). + sortByDate(data, {latestFirst, getDate}); + + return data; +} + // Specific data utilities export function filterAlbumsByCommentary(albums) { -- cgit 1.3.0-6-gf8a5 From 7830c73e6047ab8ec1322c4a56ed6a450bfb11e6 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 27 Apr 2023 16:57:09 -0300 Subject: data: make sortByConditions return sorted array This wasn't causing any bugs within the codebase but it should be consistent with the rest of the sort functions anyway. --- src/util/wiki-data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js index 2a8f12ca..89c621c5 100644 --- a/src/util/wiki-data.js +++ b/src/util/wiki-data.js @@ -260,7 +260,7 @@ export function sortByPositionInFlashAct(data) { // set of arbitrary given conditions is true first. If no conditions are met // for a given item, it's moved over to the end! export function sortByConditions(data, conditions) { - data.sort((a, b) => { + return data.sort((a, b) => { const ai = conditions.findIndex((f) => f(a)); const bi = conditions.findIndex((f) => f(b)); -- cgit 1.3.0-6-gf8a5