Compare commits
No commits in common. '2.0' and 'master' have entirely different histories.
@ -1,41 +0,0 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: build
|
||||
|
||||
steps:
|
||||
- name: docker
|
||||
image: plugins/docker
|
||||
settings:
|
||||
registry: docker.cybre.town
|
||||
repo: docker.cybre.town/adb/adb.sh
|
||||
tags:
|
||||
- "${DRONE_COMMIT_SHA:0:8}"
|
||||
- "latest"
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: deploy
|
||||
|
||||
depends_on:
|
||||
- build
|
||||
|
||||
steps:
|
||||
- name: pull and deploy
|
||||
image: appleboy/drone-ssh:linux-amd64
|
||||
settings:
|
||||
host:
|
||||
from_secret: ssh_host
|
||||
username:
|
||||
from_secret: ssh_user_name
|
||||
key:
|
||||
from_secret: ssh_private_key
|
||||
script: |
|
||||
cd /media/docker/adb.sh
|
||||
docker compose -f docker-compose.prod.yml -p adb-sh pull -q
|
||||
docker compose -f docker-compose.prod.yml -p adb-sh up -d
|
@ -1,3 +0,0 @@
|
||||
.idea
|
||||
dist
|
||||
node_modules
|
@ -1,14 +0,0 @@
|
||||
FROM node:16-alpine AS builder
|
||||
|
||||
COPY ./ /home/node/app
|
||||
WORKDIR /home/node/app
|
||||
|
||||
RUN npm ci && npm run build
|
||||
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY ./nginx.conf /etc/nginx/nginx.conf
|
||||
COPY --from=builder /home/node/app/dist /var/www/html
|
||||
|
||||
EXPOSE 8080
|
@ -1,15 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
networks:
|
||||
web:
|
||||
external: true
|
||||
|
||||
services:
|
||||
frontend:
|
||||
image: node:16
|
||||
volumes:
|
||||
- ./:/app
|
||||
working_dir: /app
|
||||
command: 'npm run dev'
|
||||
ports:
|
||||
- "8080:8080"
|
@ -1,20 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
networks:
|
||||
web:
|
||||
external: true
|
||||
|
||||
services:
|
||||
frontend:
|
||||
image: docker.cybre.town/adb/adb.sh
|
||||
restart: always
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
|
||||
- "traefik.http.routers.adb-sh.rule=Host(`adb.sh`)"
|
||||
- "traefik.http.routers.adb-sh.entrypoints=https"
|
||||
- "traefik.http.services.adb-sh.loadbalancer.server.port=8080"
|
||||
- "traefik.http.routers.adb-sh.tls.certresolver=mytlschallenge"
|
||||
- "traefik.docker.network=web"
|
||||
networks:
|
||||
- web
|
@ -1,22 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
networks:
|
||||
web:
|
||||
external: true
|
||||
|
||||
services:
|
||||
frontend:
|
||||
image: docker.cybre.town/adb/adb.sh
|
||||
build:
|
||||
dockerfile: ./Dockerfile
|
||||
context: ./
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
|
||||
- "traefik.http.routers.adb-sh.rule=Host(`adb.sh`)"
|
||||
- "traefik.http.routers.adb-sh.entrypoints=https"
|
||||
- "traefik.http.services.adb-sh.loadbalancer.server.port=8080"
|
||||
- "traefik.http.routers.adb-sh.tls.certresolver=mytlschallenge"
|
||||
- "traefik.docker.network=web"
|
||||
ports:
|
||||
- "9000:8080"
|
@ -0,0 +1,348 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>ADB</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="Alban David Becker" name="author">
|
||||
<meta content="Alban David Becker" name="publisher">
|
||||
<meta content="Alban David Becker" name="copyright">
|
||||
<meta content="Alban David Becker - Media / Programming" name="description">
|
||||
<meta content="Alban, David, Becker, Media, Photography, Programming, Engineering, Development" name="keywords">
|
||||
<meta content="Private Homepage" name="page-type">
|
||||
<meta content="en" http-equiv="content-language">
|
||||
<meta content="index, follow" name="robots">
|
||||
<meta content="width=device-width,initial-scale=0.8,maximum-scale=0.8,user-scalable=0" name="viewport">
|
||||
|
||||
<style>
|
||||
@import 'https://fonts.googleapis.com/css?family=Roboto+Mono:100';
|
||||
|
||||
html, body {
|
||||
font-family: Roboto Mono, monospace;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
background-color: #1f262b;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
width: calc(100% - 2rem);
|
||||
max-width: 40rem;
|
||||
background-color: #1f262b;
|
||||
box-shadow: 3px 3px 10px #333;
|
||||
border: 2px solid #fff;
|
||||
border-collapse: separate;
|
||||
border-spacing: 2px;
|
||||
border-radius: 0.75rem;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
font-family: "Roboto", regular, sans-serif;
|
||||
}
|
||||
|
||||
tr {
|
||||
margin: auto;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
th {
|
||||
margin: auto;
|
||||
background-color: #546E7A;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
td {
|
||||
margin: auto;
|
||||
background-color: #37474F;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
td.left, th.left {
|
||||
border-radius: 0.5rem 0 0 0.5rem;
|
||||
}
|
||||
|
||||
td.right, th.right {
|
||||
border-radius: 0 0.5rem 0.5rem 0;
|
||||
}
|
||||
|
||||
td.mid, th.mid {
|
||||
border-radius: 0 0 0 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin: 5rem 0 1rem 1rem;
|
||||
bottom: 5px;
|
||||
word-break: break-word;
|
||||
font-size: 1em;
|
||||
color: #fafafa;
|
||||
}
|
||||
|
||||
.logo-img {
|
||||
fill: #fafafa;
|
||||
}
|
||||
|
||||
.matrix {
|
||||
font-family: Helvetica, monospace;
|
||||
display: inline-block;
|
||||
height: 50px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.social_icons {
|
||||
position: absolute;
|
||||
top: 10rem;
|
||||
user-select: none;
|
||||
width: 90%;
|
||||
left: 5%;
|
||||
}
|
||||
|
||||
.social_icons > div {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: min-content;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.social {
|
||||
position: sticky;
|
||||
font-size: 3em;
|
||||
color: #fafafa;
|
||||
height: 20rem;
|
||||
width: 100%;
|
||||
top: calc(50% - 10rem);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo-img {
|
||||
fill: #fafafa;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="top">
|
||||
<div class="social">
|
||||
<div class="text">
|
||||
<noscript>Please activate JavaScript to see the text animation. There are no trackers on this site! :)
|
||||
</noscript>
|
||||
</div>
|
||||
|
||||
<div class="social_icons">
|
||||
<div onclick="location.href='https://github.com/adb-sh/'">
|
||||
<svg class="logo-img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m256 0c-140.699219 0-256 116.300781-256 257 0 139.882812 114.25 255 256 255 141.574219 0 256-114.945312 256-255 0-140.699219-115.300781-257-256-257zm45 477.5c-14.398438 3-29.699219 4.5-45 4.5s-30.601562-1.5-45-4.5v-70.199219c0-16.800781 4.5-22.800781 10.5-30.902343 3.054688-3.492188 4.898438-6.625 18.597656-27.296876l-23.097656-3.601562c-59.402344-8.699219-82.800781-39.601562-92.101562-63.601562-12-32.097657-5.699219-72.300782 15.902343-97.796876 3.300781-3.902343 6-10.503906 3.601563-17.402343-4.503906-13.800781-3.902344-35.699219-.902344-44.101563 15.90625 2.273438 32.261719 13.667969 45.902344 21.902344 6.285156 3.667969 9.582031 2.699219 12.597656 3 10.960938-2.28125 28.058594-7.800781 54.300781-7.800781 16.199219 0 33.300781 2.398437 50.101563 7.199219 3.003906-.070313 7.832031 2.484374 16.199218-2.398438 14.257813-8.6875 30.058594-19.691406 45.898438-21.902344 3 8.402344 3.601562 30.300782-.898438 44.101563-2.402343 6.898437.296876 13.5 3.601563 17.402343 21.597656 25.5 27.898437 65.699219 15.898437 97.796876-9.300781 24-32.699218 54.902343-92.101562 63.601562l-23.097656 3.601562c14.160156 21.367188 15.652344 23.929688 18.601562 27.296876 5.996094 8.101562 10.496094 14.101562 10.496094 30.902343zm30-8.699219v-61.5c0-17.101562-3.601562-28.5-8.402344-36.902343 45.601563-12.296876 78.003906-39.300782 92.402344-78 15.300781-40.796876 8.402344-89.398438-17.101562-123 4.503906-20.097657 4.503906-52.199219-6.296876-67.199219-4.800781-6.597657-11.402343-10.199219-19.800781-10.199219-.300781 0-.300781 0-.300781 0-23.261719 1.257812-41.570312 12.972656-61.199219 24.898438-18-4.800782-36.300781-7.199219-54.601562-7.199219-18.597657 0-37.199219 2.699219-53.695313 7.199219-20.664062-12.460938-38.796875-23.671876-62.703125-24.898438-7.5 0-14.101562 3.601562-18.902343 10.199219-10.796876 15-10.796876 47.101562-6.296876 67.199219-25.503906 33.601562-32.402343 82.5-17.101562 123 14.398438 38.699218 46.800781 65.703124 92.402344 78-3.722656 6.511718-6.667969 14.914062-7.828125 26.285156-9.210938 3.175781-17.199219 4.210937-24.628907 2.027344-7.835937-2.316407-13.941406-7.546876-19.246093-16.46875-11.914063-20.015626-32.207031-36.355469-55.3125-34.230469l2.636719 29.882812c10.699218-.980469 21.347656 10.339844 26.878906 19.671875 9.125 15.367188 21.417968 25.445313 36.546875 29.914063 11.230469 3.308593 21.496093 3.230469 32.550781.871093v40.449219c-87.300781-30.601562-151-114-151-211.800781 0-124.199219 101.800781-227 226-227s226 102.800781 226 227c0 97.800781-63.699219 181.199219-151 211.800781zm0 0"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div onclick="location.href='https://git.adb.sh/adb/'">
|
||||
<svg class="logo-img" viewBox="0 0 919 919" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M 901.543,500.352 500.352,901.527 c -23.094,23.11 -60.567,23.11 -83.692,0 L 333.359,818.211 439.031,712.535 c 24.563,8.293 52.727,2.727 72.297,-16.847 19.688,-19.696 25.203,-48.102 16.699,-72.75 L 629.883,521.094 c 24.648,8.496 53.066,3.004 72.754,-16.711 27.5,-27.492 27.5,-72.059 0,-99.574 -27.52,-27.516 -72.078,-27.516 -99.61,0 -20.683,20.703 -25.8,51.097 -15.312,76.582 l -95,94.992 V 326.414 c 6.699,-3.32 13.027,-7.742 18.613,-13.312 27.5,-27.497 27.5,-72.059 0,-99.598 -27.5,-27.488 -72.09,-27.488 -99.57,0 -27.5,27.539 -27.5,72.101 0,99.598 6.797,6.789 14.668,11.925 23.066,15.363 v 252.281 c -8.398,3.438 -16.25,8.531 -23.066,15.367 -20.828,20.821 -25.84,51.395 -15.156,76.977 L 292.422,777.285 17.3242,502.211 c -23.10545,-23.129 -23.10545,-60.602 0,-83.711 L 418.535,17.3242 c 23.098,-23.10545 60.559,-23.10545 83.692,0 L 901.543,416.641 c 23.113,23.113 23.113,60.605 0,83.711"
|
||||
transform="scale(1,-1) translate(0, -919)"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div onclick="location.href='https://social.adb.sh/@adb'">
|
||||
<svg class="logo-img" viewBox="0 0 256 256">
|
||||
<path d="M 115.05664 0 C 83.417974 0.25866667 52.984047 3.6847447 35.248047 11.830078 C 35.248047 11.830078 0.072265625 27.564666 0.072265625 81.25 C 0.072265625 93.543333 -0.16667709 108.24208 0.22265625 123.83008 C 1.4999896 176.33141 9.8473382 228.07387 58.388672 240.92188 C 80.770005 246.84588 99.986891 248.08699 115.46289 247.23633 C 143.52822 245.68033 159.2832 237.2207 159.2832 237.2207 L 158.35742 216.85742 C 158.35742 216.85742 138.30134 223.18082 115.77734 222.41016 C 93.461344 221.64482 69.902302 220.00414 66.292969 192.60547 C 65.959635 190.1988 65.792969 187.62454 65.792969 184.92188 C 65.792969 184.92187 87.700224 190.27683 115.46289 191.54883 C 132.43889 192.32749 148.35801 190.55433 164.52734 188.625 C 195.53534 184.92233 222.5344 165.81671 225.92773 148.35938 C 231.2744 120.85937 230.83398 81.25 230.83398 81.25 C 230.83398 27.564666 195.66016 11.830078 195.66016 11.830078 C 177.92549 3.6847447 147.47265 0.25866667 115.83398 0 L 115.05664 0 z M 79.25 41.947266 C 92.428667 41.947266 102.40719 47.012531 109.00586 57.144531 L 115.42188 67.898438 L 121.83789 57.144531 C 128.43522 47.012531 138.41375 41.947266 151.59375 41.947266 C 162.98308 41.947266 172.15997 45.951052 179.16797 53.761719 C 185.9613 61.572385 189.34375 72.130682 189.34375 85.416016 L 189.34375 150.41992 L 163.58984 150.41992 L 163.58984 87.326172 C 163.58984 74.026172 157.99411 67.275391 146.80078 67.275391 C 134.42478 67.275391 128.22266 75.282521 128.22266 91.117188 L 128.22266 125.65234 L 102.62109 125.65234 L 102.62109 91.117188 C 102.62109 75.282521 96.417016 67.275391 84.041016 67.275391 C 72.847682 67.275391 67.251953 74.026172 67.251953 87.326172 L 67.251953 150.41992 L 41.498047 150.41992 L 41.498047 85.416016 C 41.498047 72.130682 44.881115 61.572385 51.675781 53.761719 C 58.682448 45.951052 67.859333 41.947266 79.25 41.947266"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div onclick="location.href='https://matrix.to/#/@adb:adb.sh'">
|
||||
<svg class="logo-img" style="width: 60px" viewBox="0 0 210 190">
|
||||
<path d="M 8.1424685,29.681081 H 41.347757 v 13.758366 h -15.34587 v 96.903883 h 15.34587 v 13.82451 H 8.1424685 Z"/>
|
||||
<path d="m 134.15059,54.419682 q 4.76251,0 9.39273,1.852088 4.63022,1.852088 8.40054,6.482307 3.04272,3.770322 4.10105,9.26044 0.66146,3.638029 0.66146,10.649505 l -0.13229,45.442298 H 137.25945 V 82.201 q 0,-4.101052 -1.32292,-6.746892 -2.51355,-5.027095 -9.26044,-5.027095 -7.80523,0 -10.7818,6.482307 -1.52135,3.439592 -1.52135,8.268249 V 128.10632 H 95.389035 V 85.177569 q 0,-6.416161 -1.32292,-9.326585 -2.381256,-5.225533 -9.326585,-5.225533 -8.069811,0 -10.847943,5.225533 -1.521358,2.97657 -1.521358,8.863563 V 128.10632 H 53.254037 V 56.139478 h 18.32244 v 10.517213 q 3.505738,-5.622409 6.6146,-8.003665 5.490117,-4.233344 14.221388,-4.233344 8.268245,0 13.361495,3.63803 4.10105,3.373446 6.21772,8.665125 3.70418,-6.350015 9.19429,-9.326585 5.82085,-2.97657 12.96462,-2.97657 z"/>
|
||||
<path d="m 168.34806,140.34333 h 15.34587 V 43.174863 H 168.34806 V 29.681081 h 33.20529 V 154.16784 h -33.20529 z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div onclick="location.href='https://www.instagram.com/alban.da'">
|
||||
<svg class="logo-img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m75 512h362c41.355469 0 75-33.644531 75-75v-362c0-41.355469-33.644531-75-75-75h-362c-41.355469 0-75 33.644531-75 75v362c0 41.355469 33.644531 75 75 75zm-45-437c0-24.8125 20.1875-45 45-45h362c24.8125 0 45 20.1875 45 45v362c0 24.8125-20.1875 45-45 45h-362c-24.8125 0-45-20.1875-45-45zm0 0"/>
|
||||
<path d="m256 391c74.4375 0 135-60.5625 135-135s-60.5625-135-135-135-135 60.5625-135 135 60.5625 135 135 135zm0-240c57.898438 0 105 47.101562 105 105s-47.101562 105-105 105-105-47.101562-105-105 47.101562-105 105-105zm0 0"/>
|
||||
<path d="m406 151c24.8125 0 45-20.1875 45-45s-20.1875-45-45-45-45 20.1875-45 45 20.1875 45 45 45zm0-60c8.269531 0 15 6.730469 15 15s-6.730469 15-15 15-15-6.730469-15-15 6.730469-15 15-15zm0 0"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div onclick="location.href='https://open.spotify.com/user/op3q884heqao7laioz05ebaoz'">
|
||||
<svg class="logo-img" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m256 0c-140.960938 0-256 115.050781-256 256 0 140.960938 115.050781 256 256 256 140.960938 0 256-115.050781 256-256 0-140.960938-115.050781-256-256-256zm0 482c-124.617188 0-226-101.382812-226-226s101.382812-226 226-226 226 101.382812 226 226-101.382812 226-226 226zm0 0"/>
|
||||
<path d="m99.066406 148.667969 5.195313 29.546875c109.394531-19.234375 220.378906-4.640625 317.398437 37.136718l11.863282-27.550781c-102.253907-44.035156-219.179688-59.402343-334.457032-39.132812zm0 0"/>
|
||||
<path d="m103.832031 239.34375-.765625.152344 5.890625 29.417968.757813-.152343c95.839844-19.128907 197.550781-7.15625 286.394531 33.710937l12.535156-27.253906c-94.550781-43.496094-202.796875-56.238281-304.8125-35.875zm0 0"/>
|
||||
<path d="m129.703125 326.050781 5.277344 29.53125c73.082031-13.058593 147.707031-4.347656 215.808593 25.203125l11.941407-27.523437c-73.539063-31.902344-154.121094-41.3125-233.027344-27.210938zm0 0"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div onclick="location.href='https://soundcloud.com/alban-david-becker'">
|
||||
<svg class="logo-img" viewBox="0 -121 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m180 0h30v270h-30zm0 0"/>
|
||||
<path d="m120 90h30v180h-30zm0 0"/>
|
||||
<path d="m60 60h30v210h-30zm0 0"/>
|
||||
<path d="m0 150h30v120h-30zm0 0"/>
|
||||
<path d="m512 180c0-49.625-40.375-90-90-90-2.542969 0-5.082031.105469-7.605469.320312-18.867187-53.082031-71.167969-90.320312-129.394531-90.320312-11.421875 0-22.773438 1.429688-33.738281 4.253906l-11.261719 2.898438v262.847656h182c49.625 0 90-40.375 90-90zm-242-148.9375c4.949219-.707031 9.964844-1.0625 15-1.0625 49.285156 0 93.097656 33.933594 104.175781 80.6875l3.5 14.773438c11.894531-2.664063 18.164063-5.460938 29.324219-5.460938 33.085938 0 60 26.914062 60 60s-26.914062 60-60 60h-152zm0 0"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div onclick="location.href='https://t.me/ADBac'">
|
||||
<svg class="logo-img" viewBox="1 -35 511.99993 511" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m121.453125 253.171875 63.554687 158.886719 82.75-82.753906 141.535157 112.503906 102.707031-441.308594-512 205.480469zm-39.933594-47.640625 244.046875-97.945312-194.074218 117.363281zm287.535157-89.25-161.980469 148.1875-19.484375 73.425781-36.035156-90.085937zm-149.851563 219.230469 9.816406-36.996094 15.144531 12.035156zm171.65625 53.394531-147.386719-117.152344 221.902344-203.007812zm0 0"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>services I'm hosting:</h1>
|
||||
<table>
|
||||
<tr>
|
||||
<th class="left">service</th>
|
||||
<th class="right">url</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">git</td>
|
||||
<td class="right"><a href="https://git.adb.sh">git.adb.sh</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">Nextcloud</td>
|
||||
<td class="right"><a href="https://cloud.adb.sh">cloud.adb.sh</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">Matrix</td>
|
||||
<td class="right"><a href="https://chat.adb.sh">chat.adb.sh</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">Element</td>
|
||||
<td class="right"><a href="https://element.adb.sh">element.adb.sh</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">Mastodon</td>
|
||||
<td class="right"><a href="https://social.adb.sh">social.adb.sh</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">email</td>
|
||||
<td class="right"><a href="https://mail.adb.sh">mail.adb.sh</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">Jitsi</td>
|
||||
<td class="right"><a href="https://meet.adb.sh">meet.adb.sh</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">Etherpad</td>
|
||||
<td class="right"><a href="https://ether.adb.sh">ether.adb.sh</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">short url</td>
|
||||
<td class="right"><a href="https://s.adb.sh">s.adb.sh</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left">searx</td>
|
||||
<td class="right"><a href="https://searx.adb.sh">searx.adb.sh</a></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="footer">
|
||||
<div>© 2020 Alban David Becker</div>
|
||||
<div>some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from
|
||||
<a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by
|
||||
<a href="http://creativecommons.org/licenses/by/3.0/" target="_blank" title="Creative Commons BY 3.0">CC 3.0
|
||||
BY</a>
|
||||
</div>
|
||||
<a href="http://bpzvci77gdvrn4grh2slh5dmz5lxrzmg7nkij7ltxht4gv4weamc4dad.onion">
|
||||
more privacy?: http://bpzvci77gdvrn4grh2slh5dmz5lxrzmg7nkij7ltxht4gv4weamc4dad.onion
|
||||
</a><br/>
|
||||
<a href="bitcoin:bc1qaekdddmucre8yvwcy4knyhdtqs3kj5mgnk4kj6?label=adb.sh">
|
||||
bitcoin:bc1qaekdddmucre8yvwcy4knyhdtqs3kj5mgnk4kj6
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// TextScramble
|
||||
class TextScramble {
|
||||
constructor(el) {
|
||||
this.el = el
|
||||
this.chars = '!<>-_\\/[]{}—=+*^?#________'
|
||||
this.update = this.update.bind(this)
|
||||
}
|
||||
|
||||
setText(newText) {
|
||||
const oldText = this.el.innerText
|
||||
const length = Math.max(oldText.length, newText.length)
|
||||
const promise = new Promise((resolve) => this.resolve = resolve)
|
||||
this.queue = []
|
||||
for (let i = 0; i < length; i++) {
|
||||
const from = oldText[i] || ''
|
||||
const to = newText[i] || ''
|
||||
const start = Math.floor(Math.random() * 40)
|
||||
const end = start + Math.floor(Math.random() * 40)
|
||||
this.queue.push({from, to, start, end})
|
||||
}
|
||||
cancelAnimationFrame(this.frameRequest)
|
||||
this.frame = 0
|
||||
this.update()
|
||||
return promise
|
||||
}
|
||||
|
||||
update() {
|
||||
let output = ''
|
||||
let complete = 0
|
||||
for (let i = 0, n = this.queue.length; i < n; i++) {
|
||||
let {from, to, start, end, char} = this.queue[i]
|
||||
if (this.frame >= end) {
|
||||
complete++
|
||||
output += to
|
||||
} else if (this.frame >= start) {
|
||||
if (!char || Math.random() < 0.28) {
|
||||
char = this.randomChar()
|
||||
this.queue[i].char = char
|
||||
}
|
||||
output += `<span class="dud">${char}</span>`
|
||||
} else {
|
||||
output += from
|
||||
}
|
||||
}
|
||||
this.el.innerHTML = output
|
||||
if (complete === this.queue.length) {
|
||||
this.resolve()
|
||||
} else {
|
||||
this.frameRequest = requestAnimationFrame(this.update)
|
||||
this.frame++
|
||||
}
|
||||
}
|
||||
|
||||
randomChar() {
|
||||
return this.chars[Math.floor(Math.random() * this.chars.length)]
|
||||
}
|
||||
}
|
||||
|
||||
const phrases = [
|
||||
"Hey!",
|
||||
"That's my page!",
|
||||
"if you like", "check out", "my social media", "below :D"
|
||||
]
|
||||
|
||||
const el = document.querySelector('.text')
|
||||
const fx = new TextScramble(el)
|
||||
|
||||
let counter = 0
|
||||
const next = () => {
|
||||
fx.setText(phrases[counter]).then(() => {
|
||||
setTimeout(next, 600)
|
||||
})
|
||||
counter = (counter + 1) % phrases.length
|
||||
}
|
||||
|
||||
next()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,115 +0,0 @@
|
||||
worker_processes auto;
|
||||
worker_cpu_affinity auto;
|
||||
|
||||
error_log /var/log/nginx/error.log;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
#daemon off;
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
# rewrite_log on;
|
||||
include mime.types;
|
||||
default_type application/json;
|
||||
access_log /var/log/nginx/access.log;
|
||||
sendfile on;
|
||||
# tcp_nopush on;
|
||||
keepalive_timeout 3;
|
||||
# tcp_nodelay on;
|
||||
gzip on;
|
||||
client_max_body_size 1m;
|
||||
|
||||
server {
|
||||
listen 8080 default_server;
|
||||
server_name _;
|
||||
|
||||
error_page 400 = @400;
|
||||
location @400 { return 400 '{"status":400,"message":"Bad request"}\n'; }
|
||||
|
||||
error_page 401 = @401;
|
||||
location @401 { return 401 '{"status":401,"message":"Unauthorized"}\n'; }
|
||||
|
||||
error_page 403 = @403;
|
||||
location @403 { return 403 '{"status":403,"message":"Forbidden"}\n'; }
|
||||
|
||||
error_page 404 = @404;
|
||||
location @404 { return 404 '{"status":404,"message":"Resource not found"}\n'; }
|
||||
|
||||
error_page 405 = @405;
|
||||
location @405 { return 405 '{"status":405,"message":"Method not allowed"}\n'; }
|
||||
|
||||
error_page 408 = @408;
|
||||
location @408 { return 408 '{"status":408,"message":"Request timeout"}\n'; }
|
||||
|
||||
error_page 413 = @413;
|
||||
location @413 { return 413 '{"status":413,"message":"Payload too large"}\n'; }
|
||||
|
||||
error_page 414 = @414;
|
||||
location @414 { return 414 '{"status":414,"message":"Request URI too large"}\n'; }
|
||||
|
||||
error_page 415 = @415;
|
||||
location @415 { return 415 '{"status":415,"message":"Unsupported media type"}\n'; }
|
||||
|
||||
error_page 426 = @426;
|
||||
location @426 { return 426 '{"status":426,"message":"HTTP request was sent to HTTPS port"}\n'; }
|
||||
|
||||
error_page 429 = @429;
|
||||
location @429 { return 429 '{"status":429,"message":"API rate limit exceeded"}\n'; }
|
||||
|
||||
error_page 495 = @495;
|
||||
location @495 { return 495 '{"status":495,"message":"Client certificate authentication error"}\n'; }
|
||||
|
||||
error_page 496 = @496;
|
||||
location @496 { return 496 '{"status":496,"message":"Client certificate not presented"}\n'; }
|
||||
|
||||
error_page 497 = @497;
|
||||
location @497 { return 497 '{"status":497,"message":"HTTP request was sent to mutual TLS port"}\n'; }
|
||||
|
||||
error_page 500 = @500;
|
||||
location @500 { return 500 '{"status":500,"message":"Server error"}\n'; }
|
||||
|
||||
error_page 501 = @501;
|
||||
location @501 { return 501 '{"status":501,"message":"Not implemented"}\n'; }
|
||||
|
||||
error_page 502 = @502;
|
||||
location @502 { return 502 '{"status":502,"message":"Bad gateway"}\n'; }
|
||||
|
||||
location /mail {
|
||||
return 302 mailto:info@adb.sh;
|
||||
}
|
||||
|
||||
location / {
|
||||
index index.html;
|
||||
root /var/www/html;
|
||||
try_files $uri $uri/ =404;
|
||||
absolute_redirect off;
|
||||
}
|
||||
|
||||
location =/ {
|
||||
return 302 https://adb.sh/me/;
|
||||
}
|
||||
location =/linkedin {
|
||||
return 302 https://www.linkedin.com/in/alban-david-becker-800761282/;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 8080;
|
||||
server_name alban.world;
|
||||
|
||||
location / {
|
||||
return 302 https://adb.sh/;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 8080;
|
||||
server_name albans.world;
|
||||
|
||||
location / {
|
||||
return 302 https://adb.sh/;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "adb.sh_2.0",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"authors": {
|
||||
"name": "",
|
||||
"email": ""
|
||||
},
|
||||
"repository": "/adb.sh_2.0",
|
||||
"scripts": {
|
||||
"dev": "vuepress dev src",
|
||||
"build": "vuepress build src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"sass": "^1.54.9",
|
||||
"sass-loader": "^10.3.1",
|
||||
"vuepress": "^1.9.7",
|
||||
"webpack": "^4.46.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vuepress/plugin-search": "^1.9.7",
|
||||
"@vuepress/theme-default": "^1.9.7",
|
||||
"bootstrap": "^5.2.3",
|
||||
"bootstrap-darkmode": "^5.0.1",
|
||||
"bootstrap-icons": "^1.10.3",
|
||||
"vuepress-plugin-sitemap": "^2.3.1"
|
||||
}
|
||||
}
|
@ -1,318 +0,0 @@
|
||||
/**
|
||||
* Particle Network Animation https://codepen.io/franky/pen/LGMWPK
|
||||
* Inspiration: https://github.com/JulianLaval/canvas-particle-network
|
||||
*/
|
||||
|
||||
class ParticleNetworkAnimation {
|
||||
constructor(element, options) {
|
||||
this.$el = element;
|
||||
|
||||
this.container = element;
|
||||
//this.canvas = document.createElement('canvas');
|
||||
this.canvas = element;
|
||||
this.sizeCanvas();
|
||||
//this.container.appendChild(this.canvas);
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
this.particleNetwork = new ParticleNetwork(this, options);
|
||||
|
||||
this.bindUiActions();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bindUiActions() {
|
||||
window.addEventListener('resize', () => {
|
||||
this.forceUpdate();
|
||||
});
|
||||
}
|
||||
sizeCanvas() {
|
||||
this.canvas.width = this.container.offsetWidth;
|
||||
this.canvas.height = this.container.offsetHeight;
|
||||
}
|
||||
forceUpdate() {
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
this.sizeCanvas();
|
||||
this.particleNetwork.createParticles();
|
||||
}
|
||||
}
|
||||
|
||||
class Particle{
|
||||
constructor(parent, x, y) {
|
||||
this.network = parent;
|
||||
this.canvas = parent.canvas;
|
||||
this.ctx = parent.ctx;
|
||||
this.particleColor = returnRandomArrayitem(this.network.options.particleColors);
|
||||
this.radius = getLimitedRandom(1.5, 2.5);
|
||||
this.opacity = 0;
|
||||
this.x = x || Math.random() * this.canvas.width;
|
||||
this.y = y || Math.random() * this.canvas.height;
|
||||
this.velocity = {
|
||||
x: (Math.random() - 0.5) * parent.options.velocity,
|
||||
y: (Math.random() - 0.5) * parent.options.velocity
|
||||
};
|
||||
}
|
||||
|
||||
update(){
|
||||
if (this.opacity < 1) {
|
||||
this.opacity += 0.01;
|
||||
} else {
|
||||
this.opacity = 1;
|
||||
}
|
||||
// Change dir if outside map
|
||||
if (this.x > this.canvas.width + 100 || this.x < -100) {
|
||||
this.velocity.x = -this.velocity.x;
|
||||
}
|
||||
if (this.y > this.canvas.height + 100 || this.y < -100) {
|
||||
this.velocity.y = -this.velocity.y;
|
||||
}
|
||||
|
||||
// Update position
|
||||
this.x += this.velocity.x;
|
||||
this.y += this.velocity.y;
|
||||
}
|
||||
draw(){
|
||||
// Draw particle
|
||||
this.ctx.beginPath();
|
||||
this.ctx.fillStyle = this.particleColor;
|
||||
this.ctx.globalAlpha = this.opacity;
|
||||
this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
|
||||
this.ctx.fill();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ParticleNetwork{
|
||||
constructor(parent, options = {
|
||||
velocity: 2, // the higher the faster
|
||||
density: 10000, // the lower the denser
|
||||
netLineDistance: 200,
|
||||
netLineColor: '#929292',
|
||||
particleColors: ['#aaa'] // ['#6D4E5C', '#aaa', '#FFC458' ]
|
||||
}) {
|
||||
this.options = options;
|
||||
this.canvas = parent.canvas;
|
||||
this.ctx = parent.ctx;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init(){
|
||||
// Create particle objects
|
||||
this.createParticles(false);
|
||||
|
||||
// Update canvas
|
||||
this.animationFrame = requestAnimationFrame(this.update.bind(this));
|
||||
|
||||
this.bindUiActions();
|
||||
}
|
||||
|
||||
createParticles(isInitial) {
|
||||
// Initialise / reset particles
|
||||
let me = this;
|
||||
this.particles = [];
|
||||
let quantity = this.canvas.width * this.canvas.height / this.options.density;
|
||||
|
||||
if (isInitial) {
|
||||
let counter = 0;
|
||||
clearInterval(this.createIntervalId);
|
||||
this.createIntervalId = setInterval(function() {
|
||||
if (counter < quantity - 1) {
|
||||
// Create particle object
|
||||
this.particles.push(new Particle(this));
|
||||
}
|
||||
else {
|
||||
clearInterval(me.createIntervalId);
|
||||
}
|
||||
counter++;
|
||||
}.bind(this), 250);
|
||||
}
|
||||
else {
|
||||
// Create particle objects
|
||||
for (let i = 0; i < quantity; i++) {
|
||||
this.particles.push(new Particle(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createInteractionParticle() {
|
||||
// Add interaction particle
|
||||
this.interactionParticle = new Particle(this);
|
||||
this.interactionParticle.velocity = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
this.particles.push(this.interactionParticle);
|
||||
return this.interactionParticle;
|
||||
}
|
||||
|
||||
removeInteractionParticle() {
|
||||
// Find it
|
||||
let index = this.particles.indexOf(this.interactionParticle);
|
||||
if (index > -1) {
|
||||
// Remove it
|
||||
this.interactionParticle = undefined;
|
||||
this.particles.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
if (this.canvas) {
|
||||
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
this.ctx.globalAlpha = 1;
|
||||
|
||||
// Draw connections
|
||||
for (let i = 0; i < this.particles.length; i++) {
|
||||
for (let j = this.particles.length - 1; j > i; j--) {
|
||||
let distance, p1 = this.particles[i], p2 = this.particles[j];
|
||||
|
||||
// check very simply if the two points are even a candidate for further measurements
|
||||
distance = Math.min(Math.abs(p1.x - p2.x), Math.abs(p1.y - p2.y));
|
||||
if (distance > this.options.netLineDistance) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// the two points seem close enough, now let's measure precisely
|
||||
distance = Math.sqrt(
|
||||
Math.pow(p1.x - p2.x, 2) +
|
||||
Math.pow(p1.y - p2.y, 2)
|
||||
);
|
||||
if (distance > this.options.netLineDistance) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.ctx.beginPath();
|
||||
this.ctx.strokeStyle = this.options.netLineColor;
|
||||
this.ctx.globalAlpha = (this.options.netLineDistance - distance) / this.options.netLineDistance * p1.opacity * p2.opacity;
|
||||
this.ctx.lineWidth = 0.7;
|
||||
this.ctx.moveTo(p1.x, p1.y);
|
||||
this.ctx.lineTo(p2.x, p2.y);
|
||||
this.ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw particles
|
||||
this.particles.forEach(k => {
|
||||
k.update();
|
||||
k.draw();
|
||||
})
|
||||
|
||||
if (this.options.velocity !== 0) {
|
||||
this.animationFrame = requestAnimationFrame(this.update.bind(this));
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
cancelAnimationFrame(this.animationFrame);
|
||||
}
|
||||
}
|
||||
|
||||
bindUiActions() {
|
||||
// Mouse / touch event handling
|
||||
this.spawnQuantity = 3;
|
||||
this.mouseIsDown = false;
|
||||
this.touchIsMoving = false;
|
||||
|
||||
this.onMouseMove = function(e) {
|
||||
if (!this.interactionParticle) {
|
||||
this.createInteractionParticle();
|
||||
}
|
||||
this.interactionParticle.x = e.offsetX;
|
||||
this.interactionParticle.y = e.offsetY;
|
||||
}.bind(this);
|
||||
|
||||
this.onTouchMove = function(e) {
|
||||
e.preventDefault();
|
||||
this.touchIsMoving = true;
|
||||
if (!this.interactionParticle) {
|
||||
this.createInteractionParticle();
|
||||
}
|
||||
this.interactionParticle.x = e.changedTouches[0].clientX;
|
||||
this.interactionParticle.y = e.changedTouches[0].clientY;
|
||||
}.bind(this);
|
||||
|
||||
this.onMouseDown = function() {
|
||||
this.mouseIsDown = true;
|
||||
let counter = 0;
|
||||
let quantity = this.spawnQuantity;
|
||||
let intervalId = setInterval(function() {
|
||||
if (this.mouseIsDown) {
|
||||
if (counter === 1) {
|
||||
quantity = 1;
|
||||
}
|
||||
for (let i = 0; i < quantity; i++) {
|
||||
if (this.interactionParticle) {
|
||||
this.particles.push(new Particle(this, this.interactionParticle.x, this.interactionParticle.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
counter++;
|
||||
}.bind(this), 50);
|
||||
}.bind(this);
|
||||
|
||||
this.onTouchStart = function(e) {
|
||||
e.preventDefault();
|
||||
setTimeout(function() {
|
||||
if (!this.touchIsMoving) {
|
||||
for (let i = 0; i < this.spawnQuantity; i++) {
|
||||
this.particles.push(new Particle(this, e.changedTouches[0].clientX, e.changedTouches[0].clientY));
|
||||
}
|
||||
}
|
||||
}.bind(this), 200);
|
||||
}.bind(this);
|
||||
|
||||
this.onMouseUp = function() {
|
||||
this.mouseIsDown = false;
|
||||
}.bind(this);
|
||||
|
||||
this.onMouseOut = function() {
|
||||
this.removeInteractionParticle();
|
||||
}.bind(this);
|
||||
|
||||
this.onTouchEnd = function(e) {
|
||||
e.preventDefault();
|
||||
this.touchIsMoving = false;
|
||||
this.removeInteractionParticle();
|
||||
}.bind(this);
|
||||
|
||||
this.canvas.addEventListener('mousemove', this.onMouseMove);
|
||||
this.canvas.addEventListener('touchmove', this.onTouchMove);
|
||||
//this.canvas.addEventListener('mousedown', this.onMouseDown);
|
||||
this.canvas.addEventListener('touchstart', this.onTouchStart);
|
||||
this.canvas.addEventListener('mouseup', this.onMouseUp);
|
||||
this.canvas.addEventListener('mouseout', this.onMouseOut);
|
||||
this.canvas.addEventListener('touchend', this.onTouchEnd);
|
||||
}
|
||||
|
||||
unbindUiActions() {
|
||||
if (this.canvas) {
|
||||
this.canvas.removeEventListener('mousemove', this.onMouseMove);
|
||||
this.canvas.removeEventListener('touchmove', this.onTouchMove);
|
||||
this.canvas.removeEventListener('mousedown', this.onMouseDown);
|
||||
this.canvas.removeEventListener('touchstart', this.onTouchStart);
|
||||
this.canvas.removeEventListener('mouseup', this.onMouseUp);
|
||||
this.canvas.removeEventListener('mouseout', this.onMouseOut);
|
||||
this.canvas.removeEventListener('touchend', this.onTouchEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let getLimitedRandom = function(min, max, roundToInteger) {
|
||||
let number = Math.random() * (max - min) + min;
|
||||
if (roundToInteger) {
|
||||
number = Math.round(number);
|
||||
}
|
||||
return number;
|
||||
};
|
||||
|
||||
let returnRandomArrayitem = function(array) {
|
||||
return array[Math.floor(Math.random()*array.length)];
|
||||
};
|
||||
|
||||
export {
|
||||
ParticleNetworkAnimation
|
||||
};
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2021 by Justin Windle (https://codepen.io/soulwire/pen/mErPAK)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
export class TextScramble {
|
||||
constructor(el) {
|
||||
this.el = el
|
||||
this.chars = '!<>-_\\/[]{}—=+*^?#________'
|
||||
this.update = this.update.bind(this)
|
||||
}
|
||||
|
||||
setText(newText) {
|
||||
const oldText = this.el.innerText
|
||||
const length = Math.max(oldText.length, newText.length)
|
||||
const promise = new Promise((resolve) => this.resolve = resolve)
|
||||
this.queue = []
|
||||
for (let i = 0; i < length; i++) {
|
||||
const from = oldText[i] || ''
|
||||
const to = newText[i] || ''
|
||||
const start = Math.floor(Math.random() * 40)
|
||||
const end = start + Math.floor(Math.random() * 40)
|
||||
this.queue.push({from, to, start, end})
|
||||
}
|
||||
cancelAnimationFrame(this.frameRequest)
|
||||
this.frame = 0
|
||||
this.update()
|
||||
return promise
|
||||
}
|
||||
|
||||
update() {
|
||||
let output = ''
|
||||
let complete = 0
|
||||
for (let i = 0, n = this.queue.length; i < n; i++) {
|
||||
let {from, to, start, end, char} = this.queue[i]
|
||||
if (this.frame >= end) {
|
||||
complete++
|
||||
output += to
|
||||
} else if (this.frame >= start) {
|
||||
if (!char || Math.random() < 0.28) {
|
||||
char = this.randomChar()
|
||||
this.queue[i].char = char
|
||||
}
|
||||
output += `<span class="dud">${char}</span>`
|
||||
} else {
|
||||
output += from
|
||||
}
|
||||
}
|
||||
this.el.innerHTML = output
|
||||
if (complete === this.queue.length) {
|
||||
this.resolve()
|
||||
} else {
|
||||
this.frameRequest = requestAnimationFrame(this.update)
|
||||
this.frame++
|
||||
}
|
||||
}
|
||||
|
||||
randomChar() {
|
||||
return this.chars[Math.floor(Math.random() * this.chars.length)]
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 501 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 440 KiB |
Binary file not shown.
Before Width: | Height: | Size: 460 KiB |
Binary file not shown.
Before Width: | Height: | Size: 428 KiB |
Binary file not shown.
Before Width: | Height: | Size: 83 KiB |
@ -1,130 +0,0 @@
|
||||
<template>
|
||||
<div class="particle-network-animation">
|
||||
<canvas ref="pna" ></canvas>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ParticleNetworkAnimation } from '../ParticleNetworkAnimation';
|
||||
|
||||
export default {
|
||||
name: 'BannerWrapperNetwork',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
velocity: 0.5, // the higher the faster
|
||||
density: 30000, // the lower the denser
|
||||
netLineDistance: 120,
|
||||
netLineColor: '#ccc',
|
||||
particleColors: ['#ccc']
|
||||
}),
|
||||
},
|
||||
},
|
||||
data: () => ({
|
||||
animation: null,
|
||||
}),
|
||||
mounted() {
|
||||
setTimeout(() =>
|
||||
this.animation = new ParticleNetworkAnimation(this.$refs.pna, this.options
|
||||
), 1000);
|
||||
},
|
||||
updated() {
|
||||
this.animation?.forceUpdate();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.particle-network-animation {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
box-shadow: var(--shadow200);
|
||||
|
||||
&.white{
|
||||
background-color: #fff;
|
||||
}
|
||||
&.no-shadow{
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&::before {
|
||||
z-index: -2;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
opacity: 0.2;
|
||||
}
|
||||
canvas{
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.wrapper{
|
||||
//pointer-events: none;
|
||||
}
|
||||
}
|
||||
.glow {
|
||||
z-index: -1;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
background-image: radial-gradient(circle closest-side, rgba(255, 255, 255, 0.025), transparent);
|
||||
}
|
||||
$duration: 25s;
|
||||
.glow-1 {
|
||||
width: 150vw;
|
||||
height: 150vh;
|
||||
margin-top: -75vh;
|
||||
margin-left: -75vw;
|
||||
animation: glow-1-move $duration linear infinite both;
|
||||
}
|
||||
@keyframes glow-1-move {
|
||||
from {
|
||||
transform: translate(-100%, 100%);
|
||||
}
|
||||
to {
|
||||
transform: translate(100%, -100%);
|
||||
}
|
||||
}
|
||||
.glow-2 {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
margin-top: -50vh;
|
||||
margin-left: -50vw;
|
||||
animation: glow-2-move $duration linear $duration / 3 infinite both;
|
||||
}
|
||||
@keyframes glow-2-move {
|
||||
from {
|
||||
transform: translate(-100%, 0%);
|
||||
}
|
||||
to {
|
||||
transform: translate(100%, 100%);
|
||||
}
|
||||
}
|
||||
.glow-3 {
|
||||
width: 120vw;
|
||||
height: 120vh;
|
||||
margin-top: -60vh;
|
||||
margin-left: -60vw;
|
||||
animation: glow-3-move $duration linear $duration / 3 * 2 infinite both;
|
||||
}
|
||||
@keyframes glow-3-move {
|
||||
from {
|
||||
transform: translate(100%, 100%);
|
||||
}
|
||||
to {
|
||||
transform: translate(0%, -100%);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,60 +0,0 @@
|
||||
<template>
|
||||
<transition name="fade">
|
||||
<a
|
||||
class="btn currentlyListening"
|
||||
href=" https://spot2gether.cybre.town/user/op3q884heqao7laioz05ebaoz"
|
||||
target="_blank"
|
||||
ref="noopener noreferrer"
|
||||
v-if="currentlyPlaying?.item"
|
||||
>
|
||||
<div class="row align-items-center">
|
||||
<i class="bi-music-note col-auto icon" />
|
||||
<div class="col-auto d-flex flex-column text">
|
||||
<b>{{ currentlyPlaying?.item?.name }}</b>
|
||||
<div>{{ currentlyPlaying?.item?.artists.map(artist => artist.name).join(', ') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let updateMusicInfo = null;
|
||||
const noob = () => null;
|
||||
|
||||
export default {
|
||||
name: "CurrentlyListening",
|
||||
data: () => ({
|
||||
currentlyPlaying: null,
|
||||
}),
|
||||
methods: {
|
||||
async fetchMusicInfo() {
|
||||
return await fetch(
|
||||
'https://spot2gether.cybre.town/api/public/users/op3q884heqao7laioz05ebaoz/info'
|
||||
).then(data => data.json());
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.currentlyPlaying = (await this.fetchMusicInfo().catch(noob))?.currentlyPlaying;
|
||||
updateMusicInfo = setInterval(async () => {
|
||||
this.currentlyPlaying = (await this.fetchMusicInfo().catch(noob))?.currentlyPlaying;
|
||||
}, 10000);
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(updateMusicInfo);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.currentlyListening {
|
||||
position: relative;
|
||||
.icon {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.text {
|
||||
font-size: .8rem;
|
||||
text-align: left !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,32 +0,0 @@
|
||||
<template>
|
||||
<div v-if="active">
|
||||
<slot />
|
||||
</div>
|
||||
<div v-else class="card">
|
||||
<div class="card-body">
|
||||
<div>
|
||||
<slot name="lock">
|
||||
<p v-if="name">Click to load external content from {{ name }}.</p>
|
||||
<p v-else>Click to load external content.</p>
|
||||
</slot>
|
||||
</div>
|
||||
<button class="btn btn-primary" @click="active = true">load content</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ExternalContentWrapper",
|
||||
props: {
|
||||
name: String,
|
||||
},
|
||||
data: () => ({
|
||||
active: false,
|
||||
}),
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<ul>
|
||||
<slot
|
||||
v-for="page of $site.pages
|
||||
.filter(page => page.regularPath.match(new RegExp(`^${ path }.`)))
|
||||
.slice(0, limit)
|
||||
"
|
||||
:page="page"
|
||||
>
|
||||
<li>
|
||||
<router-link :to="page.regularPath">{{ page.title }}</router-link>
|
||||
</li>
|
||||
</slot>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "FolderList",
|
||||
props: {
|
||||
path: String,
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 8,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@ -1,25 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<CurrentlyListening />
|
||||
<StickyWrapper>
|
||||
<TextScramble :phrases="[
|
||||
'Hey!',
|
||||
'Welcome to adb.sh :D',
|
||||
'I do web development', 'networking / hosting', 'electronics', 'DJing / music',
|
||||
]" />
|
||||
<SocialIcons />
|
||||
<div class="row my-4 justify-content-center">
|
||||
<router-link class="col-auto mx-2 btn btn-outline-light" to="/projects" >projects</router-link>
|
||||
<router-link class="col-auto mx-2 btn btn-outline-light" to="/music" >music</router-link>
|
||||
</div>
|
||||
</StickyWrapper>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "HomeContent",
|
||||
}
|
||||
</script>
|
@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<div class="SocialIcons row">
|
||||
<a class="col-auto btn bi-github" href="https://github.com/adb-sh/" target="_blank" rel="noopener noreferrer" />
|
||||
<a class="col-auto btn bi-git" href="https://git.cybre.town/adb" target="_blank" rel="noopener noreferrer" />
|
||||
<a class="col-auto btn bi-mastodon" href="https://social.cybre.town/@adb" target="_blank" rel="noopener noreferrer" />
|
||||
<a class="col-auto btn bi-instagram" href="https://www.instagram.com/me.adb.sh" target="_blank" rel="noopener noreferrer" />
|
||||
<a class="col-auto btn bi-spotify" href="https://open.spotify.com/user/op3q884heqao7laioz05ebaoz" target="_blank" rel="noopener noreferrer" />
|
||||
<a class="col-auto btn bi-youtube" href="https://www.youtube.com/channel/UCoxRdN8T4aCR8tqDpOJAjOQ" target="_blank" rel="noopener noreferrer" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.SocialIcons {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
a.btn {
|
||||
font-size: calc(1.5rem + 1vw);
|
||||
max-font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.social_icons > div {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: min-content;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.logo-img {
|
||||
fill: #fff;
|
||||
height: 3rem;
|
||||
margin: .75rem;
|
||||
}
|
||||
</style>
|
@ -1,20 +0,0 @@
|
||||
<template>
|
||||
<div class="StickyWrapper">
|
||||
<slot name="top"/>
|
||||
<div class="content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.StickyWrapper {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
.content {
|
||||
position: sticky;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,38 +0,0 @@
|
||||
<script>
|
||||
import { TextScramble } from "../TextScramble.mjs";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
phrases: Array,
|
||||
},
|
||||
mounted() {
|
||||
const el = this.$refs.TextScramble;
|
||||
const fx = new TextScramble(el);
|
||||
|
||||
let counter = 0
|
||||
const next = () => {
|
||||
fx.setText(this.phrases[counter]).then(() => setTimeout(next, 600));
|
||||
counter = (counter + 1) % this.phrases.length;
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="TextScramble my-4" ref="TextScramble"></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.TextScramble {
|
||||
font-size: calc(1.5rem + 1vw);
|
||||
max-font-size: 2.5rem;
|
||||
text-align: center;
|
||||
font-family: "Roboto Mono", monospace;
|
||||
font-weight: 100;
|
||||
.dud {
|
||||
color: #166161;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,51 +0,0 @@
|
||||
module.exports = {
|
||||
title: '0xADB',
|
||||
description: 'Welcome to adb.sh',
|
||||
head: [
|
||||
['meta', { name: 'theme-color', content: '#3eaf7c' }],
|
||||
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
|
||||
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
|
||||
['meta', { name: 'author', content: 'Alban David Becker' }],
|
||||
['meta', { name: 'publisher', content: 'Alban David Becker' }],
|
||||
['meta', { name: 'copyright', content: 'Alban David Becker' }],
|
||||
['meta', { name: 'keywords', content: 'Alban, David, Becker, web development, development, hosting, open source, FOSS, music, DJ' }],
|
||||
['meta', { name: 'page-type', content: 'Private Homepage' }],
|
||||
['meta', { name: 'robots', content: 'follow' }],
|
||||
['meta', { 'http-equiv': 'content-language', content: 'en' }],
|
||||
],
|
||||
markdown: {
|
||||
anchor: { permalink: false },
|
||||
extendMarkdown: md => {
|
||||
md.set({ breaks: true });
|
||||
}
|
||||
},
|
||||
dest: "./dist",
|
||||
themeConfig: {
|
||||
repo: '',
|
||||
editLinks: false,
|
||||
docsDir: '',
|
||||
editLinkText: '',
|
||||
lastUpdated: false,
|
||||
searchMaxSuggestions: 10,
|
||||
searchHotkeys: ['s', 'k', '/'],
|
||||
searchPlaceholder: 'Ctrl + S',
|
||||
test: [/.+.md/],
|
||||
nav: [
|
||||
{
|
||||
text: 'projects',
|
||||
link: '/projects',
|
||||
},
|
||||
{
|
||||
text: 'music',
|
||||
link: '/music',
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: {
|
||||
'@vuepress/plugin-search': {},
|
||||
'vuepress-plugin-sitemap': {
|
||||
hostname: 'https://adb.sh/',
|
||||
exclude: ['/404.html'],
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
const matchPath = /(?<path>|.+)\/(?<filename>[-_\w]+)(?<filetype>|\/|\.html|\.md)$/;
|
||||
|
||||
export default ({
|
||||
Vue, // the version of Vue being used in the VuePress app
|
||||
options, // the options for the root Vue instance
|
||||
router, // the router instance for the app
|
||||
siteData // site metadata
|
||||
}) => {
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to.path === '/') next('/me');
|
||||
if (!to.name) {
|
||||
const { filename } = to.fullPath.match(matchPath).groups;
|
||||
next(
|
||||
siteData.pages
|
||||
.find((page) => page.regularPath.match(matchPath)?.groups?.filename === filename)
|
||||
?.regularPath
|
||||
);
|
||||
}
|
||||
next();
|
||||
});
|
||||
};
|
@ -1,92 +0,0 @@
|
||||
<template>
|
||||
<div class="app">
|
||||
<div class="background">
|
||||
<img src="../assets/background.jpg" alt="">
|
||||
</div>
|
||||
<section class="layout" data-theme="dark">
|
||||
<header>
|
||||
<div class="bg-dark-opacity1 shadow">
|
||||
<site-header class="container" />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<BannerWrapperNetwork v-if="!$page.frontmatter?.disableAnimation" class="background bg-opacity-50" />
|
||||
<div v-if="$page.frontmatter?.sidebar" class="container">
|
||||
<div class="row">
|
||||
<div class="col-xl-4 p-4">
|
||||
<div class="card toc">
|
||||
<div class="card-header">
|
||||
<router-link :to="`/${$page.path.split('/')[1]}/`"><b>/{{ $page.path.split('/')[1] }}/</b></router-link>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<FolderList :path="`/${$page.path.split('/')[1]}/`" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Content class="col-xl-8 p-4" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="container">
|
||||
<Content class="p-4" />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer py-3">
|
||||
<site-footer class="container" />
|
||||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SiteHeader from "./SiteHeader";
|
||||
import SiteFooter from "./SiteFooter";
|
||||
import FolderList from "../components/FolderList";
|
||||
|
||||
import "bootstrap-icons/font/bootstrap-icons.scss";
|
||||
import "./main.scss";
|
||||
|
||||
import "@vuepress/theme-default/styles/code.styl";
|
||||
import BannerWrapperNetwork from "../components/BannerWrapperNetwork";
|
||||
|
||||
export default {
|
||||
components: {BannerWrapperNetwork, SiteFooter, SiteHeader, FolderList },
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.layout {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
}
|
||||
header {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
main.content {
|
||||
padding: 5rem 0 2rem 0;
|
||||
.toc {
|
||||
position: sticky;
|
||||
top: 5rem;
|
||||
}
|
||||
.container {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
.background {
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<div class="m-4">
|
||||
<h1>404 Not Found</h1>
|
||||
<router-link class="btn btn-primary" to="/">Zur Startseite</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import "bootstrap/scss/bootstrap.scss";
|
||||
|
||||
export default {
|
||||
name: "NotFound"
|
||||
}
|
||||
</script>
|
@ -1,7 +0,0 @@
|
||||
<template>
|
||||
<div class="footer border-top py-2">
|
||||
<span class="copyright">Copyright © {{ (new Date).getFullYear() }} Alban David Becker</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@ -1,66 +0,0 @@
|
||||
<template>
|
||||
<nav class="navbar px-4">
|
||||
<router-link class="btn d-flex" to="/me">
|
||||
<div class="flex-column justify-content-center">
|
||||
<b>{{ $site.title }}</b>
|
||||
</div>
|
||||
</router-link>
|
||||
<div class="row align-items-center">
|
||||
<SearchBox class="col-auto" />
|
||||
<div v-for="nav of $site.themeConfig.nav" class="col-auto d-none d-xl-block">
|
||||
<div v-if="nav.children || nav.path" class="category dropdown">
|
||||
<router-link :to="nav.link" class="link btn">{{ nav.text }} <i class="bi-chevron-down" /></router-link>
|
||||
<div class="dropdown-menu">
|
||||
<router-link
|
||||
v-for="site of (nav.children ?? [])
|
||||
.concat(nav.path
|
||||
? $site.pages
|
||||
.filter(page => page.regularPath.match(new RegExp(`${nav.path}.`)))
|
||||
.map(page => ({ text: page.title, link: page.regularPath }))
|
||||
: []
|
||||
)
|
||||
"
|
||||
:to="site.link"
|
||||
class="dropdown-item"
|
||||
>
|
||||
{{ site.text }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="site">
|
||||
<router-link :to= "nav.link" class="link btn">{{ nav.text }}</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SearchBox from "@vuepress/plugin-search/SearchBox";
|
||||
|
||||
export default {
|
||||
components: { SearchBox },
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.header-title {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.header-img {
|
||||
height: 3.5rem;
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
}
|
||||
|
||||
.link {
|
||||
color: rgb(27, 29, 29);
|
||||
}
|
||||
|
||||
</style>
|
@ -1,19 +0,0 @@
|
||||
/* roboto-mono-100 - latin */
|
||||
@font-face {
|
||||
font-family: 'Roboto Mono';
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
src: local(''),
|
||||
url('../assets/fonts/roboto-mono-v22-latin-100.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||
url('../assets/fonts/roboto-mono-v22-latin-100.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||
}
|
||||
|
||||
/* roboto-mono-regular - latin */
|
||||
@font-face {
|
||||
font-family: 'Roboto Mono';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local(''),
|
||||
url('../assets/fonts/roboto-mono-v22-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||
url('../assets/fonts/roboto-mono-v22-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
$dark: #1f262b;
|
||||
$dark-opacity1: #1f262be8;
|
||||
$dark-opacity2: #1f262b80;
|
||||
|
||||
$dark-body-bg: $dark-opacity1;
|
||||
|
||||
@import "bootstrap/scss/bootstrap";
|
||||
@import "bootstrap-darkmode/scss/darktheme";
|
||||
@import "fonts.css";
|
||||
|
||||
|
||||
|
||||
|
||||
html, body {
|
||||
background-color: $dark-body-bg;
|
||||
line-break: loose;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
border-radius: .25rem;
|
||||
margin: 0.125rem;
|
||||
}
|
||||
|
||||
table {
|
||||
@extend .table;
|
||||
}
|
||||
|
||||
.search-box{
|
||||
input {
|
||||
background-color: unset !important;
|
||||
color: $light !important;
|
||||
}
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
:not(pre) > code {
|
||||
background-color: #aaa2;
|
||||
border-radius: .4rem;
|
||||
padding: .2rem .4rem;
|
||||
}
|
||||
[data-theme="dark"] .card {
|
||||
background-color: $dark-opacity2 !important;
|
||||
}
|
||||
|
||||
.bg-dark {
|
||||
background-color: $dark !important;
|
||||
}
|
||||
.bg-dark-opacity1 {
|
||||
background-color: $dark-opacity1 !important;
|
||||
}
|
||||
.bg-dark-opacity2 {
|
||||
background-color: $dark-opacity2 !important;
|
||||
}
|
||||
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition-property: opacity;
|
||||
transition-duration: .25s;
|
||||
}
|
||||
|
||||
.fade-enter-active {
|
||||
transition-delay: .25s;
|
||||
}
|
||||
|
||||
.fade-enter, .fade-leave-active {
|
||||
opacity: 0
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
---
|
||||
home: true
|
||||
meta:
|
||||
- name: description
|
||||
content: Alban David Becker - Web Development, DevOps, Engineering, Hosting, Music
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, web development, devops, development, hosting, open source, FOSS
|
||||
- name: robots
|
||||
content: index, follow
|
||||
---
|
||||
|
||||
<HomeContent />
|
||||
|
||||
---
|
||||
|
||||
## :smile: About me
|
||||
|
||||
- studying Applied Informatics in North of Germany
|
||||
- working at [Zenner IOT](https://zenner-iot.com/)
|
||||
- volunteering at [DD-IX - Dresden Internet Exchange](https://dd-ix.net/)
|
||||
|
||||
### :rocket: My Tech Stack
|
||||
|
||||
#### WebDev
|
||||
|
||||
![HTML5](https://img.shields.io/badge/html5-%23E34F26.svg?style=for-the-badge&logo=html5&logoColor=white)![TailwindCSS](https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=for-the-badge&logo=tailwind-css&logoColor=white)![Bootstrap](https://img.shields.io/badge/bootstrap-%238511FA.svg?style=for-the-badge&logo=bootstrap&logoColor=white)![JavaScript](https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E)![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white)![Vue.js](https://img.shields.io/badge/vuejs-%2335495e.svg?style=for-the-badge&logo=vuedotjs&logoColor=%234FC08D)![Nuxtjs](https://img.shields.io/badge/Nuxt-002E3B?style=for-the-badge&logo=nuxtdotjs&logoColor=#00DC82)![SolidJS](https://img.shields.io/badge/SolidJS-2c4f7c?style=for-the-badge&logo=solid&logoColor=c8c9cb)![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB)![NodeJS](https://img.shields.io/badge/node.js-6DA55F?style=for-the-badge&logo=node.js&logoColor=white)![Express.js](https://img.shields.io/badge/express.js-%23404d59.svg?style=for-the-badge&logo=express&logoColor=%2361DAFB)![Deno JS](https://img.shields.io/badge/deno%20js-000000?style=for-the-badge&logo=deno&logoColor=white)![Python](https://img.shields.io/badge/python-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54)![Django](https://img.shields.io/badge/django-%23092E20.svg?style=for-the-badge&logo=django&logoColor=white)
|
||||
|
||||
#### DevOps
|
||||
|
||||
![Debian](https://img.shields.io/badge/Debian-D70A53?style=for-the-badge&logo=debian&logoColor=white)![Arch](https://img.shields.io/badge/Arch%20Linux-1793D1?logo=arch-linux&logoColor=fff&style=for-the-badge)![Docker](https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white)![Kubernetes](https://img.shields.io/badge/kubernetes-%23326ce5.svg?style=for-the-badge&logo=kubernetes&logoColor=white)![Ansible](https://img.shields.io/badge/ansible-%231A1918.svg?style=for-the-badge&logo=ansible&logoColor=white)![Nix](https://img.shields.io/badge/NIX-5277C3.svg?style=for-the-badge&logo=NixOS&logoColor=white)
|
||||
|
||||
![MariaDB](https://img.shields.io/badge/MariaDB-003545?style=for-the-badge&logo=mariadb&logoColor=white)![Postgres](https://img.shields.io/badge/postgres-%23316192.svg?style=for-the-badge&logo=postgresql&logoColor=white)![MongoDB](https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge&logo=mongodb&logoColor=white)![Redis](https://img.shields.io/badge/redis-%23DD0031.svg?style=for-the-badge&logo=redis&logoColor=white)
|
||||
|
||||
#### UI/UX
|
||||
|
||||
![Adobe InDesign](https://img.shields.io/badge/Adobe%20InDesign-49021F?style=for-the-badge&logo=adobeindesign&logoColor=white)![Adobe Illustrator](https://img.shields.io/badge/adobe%20illustrator-%23FF9A00.svg?style=for-the-badge&logo=adobe%20illustrator&logoColor=white)![Adobe Photoshop](https://img.shields.io/badge/adobe%20photoshop-%2331A8FF.svg?style=for-the-badge&logo=adobe%20photoshop&logoColor=white)![Adobe Premiere Pro](https://img.shields.io/badge/Adobe%20Premiere%20Pro-9999FF.svg?style=for-the-badge&logo=Adobe%20Premiere%20Pro&logoColor=white)![Figma](https://img.shields.io/badge/figma-%23F24E1E.svg?style=for-the-badge&logo=figma&logoColor=white)
|
||||
|
||||
## Services I'm hosting
|
||||
|
||||
<div class="alert alert-warning" role="alert">
|
||||
* WARNING!: Planned downtime from <code>12.01.2024 8:00</code> to <code>13.01.2024 23:59</code> due to server relocation!
|
||||
</div>
|
||||
|
||||
### :rocket: Public services
|
||||
|
||||
| service | URL |
|
||||
| ---------- | ---------------------------------------------- |
|
||||
| Gitea\* | [git.cybre.town](https://git.cybre.town) |
|
||||
| Drone\* | [drone.cybre.town](https://drone.cybre.town) |
|
||||
| Mastodon\* | [social.cybre.town](https://social.cybre.town) |
|
||||
| HedgeDoc\* | [md.cybre.town](https://md.cybre.town) |
|
||||
|
||||
<!-- | Jitsi | [meet.adb.sh](https://meet.adb.sh) | -->
|
||||
<!-- | Frama Date | [polls.cybre.town](https://polls.cybre.town) | -->
|
||||
<!-- | Peertube | [video.cybre.town](https://video.cybre.town) | -->
|
||||
<!-- | Searx | [searx.cybre.town](https://searx.cybre.town) | -->
|
||||
<!-- | Penpot | [penpot.cybre.town](https://penpot.cybre.town) | -->
|
||||
|
||||
### :lock: Private services
|
||||
|
||||
| service | URL |
|
||||
| ----------- | ------------------------------------------ |
|
||||
| Nextcloud\* | [cloud.adb.sh](https://cloud.adb.sh) |
|
||||
| Matrix\* | [adb.sh](https://adb.sh/_matrix/static/) |
|
||||
| Mail | [mail.adb.sh](https://mail.adb.sh) |
|
||||
| Gotify UP\* | [push.cybre.town](https://push.cybre.town) |
|
||||
|
||||
### :globe_with_meridians: Other sites
|
||||
|
||||
| service | URL |
|
||||
| --------------------------------- | -------------------------------------------------- |
|
||||
| Cybre Town\* | [cybre.town](https://cybre.town) |
|
||||
| Strobe Town\* | [strobe.town](https://strobe.town) |
|
||||
| Strobe Town - Tickets (Pretix)\* | [tickets.strobe.town](https://tickets.strobe.town) |
|
||||
| Strobe Town - Music (Funkwhale)\* | [music.strobe.town](https://music.strobe.town) |
|
||||
|
||||
## :mailbox_with_mail: Contact me
|
||||
|
||||
- Matrix: [@adb:adb.sh](https://matrix.to/#/@adb:adb.sh)
|
||||
- Mail: info [at] this.domain
|
||||
|
||||
## :coffee: Buy me a coffee ^-^
|
||||
|
||||
- Liberapay: [liberapay/adb.sh](https://liberapay.com/adb.sh)
|
||||
- Bitcoin: [BC1QGP24D6GKPM4TEZ4ZRT3KZGKHYUJQUV68PTAXKQ](bitcoin:BC1QGP24D6GKPM4TEZ4ZRT3KZGKHYUJQUV68PTAXKQ)
|
||||
- PayPal: [paypal.me/ad2b](https://paypal.me/ad2b)
|
@ -1,54 +0,0 @@
|
||||
---
|
||||
meta:
|
||||
- name: description
|
||||
content: I do music and DJing
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, music, techno, melodic techno, DJ, djing
|
||||
---
|
||||
# Music
|
||||
|
||||
i do music 'n' stuff
|
||||
|
||||
## DJ sets
|
||||
|
||||
### CSD Magdeburg Aftershow at Insel der Jugend 2023
|
||||
<ExternalContentWrapper name="Mixcloud">
|
||||
<iframe width="100%" height="120" src="https://player-widget.mixcloud.com/widget/iframe/?hide_cover=1&feed=%2F0xADB%2Fcsd-magedburg-aftershow-at-insel-der-jugend%2F" frameborder="0" ></iframe>
|
||||
</ExternalContentWrapper>
|
||||
|
||||
Listen on [Mixcloud](https://www.mixcloud.com/0xADB/csd-magedburg-aftershow-at-insel-der-jugend/)
|
||||
|
||||
### Rainbow Rave - Alte Meierei | 27.05.2023
|
||||
<ExternalContentWrapper name="Mixcloud">
|
||||
<iframe width="100%" height="120" src="https://player-widget.mixcloud.com/widget/iframe/?hide_cover=1&feed=%2F0xADB%2Frainbow-rave-alte-meierei%2F" frameborder="0" ></iframe>
|
||||
</ExternalContentWrapper>
|
||||
|
||||
Listen on [Mixcloud](https://www.mixcloud.com/0xADB/rainbow-rave-alte-meierei/)
|
||||
|
||||
### Insel der Jugend at Magdeburg - 0xADB b2b Supermomme | 30.04.2023
|
||||
<ExternalContentWrapper name="Mixcloud">
|
||||
<iframe width="100%" height="120" src="https://player-widget.mixcloud.com/widget/iframe/?hide_cover=1&feed=%2F0xADB%2Finsel-der-jugend-at-magdeburg-0xadb-b2b-supermomme-3042023%2F" frameborder="0" ></iframe>
|
||||
</ExternalContentWrapper>
|
||||
|
||||
Listen on [Mixcloud](https://www.mixcloud.com/0xADB/insel-der-jugend-at-magdeburg-0xadb-b2b-supermomme-3042023/)
|
||||
|
||||
### Alte Meierei Kiel - opening set from 2022.11.26
|
||||
<ExternalContentWrapper name="Mixcloud">
|
||||
<iframe width="100%" height="120" src="https://player-widget.mixcloud.com/widget/iframe/?hide_cover=1&feed=%2F0xADB%2Falte-meierei-kiel-opening-set-from-20221126%2F" frameborder="0" ></iframe>
|
||||
</ExternalContentWrapper>
|
||||
|
||||
Listen on [Mixcloud]https://www.mixcloud.com/0xADB/alte-meierei-kiel-opening-set-from-20221126/)
|
||||
|
||||
### jam some techno
|
||||
<ExternalContentWrapper name="YouTube">
|
||||
<iframe width="100%" height="540" src="https://www.youtube-nocookie.com/embed/A0nvVXpzJD8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</ExternalContentWrapper>
|
||||
|
||||
watch on [YouTube](https://youtu.be/A0nvVXpzJD8)
|
||||
|
||||
### lemme stream some melodic techno or so
|
||||
<ExternalContentWrapper name="YouTube">
|
||||
<iframe width="100%" height="540" src="https://www.youtube-nocookie.com/embed/6bOJGkaX_5s" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</ExternalContentWrapper>
|
||||
|
||||
watch on [YouTube](https://youtu.be/6bOJGkaX_5s)
|
@ -1,20 +0,0 @@
|
||||
---
|
||||
sidebar: true
|
||||
excerpt: "Art-Net to DMX PCB"
|
||||
imgUrl: "https://social.cybre.town/system/media_attachments/files/105/520/482/627/757/197/original/ba1084550d15d53f.jpeg"
|
||||
meta:
|
||||
- name: description
|
||||
content: Art-Net to DMX PCB
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, ArtNet, development, embedded systems, hardware, Arduino, KiCad, pcb
|
||||
---
|
||||
|
||||
# ArtNet-Node
|
||||
|
||||
Art-Net to DMX PCB
|
||||
|
||||
![pcb stack](https://social.cybre.town/system/media_attachments/files/105/520/482/627/757/197/original/ba1084550d15d53f.jpeg)
|
||||
[social.cybre.town](https://social.cybre.town/@adb/105520488438390411)
|
||||
|
||||
![some soldered pcbs](https://social.cybre.town/system/media_attachments/files/105/933/932/633/113/971/original/42bdd85a644fd2ee.png)
|
||||
[social.cybre.town](https://social.cybre.town/@adb/105933977138735045)
|
@ -1,82 +0,0 @@
|
||||
---
|
||||
sidebar: true
|
||||
excerpt: "a simple reactive runtime JS framework inspired by Vue"
|
||||
meta:
|
||||
- name: description
|
||||
content: a simple reactive runtime JS framework inspired by Vue
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, dynaticjs, dav, web, javascript, framework
|
||||
---
|
||||
|
||||
# dynaticjs
|
||||
|
||||
a simple reactive runtime JS framework inspired by Vue
|
||||
|
||||
## about
|
||||
- stack: js
|
||||
- repo: [github.com](https://github.com/adb-sh/dynaticjs)
|
||||
- boilerplate repo: [github.com](https://github.com/adb-sh/dynaticjs-boilerplate)
|
||||
- npm: [npmjs.com](https://www.npmjs.com/package/dynaticjs)
|
||||
|
||||
## current features
|
||||
- dynamic router
|
||||
- components (recursive)
|
||||
- data binding (from component to component)
|
||||
- trigger rerender components on data change
|
||||
- scoped references to DOM elements
|
||||
|
||||
## simple component example
|
||||
```javascript
|
||||
import Component from "dynaticjs/Component";
|
||||
import { propFactory } from "dynaticjs/helpers.js";
|
||||
import RouterLink from "dynaticjs/components/RouterLink.js";
|
||||
import RouterView from "dynaticjs/components/RouterView.js";
|
||||
import Home from "./pages/Home.js";
|
||||
|
||||
export default class App extends Component {
|
||||
init() {
|
||||
return {
|
||||
components: {
|
||||
RouterLink,
|
||||
RouterView,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
data() {
|
||||
return {
|
||||
routes: propFactory([
|
||||
{
|
||||
name: 'home',
|
||||
title: 'Home',
|
||||
path: '/',
|
||||
Component: Home,
|
||||
},
|
||||
]),
|
||||
};
|
||||
}
|
||||
|
||||
render(state) {
|
||||
return `
|
||||
<div id="app">
|
||||
<nav ref="nav">
|
||||
<router-link class="btn btn-primary" to="home">Home</router-link>
|
||||
<router-link class="btn btn-primary" to="about">About</router-link>
|
||||
</nav>
|
||||
<main>
|
||||
<h1>DynaticJS Boilerplate</h1>
|
||||
<router-view bind:routes="routes"></router-view>
|
||||
</main>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
setup() {
|
||||
console.log("Hello World :D");
|
||||
console.log("#app element", this.$el); //corresponding DOM element
|
||||
console.log("nav element", this.$refs.nav); //scoped reference to DOM element with the attribute `ref="nav"`
|
||||
console.log("child components in App", this.$components) //references to child components
|
||||
}
|
||||
};
|
||||
```
|
||||
[full example](https://github.com/adb-sh/dynaticjs-boilerplate/blob/master/src/App.js)
|
@ -1,43 +0,0 @@
|
||||
---
|
||||
sidebar: true
|
||||
excerpt: "the validation tool nobody asked for"
|
||||
meta:
|
||||
- name: description
|
||||
content: the validation tool nobody asked for
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, deno, web, javascript
|
||||
---
|
||||
|
||||
# hoyams
|
||||
|
||||
the validation tool nobody asked for | hoyams = hold on you are missing something
|
||||
|
||||
- stack: deno, typescript
|
||||
- repo: [github.com](https://github.com/adb-sh/hoyams)
|
||||
- deno package: [deno.land](https://deno.land/x/hoyams)
|
||||
|
||||
## Concept
|
||||
|
||||
Rules are defined via a callback which retuns `true` or an error String. This is
|
||||
so that you can define rules by using an or operator like this:
|
||||
|
||||
```javascript
|
||||
new Rule((v) => typeof v === "string" || "is not a string");
|
||||
```
|
||||
|
||||
or this:
|
||||
|
||||
```javascript
|
||||
new Rule((v) =>
|
||||
typeof v === "string" && !!v.match(/^\w+@\w+\.\w+$/) ||
|
||||
"no valid email"
|
||||
);
|
||||
```
|
||||
|
||||
- If a executing a validation completes without an error an object with the same
|
||||
structure as the object given is returned.
|
||||
|
||||
- For creating powerful nested object rules there are some primites given:
|
||||
[How to use](https://deno.land/x/hoyams@v0.0.1#how-to-use)
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
---
|
||||
meta:
|
||||
- name: description
|
||||
content: recent projects from me
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, projects, development, software, embedded systems, hardware
|
||||
---
|
||||
|
||||
# Projects
|
||||
|
||||
<FolderList path="/projects/" v-slot="{ page }" class="m-0 p-0">
|
||||
<div class="card my-2">
|
||||
<div class="card-header"><router-link :to="page.regularPath">{{ page.title }}</router-link></div>
|
||||
<div class="card-body">
|
||||
{{ page.frontmatter.excerpt }}
|
||||
</div>
|
||||
</div>
|
||||
</FolderList>
|
@ -1,20 +0,0 @@
|
||||
---
|
||||
sidebar: true
|
||||
excerpt: "a simple matrix webapp for mobile and desktop"
|
||||
imgUrl: "https://chat.adb.sh/media/screenshot-desktop.png"
|
||||
meta:
|
||||
- name: description
|
||||
content: a simple matrix webapp for mobile and desktop
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, matrix, matrix-chat, chat, federation, vue, web, javascript
|
||||
---
|
||||
|
||||
# **[chat]** *matrix-chat*
|
||||
|
||||
a simple matrix webapp for mobile and desktop
|
||||
|
||||
![matrix-chat screenshot](../.vuepress/assets/images/matrix-chat.png)
|
||||
|
||||
- stack: Vue3, matrix-js-sdk
|
||||
- matrix.org: [matrix.org](https://matrix.org/docs/projects/client/chat)
|
||||
- repo: [git.cybre.town](https://git.cybre.town/adb/matrix-chat)
|
@ -1,24 +0,0 @@
|
||||
---
|
||||
sidebar: true
|
||||
excerpt: "I'm running my services on my own server, because it's fun :D"
|
||||
imgUrl: "../.vuepress/assets/images/server.jpg"
|
||||
meta:
|
||||
- name: description
|
||||
content: my home server rack
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, server, hosting, networking, development, devops
|
||||
---
|
||||
|
||||
# WLED nightlight
|
||||
|
||||
a little wled 5x5 led matrix
|
||||
|
||||
|
||||
- esp8266
|
||||
- 5x5 ws2812b leds
|
||||
|
||||
![](../.vuepress/assets/images/nightlight-front.png)
|
||||
![](../.vuepress/assets/images/nightlight-back.png)
|
||||
|
||||
- stack: kicad
|
||||
- repo: [github.com](https://github.com/adb-sh/nightlight)
|
@ -1,34 +0,0 @@
|
||||
---
|
||||
sidebar: true
|
||||
excerpt: "I'm running my services on my own server, because it's fun :D"
|
||||
imgUrl: "../.vuepress/assets/images/server.jpg"
|
||||
meta:
|
||||
- name: description
|
||||
content: my home server rack
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, server, hosting, networking, development, devops
|
||||
---
|
||||
|
||||
# My Server Rack
|
||||
|
||||
I'm running my services on my own server, because it's fun :D
|
||||
|
||||
![server rack](../.vuepress/assets/images/server.jpg)
|
||||
|
||||
## rack:
|
||||
### PfSense router
|
||||
- Pentium(R) Dual-Core CPU E5300 @ 2.60GHz
|
||||
- 2GB RAM
|
||||
- 8 interfaces
|
||||
### 1. HP ProLiant DL380e G8
|
||||
- 2x Intel(R) Xeon(R) CPU E5-2450L 0 @ 1.80GHz - (32 threads in summary)
|
||||
- 32GB RAM
|
||||
- Proxmox
|
||||
- 4x 4TB HDD
|
||||
- 1x 500GB SSD
|
||||
### 2. HP ProLiant DL380e G8
|
||||
- 2x Intel(R) Xeon(R) CPU E5-2450L 0 @ 1.80GHz - (32 threads in summary)
|
||||
- 64GB RAM
|
||||
- FreeNAS
|
||||
- 2x 8TB HDD
|
||||
- 1x 500GB SSD
|
@ -1,131 +0,0 @@
|
||||
---
|
||||
sidebar: true
|
||||
excerpt: "a complete working docker-compose setup for the matrix synapse server with postgres"
|
||||
meta:
|
||||
- name: description
|
||||
content: a complete working docker-compose setup for the matrix synapse server with postgres
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, matrix, synapse, docker, docker compose, devops
|
||||
---
|
||||
|
||||
# docker-compose matrix-synapse
|
||||
|
||||
a complete working docker-compose setup for the matrix synapse server with postgres
|
||||
|
||||
## clone the repo
|
||||
```bash
|
||||
git clone https://git.cybre.town/adb/docker-compose_matrix_synapse/
|
||||
```
|
||||
|
||||
## create config files
|
||||
|
||||
* Change `your.domain` in the `create_config.sh` file and simply run the script from terminal.
|
||||
* A temporary docker container will be created, that will configure the configs for you.
|
||||
* You will find your finished configs at `/var/lib/docker/volumes/synapse-data/_data`.
|
||||
* Copy this files to `./synapse_data/` in your docker-compose working directory.
|
||||
|
||||
for more details have a look at: [hub.docker.com/r/matrixdotorg/synapse](https://hub.docker.com/r/matrixdotorg/synapse)
|
||||
|
||||
## configure `./synapse_data/homserver.yaml`
|
||||
|
||||
### database
|
||||
|
||||
* comment the standard sqlite3 config
|
||||
* just below add:
|
||||
```yaml
|
||||
database:
|
||||
name: psycopg2
|
||||
args:
|
||||
user: matrix
|
||||
password: your-secret-pw
|
||||
database: synapse
|
||||
host: db
|
||||
cp_min: 5
|
||||
cp_max: 10
|
||||
```
|
||||
* change the password
|
||||
|
||||
### registration
|
||||
|
||||
* to enable user registration comment out this line: `enable_registration: true`
|
||||
|
||||
## configure `docker-compose.yml`
|
||||
|
||||
* change the postgres password to the password you've set before.
|
||||
|
||||
## create docker containers
|
||||
|
||||
|
||||
```bash
|
||||
cd /your/docker-compose/working/directory
|
||||
docker-compose -p matrix up -d
|
||||
```
|
||||
|
||||
If you can see the congrats page at `http://127.0.0.1:8008/` everything is working. This might take a few minutes, as the database has to be created.
|
||||
|
||||
## nginx config
|
||||
|
||||
To manage SSL/TLS I'm using nginx.
|
||||
|
||||
Just add another path to your working SSL v-host server, like this:
|
||||
```nginx
|
||||
#matrix server
|
||||
|
||||
#For the federation port
|
||||
listen 8448 ssl default_server;
|
||||
listen [::]:8448 ssl default_server;
|
||||
|
||||
location /_matrix {
|
||||
proxy_pass http://127.0.0.1:8008;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
# Nginx by default only allows file uploads up to 1M in size
|
||||
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
|
||||
client_max_body_size 10M;
|
||||
}
|
||||
```
|
||||
The full v-host server config might look like:
|
||||
```nginx
|
||||
server {
|
||||
server_name your.domain;
|
||||
|
||||
#main web server
|
||||
listen [::]:443 ssl ipv6only=on;
|
||||
listen 443 ssl;
|
||||
|
||||
root /var/www/your.domain;
|
||||
index index.html;
|
||||
|
||||
#matrix server
|
||||
|
||||
#For the federation port
|
||||
listen 8448 ssl default_server;
|
||||
listen [::]:8448 ssl default_server;
|
||||
|
||||
location /_matrix {
|
||||
proxy_pass http://127.0.0.1:8008;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
# Nginx by default only allows file uploads up to 1M in size
|
||||
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
|
||||
client_max_body_size 10M;
|
||||
}
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/your.domain/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/your.domain/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
|
||||
}
|
||||
server {
|
||||
if ($host = your.domain) {
|
||||
return 302 https://$host$request_uri;
|
||||
}
|
||||
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name your.domain;
|
||||
return 404;
|
||||
}
|
||||
```
|
||||
|
||||
//and that's it, good luck :D
|
@ -1,16 +0,0 @@
|
||||
---
|
||||
sidebar: true
|
||||
excerpt: "a simple webdav client in Vue3"
|
||||
meta:
|
||||
- name: description
|
||||
content: a simple webdav client in Vue3
|
||||
- name: keywords
|
||||
content: Alban, David, Becker, vuedav, cloud, dav, vue, web, javascript, node, typescript
|
||||
---
|
||||
|
||||
# vuedav
|
||||
|
||||
a simple webdav client in Vue3
|
||||
|
||||
- stack: Vue3, nginx, docker, nodejs, typescript
|
||||
- repo: [git.cybre.town](https://git.cybre.town/adb/vuedav)
|
Loading…
Reference in New Issue