Shrugs.app, A Long Journey
How did Shrugs.app happen? Almost two years ago (Aug 2018) the Interwebs held their recurring discussion of the gigantanormous amounts of resources the Slack Electron app consumed. Jigawatts of memory for a simple chat client, the GPU always spinning.
Going forwards to 2020, the memory requirements of the Slack.app are way more tolerable. An amazing job has been done to optimize that.
And once you’ve written a Slack client, you also figured out that Slack is nothing but a simple chat client, it is a complex and feature rich application.
Long story, but in large print with many pictures. I’m not a skilled writer, but thought that some background information might be interesting to some 😬
In spring the company I was consulting for had been acquired, my services not required anymore. Some blogging and coding happened: WebObjects, in Swift, a Swift NIO IRC implementation, a Redis one and then …
… as an Internet protocols fan (you’ll find my name on RFC’s like CalDAV), the question came up: What protocol does Slack even use? XMPP? Enhanced IRC? Something own? What would it take to connect to Slack?
Apart from a weak IRC gateway that eventually got killed, it unfortunately didn’t (and still doesn’t) use any standard protocols. However, it turned out that Slack quite likely has one of the world’s best documented JSON based HTTP API’s: https://api.slack.com. And part of the official API are user tokens, a.k.a. tokens to act on behalf of the user.
And there we go, Aug 16th 2018:
It was just a WKWebView frame for doing the OAuth authentication flow to acquire a login token:
End of August the authentication flow worked really well. Including the API token gateway, a small SwiftNIO (MicroExpress) server running in the cloud. This server component is required to avoid having to embed the Slack API credentials in the app (from which they would be easy to extract).
At the same time the invitation to speak at the Server Side Swift Conference arrived, it was a lot of fun:
It features a demo of my Noze.io SwiftNIO IRC setup, with an IRC bot controlling gadgets connected to the Raspberry Pi’s GPIO.
The Sprint to v0.1
Back at home the most important thing had to be done: an app icon. How? Well, by watching this PaintCode tutorial on how to create a message bubble icon. Despite zero design skills, PaintCode still yields something reasonable:
And a name emerged from nothing (probably under the 🚿):
Slick for Slack
Still love the name, but ended up dropping it for two reasons:
- The app is still not slick enough to reasonably call itself Slick.
- Changing just a letter sounds like a recipe to get sued. I don’t want that 😬
At this time there weren’t any real plans to make it an app proper,
it was just toying around with what-is-possible.
Looking at the
git log, I was working on it every day, for a month straight,
and on Oct 16th I committed
A first Slack channel live query … we are getting somewhere!
Dec 31st, 597 commits later, I finally tagged version
Having worked three months just on this, oops!
Working timeline, message rows supporting complex setups like Slack “attachments”, ability to post message.
The app wasn’t written fully from scratch, but using existing base frameworks for AppKit/UIKit I’ve been working on since 2015 (UXKit, Core/S and SeeCore). Those include a quite extensive account management framework, done in part for home automation applications I was(/am) working on (e.g. HMScriptEditor).
Beginning of 2019 - Going Indie
As the years changed the decision had to be made whether to continue spending money towards Slick, essentially angel investing into myself, or whether to find another paid project. I didn’t have any good leads for the latter, hence I decided to do the former - v0.1.0 looked quite promising.
Goal: Release the application in May 2019.
Complete Business Plan: About 10m active Slack users, still growing. Maybe 10% Mac users. 10% of those might want something better than “good enough”.
Makes the target market 1% of the Slack users: ~100k users, growing (now you know why Slack itself doesn’t bother writing a native client).
Technology applicable to other chat platforms.
Lots of things still had to be done: read markers, support for reactions, Emoji, files and pictures, message threads, etc etc. As mentioned before: Once you start implementing a Slack client, you start to appreciate how extensive and complex the application actually is.
Notably lower resource consumption was never planned as a key feature of the
A few “native” clients with low resource consumption have been flying around
already, e.g. Ripcord.
They didn’t feel appealing - none was really native in the sense of
using the macOS GUI framework AppKit.
The “slick” thing (the main USP) planned for the app was deep macOS integration. HIG conforming UI, multiple windows, popovers, tableview row actions, drag&drop, services, continuity …
End of 2018 I had also started teasing a few people and managed to find ~20 alpha testers. Thanks to all of you for taking the time! On January 31st the first ɑ test version got released, straight feedback (translated):
Inline GIFs work already? The app is essentially finished :O”
Looking at the amount of commits I don’t remember how I found the time to blog as well, but I also finished up my series about the Swift 5 @dynamicCallable feature: Unix Tools as Swift Functions, Swift/ObjC Bridge and Mustacheable.
Working, more features, getting somewhere.
Turns out the Slack team isn’t exactly lazy either, mid-February they
release the Block Kit.
A new way to format and send styled messages,
with more interactive elements.
Oops. More work for me 🤓 (did I mention that Slack is not a simple chat client already?). March 1st:
Message grouping by day, Emoji picker supporting custom Slack Emoji (including animated), channel/user/Emoji auto completion in NSTextField, reactions, quicklook, copy&paste, drag&drop, threading … April 1st already, time for a v0.1.1:
Thread popovers, online/offline mode, deal with network changes, darkmode, detect awake/sleep, port to Swift 5, drop those nasty NSStackView’s, panel for complex messages (w/ image uploads), Emoji aliases … May 1st.
Load faults, first optimizations, prefetching, improve scrolling, /shrug support for threads, scrollwheel bugs, proper rate limiting, fix this, fix that, another fix, one more bug, … May 31st.
The old plan: Release the app in May 2019.
At this point it was clear that this wouldn’t happen. The app - now code-named Marzipan for reasons - had been gaining features and worked quite well. Using it in various Slack workspaces for months already. In a way pretty close, but then maybe not. I didn’t think it was release quality yet 😒
What I had hit was the old 90/10 development rule, the last 10% take 90% of the time. It looked like a massive amount of work still had to be done.
Needed a major break from the client after coding just that for months. Work on Slick essentially stopped end of May 2019.
WWDC 2019 - The Yearly Distraction
Thankfully WWDC started beginning of June. An arguably well spend, yearly, distraction. And this year Apple released something completely new: SwiftUI.
Started watching the sessions on Monday, and by Wednesday the thinking was: This is WebObjects, but for the desktop. We need that for the Web too! And I ended up “wasting” about two weeks writing The missing ☑️: SwiftWebUI, and then SwiftUI Rules, and then Direct to SwiftUI. The summer was lost to SwiftUI.
In a somewhat weird move (considering SwiftUI), Apple also released project Marzipan - now called Catalyst. A way to port iPhone/iPad apps to the Mac.
Do the Mac a favor by not using that. The temptation may be high, don’t.
Some time was spend in July to add navigation and window restoration to Slick, but the motivation to work on it was at an all time low.
Change of Focus
As an investor I couldn’t allow my investee to go on like that. Being stuck with regards to the Slack client development, the plan was to do something easier for self motivation.
REAL ARISTS SHIP.
An original goal for ZeeZide was to develop home automation apps for the Mac and iOS, PoC’s were available already. Equipped with way more AppKit knowledge HMScriptEditor came to light in about 3 weeks. A small editor for the HomeMatic “Rega” script language:
Available on the Mac AppStore, selling for the price of a fancy coffee. Estimated target audience: 10 people (I’m proud to report that the sales are on track with 7 licenses sold 😃).
Code was flowing again …
On a Tuesday in late October someone on the SwiftDE Slack asked for a simple project to get back into iOS programming. My suggestion was to write a small frontend for the SwiftPM Library (to search for Swift packages). A minute later I had the urge to do the same, but for the Mac.
At the end of the same week SwiftPM Catalog got released, essentially an “AppStore” for discovering Swift packages.
That was going really well, two nice apps from idea to release in little time. Checking iTunes Connect for sales, I also noticed that CodeCows and ASCII Cows have been quite popular for what they are (~9k downloads!).
Self motivation: ✅
Reboot Slick Development
Half a year after dropping work on Slick for Slack, I had another look end of November. The situation was still the same:
- Using it myself every day in about 15 Slacks for almost a year now, and it is working just fine for me.
- It was still in a 90/10 shape, plenty of things worked, but there was still a lot to be done.
Time to reconsider the scope. Given that I used it everyday just fine, what had actually to be done to make it a viable release?
The number one - and more importantly, pretty much sole - feature request from testers was support for direct messages. The design was envisioned long ago, they should be shown in a separate “roster” window similar to Messages.app. Problem: That was going to take quite a while to implement. Instead I decided to make them appear as channels in the main window for this iteration.
The other thing which made me very unhappy was the state of the “complex editor”, the thing used when an image or a file is sent. It was a simple view overlay and very un-Mac-y. I really wanted to have a smaller version of the Mail.app compose window.
But apart from that, what had to be done was: primarily bug fixes, an update mechanism and all the things to actually sell it, i.e. a store, the website etc.
- 1 month for finishing up direct messages
- 1 month for doing the compose panel
- 1 month for software updates and the store
- 1 month for bug fixing
- 1 month for preparing the release
I didn’t expect to get much done in December/January for other reasons, but the new timeline was set - (Dec/Jan)/Feb/Mar/Apr/May:
New Goal: Release the application in May 2020.
2020 - The year of the release
Not blogged a toy project from January till May(*), good sign that work is in full swing and proper German discipline is in place.
Now doing a release to the excellent testers every one or two weeks. Feb 4th, Feb 17th, Feb 24th, Feb 27th, and we have DM’s starting to work quite reliably:
March 3rd comes with something dear to my heart, syntax highlighting in ```:
On March 13th a strong indicator that Slack is still growing a lot, excellent!
The IDs returned by our APIs have grown longer. They are now up to 11 characters long, and could grow longer in the future.— Slack Platform (@SlackAPI) March 13, 2020
Please audit your Slack apps, and verify any assumptions about the length of IDs for users, channels, and other objects. #changelog
March 14th, adjustments for that, ids fortunately still fit into 64-bit. Bug fixes, more of those fixes, some optimizations.
March 31st, update mechanism thanks to Sparkle:
So this is going well. Direct messages are in, the Sparkle updater is in, two more months to go. Also the important “leave conversation” works, even though there is (still) no way to join one 😬
April 23rd, the new
NSTextView based “complex” editor lands.
Supports image and file drops, very basic markdown syntax highlighting,
and most importantly the macOS “image markup” feature:
Really like it. Also bug fixes, bug fixes and more of them.
End of April Slack introduced a redesign featuring a toolbar. Due to the toolbar-less setup Slick was missing some macOS look&feel, a proper chance to fix that as well. The April 27th/28th release:
Much better, similar to Mail.app (stay tuned for the search field …). The available functionality seemed sufficiently polished, and reasonable for a first release.
The Product and the Store
About to enter May. The main thing still missing is a way to actually sell the application, a.k.a. a store. Go into the Mac App Store? Use something else? Having purchased Make Money Outside the Mac App Store months ago, I took the time to actually read through it. It convinced me to give the FastSpring store a chance, May 7th:
FastSpring could have a better API for building a real native store, but it is quite reasonable (I may be opensourcing the store sheet shown). Hope this is going to work well.
As part of this effort I also had to do pricing, which ain’t no easy thing. It is a pretty complex application that took a lot of work and deserves a proper price. On the other hand, it still lacks a lot of functionality from an application I would pay for, say €79. Hence my decision to go rather cheap with €19.99.
Since there might be a few people who’d like to support this effort by paying some extra, I came up with the “what-a-great-effort version” at €49.99. That purchase is entirely optional and not required to get Shrugs.app. To provide something in return, those licenses give access to the Shrugs beta program.
Another decision I made is to let potential customers test Shrugs.app for free prior doing a purchase. This is particularily important, because depending on the Slack workspace settings and the authentication mechanism used, Shrugs may not be able to log into Slack (e.g. because the workspace administrator has blocked that). Try before you buy!
The store is available directly via zeezide.onfastspring.com, in case you don’t care and want to send money regardless! 😉
The Final Name
The original name was “Slick for Slack”, which did sound like a great name but not like a great idea. Later I changed it to “Marzipan”, which is still used for the beta versions.
The release required a better name.
Ideally something with a free
Pulled up a dictionary and made a list:
For quite some time I thought it was going to be “Soy” (because it combines well, with like Sushi or sauce, and has icon potential). Unfortunately relevant domains were taken already.
The dictionary however suggested
A fun reference to the
/shrug Slack command,
and it even comes with Emoji 🤷♀️!
In case you didn’t know: Entering
/shrug I don't carein Slack, results in the fancy
I don't care ¯\_(ツ)_/¯.
(Nerdnote: since threads do not support slash commands, it’s hardcoded!)
dig shrug.app said that this was taken as well.
So what is better than a “shrug”?
Many shrugs of course!
Since you made it that far in this longish text, a small easter egg is well deserved. The string used by the
/shrugcommand can be configured using the
SlackShrugStringuser default. E.g. you could set it to a shrug Emoji, like 🤷♀️.
The Release of Shrugs.app
After a few more bug fixes, on May 18th the Shrugs.app release candidate 1 got branched. No more touching the code, unless absolutely necessary.
The next two weeks was doing screenshots, making videos, writing website content, coming up with a press release.
May 25th: Tagged 1.0.0
It looks like a decent release. It doesn’t do everything (in fact it still lacks a lot of features), like any software it still has bugs, but it is the thing I’m using for over a year now, and I think you might like it as well - I very much hope so!
If you are reading this, it is May 27th, and I finally managed to
Slick for Slack the Shrugs.app
to the general public: download
I have to admit that I’m a little exhausted, but also relieved that I eventually managed to SHIP 🎉
Software is never done, and that is most definitely true for Shrugs.app. There are a few things that I’d like to have myself (most importantly the ability to edit messages after they got sent).
There are also a lot of features which are 90/10 implemented and “just” need some finishing touches, like quick-open (⌘-k), typing indicators, or search. I also disabled some performance optimizations due to bugs they caused, another thing which is going to arrive eventually.
The most important thing for me of course is your feedback. What do you need the most? Suggestions to make it better? Let me know!
Welcome to Shrugs.app: I hope you like it! You can download it over here.
P.S.: If you actually managed to read this whole large blob of text, respect!