[ACTIVE] the website and home of figbert on the clearnet
git clone git://
Log | Files | Refs | README | LICENSE

commit 9d9e7405ab225e46dd53e94d0be759f7aba07b82
parent 9add511da3098e47f0c29149dfb4987daea78512
Author: FIGBERT <>
Date:   Fri, 14 Aug 2020 22:54:32 -0700

:speech_balloon: Restore articles and projects from Sapper site

Acontent/posts/ | 8++++++++
Acontent/posts/how-to-replace-keybase-in-three-easy-steps/h-card.png | 0
Acontent/posts/how-to-replace-keybase-in-three-easy-steps/ | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/posts/i-wrote-this-one/chad.jpg | 0
Acontent/posts/i-wrote-this-one/dock.png | 0
Acontent/posts/i-wrote-this-one/ | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/posts/i-wrote-this-three/collection.png | 0
Acontent/posts/i-wrote-this-three/ | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/posts/i-wrote-this-two/doughnut.mp4 | 0
Acontent/posts/i-wrote-this-two/doughnut.webm | 0
Acontent/posts/i-wrote-this-two/ | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/posts/i-wrote-this-two/jailbreak.mp4 | 0
Acontent/posts/i-wrote-this-two/jailbreak.webm | 0
Acontent/posts/i-wrote-this-two/rick-and-morty.jpg | 0
Acontent/posts/ | 11+++++++++++
Acontent/posts/pebkac-txtodo-rewrite/ascending-checkmarks-error.webm | 0
Acontent/posts/pebkac-txtodo-rewrite/ | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/posts/pebkac-txtodo-rewrite/randomized-test-values.webm | 0
Acontent/posts/pebkac-txtodo-rewrite/update-preview.webm | 0
Acontent/posts/pebkac-txtodo-rewrite/variable-comparison.webp | 0
Acontent/projects/ | 8++++++++
Acontent/projects/txtodo/core-data-structs.png | 0
Acontent/projects/txtodo/ | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/projects/txtodo/manage-task-deletion.png | 0
Acontent/projects/txtodo/tap-modifiers-order.png | 0
25 files changed, 767 insertions(+), 0 deletions(-)

diff --git a/content/posts/ b/content/posts/ @@ -0,0 +1,8 @@ ++++ +title = "Posts" +description = "" +sort_by = "date" +paginate_by = 20 +insert_anchor_links = "left" ++++ + diff --git a/content/posts/how-to-replace-keybase-in-three-easy-steps/h-card.png b/content/posts/how-to-replace-keybase-in-three-easy-steps/h-card.png Binary files differ. diff --git a/content/posts/how-to-replace-keybase-in-three-easy-steps/ b/content/posts/how-to-replace-keybase-in-three-easy-steps/ @@ -0,0 +1,122 @@ ++++ +title = "How to Replace Keybase in 3 Easy Steps" +description = "Ever since Keybase was acquired by Zoom, a company with a very bad history with security/privacy, people wanted an alternative. There have been a few different alternatives proposed: this is mine." +date = 2020-07-03 ++++ + +Ever since [Keybase was acquired by Zoom][keybase-joins-zoom], a [company][zoom-security-one] [with][zoom-security-two] [a][zoom-security-three] [very][zoom-security-four] +[bad][zoom-security-five] [history][zoom-security-six] [with][zoom-security-seven] [security][zoom-security-eight]/[privacy][zoom-security-nine], +[people wanted an alternative][zoom-security-ten]. There have been a few different alternatives proposed: this is ~~the best~~ mine. + +<!-- more --> + +## What is Keybase? + +Before we talk about replacing [Keybase][keybase], we should have a good idea of what Keybase actually is. It's main features are as follows (ordered as on the website): +* E2EE chats and messaging (people and teams). +* Cryptographic identity verification from around the net. +* [KBFS][kbfs] (Public signed file hosting, private E2EE file storage w/ sharing, [Static site hosting??][kbfs-static]) +* Git repositories? Crypto? [An alternative to PGP?][saltpack] + +## Previous Attempts to Replace Keybase + +I'm not the first person to try this, obviously. Some brave folks have tried to build Keybase alternatives, such as [][] and the brand-new [Keyoxide][keyoxide]. +I've tried both, but found that though they both are good in their own right, they are not the solutions that I am looking for. + +## OK Time for the Steps + +### Step #1: Chat/Messaging + +There are a few great pre-existing options for encrypted messaging: [Signal][signal], [ProtonMail][protonmail] if you want to go full email, [Telegram][telegram], and +[WhatsApp][whatsapp]. However, they all have their problems (though I use the first two on a daily basis). Signal requires a phone number, and is more of an iMessage/text +replacement than a Slack-style chat app. Protonmail is literally not chat – it's email. Telegram is [not][telegram-security-one] [secure][telegram-security-two]. If you use +WhatsApp for security you might be crazy – I only use it because it's *the way* to communicate with people in the Middle East and Africa. + +Instead, I would recommend you use [**Matrix**][matrix]. Matrix is an "open network for secure, decentralized communication," and it's the perfect replacement for Keybase's chat +~~and I would argue most other chat apps too~~. It utilizes E2E encrypted messaging, and can be self-hosted as well ~~or if you're cheap like me just get your friend to host~~. + +In addition to a Matrix server, you also need a client. For this, I recommend [**Riot**][riot]. Riot is a beautiful Matrix client with a bunch of awesome features, including +Slack-like integrations, and apps for pretty much every major platform (Linux, MacOS, Windows, iOS, Android, and a web client). ~~Plus it looks a lot like Discord.~~ + +### Step #2: Identity verification + +Replacing Keybase's [original function][keybase-archive] is probably the most difficult part of this tutorial: cryptographically verified identity proofs is a great and +innovative idea. I would swap this out with an [**IndieWeb**][indieweb] profile – one [part][h-card] of the larger [microformats][microformats] HTML structure. There are some +pretty great tutorials out there (I would recommend [this one][kev-article] by the fantastic [Kev Quirk][kev] and [this one][brian-article] by [Brian Wisti][brian]), so I won't +go into too much detail about exactly how to do that. However, it's important to note that though Kev recommends hiding your h-card with the `display: none;` property: [don't do +that][invisible-metadata]. I just merged my about and contact pages onto my homepage, and added the microformats classes to my existing markup. + +![My IndieWeb h-card](h-card.png) + +### Step #3: File Storage + +Replacing KBFS is easy to do, but hard to get right. Swapping to [Google Drive][drive] is probably the move that most people would make, but that abandons the entire +security/encryption aspect of Keybase. There's also [Dropbox][dropbox], but that has the same problems as above. [ProtonDrive][proton-drive] has potential, but it's not out yet. +Enter [**Syncthing**][syncthing]. [Nikita Tonsky][sync-article] wrote one of my favorite posts of all time about Syncthing – go read it. One reason Syncthing is so great is that +it's not the same thing as KBFS or any of the other "Drive" solutions. Instead of being a file hosting system, it's a "continuous file synchronization program." You have no data +limits other than your storage and no third-party to worry about. Plus, sharing folders is also incredibly easy. Just read the article. + +### Bonus Step #4: Video Calling + +It would be a shame to talk about text chat, or really any form of communication, in this new pandemic age without talking about video chat. After all, the whole reason I'm +writing this article is because the new videocalling giant [Zoom][zoom]. So, how have I replaced Zoom and how does that relate to replacing Keybase? Well, Matrix happens to have +a fantastic [Jitsi Meet][jitsi] [integration][jitsi-in-matrix]. Plus, the folks over at Jitsi are [working on E2E encryption for their calls][jitsi-e2e]. I've integrated Jitsi +Meet into my self-hosted instance of Matrix, and now all my videocalls are just that – mine! + +## Summary + +* Swapped chat to Matrix and Riot. +* Swapped identity verification to Indieweb. +* Swapped file storage/sync to Syncthing. +* Added videocalling to chat program via Jitsi. + +## Conclusion + +Keybase is a great service, and the people who work there should be really proud of what they've built. However, given Zoom's aquisition of the company, the stability and +security of the product have been called into question. So, ever one to hop on a hype train, I jumped ship. I'm really happy with my solution, and I'd love to hear your thoughts +as well ~~as soon as I set up webcomments~~. + +[keybase-joins-zoom]: +[zoom-security-one]: +[zoom-security-two]: +[zoom-security-three]: +[zoom-security-four]: +[zoom-security-five]: +[zoom-security-six]: +[zoom-security-seven]: +[zoom-security-eight]: +[zoom-security-nine]: +[zoom-security-ten]: +[keybase]: +[kbfs]: +[kbfs-static]: +[saltpack]: +[]: +[keyoxide]: +[signal]: +[protonmail]: +[telegram]: +[whatsapp]: +[telegram-security-one]: +[telegram-security-two]: +[matrix]: +[riot]: +[keybase-archive]: +[indieweb]: +[h-card]: +[microformats]: +[kev-article]: +[kev]: +[brian-article]: +[brian]: +[invisible-metadata]: +[drive]: +[dropbox]: +[proton-drive]: +[syncthing]: +[sync-article]: +[zoom]: +[jitsi]: +[jitsi-in-matrix]: +[jitsi-e2e]: + diff --git a/content/posts/i-wrote-this-one/chad.jpg b/content/posts/i-wrote-this-one/chad.jpg Binary files differ. diff --git a/content/posts/i-wrote-this-one/dock.png b/content/posts/i-wrote-this-one/dock.png Binary files differ. diff --git a/content/posts/i-wrote-this-one/ b/content/posts/i-wrote-this-one/ @@ -0,0 +1,88 @@ ++++ +title = "I Wrote This #1" +description = "So, I'm FIGBERT – I wrote this. I'm a highschooler working in the tech world, currently stuck at home like pretty much everybody else who's not trying to die. I plan on using this blog to write mainly on my experiences in the tech world, either in focused articles centered around one topic or more summary-style roundups like this, the 'I Wrote This' series." +date = 2020-06-13 +updated = 2020-08-14 ++++ + +So, I'm FIGBERT – I wrote this. ~~nailed that intro.~~ I'm a highschooler working in the tech world, currently stuck at home like pretty much everybody else who's not trying to +die. I plan on using this blog to writing mainly on my experiences in the tech world, either in focused articles centered around one topic or more summary-style roundups like +this, the "I Wrote This" series. + +<!-- more --> + +I've always found statements like that kind of funny in their generalness, and was thinking the other day that if I ever made a game studio I would name it "I Made This Game." +Then, when I was trying to think of what to name this series (The Weekly Fig? Fig Talks?), I thought it would be funny to do something similar. I plan to release these once a +week on Saturdays, if all goes to plan. Without further ado, here's a brief summary of interesting things that happened this week. + +## Releasing txtodo v2.0 + +Some people reading this may be familiar with my most recent project, [txtodo][txtodo] – you can read a full writeup of the project [here][txtodo-writeup]. The point of txtodo +was to create a todo list application without any feature bloat I found in other competing solutions – *every task deletes at midnight*. This week I launched the MacOS companion +app for txtodo, completing my long-term "cross-platform" goal for the app. I went from not knowing SwiftUI at all to having two published apps that talk to each other! Making +computers talk to each other is, like, the hardest thing you can do with computers! ~~Ok, technically a lot of it is just Apple APIs but still, let me have this.~~ I think there +is probably one more major change I could make to the app (moving the tasks from an `@State` variable to an `@EnvironmentObject`), but after that it's pretty much bugfixes +and... the bank? I don't know. + +## Signing Git Commits + +I while back I saw that when I editing my project using the GitHub web app, it got a little green "verified" badge next to the commit message. I looked into it for a +bit today, and found [this GitHub help article][signing-commits]. One GPG install and Protonmail-key-download later, now all my commits have a green badge! Neat! + +## The Meh vimrc + +I made the switch from nano to vim a few months ago, but up until a few days ago I was using the barebones default `macvim`. Not anymore! I DuckDuckGo-ed "vim configuration," +and downloaded what is supposedly "The ultimate Vim configuration." from [amix][ultimate-vim]. It's a pretty good configuration out-of-the-box: I'm using the Awesome version +with the fantastic [Jetbrains Mono][jetbrains-mono] font. I'm still not that good at actually using vim to its fullest potential but I'm confident that I'll improve with a +little practice and ascend to elite vim status in no time. + +![The virgin classic developer vs the chad linux dev][vim-dev] + +## Maybe Rust? + +Speaking of elite programmers: Rust! I've been thinking about learning the language for a while, and now that I have no main project (other than maintain my finished apps and +sites), it's as good a time as any to learn a new language. It's idiomatic syntax combined with low-level abilities makes Rust seem a little bit like Python+ to me. It also +helps that it's skyrocketing in popularity – maybe I'll do the cliche Rust developer thing and post about how much I love the language on [the orange site][hn] once I learn it. +~~ok so I was planning on linking a bunch of posts like that here, but when I looked for them on HN I actually couldn't find any, but I distinctly remember reading them so I +stand by this statement.~~ + +## From Brave to Firefox + +I made the switch from [Brave][brave] to [Firefox Developer Edition][firefox] this week, after accumulating around 50 USD in BAT. I started using Brave almost when it came out +and loved it – the chromium feel with a powerful built in adblocker? It sounded too good to be true – and perhaps it was: over time the browsers performace began to slow down, +they [hijacked links][brave-hijack], launched a [weird Zoom competitor][brave-zoom] with no fanfare or announcement, and refuse to get rid of their [required KYC][brave-kyc]. +Anyways, I dropped it. Now my dock is all blue! + +![My dock with all blue apps][dock] + +## New Music + +On a non-tech-related note, a bunch of good new music came out recently. In no particular order, here are some good new songs (largely out of the Middle East): + +* [Coronavirus by Mohamed Ramadan]( +* [Zot Ani – Ela Li Lahv]( +* [Million Dollar – Noah Kirel and Shachar Saul]( +* [Naughty – Tzagay Boi]( +* [TROLLZ – 6ix9ine & Nicki Minaj]( + +## Wrapup + +So, that's been this week's update. I've got some exciting ideas for my next posts, so I hope you stick around for what's to come. Until then, farewell! + +-- +FIGBERT + +[txtodo]: +[txtodo-writeup]: /projects/txtodo +[signing-commits]: +[ultimate-vim]: +[jetbrains-mono]: +[vim-dev]: chad.jpg +[dock]: dock.png +[hn]: +[brave]: +[firefox]: +[brave-hijack]: +[brave-zoom]: +[brave-kyc]: + diff --git a/content/posts/i-wrote-this-three/collection.png b/content/posts/i-wrote-this-three/collection.png Binary files differ. diff --git a/content/posts/i-wrote-this-three/ b/content/posts/i-wrote-this-three/ @@ -0,0 +1,188 @@ ++++ +title = "I Wrote This #3" +description = "It appears I'm not that great at keeping a weekly schedule. Right after I published my last post, I started a class on text adventures and have been living and breathing in Inform7 ever since. I've also spent some time working on this site – though I've got even bigger changes coming in the future – learning a few new languages, and listening to a whole lot of music. I think something happened in cybersec too? Oh also I learned how to drive." +date = 2020-07-04 ++++ + +It appears I'm not that great at keeping a weekly schedule. Right after I published my last post, I started a class on text adventures and have been living and breathing in +[Inform7][inform] ever since. I've also spent some time working on this site – though I've got even bigger changes coming in the future – learning a few new +languages, and listening to a whole lot of music. I think [something happened in cybersec][twitter] too? Oh also I learned how to drive. + +<!-- more --> + +## Interactive Fiction + +These past few weeks, my main work has been on interactive fiction as part of a summer class for my school. The first week was spent learning the history of text adventures (as +I will refer to them for the rest of the article, becuase calling them "interactive fiction" makes me sound like ~~a dick~~ a snob). I gathered a collection of games to play in +free time (if I ever have any more of that), from the very first of the genre – Adventure – to modern ones like Lost Pig. + +![My collection of text adventures: Adventure, Bronze, Counterfeit Monkey, Curses, Hitchhiker's Guide to the Galaxy, Lost Pig, and Slouching Towards Bedlam][if-collection] + +In the second week, we all made our own text adventures. It was a really interesting experience – drastically different than any other programming I've done. The main thing I +struggled with was the semi-NLP style of [Inform7][inform]. Rather than telling the computer what to do, I felt like I was making suggestions. I also struggled with the editor a +bit. Inform7 isn't open source, which means there's only one IDE you can use to program in the language. That would be fine if the IDE was high quality, but I often found it +~~really bad and draining~~ mediocre. This was made a little better after I changed the editor colors to be much more vibrant ~~so I wouldn't fall asleep~~, but I still +felt like it needed some work. Regardless of any struggles along the way, the payoff after the game was finished was huge. Watching my little sister play a text adventure for +the first time, *one I had made*, was awesome. + +Without further ado, I present to you: *One Angry Wizard, or the Tentacular Adventures of our Brave Hero through a World Most Strange and Foreign*. You can ~~play it online +here or~~ download the .gblorb [here][angry-wizard]. **EDIT:** I've removed the online version for privacy concerns. I'm going to push a project write-up to the projects +page soon, and plan on updating the game consistently for a while (if you want to send me feedback, send it to my [email address][email]). Enjoy! + +## Site Work + +I made some changes that you guys can see, and some other ones behind the scenes. + +### Joining Webrings + +I first encountered webrings on [Hacker News][geekring-hn], where I find most of my interesting internet things. From there, I decided to join both the [geekring][geekring] and +the [Hotline Webring][hotline-webring] – you can find links to the webrings in the nav on every page. Joining the Hotline Webring was designed to be supremely easy, but the +geekring was a little more complicated. I've never been a big IRC person (though not for lack of trying), and I ended up joining via the HTML form and getting my key via email +(I may or may not have confused my number with my private-ish key, and had to use a little bit of [bfg][bfg] magic to fix that). + +### Self-Hosting + +My site was previously hosted using a continuous deploy on [Netlify][netlify]. This was a pretty great system for me – all I had to do was commit my code to the GitHub repo, +which I was already doing, and the they would take care of everything and serve a great site – here's the kicker – **for free**. This was working really well for me for a while, +until I decided to add security headers to the site. I tried doing this in two different ways: using [Helmet][helmet] as described [in the Sapper Docs][sapper-csp] and using +Netlify [\_headers][netlify-headers]. The Helmet middleware didn't work with Netlify, and I'm honestly not sure why – possibly because of how they host the file server (I'm not +sure what/how they server the site), or maybe I just f\*cked up somewhere idk JavaScript is hard. Using the Netlify config didn't work either because I'm not a paying +subscriber, which wasn't too clear at first. This would probably be solved if I just gave them money, but I'm not going to do that any time soon. + +I decided to move to [DigitalOcean][digitalocean] and host the site myself (or I guess not totally myself – I don't feel comfortable running it on a Pi from my house just yet) +with [Caddy][caddy]. I went with DigitalOcean partially because of their dev-focused business model, but mostly because they're cheap (my droplet is USD$5/month and I get $50 +credit with them from the [GitHub Student Developer Pack][student-pack] – my first year of hosting for only $10). + +Unfortunately, I didn't quite run the transition too well. It definitely wasn't zero downtime – it was probably more like a-few-hours downtime. I doubt this really affected +anyone because of my small audience, but I was still up late working on it. If it had happened a few days later, it might have gotten mixed up with the [Cloudflare +downtime][cloudflare] (I don't use Cloudflare). + +My current setup uses a custom CaddyServer configuration to serve my site, which I am absolutely loving so far: it is so much easier to run advanced setups with Caddy than +Apache or Nginx. I wanted to move away from Javascript analytics (via [GoatCounter][goatcounter]) to log-based analytics (via [GoAccess][goaccess]) but found that Caddy's +structured logs are not supported natively. I'm hoping [they'll add it][goaccess-gh] soon though! Also, I stumbled on [this article][goaccess-script] while writing this, and may +check that out. + +### Next Steps + +I've got two major todos for my site in the near future. The first thing I want to do is Dockerize. Using Docker will significantly clean up my current setup, and allow me to +host more fun things on the same machine (for example, [my own analytics][plausible] and maybe [git][gitea]). With that said, I probably should get a little better at Docker +first... For beginners, [Flavio Copes'][flavio-docker] has a few pretty great posts on the subject. + +The second thing I want to do is a bit of a larger project, and one I'm not yet sure how I'm going to solve it. I've run into some problems with the frameworks I use to develop +[][figbert]. Sapper generates inline scripts and blobs, which tanks the security of my CSP. [Their proposed solution][sapper-csp] is to inject nonces with JS +middleware, but this doesn't work with CaddyServer. I would much rather Sapper [avoid inline scripts][sapper-gh] altogether, but this doesn't seem likely. I really like the +freedom that writing static sites in Svelte provides me versus other static site generators, but this could be a dealbreaker. I might talk a look at [Routify][routify] and see +if that's any better. I've also been reconsidering using TailwindCSS, however useful it is, after reading [these][etcd] [three][library-overuse] [articles][tailwind]. I +attempted to replicate the current look of [][figbert] without TailwindCSS, and failed. So I'm probably going to rewrite the site again, though I'm not sure how. +Through iteration, we will arrive at a stable version – this one, unfortunately, is not yet it. If I do leave Svelte, which is probably a 50/50 chance at this point, I would +probably go either back to [Hugo][hugo] (with some variation of the incredible [archie][archie] theme) or to [Zola][zola]. + +## Real World Updates + +### CyberSec + +So, some pretty crazy things have happened. For one, [Twitter got hacked][twitter] by some people from [OGUsers][ogusers] who got access to some internal managment tools. This +hack, though not necessarily the most technical hack, was super high profile. There were a few [really good articles][more-money] written about the hack, but I also noticed a +few people acting in ways that I thought were not appropriate. More specifically, [Biran Krebs][krebson], who reacted to the hack be [repeatedly][dox-one] [doxxing][dox-two] the +hackers, many of whom are still teenagers. He's received relatively little [criticism][dox-callout] for doing this, though it appears to be [a pattern of behavior][dox-past]. + +There was also a brief mention of a new [macOS malware][mac-malware], but judging by the lack of further publicity it's probably not that common in the wild. That, or people +don't care because it's spread mainly through torrenting sites and they don't want to protect people they perceived to be morally below them – which is wrong, obviously. + +### Driving + +I learned how to drive! Or rather, I got kind-of licensed to drive a car in the US. I've been driving around a lot lately as something fun I can do to pass time in quarantine, +and last week I finished my online driver's ed course and got my learner's permit. It was a surprisingly simple and COVID-friendly process! The most complicated/least +COVID-friendly part was going to the DMV to take the written test, but I wore a mask and gloves and glared at anybody who got remotely close to me. The next steps are much more +dangerous to do during a pandemic, but we have a year to complete them so we're going to delay them (some in-person driver's training and the driver's test) for a bit. For now +though, I have a piece of paper that says I can learn to drive! + +### Better Platforms + +I've also taken some time to focus on decentralization. I've had a [Mastodon account][mastodon] for a while, but I rarely used it. I didn't have a mobile client, and I almost +never use social media on my computers. To help change my behaviour I downloaded [Mast][mast], a paid Mastodon client for the Apple ecosystem. I went with Mast mostly because +it's absolutely *gorgeous* – and [open source][mast-src] – which is something I value in the apps I use. Apps that look really nice are fantastic inspiration for my own apps' +designs, and this one is no exception. + +I've also started using three other apps much more heavily recently: [Feedly][feedly], [Octal][octal], and [Element][element]. Feedly is a fantastic RSS reader, which helps me +keep track of all the interesting blogs that I find online (I read somewhere about self-hosting an RSS reader, which sounds pretty cool, but I forget what it was called). Octal +is a HN client for iOS, which is really handy for keeping up with my favorite tech news when I'm away from my computer. Element (previously Riot), is the first-party +[Matrix][matrix] client that makes using a decentralized E2EE chat service feel better than Discord. I love it. In an ideal world where I could choose the tools I use to +communicate with people, I would only use Signal and Element/Matrix (for replacing iMessage and Discord/Slack, respectively). + +### Music + +Oh my god there's so much new music. +* [Jonny by Bar Tsabari]( +* [Kukuriku by Eden Ben Zaken and Omer Adam]( +* [Ta'azri et Atzmech by Dekel Vaknin]( +* [Sivuvim by Eden Hason]( +* [Lecha Dodi by Moshe Peretz and others]( +* [Haravot BaPita (Album) by Peled]( +* [Magevet BaAvir by Noroz]( +* [Nadav\_15 by Shekel]( +* [Moshe by Narkis and Miri Mesikah]( +* [Tik Tok by Mohamed Ramadan and Super Sako]( +* [Aliyato VeNiflato Shel Shem Tov Hevi by Tamir Bar]( +* [Falafel Pop (Album) by Quarter to Africa]( +* [Lama Kacha Atzuva by Idan Raichel and Stav Beger]( +* [Kapara by Kevin Robin and Rotem Cohen]( +* [Ehad HaAm by Aya Zahavi Fayglin]( + +## Wrapup + +I hope you enjoyed reading this update! I know it's much longer than usual, and I'll try and keep them shorter than this from now on. I plan on uploaded more short, +topic-focused articles rather than just updates, but those will come soon. For now though, I need to focus on knocking out some of the larger projects that I'm working on. I +keep finding cool and interesting things to do, and I need to work on finishing the ones that I've already started! + +Salamat, FIGBERT + +[if-collection]: collection.png +[inform]: +[angry-wizard]: /content/One%20Angry%20Wizard%2C%20or%20the%20Tentac.gblorb +[email]: +[geekring]: +[geekring-hn]: +[hotline-webring]: +[bfg]: +[netlify]: +[helmet]: +[sapper-csp]: +[netlify-headers]: +[digitalocean]: +[caddy]: +[student-pack]: +[cloudflare]: +[goatcounter]: +[goaccess]: +[goaccess-gh]: +[goaccess-script]: +[plausible]: +[gitea]: +[figbert]: +[flavio-docker]: +[sapper-gh]: +[routify]: +[etcd]: +[library-overuse]: +[tailwind]: +[hugo]: +[archie]: +[zola]: +[twitter]: +[ogusers]: +[more-money]: +[krebson]: +[dox-one]: +[dox-two]: +[dox-callout]: +[dox-past]: +[mac-malware]: +[mastodon]: +[mast]: +[mast-src]: +[feedly]: +[octal]: +[element]: +[matrix]: + diff --git a/content/posts/i-wrote-this-two/doughnut.mp4 b/content/posts/i-wrote-this-two/doughnut.mp4 Binary files differ. diff --git a/content/posts/i-wrote-this-two/doughnut.webm b/content/posts/i-wrote-this-two/doughnut.webm Binary files differ. diff --git a/content/posts/i-wrote-this-two/ b/content/posts/i-wrote-this-two/ @@ -0,0 +1,140 @@ ++++ +title = "I Wrote This #2" +description = "Hi! So, I just started this series and I already missed a week. Oh well. This week was a crazy week for Apple and their operating systems, as they announced iOS 14 and macOS 11 Big Sur at this year's WWDC. I've also started working on a new game project, another little side project, and finding a good alternative to Keybase now that it's owned by Zoom." +date = 2020-06-27 +updated = 2020-08-14 ++++ + +Hi! So, I just started this series and I already missed a week. Oh well. This week was a crazy week for Apple and their operating systems, as they announced iOS 14 and macOS 11 +Big Sur at this year's [WWDC][7]. I've also started working on a new game project, another little side project, and finding a good alternative to [Keybase][31] now that it's +[owned by Zoom][20]. + +<!-- more --> + +## Jailbreaking my iPhone + +When I was a kid – or at least, a younger child than I am now – I had a friend who jailbroke his phone. I thought it was super cool, and wanted to do the same. At around the +same time I was watching [TechSource][1], I got deep into those [Top 10 Amazing Jailbreak Tweaks][2] compilations. However, I wasn't allowed to jailbreak my phone because my +parents said it wasn't allowed, and that was the end of that. + +Until last week, when I decided to jailbreak my iPhone 7 running iOS 13.5.1 using the [checkra1n][3] hardware exploit. To do this, I couldn't use my [USB-C to Lightning +cable][4] due to [a known issue][5] and instead swapped to a USB-A to Lightning cable with a USB-A to USB-C adapter. After jailbreaking the phone, I began to install a host of +tweaks. One of the most interesting things I learned about the jailbreaking community is that charging upfront for apps is quite common for premium and well-known tweaks, which +stands in high contrast to the iOS App Store's ubiquitous freemium payment model (a free download followed by a monthly subscription) especially in the light of the +[ controversy][6] of recent weeks. + +All in all, I spent around USD$21 on tweaks, which is infinitely more than I have spent on the App Store – so maybe charging upfront does work. Huh. + +<video autoplay loop muted playsinline> + <source src="jailbreak.webm" type="video/webm"> + <source src="jailbreak.mp4" type="video/mp4"> +</video> + +## Updating my iDevices to Developer Betas + +Soon after completing the jailbreak, [WWDC][7] happened and new developer betas were released. Never one to miss jumping on a hype train, I updated both of my main devices to +the [new software][8]. These new betas come with a whole host of bugs, as is to be expected, which I plan to write about in a blog post coming soon. So far, however, I'm liking +these updates – the PiP on iOS is *incredible*, and the new design on macOS is growing on me. + +Some interesting resources: +* [An interview of Craig Federighi by MKBHD][9] +* [These][12] [three][13] [issues][14] on GitLab for iTerm2 users +* [These][15] [two][16] posts for Firefox +* [This Github issue][17] for Homebrew users. ~~so basically everybody.~~ + +Interestingly, I was having a bunch of issues with brew (`curl` was broken?) after updating to Big Sur but now it seems to be working flawlessly. Very nice. + +## Making a Doughnut in Blender + +For my next medium-large project, I'm going to need to make some 3D art and models. One problem: I don't know how to do that, or rather, I didn't. Thanks internet! I powered +through the incredible [Blender Beginner Tutorial Series][18] by the [Blender Guru][19]. Here's my final animation: + +<video autoplay loop muted playsinline> + <source src="doughnut.webm" type="video/webm"> + <source src="doughnut.mp4" type="video/mp4"> +</video> + +## Replacing Keybase + +Now that [Keybase is compromised][20], I thought it would be good to seek out an alternative. Initially, I thought that []( would be perfect – I thought +it was a slightly-tweaked fork. However, this does not appear to be the case. Instead, it seems kinda like garbo – it doesn't have the budget Keybase had, and as a result, is +majorly lacking in features. However, I've replaced it completely, and am happier with this setup than I ever was with Keybase. My new setup uses [Matrix][21] and +[Riot][22] for messaging, [Jitsi][23] for video chat, [Syncthing][24] for file storage, and an [Indieweb][25] h-card for identity verification. I plan on writing more about this +at a later date, but I'm really pleased with the results so far. + +## Future Projects + +I've got a few interesting projects in the pipeline at the moment, not counting the few articles that I've already promised to write: *Glitches in macOS Big Sur and How to Fix +Them* and *How to Replace Keybase in 4 Easy Steps*. My next major project is a dreidel game/simulator for mobile devices – I plan to code it with [Godot][26], make the models +with [Blender][27], and do any music/sound stuff in [FLStudio][28]. Naturally, I'll keep you all updated on any progress there. + +I'm also working on a much smaller project that should take around a day or two to complete. The working title is "" – essentially, it's a website that takes +the size of the State of Israel, and compares it to the size of a given location and tells you how many times Israel could fit inside it. All I need to do is find a suitable +mapping API (preferably not by Google) that will tell me the size of different locations and I can whip it into a static site! + +I'm also planning on revamping the txtodo macOS app with Mac Catalyst, which I feel I haven't properly explored. I've also discovered a bug in the app that causes issues when +tasks are modified by CloudKit instead of the user, so I'm going to have to work on that as well. Shouldn't be hard! + +![Let's go. In and out. Twenty-minute adventure.][29] + +## Interesting Blog Tidbits + +I'm not sure what tense to write my headers in – I currently write them in [present continuous][30] tense but I am considering writing them like I do Git commits. Huh. I'm also +committing to writing more non-update blog posts (i.e. the two I mentioned above), but we'll see how that goes. Writing is hard, and you shouldn't make false promises. +I'm also working on implementing webmentions to the site, which is a little difficult with a static site but I'm going to give it a try. Lastly, I really need to learn how to +use vim but it's so goddamn hard. I'm writing this blog post with it but I'm definitely not using it to its full potential at all. + +## New Music + +Wow, these have been a great two weeks for the Israeli music scene. In no particular order, here are some good new songs (basically in the order they appear on the trending +tab): + +* [Habib Albi – Static and Ben El]( +* [Rak Banot – Itay Levi and Stephane Legar]( +* [Shvuaim – Eden Hason]( +* [Yom Huledet – Eliad]( +* [Hatzi Madleket – Dudu Faruk]( +* [Hayde – Peled]( +* [Ze Mi She Ani – Peled]( + +I know music isn't tech, but I like it and now it's a recurring section. + +## Wrapup + +So, that's been this week's update. I'm really enjoying writing updates on this blog, and I hope you stick around. Until then, farewell! + +-- +FIGBERT + +[1]: +[2]: +[3]: +[4]: +[5]: +[6]: +[7]: +[8]: +[9]: +[10]: +[11]: +[12]: +[13]: +[14]: +[15]: +[16]: +[17]: +[18]: +[19]: +[20]: +[21]: +[22]: +[23]: +[24]: +[25]: +[26]: +[27]: +[28]: +[29]: rick-and-morty.jpg +[30]: +[31]: + diff --git a/content/posts/i-wrote-this-two/jailbreak.mp4 b/content/posts/i-wrote-this-two/jailbreak.mp4 Binary files differ. diff --git a/content/posts/i-wrote-this-two/jailbreak.webm b/content/posts/i-wrote-this-two/jailbreak.webm Binary files differ. diff --git a/content/posts/i-wrote-this-two/rick-and-morty.jpg b/content/posts/i-wrote-this-two/rick-and-morty.jpg Binary files differ. diff --git a/content/posts/ b/content/posts/ @@ -0,0 +1,11 @@ ++++ +title = "Keybase Has an Onion Address" +description = "Little known fact about Keybase: it has two onion addresses." +date = 2020-07-03 ++++ + +Little known fact about [Keybase]( it has two onion addresses. The short [fncuwbiisyh6ak3i.onion](http://fncuwbiisyh6ak3i.onion/), and the longer +[keybase5wmilwokqirssclfnsqrjdsi7jdir5wy7y7iu3tanwmtp6oid.onion](http://keybase5wmilwokqirssclfnsqrjdsi7jdir5wy7y7iu3tanwmtp6oid.onion). Huh. + +<!-- more --> + diff --git a/content/posts/pebkac-txtodo-rewrite/ascending-checkmarks-error.webm b/content/posts/pebkac-txtodo-rewrite/ascending-checkmarks-error.webm Binary files differ. diff --git a/content/posts/pebkac-txtodo-rewrite/ b/content/posts/pebkac-txtodo-rewrite/ @@ -0,0 +1,122 @@ ++++ +title = "Problem Exists Between Keyboard and Chair: How I Spent 2 Days Chasing a Bug that Didn't Exist" +description = "Post-WWDC2020, I decided to rewrite the backend of txtodo in SwiftUI using the new App and Scene structure. Rebuilding the app from scratch may have not been the best choice, but during that process I have massively simplified the app's data structure, despaghettified some messy UI code, and spent two full days trying to solve a problem that didn't exist. This is the story of that last bit." +date = 2020-07-28 ++++ + +Post-[WWDC2020][wwdc], I decided to rewrite the backend of txtodo in SwiftUI using the new [App and Scene structure][app-and-scene]. Rebuilding the app from scratch may have not +been the best choice, but during that process I have massively simplified the app's data structure, despaghettified some messy UI code, and spent two full days trying to solve a +problem that didn't exist. This is the story of that last bit. + +<!-- more --> + +## Structural Changes + +The new app, so far, was mostly the same as the old version but without the `AppDelegate.swift` or `SceneDelegate.swift` files (using the new XCode 12 multiplatform app +template). I also combined the Core Data `FloatingTask` and `DailyTask` entities into one `Task` entity. By this point, everything was running well enough so I started to +migrate more code into the new codebase starting with the fetch request: + +```swift +@FetchRequest( + entity: Task.entity(), + sortDescriptors: [ + NSSortDescriptor(keyPath: \Task.completed, ascending: true), + NSSortDescriptor(keyPath: \Task.priority, ascending: false), + NSSortDescriptor(keyPath: \, ascending: true) + ] +) var tasks: FetchedResults<Task> +``` + +## Breaking TaskView + +Tasks are displayed as `TaskView`s in a `ForEach` loop on the homescreen, which is simple enough. The `TaskView` struct, however, is relatively complicated. The purpose of +`TaskView` is to represent and manipulate a single `Task`. In the previous version of the app (I'm going to call the original version 2.0 and the rewrite 3.0 from now on), this +involved passing a number of attributes individually to be manipulated as the view's `@State`. When migrating the view, I reduced this to a single `@ObservedObject`. I also +removed some of the text styling, which I planned to port over after I got the UI functional. + +I ran the app on my device, and this happened: + +![As you check off any task in the vertical stack, instead of checking off the task that you selected, tasks are checked off starting from the bottom and moving upwards in an +ascending order.][ascending-checkmarks-error] + +Well that was unexpected. Instead of checking off the tasks I selected, tasks were checked off starting from the bottom and ascending – obviously not the intended behavior! My +first thought was that it was caused by the use of `@ObservedObject` to declare the view's task property – I haven't seen it used to manipulate a Core Data entity before, but +it's worked fine so far in txtodo – so I rewrote the variables to match version 2.0. + +![The variables declared before the UI of version 3.0 and version 2.0. Version 3.0 has two variables, task and config, but version 2.0 has nine: task, completed, name, priority, +deleted, editingText, editingPriority, viewingNotes, and confirmingDelete.][contrasting-variables] + +Still no change. It was getting pretty late at this point, but I decided to stick it out for just a bit longer. I rewrote the `TaskView` struct from scratch *two more times* to +no avail. Something was wrong, but I had no idea where it was and there was no way I was going to figure it out at two in the morning by coding it again the exact same way. + +## Fantastic Bugs and Where to Find Them + +The next morning, I took a look at the code again. If the problem wasn't in `TaskView`, where was it? The only other thing in the UI was the button to make a new task, which +looked something like this: + +```swift +Button(action: { + let newTask = Task(context: self.managedObjectContext) + = "test" + newTask.priority = 3 + newTask.notes = [String]() as NSObject + = UUID() + = Date.init() + newTask.daily = true + do { + try + } catch { + print(error.localizedDescription) + } +}) { + Text("Add") +} +``` + +Some of you may have figured it out by this point. At the time, I was still confused – this was the exact method I was using in my previous app, but with preset values – how +could it be broken? I modified the generation slightly so I could tell the difference between tasks, and hopefully get to the bottom of the issue: + +```swift +let newTask = Task(context: self.managedObjectContext) = String(UUID().uuidString.prefix(Int.random(in: 5..<9))) +newTask.priority = Int16.random(in: 1..<4) +newTask.notes = [String]() as NSObject = UUID() = Date.init() +newTask.daily = Bool.random() +``` + +I ran the app again and saw this: + +![The tasks were not being marked off in ascending order – rather, they were being moved to the bottom when completed, which I couldn't tell before because they were all +identical.][the-big-reveal] + +## Intentional Behavior + +The tasks weren't being marked off in ascending order. They were being moved to the bottom automatically when marked as complete, which I couldn't see because a) all the tasks +were identical and b) there were no animations to indicate that was happening. They were sorted by the `FetchRequest` with a `NSSortDescriptor`, to make sure that the unfinished +tasks are the first thing the user sees. The "glitch" I had spent two days chasing down was entirely by design, and I had just forgotten. + +There were two main things I learned from this experience. First, it's incredibly important to be able to take breaks. The difference between spending two days trying to fix a +non-existent glitch and realizing it's a feature you implemented could be as simple as a nap – it was for me. Secondly, your test and placeholder data is more significant than +you might think: [garbage in, garbage out][GIGO] definitely applies here. If all your test data is the same, your tests are not good tests. + +## Wrap-up + +To make the sorting more clear, I randomized the tasks' priority, name, and category (as seen above) and added an animation with `.animation(.easeIn(duration: 0.25))`. The +current prototype looks something like this: + +![Animated, randomized tasks being checked off, deleted, and delayed.][current-txtodo] + +This has been a really fun blog post to write! A got a big laugh out of this bug chase, and I hope you've enjoyed reading it. + +Till next time, FIGBERT + +[wwdc]: +[app-and-scene]: +[ascending-checkmarks-error]: ascending-checkmarks-error.webm +[contrasting-variables]: variable-comparison.webp +[the-big-reveal]: randomized-test-values.webm +[current-txtodo]: update-preview.webm +[GIGO]: + diff --git a/content/posts/pebkac-txtodo-rewrite/randomized-test-values.webm b/content/posts/pebkac-txtodo-rewrite/randomized-test-values.webm Binary files differ. diff --git a/content/posts/pebkac-txtodo-rewrite/update-preview.webm b/content/posts/pebkac-txtodo-rewrite/update-preview.webm Binary files differ. diff --git a/content/posts/pebkac-txtodo-rewrite/variable-comparison.webp b/content/posts/pebkac-txtodo-rewrite/variable-comparison.webp Binary files differ. diff --git a/content/projects/ b/content/projects/ @@ -0,0 +1,8 @@ ++++ +title = "Projects" +description = "" +sort_by = "weight" +paginate_by = 20 +insert_anchor_links = "left" ++++ + diff --git a/content/projects/txtodo/core-data-structs.png b/content/projects/txtodo/core-data-structs.png Binary files differ. diff --git a/content/projects/txtodo/ b/content/projects/txtodo/ @@ -0,0 +1,80 @@ ++++ +title = "txtodo" +description = "" +date = 2020-05-20 +weight = 0 ++++ + +[**txtodo**][txtodo] is a minimalist open-source todo list app inspired by Jeff Huang's [*One File to Rule Them All*][one-file-to-rule-them-all]. It lists your immediate, +short-term tasks to help you get things done without overthinking it. With txtodo, you list all your tasks for the day in the morning, and throughout the day you check off tasks +as you complete them. Then, at midnight, all tasks are discarded so you can start fresh tomorrow – you can also create up to three long-term tasks that "float" with you from +day-to-day. Did I mention that it's completely open-source and built with SwiftUI? You can download txtodo from the app store [here][txtodo-store] and view the source code +[here][txtodo-src] + +## Mobile App +### Story +On 15 February 2020, I found myself staring at [a blank Xcode project][empty-project]. Minutes earlier, I had deleted my account with [Trello][trello]. For those not familiar +with Trello, it's a [kanban-style][kanban] productivity tool made by [Atlassian][atlassian] to keep track of tasks in a project with multiple engineers. I, however, am a solo +devloper. I already know what features need work, which graphics need a refresh, and what languages aren't yet supported – because I'm working actively on everything. Keeping +track of every little move in a PMS for a solo project quickly turned Trello from productivity software to [crudware][crud] with fancy graphics. I wanted an app that could +[trick the instant gratification monkey][ted-talk] into getting something done. Something free from the [creeping featurism][featurism] in todo apps. I decided to build a simple +app to do just that. + +And so, I found myself staring at the aforementioned blank Xcode project. I decided to learn and use the new [SwiftUI][swiftui] framework to make use of the latest features in +iOS development. I began coding. **txtodo** is built from the ground up to fix the problems I've found with modern task managers – something straightforward and easy-to-use, +that helps you get things done instead of getting bogged down making lists. I did this by creating a dead-simple UX with an important key feature: tasks you create disappear at +midnight. This prevents the overwhelming buildup of tasks we delay, and trains you to be highly productive – dealing only with tasks you can get done *that day*. + +I've personally found this to be very useful, especially in the COVID-19 quarantine/shelter-in-place. Even when days melt together, txtodo has helped me maintain productivity: +pushing me to finish schoolwork, code everyday, and keep developing new projects. + +### Code +txtodo is programmed 100% in Swift, with no third-party dependencies. It's also written with the most recent frameworks, [SwiftUI][swiftui] and [Combine][combine] (though as +SwiftUI is still new, I did have to write some wrappers from UIKit). The tasks are stored using the two core data models below: + +![core data models][core-data-models] + +Once a task is initialized, it's stored in an `NSPersistentCloudKitContainer` until its deleted, and displayed on the homescreen by a `ForEach` loop iterating over a +`FetchRequest`. (For more on Core Data and SwiftUI, I would point you to [this excellent tutorial][core-data-tutorial].) This `ForEach` loop is the only place where we can +control all the tasks in the list at once, and so it's here that we manage the tasks. Once we initialize each task's view, we add an `onAppear()` modifier to check if the task +should be deleted. If we're modifying a `dailyTaskView`, we check if the task's `creationDate` is equal to the day's date – if the dates match the task is displayed, and if they +don't the task is deleted from storage. If we're modifying a `floatingTaskView`, the process is a little more complicated. The task should only be deleted if it is completed and +the completion is a day or more old. This process looks something like this: + +![task deletion modifiers][task-deletion-modifiers] + +Another interesting thing about SwiftUI: the order of certain view modifiers affects the behavior of the view they're modifying. This is particularly apparent when dealing with +different combination of tap gestures. In my case, I want my task views to have single-tap, double-tap, and long press interactions. To get these interactions to work together +without conflicting, they have to be ordered like so: + +![order of tap modifiers][ordering-modifiers] + +I plan on writing more about that in a blog post about the quirks and bugs of SwiftUI. + +## # Website +The txtodo website, [][txtodo], is programmed with [Svelte][svelte] – not [Sapper][sapper], it's a single static page and doesn't need all that extra overhead – and +[TailwindCSS][tailwind]. The combination of these two frameworks has become my all time favorite – together, they give the comforting feeling of programming in pure HTML+JS+CSS, +with the ease and enhaced capability of the most modern competing frameworks. You can [view the code for the site here][site-src]. + +[txtodo]: +[one-file-to-rule-them-all]: +[txtodo-store]: +[txtodo-src]: +[empty-project]: +[trello]: +[kanban]: +[atlassian]: +[crud]: +[ted-talk]: +[featurism]: +[swiftui]: +[combine]: +[core-data-models]: core-data-structs.png +[core-data-tutorial]: +[task-deletion-modifiers]: manage-task-deletion.png +[ordering-modifiers]: tap-modifiers-order.png +[svelte]: +[sapper]: +[tailwind]: +[site-src]: + diff --git a/content/projects/txtodo/manage-task-deletion.png b/content/projects/txtodo/manage-task-deletion.png Binary files differ. diff --git a/content/projects/txtodo/tap-modifiers-order.png b/content/projects/txtodo/tap-modifiers-order.png Binary files differ.