Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Networked tags! #291

Open
wants to merge 33 commits into
base: preview
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c31eb43
data: draft art tags Two
towerofnix Oct 2, 2023
7ee9746
data: add various art tag properties
towerofnix Oct 2, 2023
cd95744
data: Tag.extraReadingURLs
towerofnix Oct 4, 2023
a6ecbca
content: generateCoverGrid: add "classes" slot
towerofnix Oct 2, 2023
d752643
content: generateArtTagGalleryPage: use generateQuickDescription
towerofnix Oct 2, 2023
e0ac333
content: generateArtTagGalleryPage: misc. additions & updates
towerofnix Oct 2, 2023
fb3619d
content: generateArtTagGalleryPage: minor tweaks
towerofnix Oct 3, 2023
cd4a0e9
support art tag info pages; ensure "art tag" terminology everywhere
towerofnix Oct 4, 2023
6790bf9
content: fix misspelled option in artTagGalleryPage.descendsFrom
towerofnix Jan 3, 2024
65d6c9f
content: generateArtTagInfoPage (stub, mostly)
towerofnix Oct 4, 2023
cc6ea6a
content: linkArtTagDynamically
towerofnix Oct 4, 2023
2414ab5
content: generateArtTagInfoPage: misc. updates
towerofnix Oct 4, 2023
eb5d59c
content, data: experimental art tag sidebar
towerofnix Oct 6, 2023
f62f8bb
content: generateArtTagSidebar: combine boxes into one
towerofnix Oct 6, 2023
39552e3
content: generateArtTagSidebar: list current tag's descendants
towerofnix Oct 6, 2023
eb2c87b
css: higher contrast in tree-list art tag sidebar
towerofnix Oct 6, 2023
9b07332
content: generateArtTagInfoPage: descendant gallery links
towerofnix Oct 6, 2023
9fc0837
content: generateArtTagGalleryPage: stub message for yet unfeatured
towerofnix Oct 6, 2023
8767400
content: generateArtTagGalleryPage: reading links
towerofnix Oct 9, 2023
331eab6
content: listTagsBy{Name,Uses} -> listArtTagsBy{Name,Uses}
towerofnix Oct 8, 2023
a2f9478
content: listArtTagNetwork
towerofnix Oct 14, 2023
e22db02
content: listArtTagNetwork: minor optimization
towerofnix Oct 14, 2023
2acfe6f
content, css: listArtTagNetwork: style tweaks
towerofnix Oct 14, 2023
0252116
content, client, css: tag gallery: showing all / direct / indirect
towerofnix Oct 14, 2023
2ee78e0
content: generateArtTagSidebar: hide sidebar without any details
towerofnix Jan 14, 2024
6eab069
content, client: listArtTagNetwork: art tag stat switcher
towerofnix Mar 19, 2024
d1b1264
content, css: listArtTagNetwork: right-align shenanigans (wip)
towerofnix Mar 19, 2024
ea8d7b3
css: art tag network center align shenanigans
towerofnix Mar 19, 2024
9c1c757
content: listArtTagNetwork: fix up "jump to" wrapping
towerofnix Mar 19, 2024
9cf0312
css: tweak art tag network elment placements
towerofnix Mar 19, 2024
8168560
content: listArtTagNetwork: descendants (leaves only) stat
towerofnix Mar 19, 2024
33240ef
content: listArtTagNetwork: more natural total uses stat
towerofnix Mar 19, 2024
16c9fb3
css: fix up top-level center align in art tag network stats
towerofnix Mar 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"#composite/wiki-data": "./src/data/composite/wiki-data/index.js",
"#composite/wiki-properties": "./src/data/composite/wiki-properties/index.js",
"#composite/things/album": "./src/data/composite/things/album/index.js",
"#composite/things/art-tag": "./src/data/composite/things/art-tag/index.js",
"#composite/things/artist": "./src/data/composite/things/artist/index.js",
"#composite/things/contribution": "./src/data/composite/things/contribution/index.js",
"#composite/things/flash": "./src/data/composite/things/flash/index.js",
Expand Down
128 changes: 128 additions & 0 deletions src/content/dependencies/generateArtTagAncestorDescendantMapList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {filterMultipleArrays, sortMultipleArrays, stitchArrays} from '#sugar';

export default {
contentDependencies: ['linkArtTagDynamically'],
extraDependencies: ['html', 'language'],

// Recursion ain't too pretty!

query(ancestorArtTag, targetArtTag) {
const recursive = artTag => {
const artTags =
artTag.directDescendantArtTags.slice();

const displayBriefly =
!artTags.includes(targetArtTag) &&
artTags.length > 3;

const artTagsIncludeTargetArtTag =
artTags.map(artTag => artTag.allDescendantArtTags.includes(targetArtTag));

const numExemptArtTags =
(displayBriefly
? artTagsIncludeTargetArtTag
.filter(includesTargetArtTag => !includesTargetArtTag)
.length
: null);

const sublists =
stitchArrays({
artTag: artTags,
includesTargetArtTag: artTagsIncludeTargetArtTag,
}).map(({artTag, includesTargetArtTag}) =>
(includesTargetArtTag
? recursive(artTag)
: null));

if (displayBriefly) {
filterMultipleArrays(artTags, sublists,
(artTag, sublist) =>
artTag === targetArtTag ||
sublist !== null);
} else {
sortMultipleArrays(artTags, sublists,
(artTagA, artTagB, sublistA, sublistB) =>
(sublistA && sublistB
? 0
: !sublistA && !sublistB
? 0
: sublistA
? 1
: -1));
}

return {
displayBriefly,
numExemptArtTags,
artTags,
sublists,
};
};

return {root: recursive(ancestorArtTag)};
},

relations(relation, query, _ancestorArtTag, _targetArtTag) {
const recursive = ({artTags, sublists}) => ({
artTagLinks:
artTags
.map(artTag => relation('linkArtTagDynamically', artTag)),

sublists:
sublists
.map(sublist => (sublist ? recursive(sublist) : null)),
});

return {root: recursive(query.root)};
},

data(query, _ancestorArtTag, targetArtTag) {
const recursive = ({displayBriefly, numExemptArtTags, artTags, sublists}) => ({
displayBriefly,
numExemptArtTags,

artTagsAreTargetTag:
artTags
.map(artTag => artTag === targetArtTag),

sublists:
sublists
.map(sublist => (sublist ? recursive(sublist) : null)),
});

return {root: recursive(query.root)};
},

generate(data, relations, {html, language}) {
const recursive = (dataNode, relationsNode) =>
html.tag('dl', {class: dataNode === data.root && 'tree-list'}, [
dataNode.displayBriefly &&
html.tag('dt',
language.$('artTagPage.sidebar.otherTagsExempt', {
tags:
language.countArtTags(dataNode.numExemptArtTags, {unit: true}),
})),

stitchArrays({
isTargetTag: dataNode.artTagsAreTargetTag,
dataSublist: dataNode.sublists,

artTagLink: relationsNode.artTagLinks,
relationsSublist: relationsNode.sublists,
}).map(({
isTargetTag, dataSublist,
artTagLink, relationsSublist,
}) => [
html.tag('dt',
{class: (dataSublist || isTargetTag) && 'current'},
artTagLink),

dataSublist &&
html.tag('dd',
recursive(dataSublist, relationsSublist)),
]),
]);

return recursive(data.root, relations.root);
},
};
177 changes: 132 additions & 45 deletions src/content/dependencies/generateArtTagGalleryPage.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import {sortAlbumsTracksChronologically} from '#sort';
import {stitchArrays} from '#sugar';
import {empty, stitchArrays, unique} from '#sugar';

export default {
contentDependencies: [
'generateArtTagGalleryPageFeaturedLine',
'generateArtTagGalleryPageShowingLine',
'generateArtTagNavLinks',
'generateCoverGrid',
'generatePageLayout',
'generateQuickDescription',
'image',
'linkAlbum',
'linkArtTag',
'linkArtTagGallery',
'linkExternal',
'linkTrack',
],

Expand All @@ -19,74 +24,114 @@ export default {
};
},

