-
-
Notifications
You must be signed in to change notification settings - Fork 21
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
IImageSourceHandler impl #70
Conversation
Please accept this PR because of followings: 1- I know this works for UriImageSources and it's not working for other image source types, but UriImageSource is more important because it needs authentication in some scenarios and if we pass custom IGlideHandler which adds required request headers, at least everything works (Image and ImageView and UriImageSource will gets handled by Glide and StreamImageSource and FileImageSource will gets handled by XF which is not high performant, but at least works!) 2- After XF fixes issues described here, our ImageSourceHandler will handle all ImageSource types without releasing new version of glidex.forms which improves xf apps performance even more! |
@ysmoradi Why can't Xamarin.Forms just always call |
From this perspective, IImageSourceHandler interface is useless. IImageViewHandler => For Image & ImageButtons But, as I'm not completly in and have no idea for all historical descicions, I'm happy to ask them about this. I'll open an issue in xamarin forms tomorrow Thanks for paying attention |
@roubachof Do you have any idea about this? |
@daniel-luberda Do you have any idea about this? |
@jonathanpeppers I've submitted an issue to XF |
@ysmoradi did you send a PR to Xamarin.Forms to fix it? |
@jonathanpeppers I've submitted an issue. I'm fine with PR too, but first of all, someone should give me basic understanding on XF image handling structure! It's totally unclear! Look at GlideX.Forms | Nuke | FFImageLoading: I'm an active person on GitHub as you can see on my profile, and I've submitted lots of PRs to several repositories. But I can't reverse engineering entire codes to submit a PR, and at the end someone says "hey! your assumptions were wrong!" A good PR comes with an good issue first! |
I see a few details are provided in my issue, I try to submit a PR, but can't give my word |
Useful improvements from PR #70
if (builder is null) { | ||
return null; | ||
} else { | ||
var result = await builder.Submit ().GetAsync (); |
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 isn't the proper way to await an IFuture
with cancellation. This should be something like:
var result = await builder.Submit ().GetAsync (); | |
var future = builder.Submit (); | |
var result = await Task.Run (() => future.Get (), token); |
return null; | ||
} else { | ||
var result = await builder.Submit ().GetAsync (); | ||
return (Bitmap) result; |
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 code throws InvalidCastException
because result
is BitmapDrawable
!
return (Bitmap) result; | |
if (result is BitmapDrawable drawable) | |
return drawable.Bitmap; |
switch (source) { | ||
case FileImageSource fileSource: | ||
var fileName = fileSource.File; | ||
var drawable = ResourceManager.GetDrawableByName (fileName); | ||
if (drawable != 0) { | ||
Forms.Debug ("Loading `{0}` as an Android resource", fileName); | ||
builder = request.AsBitmap ().Load (drawable); | ||
} else { | ||
Forms.Debug ("Loading `{0}` from disk", fileName); | ||
builder = request.AsBitmap ().Load (fileName); | ||
} | ||
break; | ||
|
||
case UriImageSource uriSource: | ||
var url = uriSource.Uri.OriginalString; | ||
Forms.Debug ("Loading `{0}` as a web URL", url); | ||
builder = request.AsBitmap ().Load (url); | ||
break; | ||
|
||
case StreamImageSource streamSource: | ||
Forms.Debug ("Loading `{0}` as a byte[]. Consider using `AndroidResource` instead, as it would be more performant", nameof (StreamImageSource)); | ||
using (var memoryStream = new MemoryStream ()) | ||
using (var stream = await streamSource.Stream (token)) { | ||
if (token.IsCancellationRequested || stream == null) | ||
return null; | ||
if (!IsActivityAlive (context, source)) { | ||
return null; | ||
} | ||
await stream.CopyToAsync (memoryStream, token); | ||
builder = request.AsBitmap ().Load (memoryStream.ToArray ()); | ||
} | ||
break; | ||
} |
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 long switch
statement is a lot of copy-paste. This should be refactored out into smaller methods that the other LoadViaGlide()
method can share.
@@ -19,5 +19,6 @@ public interface IGlideHandler | |||
/// <param name="token">The CancellationToken if you need it</param> | |||
/// <returns>True if the image was handled. Return false if you need the image to be cleared for you.</returns> | |||
bool Build (ImageView imageView, ImageSource source, RequestBuilder builder, CancellationToken token); | |||
void Build (ImageSource source, RequestBuilder builder, CancellationToken token); |
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 should be a C# 8 default interface method, so that existing IGlideHandler
implementations won't get a compilation error.
This should also use ref RequestBuilder builder
so that IGlideHandler
's can set the builder
to null
if desired.
|
||
public async Task<Bitmap> LoadImageAsync (ImageSource source, Context context, CancellationToken token = default) | ||
{ | ||
Forms.Debug ("IImageViewHandler of type `{0}`, `{1}` called.", GetType (), nameof (LoadImageAsync)); |
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.
Forms.Debug ("IImageViewHandler of type `{0}`, `{1}` called.", GetType (), nameof (LoadImageAsync)); | |
Forms.Debug ("IImageSourceHandler of type `{0}`, `{1}` called.", GetType (), nameof (LoadImageAsync)); |
Closing in favor of #77, let me know if those changes will work for you. |
Thanks so much |
There are I think I want to have a fix for #71 and |
This closes #69
To test it simply add followings to MainPage.xaml
This uses Glidex.forms image handler's method which accepts ImageSource only for UriImageSources
We need another issue in XF, because it calls our handler's method for UriImageSources but it doesn't call the same method for FileImageSources and StreamImageSources )-: