init 2.0
commit
9dd6214d62
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,29 @@
|
||||
{
|
||||
"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": {
|
||||
"dart-sass": "^1.25.0",
|
||||
"sass": "^1.54.9",
|
||||
"sass-loader": "^10.3.1",
|
||||
"vuepress": "^1.5.3",
|
||||
"webpack": "^4.46.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vuepress/plugin-search": "^1.9.7",
|
||||
"@vuepress/theme-default": "^1.9.7",
|
||||
"bootstrap": "^5.2.1",
|
||||
"bootstrap-darkmode": "^5.0.1",
|
||||
"bootstrap-icons": "^1.9.1"
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
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)]
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
<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>
|
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<ul>
|
||||
<li v-for="page of $site.pages
|
||||
.filter(page => page.regularPath.match(new RegExp(`^${ path }.`)))
|
||||
.slice(0, limit)
|
||||
">
|
||||
<router-link :to="page.regularPath">{{ page.title }}</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "FolderList",
|
||||
props: {
|
||||
path: String,
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 8,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@ -0,0 +1,36 @@
|
||||
<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.adb.sh" target="_blank" rel="noopener noreferrer" />
|
||||
<a class="col-auto btn bi-mastodon" href="https://social.cybre.town" 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: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.social_icons > div {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: min-content;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.logo-img {
|
||||
fill: #fff;
|
||||
height: 3rem;
|
||||
margin: .75rem;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<div class="StickyWrapper">
|
||||
<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>
|
@ -0,0 +1,37 @@
|
||||
<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: 2.5rem;
|
||||
font-weight: lighter;
|
||||
font-family: "Roboto Thin", monospace;
|
||||
text-align: center;
|
||||
.dud {
|
||||
color: #166161;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,50 @@
|
||||
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' }]
|
||||
],
|
||||
markdown: {
|
||||
anchor: { permalink: false },
|
||||
extendMarkdown: md => {
|
||||
md.set({ breaks: true });
|
||||
}
|
||||
},
|
||||
dest: "./dist",
|
||||
themeConfig: {
|
||||
repo: '',
|
||||
editLinks: false,
|
||||
docsDir: '',
|
||||
editLinkText: '',
|
||||
lastUpdated: false,
|
||||
searchMaxSuggestions: 10,
|
||||
test: [/.+.md/],
|
||||
nav: [
|
||||
{
|
||||
text: 'projects',
|
||||
link: '/projects',
|
||||
},
|
||||
{
|
||||
text: 'music',
|
||||
link: '/music',
|
||||
},
|
||||
],
|
||||
sidebar: {
|
||||
'/guide/': [
|
||||
{
|
||||
title: 'Guide',
|
||||
collapsable: false,
|
||||
children: [
|
||||
'',
|
||||
'using-vue',
|
||||
]
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
'@vuepress/plugin-search',
|
||||
],
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ThemeConfig } from 'bootstrap-darkmode';
|
||||
|
||||
export const themeConfig = new ThemeConfig();
|
||||
themeConfig.initTheme();
|
||||
|
||||
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.name) {
|
||||
const { filename } = to.fullPath.match(matchPath).groups;
|
||||
next(
|
||||
siteData.pages
|
||||
.find((page) => page.regularPath.match(matchPath)?.groups?.filename === filename)
|
||||
?.regularPath
|
||||
);
|
||||
}
|
||||
next();
|
||||
});
|
||||
};
|
@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<section class="layout">
|
||||
<header>
|
||||
<div class="bg-darkmode-dark shadow">
|
||||
<site-header class="container" />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<div v-if="$page.frontmatter?.sidebar" class="container">
|
||||
<div class="row">
|
||||
<div class="col-xl-4 p-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<b>/{{ $page.path.split('/')[1] }}/</b>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<FolderList :path="`/${$page.path.split('/')[1]}/`" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Content class="col-xl p-4" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="container">
|
||||
<Content class="p-4" />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer my-3">
|
||||
<site-footer class="container" />
|
||||
</footer>
|
||||
</section>
|
||||
</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";
|
||||
|
||||
export default {
|
||||
components: { SiteFooter, SiteHeader, FolderList },
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
header {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
main {
|
||||
padding: 8rem 0 2rem 0;
|
||||
.sticky-sidebar {
|
||||
position: sticky;
|
||||
top: 4rem;
|
||||
}
|
||||
background-color: #1f262b;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,14 @@
|
||||
<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>
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div class="footer border-top py-2">
|
||||
<span class="copyright">Copyright © {{ (new Date).getFullYear() }} Alban David Becker</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<nav class="navbar px-4">
|
||||
<router-link class="btn d-flex" to="/">
|
||||
<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>
|
@ -0,0 +1,19 @@
|
||||
$dark-body-bg: #1f262b;
|
||||
|
||||
@import "bootstrap/scss/bootstrap";
|
||||
@import "bootstrap-darkmode/scss/darktheme";
|
||||
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
table {
|
||||
@extend .table;
|
||||
}
|
||||
|
||||
.search-box{
|
||||
input {
|
||||
background-color: $dark !important;
|
||||
color: $light !important;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
---
|
||||
home: true
|
||||
---
|
||||
<StickyWrapper>
|
||||
<TextScramble :phrases="[
|
||||
'Hey!',
|
||||
'Welcome to adb.sh :D',
|
||||
'I do web development', 'hosting free services', 'DJing / music', 'electronics'
|
||||
]" />
|
||||
<SocialIcons />
|
||||
</StickyWrapper>
|
||||
|
||||
----
|
||||
|
||||
## services, i'm hosting
|
||||
|
||||
### public services
|
||||
|
||||
| service | URL |
|
||||
| - | - |
|
||||
| git | [git.cybre.town](https://git.cybre.town) |
|
||||
| Mastodon | [social.cybre.town](https://social.cybre.town) |
|
||||
| HedgeDoc | [md.cybre.town](https://md.cybre.town) |
|
||||
| Jitsi | [jitsi.adb.sh](https://jitsi.adb.sh) |
|
||||
| Frama Date | [polls.cybre.town](https://polls.cybre.town) |
|
||||
| Searx | [searx.cybre.town](https://searx.cybre.town) |
|
||||
|
||||
### private services
|
||||
|
||||
| service | URL |
|
||||
| - | - |
|
||||
| nextcloud | [cloud.adb.sh](https://git.cybre.town) |
|
||||
| matrix | [element.adb.sh](https://element.adb.sh) |
|
||||
| mail | [mail.adb.sh](https://mail.adb.sh) |
|
||||
|
||||
|
||||
## contact me
|
||||
|
||||
- matrix: [@adb:adb.sh](https://matrix.to/#/@adb:adb.sh)
|
||||
- mail: [info@adb.sh](mailto:info@adb.sh)
|
@ -0,0 +1,14 @@
|
||||
# Music
|
||||
|
||||
i do music n stuff
|
||||
|
||||
## DJ sets
|
||||
### Techno
|
||||
<ExternalContentWrapper name="YouTube">
|
||||
<iframe width="100%" height="auto" 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>
|
||||
|
||||
### Melodic Techno
|
||||
<ExternalContentWrapper name="YouTube">
|
||||
<iframe width="100%" height="auto" 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>
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
sidebar: true
|
||||
---
|
||||
|
||||
# ArtNet-Node
|
||||
|
||||
Art-Net to DMX PCB
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
sidebar: true
|
||||
---
|
||||
|
||||
# Projects
|
||||
|
||||
<FolderList path="/projects/" />
|
@ -0,0 +1,13 @@
|
||||
---
|
||||
sidebar: true
|
||||
---
|
||||
|
||||
# **[chat]** *matrix-chat*
|
||||
|
||||
a simple matrix webapp for mobile and desktop
|
||||
|
||||
![matrix-chat screenshot](https://chat.adb.sh/media/screenshot-desktop.png)
|
||||
|
||||
- stack: Vue3, matrix-js-sdk
|
||||
- matrix.org: [matrix.org](https://matrix.org/docs/projects/client/chat)
|
||||
- repo: [git.adb.sh](https://git.adb.sh/adb/matrix-chat)
|
@ -0,0 +1,11 @@
|
||||
---
|
||||
sidebar: true
|
||||
---
|
||||
|
||||
# My Server Rack
|
||||
|
||||
I'm running my services on my own server, because it's fun :D
|
||||
|
||||
![server rack](https://social.cybre.town/system/media_attachments/files/106/116/563/016/082/536/original/968136dcb22aca7e.jpg)
|
||||
|
||||
My main server is a HP ProLiant DL380 G8.
|
@ -0,0 +1,10 @@
|
||||
---
|
||||
sidebar: true
|
||||
---
|
||||
|
||||
# vuedav
|
||||
|
||||
a simple webdav client in Vue3
|
||||
|
||||
- stack: Vue3, nginx, docker, nodejs, typescript
|
||||
- repo: [git.adb.sh](https://git.adb.sh/adb/vuedav)
|
Loading…
Reference in New Issue