-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Conversation
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 |
@necolas great! 😊 I just fixed some minor issues and now all tests are running fine. Also, I added the |
|
||
export default class ImageUriCache { | ||
static _maximumEntries: number = 256; | ||
static _entries = {}; | ||
|
||
static has(uri: string) { | ||
static createCacheId(source: ImageSource) { | ||
return JSON.stringify(ImageLoader.resolveSource(source)); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 => { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
.
This comment has been minimized.
This comment has been minimized.
@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? |
The conflicts are because the docs were rewritten. And now there is also a7ab961 |
#2442 is a contemporary fix for this. Thanks |
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.
Please let me know if anything is missing.