2.0
adb-sh 2 years ago
commit 9dd6214d62

26871
package-lock.json generated

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,8 @@
/**
* Custom Styles here.
*
* refhttps://v1.vuepress.vuejs.org/config/#index-styl
*/
.home .hero img
max-width 450px!important

@ -0,0 +1,10 @@
/**
* Custom palette here.
*
* refhttps://v1.vuepress.vuejs.org/zh/config/#palette-styl
*/
$accentColor = #3eaf7c
$textColor = #2c3e50
$borderColor = #eaecef
$codeBgColor = #282c34

@ -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…
Cancel
Save