Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support image source objects #1470

Closed
wants to merge 4 commits into from

Conversation

jaulz
Copy link
Contributor

@jaulz jaulz commented Nov 4, 2019

This PR introduces support for Image source objects (related issue: #1019) which allows you to pass different headers or fetch data via POST method.

In the example I added a dynamic chart from Google Charts. Not directly related but to fill the row I added WebP and the mentioned redirect case in the issue.

image

Please let me know if anything is missing.

@necolas
Copy link
Owner

necolas commented Nov 4, 2019

Thanks for the PR! The unit tests are currently failing but at a glance this direction looks good to me, and should allow onProgress to be implemented too. So I'll work with you to get this merged

@jaulz
Copy link
Contributor Author

jaulz commented Nov 5, 2019

@necolas great! 😊 I just fixed some minor issues and now all tests are running fine. Also, I added the onProgress prop but that triggers only once for the example. Maybe we can find a better example?


export default class ImageUriCache {
static _maximumEntries: number = 256;
static _entries = {};

static has(uri: string) {
static createCacheId(source: ImageSource) {
return JSON.stringify(ImageLoader.resolveSource(source));
Copy link
Owner

Choose a reason for hiding this comment

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

I'm a little concerned about using JSON.stringify here. We could use a Map instead

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, I don't like it either but I could not find a smart way. The advantage of this approach is that you will always get the cached content for a combination of method, uri, headers and body. If we use a Map instead and use the source as a key then we somehow first need to get the reference to the source which leads to the same issue again. Or did you have something else in mind?

Copy link
Owner

Choose a reason for hiding this comment

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

A Map can use objects as keys

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it allows object as keys but the reference is stored as a key and not the content of the object:

const map = new Map()
const key = { a: 1 }
map.set(key, true)

map.get(key) !== map.get({ a: 1 }) // true

Copy link
Owner

Choose a reason for hiding this comment

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

Yeah that's a problem given how image sources are defined. I guess we're stuck with stringifying for now

uri = source;
} else if (source && typeof source.uri === 'string') {
uri = source.uri;
const getCacheUrl = e => {
Copy link
Owner

Choose a reason for hiding this comment

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

This looks a bit fragile. Why do we need to get the url from the native event?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If an image is loaded via XHR, the actual image src will be replaced by a blob:

image.src = window.URL.createObjectURL(request.response);

Since the onload event is triggered by the image itself, we can retrieve the new blob source in Image via the image src in the event handler without passing additional parameters. Though, of course we could also make this more explicit and pass the event and the new blob url as separate parameters in onLoad. What do you prefer?

Copy link
Owner

Choose a reason for hiding this comment

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

Can we store the blob when we get it, so we don't have to read it back from the native event?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, the blob will be stored once the image was loaded:

ImageUriCache.add(source, getCacheUrl(e));

Afterwards it shouldn't be triggered again as long as the source does not change. Or do you mean something else?

Copy link
Owner

Choose a reason for hiding this comment

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

I'm wondering why we need to get the blob from the event object when we know what it is before that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just reworked that part and now the blob is returned directly from the ImageLoader.

@matthewwillian

This comment has been minimized.

@jaulz
Copy link
Contributor Author

jaulz commented Dec 2, 2019

@necolas I am just back from vacation and saw that there are conflicting files. Though, I don't see any changes in the affected files and am not sure why it says there are conflicts. Any idea what's wrong here?

@necolas
Copy link
Owner

necolas commented Feb 10, 2020

The conflicts are because the docs were rewritten. And now there is also a7ab961

@necolas
Copy link
Owner

necolas commented Apr 10, 2023

#2442 is a contemporary fix for this. Thanks

@necolas necolas closed this Apr 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants