Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Search button to tabbar in home screen #6853

Merged
merged 5 commits into from
Jun 30, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Client.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,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 @@ -1622,6 +1623,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 @@ -3511,6 +3513,7 @@
63306D442110BAF000F25400 /* TabManagerStoreTests.swift */,
E1D8BC7921FF7A0000B100BD /* TPStatsBlocklistsTests.swift */,
DACDE995225E537900C8F37F /* VersionSettingTests.swift */,
D815A3A724A53F3200AAB221 /* TabToolbarHelperTests.swift */,
);
path = ClientTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -5327,6 +5330,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 @@ -740,6 +740,7 @@ class BrowserViewController: UIViewController {
}
})
view.setNeedsUpdateConstraints()
navigationToolbar.updateIsSearchStatus(true)
}

fileprivate func hideFirefoxHome() {
Expand All @@ -748,6 +749,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 @@ -184,5 +184,13 @@ extension BrowserViewController: TabToolbarDelegate, PhotonActionSheetProtocol {
self.present(backForwardViewController, animated: true, completion: nil)
}
}

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

func tabToolbarDidLongPressSearch(_ tabToolbar: TabToolbarProtocol, button: UIButton) {
nbhasin2 marked this conversation as resolved.
Show resolved Hide resolved

}
}

52 changes: 46 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,14 @@ 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)
func tabToolbarDidLongPressSearch(_ tabToolbar: TabToolbarProtocol, button: UIButton)
}

enum MiddleButtonState {
case reload
case stop
case search
}

@objcMembers
Expand All @@ -46,15 +55,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 {
func setMiddleButtonState(_ state: MiddleButtonState) {
nbhasin2 marked this conversation as resolved.
Show resolved Hide resolved
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 {
nbhasin2 marked this conversation as resolved.
Show resolved Hide resolved
didSet {
if !isSearch {
if loading {
setMiddleButtonState(.stop)
} else {
setMiddleButtonState(.reload)
}
}
}
}

var isSearch: Bool = false {
nbhasin2 marked this conversation as resolved.
Show resolved Hide resolved
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 +176,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 +362,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) {

}
}