query(sprawl, tag) {
const things = tag.taggedInThings.slice();
query(sprawl, artTag) {
const directThings = artTag.directlyTaggedInThings;
const indirectThings = artTag.indirectlyTaggedInThings;
const allThings = unique([...directThings, ...indirectThings]);

sortAlbumsTracksChronologically(things, {
sortAlbumsTracksChronologically(allThings, {
getDate: thing => thing.coverArtDate ?? thing.date,
latestFirst: true,
});

return {things};
return {directThings, indirectThings, allThings};
},

relations(relation, query, sprawl, tag) {
relations(relation, query, sprawl, artTag) {
const relations = {};

relations.layout =
relation('generatePageLayout');

relations.artTagMainLink =
relation('linkArtTag', tag);
relations.navLinks =
relation('generateArtTagNavLinks', artTag);

relations.quickDescription =
relation('generateQuickDescription', artTag);

relations.featuredLine =
relation('generateArtTagGalleryPageFeaturedLine');

relations.showingLine =
relation('generateArtTagGalleryPageShowingLine');

if (!empty(artTag.extraReadingURLs)) {
relations.extraReadingLinks =
artTag.extraReadingURLs
.map(url => relation('linkExternal', url));
}

if (!empty(artTag.directAncestorArtTags)) {
relations.ancestorLinks =
artTag.directAncestorArtTags
.map(artTag => relation('linkArtTagGallery', artTag));
}

if (!empty(artTag.directDescendantArtTags)) {
relations.descendantLinks =
artTag.directDescendantArtTags
.map(artTag => relation('linkArtTagGallery', artTag));
}

relations.coverGrid =
relation('generateCoverGrid');

relations.links =
query.things.map(thing =>
(thing.album
? relation('linkTrack', thing)
: relation('linkAlbum', thing)));
query.allThings
.map(thing =>
(thing.album
? relation('linkTrack', thing)
: relation('linkAlbum', thing)));

relations.images =
query.things.map(thing =>
relation('image', thing.artTags));
query.allThings
.map(thing => relation('image', thing.artTags));

return relations;
},

data(query, sprawl, tag) {
data(query, sprawl, artTag) {
const data = {};

data.enableListings = sprawl.enableListings;

data.name = tag.name;
data.color = tag.color;
data.name = artTag.name;
data.color = artTag.color;

data.numArtworks = query.things.length;
data.numArtworksIndirectly = query.indirectThings.length;
data.numArtworksDirectly = query.directThings.length;
data.numArtworksTotal = query.allThings.length;

data.names =
query.things.map(thing => thing.name);
query.allThings.map(thing => thing.name);

data.paths =
query.things.map(thing =>
query.allThings.map(thing =>
(thing.album
? ['media.trackCover', thing.album.directory, thing.directory, thing.coverArtFileExtension]
: ['media.albumCover', thing.directory, thing.coverArtFileExtension]));

data.dimensions =
query.things.map(thing => thing.coverArtDimensions);
query.allThings.map(thing => thing.coverArtDimensions);

data.coverArtists =
query.things.map(thing =>
query.allThings.map(thing =>
thing.coverArtistContribs
.map(({artist}) => artist.name));

data.onlyFeaturedIndirectly =
query.allThings.map(thing =>
!query.directThings.includes(thing));

data.hasMixedDirectIndirect =
data.onlyFeaturedIndirectly.includes(true) &&
data.onlyFeaturedIndirectly.includes(false);

return data;
},

generate: (data, relations, {html, language}) =>
language.encapsulate('tagPage', pageCapsule =>
language.encapsulate('artTagGalleryPage', pageCapsule =>
relations.layout.slots({
title:
language.$(pageCapsule, 'title', {
Expand All @@ -99,17 +144,71 @@ export default {

mainClasses: ['top-index'],
mainContent: [
html.tag('p', {class: 'quick-info'},
language.$(pageCapsule, 'infoLine', {
coverArts: language.countCoverArts(data.numArtworks, {
unit: true,
relations.quickDescription.slots({
extraReadingLinks: relations.extraReadingLinks ?? null,
}),

data.numArtworksTotal === 0 &&
html.tag('p', {class: 'quick-info'},
language.encapsulate(pageCapsule, 'featuredLine.notFeatured', capsule => [
language.$(capsule),
html.tag('br'),
language.$(capsule, 'callToAction'),
])),

relations.featuredLine.clone()
.slots({
showing: 'all',
count: data.numArtworksTotal,
}),

data.hasMixedDirectIndirect && [
relations.featuredLine.clone()
.slots({
showing: 'direct',
count: data.numArtworksDirectly,
}),

relations.featuredLine.clone()
.slots({
showing: 'indirect',
count: data.numArtworksIndirectly,
}),
})),
],

relations.ancestorLinks &&
html.tag('p', {class: 'quick-info'},
language.$(pageCapsule, 'descendsFrom', {
tags: language.formatConjunctionList(relations.ancestorLinks),
})),

relations.descendantLinks &&
html.tag('p', {class: 'quick-info'},
language.$(pageCapsule, 'descendants', {
tags: language.formatUnitList(relations.descendantLinks),
})),

data.hasMixedDirectIndirect && [
relations.showingLine.clone()
.slot('showing', 'all'),

relations.showingLine.clone()
.slot('showing', 'direct'),

relations.showingLine.clone()
.slot('showing', 'indirect'),
],

relations.coverGrid
.slots({
links: relations.links,
names: data.names,
lazy: 12,

classes:
data.onlyFeaturedIndirectly.map(onlyFeaturedIndirectly =>
(onlyFeaturedIndirectly ? 'featured-indirectly' : '')),

images:
stitchArrays({
image: relations.images,
Expand All @@ -132,21 +231,9 @@ export default {
],

navLinkStyle: 'hierarchical',
navLinks: [
{auto: 'home'},

data.enableListings &&
{
path: ['localized.listingIndex'],
title: language.$('listingIndex.title'),
},

{
html:
language.$(pageCapsule, 'nav.tag', {
tag: relations.artTagMainLink,
}),
},
],
navLinks:
relations.navLinks
.slot('currentExtra', 'gallery')
.content,
})),
};
Loading