Fix crash when opening Compose screen before account/instance is loaded

Prevents when opening the Compose screen with poor network connectivity
This commit is contained in:
Shadowfacts 2020-09-21 18:04:08 -04:00
parent 9b85090884
commit 809584cc54
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
5 changed files with 55 additions and 36 deletions

View File

@ -9,7 +9,7 @@
import Foundation
import Pachyderm
class MastodonController {
class MastodonController: ObservableObject {
static private(set) var all = [LocalData.UserAccountInfo: MastodonController]()
@ -42,8 +42,8 @@ class MastodonController {
let client: Client!
var account: Account!
var instance: Instance!
@Published private(set) var account: Account!
@Published private(set) var instance: Instance!
var loggedIn: Bool {
accountInfo != nil
@ -95,7 +95,9 @@ class MastodonController {
completion?(.failure(error))
case let .success(account, _):
self.account = account
DispatchQueue.main.async {
self.account = account
}
self.persistentContainer.backgroundContext.perform {
if let accountMO = self.persistentContainer.account(for: account.id, in: self.persistentContainer.backgroundContext) {
accountMO.updateFrom(apiAccount: account, container: self.persistentContainer)
@ -118,13 +120,12 @@ class MastodonController {
let request = Client.getInstance()
run(request) { (response) in
guard case let .success(instance, _) = response else { fatalError() }
self.instance = instance
completion?(instance)
DispatchQueue.main.async {
self.instance = instance
completion?(instance)
}
}
}
}
}
// ObservableObject so that SwiftUI views can receive it through @EnvironmentObject
extension MastodonController: ObservableObject {}

View File

@ -91,7 +91,9 @@ struct ComposeAttachmentsList: View {
}
private var canAddAttachment: Bool {
switch mastodonController.instance.instanceType {
switch mastodonController.instance?.instanceType {
case nil:
return false
case .pleroma:
return true
case .mastodon:

View File

@ -9,7 +9,7 @@
import SwiftUI
struct ComposeAvatarImageView: View {
let url: URL
let url: URL?
@State var request: ImageCache.Request? = nil
@State var avatarImage: UIImage? = nil
@ObservedObject var preferences = Preferences.shared
@ -19,7 +19,9 @@ struct ComposeAvatarImageView: View {
.resizable()
.frame(width: 50, height: 50)
.cornerRadius(preferences.avatarStyle.cornerRadiusFraction * 50)
.onAppear(perform: self.loadImage)
.conditionally(url != nil) {
$0.onAppear(perform: self.loadImage)
}
.onDisappear(perform: self.cancelRequest)
}
@ -27,24 +29,33 @@ struct ComposeAvatarImageView: View {
if let avatarImage = avatarImage {
return Image(uiImage: avatarImage)
} else {
let imageName: String
switch preferences.avatarStyle {
case .circle:
imageName = "person.crop.circle"
case .roundRect:
imageName = "person.crop.square"
}
return Image(systemName: imageName)
return placeholderImage
}
}
private var placeholderImage: Image {
let imageName: String
switch preferences.avatarStyle {
case .circle:
imageName = "person.crop.circle"
case .roundRect:
imageName = "person.crop.square"
}
return Image(systemName: imageName)
}
private func loadImage() {
guard let url = url else { return }
request = ImageCache.avatars.get(url) { (data) in
DispatchQueue.main.async {
self.request = nil
if let data = data, let image = UIImage(data: data) {
if let data = data, let image = UIImage(data: data) {
DispatchQueue.main.async {
self.request = nil
self.avatarImage = image
}
} else {
DispatchQueue.main.async {
self.request = nil
}
}
}
}

View File

@ -12,24 +12,29 @@ import Pachyderm
struct ComposeCurrentAccount: View {
@EnvironmentObject var mastodonController: MastodonController
var account: Account {
mastodonController.account!
var account: Account? {
mastodonController.account
}
var body: some View {
HStack(alignment: .top) {
ComposeAvatarImageView(url: account.avatar)
.accessibility(label: Text("\(account.displayName) avatar"))
ComposeAvatarImageView(url: account?.avatar)
.accessibility(label: Text(account != nil ? "\(account!.displayName) avatar" : "Avatar"))
VStack(alignment: .leading) {
AccountDisplayNameLabel(account: mastodonController.persistentContainer.account(for: account.id)!, fontSize: 20)
.lineLimit(1)
Text(verbatim: "@\(account.acct)")
.font(.system(size: 17, weight: .light))
.foregroundColor(.secondary)
.lineLimit(1)
if let id = account?.id,
let account = mastodonController.persistentContainer.account(for: id) {
VStack(alignment: .leading) {
AccountDisplayNameLabel(account: account, fontSize: 20)
.lineLimit(1)
Text(verbatim: "@\(account.acct)")
.font(.system(size: 17, weight: .light))
.foregroundColor(.secondary)
.lineLimit(1)
}
}
Spacer()
}
}
}

View File

@ -28,7 +28,7 @@ struct ComposeView: View {
}
var charactersRemaining: Int {
let limit = mastodonController.instance.maxStatusCharacters ?? 500
let limit = mastodonController.instance?.maxStatusCharacters ?? 500
let cwCount = draft.contentWarningEnabled ? draft.contentWarning.count : 0
return limit - (cwCount + CharacterCounter.count(text: draft.text))
}