How to Circumvent Slack’s Obnoxiously Dark Border on Its Chatbox

In the name of accessibility, Slack has rolled out an obnoxiously dark border on its chatbox. It’s so bad that people on Twitter think it’s a bug and there’s seemingly no way to disable it, without dipping into custom hacks. This chatbox is so ugly that it is inaccessible for me, so here’s a hack that restores it to how it was, more or less. The code for this hack is stolen shamelessly from reddit with the relevant parts changed.

On a Mac1, open this file:

Applications/Slack.app/Contents/Resources/app.asar.unpacked/src/static/index.js

And paste in this:

// First make sure the wrapper app is loaded
document.addEventListener("DOMContentLoaded", function() { // eslint-disable-line
   // Then get its webviews
   let webviews = document.querySelectorAll(".TeamView webview");

   // Fetch our CSS in parallel ahead of time
   const cssURI = 'https://gist.githubusercontent.com/martynchamberlin/27e5ef5fccaf7a4ba3773bbe3a355dc1/raw/0c8fc4f745fc3b228d1f8fdec87ecfb082851151/custom.css';
   let cssPromise = fetch(cssURI).then(response => response.text());

   // Then wait for the views to load
   webviews.forEach(webview => {
      webview.addEventListener('ipc-message', message => {
         if (message.channel == 'didFinishLoading')
            // Finally add the CSS in
            cssPromise.then(css => webview.insertCSS(css));
      });
   });
});

Then restart Slack, and you should be all good. If you don’t like my CSS, create your own Gist and update the cssURI variable above to point to its raw URL.

  1. If you’re on Windows, you’ll need to go to the reddit thread and try to find the proper directory src. It’s version-dependent on Windows so you’re on your own. ↩︎

Dilbert Blog Moves from Tumblr to WordPress 

Scott Adams:

We are making updates to the Dilbert blog (moving to the WordPress platform) that will result in an error message for many (example here).

Nothing quite like going from one mediocre blogging service to another. I’m at least hoping that this migration will result in this nonsensical banner from disappearing from the site:

This website uses cookies to ensure you get the best experience on our website.

Imagine if every site that used cookies showed that banner message.

What’s with the JavaScript at the Apple Machine Learning Journal? 

Nick Heer:

For some reason, the virtually all-text site includes on every page a 1 MB JavaScript file.

Two thoughts on this:

  1. The fact that this JavaScript file is not minified tells me that the gatekeepers to this journal either don’t know or don’t care enough about JavaScript and web browser performance. Minifying JavaScript greatly reduces its file size. The attitude I’m getting from this is, “Yeah, JavaScript is a necessary evil, boy is it evil, we don’t really care.” That does bother me.
  2. Nick is correct that it’s a “virtually all-text site” but that’s going to change, if I had to guess. Perusing the JavaScript — which we can do since it isn’t minified — shows a lot of little, interesting structures for interact-able elements. Apple has only published the first entry in its journal, but there are more to come, and those future ones will contain interactions. You could look at this in two ways. The pessimist takeaway would be that Apple has a bunch of standard JavaScript that it has built elsewhere and just dumped it all on the page “in case we need it some day.” The optimist takeaway would be that Apple is planning ahead for great new journal entries to come and is already laying the foundation for that at the outset.

QuickCast Sunsets Its Service 

QuickCast on Twitter:

You should be able to access, but the site will be going offline soon as the app hasn’t been available for some time now

I’ve been using QuickCast since October 2015. It was hands-down the best screen recording app I’d ever seen. Super clean and simple to use, super fast upload to the cloud. And now it’s gone.

If you have the Mac App installed on your computer, it still works, but that’ll change at any time. Sad! Time to look for a replacement, I’m afraid.

Daniel and I Aren’t Feeling The Grube on This One 

Here’s the thing: I want to believe that force quitting iOS apps doesn’t positively affect battery life, if for no other reason than because everyone I know force quits their apps; part of becoming a curmudgeon involves having well-informed reasons with which to disagree against mainstream, and this seems a perfect chance.

The Grube has this to say:

But don’t let one bad app spoil the whole barrel.

FB is the #1 most used app for a ton of people. If an app takes up half your apple barrel, maybe the worms get bored eventually and start exploring the other apples? At what point do the poorly written apps outweigh the well written ones? I’ve seen a lot of complaints lately about 100MB app bundle sizes for App Store app updates. You’re telling me that these same devs don’t care about bundle size but they do care about memory management? Not sure I’m buying that.

Oh, and if you’re a Genius at the Apple Store and you see a person who clearly uses Facebook a lot, you’re not going to tell them to force quit that sucker?

I want to, but I’m just not feeling The Grube on this one.

PhpStorm 2017.2 

Speaking of updates, here’s an update to the world’s most robust IDE, PhpStorm. Here are three big improvements that I’ll be finding very useful:

  • $this highlighting
  • Support for enhanced webpack module resolution
  • Import from ESLint

Yuge.

Transmit 5 

A few thoughts:

  • Transmit is the only FTP client I touch. All the others are garbage in comparison. This update looks to be an incredible update to the world’s greatest FTP client.
  • If you’re having to use an FTP client on a regular basis, that means you’re probably not using git, or at least, not the way it was intended to be used, and you have my sympathies. The less I use Transmit, the happier I am. Not because it’s a bad app, but because manual FTP is a lousy, archaic technology. Yes, I know Panic has auto-sync, but whatever. Your changes should be getting to the server via version control and an automated deploy system, not a find-something-do-something sync methodology.
  • That said, a huge portion of the Internet is built on things like WordPress, and FTP is still the king for WordPress development. When I use FTP, that’s what I’m using it for.
  • If you want a great example of Apple Pay on a website, this is it. I’ve not actually seen this anywhere before, and it’s truly incredible. You can spend $35 awfully fast just by visiting Panic’s landing page in Safari, both in iOS and macOS.

An Elegant Process for Handling Sub Pull Requests

Let’s say you’re working on a big feature that you’re dark launching in little incremental Pull Requests. Every few days or so, you launch a new piece of this as you get it written. We’ll assume you have some sort of developer review process, and that it takes a few hours at minimum for this review process to get completed. We’ll also assume that you prefer to only merge code in the morning, so that you have all day to address any issues that might arise with its deployment.

Pretty soon you’ll find yourself in a situation where your current Pull Request is getting too large, but you’re in zen mode and you don’t want to stop development while you get your PR reviewed, merged, and a new one started. How can you fix this?

The easiest answer is to create a new branch based off your current branch. Let’s see what this would look like.

$ git branch
* master
$ git checkout -b MC/feature-x-part-1
# do some work, to the point where MC/feature-1 is big enough for a dev review, then:
git add .
git commit -m "This is a 500 line diff PR! "
git push
# create a pull request on GitHub to merge MC/feature-x-part-1 into master, then:
git checkout -b MC/feature-x-part-2
# do some work, then:
git add .
git commit -m "Part 2"
git push
# create a pull request on GitHub to merge MC/feature-x-part-2 into MC/feature-x-part-1

Now you can continue development on MC/feature-x-part-2 to your heart’s content while MC/feature-x-part-1 is in dev review. Once MC/feature-x-part-1 gets approved and merged into master, this is where the fun part begins.

First, if your sub branch (MC/feature-x-part-2) has a ton of commits in it, consider squashing them to save you time later (I’ll explain why in a minute). Only leave as many commit SHAs as you’re comfortable copying and pasting. Next, change the base branch of your Pull Request for MC/feature-x-part-2. Instead of having it set to merge into MC/feature-x-part-1, change it to merge into master.

Once you do this, you’ll see that all the commits that were associated with MC/feature-x-part-1 are now seemingly a part of MC/feature-x-part-2. You don’t want this; not only because it’s untidy, but because you can introduce grave errors in your code without realizing it. You want to get rid of these commits, but you can’t just rebase against master, in my experience (well, you can, but you’ll likely have a lot of needless conflicts that you’ll have to resolve). Instead, there’s a more elegant way to go about this: locally delete the sub branch (MC/feature-x-part-2), re-recreate it based directly from master, then cherry-pick the commits from the sub PR. Here’s what this would look like:

git checkout master
git branch -D MC/feature-x-part-2
git checkout -b MC/feature-x-part-2
# start in chronological order (i.e. oldest first) to cherry-pick the commits from your sub PR.
git cherry-pick 31c2e4a
# if any conflicts arise, then resolve them, then `git add .; git cherry-pick --continue`
# continue to cherry-pick all the commits in the sub PR
git cherry-pick fb690ed
git push -f origin MC/feature-x-part-2

This flow is swift, has no obvious downsides, and works well for me.

How to Remove Space Between Inline Block Elements 

Yarin, writing at Stack Overflow:

All the space elimination techniques for display:inline-block are nasty hacks…

Use Flexbox

Back in day, I wrote JavaScript functions that took a block of inline sibling elements and removed the whitespace between them (particularly for <li> elements in WordPress navigations). Flexbox completely removes the need for that.

