Compare commits
4 Commits
4719342a06
...
14e8c11f02
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 14e8c11f02 | |
Shadowfacts | 9d9ea565f1 | |
Shadowfacts | 99db842411 | |
Shadowfacts | 184fe49c0f |
|
@ -1,5 +1,12 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2020.1 (10)
|
||||||
|
This build is a hotfix for a couple pressing issues. The changelog for the previous build is included below.
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
- Fix crash when opening Preferences while signed in with a deleted account
|
||||||
|
- Fix visibility and content warning not being copied when replying to a post
|
||||||
|
|
||||||
## 2020.1 (9)
|
## 2020.1 (9)
|
||||||
The marquee feature of this build is the new and improved Compose screen. It's been rewritten to use SwiftUI, is significantly more resilient to data loss, and now shows the toolbar when the main text field is not focused. It also turns out Apple is surprise-releasing iOS 14 very soon (or possibly already has, depending when you're reading this). For those who were not already on the beta train, iOS 14 brings a number of new features including a sidebar on iPadOS and lots and lots of context menus (a home screen widget is coming Soon™).
|
The marquee feature of this build is the new and improved Compose screen. It's been rewritten to use SwiftUI, is significantly more resilient to data loss, and now shows the toolbar when the main text field is not focused. It also turns out Apple is surprise-releasing iOS 14 very soon (or possibly already has, depending when you're reading this). For those who were not already on the beta train, iOS 14 brings a number of new features including a sidebar on iPadOS and lots and lots of context menus (a home screen widget is coming Soon™).
|
||||||
|
|
||||||
|
|
|
@ -2229,7 +2229,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 9;
|
CURRENT_PROJECT_VERSION = 10;
|
||||||
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
||||||
INFOPLIST_FILE = Tusker/Info.plist;
|
INFOPLIST_FILE = Tusker/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||||
|
@ -2258,7 +2258,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 9;
|
CURRENT_PROJECT_VERSION = 10;
|
||||||
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
DEVELOPMENT_TEAM = V4WK9KR9U2;
|
||||||
INFOPLIST_FILE = Tusker/Info.plist;
|
INFOPLIST_FILE = Tusker/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||||
|
|
|
@ -84,23 +84,28 @@ class MastodonController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOwnAccount(completion: ((Account) -> Void)? = nil) {
|
func getOwnAccount(completion: ((Result<Account, Client.Error>) -> Void)? = nil) {
|
||||||
if account != nil {
|
if account != nil {
|
||||||
completion?(account)
|
completion?(.success(account))
|
||||||
} else {
|
} else {
|
||||||
let request = Client.getSelfAccount()
|
let request = Client.getSelfAccount()
|
||||||
run(request) { response in
|
run(request) { response in
|
||||||
guard case let .success(account, _) = response else { fatalError() }
|
switch response {
|
||||||
self.account = account
|
case let .failure(error):
|
||||||
self.persistentContainer.backgroundContext.perform {
|
completion?(.failure(error))
|
||||||
if let accountMO = self.persistentContainer.account(for: account.id, in: self.persistentContainer.backgroundContext) {
|
|
||||||
accountMO.updateFrom(apiAccount: account, container: self.persistentContainer)
|
case let .success(account, _):
|
||||||
} else {
|
self.account = account
|
||||||
// the first time the user's account is added to the store,
|
self.persistentContainer.backgroundContext.perform {
|
||||||
// increment its reference count so that it's never removed
|
if let accountMO = self.persistentContainer.account(for: account.id, in: self.persistentContainer.backgroundContext) {
|
||||||
self.persistentContainer.addOrUpdate(account: account, incrementReferenceCount: true)
|
accountMO.updateFrom(apiAccount: account, container: self.persistentContainer)
|
||||||
|
} else {
|
||||||
|
// the first time the user's account is added to the store,
|
||||||
|
// increment its reference count so that it's never removed
|
||||||
|
self.persistentContainer.addOrUpdate(account: account, incrementReferenceCount: true)
|
||||||
|
}
|
||||||
|
completion?(.success(account))
|
||||||
}
|
}
|
||||||
completion?(account)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,10 +119,29 @@ extension MastodonController {
|
||||||
func createDraft(inReplyToID: String? = nil, mentioningAcct: String? = nil) -> Draft {
|
func createDraft(inReplyToID: String? = nil, mentioningAcct: String? = nil) -> Draft {
|
||||||
var acctsToMention = [String]()
|
var acctsToMention = [String]()
|
||||||
|
|
||||||
|
var visibility = Preferences.shared.defaultPostVisibility
|
||||||
|
var contentWarning = ""
|
||||||
|
|
||||||
if let inReplyToID = inReplyToID,
|
if let inReplyToID = inReplyToID,
|
||||||
let inReplyTo = persistentContainer.status(for: inReplyToID) {
|
let inReplyTo = persistentContainer.status(for: inReplyToID) {
|
||||||
acctsToMention.append(inReplyTo.account.acct)
|
acctsToMention.append(inReplyTo.account.acct)
|
||||||
acctsToMention.append(contentsOf: inReplyTo.mentions.map(\.acct))
|
acctsToMention.append(contentsOf: inReplyTo.mentions.map(\.acct))
|
||||||
|
visibility = inReplyTo.visibility
|
||||||
|
|
||||||
|
if !inReplyTo.spoilerText.isEmpty {
|
||||||
|
switch Preferences.shared.contentWarningCopyMode {
|
||||||
|
case .doNotCopy:
|
||||||
|
break
|
||||||
|
case .asIs:
|
||||||
|
contentWarning = inReplyTo.spoilerText
|
||||||
|
case .prependRe:
|
||||||
|
if inReplyTo.spoilerText.lowercased().starts(with: "re:") {
|
||||||
|
contentWarning = inReplyTo.spoilerText
|
||||||
|
} else {
|
||||||
|
contentWarning = "re: \(inReplyTo.spoilerText)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let mentioningAcct = mentioningAcct {
|
if let mentioningAcct = mentioningAcct {
|
||||||
acctsToMention.append(mentioningAcct)
|
acctsToMention.append(mentioningAcct)
|
||||||
|
@ -136,6 +155,9 @@ extension MastodonController {
|
||||||
draft.inReplyToID = inReplyToID
|
draft.inReplyToID = inReplyToID
|
||||||
draft.text = acctsToMention.map { "@\($0) " }.joined()
|
draft.text = acctsToMention.map { "@\($0) " }.joined()
|
||||||
draft.initialText = draft.text
|
draft.initialText = draft.text
|
||||||
|
draft.visibility = visibility
|
||||||
|
draft.contentWarning = contentWarning
|
||||||
|
draft.contentWarningEnabled = !contentWarning.isEmpty
|
||||||
return draft
|
return draft
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,13 +70,21 @@ extension OnboardingViewController: InstanceSelectorTableViewControllerDelegate
|
||||||
let tempAccountInfo = LocalData.UserAccountInfo(id: "temp", instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: nil, accessToken: accessToken)
|
let tempAccountInfo = LocalData.UserAccountInfo(id: "temp", instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: nil, accessToken: accessToken)
|
||||||
mastodonController.accountInfo = tempAccountInfo
|
mastodonController.accountInfo = tempAccountInfo
|
||||||
|
|
||||||
mastodonController.getOwnAccount { (account) in
|
mastodonController.getOwnAccount { (result) in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
// this needs to happen on the main thread because it publishes a new value for the ObservableObject
|
switch result {
|
||||||
let accountInfo = LocalData.shared.addAccount(instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: account.username, accessToken: accessToken)
|
case let .failure(error):
|
||||||
mastodonController.accountInfo = accountInfo
|
let alert = UIAlertController(title: "Unable to Verify Credentials", message: "Your account could not be fetched at this time: \(error.localizedDescription)", preferredStyle: .alert)
|
||||||
|
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
|
||||||
self.onboardingDelegate?.didFinishOnboarding(account: accountInfo)
|
self.present(alert, animated: true)
|
||||||
|
|
||||||
|
case let .success(account):
|
||||||
|
// this needs to happen on the main thread because it publishes a new value for the ObservableObject
|
||||||
|
let accountInfo = LocalData.shared.addAccount(instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: account.username, accessToken: accessToken)
|
||||||
|
mastodonController.accountInfo = accountInfo
|
||||||
|
|
||||||
|
self.onboardingDelegate?.didFinishOnboarding(account: accountInfo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,8 @@ struct LocalAccountAvatarView: View {
|
||||||
|
|
||||||
func loadImage() {
|
func loadImage() {
|
||||||
let controller = MastodonController.getForAccount(localAccountInfo)
|
let controller = MastodonController.getForAccount(localAccountInfo)
|
||||||
controller.getOwnAccount { (account) in
|
controller.getOwnAccount { (result) in
|
||||||
|
guard case let .success(account) = result else { return }
|
||||||
_ = ImageCache.avatars.get(account.avatar) { (data) in
|
_ = ImageCache.avatars.get(account.avatar) { (data) in
|
||||||
if let data = data, let image = UIImage(data: data) {
|
if let data = data, let image = UIImage(data: data) {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
|
|
@ -16,7 +16,9 @@ class MyProfileViewController: ProfileViewController {
|
||||||
title = "My Profile"
|
title = "My Profile"
|
||||||
tabBarItem.image = UIImage(systemName: "person.fill")
|
tabBarItem.image = UIImage(systemName: "person.fill")
|
||||||
|
|
||||||
mastodonController.getOwnAccount { (account) in
|
mastodonController.getOwnAccount { (result) in
|
||||||
|
guard case let .success(account) = result else { return }
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.accountID = account.id
|
self.accountID = account.id
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue