Skip to content
This repository has been archived by the owner on Feb 29, 2020. It is now read-only.

fix(highlights): Add image caching and image placeholders. #3427

Merged
merged 1 commit into from Sep 12, 2017

Conversation

AdamHillier
Copy link
Contributor

Closes #2322. Closes #3406.

@Mardak
Copy link
Member

Mardak commented Sep 12, 2017

Design says to have a blended border that shares the gradient. I mocked it quickly with a box-shadow inset as borders go outside of the image:

box-shadow: inset 0 -1px 1px rgba(0, 0, 0, 0.05)

pasted image at 2017_09_12 01_12 pm
pasted image at 2017_09_12 01_15 pm

Design says ideally no extra shadow creeping in from left/right edges but if that can't be fixed, then it's still better than the solid grey-30 border along the bottom.

@Mardak
Copy link
Member

Mardak commented Sep 12, 2017

Oh, here we go with no side shadow:

.card-outer .card-preview-image-outer::after {
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  bottom: 0;
  content: " ";
  position: absolute;
  width: 100%;
}

With the .card-preview-image-outer parent being position: relative;

pasted image at 2017_09_12 01_56 pm

Copy link
Member

@Mardak Mardak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there were some decisions made to keep backwards compatibility with other Sections. What compatibility do we actually need to keep vs having the code the way we want? E.g., instead of just relying on a hasImage, we need to additionally check image (which could be renamed to imageUrl) for Sections that only provided an image.

Also, what's the cache supposed to help with?

// We want the page, so update various fields for UI
Object.assign(page, {
image,
imageLoading: true, // We always have an image - fall back to a screenshot
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would assume this imageLoading is for other sections to have just text? Let's just rename this to hasImage as it would seem to imply it should be false if it's already loaded.

{link.image && <div className="card-preview-image" style={{backgroundImage: `url(${link.image})`}} />}
<div className={`card-details${link.image ? "" : " no-image"}`}>
{hasImage && <div className="card-preview-image-outer">
<div className={`card-preview-image${link.image ? " active" : ""}`} style={imageStyle} />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of "active" here is confusing as at least with css-related stuff, it's when the user is interacting with it. Probably name this "loaded".

@@ -56,14 +56,18 @@ class Card extends React.Component {
const isContextMenuOpen = this.state.showContextMenu && this.state.activeCard === index;
// Display "now" as "trending" until we have new strings #3402
const {icon, intlID} = cardContextTypes[link.type === "now" ? "trending" : link.type] || {};
const hasImage = link.image || link.imageLoading;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With imageLoading renamed to hasImage, I think we should just rely on that value instead of additionally checking image, so const {hasImage} = link;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Although I see you probably did this for backwards compatibility for other things passing in just image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah because pocket for example doesn't set hasImage

@@ -81,6 +90,20 @@ this.HighlightsFeed = class HighlightsFeed {

SectionsManager.updateSection(SECTION_ID, {rows: this.highlights}, this.highlightsLastUpdated === 0 || broadcast);
this.highlightsLastUpdated = Date.now();
this.imageCache.clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of the cache if we clear it on every fetch? It seems like it would only be beneficial if multiple highlights ended up using the same image?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image cache cleared at the end of every fetchHighlights once it's been used (in that method). The async fetchImage calls then fill up the cache again for the next fetchHighlights call. I think, though I could be wrong, that none of the fetchImage calls are executed before fetchHighlights has finished executing, so they fill up the cache after it has been cleared. Without the image cache I found that subsequent refreshes caused flickering of images for existing cards as the src was unset then reset again asynchronously.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm.. That makes sense. Although it's also quite dangerous how it is right now. If something were to delay this clear() until after some images were fetched and set, then it's just throwing away that work.

The cache seems to be acting more as a prefetcher, but it could be a better actual cache if it only removed items that weren't used if the concern is holding on to fetched images too long. But this can be done in a followup bug.

At minimum better comment on why it's clearing here and how the cache will still be useful.

updateSectionCard(id, url, options, shouldBroadcast) {
if (this.sections.has(id)) {
const card = this.sections.get(id).rows.find(elem => elem.url === url);
if (card) { Object.assign(card, options); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: put the if code block body on its own line

@Mardak
Copy link
Member

Mardak commented Sep 12, 2017

Oh and we'll want to pass in backgroundColor of grey-10 #f9f9fa

Copy link
Member

@Mardak Mardak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay explanations make sense. Just some nits to fix and adding the backgroundColor

@as-pine-proxy
Copy link
Collaborator

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants