Skip to content

Instantly share code, notes, and snippets.

View hscheuerle's full-sized avatar

Harry Scheuerle hscheuerle

View GitHub Profile
@hscheuerle
hscheuerle / Binding-OnChange.swift
Created December 5, 2022 17:23
Binding on change extension
import SwiftUI
extension Binding {
func onChange(_ handler: @escaping () -> Void) -> Binding<Value> {
Binding(
get: { self.wrappedValue },
set: { newValue in
self.wrappedValue = newValue
handler()
}
import SwiftUI
struct ScreenLockModifier: ViewModifier {
func body(content: Content) -> some View {
content
.onAppear {
UIApplication.shared.isIdleTimerDisabled = true
}
.onDisappear {
UIApplication.shared.isIdleTimerDisabled = false
@hscheuerle
hscheuerle / utilities.ts
Created June 28, 2021 16:55
non variadic cypress page object utility function
export const dataCy = (value: string) => cy.get(`[data-cy=${value}]`);
export const dataCyPath = (...attrs: string[]) => cy.get(attrs.map(attr => `[data-cy=${attr}]`).join(' '));
export const dataCyObject = <T extends readonly string[]>(hostAttr: string, attrs: T) =>
attrs.reduce((cyObject, attr) => (cyObject[attr] = () => dataCyPath(hostAttr, attr)) && cyObject, {} as Record<T[number], () => Cypress.Chainable<JQuery<HTMLElement>>>);
name: Deploy to Firebase Hosting on PR
"on": pull_request
jobs:
build_and_preview:
if: "${{ github.event.pull_request.head.repo.full_name == github.repository }}"
runs-on: ubuntu-latest
env:
IDS: '{ master: "hscheue-workspace", development: "work-development-6804b" }'
SA: '{ master: "FIREBASE_SERVICE_ACCOUNT_HSCHEUE_WORKSPACE", development: "FIREBASE_SERVICE_ACCOUNT_WORK_DEVELOPMENT_6804B" }'
C: '{ master: "production", development: "development" }'
name: Deploy to Firebase Hosting on merge
"on":
push:
branches:
- master
- development
jobs:
build_and_deploy:
runs-on: ubuntu-latest
env:
@hscheuerle
hscheuerle / firestore.rules
Created May 24, 2021 21:29
DocumentReference serialization is type path in Firestore rules, forward slash paths are type path in "raw" form. Here's a utility for checking ownership
function sentInvitation(invitationId) {
return exists(/databases/$(database)/documents/accounts/$(request.auth.uid))
&& get(/databases/$(database)/documents/invitations/$(invitationId)).data.invitedBy == /databases/$(database)/documents/accounts/$(request.auth.uid)
}
// In production, wrapping exists and get in small utilities is worth tradeoff in code readability
// chaining this with utility that null-checks auth and auth.uid helps read rule errors in unit tests
@hscheuerle
hscheuerle / many-to-many-firebase-functions.ts
Last active April 29, 2021 14:41
Many to many ref handling for firebase functions
import * as functions from "firebase-functions";
// import type so that lazy import isn't made useless
import type * as admin from "firebase-admin";
// global types only
type DocumentReference = admin.firestore.DocumentReference;
// lazy init admin, not required in pubsub but when paired in functions
// file with callables is important.
let initialized = false;
@hscheuerle
hscheuerle / index.js
Last active May 25, 2019 15:37
Naming for mongodb driver
const { MongoClient: driver } = require('mongodb');
const connectionSpread = [
process.env.DB_URL_DEVELOPMENT || 'mongodb://localhost:27017',
{ useNewUrlParser: true }
];
(async () => {
try {
const client = await driver.connect(...connectionSpread);
@hscheuerle
hscheuerle / request.js
Last active October 27, 2018 14:34
node.js http request with redirect
const handleRequest = async uri => {
return new Promise((resolve, reject) => {
http.get(uri, async res => {
const { statusCode } = res
if (statusCode === 302) { // redirect
const { location } = res.headers
const data = await handleRequest(location)
resolve(data)