Notifications (#275)

This commit is contained in:
ismailgulek
2022-11-21 19:37:13 +03:00
committed by GitHub
parent 9f3ed6ca7b
commit d389ce7ad7
74 changed files with 2459 additions and 324 deletions
@@ -18,26 +18,26 @@ import Kingfisher
import UIKit
struct MediaProvider: MediaProviderProtocol {
private let clientProxy: ClientProxyProtocol
private let mediaProxy: MediaProxyProtocol
private let imageCache: Kingfisher.ImageCache
private let fileCache: FileCache
private let backgroundTaskService: BackgroundTaskServiceProtocol
private let backgroundTaskService: BackgroundTaskServiceProtocol?
init(clientProxy: ClientProxyProtocol,
init(mediaProxy: MediaProxyProtocol,
imageCache: Kingfisher.ImageCache,
fileCache: FileCache,
backgroundTaskService: BackgroundTaskServiceProtocol) {
self.clientProxy = clientProxy
backgroundTaskService: BackgroundTaskServiceProtocol?) {
self.mediaProxy = mediaProxy
self.imageCache = imageCache
self.fileCache = fileCache
self.backgroundTaskService = backgroundTaskService
}
func imageFromSource(_ source: MediaSource?, avatarSize: AvatarSize?) -> UIImage? {
func imageFromSource(_ source: MediaSourceProxy?, avatarSize: AvatarSize?) -> UIImage? {
guard let source else {
return nil
}
let cacheKey = cacheKeyForURLString(source.underlyingSource.url(), avatarSize: avatarSize)
let cacheKey = cacheKeyForURLString(source.url, avatarSize: avatarSize)
return imageCache.retrieveImageInMemoryCache(forKey: cacheKey, options: nil)
}
@@ -46,19 +46,19 @@ struct MediaProvider: MediaProviderProtocol {
return nil
}
return imageFromSource(MediaSource(source: clientProxy.mediaSourceForURLString(urlString)), avatarSize: avatarSize)
return imageFromSource(.init(urlString: urlString), avatarSize: avatarSize)
}
func loadImageFromURLString(_ urlString: String, avatarSize: AvatarSize?) async -> Result<UIImage, MediaProviderError> {
await loadImageFromSource(MediaSource(source: clientProxy.mediaSourceForURLString(urlString)), avatarSize: avatarSize)
await loadImageFromSource(.init(urlString: urlString), avatarSize: avatarSize)
}
func loadImageFromSource(_ source: MediaSource, avatarSize: AvatarSize?) async -> Result<UIImage, MediaProviderError> {
func loadImageFromSource(_ source: MediaSourceProxy, avatarSize: AvatarSize?) async -> Result<UIImage, MediaProviderError> {
if let image = imageFromSource(source, avatarSize: avatarSize) {
return .success(image)
}
let loadImageBgTask = await backgroundTaskService.startBackgroundTask(withName: "LoadImage: \(source.url.hashValue)")
let loadImageBgTask = await backgroundTaskService?.startBackgroundTask(withName: "LoadImage: \(source.url.hashValue)")
defer {
loadImageBgTask?.stop()
}
@@ -73,9 +73,9 @@ struct MediaProvider: MediaProviderProtocol {
do {
let imageData: Data
if let avatarSize {
imageData = try await clientProxy.loadMediaThumbnailForSource(source.underlyingSource, width: UInt(avatarSize.scaledValue), height: UInt(avatarSize.scaledValue))
imageData = try await mediaProxy.loadMediaThumbnailForSource(source, width: UInt(avatarSize.scaledValue), height: UInt(avatarSize.scaledValue))
} else {
imageData = try await clientProxy.loadMediaContentForSource(source.underlyingSource)
imageData = try await mediaProxy.loadMediaContentForSource(source)
}
guard let image = UIImage(data: imageData) else {
@@ -92,20 +92,20 @@ struct MediaProvider: MediaProviderProtocol {
}
}
func fileFromSource(_ source: MediaSource?, fileExtension: String) -> URL? {
func fileFromSource(_ source: MediaSourceProxy?, fileExtension: String) -> URL? {
guard let source else {
return nil
}
let cacheKey = fileCacheKeyForURLString(source.underlyingSource.url())
let cacheKey = fileCacheKeyForURLString(source.url)
return fileCache.file(forKey: cacheKey, fileExtension: fileExtension)
}
@discardableResult func loadFileFromSource(_ source: MediaSource, fileExtension: String) async -> Result<URL, MediaProviderError> {
@discardableResult func loadFileFromSource(_ source: MediaSourceProxy, fileExtension: String) async -> Result<URL, MediaProviderError> {
if let url = fileFromSource(source, fileExtension: fileExtension) {
return .success(url)
}
let loadFileBgTask = await backgroundTaskService.startBackgroundTask(withName: "LoadFile: \(source.url.hashValue)")
let loadFileBgTask = await backgroundTaskService?.startBackgroundTask(withName: "LoadFile: \(source.url.hashValue)")
defer {
loadFileBgTask?.stop()
}
@@ -113,7 +113,7 @@ struct MediaProvider: MediaProviderProtocol {
let cacheKey = fileCacheKeyForURLString(source.url)
do {
let data = try await clientProxy.loadMediaContentForSource(source.underlyingSource)
let data = try await mediaProxy.loadMediaContentForSource(source)
let url = try fileCache.store(data, with: fileExtension, forKey: cacheKey)
return .success(url)
@@ -128,12 +128,12 @@ struct MediaProvider: MediaProviderProtocol {
return nil
}
return fileFromSource(MediaSource(source: clientProxy.mediaSourceForURLString(urlString)),
return fileFromSource(MediaSourceProxy(urlString: urlString),
fileExtension: fileExtension)
}
func loadFileFromURLString(_ urlString: String, fileExtension: String) async -> Result<URL, MediaProviderError> {
await loadFileFromSource(MediaSource(source: clientProxy.mediaSourceForURLString(urlString)),
await loadFileFromSource(MediaSourceProxy(urlString: urlString),
fileExtension: fileExtension)
}
@@ -24,17 +24,17 @@ enum MediaProviderError: Error {
}
protocol MediaProviderProtocol {
func imageFromSource(_ source: MediaSource?, avatarSize: AvatarSize?) -> UIImage?
func imageFromSource(_ source: MediaSourceProxy?, avatarSize: AvatarSize?) -> UIImage?
@discardableResult func loadImageFromSource(_ source: MediaSource, avatarSize: AvatarSize?) async -> Result<UIImage, MediaProviderError>
@discardableResult func loadImageFromSource(_ source: MediaSourceProxy, avatarSize: AvatarSize?) async -> Result<UIImage, MediaProviderError>
func imageFromURLString(_ urlString: String?, avatarSize: AvatarSize?) -> UIImage?
@discardableResult func loadImageFromURLString(_ urlString: String, avatarSize: AvatarSize?) async -> Result<UIImage, MediaProviderError>
func fileFromSource(_ source: MediaSource?, fileExtension: String) -> URL?
func fileFromSource(_ source: MediaSourceProxy?, fileExtension: String) -> URL?
@discardableResult func loadFileFromSource(_ source: MediaSource, fileExtension: String) async -> Result<URL, MediaProviderError>
@discardableResult func loadFileFromSource(_ source: MediaSourceProxy, fileExtension: String) async -> Result<URL, MediaProviderError>
func fileFromURLString(_ urlString: String?, fileExtension: String) -> URL?
@@ -42,11 +42,11 @@ protocol MediaProviderProtocol {
}
extension MediaProviderProtocol {
func imageFromSource(_ source: MediaSource?) -> UIImage? {
func imageFromSource(_ source: MediaSourceProxy?) -> UIImage? {
imageFromSource(source, avatarSize: nil)
}
@discardableResult func loadImageFromSource(_ source: MediaSource) async -> Result<UIImage, MediaProviderError> {
@discardableResult func loadImageFromSource(_ source: MediaSourceProxy) async -> Result<UIImage, MediaProviderError> {
await loadImageFromSource(source, avatarSize: nil)
}
@@ -0,0 +1,49 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Combine
import Foundation
import MatrixRustSDK
import UIKit
class MediaProxy: MediaProxyProtocol {
private let client: ClientProtocol
private let clientQueue: DispatchQueue
init(client: ClientProtocol,
clientQueue: DispatchQueue = .global()) {
self.client = client
self.clientQueue = clientQueue
}
func mediaSourceForURLString(_ urlString: String) -> MediaSourceProxy {
.init(urlString: urlString)
}
func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data {
try await Task.dispatch(on: clientQueue) {
let bytes = try self.client.getMediaContent(source: source.underlyingSource)
return Data(bytes: bytes, count: bytes.count)
}
}
func loadMediaThumbnailForSource(_ source: MediaSourceProxy, width: UInt, height: UInt) async throws -> Data {
try await Task.dispatch(on: clientQueue) {
let bytes = try self.client.getMediaThumbnail(source: source.underlyingSource, width: UInt64(width), height: UInt64(height))
return Data(bytes: bytes, count: bytes.count)
}
}
}
@@ -0,0 +1,25 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
protocol MediaProxyProtocol {
func mediaSourceForURLString(_ urlString: String) -> MediaSourceProxy
func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data
func loadMediaThumbnailForSource(_ source: MediaSourceProxy, width: UInt, height: UInt) async throws -> Data
}
@@ -17,24 +17,24 @@
import Foundation
import MatrixRustSDK
struct MediaSource: Equatable {
let underlyingSource: MatrixRustSDK.MediaSource
struct MediaSourceProxy: Equatable {
let underlyingSource: MediaSource
init(source: MediaSource) {
underlyingSource = source
}
init(urlString: String) {
underlyingSource = mediaSourceFromUrl(url: urlString)
}
var url: String {
underlyingSource.url()
}
init(source: MatrixRustSDK.MediaSource) {
underlyingSource = source
}
init(urlString: String) {
underlyingSource = MatrixRustSDK.mediaSourceFromUrl(url: urlString)
}
// MARK: - Equatable
static func == (lhs: MediaSource, rhs: MediaSource) -> Bool {
lhs.underlyingSource.url() == rhs.underlyingSource.url()
static func == (lhs: MediaSourceProxy, rhs: MediaSourceProxy) -> Bool {
lhs.url == rhs.url
}
}
@@ -18,11 +18,11 @@ import Foundation
import UIKit
struct MockMediaProvider: MediaProviderProtocol {
func imageFromSource(_ source: MediaSource?, avatarSize: AvatarSize?) -> UIImage? {
func imageFromSource(_ source: MediaSourceProxy?, avatarSize: AvatarSize?) -> UIImage? {
nil
}
func loadImageFromSource(_ source: MediaSource, avatarSize: AvatarSize?) async -> Result<UIImage, MediaProviderError> {
func loadImageFromSource(_ source: MediaSourceProxy, avatarSize: AvatarSize?) async -> Result<UIImage, MediaProviderError> {
.failure(.failedRetrievingImage)
}
@@ -50,11 +50,11 @@ struct MockMediaProvider: MediaProviderProtocol {
return .success(image)
}
func fileFromSource(_ source: MediaSource?, fileExtension: String) -> URL? {
func fileFromSource(_ source: MediaSourceProxy?, fileExtension: String) -> URL? {
nil
}
@discardableResult func loadFileFromSource(_ source: MediaSource, fileExtension: String) async -> Result<URL, MediaProviderError> {
@discardableResult func loadFileFromSource(_ source: MediaSourceProxy, fileExtension: String) async -> Result<URL, MediaProviderError> {
.failure(.failedRetrievingFile)
}