There are many instances of this pattern in the app which all have the same desired behavior:
* If `idealImage` is in memory, show it immediately
* Otherwise:
** show `fallbackImage` instead (placeholder or different resolution)
** on a background thread, fetch `idealImage` from the network/disk, cache it, then show it again
Let's consolidate all of this into one abstraction so we don't need to reimplement it everywhere.
== Expected results ==
=== Will it increase our velocity? ===
It should increase our velocity, since we'll be replacing multiple untested solutions with a single tested one.
=== Will it reduce risk? ===
Yes, by having redundant implementations we reduce the potential for one of them to do the wrong thing, and fixes applied to the shared implementation will apply across all uses.
=== Will it improve user happiness? ===
Yes, as we'll reduce more edge cases where images don't appear and we'll be smarter about how to store and pass around image data—which should save memory, disk, and CPU.