-498
src/app/baseFonts.js
-498
src/app/baseFonts.js
···
1
-
const baseFonts = {
2
-
opensans: {
3
-
displayName: 'Open Sans',
4
-
defs: [
5
-
{
6
-
path: '/fonts/OpenSans-Regular.ttf',
7
-
style: 'normal',
8
-
weight: 400
9
-
},
10
-
{
11
-
path: '/fonts/OpenSans-Italic.ttf',
12
-
style: 'italic',
13
-
weight: 400
14
-
},
15
-
{
16
-
path: '/fonts/OpenSans-Bold.ttf',
17
-
style: 'normal',
18
-
weight: 700
19
-
},
20
-
{
21
-
path: '/fonts/OpenSans-BoldItalic.ttf',
22
-
style: 'italic',
23
-
weight: 700
24
-
}
25
-
]
26
-
},
27
-
bricolagegrotesque: {
28
-
displayName: 'Bricolage Grotesque',
29
-
defs: [
30
-
{
31
-
path: '/fonts/BricolageGrotesque-Regular.ttf',
32
-
style: 'normal',
33
-
weight: 400
34
-
},
35
-
{
36
-
path: '/fonts/BricolageGrotesque-Bold.ttf',
37
-
style: 'normal',
38
-
weight: 700
39
-
}
40
-
]
41
-
},
42
-
spacemono: {
43
-
displayName: 'Space Mono',
44
-
defs: [
45
-
{
46
-
path: '/fonts/SpaceMono-Regular.ttf',
47
-
style: 'normal',
48
-
weight: 400
49
-
},
50
-
{
51
-
path: '/fonts/SpaceMono-Italic.ttf',
52
-
style: 'italic',
53
-
weight: 400
54
-
},
55
-
{
56
-
path: '/fonts/SpaceMono-Bold.ttf',
57
-
style: 'normal',
58
-
weight: 700
59
-
},
60
-
{
61
-
path: '/fonts/SpaceMono-BoldItalic.ttf',
62
-
style: 'italic',
63
-
weight: 700
64
-
}
65
-
]
66
-
},
67
-
inconsolata: {
68
-
displayName: 'Inconsolata',
69
-
defs: [
70
-
{
71
-
path: '/fonts/Inconsolata.otf',
72
-
style: 'normal'
73
-
}
74
-
]
75
-
},
76
-
bitter: {
77
-
displayName: 'Bitter',
78
-
defs: [
79
-
{
80
-
path: '/fonts/Bitter-Regular.otf',
81
-
style: 'normal',
82
-
weight: 400
83
-
},
84
-
{
85
-
path: '/fonts/Bitter-Italic.otf',
86
-
style: 'italic',
87
-
weight: 400
88
-
},
89
-
{
90
-
path: '/fonts/Bitter-Bold.otf',
91
-
style: 'normal',
92
-
weight: 700
93
-
},
94
-
{
95
-
path: '/fonts/Bitter-BoldItalic.otf',
96
-
style: 'italic',
97
-
weight: 700
98
-
}
99
-
]
100
-
},
101
-
archivo: {
102
-
displayName: 'Archivo',
103
-
defs: [
104
-
{
105
-
path: '/fonts/Archivo-Regular.ttf',
106
-
style: 'normal',
107
-
weight: 400
108
-
},
109
-
{
110
-
path: '/fonts/Archivo-Italic.ttf',
111
-
style: 'italic',
112
-
weight: 400
113
-
},
114
-
{
115
-
path: '/fonts/Archivo-Bold.ttf',
116
-
style: 'normal',
117
-
weight: 700
118
-
},
119
-
{
120
-
path: '/fonts/Archivo-BoldItalic.ttf',
121
-
style: 'italic',
122
-
weight: 700
123
-
}
124
-
]
125
-
},
126
-
outfit: {
127
-
displayName: 'Outfit',
128
-
defs: [
129
-
{
130
-
path: '/fonts/outfit-regular-webfont.woff2',
131
-
style: 'normal',
132
-
weight: 400
133
-
},
134
-
{
135
-
path: '/fonts/outfit-italic-webfont.woff2',
136
-
style: 'italic',
137
-
weight: 400
138
-
}
139
-
]
140
-
},
141
-
notosans: {
142
-
displayName: 'Noto Sans',
143
-
defs: [
144
-
{
145
-
path: '/fonts/NotoSans-Regular.ttf',
146
-
style: 'normal',
147
-
weight: 400
148
-
},
149
-
{
150
-
path: '/fonts/NotoSans-Italic.ttf',
151
-
style: 'italic',
152
-
weight: 400
153
-
},
154
-
{
155
-
path: '/fonts/NotoSans-Bold.ttf',
156
-
style: 'normal',
157
-
weight: 700
158
-
},
159
-
{
160
-
path: '/fonts/NotoSans-BoldItalic.ttf',
161
-
style: 'italic',
162
-
weight: 700
163
-
}
164
-
]
165
-
},
166
-
alegreya: {
167
-
displayName: 'Alegreya',
168
-
defs: [
169
-
{
170
-
path: '/fonts/Alegreya-Regular.otf',
171
-
style: 'normal',
172
-
weight: 400
173
-
},
174
-
{
175
-
path: '/fonts/Alegreya-Italic.otf',
176
-
style: 'italic',
177
-
weight: 400
178
-
},
179
-
{
180
-
path: '/fonts/Alegreya-Bold.otf',
181
-
style: 'normal',
182
-
weight: 700
183
-
},
184
-
{
185
-
path: '/fonts/Alegreya-BoldItalic.otf',
186
-
style: 'italic',
187
-
weight: 700
188
-
}
189
-
]
190
-
},
191
-
alegreyasans: {
192
-
displayName: 'Alegreya Sans',
193
-
defs: [
194
-
{
195
-
path: '/fonts/AlegreyaSans-Regular.otf',
196
-
style: 'normal',
197
-
weight: 400
198
-
},
199
-
{
200
-
path: '/fonts/AlegreyaSans-Italic.otf',
201
-
style: 'italic',
202
-
weight: 400
203
-
},
204
-
{
205
-
path: '/fonts/AlegreyaSans-Bold.otf',
206
-
style: 'normal',
207
-
weight: 700
208
-
},
209
-
{
210
-
path: '/fonts/AlegreyaSans-BoldItalic.otf',
211
-
style: 'italic',
212
-
weight: 700
213
-
}
214
-
]
215
-
},
216
-
stacksanstext: {
217
-
displayName: 'Stack Sans Text',
218
-
defs: [
219
-
{
220
-
path: '/fonts/StackSansText-Regular.ttf',
221
-
style: 'normal',
222
-
weight: 400
223
-
},
224
-
{
225
-
path: '/fonts/StackSansText-Bold.ttf',
226
-
style: 'normal',
227
-
weight: 700
228
-
}
229
-
],
230
-
},
231
-
momotrustsans: {
232
-
displayName: 'Momo Trust Sans',
233
-
defs: [
234
-
{
235
-
path: '/fonts/MomoTrustSans-Regular.ttf',
236
-
style: 'normal',
237
-
weight: 400
238
-
},
239
-
{
240
-
path: '/fonts/MomoTrustSans-Bold.ttf',
241
-
style: 'normal',
242
-
weight: 700
243
-
}
244
-
]
245
-
},
246
-
montserrat: {
247
-
displayName: 'Montserrat',
248
-
defs: [
249
-
{
250
-
path: '/fonts/Montserrat-Regular.otf',
251
-
style: 'normal',
252
-
weight: 400
253
-
},
254
-
{
255
-
path: '/fonts/Montserrat-Italic.otf',
256
-
style: 'italic',
257
-
weight: 400
258
-
},
259
-
{
260
-
path: '/fonts/Montserrat-Bold.otf',
261
-
style: 'normal',
262
-
weight: 700
263
-
},
264
-
{
265
-
path: '/fonts/Montserrat-BoldItalic.otf',
266
-
style: 'italic',
267
-
weight: 700
268
-
}
269
-
]
270
-
},
271
-
robotoslab: {
272
-
displayName: 'Roboto Slab',
273
-
defs: [
274
-
{
275
-
path: '/fonts/RobotoSlab-Regular.ttf',
276
-
style: 'normal',
277
-
weight: 400
278
-
},
279
-
{
280
-
path: '/fonts/RobotoSlab-Bold.ttf',
281
-
style: 'normal',
282
-
weight: 700
283
-
}
284
-
]
285
-
},
286
-
quicksand: {
287
-
displayName: 'Quicksand',
288
-
defs: [
289
-
{
290
-
path: '/fonts/Quicksand-Regular.otf',
291
-
style: 'normal',
292
-
weight: 400
293
-
},
294
-
{
295
-
path: '/fonts/Quicksand-Italic.otf',
296
-
style: 'italic',
297
-
weight: 400
298
-
},
299
-
{
300
-
path: '/fonts/Quicksand-Bold.otf',
301
-
style: 'normal',
302
-
weight: 700
303
-
},
304
-
{
305
-
path: '/fonts/Quicksand-BoldItalic.otf',
306
-
style: 'italic',
307
-
weight: 700
308
-
}
309
-
]
310
-
},
311
-
worksans: {
312
-
displayName: 'Work Sans',
313
-
defs: [
314
-
{
315
-
path: '/fonts/WorkSans-Regular.ttf',
316
-
style: 'normal',
317
-
weight: 400
318
-
},
319
-
{
320
-
path: '/fonts/WorkSans-Italic.ttf',
321
-
style: 'italic',
322
-
weight: 400
323
-
},
324
-
{
325
-
path: '/fonts/WorkSans-Bold.ttf',
326
-
style: 'normal',
327
-
weight: 700
328
-
},
329
-
{
330
-
path: '/fonts/WorkSans-BoldItalic.ttf',
331
-
style: 'italic',
332
-
weight: 700
333
-
}
334
-
]
335
-
},
336
-
notosans: {
337
-
displayName: 'Noto Sans',
338
-
defs: [
339
-
{
340
-
path: '/fonts/NotoSans-Regular.ttf',
341
-
style: 'normal',
342
-
weight: 400
343
-
},
344
-
{
345
-
path: '/fonts/NotoSans-Italic.ttf',
346
-
style: 'italic',
347
-
weight: 400
348
-
},
349
-
{
350
-
path: '/fonts/NotoSans-Bold.ttf',
351
-
style: 'normal',
352
-
weight: 700
353
-
},
354
-
{
355
-
path: '/fonts/NotoSans-BoldItalic.ttf',
356
-
style: 'italic',
357
-
weight: 700
358
-
}
359
-
]
360
-
},
361
-
notoserif: {
362
-
displayName: 'Noto Serif',
363
-
defs: [
364
-
{
365
-
path: '/fonts/NotoSerif-Regular.ttf',
366
-
style: 'normal',
367
-
weight: 400
368
-
},
369
-
{
370
-
path: '/fonts/NotoSerif-Italic.ttf',
371
-
style: 'italic',
372
-
weight: 400
373
-
},
374
-
{
375
-
path: '/fonts/NotoSerif-Bold.ttf',
376
-
style: 'normal',
377
-
weight: 700
378
-
},
379
-
{
380
-
path: '/fonts/NotoSerif-BoldItalic.ttf',
381
-
style: 'italic',
382
-
weight: 700
383
-
}
384
-
]
385
-
},
386
-
librebaskerville: {
387
-
displayName: 'Libre Baskerville',
388
-
defs: [
389
-
{
390
-
path: '/fonts/LibreBaskerville-Regular.otf',
391
-
style: 'normal',
392
-
weight: 400
393
-
},
394
-
{
395
-
path: '/fonts/LibreBaskerville-Italic.otf',
396
-
style: 'italic',
397
-
weight: 400
398
-
},
399
-
{
400
-
path: '/fonts/LibreBaskerville-Bold.otf',
401
-
style: 'normal',
402
-
weight: 700
403
-
}
404
-
]
405
-
},
406
-
ubuntu: {
407
-
displayName: 'Ubuntu',
408
-
defs: [
409
-
{
410
-
path: '/fonts/Ubuntu-Regular.ttf',
411
-
style: 'normal',
412
-
weight: 400
413
-
},
414
-
{
415
-
path: '/fonts/Ubuntu-Italic.ttf',
416
-
style: 'italic',
417
-
weight: 400
418
-
},
419
-
{
420
-
path: '/fonts/Ubuntu-Bold.ttf',
421
-
style: 'normal',
422
-
weight: 700
423
-
},
424
-
{
425
-
path: '/fonts/Ubuntu-BoldItalic.ttf',
426
-
style: 'italic',
427
-
weight: 700
428
-
}
429
-
]
430
-
},
431
-
parkinsans: {
432
-
displayName: 'Parkinsans',
433
-
defs: [
434
-
{
435
-
path: '/fonts/Parkinsans-Regular.ttf',
436
-
style: 'normal',
437
-
weight: 400
438
-
},
439
-
{
440
-
path: '/fonts/Parkinsans-Bold.ttf',
441
-
style: 'normal',
442
-
weight: 700
443
-
}
444
-
]
445
-
},
446
-
lora: {
447
-
displayName: 'Lora',
448
-
defs: [
449
-
{
450
-
path: '/fonts/Lora-Regular.ttf',
451
-
style: 'normal',
452
-
weight: 400
453
-
},
454
-
{
455
-
path: '/fonts/Lora-Italic.ttf',
456
-
style: 'italic',
457
-
weight: 400
458
-
},
459
-
{
460
-
path: '/fonts/Lora-Bold.ttf',
461
-
style: 'normal',
462
-
weight: 700
463
-
},
464
-
{
465
-
path: '/fonts/Lora-BoldItalic.ttf',
466
-
style: 'italic',
467
-
weight: 700
468
-
}
469
-
]
470
-
},
471
-
josefinsans: {
472
-
displayName: 'Josefin Sans',
473
-
defs: [
474
-
{
475
-
path: '/fonts/JosefinSans-Regular.ttf',
476
-
style: 'normal',
477
-
weight: 400
478
-
},
479
-
{
480
-
path: '/fonts/JosefinSans-Italic.ttf',
481
-
style: 'italic',
482
-
weight: 400
483
-
},
484
-
{
485
-
path: '/fonts/JosefinSans-Bold.ttf',
486
-
style: 'normal',
487
-
weight: 700
488
-
},
489
-
{
490
-
path: '/fonts/JosefinSans-BoldItalic.ttf',
491
-
style: 'italic',
492
-
weight: 700
493
-
}
494
-
]
495
-
}
496
-
}
497
-
498
-
export default baseFonts
+4
-4
src/app/generator/page.js
+4
-4
src/app/generator/page.js
···
1
1
"use client"
2
2
3
3
import { useEffect, useState } from "react"
4
-
import themes from "./themes.js"
5
-
import baseFonts from "../baseFonts.js"
6
-
import titleFonts from "../titleFonts.js"
4
+
import themes from "@/lib/themes.js"
5
+
import baseFonts from "@/lib/baseFonts.js"
6
+
import titleFonts from "@/lib/titleFonts.js"
7
7
import styles from "./page.module.css"
8
8
9
9
export default function Generator() {
···
122
122
<li><label><input type="checkbox" name="features[]" value="warnings" defaultChecked={props.warnings} onChange={e => updateProp(e.target.value, e.target.checked)} /> Archive Warnings</label></li>
123
123
<li><label><input type="checkbox" name="features[]" value="charTags" defaultChecked={props.charTags} onChange={e => updateProp(e.target.value, e.target.checked)} /> Character Tags</label></li>
124
124
<li><label><input type="checkbox" name="features[]" value="relTags" defaultChecked={props.relTags} onChange={e => updateProp(e.target.value, e.target.checked)} /> Relationship Tags</label></li>
125
-
<li><label><input type="checkbox" name="features[]" value="freetags" defaultChecked={props.freeTags} onChange={e => updateProp(e.target.value, e.target.checked)} /> Free Tags</label></li>
125
+
<li><label><input type="checkbox" name="features[]" value="freeTags" defaultChecked={props.freeTags} onChange={e => updateProp(e.target.value, e.target.checked)} /> Free Tags</label></li>
126
126
<li><label><input type="checkbox" name="features[]" value="summary" defaultChecked={props.summary} onChange={e => updateProp(e.target.value, e.target.checked)} /> Summary</label></li>
127
127
<li><label><input type="checkbox" name="features[]" value="wordcount" defaultChecked={props.wordcount} onChange={e => updateProp(e.target.value, e.target.checked)} /> Wordcount</label></li>
128
128
<li><label><input type="checkbox" name="features[]" value="chapters" defaultChecked={props.chapters} onChange={e => updateProp(e.target.value, e.target.checked)} /> Chapters</label></li>
+3
-2
src/app/layout.js
+3
-2
src/app/layout.js
···
4
4
5
5
export const metadata = {
6
6
title: process.env.SITENAME,
7
-
description: process.env.DESCRIPTION,
8
-
viewport: "width=device-width, initial-scale=1.0"
7
+
description: process.env.DESCRIPTION
9
8
};
9
+
10
+
export const viewport = "width=device-width, initial-scale=1.0"
10
11
11
12
export default function RootLayout({ children }) {
12
13
return (
-94
src/app/themes.js
-94
src/app/themes.js
···
1
-
const themes = {
2
-
ao3: {
3
-
name: 'AO3',
4
-
background: '#990000',
5
-
color: '#FFFFFF',
6
-
descBackground: '#FFFFFF',
7
-
descColor: '#000000',
8
-
accent: '#FFFFFF',
9
-
accent2: '#990000'
10
-
},
11
-
softEra: {
12
-
name: 'Soft Era',
13
-
background: '#F9F5F5',
14
-
color: '#C8B3B3',
15
-
descBackground: '#F9F5F5',
16
-
descColor: '#414141',
17
-
accent: '#DB90A7',
18
-
accent2: '#EEAABE'
19
-
},
20
-
wildCherry: {
21
-
name: 'Wild Cherry',
22
-
background: '#2B1F32',
23
-
color: '#FFFFFF',
24
-
descBackground: '#FFFFFF',
25
-
descColor: '#2B1F32',
26
-
accent: '#E15D97',
27
-
accent2: '#0AACC5'
28
-
},
29
-
rosePine: {
30
-
name: 'Rosé Pine',
31
-
background: '#191724',
32
-
color: '#e0def4',
33
-
descBackground: '#1f1d2e',
34
-
descColor: '#e0def4',
35
-
accent: '#eb6f92',
36
-
accent2: '#31748f'
37
-
},
38
-
rosePineDawn: {
39
-
name: 'Rosé Pine Dawn',
40
-
background: '#faf4ed',
41
-
color: '#575279',
42
-
descBackground: '#fffaf3',
43
-
descColor: '#575279',
44
-
accent: '#eb6f92',
45
-
accent2: '#286983'
46
-
},
47
-
rosePineMoon: {
48
-
name: 'Rosé Pine Moon',
49
-
background: '#232136',
50
-
color: '#e0def4',
51
-
descBackground: '#2a273f',
52
-
descColor: '#e0def4',
53
-
accent: '#b4637a',
54
-
accent2: '#3e8fb0'
55
-
},
56
-
solarizedLight: {
57
-
name: 'Solarized Light',
58
-
background: '#fdf6e3',
59
-
color: '#b58900',
60
-
descBackground: '#eee8d5',
61
-
descColor: '#002b36',
62
-
accent: '#d33682',
63
-
accent2: '#2aa198'
64
-
},
65
-
solarizedDark: {
66
-
name: 'Solarized Dark',
67
-
background: '#002b36',
68
-
color: '#b58900',
69
-
descBackground: '#073642',
70
-
descColor: '#fdf6e3',
71
-
accent: '#d33682',
72
-
accent2: '#2aa198'
73
-
},
74
-
squidgeworld: {
75
-
name: 'Squidgeworld',
76
-
background: '#b8860b',
77
-
color: '#f5f5dc',
78
-
descBackground: '#f5f5dc',
79
-
color: '#2a2a2a',
80
-
accent: '#fece3f',
81
-
accent2: '#818D4C'
82
-
},
83
-
superlove: {
84
-
name: 'Superlove',
85
-
background: '#df6191',
86
-
color: '#ffffff',
87
-
descBackground: '#FFFFFF',
88
-
color: '#2a2a2a',
89
-
accent: '#F9E4E6',
90
-
accent2: '#a33961'
91
-
}
92
-
}
93
-
94
-
export default themes
-226
src/app/titleFonts.js
-226
src/app/titleFonts.js
···
1
-
import baseFonts from "./baseFonts.js"
2
-
3
-
const titleFonts = {
4
-
...baseFonts,
5
-
playfairdisplay: {
6
-
displayName: 'Playfair Display',
7
-
defs: [
8
-
{
9
-
path: '/fonts/Playfair-Regular.ttf',
10
-
style: 'normal',
11
-
weight: 400
12
-
},
13
-
{
14
-
path: '/fonts/Playfair-Italic.ttf',
15
-
style: 'italic',
16
-
weight: 400
17
-
},
18
-
{
19
-
path: '/fonts/Playfair-Bold.ttf',
20
-
style: 'normal',
21
-
weight: 700
22
-
},
23
-
{
24
-
path: '/fonts/Playfair-BoldItalic.ttf',
25
-
style: 'italic',
26
-
weight: 700
27
-
}
28
-
]
29
-
},
30
-
ultra: {
31
-
displayName: 'Ultra',
32
-
defs: [
33
-
{
34
-
path: '/fonts/Ultra-Regular.ttf',
35
-
style: 'normal',
36
-
weight: 400
37
-
}
38
-
]
39
-
},
40
-
stacksansheadline: {
41
-
displayName: 'Stack Sans Headline',
42
-
defs: [
43
-
{
44
-
path: '/fonts/StackSansHeadline-Regular.ttf',
45
-
style: 'normal',
46
-
weight: 400
47
-
},
48
-
{
49
-
path: '/fonts/StackSansHeadline-Bold.ttf',
50
-
style: 'normal',
51
-
weight: 700
52
-
}
53
-
]
54
-
},
55
-
stacksansnotch: {
56
-
displayName: 'Stack Sans Notch',
57
-
defs: [
58
-
{
59
-
path: '/fonts/StackSansNotch-Regular.ttf',
60
-
style: 'normal',
61
-
weight: 400
62
-
},
63
-
{
64
-
path: '/fonts/StackSansNotch-Bold.ttf',
65
-
style: 'normal',
66
-
weight: 700
67
-
}
68
-
]
69
-
},
70
-
titanone: {
71
-
displayName: 'Titan One',
72
-
defs: []
73
-
},
74
-
momotrustdisplay: {
75
-
displayName: 'Momo Trust Display',
76
-
defs: [
77
-
{
78
-
path: '/fonts/MomoTrustDisplay-Regular.ttf',
79
-
style: 'normal',
80
-
weight: 400
81
-
},
82
-
{
83
-
path: '/fonts/MomoTrustDisplay-Bold.ttf',
84
-
style: 'normal',
85
-
weight: 700
86
-
}
87
-
]
88
-
},
89
-
momosignature: {
90
-
displayName: 'Momo Signature',
91
-
defs: [
92
-
{
93
-
path: '/fonts/MomoSignature-Regular.ttf',
94
-
style: 'normal',
95
-
weight: 400
96
-
}
97
-
]
98
-
},
99
-
londrinasketch: {
100
-
displayName: 'Londrina Sketch',
101
-
defs: [
102
-
{
103
-
path: '/fonts/LondrinaSketch-Regular.ttf',
104
-
style: 'normal',
105
-
weight: 400
106
-
}
107
-
]
108
-
},
109
-
londrinashadow: {
110
-
displayName: 'Londrina Shadow',
111
-
defs: [
112
-
{
113
-
path: '/fonts/LondrinaShadow-Regular.ttf',
114
-
style: 'normal',
115
-
weight: 400
116
-
}
117
-
]
118
-
},
119
-
londrinasolid: {
120
-
displayName: 'Londrina Solid',
121
-
defs: [
122
-
{
123
-
path: '/fonts/LondrinaSolid-Regular.ttf',
124
-
style: 'normal',
125
-
weight: 400
126
-
},
127
-
{
128
-
path: '/fonts/LondrinaSolid-Black.ttf',
129
-
style: 'normal',
130
-
weight: 700
131
-
}
132
-
]
133
-
},
134
-
bebasneue: {
135
-
displayName: 'Bebas Neue',
136
-
defs: [
137
-
{
138
-
path: '/fonts/BebasNeue-Regular.ttf',
139
-
style: 'normal',
140
-
weight: 400
141
-
}
142
-
]
143
-
},
144
-
oswald: {
145
-
displayName: 'Oswald',
146
-
defs: [
147
-
{
148
-
path: '/fonts/Oswald-Regular.ttf',
149
-
style: 'normal',
150
-
weight: 400
151
-
},
152
-
{
153
-
path: '/fonts/Oswald-Bold.ttf',
154
-
style: 'normal',
155
-
weight: 700
156
-
}
157
-
]
158
-
},
159
-
archivoblack: {
160
-
displayName: 'Archivo Black',
161
-
defs: [
162
-
{
163
-
path: '/fonts/ArchivoBlack.otf',
164
-
style: 'normal',
165
-
weight: 400
166
-
}
167
-
]
168
-
},
169
-
alfaslabone: {
170
-
displayName: 'Alfa Slab One',
171
-
defs: [
172
-
{
173
-
path: '/fonts/AlfaSlabOne-Regular.ttf',
174
-
style: 'normal',
175
-
weight: 400
176
-
}
177
-
]
178
-
},
179
-
sixtyfour: {
180
-
displayName: 'SixtyFour',
181
-
defs: [
182
-
{
183
-
path: '/fonts/Sixtyfour-Regular.ttf',
184
-
style: 'normal',
185
-
weight: 400
186
-
},
187
-
{
188
-
path: '/fonts/Sixtyfour-Regular.ttf',
189
-
style: 'normal',
190
-
weight: 700
191
-
}
192
-
]
193
-
},
194
-
datalegreyathin: {
195
-
displayName: 'Datalegreya Thin',
196
-
defs: [
197
-
{
198
-
path: '/fonts/Datalegreya-Thin.otf',
199
-
style: 'normal',
200
-
weight: 400
201
-
}
202
-
]
203
-
},
204
-
datalegreyadot: {
205
-
displayName: 'Datalegreya Dot',
206
-
defs: [
207
-
{
208
-
path: '/fonts/Datalegreya-Dot.otf',
209
-
style: 'normal',
210
-
weight: 400
211
-
}
212
-
]
213
-
},
214
-
datalegreyagradient: {
215
-
displayName: 'Datalegreya Gradient',
216
-
defs: [
217
-
{
218
-
path: '/fonts/Datalegreya-Gradient.otf',
219
-
style: 'normal',
220
-
weight: 400
221
-
}
222
-
]
223
-
}
224
-
}
225
-
226
-
export default titleFonts
+141
-9
src/lib/ogimage.js
+141
-9
src/lib/ogimage.js
···
11
11
backgroundColor: theme.background,
12
12
fontFamily: baseFont,
13
13
fontSize: 24,
14
-
padding: 40,
14
+
padding: 20,
15
15
width: "100%",
16
16
height: "100%",
17
17
}}
···
28
28
textTransform: "uppercase",
29
29
display: "flex",
30
30
justifyContent: "center",
31
-
color: theme.accent
31
+
gap: 10,
32
+
color: theme.accent,
33
+
alignItems: "stretch"
32
34
}}
33
35
>
34
-
{image.topLine}
36
+
<div
37
+
style={{
38
+
display: "flex"
39
+
}}
40
+
>
41
+
{image.topLine}
42
+
</div>
43
+
{image.rating && (<div
44
+
style={{
45
+
borderRadius: '100%',
46
+
backgroundColor: theme.accent,
47
+
color: theme.background,
48
+
padding: "0 10px",
49
+
display: "flex",
50
+
minWidth: 28,
51
+
justifyContent: "center",
52
+
alignItems: "center",
53
+
fontWeight: "bold"
54
+
}}
55
+
>
56
+
{image.rating}
57
+
</div>)}
58
+
{image.warnings && (
59
+
<div
60
+
style={{
61
+
borderRadius: '100%',
62
+
backgroundColor: theme.accent2,
63
+
color: theme.background,
64
+
padding: "0 5px",
65
+
display: "flex",
66
+
minWidth: 28,
67
+
justifyContent: "center",
68
+
alignItems: "center",
69
+
fontWeight: "bold"
70
+
}}
71
+
>
72
+
{image.warning}
73
+
</div>
74
+
)}
75
+
{image.category && (
76
+
<div
77
+
style={{
78
+
borderRadius: '100%',
79
+
backgroundColor: theme.accent3,
80
+
color: theme.background,
81
+
padding: "0 10px",
82
+
display: "flex",
83
+
minWidth: 28,
84
+
justifyContent: "center",
85
+
alignItems: "center",
86
+
fontWeight: "bold"
87
+
}}
88
+
>
89
+
{image.category}
90
+
</div>
91
+
)}
35
92
</div>
36
93
<div
37
94
style={{
38
95
fontSize: 54,
39
96
justifyContent: "center",
40
97
fontFamily: titleFont,
41
-
fontWeight: "bold"
98
+
fontWeight: "bold",
99
+
color: theme.color
42
100
}}
43
101
>
44
102
{image.titleLine}
···
48
106
fontSize: 42,
49
107
display: "flex",
50
108
justifyContent: "center",
51
-
fontFamily: titleFont
109
+
fontFamily: titleFont,
110
+
color: theme.color
52
111
}}
53
112
>
54
113
{`by ${image.authorLine}`}
···
59
118
fontSize: 36,
60
119
fontFamily: titleFont,
61
120
display: "flex",
62
-
justifyContent: "center"
121
+
justifyContent: "center",
122
+
color: theme.color
63
123
}}
64
124
>
65
125
{image.chapterLine}
···
76
136
alignItems: "flex-end"
77
137
}}
78
138
>
79
-
<div
139
+
{image.props.get("charTags") === 'true' && (<div
140
+
style={{
141
+
display: "flex",
142
+
flexWrap: "wrap",
143
+
gap: 5,
144
+
fontSize: 18,
145
+
width: "100%",
146
+
marginBottom: 5
147
+
}}
148
+
>
149
+
{image.charTags.map(c => (
150
+
<span
151
+
style={{
152
+
backgroundColor: theme.accent2,
153
+
color: theme.descBackground,
154
+
padding: "3px 5px",
155
+
borderRadius: 5
156
+
}}
157
+
>
158
+
{c}
159
+
</span>
160
+
))}
161
+
</div>)}
162
+
{image.props.get("relTags") === 'true' && (<div
163
+
style={{
164
+
display: "flex",
165
+
flexWrap: "wrap",
166
+
gap: 5,
167
+
fontSize: 18,
168
+
width: "100%",
169
+
marginBottom: 5
170
+
}}
171
+
>
172
+
{image.relTags.map(r => (
173
+
<span
174
+
style={{
175
+
backgroundColor: theme.accent3,
176
+
color: theme.descBackground,
177
+
padding: "3px 5px",
178
+
borderRadius: 5
179
+
}}
180
+
>
181
+
{r}
182
+
</span>
183
+
))}
184
+
</div>)}
185
+
{image.props.get("freeTags") === 'true' && (<div
186
+
style={{
187
+
display: "flex",
188
+
flexWrap: "wrap",
189
+
gap: 5,
190
+
fontSize: 18,
191
+
width: "100%",
192
+
marginBottom: 5
193
+
}}
194
+
>
195
+
{image.freeTags.map(f => (
196
+
<span
197
+
style={{
198
+
backgroundColor: theme.accent4,
199
+
color: theme.descBackground,
200
+
padding: "3px 5px",
201
+
borderRadius: 5
202
+
}}
203
+
>
204
+
{f}
205
+
</span>
206
+
))}
207
+
</div>)}
208
+
{image.props.get("summary") === 'true' && (<div
80
209
style={{
81
210
display: "flex",
82
211
flexDirection: "column",
···
94
223
{l}
95
224
</div>
96
225
))}
97
-
</div>
226
+
</div>)}
98
227
<div
99
228
style={{
100
229
textAlign: "right",
101
230
fontSize: 18,
231
+
display: "flex",
232
+
justifyContent: "flex-end",
233
+
alignItems: "center",
102
234
color: theme.accent2
103
235
}}
104
236
>
105
-
{`https://archiveofourown.org/${addr}`}
237
+
{image.props.get("wordcount") === 'true' && `${image.words} words • `}{(image.props.get("chapters") === 'true' && image.chapterCount !== null) && `${image.chapterCount} chapters • `}https://archiveofourown.org/{addr}
106
238
</div>
107
239
</div>
108
240
</div>
+74
-7
src/lib/sanitizeData.js
+74
-7
src/lib/sanitizeData.js
···
6
6
import baseFonts from '@/lib/baseFonts.js'
7
7
import titleFonts from '@/lib/titleFonts.js'
8
8
9
+
const getHighestRating = async (works) => {
10
+
const ratings = await Promise.all(works.map(async (w) => {
11
+
const work = await getWork({workId: w.id})
12
+
return work.rating
13
+
}))
14
+
if (ratings.includes("Not Rated")) {
15
+
return "NR"
16
+
} else if (ratings.includes("Explicit")) {
17
+
return "E"
18
+
} else if (ratings.includes("Mature")) {
19
+
return "M"
20
+
} else if (ratings.includes("Teen")) {
21
+
return "T"
22
+
}
23
+
return "G"
24
+
}
25
+
26
+
const getHighestWarning = async (works) => {
27
+
const warnings = await Promise.all(works.map(async (w) => {
28
+
const work = await getWork({workId: w.id})
29
+
return work.tags.warnings
30
+
}))
31
+
const warningsUnique = warnings.reduce((a, b) => { return a.concat(b) }).filter((w, i) => { return i === warnings.indexOf(w) })
32
+
if (warningsUnique.length === 1 && warningsUnique[0] === "Creator Chose Not To Use Archive Warnings") {
33
+
return "⁉️"
34
+
} else if (warningsUnique.length === 1 && warningsUnique[0] === "No Archive Warnings Apply") {
35
+
return "⭕️"
36
+
}
37
+
return "⚠️"
38
+
}
39
+
40
+
const getCategory = async (works) => {
41
+
const categories = await Promise.all(works.map(async (w) => {
42
+
const work = await getWork({workId: w.id})
43
+
return work.category
44
+
}))
45
+
const categoriesUnique = categories.reduce((a, b) => { return a.concat(b) }).filter((w, i) => { return i === categories.indexOf(w) })
46
+
if (categoriesUnique.length === 1) {
47
+
if (categoriesUnique[0] === "F/F") return "⚢"
48
+
if (categoriesUnique[0] === "M/M") return "⚣"
49
+
if (categoriesUnique[0] === "F/M") return "⚤"
50
+
if (categoriesUnique[0] === "Gen") return "◦"
51
+
if (categoriesUnique[0] === "Multi") return "⁕"
52
+
if (categoriesUnique[0] === "Other") return "⚧"
53
+
}
54
+
return "⁕"
55
+
}
56
+
9
57
export default async function sanitizeData ({ type, data, props}) {
10
58
const baseFont = props.has('baseFont') ? props.get('baseFont') : process.env.DEFAULT_BASE_FONT
11
59
const baseFontData = baseFonts[baseFont]
···
40
88
return a.username
41
89
})
42
90
: []
91
+
const rating = type === 'work' ? data.rating : await getHighestRating(data.works)
92
+
const warning = type === 'work' ? await getHighestWarning([data]) : await getHighestWarning(data.works)
93
+
const category = type === 'work' ? await getCategory([data]) : await getCategory(data.works)
43
94
const authorString = authorsFormatted.length > 1
44
95
? authorsFormatted.slice(0, -1).join(", ") + " & " +
45
96
authorsFormatted.slice(-1)[0]
···
47
98
const summaryContent = type === 'work'
48
99
? (props.get('summaryType') === 'chapter' && data.chapterInfo && data.chapterInfo.summary ? data.chapterInfo.summary : (props.get('summaryType') === 'custom' && props.has('customSummary') ? props.get('customSummary') : (data.summary ? data.summary : (parentWork ? parentWork.summary : ''))))
49
100
: (props.get('summaryType') === 'custom' && props.has('customSummary') ? props.get('customSummary') : data.notes)
101
+
const formatter = new Intl.NumberFormat('en-US')
102
+
const words = formatter.format(data.words)
50
103
const summaryDOM = new DOM(summaryContent, {decodeEntities: true});
51
104
const summaryFormatted = summaryDOM.innerHTML.replace(/\<br(?: \/)?\>/g, "\n").replace(
52
105
/(<([^>]+)>)/ig,
···
56
109
const chapterString = data.chapterInfo ? (data.chapterInfo.name
57
110
? data.chapterInfo.name
58
111
: "Chapter " + data.chapterInfo.index) : null
59
-
const chapterCountString = data.chapters
60
-
? ' | <b>Chapters:</b> '+data.chapters.published+' / '+(
112
+
const chapterCountString = type === 'work' ? (data.chapters
113
+
? data.chapters.published+'/'+(
61
114
data.chapters.total
62
115
? data.chapters.total
63
116
: '?'
64
117
)
65
-
: ''
118
+
: '') : null
66
119
const fandomString = type === 'work' ? (
67
120
data.fandoms.length > 1
68
121
? (
69
-
data.fandoms.length <= 5
122
+
data.fandoms.length <= 2
70
123
? data.fandoms.slice(0, -1).join(", ")+" & "+data.fandoms.slice(-1)
71
-
: data.fandoms.join(", ")+" (+"+(data.fandoms.length - 4)+")"
124
+
: data.fandoms.join(", ")+" (+"+(data.fandoms.length - 2)+")"
72
125
)
73
126
: data.fandoms[0]
74
127
) : (
75
-
data.works.map(w => w.fandoms).reduce((a, b) => { return a.concat(b) }).filter((w, i) => { return i === data.works.indexOf(w) })
128
+
''
76
129
)
130
+
const charTags = type === 'work' ? data.tags.characters : data.works.map(w => w.tags.characters).reduce((a, b) => { return b ? (a ? a.concat(b) : []) : (a ? a : []) }).filter((w, i) => { return i === data.works.indexOf(w) })
131
+
const relTags = type === 'work' ? data.tags.relationships : data.works.map(w => w.tags.relationships).reduce((a, b) => { return b ? (a ? a.concat(b) : []) : (a ? a : []) }).filter((w, i) => { return i === data.works.indexOf(w) })
132
+
const freeTags = type === 'work' ? data.tags.additional : data.works.map(w => w.tags.additional).reduce((a, b) => { return b ? (a ? a.concat(b) : []) : (a ? a : []) }).filter((w, i) => { return i === data.works.indexOf(w) })
133
+
const warnings = type === 'work' ? data.tags.warnings : data.works.map(w => w.tags.warnings).reduce((a, b) => { return b ? (a ? a.concat(b) : []) : (a ? a : []) }).filter((w, i) => { return i === data.works.indexOf(w) })
134
+
77
135
return {
78
136
topLine: fandomString,
79
137
titleLine: titleString,
80
138
authorLine: authorString,
81
139
chapterLine: chapterString,
140
+
chapterCount: chapterCountString,
141
+
words: words,
142
+
rating: rating,
143
+
warning: warning,
144
+
category: category,
82
145
summary: summaryFormatted,
83
-
url: 'https://archiveofourown.org/',
84
146
theme: themeData,
147
+
charTags: charTags,
148
+
relTags: relTags,
149
+
freeTags: freeTags,
150
+
warnings: warnings,
85
151
baseFont: baseFont,
86
152
titleFont: titleFont,
153
+
props: props,
87
154
opts: {
88
155
fonts: bfs.concat(tfs)
89
156
}
+32
-12
src/lib/themes.js
+32
-12
src/lib/themes.js
···
6
6
descBackground: '#FFFFFF',
7
7
descColor: '#000000',
8
8
accent: '#FFFFFF',
9
-
accent2: '#990000'
9
+
accent2: '#990000',
10
+
accent3: '#009900',
11
+
accent4: '#000099'
10
12
},
11
13
softEra: {
12
14
name: 'Soft Era',
···
15
17
descBackground: '#F9F5F5',
16
18
descColor: '#414141',
17
19
accent: '#DB90A7',
18
-
accent2: '#EEAABE'
20
+
accent2: '#EEAABE',
21
+
accent3: '#82B4E3',
22
+
accent4: '#a29acb'
19
23
},
20
24
wildCherry: {
21
25
name: 'Wild Cherry',
···
24
28
descBackground: '#FFFFFF',
25
29
descColor: '#2B1F32',
26
30
accent: '#E15D97',
27
-
accent2: '#0AACC5'
31
+
accent2: '#0AACC5',
32
+
accent3: '#FFB86C',
33
+
accent4: '#35BA66'
28
34
},
29
35
rosePine: {
30
36
name: 'Rosé Pine',
···
33
39
descBackground: '#1f1d2e',
34
40
descColor: '#e0def4',
35
41
accent: '#eb6f92',
36
-
accent2: '#31748f'
42
+
accent2: '#31748f',
43
+
accent3: '#f6c177',
44
+
accent4: '#c4a7e7'
37
45
},
38
46
rosePineDawn: {
39
47
name: 'Rosé Pine Dawn',
···
42
50
descBackground: '#fffaf3',
43
51
descColor: '#575279',
44
52
accent: '#eb6f92',
45
-
accent2: '#286983'
53
+
accent2: '#286983',
54
+
accent3: '#ea9d34',
55
+
accent4: '#907aa9'
46
56
},
47
57
rosePineMoon: {
48
58
name: 'Rosé Pine Moon',
···
51
61
descBackground: '#2a273f',
52
62
descColor: '#e0def4',
53
63
accent: '#b4637a',
54
-
accent2: '#3e8fb0'
64
+
accent2: '#3e8fb0',
65
+
accent3: '#f6c177',
66
+
accent4: '#c4a7e7'
55
67
},
56
68
solarizedLight: {
57
69
name: 'Solarized Light',
···
60
72
descBackground: '#eee8d5',
61
73
descColor: '#002b36',
62
74
accent: '#d33682',
63
-
accent2: '#2aa198'
75
+
accent2: '#2aa198',
76
+
accent3: '#859900',
77
+
accent4: '#6c71c4'
64
78
},
65
79
solarizedDark: {
66
80
name: 'Solarized Dark',
···
69
83
descBackground: '#073642',
70
84
descColor: '#fdf6e3',
71
85
accent: '#d33682',
72
-
accent2: '#2aa198'
86
+
accent2: '#2aa198',
87
+
accent3: '#859900',
88
+
accent4: '#6c71c4'
73
89
},
74
90
squidgeworld: {
75
91
name: 'Squidgeworld',
76
92
background: '#b8860b',
77
93
color: '#f5f5dc',
78
94
descBackground: '#f5f5dc',
79
-
color: '#2a2a2a',
95
+
descColor: '#2a2a2a',
80
96
accent: '#fece3f',
81
-
accent2: '#818D4C'
97
+
accent2: '#818D4C',
98
+
accent3: '#6D7A34',
99
+
accent4: '#556121'
82
100
},
83
101
superlove: {
84
102
name: 'Superlove',
85
103
background: '#df6191',
86
104
color: '#ffffff',
87
105
descBackground: '#FFFFFF',
88
-
color: '#2a2a2a',
106
+
descColor: '#2a2a2a',
89
107
accent: '#F9E4E6',
90
-
accent2: '#a33961'
108
+
accent2: '#a33961',
109
+
accent3: '#87254A',
110
+
accent4: '#6A1133'
91
111
}
92
112
}
93
113