Skip to content

Commit

Permalink
Fix mozilla-mobile#6846 - Add Search button to tabbar in home screen (m…
Browse files Browse the repository at this point in the history
…ozilla-mobile#6853)

* Add Search button to tabbar in home screen
* Reduce icon flickering and add tests
  • Loading branch information
joeyg authored and dnarcese committed Jul 14, 2020
1 parent 8c3ef1e commit f76c41e
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 6 deletions.
4 changes: 4 additions & 0 deletions Client.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@
D4C4BDCE2253725E00986F04 /* LibraryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4C4BDCD2253725E00986F04 /* LibraryTests.swift */; };
D4F3D789232F960600FBB9AA /* WhatsNewTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F3D788232F960600FBB9AA /* WhatsNewTest.swift */; };
D81127D81F84023B0050841D /* PhotonActionSheetTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D81127D71F84023B0050841D /* PhotonActionSheetTest.swift */; };
D815A3A824A53F3200AAB221 /* TabToolbarHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D815A3A724A53F3200AAB221 /* TabToolbarHelperTests.swift */; };
D81E45131F82C56D004EFFBA /* NewTabContentSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D81E45121F82C56C004EFFBA /* NewTabContentSettingsViewController.swift */; };
D821E90E2141B71C00452C55 /* SiriSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D821E9052141B71C00452C55 /* SiriSettingsViewController.swift */; };
D82ED2641FEB3C420059570B /* DefaultSearchPrefsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D82ED2631FEB3C420059570B /* DefaultSearchPrefsTests.swift */; };
Expand Down Expand Up @@ -1630,6 +1631,7 @@
D4C4BDCD2253725E00986F04 /* LibraryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryTests.swift; sourceTree = "<group>"; };
D4F3D788232F960600FBB9AA /* WhatsNewTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhatsNewTest.swift; sourceTree = "<group>"; };
D81127D71F84023B0050841D /* PhotonActionSheetTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotonActionSheetTest.swift; sourceTree = "<group>"; };
D815A3A724A53F3200AAB221 /* TabToolbarHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabToolbarHelperTests.swift; sourceTree = "<group>"; };
D81E377D2242FF61006AC72D /* Client-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Client-Bridging-Header.h"; path = "Client/Client-Bridging-Header.h"; sourceTree = SOURCE_ROOT; };
D81E45121F82C56C004EFFBA /* NewTabContentSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTabContentSettingsViewController.swift; sourceTree = "<group>"; };
D821E9052141B71C00452C55 /* SiriSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SiriSettingsViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3531,6 +3533,7 @@
63306D442110BAF000F25400 /* TabManagerStoreTests.swift */,
E1D8BC7921FF7A0000B100BD /* TPStatsBlocklistsTests.swift */,
DACDE995225E537900C8F37F /* VersionSettingTests.swift */,
D815A3A724A53F3200AAB221 /* TabToolbarHelperTests.swift */,
);
path = ClientTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -5351,6 +5354,7 @@
3943A81D1E9807C700D4F6DC /* FxAPushMessageTest.swift in Sources */,
E60D032A1D5118DB002FE3F6 /* SyncStatusResolverTests.swift in Sources */,
E683F0A61E92E0820035D990 /* MockableHistory.swift in Sources */,
D815A3A824A53F3200AAB221 /* TabToolbarHelperTests.swift in Sources */,
A83E5B1E1C1DAAAA0026D912 /* UIPasteboardExtensions.swift in Sources */,
0BF42D4F1A7CD09600889E28 /* TestFavicons.swift in Sources */,
7BBFEE741BB405D900A305AA /* TabManagerTests.swift in Sources */,
Expand Down
2 changes: 2 additions & 0 deletions Client/Frontend/Browser/BrowserViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ class BrowserViewController: UIViewController {
}
})
view.setNeedsUpdateConstraints()
navigationToolbar.updateIsSearchStatus(true)
}

fileprivate func hideFirefoxHome() {
Expand All @@ -749,6 +750,7 @@ class BrowserViewController: UIViewController {
}

self.firefoxHomeViewController = nil
navigationToolbar.updateIsSearchStatus(false)
UIView.animate(withDuration: 0.2, delay: 0, options: .beginFromCurrentState, animations: { () -> Void in
firefoxHomeViewController.view.alpha = 0
}, completion: { _ in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,9 @@ extension BrowserViewController: TabToolbarDelegate, PhotonActionSheetProtocol {
self.present(backForwardViewController, animated: true, completion: nil)
}
}

func tabToolbarDidPressSearch(_ tabToolbar: TabToolbarProtocol, button: UIButton) {
focusLocationTextField(forTab: tabManager.selectedTab)
}
}

51 changes: 45 additions & 6 deletions Client/Frontend/Browser/TabToolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ protocol TabToolbarProtocol: AnyObject {
func updateForwardStatus(_ canGoForward: Bool)
func updateReloadStatus(_ isLoading: Bool)
func updatePageStatus(_ isWebPage: Bool)
func updateIsSearchStatus(_ isHomePage: Bool)
func updateTabCount(_ count: Int, animated: Bool)
func privateModeBadge(visible: Bool)
func appMenuBadge(setVisible: Bool)
Expand All @@ -38,6 +39,13 @@ protocol TabToolbarDelegate: AnyObject {
func tabToolbarDidPressLibrary(_ tabToolbar: TabToolbarProtocol, button: UIButton)
func tabToolbarDidPressTabs(_ tabToolbar: TabToolbarProtocol, button: UIButton)
func tabToolbarDidLongPressTabs(_ tabToolbar: TabToolbarProtocol, button: UIButton)
func tabToolbarDidPressSearch(_ tabToolbar: TabToolbarProtocol, button: UIButton)
}

fileprivate enum MiddleButtonState {
case reload
case stop
case search
}

@objcMembers
Expand All @@ -46,15 +54,40 @@ open class TabToolbarHelper: NSObject {

let ImageReload = UIImage.templateImageNamed("nav-refresh")
let ImageStop = UIImage.templateImageNamed("nav-stop")
let ImageSearch = UIImage.templateImageNamed("search")

var loading: Bool = false {
didSet {
if loading {
fileprivate func setMiddleButtonState(_ state: MiddleButtonState) {
switch state {
case .reload:
toolbar.stopReloadButton.setImage(ImageReload, for: .normal)
toolbar.stopReloadButton.accessibilityLabel = NSLocalizedString("Reload", comment: "Accessibility Label for the tab toolbar Reload button")
case .stop:
toolbar.stopReloadButton.setImage(ImageStop, for: .normal)
toolbar.stopReloadButton.accessibilityLabel = NSLocalizedString("Stop", comment: "Accessibility Label for the tab toolbar Stop button")
case .search:
toolbar.stopReloadButton.setImage(ImageSearch, for: .normal)
toolbar.stopReloadButton.accessibilityLabel = NSLocalizedString("Search", comment: "Accessibility Label for the tab toolbar Search button")
}
}

var loading: Bool = false {
didSet {
if !isSearch {
if loading {
setMiddleButtonState(.stop)
} else {
setMiddleButtonState(.reload)
}
}
}
}

var isSearch: Bool = false {
didSet {
if isSearch {
setMiddleButtonState(.search)
} else {
toolbar.stopReloadButton.setImage(ImageReload, for: .normal)
toolbar.stopReloadButton.accessibilityLabel = NSLocalizedString("Reload", comment: "Accessibility Label for the tab toolbar Reload button")
setMiddleButtonState(.stop)
}
}
}
Expand Down Expand Up @@ -142,6 +175,8 @@ open class TabToolbarHelper: NSObject {
func didClickStopReload() {
if loading {
toolbar.tabToolbarDelegate?.tabToolbarDidPressStop(toolbar, button: toolbar.stopReloadButton)
} else if isSearch {
toolbar.tabToolbarDelegate?.tabToolbarDidPressSearch(toolbar, button: toolbar.stopReloadButton)
} else {
toolbar.tabToolbarDelegate?.tabToolbarDidPressReload(toolbar, button: toolbar.stopReloadButton)
}
Expand Down Expand Up @@ -326,12 +361,16 @@ extension TabToolbar: TabToolbarProtocol {
}

func updatePageStatus(_ isWebPage: Bool) {
stopReloadButton.isEnabled = isWebPage

}

func updateTabCount(_ count: Int, animated: Bool) {
tabsButton.updateTabCount(count, animated: animated)
}

func updateIsSearchStatus(_ isSearch: Bool) {
helper?.isSearch = isSearch
}
}

extension TabToolbar: Themeable, PrivateModeUI {
Expand Down
4 changes: 4 additions & 0 deletions Client/Frontend/Browser/URLBarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,10 @@ extension URLBarView: TabToolbarProtocol {
stopReloadButton.isEnabled = isWebPage
}

func updateIsSearchStatus(_ isHomePag: Bool) {

}

var access: [Any]? {
get {
if inOverlayMode {
Expand Down
143 changes: 143 additions & 0 deletions ClientTests/TabToolbarHelperTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/* 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/. */

@testable import Client

import XCTest

class TabToolbarHelperTests: XCTestCase {
var subject: TabToolbarHelper!
var mockToolbar: MockTabToolbar!

let refreshButtonImage = UIImage.templateImageNamed("nav-refresh")
let backButtonImage = UIImage.templateImageNamed("nav-back")
let forwardButtonImage = UIImage.templateImageNamed("nav-forward")
let menuButtonImage = UIImage.templateImageNamed("nav-menu")
let libraryButtonImage = UIImage.templateImageNamed("menu-library")
let stopButtonImage = UIImage.templateImageNamed("nav-stop")
let searchButtonImage = UIImage.templateImageNamed("search")

override func setUp() {
super.setUp()
mockToolbar = MockTabToolbar()
subject = TabToolbarHelper(toolbar: mockToolbar)
}

func testSetsInitialImages() {
XCTAssertEqual(mockToolbar.stopReloadButton.image(for: .normal), refreshButtonImage)
XCTAssertEqual(mockToolbar.backButton.image(for: .normal), backButtonImage)
XCTAssertEqual(mockToolbar.forwardButton.image(for: .normal), forwardButtonImage)
}

func testSetLoadingStateImages() {
subject.loading = true
XCTAssertEqual(mockToolbar.stopReloadButton.image(for: .normal), stopButtonImage)
}

func testSetLoadedStateImages() {
subject.loading = false
XCTAssertEqual(mockToolbar.stopReloadButton.image(for: .normal), refreshButtonImage)
}

func testSearchStateImages() {
subject.isSearch = true
XCTAssertEqual(mockToolbar.stopReloadButton.image(for: .normal), searchButtonImage)
}

func testSearchStoppedStateImages() {
subject.isSearch = false
XCTAssertEqual(mockToolbar.stopReloadButton.image(for: .normal), stopButtonImage)
}

func testLoadingDoesNotOverwriteSearchState() {
subject.isSearch = true
subject.loading = true
XCTAssertEqual(mockToolbar.stopReloadButton.image(for: .normal), searchButtonImage)
}
}

class MockTabsButton: TabsButton {
init() {
super.init(frame: .zero)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

class MockToolbarButton: ToolbarButton {
init() {
super.init(frame: .zero)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

class MockTabToolbar: TabToolbarProtocol {
var tabToolbarDelegate: TabToolbarDelegate? {
get { return nil }
set { }
}

var _tabsButton = MockTabsButton()
var tabsButton: TabsButton {
get { _tabsButton }
}

var _appMenuButton = MockToolbarButton()
var appMenuButton: ToolbarButton { get { _appMenuButton } }

var _libraryButton = MockToolbarButton()
var libraryButton: ToolbarButton { get { _libraryButton } }

var _forwardButton = MockToolbarButton()
var forwardButton: ToolbarButton { get { _forwardButton } }

var _backButton = MockToolbarButton()
var backButton: ToolbarButton { get { _backButton } }

var _stopReloadButton = MockToolbarButton()
var stopReloadButton: ToolbarButton { get { _stopReloadButton } }
var actionButtons: [Themeable & UIButton] {
get { return [] }
}

func updateBackStatus(_ canGoBack: Bool) {

}

func updateForwardStatus(_ canGoForward: Bool) {

}

func updateReloadStatus(_ isLoading: Bool) {
}

func updatePageStatus(_ isWebPage: Bool) {

}

func updateIsSearchStatus(_ isHomePage: Bool) {

}

func updateTabCount(_ count: Int, animated: Bool) {

}

func privateModeBadge(visible: Bool) {

}

func appMenuBadge(setVisible: Bool) {

}

func warningMenuBadge(setVisible: Bool) {

}
}

0 comments on commit f76c41e

Please sign in to comment.