Skip to content

Commit

Permalink
Refactor FXIOS-6936 [v121] Create the state model for the regular tab…
Browse files Browse the repository at this point in the history
…s view controller (mozilla-mobile#17159)
  • Loading branch information
yoanarios authored Nov 6, 2023
1 parent e76a521 commit 571c1ff
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 49 deletions.
4 changes: 4 additions & 0 deletions Client.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
219A0FD72ACC8C03009A6D1A /* InactiveTabsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 219A0FD62ACC8C03009A6D1A /* InactiveTabsHeaderView.swift */; };
219A0FD92ACC8C0F009A6D1A /* InactiveTabsFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 219A0FD82ACC8C0F009A6D1A /* InactiveTabsFooterView.swift */; };
219A0FDB2ACCCFFC009A6D1A /* InactiveTabsSectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 219A0FDA2ACCCFFC009A6D1A /* InactiveTabsSectionManager.swift */; };
219CAE1F2AF578F900E3DE02 /* TabViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 219CAE1E2AF578F900E3DE02 /* TabViewState.swift */; };
21A1C3C72996AFF800181B7C /* OverlayModeManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21A1C3C62996AFF800181B7C /* OverlayModeManagerTests.swift */; };
21A43CDD291461C700B1206D /* ReaderModeFontTypeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21A43CDC291461C700B1206D /* ReaderModeFontTypeButton.swift */; };
21A7C44E283539170071D996 /* IntroViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21A7C44D283539170071D996 /* IntroViewModel.swift */; };
Expand Down Expand Up @@ -2205,6 +2206,7 @@
219A0FD62ACC8C03009A6D1A /* InactiveTabsHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InactiveTabsHeaderView.swift; sourceTree = "<group>"; };
219A0FD82ACC8C0F009A6D1A /* InactiveTabsFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InactiveTabsFooterView.swift; sourceTree = "<group>"; };
219A0FDA2ACCCFFC009A6D1A /* InactiveTabsSectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InactiveTabsSectionManager.swift; sourceTree = "<group>"; };
219CAE1E2AF578F900E3DE02 /* TabViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabViewState.swift; sourceTree = "<group>"; };
219F41288625C09DD40F008C /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/PrivateBrowsing.strings; sourceTree = "<group>"; };
21A1C3C62996AFF800181B7C /* OverlayModeManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverlayModeManagerTests.swift; sourceTree = "<group>"; };
21A43CDC291461C700B1206D /* ReaderModeFontTypeButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReaderModeFontTypeButton.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -7501,6 +7503,7 @@
children = (
1D2F68AC2ACB266300524B92 /* RemoteTabsPanelState.swift */,
1DDE3DB62AC3820A0039363B /* TabCellState.swift */,
219CAE1E2AF578F900E3DE02 /* TabViewState.swift */,
21E77E4F2AA8BAEC00FABA10 /* TabTrayState.swift */,
21996BAA2AE95AFC00E0D55F /* TabTrayPanelType.swift */,
);
Expand Down Expand Up @@ -12645,6 +12648,7 @@
8A7368AD27924AAF005D7704 /* CanRemoveQuickActionBookmark.swift in Sources */,
8A0621B829428FBD005D1EFD /* OpenTabNotificationObject.swift in Sources */,
C2296FCC2A601C190046ECA6 /* IntensityVisualEffectView.swift in Sources */,
219CAE1F2AF578F900E3DE02 /* TabViewState.swift in Sources */,
8ADC2A102A33758E00543DAA /* FxALaunchParams.swift in Sources */,
D3C3696E1CC6B78800348A61 /* LocalRequestHelper.swift in Sources */,
E17496382991A2720096900A /* AdaptiveStack.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ import Shared
import Storage

class LegacyTabTrayViewModel {
enum Layout: Equatable {
case regular // iPad
case compact // iPhone
}

let profile: Profile
let tabManager: TabManager
let overlayManager: OverlayModeManager
Expand All @@ -21,7 +16,7 @@ class LegacyTabTrayViewModel {
let syncedTabsController: LegacyRemoteTabsPanel

var segmentToFocus: TabTrayPanelType?
var layout: Layout = .compact
var layout: TabTrayLayoutType = .compact

var normalTabsCount: String {
(tabManager.normalTabs.count < 100) ? tabManager.normalTabs.count.description : "\u{221E}"
Expand Down
4 changes: 2 additions & 2 deletions Client/Frontend/Browser/Tabs/State/TabCellState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ struct TabCellState {

let margin: CGFloat // (Changes depending on fullscreen)

static func emptyTabState() -> TabCellState {
static func emptyTabState(title: String) -> TabCellState {
return TabCellState(isSelected: false,
isPrivate: false,
isFxHomeTab: false,
tabTitle: "",
tabTitle: title,
url: nil,
screenshot: nil,
hasHomeScreenshot: false,
Expand Down
33 changes: 19 additions & 14 deletions Client/Frontend/Browser/Tabs/State/TabTrayState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,32 @@

import Foundation

enum TabTrayLayoutType: Equatable {
case regular // iPad
case compact // iPhone
}

struct TabTrayState {
var tabs: [String]
var isPrivateMode: Bool
var tabViewState: TabViewState
var remoteTabsState: RemoteTabsPanelState?
var selectedPanel: TabTrayPanelType?

// MARK: Inactive tabs
var inactiveTabs: [String]
var isInactiveTabsExpanded = true
var layout: TabTrayLayoutType = .compact
var normalTabsCount: String
var navigationTitle: String

var isPrivateTabsEmpty: Bool {
return isPrivateMode && tabs.isEmpty
var isSyncTabsPanel: Bool {
return selectedPanel == .syncedTabs
}

// For test and mock purposes will be deleted once Redux is integrated
static func getMockState(isPrivateMode: Bool) -> TabTrayState {
let tabs = ["Tab1",
"Tab2",
"Tab3",
"Tab4",
"Tab5"]
return TabTrayState(tabs: tabs,
isPrivateMode: isPrivateMode,
inactiveTabs: tabs)
let tabViewState = TabViewState.getMockState(isPrivateMode: isPrivateMode)
return TabTrayState(isPrivateMode: isPrivateMode,
tabViewState: tabViewState,
remoteTabsState: nil,
normalTabsCount: "2",
navigationTitle: "")
}
}
33 changes: 33 additions & 0 deletions Client/Frontend/Browser/Tabs/State/TabViewState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/

import Foundation

struct TabViewState {
var isPrivateMode: Bool
var tabs: [TabCellState]

// MARK: Inactive tabs
var inactiveTabs: [String]
var isInactiveTabsExpanded = true

var isPrivateTabsEmpty: Bool {
return isPrivateMode && tabs.isEmpty
}

// For test and mock purposes will be deleted once Redux is integrated
static func getMockState(isPrivateMode: Bool) -> TabViewState {
var tabs = [TabCellState]()

for index in 0...4 {
let cellState = TabCellState.emptyTabState(title: "Tab \(index)")
tabs.append(cellState)
}
return TabViewState(isPrivateMode: isPrivateMode,
tabs: tabs,
inactiveTabs: ["Tab1",
"Tab2",
"Tab3"])
}
}
4 changes: 2 additions & 2 deletions Client/Frontend/Browser/Tabs/TabDisplayViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ class TabDisplayViewController: UIViewController,
private lazy var emptyPrivateTabsView: EmptyPrivateTabsView = .build()

// MARK: Redux state
var state: TabTrayState
var state: TabViewState

init(isPrivateMode: Bool,
notificationCenter: NotificationProtocol = NotificationCenter.default,
themeManager: ThemeManager = AppContainer.shared.resolve()) {
// TODO: FXIOS-6936 Integrate Redux state
self.state = TabTrayState.getMockState(isPrivateMode: isPrivateMode)
self.state = TabViewState.getMockState(isPrivateMode: isPrivateMode)
self.notificationCenter = notificationCenter
self.themeManager = themeManager
super.init(nibName: nil, bundle: nil)
Expand Down
33 changes: 15 additions & 18 deletions Client/Frontend/Browser/Tabs/TabTrayViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@ class TabTrayViewController: UIViewController,
var didSelectUrl: ((URL, Storage.VisitType) -> Void)?

// MARK: - Redux state
var selectedPanel: TabTrayPanelType?
lazy var layout: LegacyTabTrayViewModel.Layout = {
var state: TabTrayState
lazy var layout: TabTrayLayoutType = {
return shouldUseiPadSetup() ? .regular : .compact
}()

var isSyncTabsPanel: Bool {
return selectedPanel == .syncedTabs
// iPad Layout
var isRegularLayout: Bool {
return layout == .regular
}

var hasSyncableAccount: Bool {
Expand All @@ -60,13 +61,8 @@ class TabTrayViewController: UIViewController,
return profile.hasSyncableAccount()
}

// iPad Layout
var isRegularLayout: Bool {
return layout == .regular
}

var currentPanel: UINavigationController? {
guard let index = selectedPanel?.rawValue else { return nil }
guard let index = state.selectedPanel?.rawValue else { return nil }

return childPanelControllers[index]
}
Expand All @@ -90,8 +86,7 @@ class TabTrayViewController: UIViewController,
label.font = TabsButton.UX.titleFont
label.layer.cornerRadius = TabsButton.UX.cornerRadius
label.textAlignment = .center
// TODO: FXIOS-7356 Connect to regular tabs count
label.text = "0"
label.text = self.state.normalTabsCount
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
Expand Down Expand Up @@ -185,6 +180,7 @@ class TabTrayViewController: UIViewController,
init(delegate: TabTrayViewControllerDelegate,
themeManager: ThemeManager = AppContainer.shared.resolve(),
and notificationCenter: NotificationProtocol = NotificationCenter.default) {
self.state = TabTrayState.getMockState(isPrivateMode: false)
self.delegate = delegate
self.themeManager = themeManager
self.notificationCenter = notificationCenter
Expand Down Expand Up @@ -287,7 +283,7 @@ class TabTrayViewController: UIViewController,
}

private func updateTitle() {
guard let panel = selectedPanel else { return }
guard let panel = state.selectedPanel else { return }

navigationItem.title = panel.navTitle
}
Expand Down Expand Up @@ -316,12 +312,12 @@ class TabTrayViewController: UIViewController,
return
}

let toolbarItems = isSyncTabsPanel ? bottomToolbarItemsForSync : bottomToolbarItems
let toolbarItems = state.isSyncTabsPanel ? bottomToolbarItemsForSync : bottomToolbarItems
setToolbarItems(toolbarItems, animated: true)
}

private func setupToolbarForIpad() {
if isSyncTabsPanel {
if state.isSyncTabsPanel {
navigationItem.leftBarButtonItem = nil
navigationItem.rightBarButtonItems = rightBarButtonItemsForSync
} else {
Expand All @@ -330,7 +326,7 @@ class TabTrayViewController: UIViewController,
}

navigationController?.isToolbarHidden = true
let toolbarItems = isSyncTabsPanel ? bottomToolbarItemsForSync : bottomToolbarItems
let toolbarItems = state.isSyncTabsPanel ? bottomToolbarItemsForSync : bottomToolbarItems
setToolbarItems(toolbarItems, animated: true)
}

Expand Down Expand Up @@ -363,7 +359,8 @@ class TabTrayViewController: UIViewController,

// MARK: Child panels
func setupOpenPanel(panelType: TabTrayPanelType) {
selectedPanel = panelType
// TODO: Move to Reducer
state.selectedPanel = panelType

guard let currentPanel = currentPanel else { return }

Expand Down Expand Up @@ -406,7 +403,7 @@ class TabTrayViewController: UIViewController,
@objc
private func segmentChanged() {
guard let panelType = TabTrayPanelType(rawValue: segmentedControl.selectedSegmentIndex),
selectedPanel != panelType else { return }
state.selectedPanel != panelType else { return }

setupOpenPanel(panelType: panelType)
}
Expand Down
4 changes: 2 additions & 2 deletions Client/Frontend/Browser/Tabs/Views/TabCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class TabCell: UICollectionViewCell, ThemeApplicable, ReusableCell {
}
// MARK: - Properties

private(set) var state = TabCellState.emptyTabState()
private(set) var state: TabCellState?

var isSelectedTab: Bool { return state.isSelected }
var isSelectedTab: Bool { return state?.isSelected ?? false }
var animator: SwipeAnimator?
weak var delegate: TabCellDelegate?

Expand Down
4 changes: 2 additions & 2 deletions Client/Frontend/Browser/Tabs/Views/TabDisplayView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class TabDisplayView: UIView,
case tabs
}

private(set) var state: TabTrayState
private(set) var state: TabViewState
private var inactiveTabsSectionManager: InactiveTabsSectionManager
private var tabsSectionManager: TabsSectionManager
var theme: Theme?
Expand Down Expand Up @@ -55,7 +55,7 @@ class TabDisplayView: UIView,
return collectionView
}()

public init(state: TabTrayState) {
public init(state: TabViewState) {
self.state = state
self.inactiveTabsSectionManager = InactiveTabsSectionManager()
self.tabsSectionManager = TabsSectionManager()
Expand Down
7 changes: 4 additions & 3 deletions Tests/ClientTests/TabTray/TabDisplayViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ final class TabDisplayViewTests: XCTestCase {
emptyInactiveTabs: Bool,
file: StaticString = #file,
line: UInt = #line) -> TabDisplayView {
let tabs: [String] = emptyTabs ? [String]() : ["Tab1", "Tab2"]
let tabs: [TabCellState] = emptyTabs ? [TabCellState]() : [TabCellState.emptyTabState(title: "Tab1"),
TabCellState.emptyTabState(title: "Tab2")]
let inactiveTabs: [String] = emptyInactiveTabs ? [String]() : ["Inactive1", "Inactive2"]
let tatTrayState = TabTrayState(tabs: tabs,
isPrivateMode: isPrivateMode,
let tatTrayState = TabViewState(isPrivateMode: isPrivateMode,
tabs: tabs,
inactiveTabs: inactiveTabs)

let subject = TabDisplayView(state: tatTrayState)
Expand Down

0 comments on commit 571c1ff

Please sign in to comment.