mattermost-mobile/ios/MattermostShare/ViewModels/ShareViewModel.swift
Elias Nahum d61fbd3180
Various fixes (#7161)
* Save message draft when post input is unmounted

* Fix switch CRT on/off

* Handle iPad on Stage Manager

* iOS Share Extension to use LRU cache instead of file cache

* Support building android as aab

* use handleReconnect instead of appEntry on handleCRTToggled

* show skin tone selector tutorial after running all interactions

* Update app/actions/remote/preference.ts

Co-authored-by: Daniel Espino García <larkox@gmail.com>

* fix lint

---------

Co-authored-by: Daniel Espino García <larkox@gmail.com>
2023-02-24 13:02:05 +02:00

112 lines
3.4 KiB
Swift

//
// ShareViewModel.swift
// MattermostShare
//
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
//
import Foundation
import Combine
import Gekidou
import SwiftUI
import UIKit
class ShareViewModel: ObservableObject {
@Published var server: ServerModel?
@Published var allServers: [ServerModel] = []
@Published var channel: ChannelModel?
@Published var allChannels: [ChannelModel] = []
@Published var search: String = ""
private let serverService: ServerService = ServerService()
private let channelService: ChannelService = ChannelService()
private let fileManager = LocalFileManager()
private var cancellables = Set<AnyCancellable>()
init() {
addSubscribers()
}
private func addSubscribers() {
// Selected server
serverService.$selected
.sink {[weak self] (server) in
self?.server = server
if let url = server?.url {
self?.channelService.setServerUrl(url)
self?.search = ""
}
}
.store(in: &cancellables)
// All active servers
serverService.$servers
.sink {[weak self] (servers) in
self?.allServers = servers
}
.store(in: &cancellables)
channelService.$selected
.sink{ [weak self] channel in
self?.channel = channel
self?.search = ""
}
.store(in: &cancellables)
$search
.debounce(for: .seconds(0.2), scheduler: DispatchQueue.main)
.map { (text) -> [ChannelModel] in
guard !text.isEmpty else {
return self.channelService.channels
}
let channels: [ChannelModel] = self.channelService.searchChannels(text)
return channels
}
.sink {[weak self] channels in
self?.allChannels = channels
}
.store(in: &cancellables)
}
public func selectServer(_ server: ServerModel) {
serverService.selected = server
}
public func selectChannel(_ channel: ChannelModel) {
channelService.selected = channel
}
func getProfileImage(serverUrl: String, userId: String, imageBinding: Binding<UIImage?>) {
var lastUpdateAt: Double = 0
if let updateAt = Gekidou.Database.default.getUserLastPictureAt(for: userId, forServerUrl: serverUrl) {
lastUpdateAt = updateAt
}
if let data = Gekidou.ImageCache.default.image(for: userId, updatedAt: lastUpdateAt, forServer: serverUrl) {
imageBinding.wrappedValue = UIImage(data: data)
} else {
downloadProfileImage(serverUrl: serverUrl, userId: userId, lastUpdateAt: lastUpdateAt, imageBinding: imageBinding)
}
}
func downloadProfileImage(serverUrl: String, userId: String, lastUpdateAt: Double, imageBinding: Binding<UIImage?>) {
guard let _ = URL(string: serverUrl) else {
debugPrint("Missing or Malformed URL")
return
}
Gekidou.Network.default.fetchUserProfilePicture(userId: userId, lastUpdateAt: lastUpdateAt, forServerUrl: serverUrl, completionHandler: {data, response, error in
guard (response as? HTTPURLResponse)?.statusCode == 200 else {
debugPrint("Error while fetching image \(String(describing: (response as? HTTPURLResponse)?.statusCode))")
return
}
if let data = data {
let image = UIImage(data: data)
imageBinding.wrappedValue = image
Gekidou.ImageCache.default.insertImage(data, for: userId, updatedAt: lastUpdateAt, forServer: serverUrl)
}
})
}
}