Glycerine, commenting on Yarin’s post:

This should be googles first anwer [sic]

Yes.

On the Importance of Storing Image Dimensions for iOS Applications

Every few weeks I continue to make more progress on the native Swift iPhone application for Quillify. Whilst working on it this weekend, I discovered FastImage. It’s is a Ruby gem that lets you retrieve the width and height of a remote image from a URL. It’s incredibly easy to use. Here’s how I’m doing it for Quillify’s API:

posterDimensions = FastImage.size(movie[:poster])

Storing image dimensions separately from the image itself is a borderline necessity in an iPhone application if the image dimensions are a determining factor in layout. With Quillify’s home feed, I have a UITableView component with corresponding UITableViewCell components for each movie. Part of that cell is a UIImage component for the movie poster images. If you load images in the main thread, it’s UI-blocking, which leaves you in a predicament with two terrible choices; you can load all the images at once (which is bad because you don’t want to load images unless the user actually scrolls down far enough to need them) or you can load them on demand (which results in the UI locking up while the fetching is occurring; which is even worse than the former option). To get around this predicament, you want to load the images asynchronously, after the user is already (potentially) scrolling down the page. That sounds great, except this means that the heightForRowAt method will execute before the images have arrived, and you need to give concrete numbers. If you give anything other than the correct values, you’ll end up with the UI jumping around as the images arrive and take their proper space.

With FastImage, I’m now grabbing the dimensions of the movie posters from their remote Amazon URLs and storing them directly in the database when the user posts a new movie. A simple Rails migration script allowed me to run through all the preexisting entries in the database and insert their proper dimensions too. Now the JSON payload for the home feed includes these poster dimensions, and the iPhone app’s home feed is butter smooth on initial load. It’s beautiful.

This is just a “weekends when I feel like it” kind of project but I really hope one day I’ll be able to tell you to go in the App Store and download Quillify. It’s an app like no other. Until then, you can always sign up on the website, though I’ll likely remove web-based login if and when the iPhone app premiers.

Meanwhile, if you’re tinkering with an app idea that involves images, plan on storing the dimensions. You’ll likely need them.

x.com 

Matt Novak, writing for Gizmodo:

Elon Musk just announced the launch of a new website, x.com. The billionaire founder of Tesla and SpaceX made the announcement on Twitter at 1:21am Pacific time this morning. But so far there isn’t much to look at. The website is just a single letter X.

Looking forward to seeing what x.com turns into.

The Internet Is Great (Again) 

Back in March, a very confused Nilay Patel had this to say at The Verge:

But very sad for the internet economy and startup culture: how can a new rival compete with a prioritized or zero-rated Netflix if its service is delivered more slowly or costs more in data charges?

Nobody actually thinks that ISPs would slow down a competitor to Netflix. That’s a straw man. But let’s say for the sake of argument that this did happen; is it the government’s job to protect this from happening? Absolutely not.

The Internet is great again, to correct the very crass headline today at The Verge. Ajit Pai had the courage to kick the government out of this whole affair, despite much of the populace being in opposition. Who in China or North Korea would look at a country whose Internet is unmolested by government and deny that such a country has made the right choice towards free speech, free enterprise, and the open web?

Why So-Called Net Neutrality Is Bad 

Josh Steimle, writing a refreshing piece at Forbes back in 2014:

Proponents of Net Neutrality say the telecoms have too much power. I agree. Everyone seems to agree that monopolies are bad and competition is good, and just like you, I would like to see more competition. But if monopolies are bad, why should we trust the U.S. government, the largest, most powerful monopoly in the world?

Nailed it.

Many of us see the U.S. government as a benevolent and all-knowing parent with the best interests of you and me, its children, at heart. I see the U.S. government as a dangerous tyrant, influenced by large corporate interests, seeking to control everyone and everything.

See also the prayer of the net neutralist.

Bloomberg: “Working from Home Doesn’t Work” 

Rebecca Greenfield, writing at Bloomberg:

Last year, Richard Laermer decided to let his employees work from home on a regular basis. “We hire adults, they shouldn’t be tied to the office five days a week,” said Laermer, who owns a New York-based public relations firm. “I always assumed that you can get your work done anywhere, as long as you actually get it done.”

Turns out, he was wrong.

This is in pretty stark contrast to what Stack Overflow’s 2017 survey results suggest. Here’s what I had to say about it then:

Working remote is becoming more and more of a thing. 53.3% of developers looking for a new job say that remote options are a top priority? That’s huge.

My entire company works remotely. Bloomberg cherry-picked a few anecdotes that make it sound like a bad idea, but the full picture is much different than that.

Apple’s Decadent iPhone 

Nick Heer, writing at PixelEnvy, speculating about the new iPhones coming out this fall:

If past years are any guidance, the iPhone 7S should be a respectable update, even if it lacks a new hardware design.

If there are any — any — new iPhones this year that have the same hardware design as the past three years in a row, I’m going to be disappointed. I don’t consider the iPhone 7 design to be sufficiently different from the previous two iPhones (the 6 and 6S) to warrant another year of design change dearth.

Gruber and entourage are madly curious about this purported “pro” iPhone, but the vast majority of us would consider the upgrade decadent in the same way that we consider the Apple Watch decadent. You have to have a smartphone but you don’t have to have an exorbitantly fancy smartphone. That requires justification and mental persuasion; and many a person, including multimillionaire CEOs, will not even consider obtaining said “pro” iPhone. Stated another way, the only iPhone that matters in terms of the 80/20 rule is the 7S. But it better not be called that, because it better be a brand new form factor.

If you sense an edge in my tone it’s because I know I’m probably wrong. Apple will probably announce a 7S in September that has only minor outward differences and hype it like it is a new thing. The media will say Apple is off its rocker. The pundits who literally don’t have to worry about budgets will disagree as they gloat over their overpriced decadent “pro” iPhones, but they’ll be wrong, because they’re not living the lifestyle of the average American price-conscious consumer and they’re out of touch with reality.

It feels like how John Buford felt on July 1 in the movie Gettysburg. I can see it coming; it is as though it had already happened.

iOS 11 Removes 3D Touch App Switcher 

Khushbu Choudhary, writing at App Gyann:

With iOS 11, the Cupertino-based company has decided to ditch the ability to 3D Touch the edge of the display to launch the app switcher.

This nifty shortcut, which was first introduced with the launch of pressure-sensitive 3D Touch displays alongside iPhone 6S and 6S Plus, is no longer supported in iOS 11.

Here’s what I wrote about this feature back in December:

Usually when I trigger the feature, it’s an accident.

The universe of people who will miss this feature is going to be very small. As iOS actions go, it’s uncharacteristically hard to trigger, due to the fact that it’s so similar to the much more popular “swipe left to right” action for segueing back a view.

Privacy and the :visited Selector 

From the Mozilla Developer Network:

Historically, the CSS :visited selector has been a way for sites to query the user’s history, by using getComputedStyle() or other techniques to walk through the user’s history to figure out what sites the user has visited. This can be done quickly, and makes it possible not only to determine where the user has been on the web, but can also be used to guess a lot of information about a user’s identity.

In the old days, this used to be a clever hack, but it’s no longer achievable in a modern browser.

The Perfect Pull Request 

Here’s some great advice on pull requests from GitHub. Some of my favorite parts:

Ask, don’t tell. (“What do you think about trying…?” rather than “Don’t do…”)

Questions are so much less confrontational. This stuff might sound foo-foo but when you put it into practice and experience it for yourself, it makes a huge difference. A teaspoon of sugar makes the medicine go down.

Also this:

Try to respond to every comment.

This is a real pet peeve of mine. Ignoring comments is easily perceived as hostile behavior.

The Mystery of Google Search Not Working in Chrome at Certain Times of Day

Lately I’ve been encountering the strangest thing. In the afternoons, Google Search has stopped working on my MacBook Pro. I can’t do a Google search, and I can’t go to Google.com. Upon initiating the request, the browser just spins and spins, and eventually it times out. For a while I thought there was something wrong with my ISP, because this problem only occurs in the afternoons, and it doesn’t occur on my iPhone over an LTE connection. I’ve been forced to use DuckDuckGo as my search engine.1

Over time though, I slowly discovered something. Google Search only breaks in Chrome; in Safari for example, it still works fine. And in Chrome, it works in a private browsing session. On a hunch the other day, I cleared all of my cookies in Chrome, and boom, Google Search started working again. The next time the issue arose (it doesn’t happen every afternoon, but often enough to be very irksome) I pinpointed the exact cookie that was causing the problem. It’s called Channel ID, relating to transport security perchance. If you go here2 you can see all of your Chrome cookies for the Google.com domain. While I’m writing this, I’m going there and I’m seeing a Channel ID cookie, and yet Google Search works; so that cookie only breaks Google Search at certain times of day. When it’s broken, all I have to do is delete that cookie, and it starts working again.

It’s the weirdest thing and I haven’t found anything online about this.

  1. I appreciate the competition of a free market, but let’s be honest: DuckDuckGo is vastly inferior to Google Search. ↩︎

  2. For that link to work, you’ll have to copy and paste it in your address bar in Google Chrome. Clicking it directly results in this console error:

    Not allowed to load local resource

    Meh. ↩︎

Multi-Touch Gestures in Slack for iOS 

It’s been around for quite some time but I didn’t discover this until today, heuristically. From the Slack documentation:1

  • With two fingers to the left for the previous channel or conversation, and with two fingers to the right for the next channel or conversation.
  • With three finger [sic] to the left for the previous team, and three fingers to the right for the next team.

Slack is amazing. One of my favorite applications of all time.

  1. Oops, look at that typo! ↩︎

Working Fulltime on an iPad as a Software Developer 

Justin Searls, in a lengthy piece at Medium:

Apple spent eight years iterating on iOS before shipping the extension points necessary to accomplish the sort of actions demanded by its power users. Heck, it took nine major versions for real hardware keyboard support to materialize. The iPad may be old news, but its usefulness as a computer is still a recent development.

The day I can do my job on an iPad, I’m switching, because as much as I love macOS, I love iOS even more. A couple of requirements though:

  1. It needs to not involve having to write my code in Terminal. I need a real IDE, like most developers.
  2. It needs to not involve remoting into a Mac. Instead, it needs to be self-contained within the iPad itself. No Mac should be necessary in the process.

We’re not there yet, but with each major release of iOS, we’re getting closer to the iPad being a complete replacement to the Mac for serious developers. That’s really exciting.

Bravely Default 

Seth Clifford in 2015:

Most shockingly for some nerds, I’m just using the built-in Podcasts app. Why? Because my use case is having a podcast show up, and me listening to it. At regular speed. And having them actually appear on all devices consistently (yes, it’s true) is kind of nice. Now put your eyes back in your sockets. I’m sorry to have done that to you.

This really resonates with me, even though I prefer Airmail to Mail and Bear to Notes. The default podcasting app on the iPhone is the best designed podcasting app I’ve ever seen and it just works. Why use anything else?

On the Importance of a Clean Browser Console in Web Development

The browser console is one of the most important parts of developing for the web. Every message that appears in the console should be relevant to the developer. When this is no longer the case, and messages start piling up that have no bearing to the matter at hand, developers learn to ignore those messages. This leads to an inability to solve problems.

I can’t tell you how many times I’ve looked over a developer’s shoulder and fixed a problem for them simply by looking at their console. Perhaps six of the messages were irrelevant, but one of them was relevant. And that one held the key to solving the problem. Too bad those other six were there. They gave the developer permission to ignore the seventh one.

The console should be treated as a first class citizen. One very practical way we can help it achieve this status is by constantly pruning from the console things that are irrelevant. Over time, unhelpful messages from third party vendors and even our own code base tend to accrue. Every effort to get rid of these is time well spent.

Here’s to a console that shows nothing other than messages that require your immediate attention. Treat your console like your inbox. Keep it clean.1

  1. Also, happy July 4th. I imagine our Founding Fathers stayed pretty busy on this day in 1776, and I aim to too. ↩︎

The Insanity of Wishing Browsers Did Not Run JavaScript 

This past week John Gruber has been writing and talking about a hypothetical universe where JavaScript was not allowed to run in a web browser. It reminded me of Jeff Schmidt’s excellent talk that I posted about more than a year ago, in which he explains the reason why “JavaScript has a faster dynamic language runtime than Ruby, Python, and PHP.”1 The reason? Because JavaScript was allowed to run in the browser, which in turn created an arms race for each tech company to have the fastest JS compiler and thereby the fastest browser, and dominate the market.

In terms of popular languages, JavaScript is hands-down the fastest on the planet for the very reason that Gruber hates it. This is a classic example of someone criticizing something that they have no knowledge of. It’s uninformed propaganda. Just because you think someone is abusing something (in this context, JavaScript’s Ajax abilities) doesn’t make that something wrong; it just makes that someone wrong.2 Although I even disagree that this is an abuse of JavaScript.

Anyway, I make my living writing JavaScript. I’m triggered, which is why I’m having a hard time letting this one go.

  1. JavaScript also has a faster runtime than Gruber’s beloved Perl, too. ↩︎

  2. This also applies to the Second Amendment, which Gruber is also wrong about. At least he’s consistent. ↩︎