Skip to content

Commit

Permalink
Merge pull request #692 from NoodleOfDeath/dev
Browse files Browse the repository at this point in the history
~media
  • Loading branch information
NoodleOfDeath authored Oct 15, 2023
2 parents 09cad91 + 3d7ec3b commit 6c296b7
Show file tree
Hide file tree
Showing 123 changed files with 5,324 additions and 613 deletions.
41 changes: 19 additions & 22 deletions src/mobile/ios/Extensions/Image.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,43 @@
//

import Foundation
import CoreGraphics
import SwiftUI

public extension Image {

static func loadAsync(from string: String, maxWidth: CGFloat? = nil) async -> Image? {
guard let url = URL(string: string) else { return nil }
return await self.loadAsync(from: url, maxWidth: maxWidth)
}

static func loadAsync(from url: URL?, maxWidth: CGFloat? = nil) async -> Image? {
guard let url = url else { return nil }
let request = URLRequest(url: url)
guard let (data, _) = try? await URLSession.shared.data(for: request) else { return nil }
guard let image = UIImage(data: data) else { return nil }
if let maxWidth = maxWidth, let image = image.resized(toWidth: maxWidth) {
return Image(uiImage: image)
}
return Image(uiImage: image)
static func load(from imageURL: URL, maxWidth: CGFloat) -> Image? {
guard let uiImage = UIImage.load(from: imageURL, maxWidth: maxWidth) else { return nil }
return Image(uiImage: uiImage)
}

static func load(from string: String, maxWidth: CGFloat? = nil, completion: @escaping @Sendable (_ image: Image?) -> Void) {
static func load(from string: String, completion: @escaping @Sendable (_ image: Image?) -> Void) {
guard let imageUrl = URL(string: string) else { return }
return self.load(from: imageUrl, completion: completion)
}

static func load(from url: URL?, maxWidth: CGFloat? = nil, completion: @escaping @Sendable (_ image: Image?) -> Void) {
static func load(from url: URL?, completion: @escaping @Sendable (_ image: Image?) -> Void) {
guard let url = url else {
completion(nil)
return
}
URLSession.shared.dataTask(with: url) { data, _, error in
if let data = data, let image = UIImage(data: data) {
if let maxWidth = maxWidth, let image = image.resized(toWidth: maxWidth) {
completion(Image(uiImage: image))
} else {
completion(Image(uiImage: image))
}
completion(Image(uiImage: image))
}
}.resume()
}

static func loadAsync(from string: String) async -> Image? {
guard let url = URL(string: string) else { return nil }
return await self.loadAsync(from: url)
}

static func loadAsync(from url: URL?) async -> Image? {
guard let url = url else { return nil }
let request = URLRequest(url: url)
guard let (data, _) = try? await URLSession.shared.data(for: request) else { return nil }
guard let image = UIImage(data: data) else { return nil }
return Image(uiImage: image)
}

}
44 changes: 34 additions & 10 deletions src/mobile/ios/Extensions/UIImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,44 @@
//

import Foundation
import ImageIO
import UIKit

extension UIImage {

func resized(toWidth width: CGFloat, isOpaque: Bool = true) -> UIImage? {
let size = CGSize(width: width, height: width / size.width * size.height)
return self.resized(toSize: size, isOpaque: isOpaque)
}

func resized(toSize size: CGSize, isOpaque: Bool = true) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, true, 1.0)
self.draw(in: CGRect(origin: .zero, size: size))
defer { UIGraphicsEndImageContext() }
return UIGraphicsGetImageFromCurrentImageContext()
static func load(from imageURL: URL, maxWidth: CGFloat) -> UIImage? {

// Create an CGImageSource that represent an image
let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
guard let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL, imageSourceOptions) else {
return nil
}

guard let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as Dictionary?,
let pixelWidth = imageProperties[kCGImagePropertyPixelWidth]?.floatValue,
let pixelHeight = imageProperties[kCGImagePropertyPixelHeight]?.floatValue
else {
return nil
}

let size = CGSize(width: maxWidth, height: maxWidth / CGFloat(pixelWidth) * CGFloat(pixelHeight))

// Calculate the desired dimension
let maxDimensionInPixels = max(size.width, size.height)

// Perform downsampling
let options = [
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceCreateThumbnailFromImageIfAbsent: true,
kCGImageSourceShouldCacheImmediately: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels
] as CFDictionary

guard let imgRef = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options) else { return nil }
return UIImage(cgImage: imgRef)
}

}


