Skip to content

Commit

Permalink
Refactor jarflop
Browse files Browse the repository at this point in the history
  • Loading branch information
saboooor committed Jun 21, 2024
1 parent 328d291 commit 20233e1
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 142 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "birdflop",
"version": "8.12.0",
"version": "8.13.0",
"homepage": "https://www.birdflop.com",
"description": "The only 501(c)(3) nonprofit Minecraft server host.",
"repository": {
Expand Down
4 changes: 2 additions & 2 deletions src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ export default component$(() => {
})}
</ul>
{plan.outOfStock ?
<Button color="red" class={{ 'w-full': true }} onClick$={() => {window.open("https://discord.gg/nmgtX5z", "_blank")}}>
<ButtonAnchor href="https://discord.gg/nmgtX5z" target='_blank' color="red" class={{ 'w-full': true }}>
<AlertCircleOutline width="30" class="text-3xl" /> Out of stock
</Button>
</ButtonAnchor>
:
<Link href={`/plans?plan=${encodeURIComponent(planName)}`} class="pt-4">
<Button color="blue" class={{ 'w-full': true }}>
Expand Down
2 changes: 1 addition & 1 deletion src/routes/resources/animtexture/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export default component$(() => {
</div>

</div>
<canvas id="c" class="w-24 max-h-screen ml-48 hidden"></canvas>
<canvas id="c" class="w-24 max-h-svh ml-48 hidden"></canvas>
</section>
);
});
Expand Down
238 changes: 101 additions & 137 deletions src/routes/resources/jars/index.tsx
Original file line number Diff line number Diff line change
@@ -1,169 +1,115 @@
import { component$, useStore, $ } from '@builder.io/qwik';
import { Card, Header, TextInput, Button } from '@luminescent/ui';
import { Card, Header, TextInput, ButtonAnchor } from '@luminescent/ui';
import { CloseOutline } from 'qwik-ionicons';

