Skip to content

Commit

Permalink
Issue #394: Improve profiles navigation, crash fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mipolansk committed Jul 17, 2024
1 parent 82b5b8d commit 8153848
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 60 deletions.
13 changes: 3 additions & 10 deletions SUPLA/Core/Events/ListsEventsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ protocol UpdateEventsManager: UpdateEventsManagerEmitter {
final class UpdateEventsManagerImpl: UpdateEventsManager {

private var subjects: [Id: BehaviorRelay<Int>] = [:]
private let syncedQueue = DispatchQueue(label: "ListsEventsPrivateQueue", attributes: .concurrent)

private let channelUpdatesSubject = BehaviorRelay(value: ())
private let groupUpdatesSubject = BehaviorRelay(value: ())
Expand Down Expand Up @@ -134,21 +133,15 @@ final class UpdateEventsManagerImpl: UpdateEventsManager {
}

private func getSubjectForScene(sceneId: Int) -> BehaviorRelay<Int> {
return syncedQueue.sync(execute: {
getSubject(id: sceneId, type: .scene)
})
return synced(self) { getSubject(id: sceneId, type: .scene) }
}

private func getSubjectForChannel(channelId: Int) -> BehaviorRelay<Int> {
return syncedQueue.sync(execute: {
getSubject(id: channelId, type: .channel)
})
return synced(self) { getSubject(id: channelId, type: .channel) }
}

private func getSubjectForGroup(groupId: Int) -> BehaviorRelay<Int> {
return syncedQueue.sync(execute: {
getSubject(id: groupId, type: .group)
})
return synced(self) { getSubject(id: groupId, type: .group) }
}

private func getSubject(id: Int, type: IdType) -> BehaviorRelay<Int> {
Expand Down
6 changes: 6 additions & 0 deletions SUPLA/Core/Extensions/Synchronization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ func synced(_ lock: Any, closure: () -> ()) {
defer { objc_sync_exit(lock) }
closure()
}

func synced<T>(_ lock: Any, closure: () -> T) -> T {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
return closure()
}
3 changes: 1 addition & 2 deletions SUPLA/Core/State/SuplaAppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,11 @@ enum SuplaAppState: Equatable {

private func firstProfileCreationNextState(for event: SuplaAppEvent) -> SuplaAppState? {
switch (event) {
case .onStart, .networkConnected: nil
case .onStart, .networkConnected, .finish: nil
case .connecting: .connecting()
case .connected: try! illegalConnectedEvent()
case .cancel: try! illegalCancelEvent()
case .unlock: try! illegalUnlockEvent()
case .finish: try! illegalFinishEvent()
case .error: try! illegalErrorEvent()
case .initialized: try! illegalInitializedEvent()
case .noAccount: try! illegalNoAccountEvent()
Expand Down
1 change: 0 additions & 1 deletion SUPLA/CreateAccountVC.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ @implementation SACreateAccountVC {
- (void)viewDidLoad {
[super viewDidLoad];
[self.webView setDelegate:self];
self.statusBarBackgroundView.backgroundColor = [UIColor toolbar];
self.title = @"supla";
}

Expand Down
26 changes: 15 additions & 11 deletions SUPLA/Features/AccountCreation/AccountCreationVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import RxCocoa
class AccountCreationVC: BaseViewControllerVM<AccountCreationViewState, AccountCreationViewEvent, AccountCreationVM> {

@Singleton<SuplaAppCoordinator> private var coordinator
@Singleton<SuplaAppStateHolder> private var stateHolder

// MARK: UI variables
@IBOutlet private var controlStack: UIStackView!
Expand Down Expand Up @@ -102,12 +103,7 @@ class AccountCreationVC: BaseViewControllerVM<AccountCreationViewState, AccountC
override func viewDidLoad() {
super.viewDidLoad()

NotificationCenter.default.addObserver(
self,
selector: #selector(onBackButtonPressed(_:)),
name: Notification.Name(kSAMenubarBackButtonPressed),
object: nil
)
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "backbtn"), style: .done, target: self, action: #selector(onBackButtonPressed))

configureUI()
bindVM()
Expand Down Expand Up @@ -295,14 +291,14 @@ class AccountCreationVC: BaseViewControllerVM<AccountCreationViewState, AccountC
coordinator.navigateToCreateAccountWeb()
break
case .navigateToRemoveAccount(let needsRestart, let serverAddress):
coordinator.popViewController()
popToProfiles()
coordinator.navigateToRemoveAccountWeb(needsRestart: needsRestart, serverAddress: serverAddress)
break
case .finish(let needsRestart, let needsReauth):
if (needsRestart || needsReauth) {
coordinator.popToStatus()
} else {
coordinator.popViewController()
popToProfiles()
}
break
case .showRemovalFailure:
Expand Down Expand Up @@ -370,7 +366,7 @@ class AccountCreationVC: BaseViewControllerVM<AccountCreationViewState, AccountC
if (needsReauth) {
coordinator.popToStatus()
} else {
coordinator.popViewController()
popToProfiles()
}
if (needsReauth || !SAApp.suplaClientConnected()) {
NotificationCenter.default.post(name: .saConnecting, object: self, userInfo: nil)
Expand Down Expand Up @@ -423,8 +419,12 @@ class AccountCreationVC: BaseViewControllerVM<AccountCreationViewState, AccountC
present(alert, animated: true)
}

@objc private func onBackButtonPressed(_ n: Notification) {
coordinator.popViewController()
@objc private func onBackButtonPressed() {
if (stateHolder.currentState() == .firstProfileCreation) {
coordinator.popToStatus()
} else {
popToProfiles()
}
}

@objc private func didTapBackground(_ gr: UITapGestureRecognizer) {
Expand All @@ -438,6 +438,10 @@ class AccountCreationVC: BaseViewControllerVM<AccountCreationViewState, AccountC
default: return nil
}
}

private func popToProfiles() {
coordinator.popToViewController(ofClass: ProfilesVC.self)
}
}

extension AccountCreationVC: UITextFieldDelegate {
Expand Down
11 changes: 7 additions & 4 deletions SUPLA/Features/LockScreen/LockScreenVM.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,21 @@ extension LockScreenFeature {
onNext: { [weak self] in
switch ($0) {
case .unlocked:
self?.coordinator.popViewController()

switch (unlockAction) {
case .authorizeAccountsCreate:
self?.coordinator.navigateToProfile(profileId: nil, withLockCheck: false)
case .authorizeAccountsEdit(let profileId):
self?.coordinator.navigateToProfile(profileId: profileId, withLockCheck: false)
default: break
default:
self?.coordinator.popViewController()
}
case .unlockedNoAccount:
if (unlockAction == .authorizeAccountsCreate) {
switch (unlockAction) {
case .authorizeAccountsCreate:
self?.coordinator.navigateToProfile(profileId: nil, withLockCheck: false)
case .authorizeApplication:
self?.coordinator.popViewController()
default: break
}
case .failure:
if let self = self {
Expand Down
2 changes: 0 additions & 2 deletions SUPLA/UI/BaseViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
NS_ASSUME_NONNULL_BEGIN

@interface BaseViewController : UIViewController
@property (readonly,nonatomic) UIView *statusBarBackgroundView;
- (BOOL)adjustsStatusBarBackground;
- (BOOL)hidesNavigationBar;
- (void)addChildView: (UIView *)v;
- (BOOL)shouldUpdateTitleFont;
Expand Down
28 changes: 1 addition & 27 deletions SUPLA/UI/BaseViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,14 @@ @interface BaseViewController ()

@end

@implementation BaseViewController {
UIView *statusBarBg;
}
@implementation BaseViewController {}

- (void)viewDidLoad {
[super viewDidLoad];

if(@available(iOS 14, *)) {
self.navigationItem.backButtonDisplayMode = UINavigationItemBackButtonDisplayModeMinimal;
}

if([self adjustsStatusBarBackground]) {
CGRect sbFrame;
sbFrame = [[UIApplication sharedApplication] statusBarFrame];
statusBarBg = [[UIView alloc] initWithFrame: CGRectZero];
statusBarBg.backgroundColor = [UIColor toolbar];
statusBarBg.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview: statusBarBg];
[statusBarBg.topAnchor constraintEqualToAnchor: self.view.topAnchor].active = YES;
[statusBarBg.leftAnchor constraintEqualToAnchor: self.view.leftAnchor].active = YES;
[statusBarBg.rightAnchor constraintEqualToAnchor: self.view.rightAnchor].active = YES;
[statusBarBg.heightAnchor constraintEqualToConstant:sbFrame.size.height].active = YES;
}
}

- (void)updateNavBarFont {
Expand All @@ -69,9 +54,6 @@ - (void)updateNavBarFont {

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear: animated];
if(statusBarBg) {
[self.view bringSubviewToFront: statusBarBg];
}

[self.navigationController setNavigationBarHidden: [self hidesNavigationBar]
animated: animated];
Expand All @@ -83,18 +65,10 @@ - (void)viewWillDisappear:(BOOL)animated {
[self updateNavBarFont];
}

- (BOOL)adjustsStatusBarBackground {
return YES;
}

- (BOOL)hidesNavigationBar {
return NO;
}

- (UIView*)statusBarBackgroundView {
return statusBarBg;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait |
UIInterfaceOrientationMaskPortraitUpsideDown;
Expand Down
6 changes: 3 additions & 3 deletions SUPLATests/Tests/Features/LockScreen/LockScreenVMTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class LockScreenVMTests: XCTestCase {
// then
XCTAssertTuples(checkPinUseCase.parameters, [(action, CheckPinAction.checkPin(pin: pin))])
XCTAssertTuples(coordinator.navigateToProfileWithLockCheckMock.parameters, [(nil, false)])
coordinator.verifyPopViewController([true])
coordinator.verifyPopViewController([])
}

func test_shouldVerifyPin_andNavigateToEditProfile() {
Expand All @@ -95,7 +95,7 @@ class LockScreenVMTests: XCTestCase {
// then
XCTAssertTuples(checkPinUseCase.parameters, [(action, CheckPinAction.checkPin(pin: pin))])
XCTAssertTuples(coordinator.navigateToProfileWithLockCheckMock.parameters, [(profileId, false)])
coordinator.verifyPopViewController([true])
coordinator.verifyPopViewController([])
}

func test_shouldVerifyPin_andDoNothingWhenNoAccount() {
Expand All @@ -113,7 +113,7 @@ class LockScreenVMTests: XCTestCase {
// then
XCTAssertTuples(checkPinUseCase.parameters, [(action, CheckPinAction.checkPin(pin: pin))])
XCTAssertTuples(coordinator.navigateToProfileWithLockCheckMock.parameters, [])
coordinator.verifyPopViewController([])
coordinator.verifyPopViewController([true])
}

func test_shouldRejectPin() {
Expand Down

0 comments on commit 8153848

Please sign in to comment.