feat: turn team and special thanks into content files

This commit is contained in:
mrjvs
2026-08-15 18:23:45 +02:00
parent 324b300d4c
commit b789cdd3ba
5 changed files with 249 additions and 232 deletions

View File

@@ -65,6 +65,31 @@ export default defineContentConfig({
}),
code: z.string()
})
}),
team: defineCollection({
type: 'data',
source: 'team.json',
schema: z.object({
people: z.array(z.object({
name: z.string(),
captionKey: z.string(),
picture: z.string().url(),
github: z.string().url()
}))
})
}),
specialThanks: defineCollection({
type: 'data',
source: 'specialthanks.json',
schema: z.object({
people: z.array(z.object({
name: z.string(),
captionKey: z.string(),
picture: z.string().url(),
github: z.string().url(),
isSpecial: z.boolean().default(false)
}))
})
})
}
});

View File

@@ -0,0 +1,83 @@
{
"people": [
{
"name": "superwhiskers",
"captionKey": "forCrunch",
"picture": "https://github.com/superwhiskers.png",
"github": "https://github.com/superwhiskers"
},
{
"name": "Stary",
"captionKey": "forCtrDev",
"picture": "https://github.com/Stary2001.png",
"github": "https://github.com/Stary2001"
},
{
"name": "rverse",
"captionKey": "forMiiverseHelp",
"picture": "https://github.com/rverseTeam.png",
"github": "https://twitter.com/rverseClub"
},
{
"name": "Kinnay",
"isSpecial": true,
"captionKey": "forResearch",
"picture": "https://cdn.discordapp.com/avatars/186572995848830987/b55c0d4e7bfd792edf0689f83a25d8ea.png?size=128",
"github": "https://github.com/Kinnay"
},
{
"name": "NinStar",
"captionKey": "forIcons",
"picture": "https://github.com/ninstar.png",
"github": "https://github.com/ninstar"
},
{
"name": "Rambo6Glaz",
"captionKey": "forServerDev",
"picture": "https://github.com/EpicUsername12.png",
"github": "https://github.com/EpicUsername12"
},
{
"name": "GaryOderNichts",
"captionKey": "forPatches",
"picture": "https://github.com/GaryOderNichts.png",
"github": "https://github.com/GaryOderNichts"
},
{
"name": "zaksabeast",
"captionKey": "forPatches",
"picture": "https://cdn.discordapp.com/avatars/219324395707957248/c62573fbd4d26c8b4724f54413df6960.png?size=128",
"github": "https://github.com/zaksabeast"
},
{
"name": "mrjvs",
"captionKey": "forServers",
"picture": "https://github.com/mrjvs.png",
"github": "https://github.com/mrjvs"
},
{
"name": "binaryoverload",
"captionKey": "forServers",
"picture": "https://github.com/binaryoverload.png",
"github": "https://github.com/binaryoverload"
},
{
"name": "Simonx22",
"captionKey": "forSplatoon",
"picture": "https://github.com/Simonx22.png",
"github": "https://github.com/Simonx22"
},
{
"name": "OatmealDome",
"captionKey": "forSplatoon",
"picture": "https://github.com/OatmealDome.png",
"github": "https://github.com/OatmealDome"
},
{
"name": "GitHub contributors",
"captionKey": "general",
"picture": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png",
"github": "https://github.com/PretendoNetwork"
}
]
}

76
content/team.json Normal file
View File

