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

Loading an image with Styler #258

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

MrWoWander
Copy link

Added the ability to download an image from the markdown using the Styler class

@MrWoWander MrWoWander changed the title Downloading an Image into Styler Loading an image with Styler May 25, 2021
@codecov
Copy link

codecov bot commented May 25, 2021

Codecov Report

Merging #258 (2745a14) into master (bf24fcb) will decrease coverage by 7.13%.
The diff coverage is 2.12%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #258      +/-   ##
==========================================
- Coverage   91.31%   84.17%   -7.14%     
==========================================
  Files          60       61       +1     
  Lines        1059     1150      +91     
==========================================
+ Hits          967      968       +1     
- Misses         92      182      +90     
Impacted Files Coverage Δ
...rces/Down/AST/Styling/Stylers/AsyncImageLoad.swift 0.00% <0.00%> (ø)
Sources/Down/AST/Styling/Stylers/DownStyler.swift 93.24% <22.22%> (-3.24%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bf24fcb...2745a14. Read the comment docs.

@MrWoWander
Copy link
Author

I cannot yet add testing, as Codecov asks for it, since I don’t understand how testing works in your project.
This code works for me (in my project I inherited from the DownStyler class)

image

@johnxnguyen
Copy link
Owner

Hi @MrWoWander , thanks for the pull request! I'll take a look at this soon and get back to you.

@MrWoWander
Copy link
Author

And the question arose: is it necessary to make a function that will automatically resize the image if it is larger than the device's resolution in width?

@MrWoWander
Copy link
Author

For iOS, I did this:

extension UIImage {
    
    func scalePreservingAspectRatio(width: CGFloat) -> UIImage {
        let widthRatio = size.width / width
        let heightRatio = size.height / widthRatio
        
        // Compute the new image size that preserves aspect ratio
        let scaledImageSize = CGSize(
            width: width,
            height: heightRatio
        )
        
        // Draw and return the resized UIImage
        let renderer = UIGraphicsImageRenderer(
            size: scaledImageSize
        )
        
        let scaledImage = renderer.image { _ in
            self.draw(in: CGRect(
                origin: .zero,
                size: scaledImageSize
            ))
        }
        
        return scaledImage
    }
}

I personally use Down in conjunction with SwiftUI and while working in VStack, the picture crawls out of the edges of the screen. This method allows you to solve this problem.

@MrWoWander
Copy link
Author

I also noticed that GIF images don't work. They are static. I'll try to come up with some solution

@johnxnguyen
Copy link
Owner

@MrWoWander sorry for the delay in reviewing this, it's been a busy past week. I'm planning to take a look at tonight.

Sources/Down/AST/Styling/Stylers/DownStyler.swift Outdated Show resolved Hide resolved
Comment on lines 225 to 226
URLSession.shared.dataTask(with: url) { data, _, _ in
if let data = data {
Copy link
Owner

Choose a reason for hiding this comment

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

A couple things:

  1. What happens when the url doesn't point to an image?
  2. What happens when there is a network error?
  3. I think it's important to make image fetching an optional behavior (preferably opt in) since users of the library may not want to automatically fetch data from unknown urls. This could be achieved with a simple flag in the styler configuration.

@johnxnguyen
Copy link
Owner

And the question arose: is it necessary to make a function that will automatically resize the image if it is larger than the device's resolution in width?

I think it would be good to limit the size of the image to fit within the view that contains the string.

I cannot yet add testing, as Codecov asks for it, since I don’t understand how testing works in your project.

I use snapshot tests to assert the styling methods. In the case of images, you could probably add a test image and get the url of that resource. I think it would be good to have several tests to assert various cases of images, such as small images, large images, and invalid urls.

@MrWoWander
Copy link
Author

@johnxnguyen, ok, I'll try in the coming days to think about replacing semaphore and handling URL requests, with the option to prohibit downloading and downloading from local paths

I will also add a reduction in the size of the images

@MrWoWander MrWoWander closed this Jun 2, 2021
@MrWoWander MrWoWander reopened this Jun 2, 2021
@johnxnguyen
Copy link
Owner

@MrWoWander let me know if you need help, I'm happy to discuss ideas and problems together!

@MrWoWander
Copy link
Author

@johnxnguyen
It seems that asynchronous loading of the image should work while viewing markdown

Please check it out. If it works the way you wanted, then I will already make the error handler and the rest of the functionality that we discussed

@MrWoWander
Copy link
Author

In some cases, I did not have time to download images in the SwiftUI view, so I added a delegate that allows me to update the view

Copy link
Owner

@johnxnguyen johnxnguyen left a comment

Choose a reason for hiding this comment

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

Generally it looks fine to me, just have a few comments.

func textAttachmentDidLoadImage(textAttachment: AsyncImageLoad, displaySizeChanged: Bool)
}

final public class AsyncImageLoad: NSTextAttachment
Copy link
Owner

Choose a reason for hiding this comment

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

Does this need to be public?

Copy link
Owner

Choose a reason for hiding this comment

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

Name suggestion: AsyncImageAttachment


final public class AsyncImageLoad: NSTextAttachment
{
public var imageURL: URL?
Copy link
Owner

Choose a reason for hiding this comment

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

Does this need to be optional?


public var maximumDisplayWidth: CGFloat?

public var delegate: AsyncImageLoadDelegate?
Copy link
Owner

Choose a reason for hiding this comment

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

Shouldn't this delegate be ��weak?

{
let imageSize = image.size

if self.displaySize == nil
Copy link
Owner

Choose a reason for hiding this comment

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

Is the purpose of displaySize to allow an explicit size to be set for the image, rather than it's actual size?

// find character range for this attachment
let range = NSRange(location: 0, length: attributedString.length)

var refreshRanges = [NSRange]()
Copy link
Owner

Choose a reason for hiding this comment

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

Would we ever expect to find more than one range for a single attachment?

}

/// Trigger a relayout for an attachment
public func setNeedsLayout(forAttachment attachment: NSTextAttachment)
Copy link
Owner

Choose a reason for hiding this comment

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

Does this need to be public?

@@ -40,10 +40,12 @@ open class DownStyler: Styler {
.font: fonts.listItemPrefix,
.foregroundColor: colors.listItemPrefix]
}

private var delegate: AsyncImageLoadDelegate?
Copy link
Owner

Choose a reason for hiding this comment

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

Name suggestion: asyncImageAttachmentDelegate

Comment on lines +227 to +228
let image1Attachment = AsyncImageLoad(imageURL: url, delegate: delegate)
let image1String = NSAttributedString(attachment: image1Attachment)
Copy link
Owner

Choose a reason for hiding this comment

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

Name suggestions: attachment, and attachmentString

Comment on lines +193 to +194
guard let url = url,
let urlImg = URL(string: url) else { return }
Copy link
Owner

Choose a reason for hiding this comment

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

Suggestion:

guard let imageURL = url.flatMap(URL.init) else { return }

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.

None yet

2 participants