forked from pub-solar/pub.solar
Merge pull request 'feature/lume' (#3) from feature/lume into main
Reviewed-on: https://git.b12f.io/pub-solar/pub.solar/pulls/3
This commit is contained in:
commit
c87243145c
22
.drone.yml
22
.drone.yml
|
@ -1,13 +1,25 @@
|
|||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
when:
|
||||
events:
|
||||
- push
|
||||
- pull_request
|
||||
image: denoland/deno:alpine
|
||||
commands:
|
||||
- deno run -A https://deno.land/x/lume@v1.6.4/install.ts
|
||||
- deno task build
|
||||
|
||||
- name: publish
|
||||
when:
|
||||
events:
|
||||
- push
|
||||
branch:
|
||||
- main
|
||||
image: appleboy/drone-scp
|
||||
repo: pub-solar/pub.solar
|
||||
settings:
|
||||
host: pub.solar
|
||||
port: 2020
|
||||
|
@ -16,12 +28,6 @@ steps:
|
|||
key:
|
||||
from_secret: ps_ssh_key
|
||||
source:
|
||||
- "!.envrc"
|
||||
- "!.git"
|
||||
- "!.gitignore"
|
||||
- "!.drone.yml"
|
||||
- "!LICENSE.md"
|
||||
- "!shell.nix"
|
||||
- ./*
|
||||
- ./_site/*
|
||||
target: /srv/pub.solar/
|
||||
overwrite: true
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
tags
|
||||
.direnv
|
||||
_site
|
||||
|
|
29
_config.ts
Normal file
29
_config.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import lume from "https:/deno.land/x/lume/mod.ts";
|
||||
import sass from "https:/deno.land/x/lume/plugins/sass.ts";
|
||||
import date from "https:/deno.land/x/lume/plugins/date.ts";
|
||||
import jsx from "https:/deno.land/x/lume/plugins/jsx.ts";
|
||||
import terser from "https:/deno.land/x/lume/plugins/terser.ts";
|
||||
import postcss from "https:/deno.land/x/lume/plugins/postcss.ts";
|
||||
|
||||
const site = lume();
|
||||
|
||||
site.use(sass());
|
||||
site.use(date());
|
||||
site.use(jsx());
|
||||
site.use(terser());
|
||||
site.use(postcss());
|
||||
|
||||
site.loadAssets([
|
||||
".png",
|
||||
".jpg",
|
||||
".svg",
|
||||
".pdf",
|
||||
".woff2",
|
||||
".woff",
|
||||
".ttf",
|
||||
".otf",
|
||||
".js",
|
||||
".txt",
|
||||
]);
|
||||
|
||||
export default site;
|
1
_data/cacheBust.yml
Normal file
1
_data/cacheBust.yml
Normal file
|
@ -0,0 +1 @@
|
|||
'?v=1'
|
18
_includes/Background.tsx
Normal file
18
_includes/Background.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import Logo from './Logo.tsx';
|
||||
|
||||
const x1312 = (new Array(400)).fill("0x1312").join(" ");
|
||||
|
||||
export default () => <div
|
||||
id="background"
|
||||
className="ps-background ps-main--background"
|
||||
>
|
||||
<div
|
||||
id="x1312"
|
||||
className="ps-background--1312"
|
||||
>{x1312}</div>
|
||||
<script
|
||||
src="/scripts/background.js"
|
||||
async
|
||||
></script>
|
||||
<Logo className="ps-background--logo" />
|
||||
</div>;
|
66
_includes/DefaultLayout.tsx
Normal file
66
_includes/DefaultLayout.tsx
Normal file
|
@ -0,0 +1,66 @@
|
|||
import {
|
||||
title as titleFilter,
|
||||
en,
|
||||
de,
|
||||
md,
|
||||
} from '../../filters.ts';
|
||||
import Background from '../../components/Background.tsx';
|
||||
|
||||
export default ({ title, theme, extraStylesheets, content, cssCacheBust }) => <>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>{ titleFilter(title) }</title>
|
||||
|
||||
<link rel="shortcut icon" href="/assets/pubsolar.svg" />
|
||||
|
||||
<meta name="theme-color" content="{{ theme.color }}" id="theme-color" />
|
||||
<meta name="description" content="pub.solar wants you to have control of your data and privacy. We host Matrix, Nextcloud, and Mastodon for you to use." />
|
||||
|
||||
<meta id="viewport" name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/style.css?1" media="all" />
|
||||
|
||||
<>
|
||||
{(extraStylesheets || [])
|
||||
.map(extraStylesheet => <link rel="stylesheet" type="text/css" href="{{ extraStylesheet }}{{ cssCacheBust }}" media="all" />)}
|
||||
</>
|
||||
</head>
|
||||
<body className="ps-main">
|
||||
<Background />
|
||||
<main className="ps-main--page ps-page">
|
||||
<section
|
||||
lang="en"
|
||||
id="en"
|
||||
className="ps-page--section"
|
||||
>
|
||||
<a
|
||||
className="ps-page--section-link"
|
||||
href="#de"
|
||||
>Deutsche übersetzung unten</a>
|
||||
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: md(content.en) }}
|
||||
className="ps-page--section-contents"
|
||||
></div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
lang="de"
|
||||
id="de"
|
||||
className="ps-page--section"
|
||||
>
|
||||
<a
|
||||
className="ps-page--section-link"
|
||||
href="#en"
|
||||
>English translation above</a>
|
||||
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: md(content.de) }}
|
||||
className="ps-page--section-contents"
|
||||
></div>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
</>;
|
1
_includes/HakkenDates.tsx
Normal file
1
_includes/HakkenDates.tsx
Normal file
|
@ -0,0 +1 @@
|
|||
export default ({ lang }) => <div id={`dates-list-${lang}`}></div>;
|
30
_includes/Head.tsx
Normal file
30
_includes/Head.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { title as titleFilter } from '../filters.ts';
|
||||
|
||||
export default ({
|
||||
title,
|
||||
theme,
|
||||
extraStylesheets,
|
||||
extraScripts,
|
||||
cacheBust,
|
||||
}) => <head>
|
||||
<meta charset="utf-8" />
|
||||
<title>{ titleFilter(title) }</title>
|
||||
|
||||
<link rel="shortcut icon" href="/assets/pubsolar.svg" />
|
||||
|
||||
<meta name="theme-color" content="{{ theme.color }}" id="theme-color" />
|
||||
<meta name="description" content="pub.solar wants you to have control of your data and privacy. We host Matrix, Nextcloud, and Mastodon for you to use." />
|
||||
|
||||
<meta id="viewport" name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href={`/style.css${cacheBust}`} media="all" />
|
||||
|
||||
<>
|
||||
{(extraStylesheets || [])
|
||||
.map(extraStylesheet => <link rel="stylesheet" type="text/css" href={`${extraStylesheet}${cacheBust}`} media="all" />)}
|
||||
</>
|
||||
<>
|
||||
{(extraScripts || [])
|
||||
.map(extraScript => <script defer type="application/javascript" src={`${extraScript}${cacheBust}`}></script>)}
|
||||
</>
|
||||
</head>;
|
1
_includes/Homelink.tsx
Normal file
1
_includes/Homelink.tsx
Normal file
|
@ -0,0 +1 @@
|
|||
export default () => <a className="ps-homelink" href="/">pub.solar/</a>;
|
11
_includes/Logo.tsx
Normal file
11
_includes/Logo.tsx
Normal file
File diff suppressed because one or more lines are too long
71
_includes/layouts/default.tsx
Normal file
71
_includes/layouts/default.tsx
Normal file
|
@ -0,0 +1,71 @@
|
|||
import { md } from '../../filters.ts';
|
||||
import Head from '../Head.tsx';
|
||||
import Background from '../Background.tsx';
|
||||
import Homelink from '../Homelink.tsx';
|
||||
import HakkenDates from '../HakkenDates.tsx';
|
||||
|
||||
export default ({
|
||||
title,
|
||||
content,
|
||||
|
||||
theme,
|
||||
extraStylesheets,
|
||||
extraScripts,
|
||||
cacheBust,
|
||||
|
||||
showHakkenDates,
|
||||
}) => <>
|
||||
<html>
|
||||
<Head
|
||||
title={title}
|
||||
theme={theme}
|
||||
extraStylesheets={extraStylesheets}
|
||||
cacheBust={cacheBust}
|
||||
extraScripts={extraScripts}
|
||||
/>
|
||||
<body className="ps-main">
|
||||
|
||||
<Background />
|
||||
|
||||
<Homelink />
|
||||
|
||||
<main className="ps-main--page ps-page">
|
||||
<section
|
||||
lang="en"
|
||||
id="en"
|
||||
className="ps-page--section"
|
||||
>
|
||||
<a
|
||||
className="ps-page--section-link"
|
||||
href="#de"
|
||||
>Deutsche übersetzung unten</a>
|
||||
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: md(content.en) }}
|
||||
className="ps-page--section-contents"
|
||||
></div>
|
||||
|
||||
{showHakkenDates ? <HakkenDates lang="en" /> : null}
|
||||
</section>
|
||||
|
||||
<section
|
||||
lang="de"
|
||||
id="de"
|
||||
className="ps-page--section"
|
||||
>
|
||||
<a
|
||||
className="ps-page--section-link"
|
||||
href="#en"
|
||||
>English translation above</a>
|
||||
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: md(content.de) }}
|
||||
className="ps-page--section-contents"
|
||||
></div>
|
||||
|
||||
{showHakkenDates ? <HakkenDates lang="de" /> : null}
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
</>;
|
39
_includes/layouts/homepage.tsx
Normal file
39
_includes/layouts/homepage.tsx
Normal file
|
@ -0,0 +1,39 @@
|
|||
import Head from '../Head.tsx';
|
||||
import Background from '../Background.tsx';
|
||||
|
||||
export default ({
|
||||
title,
|
||||
content,
|
||||
links,
|
||||
|
||||
theme,
|
||||
extraStylesheets,
|
||||
extraScripts,
|
||||
cacheBust,
|
||||
|
||||
showHakkenDates,
|
||||
}) => <>
|
||||
<html>
|
||||
<Head
|
||||
title={title}
|
||||
theme={theme}
|
||||
extraStylesheets={extraStylesheets}
|
||||
cacheBust={cacheBust}
|
||||
extraScripts={extraScripts}
|
||||
/>
|
||||
<body className="ps-main">
|
||||
<Background />
|
||||
<main className="ps-main--page ps-page ps-page_home">
|
||||
{links.map(({ href, title, openInNewTab }) =>
|
||||
<a href={href} target={openInNewTab ? '_blank' : '_self'} className="ps-page--link">{title}</a>
|
||||
)}
|
||||
<footer className="ps-footer">
|
||||
<a
|
||||
href="https://www.thegreenwebfoundation.org/green-web-check/?url=https%3A%2F%2Fpub.solar"
|
||||
className="ps-footer--link"
|
||||
>climate-neutral hosting by Greenbaum Cloud</a>
|
||||
</footer>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
</>;
|
94
about.html
94
about.html
File diff suppressed because one or more lines are too long
81
about.yml
Normal file
81
about.yml
Normal file
|
@ -0,0 +1,81 @@
|
|||
layout: layouts/default.tsx
|
||||
|
||||
title: About & Imprint
|
||||
|
||||
content:
|
||||
en: |
|
||||
# Hi! We're pub.solar
|
||||
|
||||
We are a non-registered association seated in Cologne, Germany. Our goal is to enable more people to use free software, have secure digital communications, and to take control over their private data. We offer free software for you and all the people you love. We do this transparently and democratically.
|
||||
|
||||
We currently have four larger projects:
|
||||
|
||||
* [Matrix](https://chat.pub.solar): a decentralized, end-to-end encrypted chat, similar to Slack or Discord.
|
||||
* [Mastodon](https://mastodon.pub.solar): a decentralized microblogging platform, similar to Twitter.
|
||||
* [Nextcloud](https://cloud.pub.solar): a cloud with office capabilities, similar to the Google Suite and Microsoft Office 365.
|
||||
* [PubSolarOS](https://get.pub.solar): a GNU+Linux Distribution that is based on NixOS.
|
||||
|
||||
Our Mastodon and Matrix instances are publicly open for registration. If you (or your non profit, or your family) would like to use our Nextcloud, send us a message.
|
||||
|
||||
You can reach us via [#General in Matrix](https://matrix.to/#/#general:pub.solar?via=chat.pub.solar) and [@crew on Mastodon](https://mastodon.pub.solar/@crew), or send a mail to [crew@pub.solar](mailto:crew@pub.solar).
|
||||
|
||||
## Imprint
|
||||
|
||||
pub.solar n.e.V.
|
||||
Benjamin Bädorf, Jhonas Wernery, Hendrik Sokolowki
|
||||
c/o MiOM 202,
|
||||
Wilhelm-Mauser-Straße 47 Halle 5,
|
||||
D-50827 Köln,
|
||||
[crew@pub.solar](mailto:crew@pub.solar)
|
||||
|
||||
## Our Statutes
|
||||
|
||||
Are over [here](https://cloud.pub.solar/s/2KErtaYeLn5d6MZ).
|
||||
|
||||
## Our Privacy Policy
|
||||
|
||||
Is over [here](https://pub.solar/privacy).
|
||||
|
||||
## Our hosting
|
||||
|
||||
Our friends at Greenbaum Cloud (Jhonas works there) are kindly providing us their infrastructure for hosting without charging us. Give them a visit.
|
||||
[]
|
||||
<a href=\"https://greenbaum.cloud\"><img src=\"/assets/greenbaum-cloud-logo.svg\" width=\"230\" height=\"auto\"></a>
|
||||
|
||||
de: |
|
||||
# Hi! Wir sind pub.solar
|
||||
|
||||
Wir sind ein nicht eingetragener Verein mit Sitz in Köln. Unser Ziel ist es mehr Menschen zu ermöglichen, Freie Software zu benutzen, sicher digital zu kommunizieren, und datensparsamer zu leben. Wir stellen für Dich und alle Menschen die Du lieb hast auf transparente und demokratische Weise Freie Software zur Verfügung.
|
||||
|
||||
Momentan haben wir vier größere Projekte:
|
||||
|
||||
* [Matrix](https://chat.pub.solar): dezentraler, Ende-zu-Ende verschlüsselter Chat, ähnlich wie Slack oder Discord
|
||||
* [Mastodon](https://mastodon.pub.solar): dezentrale Mikrobloggingplattform, ähnlich wie Twitter
|
||||
* [Nextcloud](https://cloud.pub.solar): Cloud mit Office Möglichkeiten, ähnlich wie Teile der Google Suite und Microsoft Office 365
|
||||
* [PubSolarOS](https://get.pub.solar), eine Linux Distribution die auf NixOS basiert
|
||||
|
||||
Auf unseren Mastodon und Matrix Instanzen ist die Registrierung für alle offen. Wenn Du (oder dein Verein, oder deine Familie) gerne unsere Nextcloud benutzen möchten, schreib uns gerne an.
|
||||
|
||||
Du kannst uns via [#General in Matrix](https://matrix.to/#/#general:pub.solar?via=chat.pub.solar) und [@crew auf Mastodon](https://mastodon.pub.solar/@crew) erreichen, oder eine Mail an [crew@pub.solar](mailto:crew@pub.solar) schicken.
|
||||
|
||||
## Impressum
|
||||
|
||||
pub.solar n.e.V.
|
||||
Benjamin Bädorf, Jhonas Wernery, Hendrik Sokolowki
|
||||
c/o MiOM 202,
|
||||
Wilhelm-Mauser-Straße 47 Halle 5,
|
||||
D-50827 Köln,
|
||||
[crew@pub.solar](mailto:crew@pub.solar)
|
||||
|
||||
### Unsere Satzung
|
||||
|
||||
Findest Du [hier](https://cloud.pub.solar/s/2KErtaYeLn5d6MZ).
|
||||
|
||||
## Unsere Datenschutzerklärung
|
||||
Findest Du [hier](https://pub.solar/privacy).
|
||||
|
||||
## Unser Hosting
|
||||
|
||||
Unsere Freunde bei der Firma Greenbaum Cloud (Jhonas arbeitet dort auch) sind so cool uns ihre Infrastruktur momentan gratis zur Verfügung zu stellen. Klickt gerne mal rein.
|
||||
<a href=\"https://greenbaum.cloud\"><img src=\"/assets/greenbaum-cloud-logo.svg\" width=\"230\" height=\"auto\"></a>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
document.getElementById('x1312').innerHTML = (new Array(400)).fill("0x1312").join(" ");
|
||||
const background = document.getElementById("background");
|
||||
const logo = document.getElementById("logo").cloneNode(true);
|
||||
logo.id = "";
|
||||
(new Array(Math.ceil(window.innerWidth / 100) * Math.ceil(window.innerHeight / 100)))
|
||||
.fill(null)
|
||||
.map(_ => logo.cloneNode(true))
|
||||
.forEach(l => {
|
||||
background.appendChild(l);
|
||||
});
|
12
deno.json
Normal file
12
deno.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"importMap": "import_map.json",
|
||||
"tasks": {
|
||||
"lume": "deno eval \"import 'lume/task.ts'\" --",
|
||||
"build": "deno task lume",
|
||||
"serve": "deno task lume -s"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "react"
|
||||
}
|
||||
}
|
31
filters.ts
Normal file
31
filters.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import MarkdownIt from "https://jspm.dev/markdown-it";
|
||||
|
||||
const mdIt = new MarkdownIt({
|
||||
html: false, // Enable HTML tags in source
|
||||
xhtmlOut: false, // Use '/' to close single tags (<br />).
|
||||
// This is only for full CommonMark compatibility.
|
||||
breaks: true, // Convert '\n' in paragraphs into <br>
|
||||
langPrefix: 'language-', // CSS language prefix for fenced blocks. Can be
|
||||
// useful for external highlighters.
|
||||
linkify: true, // Autoconvert URL-like text to links
|
||||
|
||||
// Enable some language-neutral replacement + quotes beautification
|
||||
// For the full list of replacements, see https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.js
|
||||
typographer: false,
|
||||
|
||||
// Double + single quotes replacement pairs, when typographer enabled,
|
||||
// and smartquotes on. Could be either a String or an Array.
|
||||
//
|
||||
// For example, you can use '«»„“' for Russian, '„“‚‘' for German,
|
||||
// and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp).
|
||||
quotes: '“”‘’',
|
||||
|
||||
// Highlighter function. Should return escaped HTML,
|
||||
// or '' if the source string is not changed and should be escaped externally.
|
||||
// If result starts with <pre... internal wrapper is skipped.
|
||||
highlight: function (/*str, lang*/) { return ''; }
|
||||
});
|
||||
|
||||
export const md = (string) => mdIt.render(string);
|
||||
|
||||
export const title = (value = '') => value + (value ? " | " : "") + "pub.solar";
|
198
hakken-dates.js
198
hakken-dates.js
|
@ -1,107 +1,109 @@
|
|||
const skippedMonths = [
|
||||
{ m: 8, y: 2022 },
|
||||
{ m: 12, y: 2022 },
|
||||
];
|
||||
(() => {
|
||||
const skippedMonths = [
|
||||
{ m: 8, y: 2022 },
|
||||
{ m: 12, y: 2022 },
|
||||
];
|
||||
|
||||
const i18n = {
|
||||
en: {
|
||||
comingDates: 'The following dates are scheduled:',
|
||||
friday: 'friday',
|
||||
sunday: 'sunday',
|
||||
until: 'until',
|
||||
months: [
|
||||
'Jan.',
|
||||
'Feb.',
|
||||
'Mar.',
|
||||
'Apr.',
|
||||
'May',
|
||||
'Jun.',
|
||||
'Jul.',
|
||||
'Aug.',
|
||||
'Sep.',
|
||||
'Oct.',
|
||||
'Nov.',
|
||||
'Dec.',
|
||||
],
|
||||
},
|
||||
de: {
|
||||
comingDates: 'Folgende Termine stehen an:',
|
||||
friday: 'Freitag',
|
||||
sunday: 'Sonntag',
|
||||
until: 'bis',
|
||||
months: [
|
||||
'Jan.',
|
||||
'Feb.',
|
||||
'Mär.',
|
||||
'Apr.',
|
||||
'Mai',
|
||||
'Jun.',
|
||||
'Jul.',
|
||||
'Aug.',
|
||||
'Sep.',
|
||||
'Okt.',
|
||||
'Nov.',
|
||||
'Dez.',
|
||||
],
|
||||
},
|
||||
};
|
||||
const i18n = {
|
||||
en: {
|
||||
comingDates: 'The following dates are scheduled:',
|
||||
friday: 'friday',
|
||||
sunday: 'sunday',
|
||||
until: 'until',
|
||||
months: [
|
||||
'Jan.',
|
||||
'Feb.',
|
||||
'Mar.',
|
||||
'Apr.',
|
||||
'May',
|
||||
'Jun.',
|
||||
'Jul.',
|
||||
'Aug.',
|
||||
'Sep.',
|
||||
'Oct.',
|
||||
'Nov.',
|
||||
'Dec.',
|
||||
],
|
||||
},
|
||||
de: {
|
||||
comingDates: 'Folgende Termine stehen an:',
|
||||
friday: 'Freitag',
|
||||
sunday: 'Sonntag',
|
||||
until: 'bis',
|
||||
months: [
|
||||
'Jan.',
|
||||
'Feb.',
|
||||
'Mär.',
|
||||
'Apr.',
|
||||
'Mai',
|
||||
'Jun.',
|
||||
'Jul.',
|
||||
'Aug.',
|
||||
'Sep.',
|
||||
'Okt.',
|
||||
'Nov.',
|
||||
'Dez.',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const datesLists = {
|
||||
en: document.getElementById('dates-list-en'),
|
||||
de: document.getElementById('dates-list-de'),
|
||||
};
|
||||
const datesLists = {
|
||||
en: document.getElementById('dates-list-en'),
|
||||
de: document.getElementById('dates-list-de'),
|
||||
};
|
||||
|
||||
const day = 24 * 60 * 60 * 1000;
|
||||
const week = 7 * day;
|
||||
const endOfWeekend = 2 * day;
|
||||
const start = new Date();
|
||||
const hakkens = [];
|
||||
// We'll be looking about half a year into the future
|
||||
for (let i = 0; i < 185; i++) {
|
||||
const dateToTry = new Date(start.valueOf() + (i * day));
|
||||
if (dateToTry.getDay() !== 5) {
|
||||
continue;
|
||||
const day = 24 * 60 * 60 * 1000;
|
||||
const week = 7 * day;
|
||||
const endOfWeekend = 2 * day;
|
||||
const start = new Date();
|
||||
const hakkens = [];
|
||||
// We'll be looking about half a year into the future
|
||||
for (let i = 0; i < 185; i++) {
|
||||
const dateToTry = new Date(start.valueOf() + (i * day));
|
||||
if (dateToTry.getDay() !== 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const oneWeekLater = new Date(dateToTry.valueOf() + week);
|
||||
if (dateToTry.getMonth() === oneWeekLater.getMonth()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const m = dateToTry.getMonth() + 1;
|
||||
const y = dateToTry.getFullYear();
|
||||
if (skippedMonths.find((s) => s.m === m && s.y === y)) {
|
||||
continue;
|
||||
}
|
||||
hakkens.push(dateToTry);
|
||||
}
|
||||
|
||||
const oneWeekLater = new Date(dateToTry.valueOf() + week);
|
||||
if (dateToTry.getMonth() === oneWeekLater.getMonth()) {
|
||||
continue;
|
||||
// Helper function to add leading zeros to dates
|
||||
const d = (num) => ('0' + num).slice(-2);
|
||||
|
||||
const writeText = (lang) => {
|
||||
const p = document.createElement('p');
|
||||
p.innerHTML = i18n[lang].comingDates;
|
||||
datesLists[lang].appendChild(p);
|
||||
}
|
||||
|
||||
const m = dateToTry.getMonth() + 1;
|
||||
const y = dateToTry.getFullYear();
|
||||
if (skippedMonths.find((s) => s.m === m && s.y === y)) {
|
||||
continue;
|
||||
const writeDateList = (lang) => {
|
||||
const ul = document.createElement('ul');
|
||||
hakkens.forEach(hakken => {
|
||||
hakkend = new Date(hakken.valueOf() + endOfWeekend);
|
||||
const showFirstMonth = hakken.getMonth() !== hakkend.getMonth();
|
||||
const li = document.createElement('li');
|
||||
li.innerHTML = `
|
||||
${i18n[lang].friday} ${d(hakken.getDate())}. ${showFirstMonth ? i18n[lang].months[hakken.getMonth()] : ''}
|
||||
${i18n[lang].until}
|
||||
${d(hakkend.getDate())}. ${i18n[lang].months[hakkend.getMonth()]}
|
||||
`;
|
||||
ul.appendChild(li);
|
||||
});
|
||||
datesLists[lang].appendChild(ul);
|
||||
}
|
||||
hakkens.push(dateToTry);
|
||||
}
|
||||
|
||||
// Helper function to add leading zeros to dates
|
||||
const d = (num) => ('0' + num).slice(-2);
|
||||
|
||||
const writeText = (lang) => {
|
||||
const p = document.createElement('p');
|
||||
p.innerHTML = i18n[lang].comingDates;
|
||||
datesLists[lang].appendChild(p);
|
||||
}
|
||||
|
||||
const writeDateList = (lang) => {
|
||||
const ul = document.createElement('ul');
|
||||
hakkens.forEach(hakken => {
|
||||
hakkend = new Date(hakken.valueOf() + endOfWeekend);
|
||||
const showFirstMonth = hakken.getMonth() !== hakkend.getMonth();
|
||||
const li = document.createElement('li');
|
||||
li.innerHTML = `
|
||||
${i18n[lang].friday} ${d(hakken.getDate())}. ${showFirstMonth ? i18n[lang].months[hakken.getMonth()] : ''}
|
||||
${i18n[lang].until}
|
||||
${d(hakkend.getDate())}. ${i18n[lang].months[hakkend.getMonth()]}
|
||||
`;
|
||||
ul.appendChild(li);
|
||||
});
|
||||
datesLists[lang].appendChild(ul);
|
||||
}
|
||||
|
||||
writeText('de');
|
||||
writeText('en');
|
||||
writeDateList('de');
|
||||
writeDateList('en');
|
||||
writeText('de');
|
||||
writeText('en');
|
||||
writeDateList('de');
|
||||
writeDateList('en');
|
||||
})();
|
||||
|
|
100
hakken.html
100
hakken.html
File diff suppressed because one or more lines are too long
92
hakken.yml
Normal file
92
hakken.yml
Normal file
|
@ -0,0 +1,92 @@
|
|||
layout: layouts/default.tsx
|
||||
|
||||
title: hakken.irl
|
||||
showHakkenDates: true
|
||||
|
||||
extraScripts:
|
||||
- /scripts/hakken-dates.js
|
||||
|
||||
content:
|
||||
en: |
|
||||
# hakken.irl
|
||||
|
||||
You're invited!
|
||||
|
||||
We meet (almost) every month in Cologne for hakken.irl, a small three-day (friday to sunday) hackathon that's just about having fun and nerding around.
|
||||
|
||||
## What will we be doing?
|
||||
|
||||
There is only one set agenda point: riding with Critical Mass. In general, we'll be hakking on pub.solar related stuff like [PubSolarOS](https://git.b12f.io/pub-solar/os "PubSolarOS git repo") or [our Infra](https://git.b12f.io/pub-solar/infra "pub.solar infra repo").
|
||||
|
||||
Stuff we've done so far:
|
||||
|
||||
* [configured Matrix monitoring with Prometheus](https://git.b12f.io/pub-solar/infra/commit/c682a97746770121b419a9ad2c8c94688e5fa0f8),
|
||||
* [refactored the core module of PubSolarOS](https://git.b12f.io/pub-solar/os/pulls/115),
|
||||
* [started sway as a systemd service](https://git.b12f.io/pub-solar/os/commit/159ae86722bc706ff42d4d3e4b0f49ede2f253de),
|
||||
* [added a "paranoid" option that always uses encrypted hibernation instead of sleep](https://git.b12f.io/pub-solar/os/pulls/74),
|
||||
* [removed nonfree software from PubSolarOS](https://git.b12f.io/pub-solar/os/pulls/113),
|
||||
* played Wizard, cards and board games,
|
||||
* cooked, ordered, and ate together,
|
||||
* and made fun of neoliberals.
|
||||
|
||||
## So is it just for über-nerds?
|
||||
|
||||
It's pretty nerdy over all, and you should definitely bring your laptop. However we don't really care what you do while you're with us. It's good if you can also entertain yourself with a project. We use the space to work together and connect, but if we vibe you can also just sit with us and play games all day.
|
||||
|
||||
## What do I have to pay?
|
||||
|
||||
It's free, but if we order food or get some stuff at a kiosk it'd be cool if you chip in. A small donation to the association is also always welcome.
|
||||
|
||||
## Where do I sleep?
|
||||
|
||||
If you cannot find an (affordable, cool, safe) place to stay in Cologne, then talk to us. We'll surely be able to set you up with a place to stay somewhere.
|
||||
|
||||
## Where do I sign up?
|
||||
|
||||
Write us a short message. You can reach us via [Matrix](https://matrix.to/#/#general:pub.solar?via=chat.pub.solar) and [Mastodon](https://mastodon.pub.solar/@crew), or send a mail to[crew@pub.solar](mailto:crew@pub.solar).
|
||||
|
||||
## When will this happen?
|
||||
|
||||
hakken.irl always starts on the last friday of the month.
|
||||
|
||||
de: |
|
||||
# hakken.irl
|
||||
|
||||
Du bist eingeladen!
|
||||
|
||||
Wir treffen uns (fast) monatlich in Köln zum hakken.irl, ein kleiner 3-Tägiger (Freitag bis Sonntag) Hackathon bei dem es nur darum geht Spaß zu haben und ab zu nerden.
|
||||
|
||||
## Was machen wir denn so?
|
||||
|
||||
Es gibt nur einen festen Programmpunkt: bei der Critical Mass mitradeln. Tendenziell hakken wir danach an pub.solar relatierten sachen wie z.B. [PubSolarOS](https://git.b12f.io/pub-solar/os "PubSolarOS git repo") oder [unsere Infra](https://git.b12f.io/pub-solar/infra "pub.solar infra repo").
|
||||
|
||||
Was wir bisher so gemacht haben:
|
||||
|
||||
* [Matrix monitoring per Prometheus konfiguriert](https://git.b12f.io/pub-solar/infra/commit/c682a97746770121b419a9ad2c8c94688e5fa0f8),
|
||||
* [das core module in PubSolarOS gerefactored](https://git.b12f.io/pub-solar/os/pulls/115),
|
||||
* [sway als systemd service starten](https://git.b12f.io/pub-solar/os/commit/159ae86722bc706ff42d4d3e4b0f49ede2f253de),
|
||||
* [eine "paranoid" Option für PubSolarOS hinzugefügt, bei dem der PC immer in encrypted hibernation locked](https://git.b12f.io/pub-solar/os/pulls/74),
|
||||
* [nonfree software aus PubSolarOS entfernt](https://git.b12f.io/pub-solar/os/pulls/113),
|
||||
* Wizard, Karten und Brettspiele gespielt,
|
||||
* zusammen gekocht, bestellt, und gegessen,
|
||||
* und über die FDP her gezogen.
|
||||
|
||||
## Ist das also nur für über-nerds?
|
||||
|
||||
Es geht schon ziemlich nerdy zu, und du solltest auf jeden Fall deinen Laptop dabei haben. Allerdings ist es uns eigentlich egal, wie du deine Zeit vertreibst. Im besten Falle kannst du dich auch allein an einem eigenen Projekt vergnügen. Wir benutzen den Raum zum gemeinsamen Arbeiten und Austauschen, aber wenn der vibe passt kannst du dich auch dazu setzen und nur Zocken.
|
||||
|
||||
## Was kostet das?
|
||||
|
||||
Es kostet nichts, aber wenn wir mal Essen bestellen oder beim Kiosk was holen wärs cool wenn du was rein gibst. Auch ist ne kleine Spende an den Verein immer gerne gesehen.
|
||||
|
||||
## Wo schlafe ich?
|
||||
|
||||
Falls du keine (bezahlbare, coole, sichere) Übernachtungsmöglichkeit in Köln finden kannst, dann rede mit uns. Wir kriegen garantiert einen Schlafplatz organisiert.
|
||||
|
||||
## Wo melde ich mich an?
|
||||
|
||||
Schreib uns kurz ne Nachricht. Du kannst uns via [Matrix](https://matrix.to/#/#general:pub.solar?via=chat.pub.solar) und [Mastodon](https://mastodon.pub.solar/@crew) erreichen, oder eine Mail an [crew@pub.solar](mailto:crew@pub.solar) schicken.
|
||||
|
||||
## Und wann soll das sein?
|
||||
|
||||
hakken.irl startet immer am letzten Freitag des Monats
|
7
import_map.json
Normal file
7
import_map.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"imports": {
|
||||
"lume/": "https://deno.land/x/lume@v1.11.4/",
|
||||
"react/jsx-runtime": "https://deno.land/x/lume@v1.11.4/deps/react_runtime.ts",
|
||||
"react": "https://deno.land/x/lume@v1.11.4/deps/react.ts"
|
||||
}
|
||||
}
|
39
index.html
39
index.html
File diff suppressed because one or more lines are too long
23
index.yml
Normal file
23
index.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
layout: layouts/homepage.tsx
|
||||
|
||||
links:
|
||||
- href: https://en.wikipedia.org/wiki/Free_software
|
||||
title: Fucking Free
|
||||
openInNewTab: true
|
||||
- href: https://pub.solar/os/
|
||||
title: PubSolarOS
|
||||
- href: https://chat.pub.solar/
|
||||
title: Matrix
|
||||
openInNewTab: true
|
||||
- href: https://mastodon.pub.solar/
|
||||
title: Mastodon
|
||||
openInNewTab: true
|
||||
- href: https://cloud.pub.solar/
|
||||
title: Nextcloud
|
||||
openInNewTab: true
|
||||
- href: ./hakken
|
||||
title: hakken.irl
|
||||
- href: ./about
|
||||
title: About & Imprint
|
||||
- href: ./privacy
|
||||
title: Privacy policy
|
91
privacy.html
91
privacy.html
File diff suppressed because one or more lines are too long
70
privacy.yml
Normal file
70
privacy.yml
Normal file
|
@ -0,0 +1,70 @@
|
|||
layout: layouts/default.tsx
|
||||
|
||||
title: Privacy Policy
|
||||
|
||||
content:
|
||||
en: |
|
||||
# Privacy Policy
|
||||
|
||||
Information on data privacy and protection for the Matrix service operated by pub.solar n.e.V. as required by article 13 DSGVO
|
||||
|
||||
*Explanation: Our Matrix service consists of the "Homeserver"; `https://matrix.pub.solar`, as well as the web-based Element-Messenger ([chat.pub.solar](https://chat.pub.solar/)).*
|
||||
|
||||
## Responsible for operating the service
|
||||
|
||||
**pub.solar n.e.V.**
|
||||
Benjamin Bädorf, Jhonas Wernery, Hendrik Sokolowki
|
||||
c/o MiOM 202
|
||||
Wilhelm-Mauser-Straße 47 Halle 5,
|
||||
D-50827 Köln
|
||||
[crew@pub.solar](mailto:crew@pub.solar)
|
||||
|
||||
## Contact for data protection issues
|
||||
|
||||
If you have any questions regarding data protection, please contact us at [crew@pub.solar](mailto:crew@pub.solar) or at the postal address given above.
|
||||
|
||||
## What is the purpose of the data processing?
|
||||
|
||||
"Matrix" is an open, decentralized communication service for real-time communication. It enables members of pub.solar n.e.V., as well as other interested parties, to communicate with other users of this server as well as other Matrix users of federated Matrix servers via chat and audio/video telephony by means of a Matrix account.
|
||||
|
||||
## What personal data is processed?
|
||||
|
||||
The processing includes the following personal data:
|
||||
|
||||
* Access control: matrix ID, display name, e-mail address (optional), phone number (optional)
|
||||
* Authentication: username and password
|
||||
* User content: all data that the user enters into the system (end-to-end encryption is enabled by default in 1:1 rooms)
|
||||
* Device identification: IP addresses with time stamp and device name; type of end device used (mobile / desktop), operating system
|
||||
* Server log: IP addresses with timestamp
|
||||
* Audio/video chat: IP addresses, audio/video data
|
||||
* Notifications (e-mail)
|
||||
|
||||
## How long will the personal data be stored?
|
||||
|
||||
The personal data will be deleted from our server after 15 months of inactivity. The deletion requests are forwarded to the federated servers. However, we have no influence on their execution.
|
||||
|
||||
## Where is the personal data stored?
|
||||
|
||||
We run our Matrix service on servers of the company [Greenbaum Cloud](https://greenbaum.cloud/).
|
||||
|
||||
## Data subject rights
|
||||
|
||||
When we process personal data about you, you have the following rights:
|
||||
|
||||
* right of access to the data processed and right to obtain a copy of it,
|
||||
* right of rectification if we process incorrect data about you,
|
||||
* right to deletion, unless exceptions apply as to why we are still storing the data, for example, retention obligations or limitation periods
|
||||
* right to restriction of processing,
|
||||
* right to withdraw consent to data processing at any time,
|
||||
* right to object to processing in the public or legitimate interest,
|
||||
* right to data portability,
|
||||
* right to lodge a complaint with a data protection supervisory authority if you believe that we are not processing your data properly. The State Commissioner for Data Protection and Freedom of Information in Nordrhein-Westfalen is responsible in our case. However, if you are in another federal state or not in Germany, you can also contact the data protection authority there.
|
||||
|
||||
## References/License
|
||||
|
||||
We have created the basic structure of this data protection information with the help of [DS-GVO.clever-Tools](https://www.baden-wuerttemberg.datenschutz.de/ds-gvo.clever/) and adapted it to our needs. We have also used parts of [Datenschutzerklärung der TU-Dresden](https://doc.matrix.tu-dresden.de/privacy/) and adjusted them accordingly. Text is licensed [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.de).
|
||||
|
||||
de: |
|
||||
Es gibt momentan leider keine Deutsche Version unserer Datenschutzerklärung.
|
||||
|
||||
Falls Du unbedingt eine sehen willst, dann kontaktiere die Crew damit wir das Thema höher priorisieren können.
|
11
scripts/background.js
Normal file
11
scripts/background.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
(() => {
|
||||
const background = document.getElementById("background");
|
||||
const logo = document.getElementById("logo").cloneNode(true);
|
||||
logo.id = "";
|
||||
(new Array(Math.ceil(window.innerWidth / 100) * Math.ceil(window.innerHeight / 100)))
|
||||
.fill(null)
|
||||
.map(_ => logo.cloneNode(true))
|
||||
.forEach(l => {
|
||||
background.appendChild(l);
|
||||
});
|
||||
})();
|
107
scripts/hakken-dates.js
Normal file
107
scripts/hakken-dates.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
const skippedMonths = [
|
||||
{ m: 8, y: 2022 },
|
||||
{ m: 12, y: 2022 },
|
||||
];
|
||||
|
||||
const i18n = {
|
||||
en: {
|
||||
comingDates: 'The following dates are scheduled:',
|
||||
friday: 'friday',
|
||||
sunday: 'sunday',
|
||||
until: 'until',
|
||||
months: [
|
||||
'Jan.',
|
||||
'Feb.',
|
||||
'Mar.',
|
||||
'Apr.',
|
||||
'May',
|
||||
'Jun.',
|
||||
'Jul.',
|
||||
'Aug.',
|
||||
'Sep.',
|
||||
'Oct.',
|
||||
'Nov.',
|
||||
'Dec.',
|
||||
],
|
||||
},
|
||||
de: {
|
||||
comingDates: 'Folgende Termine stehen an:',
|
||||
friday: 'Freitag',
|
||||
sunday: 'Sonntag',
|
||||
until: 'bis',
|
||||
months: [
|
||||
'Jan.',
|
||||
'Feb.',
|
||||
'Mär.',
|
||||
'Apr.',
|
||||
'Mai',
|
||||
'Jun.',
|
||||
'Jul.',
|
||||
'Aug.',
|
||||
'Sep.',
|
||||
'Okt.',
|
||||
'Nov.',
|
||||
'Dez.',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const datesLists = {
|
||||
en: document.getElementById('dates-list-en'),
|
||||
de: document.getElementById('dates-list-de'),
|
||||
};
|
||||
|
||||
const day = 24 * 60 * 60 * 1000;
|
||||
const week = 7 * day;
|
||||
const endOfWeekend = 2 * day;
|
||||
const start = new Date();
|
||||
const hakkens = [];
|
||||
// We'll be looking about half a year into the future
|
||||
for (let i = 0; i < 185; i++) {
|
||||
const dateToTry = new Date(start.valueOf() + (i * day));
|
||||
if (dateToTry.getDay() !== 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const oneWeekLater = new Date(dateToTry.valueOf() + week);
|
||||
if (dateToTry.getMonth() === oneWeekLater.getMonth()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const m = dateToTry.getMonth() + 1;
|
||||
const y = dateToTry.getFullYear();
|
||||
if (skippedMonths.find((s) => s.m === m && s.y === y)) {
|
||||
continue;
|
||||
}
|
||||
hakkens.push(dateToTry);
|
||||
}
|
||||
|
||||
// Helper function to add leading zeros to dates
|
||||
const d = (num) => ('0' + num).slice(-2);
|
||||
|
||||
const writeText = (lang) => {
|
||||
const p = document.createElement('p');
|
||||
p.innerHTML = i18n[lang].comingDates;
|
||||
datesLists[lang].appendChild(p);
|
||||
}
|
||||
|
||||
const writeDateList = (lang) => {
|
||||
const ul = document.createElement('ul');
|
||||
hakkens.forEach(hakken => {
|
||||
hakkend = new Date(hakken.valueOf() + endOfWeekend);
|
||||
const showFirstMonth = hakken.getMonth() !== hakkend.getMonth();
|
||||
const li = document.createElement('li');
|
||||
li.innerHTML = `
|
||||
${i18n[lang].friday} ${d(hakken.getDate())}. ${showFirstMonth ? i18n[lang].months[hakken.getMonth()] : ''}
|
||||
${i18n[lang].until}
|
||||
${d(hakkend.getDate())}. ${i18n[lang].months[hakkend.getMonth()]}
|
||||
`;
|
||||
ul.appendChild(li);
|
||||
});
|
||||
datesLists[lang].appendChild(ul);
|
||||
}
|
||||
|
||||
writeText('de');
|
||||
writeText('en');
|
||||
writeDateList('de');
|
||||
writeDateList('en');
|
15
shell.nix
15
shell.nix
|
@ -1,8 +1,13 @@
|
|||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
pkgs.mkShell {
|
||||
with (import (fetchTarball https://github.com/nixos/nixpkgs/archive/nixpkgs-unstable.tar.gz) {});
|
||||
mkShell {
|
||||
buildInputs = [
|
||||
pkgs.nodejs
|
||||
pkgs.nodePackages.serve
|
||||
nodejs
|
||||
deno
|
||||
nodePackages.json
|
||||
nodePackages.triton
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
eval "$(triton env --triton)"
|
||||
'';
|
||||
}
|
||||
|
|
38
style.css
38
style.css
|
@ -197,8 +197,16 @@ html {
|
|||
}
|
||||
}
|
||||
|
||||
.ps-page--section-link {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: var(--background);
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1200px) {
|
||||
.mobile-only {
|
||||
.ps-page--section-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +227,7 @@ html {
|
|||
|
||||
.ps-background--logo {
|
||||
width: calc(100vw / 9);
|
||||
// height: 4rem;
|
||||
height: 4rem;
|
||||
margin: 0.1rem;
|
||||
}
|
||||
|
||||
|
@ -289,3 +297,29 @@ html {
|
|||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.ps-homelink {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
|
||||
pointer-events: all;
|
||||
color: var(--foreground);
|
||||
background: white;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
font-weight: 900;
|
||||
font-size: 2rem;
|
||||
line-height: 1em;
|
||||
padding: 0.4vw;
|
||||
text-shadow: 0.15vw 0px 0px white;
|
||||
transition: text-shadow 0.1s ease;
|
||||
border: 12px solid black;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.ps-homelink:hover {
|
||||
text-shadow: 0.3vw 0px 0px var(--accent);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue