Ich hab endlich mal wieder angefangen Diablo 3 zu spielen. Diesmal auf der Switch. Immer noch grandios!
Since 2005.
Ich hab endlich mal wieder angefangen Diablo 3 zu spielen. Diesmal auf der Switch. Immer noch grandios!
Heute, am Pfingstmontag, wollte ich ein paar Stunden Arbeit nachholen, die ich am Freitag nicht mehr geschafft habe. Was man halt so macht, an einem wunderbar sonnigen Feiertag.
Da sich Feiertage anbieten, um kritische Software-Updates durchzuführen, denn sonst arbeitet ja keiner, loggte ich mich erstmal auf dem entsprechenden Server ein und updatete unsere GitLab-Installation. Im Normalfall läuft das immer völlig problemlos durch und erfordert kein manuelles Eingreifen.
Während das Update noch läuft, wechsel ich zu Tower und versuche mal den aktuellsten Stand eines Branches zu ziehen und bekomme direkt einen Fehler. Toll.
Vor kurzem zog ich ja mit einem kurzen Umweg über mailbox.org zu Fastmail um. An und für sich funktioniert auch noch alles ganz gut, aber eins ist doch immer noch nicht ganz so fast — die Suche. Damals, mit Google Mail, war die Suche immer wirklich schnell und zielsicher. Bei Fastmail dauert es manchmal schon einige SEKUNDEN, bis alle Ergebnisse gefunden wurden.
Ja gut, man könnte sagen, dann warte halt mal ein bisschen, stell dich nicht so an, und das wäre wahrscheinlich die korrekte Einstellung, aber ich wäre nicht ich, wenn mich das nicht kolossal stören würde, denn vorher ging es ja.
Zu Google will ich nicht zurück, was kann ich also tun? Mein erster Gedanke: Ein paar E-Mails löschen, damit der Suchindex vielleicht kleiner wird, vielleicht beschleunigt das etwas?
Man muss wissen, dass ich seit immer die “Archivieren”-Funktion in Mail-Clients benutze, das heißt, ich habe seit mindestens 2010, oder so, quasi keine E-Mail gelöscht.
Kämen in meinem Postfach nun nur sehr wichtige E-Mails an, wäre das nicht schlimm, aber ich hatte damals zum Beispiel auch so 15 Twitter-Quatsch-Accounts, und 5-10 Jahre Twitter-Notifications für fünfzehn Accounts sind schon einige E-Mails. Die wurden zwar per Filter immer automatisch archiviert, aber eigentlich ist es Quatsch diesen Müll zu behalten.
Puh, da googelt man einmal falsch, schreibt einen langen Blogpost dazu, und schon kommt die Rettung per Twitter.
$ yarn global add @vue/cli
$ vue create tagebuch
$ cd tagebuch
$ vue add electron-builder
$ yarn electron:serve

War doch nicht so schlimm wie erwartet! Bin nach 15 Minuten quasi fertig.
(Kauft Mouseless und Glyphfinder!)
Irgendwann Ende 2011 fing ich damit an ein Tagebuch zu schreiben. Erst in einem Heftchen, kurze Zeit später per Day One. So füllte sich mein digitales Journal von Jahr zu Jahr mit Einträgen. Manchmal mehr, manchmal weniger. Teilweise habe ich Monate lange Streaks mit täglichen Einträgen, hier und da fehlt ein halbes Jahr. Letzteres ist natürlich sehr schade, aber so ist das mit mir und Habits. 18 Tage scheinen bei mir nicht zu reichen, um eines zu formen!
Vor ein paar Monaten startete ich mal wieder einen Versuch, das Tagebuchschreiben zu einem festeren Bestandteil meines Tages werden zu lassen, aktualisierte Day One und kaufte sogar eine Premium-Subscription um den Dark Mode zu bekommen.
Meine Freundschaft mit Day One war allerdings schon mit der Einführung von Day One 2.0 vor einigen Jahren leicht angekratzt. Statt weiter auf Dropbox oder iCloud-Sync zu setzen, bauten sie ihr eigenes Sync-System, und eine Verschlüsselung ließ lange auf sich warten. Zusätzlich kamen immer weitere Features hinzu (z.B. Tagebucheinträge Blog-mäßig veröffentlichen, wer will das? Was passiert, wenn ich aus Versehen den Button drücke?), die ich nicht brauchte und das Interface wurde immer überladener und unschöner.
Damit ich das alles nicht mehr sehen muss, schrieb ich mir einen iOS Shortcut, mit dem ich Tagebucheinträge schreiben konnte, ohne Day One öffnen zu müssen. Schonmal nicht schlecht.
Ein paar Tage später fiel mir dann ein, dass ich noch nicht genug Side Projects habe und baute mir einen neuen Shortcut, der einfach Textdateien im iCloud Drive ablegt, immer, wenn ich einen Tagebucheintrag schreiben will. So einfach!
Ich brauche keine Bilder (die sind eh in Photos.app), kein Wetter, keine Location, etc — ein Tagebucheintrag ist ein Text, fertig aus.
Ein paar Problemchen gabs natürlich noch. Zum Ersten darf die Shortcuts-App nur in den „Shortcuts“-Ordner im iCloud Drive speichern, lol. Ich schrieb also einen Cronjob auf meinem Mac, der die Dateien automatisch in ein anderes Verzeichnis zieht.
Des Weiteren hätte ich die Sachen natürlich gerne verschlüsselt, auch das erledigt mein Cronjob.
Als das alles ganz gut lief, kündigte ich die Premium-Subscription und schrieb einen Importer für den Day One-Export. Rund 2.000 Einträge wanderten in meine einfache Dateistruktur.
Das letzte, ungelöste Problem: Ich habe keine schöne Methode mehr, die Einträge anzuzeigen, wie schade ist das denn.
Mein Plan dafür war es, eine kleine Electron-App zu schreiben, die das Verzeichnis einliest, und alles schön präsentiert. So richtig wichtig war es mir die letzten Monate aber nun auch nicht, und so geriet es in Vergessenheit…
Heute googelte ich mal „electron vue getting started“, öffnete drei Tabs, schloss vier Tabs, den Mac und das Arbeitszimmer. Vielleicht baue ich es doch lieber als normale Webseite.
(Alle Getting Started-Guides und Boilerplates sahen nicht so aus, als könnte man in fünf Minuten, etwas halbwegs laufendes Hochziehen, das ist ja schonmal sehr abschreckend.)
Bei der Rezepte-App hänge ich so langsam fest. Je nachdem, worauf ich gerade Lust habe, baue ich ein Feature ein. Zeit zum preppen dank Corona? Endlich kann ich die Lager-Seite einbauen, damit ich aufschreiben kann, was im Keller liegt. Habe ich das fertig, könnte ich in die Rezept-Ansicht einbauen, dass direkt gehighlighted wird, welche Zutaten noch da sind, ups, da ist ja noch anderer Bug, ach und dies und das.
Am Ende ist nichts fertig und alles kaputter als vorher.
Auf wenn es natürlich Spaß macht, so wild herum zu wüten — und Spaß ist ja das einzige was für mich bei Sideprojects zählt, was wahrscheinlich der Grund ist, warum ich nie was fertig bekomme — entschied ich mich, die ganze etwas strukturierter anzugehen und legte mehrere Projekte mit Tasks in Things an.

Des Weiteren fehlten mir zur völligen Vollendung noch ein paar Designs nach denen ich mich richten kann. Seit jeher programmiere ich eigentlich ungern an Sachen, die am Ende nicht schön werden — wahrscheinlich noch ein Grund, warum ich nie was fertig bekomme.
Wie auch immer. Ich kann das zwar nicht, denn wenn ich es könnte, wär ich Designer und nicht Programmierer, denn Designer ist der coolere Job, da ist man nämlich nicht darauf angewiesen, dass man einen Designer hat, damit das Endprodukt schön ist, aber immerhin kann ich figma.com in die Adresszeile meines Browsers eingeben und ein paar Boxen aufziehen. (Ich kann natürlich auch Sketch starten, aber ich wollte hip sein)

Ein paar Stunden später hatte ich ein paar Screens fertig, und auch jetzt, zwei Tage später, find ich sie sogar noch ganz gut. Fast so gut, dass ich mir vorstellen könnte, sie umzusetzen! Natürlich werde ich am Ende sicherlich noch ein paar Stunden mit Hannah die Feinheiten einarbeiten, aber ich bin halbwegs zufrieden mit dieser Grundlage.
Wird die Rezepte-App jemals fertig werden? Immerhin habe ich nach ein paar Stunden Aufräum-, Konzept- und Designarbeit jetzt einen genaueren Überblick über die Features, die ich mir wünsche, welche noch fehlen. Zusätzlich war es mal eine gute Abwechslung zum programmieren. Kann man mal machen!

Wie gesagt, ich hab mal einen aktuellen Apple-Datenexport gezogen. Insgesamt überraschend wenig Inhalt, das Witzigste ist wohl diese sehr sinnvolle Datei.

