It’s amazing, and perhaps a little shocking when you think about it, how much time spent on planning software development activities is actually spent on fighting Jira.
Feature needed for news sites: a mouse-over for names in an article that quickly shows you who they are and how they relate to the reported issue. I always forget who is who and have to go back to the top of the article to reread their introduction. Books need this as well.
Things I don’t miss about commuting to work: delays due to public transport interruptions. 😒
I only just learnt today that NetNewsWire on the iPad does not require an internet connection in order to read articles. They seem to be stored on device, complete with pictures. At home there was always WiFi so I never had a chance to try this. Very nice!
I’m wondering if there should be a set of conventions for people on video calls to indicate acknowledgement without needing to speak or turn the video on. Reactions, and other status indicators, are not available in every service, and the ones that do have it tend to be for getting the speakers attention.
There’s a convention in aviation, at least in recreational aviation that I’m familiar with, that has inspired this thinking. If someone needed to transmit a message over the radio, they will do so by pressing down the push-to-talk button and speaking their message. With VHF radio, only one person can be transmitting at any one time. Everyone one else on that particular wavelength will be able to hear them, but if they tried to transmit, the whole message will be garbled.
So there’s always a bit of caution when there is a need to use the radio. You’re generally advised to wait a few seconds before speaking on the off chance that someone else starts before you. This is also not a medium that grants you a lot of time to talk: messages are usually quite short, and are usually only made when required.
I guess that’s why a convention was developed, where someone operating the radio will indicate acknowledgement by quickly depressing the push-to-talk button. Doing so usually results in a burst of static clearly audible to everyone else on that wavelength. Unlike accidental presses, this quick tap is less than than a second, so there is no mistaking that it was intentional. This makes it perfect for quickly indicating a message was received, just like a thumbs up would if the conversation was face-to-face.
A convention similar to this would be great for videoconferences. Whereas status indicators are not available everywhere, most videoconference software I’ve used have a mute indicator for each participant. Quickly unmuting and muting the mike would pulse this indicator, which is pretty close to the visual equivalent of that burst of static. Done quickly enough, it will indicate intent, and would therefore be a perfect to quickly indicate the message has been received.
Returning to the office today. Not sure if it will be full time, hopefully there will be opportunities to work from home going forward. But I’m getting a sense here that the year-long WFH experience is coming to an end.
Australia’s ABC News shot to the top of the App Store charts following Facebook’s news ban
From the Verge:
The Australian Broadcasting Corporation’s ABC News app shot to the top of Apple’s App Store charts in Australia over the course of the last few days, not long after Facebook banned Australian news sources on its platform.
[…]
ABC News currently sits at No. 2 in the App Store’s overall app rankings in Australia, according to the analytics firm App Annie, and No. 1 in the news app charts. When Patel noticed the change, the app was also briefly No. 1 overall, ahead of Instagram, Facebook Messenger, and the Facebook app itself.
I’ve been seeing these banners on ABC News site myself, and I was sceptical that anything would come of it. Turn’s out I’m pleasantly mistaken. It’s really good to see people choosing to go to a reputable news source directly.
Some uninformed thoughts about the ACCC Media Bargaining Code
Yesterday, when the news about the news and Facebook was making the rounds in Australia, I have been wondering about my position about the whole thing. After listening to the Stratechery Daily Update1 from Ben Thompson about it, I think my position on this has solidified.
I’m no fan of Facebook, but I can completely understand why they took the action they did, and I believe that it is in their right to do so. It could be argued that banning links and pages from government and NPO organisations was wide-reaching, and for that, I think it’s important to consider the motivation here. Was Facebook being cautious about their interpretation of the proposed law, which was written so poorly to suggest that anything related to the goings on in Australia fell under the code? Where they just being sloppy about which organisations were banned? Or were they going to such broad lengths to make a point and leverage their negotiation position? I don’t know: all three scenarios seem plausible.
But I think Ben Thompson is spot-on in making the point that there was a lack of political ground work prior to Facebook taking this action. Contrast that with Google, which since last month was warning about maybe pulling out of the Australian market if there was a chance that they would violate the code. I didn’t see anything like this from Facebook, and Ben Thompson made the point that this was a lot like the saga around WhatsApp and the privacy changes. Who knows? Maybe if they did this, they would have more sympathy in the eyes of the public.
It may sound like I’m taking Facebook side here. I won’t go so far as to say that, but living in a society with free enterprise I don’t see why they couldn’t do what they did. No one is preordained with a right to post on Facebook, and expect that they can extract rent for doing so. It was a mistake on part of the government and media organisations (hi, Mr. Murdoch) to think otherwise.
The whole mess is regrettable but I hope everyone comes out of this a little wiser. I think for me it just reinforces the importance of maintaining your own, independent position on the web. There might be subsequent words on this thought down the line.
-
This article is paywalled, but if you are in any way interested in technology, I highly recommend subscribing. ↩︎
A $2000.00 Smartphone with Ads
I just learnt today that the Samsung Galaxy S21 Ultra has ads. I’m generally not that interested in Samsung phones, but the idea of putting ads on a device that costs up to $US 2,000.00 offends me so much that I had to comment.
If I shell out that amount of money for a device, I expect an experience that is worthy of that price. Having that experienced degraded with crappy banner ads, and a built-in app1 which hijacks the lock screen, really brings down the intrinsic worth of the whole device to a point that doesn’t justify the price they’re asking for. It shows contempt for the customer — you know, the person that, by right, is the owner of the phone they paid for — and it’s just overall dishonorable.
I know how difficult it can be for Android OEMs to compete given the current race to the bottom. But my understanding is that Samsung is actually second to Apple in terms of revenue per device, so I see absolutely no reason why they would consider a move like this.
Yeah, I know it’s a first world problem, but I’m seeing more and more phone vendors thinking that the device that they sell, supposably at a profit, is also a vector for which they can push marketing messages through without regard, and I really don’t want that to happen.
-
The built in app, called “Samsung Global Goals”, is designed to promote charitable causes through the use of promotions. I appreciate the motivation of funding these causes, but not the approach they use to do so. ↩︎
Communication Among Stimulus Controllers
From the time I’ve started playing around with Stimulus, I’ve been thinking about the best way that controllers can communicate with each other.
The nice thing about Stimulus is that the state of the controller is representable from within the DOM itself, meaning that if a property of a controller needs to change, it can be done so by simply modifying the attribute value of the element the controller is bound to (see here for how that works).
This, however, doesn’t extend nicely to instances when you only need to notify the controller of an event or send a message that is more one shot: “I did a thing”, or “please do that thing”. It’s not always possible to translate these interactions to one that is based on modifying attribute values, and most attempts to do so always end up as a bit of a code smell.
After a bit of experimentation, I think I’ve found a method which works for me.
Existing Solutions
Stimulus does not have a way of doing this using their API, at least at the time this post was written. I’ve found some examples of how to achieve this using the private API which, although they may work, I found slightly ugly. In general, I try to avoid dealing with the unexposed inners of a library, even if it’s implicitly available to me1. Doing so usually results in constant maintenance of the integration, as the original library authors assume that they are free to change or refactor the internals as they see fit. It then falls on you to keep up, and fix any breakages as they occur.
One could argue that going to these extremes indicate that support for this form of communication is missing in the library. This might be true, but the fact remains that it’s not available to me now. So an alternative will have to be considered.
The Approach
For a while I’ve been wondering this could be done at all. But after a bit of playing around, I’ve settled on a solution that uses Custom Events — the ability to create, and receive, events that are completely user definable — to achieve this.
Custom events have have some nice properties that work well with Stimulus:
- It’s already available, and well supported by modern browser.
- It works with the Stimulus
data-action
attribute. - It doesn’t assume any internal workings of Stimulus itself.
The general approach is as follows: a controller that wants to send a message to another controller
creates a custom event, and sends it using the dispatchEvent()
method on a DOM element:
element.dispatchEvent(new CustomEvent("eventName", {
detail: {
// optional details
},
}));
A custom event is made by calling the CustomEvent
constructor and providing it with an event name. Data can be associated with the event by putting it inside the detail
object.
Controllers interested in receiving the event can use data-action
to register a handler, just like any other browser event. The optional details can be retrieved through the detail
attribute on the event object passed into the handler:
<div data-controller="listener" data-action="eventName->listener#eventHandler">...</div>
export default class extends Controller {
eventHandler(ev) {
let details = ev.detail;
// Handle the event
}
}
That’s pretty much all there is to it. The only thing that changes is which element actually dispatches the event, along with some specifics on how the event is created. These relate closely on the relationship of the various controllers, which are explored in the following sections.
Pattern 1: From Child To Parent Controllers
This pattern applies for events that are sent from the child to the parent. There are some cases where this can come in useful, such as when a child controller wants to propagate the value of input fields to the parent controller bound to a form, potentially useful when determining whether it’s safe to submit it.
First, it’s probably important to highlight what this is not. It’s not simply referring to the parent controller in an element nested within a child controller:
<div data-controller="parent">
<div data-controller="child">
<!-- The child is not sending the event. The button is contacting the parent directly -->
<button data-action="click->parent#doSomething">Do Something</button>
</div>
</div>
The child controller is available but the actual handler in the example above is actually handled by the parent. As such, the child is not notifying the parent of the event: the button element is.
Instead, this pattern is for cases whereby the child controller itself sends the event, and it works when the event is configured to “bubble up”.
Event bubbling is a mechanism of event propagation whereby the browser will pass the event up through the DOM, running each of the event handlers that are capable of handling the event. This means that when an event is dispatching from the element bound to the child controller, and that event is configured to bubble up, it will pass through he parent controller on it’s way up to the root of the DOM. The parent just needs to listen for it by setting up a data-action
handler.
Here’s an example:
<div data-controller="parent" data-action="messageFromChild->parent#handleMessage">
<span data-cp-parent-target="message"></span>
<div data-controller="child">
<button data-action="child#sendMessageToParent">Send Message</button>
</div>
</div>
The child:
export default class extends Controller {
sendMessageToParent() {
this.element.dispatchEvent(new CustomEvent("messageFromChild", {
detail: {
message: "Hello from child"
},
bubbles: true // This needs to be explicitly set to enable event bubbling
}));
}
}
The parent:
export default class extends Controller {
static targets = ["message"];
handleMessage(ev) {
console.log("Received event");
let message = ev.detail.message;
this.messageTarget.textContent = `Message from child: ${message}`;
}
}
In this example, clicking the button will cause the child controller to dispatch the messageFromChild
event. That event will bubble up the DOM and be caught by the handleMessage
event handler configured on the parent. The parent is free to react to the event and display the message sent from the child.
The parent handler can also include a call to the stopPropogation() method on ev
to prevent the event bubbling further up the DOM if necessary.
From Parent To Child Controllers
Browser events that bubble up will not work in cases when a message needs to be sent from the parent to a child.
First, it’s worth considering whether events are the best way to pass information from the parent to the child. Even though StimulusJS is not a framework like ReactJS or Vue, I like to follow the approach to data exchange that these frameworks recommend, which is to:
- Pass information from parent to child through the use of properties (or in the case of Stimulus, through values).
- Pass information from the child to the parent through the use of events
The fact that events coming from the child are easier to handle than events sent to the child provides an incentive to follow this pattern. It’s usually better to go with the grain when it comes to these decisions rather than attempt to fight it. But I’m fully cognisant that this is not possible in all circumstances, and sometimes an alternative approach is necessary.
With that out of the way, here’s an approach for a parent controller to notify a child within its scope. Events are used here as well. The only difference is that instead of relying on implicit event bubbling, we can send an event directly to the controller.
Consider the following HTML, in which we want to display a message within the <span>
when the button is pressed:
<div data-controller="parent">
<button data-action="parent#sendMessageToChild">
Send Message
</button>
<div data-controller="child" data-parent-target="children" data-action="messageFromParent->child#handleMessage">
<span data-child-target="message"></span>
</div>
</div>
Thanks to the data-target
attribute, the parent controller has a direct reference to the child element. We can therefore invoke dispatchEvent
directly on the child element:
import { Controller } from "stimulus"
export default class extends Controller {
static targets = ["children"];
sendMessageToChild() {
this.childrenTarget.dispatchEvent(new CustomEvent("messageFromParent", {
detail: {
message: "Hello from parent"
}
}));
}
}
Doing so will fire the event handler declared within data-action
:
import { Controller } from "stimulus"
export default class extends Controller {
static targets = ["message"];
handleMessage(ev) {
let message = ev.detail.message;
this.messageTarget.textContent = `Message from parent: ${message}`;
}
}
It’s also possible to do this to multiple child events bound to the same data-target
annotation:
// Parent
sendMessageToChild() {
for (let target of this.childrenTargets) {
target.dispatchEvent(new CustomEvent("messageFromParent", {
detail: {
message: "Hello from parent"
}
}));
}
}
For Controllers That Are Distinct
The final pattern is one involving controllers that are distinct. These are controllers that do not have a parent-child relationship in any way, making it difficult to get a reference to the element or implicitly pass events between the two. It’s still possible for the two controllers to communicate with each other, but it will require some mediation from the top-level window
object.
The window
object fires events that relate to the browser window itself, and Stimulus allows controllers to subscribe to these events through the use of the @window
modifier in the data-action attribute value. For example, setting up a handler which will be invoked when the window is resized can be done in the following way:
<div data-controller="receiver1" data-action="resize@window->receiver#handleResizeEvent">
This also works for custom events, meaning that we can use the window
object as a form of message broker. If we want an event to reach components that we cannot reference directly, we can simply “publish” a custom browser event to the window
object:
window.dispatchEvent(new CustomEvent("messageFromSender"));
And all interested components can “subscribe” to that event by attaching a handler to the window using the data-action
attribute.
<div data-controller="messageSender">
<button>Send Message</button>
</div>
<div data-controller="receiver1" data-action="messageFromSender@window->receiver1#handleMessage">
<div data-receiver1-target="message">This is the message</div>
</div>
<div data-controller="receiver2" data-action="messageFromSender@window->receiver2#handleMessage">
<div data-receiver1-target="message">This will also handle message</div>
</div>
The nice thing about this pattern is that is does not assume anything between the two controllers that are communicating. The sender knows nothing about which controllers that have subscribed to the events that it’s posting to window
. If there are no subscribers, then the event will simply be left unhandled. Likewise, if a controller sets up a handler for a window event that will never be published, it wouldn’t need to handle the lack of any publishers as a special case. The handler will simply never be called.
This leaves a nice, flexible architecture in which controllers are completely independent from each other, yet can still receive messages from any of them. This frees up the controller elements so that they can be rearranged within the HTML as deemed necessary — even be nested within each other, forming new parent-child relationships — without the need to change any of the controller’s code.
-
This is easy in a language like JavaScript with relatively weak boundaries between modules. ↩︎
On the Facebook Watch
Ron Amadeo, from Ars Technica, on Facebook considering an Android Watch:
The Information says Facebook’s smartwatch push is part of a larger plan aimed at “controlling the next computing platforms after smartphones.” In the smartphone era, Facebook is at the mercy of the two big smartphone operating system vendors, Google and Apple, neither of which have a particularly good relationship with Facebook.
The need for a platform looms large over this announcement, particularly given the recent tiff between Facebook and Apple over user tracking. But as the article points out, they’ve got quite the hill to climb to be successful in this endeavour: if Google had trouble doing it, then the prospects of Facebook succeeding here look tiny.
Some free advice for Facebook from someone with no branding or product design experience: consider spinning the hardware devision out into a separate brand, and keep the relationship between the two as quiet as you can. Given the current reputation of the company, I’m not sure developers will like to advertise that they’re building stuff for the Facebook Watch.
It only felt like a week ago when I saw the launch of NASA’s Perseverance rover. Yet here we are, days away from its arrival. Good luck to everyone involved. Here’s hoping for a smooth landing.
Viewing webpages with View
Here’s a way to simplify the number of keystrokes when viewing things from the web using Vim.
Previously, I was typing the following incantation whenever I wanted to view the source of a web-page from the command line:
$ curl <url> | view -
This works, but has some very minor drawbacks. One of them that I run into is that I occasionally forget to add the trailing dash, which usually results in a lot of noisy characters coming through as Vim tries to interpret the output.
Today, by accident, I simply typed the following:
$ view <url>
and it actually worked. The site was fetched using curl
in the background and the page opened up in Vim. It even opened with syntax highlighting as the page was downloaded to a temporary file first.
Argh, stop with the popups for my email address while I’m trying to read your blog! How can I enjoy your content when I’m interrupted with these? It does your site, or the prospects for getting newsletter subscriptions, no credit.
I’m more than happy to consider subscribing to a newsletter if I think the content you write is worth it. So by all means, offer a chance to do so and the end, or even in the middle, of the article. But don’t show a popup obstructing the very content I’m trying to read and that you want me to consume more of. It gives me a sense of desperation and lack of empathy for the readers you’re trying to attract.
Note to self: never do this yourself.
Qualcomm unhappy with Nvidia wanting to buy Arm
From Ars Technica:
According to CNBC, Qualcomm is one of many Arm licensees who continues to object to the acquisition. Although Qualcomm has so far refused to comment publicly, CNBC’s sources say it believes Nvidia cannot complete the acquisition without “crossing certain lines that people are worried about”—most likely, the anti-competitive lines we discussed above.
Seems to me there isn’t enough competition in this space at the moment, and Nvidia acquiring Arm may shake things up a bit.
I get the impression that Qualcomm is not interested in competing on merit in this space. It seems like they are persuing revenue streams that are not so much because of their technology, but because they are the only gig in town. They’re not afraid of squeezing customers over patient payments or not updating processors in four years.
They can do these things because who else are these OEM’s going to go to? Intel doesn’t work with Arm. I guess they can go with Samsung or AMD, but I get the feeling that this is not always viable.
Maybe having a competitor here will help with improving the quality of the technology in this space. It’s probably not likely Nvidia — I sense that having control of the Arm architecture is more important to them than getting license free access to the IP — but it would be nice if it was.
Is there a way, in Android Studios, to configure the debugger so that pausing a Kotlin app at a suspended function call, and stepping into, or over, keeps the debugger in the same thread?
I’ve never managed to get this working. When I do set a breakpoint at a suspended function call, and attempt to step over it, the application continues without the debugger stopping.
I’ve find myself needing to set successive breakpoints to work around this limitation. However, the statement just after the suspended call is usually another suspended call, which means more breakpoints that need to be set. When the number of breakpoints get too high, the cognitive load of remembering why each one was set becomes too much and I find myself forgetting why that particular breakpoint was set in the first place.
I understand that Kotlin co-routines are an abstraction layered atop the JVM, and that all the language facilities may not be in place to offer full support for these in the debugger. I only hope that someone is working on this though. Kotlin co-routines are pretty nice to work with, but with limitations in the tooling like this, the leaks are easy to spot.
February Photoblogging Challenge. Day 12: Sporg.
Mind turning slowly into sporg as I try to chase down this bug.

Current status: looking at sqlite3 DBs of an Android app in development while waiting for XCode to update to build a project to write a post on the dealing with breakpoints and coroutines in Kotlin. All while listening to a podcast and following the ABC Coronavirus live-blog.
The interesting thing about the “out of date” messages from Google’s iOS apps is the fact that they have the ability to turn these messages off without modifying the app. It makes you wonder how many of the features within these apps are controlled by server-side feature flags.
It’s a shame that we’ve had to go back into lockdown for 5 days, due to the highly infectious nature of the B117 variant. Hopefully it’s enough to stamp out the current outbreak. But what then? I’d be curious to know how we can continue to use hotels for quarantine given that this variant is spreading at a rate that is stretching the limits of our contact tracers. Maybe we can start using quarantine centres that are fit for purpose?