Skip to content

Instantly share code, notes, and snippets.

View jhannes's full-sized avatar

Johannes Brodwall jhannes

View GitHub Profile
@jhannes
jhannes / LocalizationDemo.tsx
Created June 24, 2021 20:07
TypeScript localization
import React, { useContext, useState } from "react";
import { BrowserRouter, Link } from "react-router-dom";
import { Route, Switch } from "react-router";
import { format, formatDistance, formatRelative } from "date-fns";
import nb from "date-fns/locale/nb";
import enUS from "date-fns/locale/en-US";
type AppLocale = "en" | "nb";
interface ApplicationTexts extends Record<AppLocale, string> {
@jhannes
jhannes / FcmSender.java
Last active June 23, 2021 20:09
Firebase Cloud Messaging sender client in java
import org.jsonbuddy.JsonNode;
import org.jsonbuddy.JsonObject;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
@jhannes
jhannes / ApplicationTexts.en.ts
Created October 29, 2020 23:00
Localization with TypeScript and React context
const english: ApplicationTexts = {
standardTexts: {
submit: "Submit",
},
personTexts: {
givenName: "First name",
familyName: "Last name",
title: "Title",
header: "Enter your details"
}
@jhannes
jhannes / ApplicationTexts.ts
Last active October 29, 2020 23:07
Localization with TypeScript and React context
interface ApplicationTexts {
standardTexts: {
submit: string;
};
personTexts: {
givenName: string;
familyName: string;
title: string;
header: string;
};
@jhannes
jhannes / App.tsx
Last active October 29, 2020 23:02
Localization with TypeScript and React context
export default function App() {
const [language, setLanguage] = useState(english);
return (
<ApplicationTextsContext.Provider value={language}>
<div className="App">
<MainPage />
<SelectLanguage onChangeLanguage={setLanguage} />
</div>
</ApplicationTextsContext.Provider>
);
@jhannes
jhannes / MainPage.tsx
Last active October 29, 2020 23:02
Localization with TypeScript and React context
function MainPage() {
const { standardTexts, personTexts: texts } = useContext(
ApplicationTextsContext
);
return (
<div>
<h2>{texts.header}</h2>
<div>
<label>{texts.givenName}:</label>
<input />
@jhannes
jhannes / useLoader.ts
Created October 24, 2020 20:33
Zombie spinner killer
function useLoader<T>(
loadingFunction: () => Promise<T>,
deps: DependencyList[] = []
) {
const [data, setData] = useState<T | undefined>();
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | undefined>();
async function reload() {
setData(undefined);
@jhannes
jhannes / TodoList.tsx
Last active October 24, 2020 20:34
React Zombie spinner killer
function TodoList({ list }: { list: string }) {
const { data, error, loading, reload } = useLoader(
async () => listTodos(list),
[list]
);
return (
<>
<h2>Items in {list}</h2>
{loading && <Spinner />}
{error && <ErrorView error={error} reload={reload} />}
@jhannes
jhannes / GoogleForms-to-Trello.gs
Last active May 23, 2023 14:45
Google Forms to Trello
var authentication = "key=a...&token=9...";
var idBoard = "592....";
var inboxList = "592...";
var updatedLabel = "592....";
function getField(itemResponses, fieldName) {
var titles = [];
for (var i in itemResponses) {
if (itemResponses[i].getItem().getTitle() === fieldName && itemResponses[i].getResponse().length > 0) {
@jhannes
jhannes / AnnotationScanner.java
Created January 16, 2015 14:49
Jetty 9 embedded Servlet 3.0 annotations without war file
public class AnnotationScanner {
protected void scanForAnnotations(final String javaPackage, WebAppContext webapp) throws Exception {
Set<AnnotationParser.Handler> handlers = new HashSet<>();
handlers.add(new WebServletAnnotationHandler(webapp));
handlers.add(new WebFilterAnnotationHandler(webapp));
handlers.add(new WebListenerAnnotationHandler(webapp));
AnnotationParser annotationParser = new AnnotationParser();
for (URL url : ((URLClassLoader) getClass().getClassLoader()).getURLs()) {