export default component$(() => {
const state = useStore({
searchTerm: '',
hoverIndex: null,
showModal: false,
selectedJar: null,
isScrolledToEnd: false,
latestVersion: '',
downloadLink: '',
});

const fetchLatestPurpurVersion = $(async () => {
try {
const response = await fetch('https://api.purpurmc.org/v2/purpur');
const data = await response.json();
const versions = data.versions;
const latestVersion = versions[versions.length - 1];
return `https://api.purpurmc.org/v2/purpur/${latestVersion}/latest/download`;
} catch (error) {
console.error('Failed to fetch the latest version:', error);
return null;
}
});
const fetchLatestPurpurVersion = $(async () => {
const response = await fetch('https://api.purpurmc.org/v2/purpur');
const data = await response.json();
const versions = data.versions;
const latestVersion = versions[versions.length - 1];
return `https://api.purpurmc.org/v2/purpur/${latestVersion}/latest/download`;
});

const fetchLatestPaperVersion = $(async () => {
try {
const response = await fetch('https://papermc.io/api/v2/projects/paper');
const data = await response.json();
const versions = data.versions;
const latestVersion = versions[versions.length - 1];
const buildResponse = await fetch(`https://papermc.io/api/v2/projects/paper/versions/${latestVersion}`);
const buildData = await buildResponse.json();
const latestBuild = buildData.builds[buildData.builds.length - 1];
const downloadResponse = await fetch(`https://papermc.io/api/v2/projects/paper/versions/${latestVersion}/builds/${latestBuild}`);
const downloadData = await downloadResponse.json();
const downloadName = downloadData.downloads.application.name;
return `https://papermc.io/api/v2/projects/paper/versions/${latestVersion}/builds/${latestBuild}/downloads/${downloadName}`;
} catch (error) {
console.error('Failed to fetch the latest version:', error);
return null;
}
});
const fetchLatestPaperVersion = $(async () => {
const response = await fetch('https://papermc.io/api/v2/projects/paper');
const data = await response.json();
const versions = data.versions;
const latestVersion = versions[versions.length - 1];
const buildResponse = await fetch(`https://papermc.io/api/v2/projects/paper/versions/${latestVersion}`);
const buildData = await buildResponse.json();
const latestBuild = buildData.builds[buildData.builds.length - 1];
const downloadResponse = await fetch(`https://papermc.io/api/v2/projects/paper/versions/${latestVersion}/builds/${latestBuild}`);
const downloadData = await downloadResponse.json();
const downloadName = downloadData.downloads.application.name;
return `https://papermc.io/api/v2/projects/paper/versions/${latestVersion}/builds/${latestBuild}/downloads/${downloadName}`;
});

const fetchLatestPufferfishVersion = $(async () => {
try {
const response = await fetch('https://ci.pufferfish.host/job/Pufferfish-1.20/api/json?tree=builds[number,status,timestamp,id,result,changeSet[items[comment,commitId]],artifacts[*]]');
const data = await response.json();
const latestBuild = data.builds[0];
const latestBuildNumber = latestBuild.number;
const artifact = latestBuild.artifacts.find((a: any) => a.fileName.endsWith('.jar'));
return `https://ci.pufferfish.host/job/Pufferfish-1.20/${latestBuildNumber}/artifact/${artifact.relativePath}`;
} catch (error) {
console.error('Failed to fetch the latest version:', error);
return null;
}
});

const handleSearchChange = $((e: Event) => {
const target = e.target as HTMLInputElement;
state.searchTerm = target.value;
});

const handleJarClick = $((jar: any) => {
state.selectedJar = jar;
state.showModal = true;
});

const closeModal = $(() => {
state.showModal = false;
state.selectedJar = null;
});
const fetchLatestPufferfishVersion = $(async () => {
const response = await fetch('https://ci.pufferfish.host/job/Pufferfish-1.20/api/json?tree=builds[number,status,timestamp,id,result,changeSet[items[comment,commitId]],artifacts[*]]');
const data = await response.json();
const latestBuild = data.builds[0];
const latestBuildNumber = latestBuild.number;
const artifact = latestBuild.artifacts.find((a: any) => a.fileName.endsWith('.jar'));
return `https://ci.pufferfish.host/job/Pufferfish-1.20/${latestBuildNumber}/artifact/${artifact.relativePath}`;
});

const handleDownloadClick = $(async (jarName: string) => {
let downloadLink;
if (jarName === 'PurpurMC') {
downloadLink = await fetchLatestPurpurVersion();
} else if (jarName === 'PaperMC') {
downloadLink = await fetchLatestPaperVersion();
} else if (jarName === 'Pufferfish') {
downloadLink = await fetchLatestPufferfishVersion();
}
function getDownloadLink(jarName: string) {
switch (jarName) {
case 'PurpurMC':
return fetchLatestPurpurVersion();
case 'PaperMC':
return fetchLatestPaperVersion();
case 'Pufferfish':
return fetchLatestPufferfishVersion();
default:
return '';
}
}

if (downloadLink) {
window.location.href = downloadLink;
}
});
const serverJars = [
{
name: 'PurpurMC',
website: 'https://purpurmc.org/',
logo: 'https://purpurmc.org/docs/images/purpur-small.png',
description: 'Purpur aims to provide a high-performance, stable!',
longDescription: 'PurpurMC provides additional enhancements and features on top of the PaperMC server. Includes advanced configuration options, additional commands, and more control over server performance.',
},
{
name: 'PaperMC',
website: 'https://papermc.io/',
logo: 'https://docs.papermc.io/assets/images/papermc-logomark-512-f125384f3367cd4d9291ca983fcb7334.png',
description: 'PaperMC is designed to improve performance and customization!',
longDescription: 'PaperMC is a high performance Minecraft server that is compatible with the Vanilla Minecraft server. It is designed to be lightweight and fast, providing a smooth experience for players.',
},
{
name: 'Pufferfish',
website: 'https://pufferfish.host',
logo: 'https://pufferfish.host/_next/static/images/pufferfish-mark-610a2bf4c7063641b6d396a5e9d0760f.svg',
description: 'A highly optimized Paper fork designed for large servers!',
longDescription: 'Pufferfish is a Minecraft server software that is designed to be lightweight and easy to use. It is compatible with the Vanilla Minecraft server and provides additional features and enhancements.',
},
];

const handleScroll = $((e: Event) => {
const target = e.target as HTMLDivElement;
state.isScrolledToEnd = target.scrollHeight - target.scrollTop === target.clientHeight;
export default component$(() => {
const store = useStore({
searchTerm: '',
selectedJar: null as typeof serverJars[number] | null,
latestVersion: '',
downloadLink: '',
});

const serverJars = [
{
name: 'PurpurMC',
website: 'https://purpurmc.org/',
logo: 'https://purpurmc.org/docs/images/purpur-small.png',
description: 'Purpur aims to provide a high-performance, stable!',
longDescription: 'PurpurMC provides additional enhancements and features on top of the PaperMC server. Includes advanced configuration options, additional commands, and more control over server performance.',
},
{
name: 'PaperMC',
website: 'https://papermc.io/',
logo: 'https://docs.papermc.io/assets/images/papermc-logomark-512-f125384f3367cd4d9291ca983fcb7334.png',
description: 'PaperMC is designed to improve performance and customization!',
longDescription: 'PaperMC is a high performance Minecraft server that is compatible with the Vanilla Minecraft server. It is designed to be lightweight and fast, providing a smooth experience for players.',
},
{
name: 'Pufferfish',
website: 'https://pufferfish.host',
logo: 'https://pufferfish.host/_next/static/images/pufferfish-mark-610a2bf4c7063641b6d396a5e9d0760f.svg',
description: 'A highly optimized Paper fork designed for large servers!',
longDescription: 'Pufferfish is a Minecraft server software that is designed to be lightweight and easy to use. It is compatible with the Vanilla Minecraft server and provides additional features and enhancements.',
},
];

const filteredJars = serverJars.filter((jar) =>
jar.name.toLowerCase().includes(state.searchTerm.toLowerCase()),
jar.name.toLowerCase().includes(store.searchTerm.toLowerCase()),
);

if (state.showModal && state.selectedJar !== null) {
const selectedJar = state.selectedJar as any;
return (
<div class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-75 z-50 p-4">
<div class="bg-gray-800 text-white p-6 rounded-lg shadow-lg relative max-w-lg w-full transform transition-transform duration-300 ease-in-out scale-100">
<button onClick$={closeModal} class="absolute top-2 right-2 text-gray-400 hover:text-gray-200 transform transition-transform duration-300 ease-in-out hover:scale-110">
<CloseOutline width="30" style={{ color: 'white' }} />
</button>
<div class="flex items-center mb-4">
<img src={selectedJar.logo} alt={`${selectedJar.name} logo`} class="w-12 h-12 mr-4" height="1" width="1"/>
<h2 class="text-2xl font-bold">{selectedJar.name}</h2>
</div>
<p class="mb-4">{selectedJar.longDescription}</p>
<Button onClick$={() => handleDownloadClick(selectedJar.name)}>
Download Latest Version
</Button>
</div>
</div>
);
}

return (
<div class="min-h-screen flex flex-col items-center bg-gray-900 text-white p-4 pt-28 relative">
<div class="flex mx-auto max-w-7xl px-6 items-center justify-center min-h-svh pt-[72px]">
<div class="w-full max-w-2xl flex flex-col items-center space-y-4 p-4">
<h1 class="text-3xl font-bold mb-4 text-center">Jarflop - The Minecraft Server Jar Hub!</h1>
<div class="w-full mb-6">
<TextInput
id="search-input"
placeholder="Search for a version..."
value={state.searchTerm}
onInput$={handleSearchChange}
value={store.searchTerm}
onInput$={(e, el) => store.searchTerm = el.value}
/>
</div>
<div class="w-full relative">
<div
class="space-y-4 overflow-y-auto max-h-96"
onScroll$={handleScroll}
style={{ maxHeight: 'calc(100vh - 300px)' }}
>
{filteredJars.length > 0 ? (
filteredJars.map((jar, index) => (
<Card key={index} hover="clickable" onClick$={() => handleJarClick(jar)}>
<Card key={index} hover="clickable" onClick$={async () => {
try {
store.downloadLink = await getDownloadLink(jar.name);
store.selectedJar = jar;
}
catch (error) {
console.error('Error fetching download link:', error);
}
}}>
<div class="flex items-center">
<img src={jar.logo} alt={`${jar.name} logo`} class="w-12 h-12 mr-4" height="1" width="1" />
<div>
Expand All @@ -180,6 +126,24 @@ export default component$(() => {
</div>
</div>
</div>
{store.selectedJar !== null &&
<div class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-75 z-50 p-4">
<div class="bg-gray-800 text-white p-6 rounded-lg shadow-lg relative max-w-lg w-full transform transition-transform duration-300 ease-in-out scale-100">
<button onClick$={() => store.selectedJar = null} class="absolute top-2 right-2 text-gray-400 hover:text-gray-200 transform transition-transform duration-300 ease-in-out hover:scale-110">
<CloseOutline width="30" style={{ color: 'white' }} />
</button>
<div class="flex items-center mb-4">
<img src={store.selectedJar.logo} alt={`${store.selectedJar.name} logo`} class="w-12 h-12 mr-4" height="1" width="1"/>
<h2 class="text-2xl font-bold">{store.selectedJar.name}</h2>
</div>
<p class="mb-4">{store.selectedJar.longDescription}</p>
<ButtonAnchor href={store.downloadLink} onClick$={async () => {
}}>
Download Latest Version
</ButtonAnchor>
</div>
</div>
}
</div>
);
});
2 changes: 1 addition & 1 deletion src/routes/staff/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const staffList = [
export default component$(() => {
return (
<section class="flex mx-auto max-w-7xl px-6 justify-center min-h-svh pt-[72px]">
<Background class="fixed min-h-screen w-full bottom-0 overflow-hidden -z-10 object-cover object-center opacity-50" id="bg" alt="background" />
<Background class="fixed bottom-0 -z-10 h-lvh w-lvw object-cover object-center opacity-55" id="bg" alt="background" />
<div class="w-full my-10 min-h-[60px] scale-for-mac">
<h1 class="flex gap-4 items-center justify-center text-gray-100 text-2xl sm:text-4xl font-bold text-center drop-shadow-lg mb-6">
<PeopleOutline width="64" style={{ color: 'white' }} /> Meet The Team
Expand Down

0 comments on commit 20233e1

Please sign in to comment.