Merge pull request #108 from Supercolbat/dev‎‎​

UI/UX changes
This commit is contained in:
Joey L 2023-08-07 00:38:31 +00:00 committed by GitHub
commit a5c9d5ebb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 992 additions and 681 deletions

View File

@ -11,3 +11,6 @@ node_modules
pnpm-lock.yaml
package-lock.json
yarn.lock
# Ignore NixOS flake lock
flake.lock

76
flake.lock Normal file
View File

@ -0,0 +1,76 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1689068808,
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
"type": "github"
},
"original": {
"id": "flake-utils",
"type": "indirect"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1691209513,
"narHash": "sha256-V8e6wywJ34DgwP4sDSWpHMPx3OC+k1l/xPSQTfdPj5U=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "cc0e47cd36a2d6815eba5abf3317e519abd35571",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "master",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"systems": "systems_2"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

26
flake.nix Normal file
View File

@ -0,0 +1,26 @@
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/master";
inputs.systems.url = "github:nix-systems/default";
outputs = {
self,
nixpkgs,
flake-utils,
systems,
}:
flake-utils.lib.eachSystem (import systems)
(system: let
pkgs = import nixpkgs {
inherit system;
};
in {
devShells.default = pkgs.mkShell {
buildInputs = [
pkgs.nodejs
# Package manager
pkgs.nodePackages.pnpm
];
};
});
}

View File

@ -12,30 +12,30 @@
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
"@iconify-json/ic": "^1.1.12",
"@iconify-json/simple-icons": "^1.1.41",
"@sveltejs/adapter-node": "^1.1.4",
"@sveltejs/kit": "^1.1.4",
"@types/sanitize-html": "^2.8.0",
"@unocss/reset": "^0.48.4",
"axios": "^1.2.4",
"dayjs": "^1.11.7",
"prettier": "^2.8.3",
"prettier-plugin-svelte": "^2.9.0",
"sanitize-html": "^2.8.1",
"svelte": "^3.55.1",
"svelte-check": "^3.0.2",
"@iconify-json/ic": "^1.1.13",
"@iconify-json/simple-icons": "^1.1.63",
"@sveltejs/adapter-node": "^1.3.1",
"@sveltejs/kit": "^1.22.4",
"@types/sanitize-html": "^2.9.0",
"@unocss/reset": "^0.48.5",
"axios": "^1.4.0",
"dayjs": "^1.11.9",
"prettier": "^3.0.1",
"prettier-plugin-svelte": "^3.0.3",
"sanitize-html": "^2.11.0",
"svelte": "^3.59.2",
"svelte-check": "^3.4.6",
"svelte-dark-mode": "^2.1.0",
"tslib": "^2.4.1",
"typescript": "^4.9.4",
"unocss": "^0.48.4",
"vite": "^4.0.4"
"tslib": "^2.6.1",
"typescript": "^4.9.5",
"unocss": "^0.48.5",
"vite": "^4.4.8"
},
"type": "module",
"dependencies": {
"@auth/core": "^0.2.5",
"@auth/sveltekit": "^0.1.12",
"joi": "^17.7.0",
"joi": "^17.9.2",
"snarkdown": "^2.0.0",
"svelte-hcaptcha": "^0.1.1"
}

File diff suppressed because it is too large Load Diff

View File

