Skip to content

Instantly share code, notes, and snippets.

View fabe's full-sized avatar
🪼

Fabian Schultz fabe

🪼
View GitHub Profile
@fabe
fabe / rclone-putio-umbrel-home.md
Created February 12, 2026 13:54
rclone Put.io Sync on Umbrel Home

rclone Put.io Sync on Umbrel Home

Overview

Automatically syncs files from Put.io to Umbrel Home every 5 minutes using rclone running in a Docker container, deployed directly on the host (not through Portainer).

Why Not Portainer?

Portainer on Umbrel runs with a Docker-in-Docker (DinD) setup (docker:27.2.0-dind). This means containers created via Portainer's UI run inside Portainer's own Docker daemon, not on the host. Volume bind mounts reference the filesystem inside the DinD container, not the real Umbrel filesystem. Files written inside Portainer-managed containers never appear on the host.

@fabe
fabe / expo-pkce.js
Created August 6, 2019 23:00
Create a `verifier` and `challenge` in Expo (React Native) for the Authorization Code Grant Flow with PKCE (Auth0)
// Usage:
// const [verifier, challenge] = await createVerifierChallenge();
import * as Random from 'expo-random';
import * as Crypto from 'expo-crypto';
if (typeof Buffer === 'undefined') {
global.Buffer = require('buffer').Buffer;
}
@fabe
fabe / dotgrid.js
Last active January 18, 2023 10:21
Creates an svg dot grid in React
import React from 'react';
export default ({
width = 10,
height = 10,
space = 10,
radius = 1.5,
fill = '#000',
}) => {
const viewWidth = width * radius * 2 + (width - 1) * (space - radius * 2);
const getUserConfirmation = (location, callback) => {
const [newUrl, action] = location.split('|');
// Check if user wants to navigate to the same page.
// If so, we don't want to trigger the page transitions.
// We have to check the `action`, because the pathnames
// are the same when going back in history 🤷‍
const currentUrl = `${window.location.pathname}${window.location.search}`;
if (newUrl === currentUrl && action === 'PUSH') {
callback(false);
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
import React from 'react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
export const replaceComponentRenderer = ({ props }) => {
const children = React.createElement(props.pageResources.component, props);
return (
<div>
<TransitionGroup>
<CSSTransition key={props['*']} timeout={200} classNames="fade">
const objHasProps = (obj, props) => {
const check = props.map(prop => prop in obj)
return check.indexOf(false) === -1;
}
const obj = { a: 1, b: 2, c: 3 };
if (objHasProps(obj, ['a', 'c'])) {
// ...
@fabe
fabe / subnav.liquid
Created August 15, 2017 15:13
Jekyll Subnavigation / Subpages (nested)
---
layout: default
title: Portfolio
listed: true
---
{% assign entries = site.pages | sort: "path" %}
<!-- We'll split the url and check if the first element is the title of the page, then show it. -->
<ul>
{% for entry in entries %}
@fabe
fabe / component.js
Last active November 15, 2016 18:43
var Example = React.createClass({
render: function() {
return(
React.createElement('div', null, 'Hello from the other side!')
);
}
});
@fabe
fabe / Columns.jsx
Created April 13, 2016 10:31
Simple two column masonry layout for React
import React from 'react';
class Columns extends React.Component {
render() {
var columnFirst = []
var columnSecond = []
this.props.nodes.map(function(node, index) {
if(index % 2 == 0) {
columnFirst.push(node)
} else {