Zwei Bücher, bei denen ich nicht widerstehen konnte sie zum Neuerscheinungspreis zu kaufen, als Hunger Games- und Thelen-Fanboy.
Stellt euch vor, ihr habt eine Rezepte-App mit einer Suche und ihr wolltet schon immer so eine Suchleiste, die ein bisschen so ist, wie in jeder halbwegs fancy Mail-App, oder so, und zwar, dass man neben der normalen Volltext-Suche auch so Facetten hat, nach denen man suchen kann. In den Mail-Apps sind das dann Sachen wie Absender und Empfänger, und hier halt zum Beispiel Zutaten oder Tags.
Nun ist die Frage, wie baut man sowas. Im Grunde ist es ein <input>-Feld, aber mit etwas fancyness, damit die Facetten automatisch erkannt und anders eingefärbt werden. Dazu soll man sie natürlich noch einfach mit einem Klick entfernen können, oder wenn man Backspace drückt, etc.
Aussehen soll es etwa so:
Da ich gerne verstehe, wie etwas funktioniert, wollte ich es gerne selber bauen. Also abgesehen davon habe ich auch ca. vier Sekunden gegoogelt, aber fand auch kein npm-Package, dass das leistet. Suchte aber auch nur nach “fancy schmancy search box”.
Mein erster Gedanke war ein <input>-Feld zu nehmen, wo man Sachen eingibt, und das von einem <div> mit den gerenderten Elementen zu überdecken. Problem dabei: Wo bleibt der Cursor, und woher weiß man wo man gerade tippt? blöde Idee.
Da ich einen Blogpost daraus machen wollte, habe ich den Zwischenstand allerdings aufgehoben, hier eine Live Demo:
Nachdem ich mit der ersten sehr naiven Version nicht weiter kam, dachte ich kurz an contenteditable. Mit diesem Attribut kann man ja jedes HTML-Element zu einem Eingabefeld machen, toll! Ich las zwar in den letzten Jahren immer sehr viel Negatives, und es ist in meinem Kopf eher unter considered evil abgespeichert. Aber was solls!
Iframes sagen mehr als tausend Worte, hier also schonmal das Ergebnis:
Doch wie funktioniert es? Irgendwie low-leveliger, als mir lieb ist. Ich überwache die input-Events von meinem editierbaren <div> und entscheide für jede gedrückte Taste, was passieren soll. Letztendlich sammle ich immer alle Buchstaben in einem Buffer, und sobald ein Leerzeichen getippt wird, wird der aktuelle Buffer in ein Token-Array gespeichert und geleert. Bei nem Backspace wird der letzte Token gelöscht, etc etc.
input(ev) {
const type = ev.inputType;
const char = ev.data;
if(type === 'deleteContentBackward') {
if(this.currentBuffer.trim().length) {
this.currentBuffer = this.currentBuffer.substring(0, this.currentBuffer.length -1);
} else {
if(this.tokens.length) {
this.tokens.splice(this.tokens.length - 1, 1);
}
}
} else {
if(char === ' ') {
this.tokens.push(this.currentBuffer);
this.currentBuffer = ' ';
}
this.currentBuffer += char;
}
this.$refs.wurst.innerHTML =
this.render(this.tokens) + ' ' + this.currentBuffer;
placeCaretAtEnd(this.$refs.wurst);
},
Immer wenn ich solchen Code schreibe, der irgendwas mit einzelnen Zeichen macht, fühle ich mich schmutzig und denke, dass ich lieber eine fertige Library nehmen sollte, aber Ziel dieser Aktion war es ja, zu verstehen, wie das funktionieren könnte. Daher waschen wir uns kurz die Hände und machen weiter!
Nach jedem Event rendere ich dann alle Tokens neu in das <div> und setze den Cursor mit einer von Stack Overflow geklauten Funktion wieder ans Ende (hab kein Interesse daran, zu verstehen, wie man den Focus ans Ende setzt)
Tatsächlich funktioniert das schon ganz gut so und nach 20 Minuten rumprobieren war meine Neugier auch erstmal gestillt.
Der nächste Schritt wäre jetzt, die einzelnen Tokens als Vue-Komponenten zu rendern, damit ich ihnen mehr Funktionen geben kann. Ob das klappt, erzähle ich beim nächsten Mal!
Ich habe eben mal das Such-Formular (ganz unten) reaktiviert. Endlich findet man wieder Dinge auf dieser Seite!