@ -17,9 +17,22 @@ html.light {
--alt: #ddd;
--alt-text: #333;
--black: #151515;
--body-text: #666;
color-scheme: light;
}
html.dark {
--primary: #151515;
--secondary: #1d1d1d;
--tertiary: #353535;
--text: #ffffffde;
--grey: #5454547a;
--alt: #333;
--alt-text: #ddd;
--body-text: #bbb;
color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
html {
--primary: #151515;
@ -29,6 +42,7 @@ html.light {
--grey: #5454547a;
--alt: #333;
--alt-text: #ddd;
--body-text: #bbb;
color-scheme: dark;
}
}
@ -50,26 +64,35 @@ a:hover {
}
h1 {
@apply text-4xl font-bold my-8 border-b-2 border-accent pb-2;
@apply text-4xl font-bold mt-8 mb-2 border-b-2 border-accent pb-2;
}
.h1-no-lg {
@apply my-8 border-b-2 border-accent pb-2;
@apply mt-8 mb-2 border-b-2 border-accent pb-2;
}
h2 {
@apply text-3xl font-bold my-8;
@apply text-3xl font-bold mt-8 mb-2;
}
h3 {
@apply text-2xl font-bold my-8;
@apply text-2xl font-bold mt-8 mb-2;
}
h4 {
@apply text-xl font-bold my-8;
@apply text-xl font-bold mt-8 mb-2;
}
details {
p {
color: var(--body-text);
}
/* Between-paragraph spacing */
p + p {
@apply mt-4;
}
summary {
@apply cursor-pointer;
}

View File

@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />

View File

@ -5,7 +5,13 @@ import type { Provider } from "@auth/core/providers";
import type { Profile } from "@auth/core/types";
import { redirect, type Handle } from "@sveltejs/kit";
import { sequence } from "@sveltejs/kit/hooks";
import { announcements, pubnixUsers, blogPosts, blogTags, blogAuthors } from "./stores";
import {
announcements,
pubnixUsers,
blogPosts,
blogTags,
blogAuthors
} from "./stores";
import axios from "axios";
import { Agent } from "https";
@ -74,10 +80,10 @@ export const fetchGhost = async (action: string, additional?: string) => {
const updateMap = async () => {
try {
const res = await axios(
env.KUMA_URL,
{ httpsAgent: agent, timeout: 10000 }
);
const res = await axios(env.KUMA_URL, {
httpsAgent: agent,
timeout: 10000
});
if (res.status === 200) {
announcements.set(res.data);
@ -89,10 +95,10 @@ const updateMap = async () => {
}
try {
const res = await axios(
"https://publapi.p.projectsegfau.lt/users",
{ httpsAgent: agent, timeout: 10000 }
);
const res = await axios("https://publapi.p.projectsegfau.lt/users", {
httpsAgent: agent,
timeout: 10000
});
if (res.status === 200) {
pubnixUsers.set(res.data);
@ -142,4 +148,4 @@ const updateMap = async () => {
updateMap();
setInterval(updateMap, 30000);
setInterval(updateMap, 30000);

View File

@ -2,7 +2,9 @@
<h1 class="text-5xl font-extrabold text-accent my-0 border-b-0 pb-0">
Project Segfault
</h1>
<p class="text-2xl">Open source development and hosted services.</p>
<p class="text-2xl text-text">
Open-source development and hosted services.
</p>
<div class="flex gap-4 flex-col w-full sm:(flex-row justify-center)">
<a
href="/instances"

View File

@ -7,16 +7,17 @@
const links = [
{ href: "/instances", text: "Instances" },
{ href: "/donate", text: "Donate" },
{ href: "/pubnix", text: "Pubnix" },
{ href: "/contact", text: "Contact" },
{ href: "/team", text: "Team" },
{
href: "https://wiki.projectsegfau.lt/",
text: "Wiki",
external: true
},
{ href: "/blog", text: "Blog" },
{ href: "/donate", text: "Donate" },
{ href: "/contact", text: "Contact" },
{ href: "/team", text: "Team" },
{
href: "https://status.projectsegfau.lt/",
text: "Status",
@ -83,6 +84,8 @@
>
<!-- Slot for the progress bar -->
<slot />
<!-- Nav without links -->
<div class="flex items-center justify-between w-full">
<Logo />
<button
@ -96,11 +99,13 @@
/>
</button>
</div>
{#if showMenu}
<!-- Nav with links -->
<div class={showMenu ? "contents" : "hidden"}>
<div
class="
{linkContainerStyles}
lt-navPlus1:(flex-col !items-start fixed pl-4 pb-4 z-50 w-full left-0 top-16)
lt-navPlus1:(flex-col !items-end fixed pr-4 pb-4 z-50 w-full left-0 top-16)
"
transition:slide={{ duration: 300, easing: quintOut }}
>
@ -115,7 +120,7 @@
{/each}
<ThemeToggle />
</div>
{/if}
</div>
</nav>
<noscript>

View File

@ -17,12 +17,19 @@
<button
on:click={toggle}
class="text-text flex items-center text-sm"
class="theme-toggle button text-text flex items-center text-sm"
aria-label="Toggle theme"
>
<div
class="i-ic:{theme === 'dark'
? 'outline-light-mode'
: 'outline-dark-mode'} h-4 w-4"
/>
<span class="ml-2 navPlus1:(hidden)">Toggle theme</span>
<span class="navPlus1:(hidden)">Toggle theme</span>
</button>
<style>
.theme-toggle:hover {
@apply brightness-70;
}
</style>

View File

@ -9,17 +9,15 @@
import PageTransition from "$lib/PageTransition.svelte";
import type { LayoutData } from "./$types";
const title = $page.url.pathname.startsWith("/blog")
? `${$page.data.title} | Project Segfault blog`
: `${$page.data.title} | Project Segfault`;
export let data: LayoutData;
</script>
<svelte:head>
<title
>{$page.data.title} | Project Segfault {$page.url.pathname.startsWith(
"/blog"
)
? "blog"
: ""}</title
>
<title>{title}</title>
{#if $page.data.description}
<meta
name="description"

View File

@ -5,11 +5,11 @@ import { get } from "svelte/store";
export const load = (async () => {
const meta = {
title: "Home",
description: "Open source development and hosted services."
description: "Open-source development and hosted services."
};
return {
announcements: get(announcements),
...meta
}
};
}) satisfies PageServerLoad;

View File

@ -12,7 +12,7 @@
We have a Matrix space for general discussion, support and announcements
about Project Segfault over at <a
href="https://matrix.to/#/#project-segfault:projectsegfau.lt/"
>this link</a
>#project-segfault:projectsegfau.lt</a
>.
</p>
@ -20,7 +20,8 @@
<p>
We have an XMPP MUC for general discussion about Project Segfault over at <a
href="https://join.jabber.network/#general@conference.projectsegfau.lt?join">this link</a
href="https://join.jabber.network/#general@conference.projectsegfau.lt?join"
>#general@conference.projectsegfau.lt</a
>.
</p>
@ -44,7 +45,7 @@
<h2>Members</h2>
<p>
You can contact individual members by using the links provided in <a
href="/team">the team page</a
You can contact individual members by using the links provided in the <a
href="/team">team page</a
>.
</p>

View File

@ -7,7 +7,7 @@
<h1>{data.title}</h1>
<h2>What we do with donations</h2>
<h2>What we do with donations?</h2>
<p>
These donations primarily help us pay for our VPSes, domain names and other
@ -27,7 +27,7 @@
<a
href="https://liberapay.com/ProjectSegfault/donate"
class="button !bg-amber !text-black w-fit"
><div class="i-simple-icons:liberapay" />
><div class="va-icon i-simple-icons:liberapay" />
Liberapay</a
>
@ -46,23 +46,50 @@
and <a href="https://electrum-ltc.org">Electrum-LTC</a>.
</p>
<h4>Monero</h4>
<p class="text-text font-bold mt-4">
<i
class="va-icon i-simple-icons:monero inline-block text-[#F60]"
aria-hidden="true"
/>
Monero
</p>
<CryptoInfo
name="Monero"
address="47L7Qsto7XcifY3CdG18ySe5Tt83kpFLDLve9jQwbc9taPBLNGv6ZrJNUKpMG9Nj9zHgCZ4FQMSyt75e8Jvx12JFLtJyFdA"
qr="Monero.png"
/>
<h4>Bitcoin</h4>
<p class="text-text font-bold mt-4">
<i
class="va-icon i-simple-icons:bitcoin inline-block text-[#F7931A]"
aria-hidden="true"
/>
Bitcoin
</p>
<CryptoInfo
name="Bitcoin"
address="bc1qrc8ywgp95a6p3zausp4nff70qzstp6h8z86sxd"
qr="Bitcoin.png"
/>
<h4>Litecoin</h4>
<p class="text-text font-bold mt-4">
<i
class="va-icon i-simple-icons:litecoin inline-block text-[#A6A9AA]"
aria-hidden="true"
/>
Litecoin
</p>
<CryptoInfo
name="Litecoin"
address="ltc1qn3ald586h2ntt0n3zkvwsmju2e5vndgtvvgatj"
qr="Litecoin.png"
/>
<style>
.va-icon {
vertical-align: -0.125em;
}
</style>

View File

@ -1,4 +1,5 @@
<script lang="ts">
export let name: string = "";
export let address: string = "";
export let qr: string = "";
</script>
@ -13,10 +14,16 @@
{#if qr}
<details class="p-0">
<summary>QR code</summary>
<img
src="/qr/{qr}"
alt="QR code"
class="mt-2"
/>
<a
href="/qr/{qr}"
target="_blank"
rel="noreferrer"
>
<img
src="/qr/{qr}"
alt="QR code to {name} address"
class="mt-2"
/>
</a>
</details>
{/if}

View File

@ -1,10 +1,18 @@
import instances from "./instances";
import type { PageServerLoad } from "./$types";
export const load = (() => {
export const load = (({ url }) => {
const meta = {
title: "Instances"
};
return { instances, ...meta };
// If the ?short url query exists, then longUrl is false
// Every other case is true
const queryLongUrl = !url.searchParams.has("short");
return {
instances,
queryLongUrl,
...meta
};
}) satisfies PageServerLoad;

View File

@ -3,95 +3,112 @@
export let data: PageData;
let insturl: "short" | "long";
$: longUrl = data.queryLongUrl;
let toggle = () => {
insturl = insturl === "long" ? "short" : "long";
longUrl = !longUrl;
};
insturl = "long";
</script>
<div class="h1-no-lg flex flex-col sm:(flex-row items-center) gap-4 !mb-0">
<span class="text-4xl font-bold">{data.title}</span>
<!-- With JavaScript -->
<a
href="/instances/advanced"
class="button sm:w-fit"
><div class="i-ic:outline-computer" />
Advanced</a
>
<button
on:click={toggle}
class="text-text flex items-center text-sm"
>
<div
class="i-ic:{insturl === 'long'
? 'baseline-toggle-off bg-accent'
: 'baseline-toggle-on bg-amber-500'} h-15 w-15"
/>
{#if insturl === "long"}
Long URL
{:else}
Short URL
{/if}
</button>
<button
on:click={toggle}
class="text-text flex items-center text-sm js"
>
<div
class="i-ic:{longUrl
? 'baseline-toggle-off bg-alt'
: 'baseline-toggle-on bg-accent'} h-15 w-15"
/>
Use short URL
</button>
<!-- Without JavaScript -->
<noscript>
<a
href="?{data.queryLongUrl ? 'short' : ''}"
class="text-text flex items-center text-sm"
>
<div
class="i-ic:{data.queryLongUrl
? 'baseline-toggle-off bg-alt'
: 'baseline-toggle-on bg-accent'} h-15 w-15"
/>
Use short URL
</a>
<style>
.js {
display: none;
}
</style>
</noscript>
</div>
<div class="flex flex-col">
{#if insturl === "long"}
{#each data.instances as category}
<div class="flex flex-col">
<h2>{category.name}</h2>
<div class="flex flex-row flex-wrap gap-4">
{#each category.data as instance}
<a
href={instance.geo || instance.eu}
class="flex flex-row items-center gap-4 rounded bg-secondary p-4 w-110 no-underline text-text"
>
{#if instance.icon}
<img
src={instance.icon}
alt="{instance.name} logo"
class="h-20 rounded"
/>
{/if}
<div>
<span class="text-2xl">{instance.name}</span>
<p>{instance.description}</p>
</div>
</a>
{/each}
{#if longUrl}
{#each data.instances as category}
<div class="flex flex-col">
<h2>{category.name}</h2>
<div class="flex flex-row flex-wrap gap-4">
{#each category.data as instance}
<a
href={instance.geo || instance.eu}
class="flex flex-row items-center gap-4 rounded bg-secondary p-4 w-110 no-underline text-text"
>
{#if instance.icon}
<img
src={instance.icon}
alt="{instance.name} logo"
class="h-20 rounded"
/>
{/if}
<div>
<span class="text-2xl">{instance.name}</span>
<p>{instance.description}</p>
</div>
</a>
{/each}
</div>
</div>
</div>
{/each}
{/each}
{:else}
{#each data.instances as category}
<div class="flex flex-col">
<h2>{category.name}</h2>
<div class="flex flex-row flex-wrap gap-4">
{#each category.data as instance}
<a
href={instance.short_geo || instance.short_eu || instance.geo || instance.eu}
class="flex flex-row items-center gap-4 rounded bg-secondary p-4 w-110 no-underline text-text"
>
{#if instance.icon}
<img
src={instance.icon}
alt="{instance.name} logo"
class="h-20 rounded"
/>
{/if}
<div>
<span class="text-2xl">{instance.name}</span>
<p>{instance.description}</p>
</div>
</a>
{/each}
{#each data.instances as category}
<div class="flex flex-col">
<h2>{category.name}</h2>
<div class="flex flex-row flex-wrap gap-4">
{#each category.data as instance}
<a
href={instance.short_geo ||
instance.short_eu ||
instance.geo ||
instance.eu}
class="flex flex-row items-center gap-4 rounded bg-secondary p-4 w-110 no-underline text-text"
>
{#if instance.icon}
<img
src={instance.icon}
alt="{instance.name} logo"
class="h-20 rounded"
/>
{/if}
<div>
<span class="text-2xl">{instance.name}</span>
<p>{instance.description}</p>
</div>
</a>
{/each}
</div>
</div>
</div>
{/each}
{/each}
{/if}
</div>

View File

@ -18,50 +18,56 @@
{#each data.instances as category}
{#each category.data as instance}
<h2>{instance.name}</h2>
<div class="flex flex-row gap-2">
<ul class="instances flex flex-row flex-wrap gap-2">
{#if instance.geo}
<a href={instance.geo}>GeoDNS</a>
<li><a href={instance.geo}>GeoDNS</a></li>
{/if}
{#if instance.eu}
<a href={instance.eu}>EU</a>
<li><a href={instance.eu}>EU</a></li>
{/if}
{#if instance.us}
<a href={instance.us}>US</a>
<li><a href={instance.us}>US</a></li>
{/if}
{#if instance.in}
<a href={instance.in}>IN</a>
<li><a href={instance.in}>IN</a></li>
{/if}
{#if instance.bp}
<a href={instance.bp}>Backup</a>
<li><a href={instance.bp}>Backup</a></li>
{/if}
{#if instance.short_geo}
<a href={instance.short_geo}>GeoDNS (Short URL)</a>
<li><a href={instance.short_geo}>GeoDNS (Short URL)</a></li>
{/if}
{#if instance.short_eu}
<a href={instance.short_eu}>EU (Short URL)</a>
<li><a href={instance.short_eu}>EU (Short URL)</a></li>
{/if}
{#if instance.short_us}
<a href={instance.short_us}>US (Short URL)</a>
<li><a href={instance.short_us}>US (Short URL)</a></li>
{/if}
{#if instance.short_in}
<a href={instance.short_in}>IN (Short URL)</a>
<li><a href={instance.short_in}>IN (Short URL)</a></li>
{/if}
{#if instance.short_bp}
<a href={instance.short_bp}>Backup (Short URL)</a>
<li><a href={instance.short_bp}>Backup (Short URL)</a></li>
{/if}
{#if instance.tor}
<a href={instance.tor}>Tor</a>
<li><a href={instance.tor}>Tor</a></li>
{/if}
{#if instance.torBp}
<a href={instance.torBp}>Tor backup</a>
<li><a href={instance.torBp}>Tor backup</a></li>
{/if}
{#if instance.i2p}
<a href={instance.i2p}>I2P</a>
<li><a href={instance.i2p}>I2P</a></li>
{/if}
{#if instance.i2pBp}
<a href={instance.i2pBp}>I2P backup</a>
<li><a href={instance.i2pBp}>I2P backup</a></li>
{/if}
</div>
</ul>
{/each}
{/each}
</div>
<style>
.instances li:not(:last-child)::after {
content: ",";
}
</style>

View File

@ -29,7 +29,7 @@ const instances: Instances[] = [
data: [
{
name: "Invidious",
description: "A frontend for YouTube.",
description: "A front-end for YouTube.",
eu: "https://invidious.projectsegfau.lt/",
short_eu: "https://i.psf.lt/",
us: "https://inv.us.projectsegfau.lt/",
@ -46,7 +46,7 @@ const instances: Instances[] = [
},
{
name: "Piped",
description: "Another frontend for YouTube.",
description: "Another front-end for YouTube.",
eu: "https://piped.projectsegfau.lt/",
short_eu: "https://pi.psf.lt/",
us: "https://piped.us.projectsegfau.lt/",
@ -57,7 +57,7 @@ const instances: Instances[] = [
},
{
name: "Libreddit",
description: "A frontend for Reddit.",
description: "A front-end for Reddit.",
geo: "https://libreddit.projectsegfau.lt/",
short_geo: "https://lr.psf.lt/",
eu: "https://libreddit.eu.projectsegfau.lt/",
@ -72,7 +72,7 @@ const instances: Instances[] = [
},
{
name: "Nitter",
description: "A frontend for Twitter.",
description: "A front-end for Twitter.",
geo: "https://nitter.projectsegfau.lt/",
short_geo: "https://n.psf.lt/",
eu: "https://nitter.eu.projectsegfau.lt/",
@ -87,7 +87,7 @@ const instances: Instances[] = [
},
{
name: "AnonymousOverflow",
description: "A frontend for StackOverflow.",
description: "A front-end for StackOverflow.",
geo: "https://overflow.projectsegfau.lt/",
short_geo: "https://o.psf.lt/",
eu: "https://overflow.eu.projectsegfau.lt/",
@ -101,7 +101,7 @@ const instances: Instances[] = [
},
{
name: "BreezeWiki",
description: "A frontend for Fandom.",
description: "A front-end for Fandom.",
geo: "https://bw.projectsegfau.lt/",
short_geo: "https://bw.psf.lt/",
eu: "https://bw.eu.projectsegfau.lt/",
@ -116,7 +116,7 @@ const instances: Instances[] = [
},
{
name: "GotHub",
description: "A frontend for GitHub.",
description: "A front-end for GitHub.",
geo: "https://gothub.projectsegfau.lt/",
short_geo: "https://gh.psf.lt/",
eu: "https://gothub.eu.projectsegfau.lt/",
@ -130,7 +130,7 @@ const instances: Instances[] = [
},
{
name: "HyperPipe",
description: "A frontend for YT Music.",
description: "A front-end for YT Music.",
geo: "https://hyperpipe.projectsegfau.lt/",
short_geo: "https://hp.psf.lt/",
eu: "https://hyperpipe.eu.projectsegfau.lt/",
@ -143,7 +143,7 @@ const instances: Instances[] = [
},
{
name: "Rimgo",
description: "A frontend for Imgur.",
description: "A front-end for Imgur.",
geo: "https://rimgo.projectsegfau.lt/",
short_geo: "https://rg.psf.lt/",
eu: "https://rimgo.eu.projectsegfau.lt/",
@ -157,7 +157,7 @@ const instances: Instances[] = [
},
{
name: "Safetwitch",
description: "A frontend for Twitch.",
description: "A front-end for Twitch.",
geo: "https://safetwitch.projectsegfau.lt/",
short_geo: "https://tw.psf.lt/",
eu: "https://safetwitch.eu.projectsegfau.lt/",
@ -171,7 +171,7 @@ const instances: Instances[] = [
},
{
name: "Scribe",
description: "A frontend for Medium.",
description: "A front-end for Medium.",
geo: "https://scribe.projectsegfau.lt/",
short_geo: "https://sc.psf.lt/",
eu: "https://scribe.eu.projectsegfau.lt/",
@ -185,7 +185,7 @@ const instances: Instances[] = [
},
{
name: "SimplyTranslate",
description: "A frontend for many translation engines.",
description: "A front-end for many translation engines.",
geo: "https://simplytranslate.projectsegfau.lt/",
short_geo: "https://tl.psf.lt/",
eu: "https://simplytranslate.eu.projectsegfau.lt/",
@ -198,7 +198,7 @@ const instances: Instances[] = [
},
{
name: "Teddit",
description: "Another frontend for Reddit.",
description: "Another front-end for Reddit.",
geo: "https://teddit.projectsegfau.lt/",
short_geo: "https://t.psf.lt/",
eu: "https://teddit.eu.projectsegfau.lt/",
@ -209,7 +209,7 @@ const instances: Instances[] = [
short_in: "https://t.in.psf.lt/",
tor: "http://teddit.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
icon: "/icons/teddit.png"
},
}
]
},
{
@ -217,7 +217,8 @@ const instances: Instances[] = [
data: [
{
name: "Matrix",
description: "An open network for secure, decentralized communication.",
description:
"An open network for secure, decentralized communication.",
eu: "https://wiki.projectsegfau.lt/Matrix",
short_eu: "https://w.psf.lt/Matrix",
icon: "/icons/matrix.svg"
@ -258,7 +259,7 @@ const instances: Instances[] = [
},
{
name: "SearXNG",
description: "A private meta-search engine.",
description: "A private metasearch engine.",
eu: "https://search.projectsegfau.lt/",
short_eu: "https://s.psf.lt/",
us: "https://search.us.projectsegfau.lt/",
@ -271,7 +272,8 @@ const instances: Instances[] = [
},
{
name: "Gitea",
description: "A web interface for Git, alternative to GitHub.",
description:
"A web interface for Git. An alternative to GitHub.",
eu: "https://git.projectsegfau.lt/",
short_eu: "https://git.psf.lt/",
tor: "http://git.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
@ -280,14 +282,14 @@ const instances: Instances[] = [
},
{
name: "Hedgedoc",
description: "Collaborative markdown notes.",
description: "Collaborative Markdown notes.",
eu: "https://doc.projectsegfau.lt/",
short_eu: "https://d.psf.lt/",
icon: "/icons/hedgedoc.svg"
},
{
name: "LibreTranslate",
description: "Free and Open Source Machine Translation API.",
description: "Free and open-source machine translation API.",
in: "https://libretranslate.projectsegfau.lt",
short_in: "https://lt.psf.lt/",
icon: "/icons/libretranslate.png"
@ -301,7 +303,7 @@ const instances: Instances[] = [
},
{
name: "Kbin",
description: "Federated reddit alternative.",
description: "Federated Reddit alternative.",
eu: "https://kbin.projectsegfau.lt/",
short_eu: "https://kb.psf.lt/",
icon: "/icons/kbin.svg"
@ -317,28 +319,28 @@ const instances: Instances[] = [
},
{
name: "Jitsi",
description: "An open source video conferencing platform.",
description: "An open-source video conferencing platform.",
eu: "https://jitsi.projectsegfau.lt/",
short_eu: "https://j.psf.lt/",
icon: "/icons/jitsi.svg"
},
{
name: "Vaultwarden",
description: "An open source password manager.",
description: "An open-source password manager.",
eu: "https://pass.projectsegfau.lt/",
short_eu: "https://vw.psf.lt/",
tor: "http://pass.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion",
icon: "/icons/vaultwarden.svg"
},
{
name: "Plausible analytics",
name: "Plausible Analytics",
description: "Analytics for our website.",
eu: "https://analytics.projectsegfau.lt/",
icon: "/icons/plausible.png"
},
{
name: "Healthchecks",
description: "Simple and Effective Cron Job Monitoring.",
description: "Simple and effective cron job monitoring.",
eu: "https://healthchecks.projectsegfau.lt/",
short_eu: "https://hc.psf.lt/",
icon: "/icons/healthchecks.svg"
@ -358,7 +360,8 @@ const instances: Instances[] = [
data: [
{
name: "Pubnix",
description: "A Unix server open to the public with non-commercial recreational goals.",
description:
"A Unix server open to the public for non-commercial recreational usage.",
eu: "https://p.projectsegfau.lt/",
short_eu: "https://p.psf.lt/",
icon: "/icons/pubnix.png"
@ -399,14 +402,15 @@ const instances: Instances[] = [
},
{
name: "SimpleLogin",
description: "An open source email alias creator/manager",
description: "An open-source email alias creator/manager",
eu: "https://sl.projectsegfau.lt/",
short_eu: "https://sl.psf.lt/",
icon: "/icons/simplelogin.svg"
},
{
name: "Dendrite",
description: "Another matrix server, running on Project Segfault's India node!",
description:
"Another Matrix server running on Project Segfault's India node!",
eu: "https://w.psf.lt/Matrix#Dendrite",
icon: "/icons/matrix.svg"
}

View File

@ -24,22 +24,22 @@
<h3>What do I do if a user is disturbing me?</h3>
<p>
If some user of our services is disturbing you, you should immediately
contact us. You can do that either by <a
href="mailto:contact@projectsegfau.lt">emailing us</a
If you are being disturbed by a user on our services, then you should
immediately contact us. You can do that by sending us an <a
href="mailto:contact@projectsegfau.lt">email</a
>
or sending us a message on
<a href="https://matrix.to/#/#support:projectsegfau.lt"
>the Matrix support channel</a
>. If you prefer to keep your report private on Matrix, contact one of our
team members. You can find their info on <a href="/team">our team page</a>.
or through our Matrix
<a href="https://matrix.to/#/#support:projectsegfau.lt">support channel</a>.
If you prefer to keep your report private on Matrix, contact one of our team
members directly. You can find their info on our
<a href="/team">team page</a>.
</p>
<h3>How can I trust you?</h3>
<p>
We have written a privacy policy, which is accessible through this website!
You can find it <a href="/legal/privacy-policy">here</a>.
We have a <a href="/legal/privacy-policy">privacy policy</a> which outlines how
we collect and handle your data.
</p>
<style>

View File

@ -12,20 +12,20 @@
Do not use our services to (D)DOS or attempt to disrupt someone elses
online stability.
</li>
<li>Do not use our services to dox someone.</li>
<li>
<li class="mt-2">Do not use our services to dox someone.</li>
<li class="mt-2">
Do not do anything on our services that would be illegal in France, the
USA, Luxembourg, and India. (Example: CSAM, Loli, Drugs etc...)
</li>
<li>Do not harass people using our services.</li>
<li>
<li class="mt-2">Do not harass people using our services.</li>
<li class="mt-2">
While we do try to keep your data safe, you have to acknowledge that we
are not responsible if anything unintentional happens (such as data
loss, inability to extract your data due to the server being down or
something else.). It is also your responsibility to keep a backup of
your data if it matters to you.
</li>
<li>
<li class="mt-2">
The services provided by Project Segfault are provided as is. We do not
warrant the reliability, accessibility or quality of our services and we
are not responsible for ANY DAMAGES WHATSOEVER by using our services.

View File

@ -10,5 +10,5 @@ export const load = (async () => {
return {
users: get(pubnixUsers),
...meta
}
};
}) satisfies PageServerLoad;

View File

@ -49,28 +49,38 @@
</div>
<div class="children:text-text flex flex-row items-center gap-4 text-lg">
{#if user.email}
<a href="mailto:{user.email}"><div class="i-ic:outline-email" /></a>
<a
href="mailto:{user.email}"
aria-label="Email"><div class="i-ic:outline-email" /></a
>
{/if}
{#if user.matrix}
<a href="https://matrix.to/#/{user.matrix}"
><div class="i-simple-icons:matrix" /></a
<a
href="https://matrix.to/#/{user.matrix}"
aria-label="Matrix"><div class="i-simple-icons:matrix" /></a
>
{/if}
{#if user.fediverse}
<a href="https://{user.fediverse}"
<a
href="https://{user.fediverse}"
aria-label="Fediverse"
><div class="i-simple-icons:mastodon" /></a
>
{/if}
{#if user.website}
<a href={user.website}><div class="i-ic:outline-language" /></a>
<a
href={user.website}
aria-label="Website"><div class="i-ic:outline-language" /></a
>
{/if}
{#if user.capsule}
<a
href="https://geminiproxy.p.projectsegfau.lt/gemini/{user.capsule}"
aria-label="Gemini"
class="no-underline text-base">Gemini</a
>
{/if}

View File

@ -22,16 +22,15 @@
>
<h2>How do I get started?</h2>
<span
>First, you need to register an account. You can do that <a
href="/pubnix/register">here</a
>. After registering, you need to wait a while because we manually check
each registration. If you get accepted, you will receive an email.</span
>First, you need to <a href="/pubnix/register">register an account</a>.
After registering, you need to wait a while because we manually check each
registration. If you get accepted, you will receive an email.</span
>
<h2>What's your systems specs?</h2>
<h2>What are your system's specs?</h2>
<span>Guess you'll have to find out. Join today!</span>
<h2>I joined, but I have no idea what to do.</h2>
<span
>No worries! We have put out tutorials on how to do common things on our <a
>No worries! We put out tutorials on how to do common things on our <a
href="https://wiki.projectsegfau.lt/index.php?title=Category%3APubnix"
>wiki</a
>.</span
@ -41,6 +40,9 @@
>Yep! We have a <a href="https://matrix.to/#/#pubnix:projectsegfau.lt"
>Matrix room</a
>
and an <a href="https://join.jabber.network/#pubnix@conference.projectsegfau.lt?join">XMPP MUC</a> to
discuss the pubnix.</span
and an
<a
href="https://join.jabber.network/#pubnix@conference.projectsegfau.lt?join"
>XMPP MUC</a
> to discuss the pubnix.</span
>

View File

@ -5,7 +5,7 @@
export let data: PageData;
let siteKey = "cb477b1b-6f87-43ee-aa79-71e3302fbb34";
//export const hcaptchaSiteKey = env.HCAPTCHA_SITE_KEY;
//export const hcaptchaSiteKey = env.HCAPTCHA_SITE_KEY;
</script>
<h1>{data.title}</h1>
@ -47,13 +47,10 @@
rows="5"
required
/>
<div>
<label for="h-captcha-response"
><HCaptcha sitekey={siteKey} />
</label>
</div>
<div>
<label for="h-captcha-response"><HCaptcha sitekey={siteKey} /> </label>
</div>
{#if form?.success}
@ -64,8 +61,18 @@
{form.message}
{/if}
<div style="display:block;" >
<input type="checkbox" style="display:inline-block;width: 1em;margin-right: 10px;" required><p style="display:inline-block;word-break: break-all;">I agree to the <a href="/legal/tos">Terms of Service</p>.
<div style="display:block;">
<input
id="tos"
type="checkbox"
required
/>
<label
for="tos"
style="display:inline-block;word-break: break-all;"
>
I agree to the <a href="/legal/tos">Terms of Service</a>.
</label>
</div>
<button
@ -81,12 +88,20 @@
form > div {
@apply flex flex-col items-start gap-2 w-fit;
}
form > div > label {
form label:not([for="tos"]) {
@apply text-xl font-semibold;
}
form > div > input,
form > div > textarea,
form > button {
@apply w-110 lt-sm\:w-70 px-2 py-1 bg-secondary rounded flex items-center gap-2 text-lg;
form input,
form textarea,
form button {
@apply w-110 lt-sm\:w-70 px-2 py-1 bg-secondary rounded flex justify-center items-center gap-2 text-lg;
border: 1pt solid var(--alt);
}
form input[type="checkbox"] {
display: inline-block;
width: min-content;
}
</style>

View File

@ -10,5 +10,5 @@ export const load = (async () => {
return {
users: get(pubnixUsers),
...meta
}
};
}) satisfies PageServerLoad;

View File

@ -20,40 +20,55 @@
</div>
<div class="children:text-text flex flex-row gap-4 text-lg">
{#if member.website}
<a href={member.website}
<a
href={member.website}
aria-label="Website"
><div class="i-ic:outline-language" /></a
>
{/if}
{#if member.matrix}
<a href={member.matrix}
<a
href={member.matrix}
aria-label="Matrix"
><div class="i-simple-icons:matrix" /></a
>
{/if}
{#if member.xmpp}
<a href={member.xmpp}><div class="i-simple-icons:xmpp" /></a
<a
href={member.xmpp}
aria-label="XMPP"><div class="i-simple-icons:xmpp" /></a
>
{/if}
{#if member.fedi}
<a href={member.fedi}
<a
href={member.fedi}
aria-label="Fediverse"
><div class="i-simple-icons:mastodon" /></a
>
{/if}
{#if member.git}
<a href={member.git}><div class="i-simple-icons:git" /></a>
<a