81 changes: 0 additions & 81 deletions src/mobile/ios/Models/BulkMetadataResponse.swift

This file was deleted.

31 changes: 26 additions & 5 deletions src/mobile/ios/Models/BulkResponse.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
//
// PublicOutletAttributes.swift
//
// Generated by openapi-generator
// https://openapi-generator.tech
// BulkResponse.swift
//

import Foundation
#if canImport(AnyCodable)
import AnyCodable
#endif

public struct BulkResponse<T: Codable, M: Codable>: Codable {
public struct BulkResponse<T: Codable>: Codable {

public var count: Int
public var rows: [T]

public init(count: Int, rows: [T]) {
self.count = count
self.rows = rows
}

public enum CodingKeys: String, CodingKey, CaseIterable {
case count
case rows
}

// Encodable protocol methods

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(count, forKey: .count)
try container.encode(rows, forKey: .rows)
}
}

public struct BulkMetadataResponse<T: Codable, M: Codable>: Codable {

public var count: Int
public var rows: [T]
Expand Down
3 changes: 0 additions & 3 deletions src/mobile/ios/Models/PublicCategoryAttributes.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
//
// PublicCategoryAttributes.swift
//
// Generated by openapi-generator
// https://openapi-generator.tech
//

import Foundation
#if canImport(AnyCodable)
Expand Down
3 changes: 0 additions & 3 deletions src/mobile/ios/Models/PublicPublisherAttributes.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
//
// PublicPublisherAttributes.swift
//
// Generated by openapi-generator
// https://openapi-generator.tech
//

import Foundation
#if canImport(AnyCodable)
Expand Down
31 changes: 13 additions & 18 deletions src/mobile/ios/Models/PublicSummaryAttributes.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
//
// PickSummaryAttributesExcludeKeyofSummaryAttributesRawTextOrFilteredText.swift
//
// Generated by openapi-generator
// https://openapi-generator.tech
// PublicSummaryAttributes.swift
//

import Foundation
Expand All @@ -13,7 +10,7 @@ import AnyCodable

/** From T, pick a set of properties whose keys are in the union K */
public struct PublicSummaryAttributes: Codable, Hashable {

public var id: Int
public var url: String
public var title: String
Expand All @@ -24,7 +21,7 @@ public struct PublicSummaryAttributes: Codable, Hashable {
public var media: [String: String]?
public var originalDate: Date?
public var translations: [String: String]?

public init(id: Int,
url: String,
title: String,
Expand All @@ -46,7 +43,7 @@ public struct PublicSummaryAttributes: Codable, Hashable {
self.originalDate = originalDate
self.translations = translations
}

public enum CodingKeys: String, CodingKey, CaseIterable {
case id
case url
Expand All @@ -59,9 +56,9 @@ public struct PublicSummaryAttributes: Codable, Hashable {
case originalDate
case translations
}

// Encodable protocol methods

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
Expand Down Expand Up @@ -118,13 +115,10 @@ public class Summary {
@Published public var publisherIcon: Image?

public func loadImages() {
Image.load(from: primaryImageUrl, maxWidth: 400) { self.image = $0 }
Image.load(from: publisher.icon) { self.publisherIcon = $0 }
}

public func loadImagesAsync() async {
image = await Image.loadAsync(from: primaryImageUrl, maxWidth: 400)
publisherIcon = await Image.loadAsync(from: publisher.icon)
if let url = primaryImageUrl {
image = Image.load(from: url, maxWidth: 100)
}
publisherIcon = Image.load(from: publisher.icon, maxWidth: 40)
}

}
Expand All @@ -135,9 +129,9 @@ public var MOCK_SUMMARY_1 = Summary(
url: "https://readless.ai",
title: "Summary Preview",
shortSummary: "Short Summary",
publisher: PublicPublisherAttributes(name: "cnn",
publisher: PublicPublisherAttributes(name: "cnn",
displayName: "CNN"),
category: PublicCategoryAttributes(name: "sports",
category: PublicCategoryAttributes(name: "sports",
displayName: "Sports",
icon: "basketball")
))
Expand Down Expand Up @@ -177,3 +171,4 @@ public var MOCK_SUMMARY_4 = Summary(
displayName: "politics",
icon: "bank")
))

Loading

0 comments on commit 6c296b7

Please sign in to comment.