@@ -0,0 +1,76 @@
{
"people": [
{
"name": "Jonathan Barrow (jonbarrow)",
"captionKey": "owner",
"picture": "https://github.com/jonbarrow.png",
"github": "https://github.com/jonbarrow"
},
{
"name": "Jemma (CaramelKat)",
"captionKey": "miiverseDev",
"picture": "https://github.com/caramelkat.png",
"github": "https://github.com/CaramelKat"
},
{
"name": "quarky",
"captionKey": "wiiuResearchAndPatchDev",
"picture": "https://github.com/ashquarky.png",
"github": "https://github.com/ashquarky"
},
{
"name": "SuperMarioDaBom",
"captionKey": "researchAndServerArch",
"picture": "https://github.com/supermariodabom.png",
"github": "https://github.com/SuperMarioDaBom"
},
{
"name": "limes.pink",
"captionKey": "webDev",
"picture": "https://github.com/limesdotpink.png",
"github": "https://github.com/limesdotpink"
},
{
"name": "Shutterbug2000",
"captionKey": "researchAndGameDev",
"picture": "https://cdn.discordapp.com/avatars/191370953807233024/0311b61e2009c1576828dd2e9a59d72e.png?size=128",
"github": "https://github.com/shutterbug2000"
},
{
"name": "Billy",
"captionKey": "preserveAndServerArch",
"picture": "https://github.com/InternalLoss.png",
"github": "https://github.com/InternalLoss"
},
{
"name": "DaniElectra",
"captionKey": "researchAndGameDev",
"picture": "https://github.com/danielectra.png",
"github": "https://github.com/DaniElectra"
},
{
"name": "niko",
"captionKey": "webDevAndGameDev",
"picture": "https://github.com/hauntii.png",
"github": "https://github.com/hauntii"
},
{
"name": "MatthewL246",
"captionKey": "devopsAndCommunityWork",
"picture": "https://github.com/MatthewL246.png",
"github": "https://github.com/MatthewL246"
},
{
"name": "wolfendale",
"captionKey": "gameDevAndOptimise",
"picture": "https://github.com/wolfendale.png",
"github": "https://github.com/wolfendale"
},
{
"name": "TraceEntertains",
"captionKey": "ctrResearchAndPatchDev",
"picture": "https://github.com/TraceEntertains.png",
"github": "https://github.com/TraceEntertains"
}
]
}

View File

@@ -114,171 +114,35 @@
"credits": {
"title": "The team",
"text": "Meet the team behind the project",
"people": [
{
"name": "Jonathan Barrow (jonbarrow)",
"caption": "Project owner and lead developer",
"picture": "https://github.com/jonbarrow.png",
"github": "https://github.com/jonbarrow"
},
{
"name": "Jemma (CaramelKat)",
"caption": "Miiverse research and development",
"picture": "https://github.com/caramelkat.png",
"github": "https://github.com/CaramelKat"
},
{
"name": "quarky",
"caption": "Wii U research and patch development",
"picture": "https://github.com/ashquarky.png",
"github": "https://github.com/ashquarky"
},
{
"name": "SuperMarioDaBom",
"caption": "Systems research and server architecture",
"picture": "https://github.com/supermariodabom.png",
"github": "https://github.com/SuperMarioDaBom"
},
{
"name": "limes.pink",
"caption": "Web development",
"picture": "https://github.com/limesdotpink.png",
"github": "https://github.com/limesdotpink"
},
{
"name": "Shutterbug2000",
"caption": "Systems research and server development",
"picture": "https://cdn.discordapp.com/avatars/191370953807233024/0311b61e2009c1576828dd2e9a59d72e.png?size=128",
"github": "https://github.com/shutterbug2000"
},
{
"name": "Billy",
"caption": "Preservationist and server architecture",
"picture": "https://github.com/InternalLoss.png",
"github": "https://github.com/InternalLoss"
},
{
"name": "DaniElectra",
"caption": "Systems research and server development",
"picture": "https://github.com/danielectra.png",
"github": "https://github.com/DaniElectra"
},
{
"name": "niko",
"caption": "Web and server development",
"picture": "https://github.com/hauntii.png",
"github": "https://github.com/hauntii"
},
{
"name": "MatthewL246",
"caption": "DevOps and community work",
"picture": "https://github.com/MatthewL246.png",
"github": "https://github.com/MatthewL246"
},
{
"name": "wolfendale",
"caption": "Server development and optimization",
"picture": "https://github.com/wolfendale.png",
"github": "https://github.com/wolfendale"
},
{
"name": "TraceEntertains",
"caption": "3DS patch development and research",
"picture": "https://github.com/TraceEntertains.png",
"github": "https://github.com/TraceEntertains"
}
]
"roles": {
"owner": "Project owner and lead developer",
"miiverseDev": "Miiverse research and development",
"wiiuResearchAndPatchDev": "Wii U research and patch development",
"researchAndGameDev": "Systems research and server development",
"researchAndServerArch": "Systems research and server architecture",
"webDev": "Web development",
"preserveAndServerArch": "Preservationist and server architecture",
"webDevAndGameDev": "Web and server development",
"gameDevAndOptimise": "Server development and optimization",
"ctrResearchAndPatchDev": "3DS patch development and research",
"devopsAndCommunityWork": "DevOps and community work"
}
},
"specialThanks": {
"title": "Special thanks",
"text": "Without them, Pretendo wouldn't be where it is today.",
"people": [
{
"name": "GitHub contributors",
"caption": "Localizations and other contributions",
"picture": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png",
"github": "https://github.com/PretendoNetwork"
},
{
"name": "superwhiskers",
"caption": "crunch library development",
"picture": "https://github.com/superwhiskers.png",
"github": "https://github.com/superwhiskers"
},
{
"name": "Stary",
"caption": "3DS development and NEX dissector",
"picture": "https://github.com/Stary2001.png",
"github": "https://github.com/Stary2001"
},
{
"name": "rverse",
"caption": "Miiverse information sharing",
"picture": "https://github.com/rverseTeam.png",
"github": "https://twitter.com/rverseClub"
},
{
"name": "Kinnay",
"special": "Special thanks",
"caption": "Research on Nintendo datastructures",
"picture": "https://cdn.discordapp.com/avatars/186572995848830987/b55c0d4e7bfd792edf0689f83a25d8ea.png?size=128",
"github": "https://github.com/Kinnay"
},
{
"name": "NinStar",
"caption": "Icons for the Mii Editor and Juxt reactions",
"picture": "https://github.com/ninstar.png",
"github": "https://github.com/ninstar"
},
{
"name": "Rambo6Glaz",
"caption": "Console research and game servers",
"picture": "https://github.com/EpicUsername12.png",
"github": "https://github.com/EpicUsername12"
},
{
"name": "GaryOderNichts",
"caption": "Wii U patch development",
"picture": "https://github.com/GaryOderNichts.png",
"github": "https://github.com/GaryOderNichts"
},
{
"name": "zaksabeast",
"caption": "3DS patch creator",
"picture": "https://cdn.discordapp.com/avatars/219324395707957248/c62573fbd4d26c8b4724f54413df6960.png?size=128",
"github": "https://github.com/zaksabeast"
},
{
"name": "mrjvs",
"caption": "Server architecture",
"picture": "https://github.com/mrjvs.png",
"github": "https://github.com/mrjvs"
},
{
"name": "binaryoverload",
"caption": "Server architecture",
"picture": "https://github.com/binaryoverload.png",
"github": "https://github.com/binaryoverload"
},
{
"name": "Simonx22",
"caption": "Splatoon rotations and research",
"picture": "https://github.com/Simonx22.png",
"github": "https://github.com/Simonx22"
},
{
"name": "OatmealDome",
"caption": "Splatoon rotations and research",
"picture": "https://github.com/OatmealDome.png",
"github": "https://github.com/OatmealDome"
},
{
"name": "GitHub contributors",
"caption": "Localizations and other contributions",
"picture": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png",
"github": "https://github.com/PretendoNetwork"
}
]
"reasons": {
"general": "Localizations and other contributions",
"forCrunch": "crunch library development",
"forCtrDev": "3DS development and NEX dissector",
"forMiiverseHelp": "Miiverse information sharing",
"forResearch": "Research on Nintendo datastructures",
"forServerDev": "Console research and game servers",
"forIcons": "Icons for the Mii Editor and Juxt reactions",
"forSplatoon": "Splatoon rotations and research",
"forPatches": "Console patch development",
"forServers": "Server architecture"
}
},
"discordJoin": {
"title": "Stay up to date",
@@ -419,7 +283,7 @@
"upgradePush": "To become a subscriber and gain access to cool perks, visit the <a href=\"/account/upgrade\">upgrade page</a>."
},
"miiEditor": {
"nickname":"Nickname",
"nickname": "Nickname",
"creator": "Creator",
"birthday": "Birthday",
"clickToSet": "Click to set",

View File

@@ -5,9 +5,11 @@ import type { ProgressItem } from '~~/shared/api-types';
const { te, t, tm } = useI18n();
const progress = await useFetch('/api/progress');
const nOfQAs = computed(() => tm<string>('faq.QAs') as string[]).value.length - 1;
const maxCoreStaffIndex = computed(() => tm<string>('credits.people') as string[]).value.length - 1;
const maxContributorsIndex = computed(() => tm<string>('specialThanks.people') as string[]).value.length - 1;
const faqItems = computed(() => Object.keys(tm<string>('faq.QAs')));
const { data: team } = await useAsyncData(async () => queryCollection('team').first());
const teamMembers = computed(() => team.value?.people ?? []);
const { data: specialThanks } = await useAsyncData(async () => (await queryCollection('specialThanks').first()));
const specialThanksMembers = computed(() => specialThanks.value?.people ?? []);
const summaryProgress = computed<ProgressItem>(() => {
return {
@@ -22,16 +24,9 @@ const summaryProgress = computed<ProgressItem>(() => {
};
});
function array(n: number) {
return Array.from({ length: n + 1 }, (_, i) => i);
}
function odd(n: number) {
return array(n).filter(i => i % 2 === 1);
}
function even(n: number) {
return array(n).filter(i => i % 2 === 0);
function arraySplit<T>(array: Array<T>, groupCount: number): Array<Array<T>> {
return Array.from({ length: groupCount })
.map((_, groupIndex) => array.filter((_, i) => i % groupCount === groupIndex));
}
function titleSuffixHandler(path: string) {
@@ -174,25 +169,16 @@ function titleSuffixHandler(path: string) {
</p>
</div>
<div class="questions column-2">
<div class="left questions-left">
<div
v-for="(faq, groupIndex) of arraySplit(faqItems, 2)"
:key="groupIndex"
:class="{
'left questions-left': groupIndex === 0,
'right questions-right': groupIndex === 1,
}"
>
<details
v-for="i in even(nOfQAs)"
:key="i"
class="question-and-answer"
>
<summary>
{{ $t(`faq.QAs[${i}].question`) }}
</summary>
<p
class="text"
v-html="$t(`faq.QAs[${i}].answer`)"
/>
</details>
</div>
<div class="right questions-right">
<details
v-for="i in odd(nOfQAs)"
v-for="i in faq"
:key="i"
class="question-and-answer"
>
@@ -267,26 +253,22 @@ function titleSuffixHandler(path: string) {
</div>
<div class="team-cards">
<div
v-for="i in array(maxCoreStaffIndex)"
:key="i"
v-for="member in teamMembers"
:key="member.github"
class="card"
>
<div class="card-left">
<img
:src="$t(`credits.people[${i}].picture`)"
:src="member.picture"
class="pfp"
alt=""
>
</div>
<div class="card-core">
<span
v-if="$te(`credits.people[${i}].special`)"
class="sub"
>{{ $t(`credits.people[${i}].special`) }}</span>
<h3 class="title">
<span>{{ $t(`credits.people[${i}].name`) }}</span>
<span>{{ member.name }}</span>
<a
:href="$t(`credits.people[${i}].github`)"
:href="member.github"
class="github"
target="_blank"
aria-label="Open Github"
@@ -298,7 +280,7 @@ function titleSuffixHandler(path: string) {
</a>
</h3>
<p class="text">
{{ $t(`credits.people[${i}].caption`) }}
{{ $t(`credits.roles.${member.captionKey}`) }}
</p>
</div>
</div>
@@ -319,45 +301,32 @@ function titleSuffixHandler(path: string) {
</p>
</div>
<div class="animation-wrapper">
<div class="row first">
<div
v-for="(members, groupIndex) of arraySplit(specialThanksMembers, 2)"
:key="groupIndex"
class="row"
:class="{
first: groupIndex === 0,
second: groupIndex === 1,
}"
>
<div class="team-helpers-cards">
<a
v-for="i in [...even(maxContributorsIndex), ...even(maxContributorsIndex)]"
:key="i"
:href="$te(`specialThanks.people[${i}].github`) ? $t(`specialThanks.people[${i}].github`) : undefined"
v-for="member in [...members, ...members]"
:key="member.name"
:href="member.github"
target="_blank"
:class="{ 'helper-card': true, 'special': $te(`specialThanks.people[${i}].special`) }"
:class="{ 'helper-card': true, 'special': member.isSpecial }"
>
<div class="img-wrapper">
<img
:src="$t(`specialThanks.people[${i}].picture`)"
:src="member.picture"
class="pfp"
alt=""
>
</div>
<span>{{ $t(`specialThanks.people[${i}].name`) }}</span>
<p>{{ $t(`specialThanks.people[${i}].caption`) }}</p>
</a>
</div>
</div>
<div class="row second">
<div class="team-helpers-cards">
<a
v-for="i in [...odd(maxContributorsIndex), ...odd(maxContributorsIndex)]"
:key="i"
:href="$te(`specialThanks.people[${i}].github`) ? $t(`specialThanks.people[${i}].github`) : undefined"
target="_blank"
:class="{ 'helper-card': true, 'special': $te(`specialThanks.people[${i}].special`) }"
>
<div class="img-wrapper">
<img
:src="$t(`specialThanks.people[${i}].picture`)"
class="pfp"
alt=""
>
</div>
<span>{{ $t(`specialThanks.people[${i}].name`) }}</span>
<p>{{ $t(`specialThanks.people[${i}].caption`) }}</p>
<span>{{ member.name }}</span>
<p>{{ $t(`specialThanks.reasons.${member.captionKey}`) }}</p>
</a>
</div>
</div>