Fix renaming list not updating UI

Closes #213
This commit is contained in:
Shadowfacts 2022-11-11 18:08:44 -05:00
parent 21bd716844
commit b465838b71
6 changed files with 140 additions and 23 deletions

View File

@ -313,6 +313,7 @@
D6F6A54C291EF6FE00F496A8 /* EditListSearchResultsContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F6A54B291EF6FE00F496A8 /* EditListSearchResultsContainerViewController.swift */; }; D6F6A54C291EF6FE00F496A8 /* EditListSearchResultsContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F6A54B291EF6FE00F496A8 /* EditListSearchResultsContainerViewController.swift */; };
D6F6A54E291EF7E100F496A8 /* EditListSearchFollowingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F6A54D291EF7E100F496A8 /* EditListSearchFollowingViewController.swift */; }; D6F6A54E291EF7E100F496A8 /* EditListSearchFollowingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F6A54D291EF7E100F496A8 /* EditListSearchFollowingViewController.swift */; };
D6F6A550291F058600F496A8 /* CreateListService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F6A54F291F058600F496A8 /* CreateListService.swift */; }; D6F6A550291F058600F496A8 /* CreateListService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F6A54F291F058600F496A8 /* CreateListService.swift */; };
D6F6A552291F098700F496A8 /* RenameListService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F6A551291F098700F496A8 /* RenameListService.swift */; };
D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EF21251A2900CF0F2B /* MastodonController.swift */; }; D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EF21251A2900CF0F2B /* MastodonController.swift */; };
D6FF9860255C717400845181 /* AccountSwitchingContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6FF985F255C717400845181 /* AccountSwitchingContainerViewController.swift */; }; D6FF9860255C717400845181 /* AccountSwitchingContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6FF985F255C717400845181 /* AccountSwitchingContainerViewController.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -681,6 +682,7 @@
D6F6A54B291EF6FE00F496A8 /* EditListSearchResultsContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditListSearchResultsContainerViewController.swift; sourceTree = "<group>"; }; D6F6A54B291EF6FE00F496A8 /* EditListSearchResultsContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditListSearchResultsContainerViewController.swift; sourceTree = "<group>"; };
D6F6A54D291EF7E100F496A8 /* EditListSearchFollowingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditListSearchFollowingViewController.swift; sourceTree = "<group>"; }; D6F6A54D291EF7E100F496A8 /* EditListSearchFollowingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditListSearchFollowingViewController.swift; sourceTree = "<group>"; };
D6F6A54F291F058600F496A8 /* CreateListService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateListService.swift; sourceTree = "<group>"; }; D6F6A54F291F058600F496A8 /* CreateListService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateListService.swift; sourceTree = "<group>"; };
D6F6A551291F098700F496A8 /* RenameListService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenameListService.swift; sourceTree = "<group>"; };
D6F953EF21251A2900CF0F2B /* MastodonController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonController.swift; sourceTree = "<group>"; }; D6F953EF21251A2900CF0F2B /* MastodonController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonController.swift; sourceTree = "<group>"; };
D6FF985F255C717400845181 /* AccountSwitchingContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSwitchingContainerViewController.swift; sourceTree = "<group>"; }; D6FF985F255C717400845181 /* AccountSwitchingContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSwitchingContainerViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -1491,6 +1493,7 @@
D61ABEFD28F1C92600B29151 /* FavoriteService.swift */, D61ABEFD28F1C92600B29151 /* FavoriteService.swift */,
D621733228F1D5ED004C7DB1 /* ReblogService.swift */, D621733228F1D5ED004C7DB1 /* ReblogService.swift */,
D6F6A54F291F058600F496A8 /* CreateListService.swift */, D6F6A54F291F058600F496A8 /* CreateListService.swift */,
D6F6A551291F098700F496A8 /* RenameListService.swift */,
); );
path = API; path = API;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1801,6 +1804,7 @@
D627944F23A9C99800D38C68 /* EditListAccountsViewController.swift in Sources */, D627944F23A9C99800D38C68 /* EditListAccountsViewController.swift in Sources */,
D6945C3423AC6431005C403C /* AddSavedHashtagViewController.swift in Sources */, D6945C3423AC6431005C403C /* AddSavedHashtagViewController.swift in Sources */,
D627943723A552C200D38C68 /* BookmarkStatusActivity.swift in Sources */, D627943723A552C200D38C68 /* BookmarkStatusActivity.swift in Sources */,
D6F6A552291F098700F496A8 /* RenameListService.swift in Sources */,
D68ACE5D279B1ABA001CE8EB /* AssetPickerControlCollectionViewCell.swift in Sources */, D68ACE5D279B1ABA001CE8EB /* AssetPickerControlCollectionViewCell.swift in Sources */,
D62D2426217ABF63005076CC /* UserActivityType.swift in Sources */, D62D2426217ABF63005076CC /* UserActivityType.swift in Sources */,
D6AC956723C4347E008C9946 /* MainSceneDelegate.swift in Sources */, D6AC956723C4347E008C9946 /* MainSceneDelegate.swift in Sources */,

View File

@ -0,0 +1,69 @@
//
// RenameListService.swift
// Tusker
//
// Created by Shadowfacts on 11/11/22.
// Copyright © 2022 Shadowfacts. All rights reserved.
//
import UIKit
import Pachyderm
@MainActor
class RenameListService {
private let list: List
private let mastodonController: MastodonController
private let present: (UIViewController) -> Void
private var renameAction: UIAlertAction?
init(list: List, mastodonController: MastodonController, present: @escaping (UIViewController) -> Void) {
self.list = list
self.mastodonController = mastodonController
self.present = present
}
func run() {
let alert = UIAlertController(title: NSLocalizedString("Rename List", comment: "rename list alert title"), message: nil, preferredStyle: .alert)
alert.addTextField { (textField) in
textField.text = self.list.title
textField.addTarget(self, action: #selector(self.alertTextFieldValueChanged), for: .editingChanged)
}
alert.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: "rename list alert cancel button"), style: .cancel, handler: nil))
renameAction = UIAlertAction(title: NSLocalizedString("Rename", comment: "renaem list alert rename button"), style: .default, handler: { (_) in
let textField = alert.textFields!.first!
let title = textField.text ?? ""
Task {
await self.updateList(with: title)
}
})
alert.addAction(renameAction!)
present(alert)
}
@objc private func alertTextFieldValueChanged(_ textField: UITextField) {
renameAction?.isEnabled = textField.text?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false
}
private func updateList(with title: String) async {
do {
let req = List.update(list, title: title)
let (list, _) = try await mastodonController.run(req)
NotificationCenter.default.post(name: .listRenamed, object: list.id, userInfo: ["list": list])
} catch {
let alert = UIAlertController(title: "Error Updating List", message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
alert.addAction(UIAlertAction(title: "Retry", style: .default, handler: { _ in
Task {
await self.updateList(with: title)
}
}))
present(alert)
}
}
}
extension Foundation.Notification.Name {
static let listRenamed = Notification.Name("listRenamed")
}

View File

