forked from zelo72/mastodon-ios
fix: status menu cause memory leaking issue
This commit is contained in:
parent
c88daf56be
commit
80ea6ac913
|
@ -67,7 +67,6 @@ extension StatusSection {
|
|||
timelineContext: TimelineContext,
|
||||
dependency: NeedsDependency,
|
||||
managedObjectContext: NSManagedObjectContext,
|
||||
timestampUpdatePublisher: AnyPublisher<Date, Never>,
|
||||
statusTableViewCellDelegate: StatusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate?,
|
||||
threadReplyLoaderTableViewCellDelegate: ThreadReplyLoaderTableViewCellDelegate?
|
||||
|
@ -363,7 +362,6 @@ extension StatusSection {
|
|||
}
|
||||
}()
|
||||
|
||||
|
||||
if status.author.id == requestUserID || status.reblog?.author.id == requestUserID {
|
||||
// do not filter myself
|
||||
} else {
|
||||
|
@ -473,9 +471,10 @@ extension StatusSection {
|
|||
.receive(on: RunLoop.main)
|
||||
.sink { _ in
|
||||
// do nothing
|
||||
} receiveValue: { [weak cell, weak tableView] change in
|
||||
} receiveValue: { [weak cell, weak tableView, weak dependency] change in
|
||||
guard let cell = cell else { return }
|
||||
guard let tableView = tableView else { return }
|
||||
guard let dependency = dependency else { return }
|
||||
guard case .update(let object) = change.changeType,
|
||||
let status = object as? Status, !status.isDeleted else {
|
||||
return
|
||||
|
@ -1072,7 +1071,7 @@ extension StatusSection {
|
|||
cell.statusView.actionToolbarContainer.reblogButton.isEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// set like
|
||||
let isLike = status.favouritedBy.flatMap { $0.contains(where: { $0.id == requestUserID }) } ?? false
|
||||
let favoriteCountTitle: String = {
|
||||
|
@ -1107,7 +1106,7 @@ extension StatusSection {
|
|||
StatusSection.setupStatusMoreButtonMenu(cell: cell, dependency: dependency, status: status)
|
||||
})
|
||||
.store(in: &cell.disposeBag)
|
||||
self.setupStatusMoreButtonMenu(cell: cell, dependency: dependency, status: status)
|
||||
setupStatusMoreButtonMenu(cell: cell, dependency: dependency, status: status)
|
||||
}
|
||||
|
||||
static func configureStatusAccessibilityLabel(cell: StatusTableViewCell) {
|
||||
|
|
|
@ -212,8 +212,17 @@ extension UserProviderFacade {
|
|||
let name = mastodonUser.displayNameWithFallback
|
||||
|
||||
if let shareUser = shareUser {
|
||||
let shareAction = UIAction(title: L10n.Common.Controls.Actions.shareUser(name), image: UIImage(systemName: "square.and.arrow.up"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in
|
||||
let shareAction = UIAction(
|
||||
title: L10n.Common.Controls.Actions.shareUser(name),
|
||||
image: UIImage(systemName: "square.and.arrow.up"),
|
||||
identifier: nil,
|
||||
discoverabilityTitle: nil,
|
||||
attributes: [],
|
||||
state: .off
|
||||
) { [weak provider, weak sourceView, weak barButtonItem] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let sourceView = sourceView else { return }
|
||||
guard let barButtonItem = barButtonItem else { return }
|
||||
let activityViewController = createActivityViewControllerForMastodonUser(mastodonUser: shareUser, dependency: provider)
|
||||
provider.coordinator.present(
|
||||
scene: .activityViewController(
|
||||
|
@ -229,8 +238,17 @@ extension UserProviderFacade {
|
|||
}
|
||||
|
||||
if let shareStatus = shareStatus {
|
||||
let shareAction = UIAction(title: L10n.Common.Controls.Actions.sharePost, image: UIImage(systemName: "square.and.arrow.up"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in
|
||||
let shareAction = UIAction(
|
||||
title: L10n.Common.Controls.Actions.sharePost,
|
||||
image: UIImage(systemName: "square.and.arrow.up"),
|
||||
identifier: nil,
|
||||
discoverabilityTitle: nil,
|
||||
attributes: [],
|
||||
state: .off
|
||||
) { [weak provider, weak sourceView, weak barButtonItem] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let sourceView = sourceView else { return }
|
||||
guard let barButtonItem = barButtonItem else { return }
|
||||
let activityViewController = createActivityViewControllerForMastodonUser(status: shareStatus, dependency: provider)
|
||||
provider.coordinator.present(
|
||||
scene: .activityViewController(
|
||||
|
@ -253,8 +271,9 @@ extension UserProviderFacade {
|
|||
discoverabilityTitle: isMuting ? nil : L10n.Common.Controls.Friendship.muteUser(name),
|
||||
attributes: isMuting ? [] : .destructive,
|
||||
state: .off
|
||||
) { [weak provider] _ in
|
||||
) { [weak provider, weak cell] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let cell = cell else { return }
|
||||
|
||||
UserProviderFacade.toggleUserMuteRelationship(
|
||||
provider: provider,
|
||||
|
@ -283,8 +302,9 @@ extension UserProviderFacade {
|
|||
discoverabilityTitle: isBlocking ? nil : L10n.Common.Controls.Friendship.blockUser(name),
|
||||
attributes: isBlocking ? [] : .destructive,
|
||||
state: .off
|
||||
) { [weak provider] _ in
|
||||
) { [weak provider, weak cell] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let cell = cell else { return }
|
||||
|
||||
UserProviderFacade.toggleUserBlockRelationship(
|
||||
provider: provider,
|
||||
|
@ -306,7 +326,14 @@ extension UserProviderFacade {
|
|||
}
|
||||
|
||||
if !isMyself {
|
||||
let reportAction = UIAction(title: L10n.Common.Controls.Actions.reportUser(name), image: UIImage(systemName: "flag"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in
|
||||
let reportAction = UIAction(
|
||||
title: L10n.Common.Controls.Actions.reportUser(name),
|
||||
image: UIImage(systemName: "flag"),
|
||||
identifier: nil,
|
||||
discoverabilityTitle: nil,
|
||||
attributes: [],
|
||||
state: .off
|
||||
) { [weak provider] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let authenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
||||
return
|
||||
|
@ -328,19 +355,37 @@ extension UserProviderFacade {
|
|||
|
||||
if !isInSameDomain {
|
||||
if isDomainBlocking {
|
||||
let unblockDomainAction = UIAction(title: L10n.Common.Controls.Actions.unblockDomain(mastodonUser.domainFromAcct), image: UIImage(systemName: "nosign"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in
|
||||
let unblockDomainAction = UIAction(
|
||||
title: L10n.Common.Controls.Actions.unblockDomain(mastodonUser.domainFromAcct),
|
||||
image: UIImage(systemName: "nosign"),
|
||||
identifier: nil,
|
||||
discoverabilityTitle: nil,
|
||||
attributes: [],
|
||||
state: .off
|
||||
) { [weak provider, weak cell] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let cell = cell else { return }
|
||||
provider.context.blockDomainService.unblockDomain(userProvider: provider, cell: cell)
|
||||
}
|
||||
children.append(unblockDomainAction)
|
||||
} else {
|
||||
let blockDomainAction = UIAction(title: L10n.Common.Controls.Actions.blockDomain(mastodonUser.domainFromAcct), image: UIImage(systemName: "nosign"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in
|
||||
let blockDomainAction = UIAction(
|
||||
title: L10n.Common.Controls.Actions.blockDomain(mastodonUser.domainFromAcct),
|
||||
image: UIImage(systemName: "nosign"),
|
||||
identifier: nil,
|
||||
discoverabilityTitle: nil,
|
||||
attributes: [],
|
||||
state: .off
|
||||
) { [weak provider, weak cell] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let cell = cell else { return }
|
||||
|
||||
let alertController = UIAlertController(title: L10n.Common.Alerts.BlockDomain.title(mastodonUser.domainFromAcct), message: nil, preferredStyle: .alert)
|
||||
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .default) { _ in
|
||||
}
|
||||
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .default) { _ in }
|
||||
alertController.addAction(cancelAction)
|
||||
let blockDomainAction = UIAlertAction(title: L10n.Common.Alerts.BlockDomain.blockEntireDomain, style: .destructive) { _ in
|
||||
let blockDomainAction = UIAlertAction(title: L10n.Common.Alerts.BlockDomain.blockEntireDomain, style: .destructive) { [weak provider, weak cell] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let cell = cell else { return }
|
||||
provider.context.blockDomainService.blockDomain(userProvider: provider, cell: cell)
|
||||
}
|
||||
alertController.addAction(blockDomainAction)
|
||||
|
@ -351,19 +396,26 @@ extension UserProviderFacade {
|
|||
}
|
||||
|
||||
if let status = shareStatus, isMyself {
|
||||
let deleteAction = UIAction(title: L10n.Common.Controls.Actions.delete, image: UIImage(systemName: "delete.left"), identifier: nil, discoverabilityTitle: nil, attributes: [.destructive], state: .off) {
|
||||
[weak provider] _ in
|
||||
let deleteAction = UIAction(
|
||||
title: L10n.Common.Controls.Actions.delete,
|
||||
image: UIImage(systemName: "delete.left"),
|
||||
identifier: nil,
|
||||
discoverabilityTitle: nil,
|
||||
attributes: [.destructive],
|
||||
state: .off
|
||||
) { [weak provider] _ in
|
||||
guard let provider = provider else { return }
|
||||
|
||||
|
||||
let alertController = UIAlertController(title: L10n.Common.Alerts.DeletePost.title, message: nil, preferredStyle: .alert)
|
||||
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .default) { _ in
|
||||
}
|
||||
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .default) { _ in }
|
||||
alertController.addAction(cancelAction)
|
||||
let deleteAction = UIAlertAction(title: L10n.Common.Alerts.DeletePost.delete, style: .destructive) { _ in
|
||||
let deleteAction = UIAlertAction(title: L10n.Common.Alerts.DeletePost.delete, style: .destructive) { [weak provider] _ in
|
||||
guard let provider = provider else { return }
|
||||
guard let activeMastodonAuthenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else { return }
|
||||
provider.context.apiService.deleteStatus(domain: activeMastodonAuthenticationBox.domain,
|
||||
statusID: status.id,
|
||||
authorizationBox: activeMastodonAuthenticationBox
|
||||
provider.context.apiService.deleteStatus(
|
||||
domain: activeMastodonAuthenticationBox.domain,
|
||||
statusID: status.id,
|
||||
authorizationBox: activeMastodonAuthenticationBox
|
||||
)
|
||||
.sink { _ in
|
||||
// do nothing
|
||||
|
@ -374,7 +426,6 @@ extension UserProviderFacade {
|
|||
}
|
||||
alertController.addAction(deleteAction)
|
||||
provider.present(alertController, animated: true, completion: nil)
|
||||
|
||||
}
|
||||
children.append(deleteAction)
|
||||
}
|
||||
|
|
|
@ -17,17 +17,11 @@ extension HashtagTimelineViewModel {
|
|||
statusTableViewCellDelegate: StatusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate
|
||||
) {
|
||||
let timestampUpdatePublisher = Timer.publish(every: 1.0, on: .main, in: .common)
|
||||
.autoconnect()
|
||||
.share()
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
diffableDataSource = StatusSection.tableViewDiffableDataSource(
|
||||
for: tableView,
|
||||
timelineContext: .hashtag,
|
||||
dependency: dependency,
|
||||
managedObjectContext: context.managedObjectContext,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
statusTableViewCellDelegate: statusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: timelineMiddleLoaderTableViewCellDelegate,
|
||||
threadReplyLoaderTableViewCellDelegate: nil
|
||||
|
|
|
@ -18,17 +18,11 @@ extension HomeTimelineViewModel {
|
|||
statusTableViewCellDelegate: StatusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate
|
||||
) {
|
||||
let timestampUpdatePublisher = Timer.publish(every: 1.0, on: .main, in: .common)
|
||||
.autoconnect()
|
||||
.share()
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
diffableDataSource = StatusSection.tableViewDiffableDataSource(
|
||||
for: tableView,
|
||||
timelineContext: .home,
|
||||
dependency: dependency,
|
||||
managedObjectContext: fetchedResultsController.managedObjectContext,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
statusTableViewCellDelegate: statusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: timelineMiddleLoaderTableViewCellDelegate,
|
||||
threadReplyLoaderTableViewCellDelegate: nil
|
||||
|
|
|
@ -42,6 +42,10 @@ final class NotificationViewController: UIViewController, NeedsDependency {
|
|||
}()
|
||||
|
||||
let refreshControl = UIRefreshControl()
|
||||
|
||||
deinit {
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
}
|
||||
}
|
||||
|
||||
extension NotificationViewController {
|
||||
|
|
|
@ -13,18 +13,12 @@ extension FavoriteViewModel {
|
|||
for tableView: UITableView,
|
||||
dependency: NeedsDependency,
|
||||
statusTableViewCellDelegate: StatusTableViewCellDelegate
|
||||
) {
|
||||
let timestampUpdatePublisher = Timer.publish(every: 1.0, on: .main, in: .common)
|
||||
.autoconnect()
|
||||
.share()
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
) {
|
||||
diffableDataSource = StatusSection.tableViewDiffableDataSource(
|
||||
for: tableView,
|
||||
timelineContext: .favorite,
|
||||
dependency: dependency,
|
||||
managedObjectContext: statusFetchedResultsController.fetchedResultsController.managedObjectContext,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
statusTableViewCellDelegate: statusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: nil,
|
||||
threadReplyLoaderTableViewCellDelegate: nil
|
||||
|
|
|
@ -97,7 +97,7 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi
|
|||
}
|
||||
|
||||
deinit {
|
||||
os_log("%{public}s[%{public}ld], %{public}s: deinit", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,17 +14,11 @@ extension UserTimelineViewModel {
|
|||
dependency: NeedsDependency,
|
||||
statusTableViewCellDelegate: StatusTableViewCellDelegate
|
||||
) {
|
||||
let timestampUpdatePublisher = Timer.publish(every: 1.0, on: .main, in: .common)
|
||||
.autoconnect()
|
||||
.share()
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
diffableDataSource = StatusSection.tableViewDiffableDataSource(
|
||||
for: tableView,
|
||||
timelineContext: .account,
|
||||
dependency: dependency,
|
||||
managedObjectContext: statusFetchedResultsController.fetchedResultsController.managedObjectContext,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
statusTableViewCellDelegate: statusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: nil,
|
||||
threadReplyLoaderTableViewCellDelegate: nil
|
||||
|
|
|
@ -17,17 +17,11 @@ extension PublicTimelineViewModel {
|
|||
statusTableViewCellDelegate: StatusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate
|
||||
) {
|
||||
let timestampUpdatePublisher = Timer.publish(every: 1.0, on: .main, in: .common)
|
||||
.autoconnect()
|
||||
.share()
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
diffableDataSource = StatusSection.tableViewDiffableDataSource(
|
||||
for: tableView,
|
||||
timelineContext: .public,
|
||||
dependency: dependency,
|
||||
managedObjectContext: fetchedResultsController.managedObjectContext,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
statusTableViewCellDelegate: statusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: timelineMiddleLoaderTableViewCellDelegate,
|
||||
threadReplyLoaderTableViewCellDelegate: nil
|
||||
|
|
|
@ -94,6 +94,10 @@ final class SearchViewController: UIViewController, NeedsDependency {
|
|||
}()
|
||||
|
||||
let searchBarTapPublisher = PassthroughSubject<Void, Never>()
|
||||
|
||||
deinit {
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -111,6 +111,10 @@ final class StatusTableViewCell: UITableViewCell, StatusCell {
|
|||
_init()
|
||||
}
|
||||
|
||||
deinit {
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension StatusTableViewCell {
|
||||
|
|
|
@ -19,17 +19,11 @@ extension ThreadViewModel {
|
|||
statusTableViewCellDelegate: StatusTableViewCellDelegate,
|
||||
threadReplyLoaderTableViewCellDelegate: ThreadReplyLoaderTableViewCellDelegate
|
||||
) {
|
||||
let timestampUpdatePublisher = Timer.publish(every: 1.0, on: .main, in: .common)
|
||||
.autoconnect()
|
||||
.share()
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
diffableDataSource = StatusSection.tableViewDiffableDataSource(
|
||||
for: tableView,
|
||||
timelineContext: .thread,
|
||||
dependency: dependency,
|
||||
managedObjectContext: context.managedObjectContext,
|
||||
timestampUpdatePublisher: timestampUpdatePublisher,
|
||||
statusTableViewCellDelegate: statusTableViewCellDelegate,
|
||||
timelineMiddleLoaderTableViewCellDelegate: nil,
|
||||
threadReplyLoaderTableViewCellDelegate: threadReplyLoaderTableViewCellDelegate
|
||||
|
|
Loading…
Reference in New Issue