@turnipxenon/pineapple 2.4.32 → 2.4.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/workspace.xml +33 -29
- package/.svelte-kit/__package__/components/navigation_component/NavigationComponent.svelte +5 -3
- package/.svelte-kit/__package__/components/navigation_component/NavigationComponent.svelte.d.ts +2 -0
- package/.svelte-kit/__package__/components/navigation_component/PageMeta.d.ts +44 -10
- package/.svelte-kit/__package__/components/navigation_component/PageMeta.js +75 -23
- package/.svelte-kit/generated/server/internal.js +1 -1
- package/dist/components/navigation_component/NavigationComponent.svelte +5 -3
- package/dist/components/navigation_component/NavigationComponent.svelte.d.ts +2 -0
- package/dist/components/navigation_component/PageMeta.d.ts +44 -10
- package/dist/components/navigation_component/PageMeta.js +75 -23
- package/package.json +1 -1
- package/src/lib/components/navigation_component/NavigationComponent.svelte +5 -3
- package/src/lib/components/navigation_component/PageMeta.ts +120 -34
- package/src/routes/(pineapple)/pineapple/(extra-pages)/ImageMap.ts +5 -0
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page1/+page.svelte +0 -5
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page1/meta.json +14 -0
- package/src/routes/(pineapple)/pineapple/(extra-pages)/page2/meta.json +8 -0
- package/src/routes/(pineapple)/pineapple/+page.svelte +5 -1
- package/vite.config.ts +1 -1
package/.idea/workspace.xml
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
<option name="autoReloadType" value="SELECTIVE" />
|
|
5
5
|
</component>
|
|
6
6
|
<component name="ChangeListManager">
|
|
7
|
-
<list default="true" id="accb6ba2-c343-4f84-ad30-6e2d71eceee5" name="Changes" comment="
|
|
8
|
-
<change beforePath="$PROJECT_DIR$/src/lib/components/navigation_component/NavigationComponent.svelte" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib/components/navigation_component/NavigationComponent.svelte" afterDir="false" />
|
|
7
|
+
<list default="true" id="accb6ba2-c343-4f84-ad30-6e2d71eceee5" name="Changes" comment="Migrate from relying on json instead of comments for meta">
|
|
9
8
|
<change beforePath="$PROJECT_DIR$/src/lib/components/navigation_component/PageMeta.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib/components/navigation_component/PageMeta.ts" afterDir="false" />
|
|
9
|
+
<change beforePath="$PROJECT_DIR$/src/routes/(pineapple)/pineapple/(extra-pages)/page1/meta.json" beforeDir="false" afterPath="$PROJECT_DIR$/src/routes/(pineapple)/pineapple/(extra-pages)/page1/meta.json" afterDir="false" />
|
|
10
|
+
<change beforePath="$PROJECT_DIR$/src/routes/(pineapple)/pineapple/(extra-pages)/page2/meta.json" beforeDir="false" afterPath="$PROJECT_DIR$/src/routes/(pineapple)/pineapple/(extra-pages)/page2/meta.json" afterDir="false" />
|
|
10
11
|
</list>
|
|
11
12
|
<option name="SHOW_DIALOG" value="false" />
|
|
12
13
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
@@ -43,8 +44,8 @@
|
|
|
43
44
|
<option value="CSS File" />
|
|
44
45
|
<option value="+page" />
|
|
45
46
|
<option value="NavigationComponent" />
|
|
46
|
-
<option value="TypeScript File" />
|
|
47
47
|
<option value="NavigationControl" />
|
|
48
|
+
<option value="TypeScript File" />
|
|
48
49
|
</list>
|
|
49
50
|
</option>
|
|
50
51
|
</component>
|
|
@@ -93,7 +94,7 @@
|
|
|
93
94
|
"WebServerToolWindowFactoryState": "false",
|
|
94
95
|
"git-widget-placeholder": "turnip/navigation",
|
|
95
96
|
"ignore.virus.scanning.warn.message": "true",
|
|
96
|
-
"last_opened_file_path": "C:/Users/Pumpkin/Projects/Web/pineapple/src/
|
|
97
|
+
"last_opened_file_path": "C:/Users/Pumpkin/Projects/Web/pineapple/src/routes/(pineapple)/pineapple/(extra-pages)/page2",
|
|
97
98
|
"list.type.of.created.stylesheet": "CSS",
|
|
98
99
|
"node.js.detected.package.eslint": "true",
|
|
99
100
|
"node.js.detected.package.tslint": "true",
|
|
@@ -114,18 +115,18 @@
|
|
|
114
115
|
}</component>
|
|
115
116
|
<component name="RecentsManager">
|
|
116
117
|
<key name="CopyFile.RECENT_KEYS">
|
|
118
|
+
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\(extra-pages)\page2" />
|
|
117
119
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\lib\components\navigation_component" />
|
|
118
120
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\page3\page7\(test_layout)\page8" />
|
|
119
121
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\page3\page7" />
|
|
120
122
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\page3" />
|
|
121
|
-
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\page3\page5" />
|
|
122
123
|
</key>
|
|
123
124
|
<key name="MoveFile.RECENT_KEYS">
|
|
125
|
+
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\(extra-pages)\page1" />
|
|
126
|
+
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\(extra-pages)\page2" />
|
|
127
|
+
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\(extra-pages)\page3" />
|
|
124
128
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\(extra-pages)" />
|
|
125
129
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\(pineapple)\pineapple\page3\page7\(test_layout)" />
|
|
126
|
-
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\lib\components\navigation_component" />
|
|
127
|
-
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\lib\components\dialog_overlay" />
|
|
128
|
-
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\lib\components\overrideable_meta" />
|
|
129
130
|
</key>
|
|
130
131
|
<key name="es6.move.members.recent.items">
|
|
131
132
|
<recent name="C:\Users\Pumpkin\Projects\Web\pineapple\src\routes\types\RootLayoutProps.ts" />
|
|
@@ -242,23 +243,10 @@
|
|
|
242
243
|
<workItem from="1711472302524" duration="9738000" />
|
|
243
244
|
<workItem from="1711482094100" duration="5506000" />
|
|
244
245
|
<workItem from="1711487798169" duration="264000" />
|
|
245
|
-
<workItem from="1711488375110" duration="
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
<
|
|
249
|
-
<created>1710305826429</created>
|
|
250
|
-
<option name="number" value="00060" />
|
|
251
|
-
<option name="presentableId" value="LOCAL-00060" />
|
|
252
|
-
<option name="project" value="LOCAL" />
|
|
253
|
-
<updated>1710305826429</updated>
|
|
254
|
-
</task>
|
|
255
|
-
<task id="LOCAL-00061" summary="Reorganize directories to make Pineapple as default layout but still overrideable by Seaweed">
|
|
256
|
-
<option name="closed" value="true" />
|
|
257
|
-
<created>1710373523715</created>
|
|
258
|
-
<option name="number" value="00061" />
|
|
259
|
-
<option name="presentableId" value="LOCAL-00061" />
|
|
260
|
-
<option name="project" value="LOCAL" />
|
|
261
|
-
<updated>1710373523715</updated>
|
|
246
|
+
<workItem from="1711488375110" duration="856000" />
|
|
247
|
+
<workItem from="1711490061858" duration="2823000" />
|
|
248
|
+
<workItem from="1711492999560" duration="85000" />
|
|
249
|
+
<workItem from="1711493260312" duration="1358000" />
|
|
262
250
|
</task>
|
|
263
251
|
<task id="LOCAL-00062" summary="Improve text contrast in dark mode">
|
|
264
252
|
<option name="closed" value="true" />
|
|
@@ -636,7 +624,23 @@
|
|
|
636
624
|
<option name="project" value="LOCAL" />
|
|
637
625
|
<updated>1711487908874</updated>
|
|
638
626
|
</task>
|
|
639
|
-
<
|
|
627
|
+
<task id="LOCAL-00109" summary="Add a way to hide an entry in NavigationComponent">
|
|
628
|
+
<option name="closed" value="true" />
|
|
629
|
+
<created>1711489071463</created>
|
|
630
|
+
<option name="number" value="00109" />
|
|
631
|
+
<option name="presentableId" value="LOCAL-00109" />
|
|
632
|
+
<option name="project" value="LOCAL" />
|
|
633
|
+
<updated>1711489071463</updated>
|
|
634
|
+
</task>
|
|
635
|
+
<task id="LOCAL-00110" summary="Migrate from relying on json instead of comments for meta">
|
|
636
|
+
<option name="closed" value="true" />
|
|
637
|
+
<created>1711492747330</created>
|
|
638
|
+
<option name="number" value="00110" />
|
|
639
|
+
<option name="presentableId" value="LOCAL-00110" />
|
|
640
|
+
<option name="project" value="LOCAL" />
|
|
641
|
+
<updated>1711492747331</updated>
|
|
642
|
+
</task>
|
|
643
|
+
<option name="localTasksCounter" value="111" />
|
|
640
644
|
<servers />
|
|
641
645
|
</component>
|
|
642
646
|
<component name="TypeScriptGeneratedFilesManager">
|
|
@@ -694,8 +698,6 @@
|
|
|
694
698
|
</option>
|
|
695
699
|
</component>
|
|
696
700
|
<component name="VcsManagerConfiguration">
|
|
697
|
-
<MESSAGE value="Adjust turnip fab button color" />
|
|
698
|
-
<MESSAGE value="Replace btn-group postcss class with turnip-menu There is postcss defined class called btn-group which has styles that have !important, which I accidentally used not knowing it exists, and it overrides whatever styles I apply on my class" />
|
|
699
701
|
<MESSAGE value="Add external link warning stub" />
|
|
700
702
|
<MESSAGE value="Refactor Game Section to separate component" />
|
|
701
703
|
<MESSAGE value="Refactor GameSection out of SeaweedTemplate" />
|
|
@@ -719,6 +721,8 @@
|
|
|
719
721
|
<MESSAGE value="Move NavigationControl to a component" />
|
|
720
722
|
<MESSAGE value="Set queryParams based on index and pageSize" />
|
|
721
723
|
<MESSAGE value="Export NavigationComponent" />
|
|
722
|
-
<
|
|
724
|
+
<MESSAGE value="Add a way to hide an entry in NavigationComponent" />
|
|
725
|
+
<MESSAGE value="Migrate from relying on json instead of comments for meta" />
|
|
726
|
+
<option name="LAST_COMMIT_MESSAGE" value="Migrate from relying on json instead of comments for meta" />
|
|
723
727
|
</component>
|
|
724
728
|
</project>
|
|
@@ -3,11 +3,13 @@ import { Card, createGoToFunction } from "../..";
|
|
|
3
3
|
import { parsePageMeta } from "./PageMeta";
|
|
4
4
|
export let title = void 0;
|
|
5
5
|
export let fileList;
|
|
6
|
+
export let jsonList;
|
|
7
|
+
export let imageMap = /* @__PURE__ */ new Map();
|
|
6
8
|
export let parentSubpath;
|
|
7
9
|
export let compareFn = void 0;
|
|
8
10
|
export let pageSize = 5;
|
|
9
11
|
export let currentIndex = 0;
|
|
10
|
-
const pageFlatList = parsePageMeta(fileList, compareFn);
|
|
12
|
+
const pageFlatList = parsePageMeta(fileList, jsonList, imageMap, compareFn);
|
|
11
13
|
$:
|
|
12
14
|
visiblePages = pageFlatList.slice(currentIndex * pageSize, currentIndex * pageSize + pageSize);
|
|
13
15
|
</script>
|
|
@@ -32,8 +34,8 @@ $:
|
|
|
32
34
|
<button class="navigation-element"
|
|
33
35
|
title={fullPath}
|
|
34
36
|
on:click={createGoToFunction(fullPath)}>
|
|
35
|
-
{#if pageMeta.
|
|
36
|
-
<img src={pageMeta.
|
|
37
|
+
{#if pageMeta.imageUrl}
|
|
38
|
+
<img src={pageMeta.imageUrl} alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
|
|
37
39
|
{/if}
|
|
38
40
|
<section class="blurb-text">
|
|
39
41
|
<h2>{pageMeta.title}</h2>
|
package/.svelte-kit/__package__/components/navigation_component/NavigationComponent.svelte.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ declare const __propDef: {
|
|
|
4
4
|
props: {
|
|
5
5
|
title?: string | undefined;
|
|
6
6
|
fileList: Record<string, unknown>;
|
|
7
|
+
jsonList: Record<string, unknown>;
|
|
8
|
+
imageMap?: Map<string, string> | undefined;
|
|
7
9
|
/**
|
|
8
10
|
* Should include a slash before and after the path
|
|
9
11
|
*/ parentSubpath: string;
|
|
@@ -1,18 +1,44 @@
|
|
|
1
1
|
export interface PageMeta {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
tags: string[];
|
|
2
|
+
datePublished?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
imageAlt?: string;
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
6
|
+
* imageID is an ID that NavigationComponent can use to identify imported images
|
|
7
|
+
*
|
|
8
|
+
* To use imageID:
|
|
9
|
+
* 1. Add the imageID entry to the meta.json for the page
|
|
10
|
+
* 2. Create a typescript file with the variable ImageMap: Map<string, string>
|
|
11
|
+
* 3. Add a new entry with your imageID as key, and the image url as the value. Since this is
|
|
12
|
+
* Typescript, you can use import ImageUrl from "./path.png" as you would normally do.
|
|
13
|
+
* 4. Add ImageMap as an argument to your NavigationComponent.
|
|
14
|
+
* Overall, this involves four files
|
|
15
|
+
* - Your navigation page: ./+page.svelte
|
|
16
|
+
* - Your image map typescript: ImageMap.ts
|
|
17
|
+
* - The page you want with an image represented in the navigation: ./topic1/+page.svelte
|
|
18
|
+
* - The meta for that page: ./topic1/meta.json
|
|
19
|
+
*
|
|
20
|
+
* imageID takes precedence over imageURL
|
|
8
21
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
22
|
+
imageID?: string;
|
|
23
|
+
/**
|
|
24
|
+
* imageURL is only limited to absolute paths (includes files in static folder)
|
|
25
|
+
*
|
|
26
|
+
* if imageID is defined, this will be ignored
|
|
27
|
+
*/
|
|
28
|
+
imageUrl?: string;
|
|
13
29
|
lastUpdated?: string;
|
|
30
|
+
nestedPages: PageMeta[];
|
|
31
|
+
/**
|
|
32
|
+
* relativeLink is generated automatically. This will be ignored in meta.json.
|
|
33
|
+
*/
|
|
34
|
+
relativeLink: string;
|
|
14
35
|
shouldGroup?: boolean;
|
|
15
36
|
shouldHide?: boolean;
|
|
37
|
+
tags: string[];
|
|
38
|
+
/**
|
|
39
|
+
* title defaults to the directory name if it's an empty string.
|
|
40
|
+
*/
|
|
41
|
+
title: string;
|
|
16
42
|
}
|
|
17
43
|
/**
|
|
18
44
|
* todo: doc
|
|
@@ -21,4 +47,12 @@ export interface PageMeta {
|
|
|
21
47
|
*/
|
|
22
48
|
export declare const findPageMetaParent: (parentList: PageMeta[], child: PageMeta) => boolean;
|
|
23
49
|
export type ParsePageMetaCompareFn = ((a: PageMeta, b: PageMeta) => number);
|
|
24
|
-
export declare const parsePageMeta: (fileList: Record<string, unknown>, compareFn?: ParsePageMetaCompareFn) => PageMeta[];
|
|
50
|
+
export declare const parsePageMeta: (fileList: Record<string, unknown>, jsonList: Record<string, unknown>, imageMap: Map<string, string>, compareFn?: ParsePageMetaCompareFn) => PageMeta[];
|
|
51
|
+
/**
|
|
52
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
53
|
+
*
|
|
54
|
+
* @param a
|
|
55
|
+
* @param b
|
|
56
|
+
* @constructor
|
|
57
|
+
*/
|
|
58
|
+
export declare const DefaultPageMetaSorter: ParsePageMetaCompareFn;
|
|
@@ -18,10 +18,27 @@ export const findPageMetaParent = (parentList, child) => {
|
|
|
18
18
|
});
|
|
19
19
|
return isChild;
|
|
20
20
|
};
|
|
21
|
-
export const parsePageMeta = (fileList, compareFn) => {
|
|
21
|
+
export const parsePageMeta = (fileList, jsonList, imageMap, compareFn) => {
|
|
22
22
|
const pageFlatList = [];
|
|
23
23
|
// save for the future
|
|
24
24
|
// let pageGroupedList: PageMeta[] = [];
|
|
25
|
+
const jsonMap = new Map();
|
|
26
|
+
Object.keys(jsonList).forEach(path => {
|
|
27
|
+
const pathParts = path.split("/");
|
|
28
|
+
pathParts.pop();
|
|
29
|
+
// get title
|
|
30
|
+
// const title = pathParts[pathParts.length - 1].replaceAll("-", " ");
|
|
31
|
+
// get url path
|
|
32
|
+
const subPath = pathParts.filter(s => {
|
|
33
|
+
return s !== "." && s.indexOf("(") !== 0;
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
jsonMap.set(subPath.join("/"), JSON.parse(jsonList[path].default));
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
console.error(`Error parsing json at: ${path}: ${e}`);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
25
42
|
for (const path in fileList) {
|
|
26
43
|
const pathParts = path.split("/");
|
|
27
44
|
pathParts.pop();
|
|
@@ -40,30 +57,26 @@ export const parsePageMeta = (fileList, compareFn) => {
|
|
|
40
57
|
nestedPages: []
|
|
41
58
|
// todo: transform the data in server.ts?
|
|
42
59
|
};
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
meta.
|
|
56
|
-
meta.
|
|
57
|
-
|
|
58
|
-
meta.imageAlt = metadata["imageAlt"];
|
|
59
|
-
if (!meta.imageAlt) {
|
|
60
|
-
console.warn(`Accessibility issues: image alt missing for image ${meta.image}`);
|
|
61
|
-
}
|
|
60
|
+
const metadata = jsonMap.get(meta.relativeLink);
|
|
61
|
+
if (metadata) {
|
|
62
|
+
meta.title = metadata["title"] ?? meta.title;
|
|
63
|
+
meta.tags = metadata["tags"] ?? [];
|
|
64
|
+
meta.description = metadata["description"];
|
|
65
|
+
meta.datePublished = metadata["datePublished"];
|
|
66
|
+
meta.lastUpdated = metadata["lastUpdated"];
|
|
67
|
+
meta.shouldGroup = metadata["shouldGroup"];
|
|
68
|
+
meta.shouldHide = metadata["shouldHide"];
|
|
69
|
+
meta.imageID = metadata["imageID"];
|
|
70
|
+
meta.imageUrl = imageMap.get(meta.imageID) ?? metadata["imageUrl"];
|
|
71
|
+
if (meta.imageUrl) {
|
|
72
|
+
meta.imageAlt = metadata["imageAlt"];
|
|
73
|
+
if (!meta.imageAlt) {
|
|
74
|
+
console.warn(`Accessibility issues: image alt missing for image ${meta.imageUrl}`);
|
|
62
75
|
}
|
|
63
76
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
}
|
|
78
|
+
if (meta.shouldHide) {
|
|
79
|
+
continue;
|
|
67
80
|
}
|
|
68
81
|
pageFlatList.push(meta);
|
|
69
82
|
}
|
|
@@ -79,5 +92,44 @@ export const parsePageMeta = (fileList, compareFn) => {
|
|
|
79
92
|
if (compareFn) {
|
|
80
93
|
pageFlatList.sort(compareFn);
|
|
81
94
|
}
|
|
95
|
+
else {
|
|
96
|
+
pageFlatList.sort(DefaultPageMetaSorter);
|
|
97
|
+
}
|
|
82
98
|
return pageFlatList;
|
|
83
99
|
};
|
|
100
|
+
const AWins = -1;
|
|
101
|
+
const BWins = 1;
|
|
102
|
+
/**
|
|
103
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
104
|
+
*
|
|
105
|
+
* @param a
|
|
106
|
+
* @param b
|
|
107
|
+
* @constructor
|
|
108
|
+
*/
|
|
109
|
+
export const DefaultPageMetaSorter = (a, b) => {
|
|
110
|
+
if (a.lastUpdated && !b.lastUpdated) {
|
|
111
|
+
return AWins;
|
|
112
|
+
}
|
|
113
|
+
else if (!a.lastUpdated && b.lastUpdated) {
|
|
114
|
+
return BWins;
|
|
115
|
+
}
|
|
116
|
+
else if (a.lastUpdated && b.lastUpdated) {
|
|
117
|
+
return a.lastUpdated.localeCompare(b.lastUpdated);
|
|
118
|
+
}
|
|
119
|
+
if (a.datePublished && !b.datePublished) {
|
|
120
|
+
return AWins;
|
|
121
|
+
}
|
|
122
|
+
else if (!a.lastUpdated && b.datePublished) {
|
|
123
|
+
return BWins;
|
|
124
|
+
}
|
|
125
|
+
else if (a.datePublished && b.datePublished) {
|
|
126
|
+
return a.datePublished.localeCompare(b.datePublished);
|
|
127
|
+
}
|
|
128
|
+
if (a.description && !b.description) {
|
|
129
|
+
return AWins;
|
|
130
|
+
}
|
|
131
|
+
else if (!a.description && b.description) {
|
|
132
|
+
return BWins;
|
|
133
|
+
}
|
|
134
|
+
return a.title.localeCompare(b.title);
|
|
135
|
+
};
|
|
@@ -21,7 +21,7 @@ export const options = {
|
|
|
21
21
|
app: ({ head, body, assets, nonce, env }) => "<!DOCTYPE html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<link rel=\"icon\" href=\"" + assets + "/favicon.png\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width\" />\n\t\t" + head + "\n\t</head>\n\n\t<body data-sveltekit-preload-data=\"hover\" data-theme=\"crimson\">\n\t\t<div style=\"display: contents\" class=\"h-full overflow-hidden\">" + body + "</div>\n\t</body>\n</html>\n",
|
|
22
22
|
error: ({ status, message }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>" + message + "</title>\n\n\t\t<style>\n\t\t\tbody {\n\t\t\t\t--bg: white;\n\t\t\t\t--fg: #222;\n\t\t\t\t--divider: #ccc;\n\t\t\t\tbackground: var(--bg);\n\t\t\t\tcolor: var(--fg);\n\t\t\t\tfont-family:\n\t\t\t\t\tsystem-ui,\n\t\t\t\t\t-apple-system,\n\t\t\t\t\tBlinkMacSystemFont,\n\t\t\t\t\t'Segoe UI',\n\t\t\t\t\tRoboto,\n\t\t\t\t\tOxygen,\n\t\t\t\t\tUbuntu,\n\t\t\t\t\tCantarell,\n\t\t\t\t\t'Open Sans',\n\t\t\t\t\t'Helvetica Neue',\n\t\t\t\t\tsans-serif;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t.error {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tmax-width: 32rem;\n\t\t\t\tmargin: 0 1rem;\n\t\t\t}\n\n\t\t\t.status {\n\t\t\t\tfont-weight: 200;\n\t\t\t\tfont-size: 3rem;\n\t\t\t\tline-height: 1;\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -0.05rem;\n\t\t\t}\n\n\t\t\t.message {\n\t\t\t\tborder-left: 1px solid var(--divider);\n\t\t\t\tpadding: 0 0 0 1rem;\n\t\t\t\tmargin: 0 0 0 1rem;\n\t\t\t\tmin-height: 2.5rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.message h1 {\n\t\t\t\tfont-weight: 400;\n\t\t\t\tfont-size: 1em;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbody {\n\t\t\t\t\t--bg: #222;\n\t\t\t\t\t--fg: #ddd;\n\t\t\t\t\t--divider: #666;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"error\">\n\t\t\t<span class=\"status\">" + status + "</span>\n\t\t\t<div class=\"message\">\n\t\t\t\t<h1>" + message + "</h1>\n\t\t\t</div>\n\t\t</div>\n\t</body>\n</html>\n"
|
|
23
23
|
},
|
|
24
|
-
version_hash: "
|
|
24
|
+
version_hash: "1l3dq8o"
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export async function get_hooks() {
|
|
@@ -3,11 +3,13 @@ import { Card, createGoToFunction } from "../..";
|
|
|
3
3
|
import { parsePageMeta } from "./PageMeta";
|
|
4
4
|
export let title = void 0;
|
|
5
5
|
export let fileList;
|
|
6
|
+
export let jsonList;
|
|
7
|
+
export let imageMap = /* @__PURE__ */ new Map();
|
|
6
8
|
export let parentSubpath;
|
|
7
9
|
export let compareFn = void 0;
|
|
8
10
|
export let pageSize = 5;
|
|
9
11
|
export let currentIndex = 0;
|
|
10
|
-
const pageFlatList = parsePageMeta(fileList, compareFn);
|
|
12
|
+
const pageFlatList = parsePageMeta(fileList, jsonList, imageMap, compareFn);
|
|
11
13
|
$:
|
|
12
14
|
visiblePages = pageFlatList.slice(currentIndex * pageSize, currentIndex * pageSize + pageSize);
|
|
13
15
|
</script>
|
|
@@ -32,8 +34,8 @@ $:
|
|
|
32
34
|
<button class="navigation-element"
|
|
33
35
|
title={fullPath}
|
|
34
36
|
on:click={createGoToFunction(fullPath)}>
|
|
35
|
-
{#if pageMeta.
|
|
36
|
-
<img src={pageMeta.
|
|
37
|
+
{#if pageMeta.imageUrl}
|
|
38
|
+
<img src={pageMeta.imageUrl} alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
|
|
37
39
|
{/if}
|
|
38
40
|
<section class="blurb-text">
|
|
39
41
|
<h2>{pageMeta.title}</h2>
|
|
@@ -4,6 +4,8 @@ declare const __propDef: {
|
|
|
4
4
|
props: {
|
|
5
5
|
title?: string | undefined;
|
|
6
6
|
fileList: Record<string, unknown>;
|
|
7
|
+
jsonList: Record<string, unknown>;
|
|
8
|
+
imageMap?: Map<string, string> | undefined;
|
|
7
9
|
/**
|
|
8
10
|
* Should include a slash before and after the path
|
|
9
11
|
*/ parentSubpath: string;
|
|
@@ -1,18 +1,44 @@
|
|
|
1
1
|
export interface PageMeta {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
tags: string[];
|
|
2
|
+
datePublished?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
imageAlt?: string;
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
6
|
+
* imageID is an ID that NavigationComponent can use to identify imported images
|
|
7
|
+
*
|
|
8
|
+
* To use imageID:
|
|
9
|
+
* 1. Add the imageID entry to the meta.json for the page
|
|
10
|
+
* 2. Create a typescript file with the variable ImageMap: Map<string, string>
|
|
11
|
+
* 3. Add a new entry with your imageID as key, and the image url as the value. Since this is
|
|
12
|
+
* Typescript, you can use import ImageUrl from "./path.png" as you would normally do.
|
|
13
|
+
* 4. Add ImageMap as an argument to your NavigationComponent.
|
|
14
|
+
* Overall, this involves four files
|
|
15
|
+
* - Your navigation page: ./+page.svelte
|
|
16
|
+
* - Your image map typescript: ImageMap.ts
|
|
17
|
+
* - The page you want with an image represented in the navigation: ./topic1/+page.svelte
|
|
18
|
+
* - The meta for that page: ./topic1/meta.json
|
|
19
|
+
*
|
|
20
|
+
* imageID takes precedence over imageURL
|
|
8
21
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
22
|
+
imageID?: string;
|
|
23
|
+
/**
|
|
24
|
+
* imageURL is only limited to absolute paths (includes files in static folder)
|
|
25
|
+
*
|
|
26
|
+
* if imageID is defined, this will be ignored
|
|
27
|
+
*/
|
|
28
|
+
imageUrl?: string;
|
|
13
29
|
lastUpdated?: string;
|
|
30
|
+
nestedPages: PageMeta[];
|
|
31
|
+
/**
|
|
32
|
+
* relativeLink is generated automatically. This will be ignored in meta.json.
|
|
33
|
+
*/
|
|
34
|
+
relativeLink: string;
|
|
14
35
|
shouldGroup?: boolean;
|
|
15
36
|
shouldHide?: boolean;
|
|
37
|
+
tags: string[];
|
|
38
|
+
/**
|
|
39
|
+
* title defaults to the directory name if it's an empty string.
|
|
40
|
+
*/
|
|
41
|
+
title: string;
|
|
16
42
|
}
|
|
17
43
|
/**
|
|
18
44
|
* todo: doc
|
|
@@ -21,4 +47,12 @@ export interface PageMeta {
|
|
|
21
47
|
*/
|
|
22
48
|
export declare const findPageMetaParent: (parentList: PageMeta[], child: PageMeta) => boolean;
|
|
23
49
|
export type ParsePageMetaCompareFn = ((a: PageMeta, b: PageMeta) => number);
|
|
24
|
-
export declare const parsePageMeta: (fileList: Record<string, unknown>, compareFn?: ParsePageMetaCompareFn) => PageMeta[];
|
|
50
|
+
export declare const parsePageMeta: (fileList: Record<string, unknown>, jsonList: Record<string, unknown>, imageMap: Map<string, string>, compareFn?: ParsePageMetaCompareFn) => PageMeta[];
|
|
51
|
+
/**
|
|
52
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
53
|
+
*
|
|
54
|
+
* @param a
|
|
55
|
+
* @param b
|
|
56
|
+
* @constructor
|
|
57
|
+
*/
|
|
58
|
+
export declare const DefaultPageMetaSorter: ParsePageMetaCompareFn;
|
|
@@ -18,10 +18,27 @@ export const findPageMetaParent = (parentList, child) => {
|
|
|
18
18
|
});
|
|
19
19
|
return isChild;
|
|
20
20
|
};
|
|
21
|
-
export const parsePageMeta = (fileList, compareFn) => {
|
|
21
|
+
export const parsePageMeta = (fileList, jsonList, imageMap, compareFn) => {
|
|
22
22
|
const pageFlatList = [];
|
|
23
23
|
// save for the future
|
|
24
24
|
// let pageGroupedList: PageMeta[] = [];
|
|
25
|
+
const jsonMap = new Map();
|
|
26
|
+
Object.keys(jsonList).forEach(path => {
|
|
27
|
+
const pathParts = path.split("/");
|
|
28
|
+
pathParts.pop();
|
|
29
|
+
// get title
|
|
30
|
+
// const title = pathParts[pathParts.length - 1].replaceAll("-", " ");
|
|
31
|
+
// get url path
|
|
32
|
+
const subPath = pathParts.filter(s => {
|
|
33
|
+
return s !== "." && s.indexOf("(") !== 0;
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
jsonMap.set(subPath.join("/"), JSON.parse(jsonList[path].default));
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
console.error(`Error parsing json at: ${path}: ${e}`);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
25
42
|
for (const path in fileList) {
|
|
26
43
|
const pathParts = path.split("/");
|
|
27
44
|
pathParts.pop();
|
|
@@ -40,30 +57,26 @@ export const parsePageMeta = (fileList, compareFn) => {
|
|
|
40
57
|
nestedPages: []
|
|
41
58
|
// todo: transform the data in server.ts?
|
|
42
59
|
};
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
meta.
|
|
56
|
-
meta.
|
|
57
|
-
|
|
58
|
-
meta.imageAlt = metadata["imageAlt"];
|
|
59
|
-
if (!meta.imageAlt) {
|
|
60
|
-
console.warn(`Accessibility issues: image alt missing for image ${meta.image}`);
|
|
61
|
-
}
|
|
60
|
+
const metadata = jsonMap.get(meta.relativeLink);
|
|
61
|
+
if (metadata) {
|
|
62
|
+
meta.title = metadata["title"] ?? meta.title;
|
|
63
|
+
meta.tags = metadata["tags"] ?? [];
|
|
64
|
+
meta.description = metadata["description"];
|
|
65
|
+
meta.datePublished = metadata["datePublished"];
|
|
66
|
+
meta.lastUpdated = metadata["lastUpdated"];
|
|
67
|
+
meta.shouldGroup = metadata["shouldGroup"];
|
|
68
|
+
meta.shouldHide = metadata["shouldHide"];
|
|
69
|
+
meta.imageID = metadata["imageID"];
|
|
70
|
+
meta.imageUrl = imageMap.get(meta.imageID) ?? metadata["imageUrl"];
|
|
71
|
+
if (meta.imageUrl) {
|
|
72
|
+
meta.imageAlt = metadata["imageAlt"];
|
|
73
|
+
if (!meta.imageAlt) {
|
|
74
|
+
console.warn(`Accessibility issues: image alt missing for image ${meta.imageUrl}`);
|
|
62
75
|
}
|
|
63
76
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
}
|
|
78
|
+
if (meta.shouldHide) {
|
|
79
|
+
continue;
|
|
67
80
|
}
|
|
68
81
|
pageFlatList.push(meta);
|
|
69
82
|
}
|
|
@@ -79,5 +92,44 @@ export const parsePageMeta = (fileList, compareFn) => {
|
|
|
79
92
|
if (compareFn) {
|
|
80
93
|
pageFlatList.sort(compareFn);
|
|
81
94
|
}
|
|
95
|
+
else {
|
|
96
|
+
pageFlatList.sort(DefaultPageMetaSorter);
|
|
97
|
+
}
|
|
82
98
|
return pageFlatList;
|
|
83
99
|
};
|
|
100
|
+
const AWins = -1;
|
|
101
|
+
const BWins = 1;
|
|
102
|
+
/**
|
|
103
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
104
|
+
*
|
|
105
|
+
* @param a
|
|
106
|
+
* @param b
|
|
107
|
+
* @constructor
|
|
108
|
+
*/
|
|
109
|
+
export const DefaultPageMetaSorter = (a, b) => {
|
|
110
|
+
if (a.lastUpdated && !b.lastUpdated) {
|
|
111
|
+
return AWins;
|
|
112
|
+
}
|
|
113
|
+
else if (!a.lastUpdated && b.lastUpdated) {
|
|
114
|
+
return BWins;
|
|
115
|
+
}
|
|
116
|
+
else if (a.lastUpdated && b.lastUpdated) {
|
|
117
|
+
return a.lastUpdated.localeCompare(b.lastUpdated);
|
|
118
|
+
}
|
|
119
|
+
if (a.datePublished && !b.datePublished) {
|
|
120
|
+
return AWins;
|
|
121
|
+
}
|
|
122
|
+
else if (!a.lastUpdated && b.datePublished) {
|
|
123
|
+
return BWins;
|
|
124
|
+
}
|
|
125
|
+
else if (a.datePublished && b.datePublished) {
|
|
126
|
+
return a.datePublished.localeCompare(b.datePublished);
|
|
127
|
+
}
|
|
128
|
+
if (a.description && !b.description) {
|
|
129
|
+
return AWins;
|
|
130
|
+
}
|
|
131
|
+
else if (!a.description && b.description) {
|
|
132
|
+
return BWins;
|
|
133
|
+
}
|
|
134
|
+
return a.title.localeCompare(b.title);
|
|
135
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turnipxenon/pineapple",
|
|
3
3
|
"description": "personal package for base styling for other personal projects",
|
|
4
|
-
"version": "2.4.
|
|
4
|
+
"version": "2.4.34",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
7
7
|
"build": "npm run check-requirements && vite build && yarn package",
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
export let title: string | undefined = undefined;
|
|
7
7
|
export let fileList: Record<string, unknown>;
|
|
8
|
+
export let jsonList: Record<string, unknown>;
|
|
9
|
+
export let imageMap = new Map<string, string>();
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Should include a slash before and after the path
|
|
@@ -15,7 +17,7 @@
|
|
|
15
17
|
export let pageSize = 5;
|
|
16
18
|
export let currentIndex = 0;
|
|
17
19
|
|
|
18
|
-
const pageFlatList = parsePageMeta(fileList, compareFn);
|
|
20
|
+
const pageFlatList = parsePageMeta(fileList, jsonList, imageMap, compareFn);
|
|
19
21
|
|
|
20
22
|
$: visiblePages = pageFlatList.slice(currentIndex * pageSize, (currentIndex * pageSize) + pageSize);
|
|
21
23
|
</script>
|
|
@@ -40,8 +42,8 @@
|
|
|
40
42
|
<button class="navigation-element"
|
|
41
43
|
title={fullPath}
|
|
42
44
|
on:click={createGoToFunction(fullPath)}>
|
|
43
|
-
{#if pageMeta.
|
|
44
|
-
<img src={pageMeta.
|
|
45
|
+
{#if pageMeta.imageUrl}
|
|
46
|
+
<img src={pageMeta.imageUrl} alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
|
|
45
47
|
{/if}
|
|
46
48
|
<section class="blurb-text">
|
|
47
49
|
<h2>{pageMeta.title}</h2>
|
|
@@ -1,24 +1,51 @@
|
|
|
1
|
-
import type { RawGlob } from "$pkg";
|
|
1
|
+
import type { RawGlob } from "$pkg/util/util";
|
|
2
2
|
|
|
3
3
|
export interface PageMeta {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
nestedPages: PageMeta[];
|
|
4
|
+
datePublished?: string;
|
|
5
|
+
description?: string;
|
|
7
6
|
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
imageAlt?: string; // defaults to directory name
|
|
8
|
+
/**
|
|
9
|
+
* imageID is an ID that NavigationComponent can use to identify imported images
|
|
10
|
+
*
|
|
11
|
+
* To use imageID:
|
|
12
|
+
* 1. Add the imageID entry to the meta.json for the page
|
|
13
|
+
* 2. Create a typescript file with the variable ImageMap: Map<string, string>
|
|
14
|
+
* 3. Add a new entry with your imageID as key, and the image url as the value. Since this is
|
|
15
|
+
* Typescript, you can use import ImageUrl from "./path.png" as you would normally do.
|
|
16
|
+
* 4. Add ImageMap as an argument to your NavigationComponent.
|
|
17
|
+
* Overall, this involves four files
|
|
18
|
+
* - Your navigation page: ./+page.svelte
|
|
19
|
+
* - Your image map typescript: ImageMap.ts
|
|
20
|
+
* - The page you want with an image represented in the navigation: ./topic1/+page.svelte
|
|
21
|
+
* - The meta for that page: ./topic1/meta.json
|
|
22
|
+
*
|
|
23
|
+
* imageID takes precedence over imageURL
|
|
24
|
+
*/
|
|
25
|
+
imageID?: string;
|
|
11
26
|
|
|
12
27
|
/**
|
|
13
|
-
*
|
|
28
|
+
* imageURL is only limited to absolute paths (includes files in static folder)
|
|
29
|
+
*
|
|
30
|
+
* if imageID is defined, this will be ignored
|
|
14
31
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
description?: string;
|
|
18
|
-
datePublished?: string;
|
|
32
|
+
imageUrl?: string;
|
|
33
|
+
|
|
19
34
|
lastUpdated?: string;
|
|
35
|
+
nestedPages: PageMeta[];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* relativeLink is generated automatically. This will be ignored in meta.json.
|
|
39
|
+
*/
|
|
40
|
+
relativeLink: string;
|
|
20
41
|
shouldGroup?: boolean;
|
|
21
42
|
shouldHide?: boolean;
|
|
43
|
+
tags: string[];
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* title defaults to the directory name if it's an empty string.
|
|
47
|
+
*/
|
|
48
|
+
title: string;
|
|
22
49
|
}
|
|
23
50
|
|
|
24
51
|
/**
|
|
@@ -48,10 +75,32 @@ export const findPageMetaParent = (parentList: PageMeta[], child: PageMeta): boo
|
|
|
48
75
|
export type ParsePageMetaCompareFn = ((a: PageMeta, b: PageMeta) => number);
|
|
49
76
|
|
|
50
77
|
export const parsePageMeta = (fileList: Record<string, unknown>,
|
|
78
|
+
jsonList: Record<string, unknown>,
|
|
79
|
+
imageMap: Map<string, string>,
|
|
51
80
|
compareFn?: ParsePageMetaCompareFn): PageMeta[] => {
|
|
52
81
|
const pageFlatList: PageMeta[] = [];
|
|
53
82
|
// save for the future
|
|
54
83
|
// let pageGroupedList: PageMeta[] = [];
|
|
84
|
+
const jsonMap = new Map<string, { [k: string]: unknown }>();
|
|
85
|
+
Object.keys(jsonList).forEach(path => {
|
|
86
|
+
const pathParts = path.split("/");
|
|
87
|
+
pathParts.pop();
|
|
88
|
+
|
|
89
|
+
// get title
|
|
90
|
+
// const title = pathParts[pathParts.length - 1].replaceAll("-", " ");
|
|
91
|
+
|
|
92
|
+
// get url path
|
|
93
|
+
const subPath = pathParts.filter(s => {
|
|
94
|
+
return s !== "." && s.indexOf("(") !== 0;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
jsonMap.set(subPath.join("/"), JSON.parse((jsonList[path] as RawGlob).default));
|
|
99
|
+
} catch (e) {
|
|
100
|
+
console.error(`Error parsing json at: ${path}: ${e}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
});
|
|
55
104
|
|
|
56
105
|
for (const path in fileList) {
|
|
57
106
|
const pathParts = path.split("/");
|
|
@@ -77,32 +126,31 @@ export const parsePageMeta = (fileList: Record<string, unknown>,
|
|
|
77
126
|
};
|
|
78
127
|
|
|
79
128
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
meta.
|
|
95
|
-
if (meta.
|
|
96
|
-
|
|
97
|
-
if (!meta.imageAlt) {
|
|
98
|
-
console.warn(`Accessibility issues: image alt missing for image ${meta.image}`);
|
|
99
|
-
}
|
|
129
|
+
const metadata = jsonMap.get(meta.relativeLink);
|
|
130
|
+
if (metadata) {
|
|
131
|
+
meta.title = metadata["title"] as string ?? meta.title;
|
|
132
|
+
meta.tags = metadata["tags"] as string[] ?? [];
|
|
133
|
+
meta.description = metadata["description"] as string;
|
|
134
|
+
meta.datePublished = metadata["datePublished"] as string;
|
|
135
|
+
meta.lastUpdated = metadata["lastUpdated"] as string;
|
|
136
|
+
meta.shouldGroup = metadata["shouldGroup"] as boolean;
|
|
137
|
+
meta.shouldHide = metadata["shouldHide"] as boolean;
|
|
138
|
+
|
|
139
|
+
meta.imageID = metadata["imageID"] as string;
|
|
140
|
+
meta.imageUrl = imageMap.get(meta.imageID) ?? metadata["imageUrl"] as string;
|
|
141
|
+
|
|
142
|
+
if (meta.imageUrl) {
|
|
143
|
+
meta.imageAlt = metadata["imageAlt"] as string;
|
|
144
|
+
if (!meta.imageAlt) {
|
|
145
|
+
console.warn(`Accessibility issues: image alt missing for image ${meta.imageUrl}`);
|
|
100
146
|
}
|
|
101
|
-
} catch (e) {
|
|
102
|
-
console.error(`Error at ${meta.relativeLink}: ${e}`);
|
|
103
147
|
}
|
|
104
148
|
}
|
|
105
149
|
|
|
150
|
+
if (meta.shouldHide) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
|
|
106
154
|
pageFlatList.push(meta);
|
|
107
155
|
}
|
|
108
156
|
|
|
@@ -119,7 +167,45 @@ export const parsePageMeta = (fileList: Record<string, unknown>,
|
|
|
119
167
|
|
|
120
168
|
if (compareFn) {
|
|
121
169
|
pageFlatList.sort(compareFn);
|
|
170
|
+
} else {
|
|
171
|
+
pageFlatList.sort(DefaultPageMetaSorter);
|
|
122
172
|
}
|
|
123
173
|
|
|
124
174
|
return pageFlatList;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const AWins = -1;
|
|
178
|
+
const BWins = 1;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Prioritizes, in order, lastUpdated, datePublished, has description, then title
|
|
182
|
+
*
|
|
183
|
+
* @param a
|
|
184
|
+
* @param b
|
|
185
|
+
* @constructor
|
|
186
|
+
*/
|
|
187
|
+
export const DefaultPageMetaSorter: ParsePageMetaCompareFn = (a, b) => {
|
|
188
|
+
if (a.lastUpdated && !b.lastUpdated) {
|
|
189
|
+
return AWins;
|
|
190
|
+
} else if (!a.lastUpdated && b.lastUpdated) {
|
|
191
|
+
return BWins;
|
|
192
|
+
} else if (a.lastUpdated && b.lastUpdated) {
|
|
193
|
+
return a.lastUpdated.localeCompare(b.lastUpdated);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (a.datePublished && !b.datePublished) {
|
|
197
|
+
return AWins;
|
|
198
|
+
} else if (!a.lastUpdated && b.datePublished) {
|
|
199
|
+
return BWins;
|
|
200
|
+
} else if (a.datePublished && b.datePublished) {
|
|
201
|
+
return a.datePublished.localeCompare(b.datePublished);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (a.description && !b.description) {
|
|
205
|
+
return AWins;
|
|
206
|
+
} else if (!a.description && b.description) {
|
|
207
|
+
return BWins;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return a.title.localeCompare(b.title);
|
|
125
211
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"datePublished": "23-01-01",
|
|
3
|
+
"description": "random description but look at Ares!",
|
|
4
|
+
"imageAlt": "Image of Ares being excited",
|
|
5
|
+
"imageID": "testImageID",
|
|
6
|
+
"imageURL": "./favicon.png/?q=imageIDTakesPrecedence",
|
|
7
|
+
"lastUpdated": "23-02-02",
|
|
8
|
+
"shouldGroup": false,
|
|
9
|
+
"shouldHide": false,
|
|
10
|
+
"tags": [
|
|
11
|
+
"random"
|
|
12
|
+
],
|
|
13
|
+
"title": "Custom title for page 1!!!"
|
|
14
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import TestDialogYarn from "./TestDialog.yarn?raw";
|
|
5
5
|
import { Card, dialogManager } from "$pkg";
|
|
6
6
|
import NavigationComponent from "$pkg/components/navigation_component/NavigationComponent.svelte";
|
|
7
|
+
import { ImageMap } from "./(extra-pages)/ImageMap";
|
|
7
8
|
|
|
8
9
|
// region Toast test scripts
|
|
9
10
|
let testingQueueNumber = 1;
|
|
@@ -29,7 +30,8 @@
|
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
// todo: fix fragile relative reference to the root
|
|
32
|
-
const fileList = import.meta.glob("./**/+page.svelte", { query: "?raw"
|
|
33
|
+
const fileList = import.meta.glob("./**/+page.svelte", { query: "?raw" });
|
|
34
|
+
const jsonList = import.meta.glob("./**/meta.json", { query: "?raw", eager: true });
|
|
33
35
|
</script>
|
|
34
36
|
|
|
35
37
|
<div class="pineapple-container">
|
|
@@ -54,6 +56,8 @@
|
|
|
54
56
|
|
|
55
57
|
<NavigationComponent title="Navigation Component Test"
|
|
56
58
|
fileList={fileList}
|
|
59
|
+
jsonList={jsonList}
|
|
60
|
+
imageMap={ImageMap}
|
|
57
61
|
parentSubpath="/pineapple/">
|
|
58
62
|
</NavigationComponent>
|
|
59
63
|
</div>
|
package/vite.config.ts
CHANGED