@ -71,6 +71,7 @@ class ExploreViewController: UIViewController, UICollectionViewDelegate {
NotificationCenter.default.addObserver(self, selector: #selector(savedHashtagsChanged), name: .savedHashtagsChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(savedHashtagsChanged), name: .savedHashtagsChanged, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(savedInstancesChanged), name: .savedInstancesChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(savedInstancesChanged), name: .savedInstancesChanged, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(reloadLists), name: .listsChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(reloadLists), name: .listsChanged, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(listRenamed(_:)), name: .listRenamed, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
} }
@ -197,6 +198,23 @@ class ExploreViewController: UIViewController, UICollectionViewDelegate {
} }
} }
@objc private func listRenamed(_ notification: Foundation.Notification) {
let list = notification.userInfo!["list"] as! List
var snapshot = dataSource.snapshot()
let existing = snapshot.itemIdentifiers(inSection: .lists).first(where: {
if case .list(let existingList) = $0, existingList.id == list.id {
return true
} else {
return false
}
})
if let existing {
snapshot.insertItems([.list(list)], afterItem: existing)
snapshot.deleteItems([existing])
dataSource.apply(snapshot)
}
}
@MainActor @MainActor
private func fetchSavedHashtags() -> [SavedHashtag] { private func fetchSavedHashtags() -> [SavedHashtag] {
let req = SavedHashtag.fetchRequest() let req = SavedHashtag.fetchRequest()
@ -490,7 +508,7 @@ extension ExploreViewController {
case (.profileDirectory, .profileDirectory): case (.profileDirectory, .profileDirectory):
return true return true
case let (.list(a), .list(b)): case let (.list(a), .list(b)):
return a.id == b.id return a.id == b.id && a.title == b.title
case (.addList, .addList): case (.addList, .addList):
return true return true
case let (.savedHashtag(a), .savedHashtag(b)): case let (.savedHashtag(a), .savedHashtag(b)):
@ -521,6 +539,7 @@ extension ExploreViewController {
case let .list(list): case let .list(list):
hasher.combine("list") hasher.combine("list")
hasher.combine(list.id) hasher.combine(list.id)
hasher.combine(list.title)
case .addList: case .addList:
hasher.combine("addList") hasher.combine("addList")
case let .savedHashtag(hashtag): case let .savedHashtag(hashtag):

View File

@ -13,7 +13,7 @@ class EditListAccountsViewController: EnhancedTableViewController {
let mastodonController: MastodonController let mastodonController: MastodonController
let list: List private var list: List
var dataSource: DataSource! var dataSource: DataSource!
@ -28,7 +28,9 @@ class EditListAccountsViewController: EnhancedTableViewController {
super.init(style: .plain) super.init(style: .plain)
title = String(format: NSLocalizedString("Edit %@", comment: "edit list screen title"), list.title) listChanged()
NotificationCenter.default.addObserver(self, selector: #selector(listRenamed(_:)), name: .listRenamed, object: list.id)
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@ -82,6 +84,16 @@ class EditListAccountsViewController: EnhancedTableViewController {
} }
} }
private func listChanged() {
title = String(format: NSLocalizedString("Edit %@", comment: "edit list screen title"), list.title)
}
@objc private func listRenamed(_ notification: Foundation.Notification) {
let list = notification.userInfo!["list"] as! List
self.list = list
self.listChanged()
}
func loadAccounts() async { func loadAccounts() async {
do { do {
let request = List.getAccounts(list) let request = List.getAccounts(list)
@ -149,24 +161,7 @@ class EditListAccountsViewController: EnhancedTableViewController {
// MARK: - Interaction // MARK: - Interaction
@objc func renameButtonPressed() { @objc func renameButtonPressed() {
let alert = UIAlertController(title: NSLocalizedString("Rename List", comment: "rename list alert title"), message: nil, preferredStyle: .alert) RenameListService(list: list, mastodonController: mastodonController, present: { self.present($0, animated: true) }).run()
alert.addTextField { (textField) in
textField.text = self.list.title
}
alert.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: "rename list alert cancel button"), style: .cancel, handler: nil))
alert.addAction(UIAlertAction(title: NSLocalizedString("Rename", comment: "renaem list alert rename button"), style: .default, handler: { (_) in
guard let text = alert.textFields?.first?.text else {
fatalError()
}
let request = List.update(self.list, title: text)
self.mastodonController.run(request) { (response) in
guard case .success(_, _) = response else {
fatalError()
}
// todo: show success message somehow
}
}))
present(alert, animated: true)
} }
} }

View File

@ -11,7 +11,7 @@ import Pachyderm
class ListTimelineViewController: TimelineViewController { class ListTimelineViewController: TimelineViewController {
let list: List private(set) var list: List
var presentEditOnAppear = false var presentEditOnAppear = false
@ -20,7 +20,9 @@ class ListTimelineViewController: TimelineViewController {
super.init(for: .list(id: list.id), mastodonController: mastodonController) super.init(for: .list(id: list.id), mastodonController: mastodonController)
title = list.title listChanged()
NotificationCenter.default.addObserver(self, selector: #selector(listRenamed(_:)), name: .listRenamed, object: list.id)
} }
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
@ -41,6 +43,16 @@ class ListTimelineViewController: TimelineViewController {
} }
} }
private func listChanged() {
title = list.title
}
@objc private func listRenamed(_ notification: Foundation.Notification) {
let list = notification.userInfo!["list"] as! List
self.list = list
self.listChanged()
}
func presentEdit(animated: Bool) { func presentEdit(animated: Bool) {
let editListAccountsController = EditListAccountsViewController(list: list, mastodonController: mastodonController) let editListAccountsController = EditListAccountsViewController(list: list, mastodonController: mastodonController)
editListAccountsController.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(editListDoneButtonPressed)) editListAccountsController.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(editListDoneButtonPressed))

View File

@ -100,6 +100,7 @@ class MainSidebarViewController: UIViewController {
NotificationCenter.default.addObserver(self, selector: #selector(reloadSavedHashtags), name: .savedHashtagsChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(reloadSavedHashtags), name: .savedHashtagsChanged, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(reloadSavedInstances), name: .savedInstancesChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(reloadSavedInstances), name: .savedInstancesChanged, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(reloadLists), name: .listsChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(reloadLists), name: .listsChanged, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(listRenamed(_:)), name: .listRenamed, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
onViewDidLoad?() onViewDidLoad?()
@ -224,6 +225,23 @@ class MainSidebarViewController: UIViewController {
} }
} }
@objc private func listRenamed(_ notification: Foundation.Notification) {
let list = notification.userInfo!["list"] as! List
var snapshot = dataSource.snapshot()
let existing = snapshot.itemIdentifiers(inSection: .lists).first(where: {
if case .list(let existingList) = $0, existingList.id == list.id {
return true
} else {
return false
}
})
if let existing {
snapshot.insertItems([.list(list)], afterItem: existing)
snapshot.deleteItems([existing])
dataSource.apply(snapshot)
}
}
@MainActor @MainActor
private func fetchSavedHashtags() -> [SavedHashtag] { private func fetchSavedHashtags() -> [SavedHashtag] {
let req = SavedHashtag.fetchRequest() let req = SavedHashtag.fetchRequest()