+2
src/app/api/series/[seriesId]/route.js
+2
src/app/api/series/[seriesId]/route.js
···
6
6
export async function GET(req, ctx) {
7
7
const { seriesId } = await ctx.params
8
8
const { archive } = await req.nextUrl.searchParams
9
+
console.log(seriesId)
10
+
console.log(archive)
9
11
const domain = await req.nextUrl.hostname
10
12
const subdomain = domain.split(".").length > 1 ? domain.split(".")[0] : null
11
13
if (subdomain) setArchiveBaseUrl('https://'+subdomain)
+4
-4
src/app/series/[seriesId]/preview/route.js
+4
-4
src/app/series/[seriesId]/preview/route.js
···
18
18
const p = await req.nextUrl.searchParams
19
19
const props = querystring.parse(p.toString())
20
20
const addr = `series/${seriesId}`
21
-
if (props.archive) setArchiveBaseUrl('https://'+props.archive)
22
-
const data = await getSeries({seriesId: seriesId})
23
-
if (props.archive) resetArchiveBaseUrl()
24
-
const imageParams = await sanitizeData({type: 'series', data: data, props: props})
21
+
const domainParam = p && p.has('archive') ? `?archive=${p.get('archive')}` : ''
22
+
const work = await fetch(`http://${process.env.DOMAIN}/api/series/${seriesId}${domainParam}`)
23
+
const data = await work.json()
24
+
const imageParams = await sanitizeData({type: 'series', data: data, props: p})
25
25
const theme = imageParams.theme
26
26
const baseFont = baseFonts[imageParams.baseFont].displayName
27
27
const titleFont = titleFonts[imageParams.titleFont].displayName
+1
-1
src/app/works/[workId]/opengraph-image.jsx
+1
-1
src/app/works/[workId]/opengraph-image.jsx
···
18
18
const addr = `works/${workId}`
19
19
const data = await getWork({workId: workId})
20
20
if (data.locked) return OGImageLocked({theme: process.env.DEFAULT_THEME})
21
-
const imageParams = await sanitizeData({type: 'work', data: data, props: defaults})
21
+
const imageParams = await sanitizeData({type: 'work', data: data, props: new URLSearchParams(defaults)})
22
22
const theme = imageParams.theme
23
23
const baseFont = baseFonts[imageParams.baseFont].displayName
24
24
const titleFont = titleFonts[imageParams.titleFont].displayName
+20
-19
src/lib/ogimage.js
+20
-19
src/lib/ogimage.js
···
13
13
import NoWarnings from "@/icons/nowarnings.js"
14
14
import Warnings from "@/icons/warnings.js"
15
15
import ChoseNotToWarn from "@/icons/chosenottowarn.js"
16
+
import { checkItem, checkToggle } from '@/lib/propUtils.js'
16
17
17
18
export default async function OGImage ({ theme, baseFont, titleFont, image, addr, opts }) {
18
19
console.log(image)
···
61
62
gap: 10
62
63
}}
63
64
>
64
-
{image.props.get('rating') && image.rating === 'E' && (<Explicit fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
65
-
{image.props.get('rating') && image.rating === 'M' && (<Mature fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
66
-
{image.props.get('rating') && image.rating === 'T' && (<Teen fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
67
-
{image.props.get('rating') && image.rating === 'G' && (<General fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
68
-
{image.props.get('rating') && image.rating === 'NR' && (<NotRated fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
65
+
{checkToggle('rating', image.props) && image.rating === 'E' && (<Explicit fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
66
+
{checkToggle('rating', image.props) && image.rating === 'M' && (<Mature fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
67
+
{checkToggle('rating', image.props) && image.rating === 'T' && (<Teen fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
68
+
{checkToggle('rating', image.props) && image.rating === 'G' && (<General fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
69
+
{checkToggle('rating', image.props) && image.rating === 'NR' && (<NotRated fg={theme.accentColor} bg={theme.accent} width={28} height={28} />)}
69
70
70
-
{image.props.get('warnings') && image.warning === 'NW' && (<NoWarnings fg={theme.accent2Color} bg={theme.accent2} width={28} height={28} />)}
71
-
{image.props.get('warnings') && image.warning === 'CNTW' && (<ChoseNotToWarn fg={theme.accent2Color} bg={theme.accent2} width={28} height={28} />)}
72
-
{image.props.get('warnings') && image.warning === 'W' && (<Warnings fg={theme.accent2Color} bg={theme.accent2} width={28} height={28} />)}
71
+
{checkToggle('warnings', image.props) && image.warning === 'NW' && (<NoWarnings fg={theme.accent2Color} bg={theme.accent2} width={28} height={28} />)}
72
+
{checkToggle('warnings', image.props) && image.warning === 'CNTW' && (<ChoseNotToWarn fg={theme.accent2Color} bg={theme.accent2} width={28} height={28} />)}
73
+
{checkToggle('warnings', image.props) && image.warning === 'W' && (<Warnings fg={theme.accent2Color} bg={theme.accent2} width={28} height={28} />)}
73
74
74
-
{image.props.get('category') && image.category === 'F' && (<Yuri fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
75
-
{image.props.get('category') && image.category === 'M' && (<Yaoi fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
76
-
{image.props.get('category') && image.category === 'FM' && (<Het fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
77
-
{image.props.get('category') && image.category === 'G' && (<Gen fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
78
-
{image.props.get('category') && image.category === 'MX' && (<MultiShip fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
79
-
{image.props.get('category') && image.category === 'O' && (<OtherShip fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
75
+
{checkToggle('category', image.props) && image.category === 'F' && (<Yuri fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
76
+
{checkToggle('category', image.props)&& image.category === 'M' && (<Yaoi fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
77
+
{checkToggle('category', image.props) && image.category === 'FM' && (<Het fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
78
+
{checkToggle('category', image.props) && image.category === 'G' && (<Gen fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
79
+
{checkToggle('category', image.props) && image.category === 'MX' && (<MultiShip fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
80
+
{checkToggle('category', image.props) && image.category === 'O' && (<OtherShip fg={theme.accent3Color} bg={theme.accent3} width={28} height={28} />)}
80
81
</div>
81
82
<div
82
83
style={{
···
127
128
alignItems: "flex-end"
128
129
}}
129
130
>
130
-
{image.props.get('charTags') && (<div
131
+
{checkToggle('charTags', image.props) && (<div
131
132
style={{
132
133
display: "flex",
133
134
flexWrap: "wrap",
···
150
151
</span>
151
152
))}
152
153
</div>)}
153
-
{image.props.get('relTags') && (<div
154
+
{checkToggle('relTags', image.props) && (<div
154
155
style={{
155
156
display: "flex",
156
157
flexWrap: "wrap",
···
173
174
</span>
174
175
))}
175
176
</div>)}
176
-
{image.props.freeTags && (<div
177
+
{checkToggle('freeTags', image.props) && (<div
177
178
style={{
178
179
display: "flex",
179
180
flexWrap: "wrap",
···
196
197
</span>
197
198
))}
198
199
</div>)}
199
-
{image.props.get('summary') && (<div
200
+
{checkToggle('summary', image.props) && (<div
200
201
style={{
201
202
display: "flex",
202
203
flexDirection: "column",
···
225
226
color: theme.accent2
226
227
}}
227
228
>
228
-
{image.props.get('wordcount') && `${image.words} words • `}{(image.props.get('chapters') && image.chapterCount !== null) && `${image.chapterCount} chapters • `}{image.props.get('postedAt') && `posted on ${image.postedAt} • `}{image.props.get('updatedAt') && `updated on ${image.updatedAt} • `}{addr}
229
+
{checkToggle('wordcount', image.props) && `${image.words} words • `}{(checkToggle('chapters', image.props) && image.chapterCount !== null) && `${image.chapterCount} chapters • `}{checkToggle('postedAt', image.props) && `posted on ${image.postedAt} • `}{checkToggle('updatedAt', image.props) && `updated on ${image.updatedAt} • `}{addr}
229
230
</div>
230
231
</div>
231
232
</div>
+7
src/lib/propUtils.js
+7
src/lib/propUtils.js
+8
-7
src/lib/sanitizeData.js
+8
-7
src/lib/sanitizeData.js
···
5
5
import themes from '@/lib/themes.js'
6
6
import baseFonts from '@/lib/baseFonts.js'
7
7
import titleFonts from '@/lib/titleFonts.js'
8
+
import { checkItem, checkToggle } from '@/lib/propUtils.js'
8
9
9
10
const getWork = async (workId, archive = null) => {
10
11
const domainParam = (archive && archive !== process.env.ARCHIVE) ? `?archive=${archive}` : ''
···
82
83
}
83
84
84
85
export default async function sanitizeData ({ type, data, props}) {
85
-
const archive = props && props.archive ? props.archive : process.env.ARCHIVE
86
+
const archive = props && checkItem('archive', props) ? props.get('archive') : process.env.ARCHIVE
86
87
console.log(props)
87
-
const baseFont = props.baseFont ? props.baseFont : process.env.DEFAULT_BASE_FONT
88
+
const baseFont = checkItem('baseFont', props) ? props.get('baseFont') : process.env.DEFAULT_BASE_FONT
88
89
const baseFontData = baseFonts[baseFont]
89
-
const titleFont = props.titleFont ? props.titleFont : process.env.DEFAULT_TITLE_FONT
90
+
const titleFont = checkItem('titleFont', props) ? props.get('titleFont') : process.env.DEFAULT_TITLE_FONT
90
91
const titleFontData = titleFonts[titleFont]
91
-
const archClean = props.has('archive') ? props.get('archive').replace("https://", '').replace('/', '') : null
92
-
const theme = props.has('theme') ? props.get('theme') : (props.has('archive') && !["ao3.org", "archiveofourown.org", "archive.transformativeworks.org"].includes(archClean) && Object.values(siteMap).includes(archClean) ? Object.keys(siteMap)[Object.values(siteMap).indexOf(archClean)] : process.env.DEFAULT_THEME)
92
+
const archClean = checkItem('archive', props) ? props.get('archive').replace("https://", '').replace('/', '') : null
93
+
const theme = checkItem('theme', props) ? props.get('theme') : (checkItem('archive', props) && !["ao3.org", "archiveofourown.org", "archive.transformativeworks.org"].includes(archClean) && Object.values(siteMap).includes(archClean) ? Object.keys(siteMap)[Object.values(siteMap).indexOf(archClean)] : process.env.DEFAULT_THEME)
93
94
const themeData = themes[theme]
94
95
const parentWork = type === 'work' && data.chapterInfo ? await getWork(data.id, archive) : null
95
96
const bfs = await Promise.all(baseFontData.defs.map(async (bf) => {
···
127
128
authorsFormatted.slice(-1)[0]
128
129
: authorsFormatted[0])
129
130
const summaryContent = type === 'work'
130
-
? (props.summaryType === 'chapter' && data.chapterInfo && data.chapterInfo.summary ? data.chapterInfo.summary : (props.summaryType === 'custom' && props.customSummary !== '' ? props.customSummary : (data.summary ? data.summary : (parentWork ? parentWork.summary : ''))))
131
-
: (props.summaryType === 'custom' && props.customSummary !== '' ? props.customSummary : data.notes)
131
+
? (props.get('summaryType') === 'chapter' && data.chapterInfo && data.chapterInfo.summary ? data.chapterInfo.summary : (props.get('summaryType') === 'custom' && props.get('customSummary') !== '' ? props.get('customSummary') : (data.summary ? data.summary : (parentWork ? parentWork.summary : ''))))
132
+
: (props.get('summaryType') === 'custom' && props.get('customSummary') !== '' ? props.get('customSummary') : data.notes)
132
133
const formatter = new Intl.NumberFormat('en-US')
133
134
const words = formatter.format(data.words)
134
135
const summaryDOM = new DOM(summaryContent, {decodeEntities: true})