Skip to content

Commit

Permalink
Merge pull request #7 from tschob/feature/qamenu-configuration-items
Browse files Browse the repository at this point in the history
Persist trigger and dismiss behavior configuration in user defaults
  • Loading branch information
tschob authored Feb 2, 2021
2 parents 966a838 + d37f097 commit bd3e755
Show file tree
Hide file tree
Showing 32 changed files with 1,226 additions and 97 deletions.
1 change: 0 additions & 1 deletion .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ opt_in_rules:
- file_name_no_space
- file_types_order
- force_unwrapping
- let_var_whitespace
- lower_acl_than_parent
- modifier_order
- multiline_arguments
Expand Down
17 changes: 12 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@

#### Breaking Changes

* [QAMenu] Renamed parameter `isSearchable` to `isPaneSearchable` in `Item.asChildPaneItem()` (MR #6)
* [QAMenu] Renamed parameter `isSearchable` to `isPaneSearchable` in `Item.asChildPaneItem()` (PR #6)
* [QAMenu] Removed parameter `trigger` from `QAMenu()` in favor of `QAMenu.setTrigger()` (PR #7)
* [QAMenu] Renamed `QAMenuDismissBehavior` to `QAMenu.DismissBehavior()` (PR #7)
* [QAMenuCatalog] `QAMenu.Catalog.all()` requires now a `QAMenu` instance as parameter (PR #7)

#### Enhancements

* [QAMenu] Added missing `asChildPaneItem()` options to create items with values (MR #6)
* [QAMenu] Added missing `asChildPaneItem()` options to create items with values (PR #6)
* [QAMenu] Allow to pass the root pane after initializing `QAMenu` with `setRootPane()` (PR #7)
* [QAMenu] `QAMenu.Trigger` configuration is now backed by NSUserDefaults (PR #7)
* [QAMenu] Exposed configuration option `QAMenu.DismissBehavior` (PR #7)
* [QAMenuCatalog] Added group and items to be able to see and modify the QAMenu configuration (PR #7)

#### Bug Fixes

* [QAMenuUIKit] Fix not adapting layout when using split screen (MR #2)
* [QAMenuUIKit] Update status bar color when the app is showing a modal screen (MR #2)
* [QAMenuUIKit] Fix not adapting layout when using split screen (PR #2)
* [QAMenuUIKit] Update status bar color when the app is showing a modal screen (PR #2)


## 0.2.0
Expand All @@ -24,7 +31,7 @@

#### Enhancements

* [QAMenuUIKit] Remove custom navigate to root pane button and use back button titles again (MR #1)
* [QAMenuUIKit] Remove custom navigate to root pane button and use back button titles again (PR #1)

#### Bug Fixes

Expand Down
28 changes: 22 additions & 6 deletions Examples/Example-iOS/Sources/ExampleViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,29 @@ class ExampleViewController: UITableViewController {
}

private func setupShowcaseQAMenu() {
self.showcaseQAMenu = QAMenu(pane: ShowcaseItemsFactory.makeRootPane(), presenterType: QAMenuUIKitPresenter.self)
self.showcaseQAMenu = QAMenu(
identifier: "Simple QAMenu",
pane: ShowcaseItemsFactory.makeRootPane(),
presenterType: QAMenuUIKitPresenter.self
)
if let presenter = self.showcaseQAMenu?.presenter as? QAMenuUIKitPresenter {
presenter.ui.register(CustomPaneViewController.self, for: CustomPane.self)
}
}

private func setupCatalogQAMenu() {
self.catalogQAMenu = QAMenu(
pane: RootPane(title: .static("QA Menu Catalog"), groups: QAMenu.Catalog.all),
identifier: "Catalog QAMenu",
presenterType: QAMenuUIKitPresenter.self
)
self.catalogQAMenu?.setTrigger([], mode: .initialValue)
self.catalogQAMenu?.setDismissBehavior(.resetImmediately, mode: .initialValue)
self.catalogQAMenu?.setRootPane(
RootPane(
title: .static("QA Menu Catalog"),
groups: QAMenu.Catalog.all(qaMenu: self.catalogQAMenu)
)
)
}

private var simpleProjectCacheEnabled = true
Expand Down Expand Up @@ -166,14 +178,18 @@ class ExampleViewController: UITableViewController {
}
)
])
self.simpleProjectQAMenu = QAMenu(
identifier: "Simple QAMenu",
presenterType: QAMenuUIKitPresenter.self
)
let groups: [Group] = [
QAMenu.Catalog.AppInfo.group(),
cacheGroup,
QAMenu.Catalog.Preferences.group()
QAMenu.Catalog.Preferences.group(),
QAMenu.Catalog.QAMenuConfiguration.group(qaMenu: self.simpleProjectQAMenu)
]
self.simpleProjectQAMenu = QAMenu(
pane: RootPane(title: .static("Simple Project"), groups: groups),
presenterType: QAMenuUIKitPresenter.self
self.simpleProjectQAMenu?.setRootPane(
RootPane(title: .static("Simple Project"), groups: groups)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

self.qaMenu = QAMenu(pane: RootPane(groups: QAMenu.Catalog.all), presenterType: QAMenuUIKitPresenter.self)
self.qaMenu = QAMenu(presenterType: QAMenuUIKitPresenter.self)
self.qaMenu?.setRootPane(RootPane(groups: QAMenu.Catalog.all(qaMenu: self.qaMenu)))
}

@IBAction private func showQAMenu(_ sender: Any) {
Expand Down
16 changes: 8 additions & 8 deletions Examples/Pod-Integration/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
PODS:
- QAMenu (0.1.0):
- QAMenu (0.2.0):
- QAMenuUtils
- QAMenuCatalog (0.1.0):
- QAMenuCatalog (0.2.0):
- QAMenu
- QAMenuUIKit (0.1.0):
- QAMenuUIKit (0.2.0):
- QAMenu
- QAMenuUtils (0.1.0)
- QAMenuUtils (0.2.0)

DEPENDENCIES:
- QAMenu (from `../..`)
Expand All @@ -24,10 +24,10 @@ EXTERNAL SOURCES:
:path: "../.."

SPEC CHECKSUMS:
QAMenu: 9dbc18fae328259da26d5f1494e13a4c2ea112da
QAMenuCatalog: b39b17b18002e9697ff784970b4da6c4010a10b7
QAMenuUIKit: ee79926c0ad022be07ee1ab5cd47652c90c8d982
QAMenuUtils: 8b29e285e6acc1ba46ee455e8c6dde0599f218d4
QAMenu: 4b2bdb83593499d55526f8a43440260c4af0027d
QAMenuCatalog: b8cfd5d4b1a9d41eb1140d63f06d428f4780b08c
QAMenuUIKit: eabc20413bcd35ca6fb46f395110034225514cf0
QAMenuUtils: 2f3670d4c7f8c951e2f3f29fb495c4acc37b70d2

PODFILE CHECKSUM: c44ec374043f6477287d76b1a823a5ed8712e2ed

Expand Down
30 changes: 29 additions & 1 deletion QAMenu.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@
A2172D2C25C9DF43009DC774 /* DisposableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172D0325C9DF43009DC774 /* DisposableTests.swift */; };
A2172D2D25C9DF43009DC774 /* DisposeBagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172D0425C9DF43009DC774 /* DisposeBagTests.swift */; };
A2172D7B25C9E4F0009DC774 /* RootPaneTests+Conversions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172D7A25C9E4F0009DC774 /* RootPaneTests+Conversions.swift */; };
A2172D9725C9EAD1009DC774 /* QAMenuConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172D9525C9EAD1009DC774 /* QAMenuConfiguration.swift */; };
A2172D9825C9EAD1009DC774 /* QAMenuConfigurationStorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172D9625C9EAD1009DC774 /* QAMenuConfigurationStorable.swift */; };
A2172D9F25C9EAEC009DC774 /* Catalog+QAMenuConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172D9E25C9EAEC009DC774 /* Catalog+QAMenuConfiguration.swift */; };
A2172DA725C9EB2D009DC774 /* QAMenuConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172DA525C9EB2D009DC774 /* QAMenuConfigurationTests.swift */; };
A2172DA825C9EB2D009DC774 /* QAMenu+DismissBehaviorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172DA625C9EB2D009DC774 /* QAMenu+DismissBehaviorTests.swift */; };
A2172DB925C9EE07009DC774 /* QAMenu+DismissBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172DB825C9EE07009DC774 /* QAMenu+DismissBehavior.swift */; };
A2172DC025C9F38D009DC774 /* QAMenu+TriggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2172DBF25C9F38D009DC774 /* QAMenu+TriggerTests.swift */; };
A2326E292558621500CB39E7 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2326E202558621500CB39E7 /* Logger.swift */; };
A2326E2A2558621500CB39E7 /* SwiftPrinter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2326E212558621500CB39E7 /* SwiftPrinter.swift */; };
A2326E2B2558621500CB39E7 /* SwiftDateProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2326E222558621500CB39E7 /* SwiftDateProvider.swift */; };
Expand Down Expand Up @@ -295,6 +302,13 @@
A2172D0425C9DF43009DC774 /* DisposeBagTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisposeBagTests.swift; sourceTree = "<group>"; };
A2172D0525C9DF43009DC774 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A2172D7A25C9E4F0009DC774 /* RootPaneTests+Conversions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RootPaneTests+Conversions.swift"; sourceTree = "<group>"; };
A2172D9525C9EAD1009DC774 /* QAMenuConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QAMenuConfiguration.swift; sourceTree = "<group>"; };
A2172D9625C9EAD1009DC774 /* QAMenuConfigurationStorable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QAMenuConfigurationStorable.swift; sourceTree = "<group>"; };
A2172D9E25C9EAEC009DC774 /* Catalog+QAMenuConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Catalog+QAMenuConfiguration.swift"; sourceTree = "<group>"; };
A2172DA525C9EB2D009DC774 /* QAMenuConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QAMenuConfigurationTests.swift; sourceTree = "<group>"; };
A2172DA625C9EB2D009DC774 /* QAMenu+DismissBehaviorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "QAMenu+DismissBehaviorTests.swift"; sourceTree = "<group>"; };
A2172DB825C9EE07009DC774 /* QAMenu+DismissBehavior.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "QAMenu+DismissBehavior.swift"; sourceTree = "<group>"; };
A2172DBF25C9F38D009DC774 /* QAMenu+TriggerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "QAMenu+TriggerTests.swift"; sourceTree = "<group>"; };
A2217BB7255806ED0070FC68 /* QAMenuUtils-UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "QAMenuUtils-UnitTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
A2217BEF2558081E0070FC68 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A2326E202558621500CB39E7 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -478,7 +492,10 @@
A2172CE625C9DF43009DC774 /* Data Structures */,
A2172CF925C9DF43009DC774 /* Dictionary+QAMenuTests.swift */,
A2172CFA25C9DF43009DC774 /* Utils */,
A2172DA625C9EB2D009DC774 /* QAMenu+DismissBehaviorTests.swift */,
A2172DBF25C9F38D009DC774 /* QAMenu+TriggerTests.swift */,
A2172CFE25C9DF43009DC774 /* QAMenu+LogTests.swift */,
A2172DA525C9EB2D009DC774 /* QAMenuConfigurationTests.swift */,
A2172D0025C9DF43009DC774 /* QAMenuTests.swift */,
A2172D0125C9DF43009DC774 /* Observable */,
A2172D0525C9DF43009DC774 /* Info.plist */,
Expand Down Expand Up @@ -668,8 +685,11 @@
A238A06B253C71AB0016BBD7 /* Utils */,
A28873E42516822A003528E5 /* Dictionary+QAMenu.swift */,
A28873E12516822A003528E5 /* QAMenu.swift */,
A2172DB825C9EE07009DC774 /* QAMenu+DismissBehavior.swift */,
A28873E22516822A003528E5 /* QAMenu+Log.swift */,
A28873E02516822A003528E5 /* QAMenu+Trigger.swift */,
A2172D9525C9EAD1009DC774 /* QAMenuConfiguration.swift */,
A2172D9625C9EAD1009DC774 /* QAMenuConfigurationStorable.swift */,
A28873E32516822A003528E5 /* QAMenuPresenter.swift */,
);
path = Public;
Expand Down Expand Up @@ -932,11 +952,12 @@
A2969E6025167D8600EA54D5 /* Public */ = {
isa = PBXGroup;
children = (
A2969E6125167D8600EA54D5 /* Catalog+AppInfo.swift */,
A2969E6225167D8600EA54D5 /* Catalog.Device+Accessibility.swift */,
A2969E6525167D8600EA54D5 /* Catalog.Device+Locale.swift */,
A2969E6125167D8600EA54D5 /* Catalog+AppInfo.swift */,
A2969E6325167D8600EA54D5 /* Catalog+Device.swift */,
A2969E6425167D8600EA54D5 /* Catalog+Preferences.swift */,
A2172D9E25C9EAEC009DC774 /* Catalog+QAMenuConfiguration.swift */,
A2969E6625167D8600EA54D5 /* QAMenu+Catalog.swift */,
);
path = Public;
Expand Down Expand Up @@ -1503,8 +1524,11 @@
A249DE60258FA0E2002AEC41 /* DialogTrigger.swift in Sources */,
A28873E92516822A003528E5 /* Searchable.swift in Sources */,
A238A06D253C71AC0016BBD7 /* Dynamic.swift in Sources */,
A2172D9825C9EAD1009DC774 /* QAMenuConfigurationStorable.swift in Sources */,
A249DE66258FA7A9002AEC41 /* NavigationTrigger.swift in Sources */,
A249DE46258E5CAD002AEC41 /* PickableItem.swift in Sources */,
A2172D9725C9EAD1009DC774 /* QAMenuConfiguration.swift in Sources */,
A2172DB925C9EE07009DC774 /* QAMenu+DismissBehavior.swift in Sources */,
A2BEC0E4257BFD5B0005EFDF /* PaneRepresentable.swift in Sources */,
A2EA8C9825867E25008F18DF /* PickerGroup.swift in Sources */,
A28873F22516822A003528E5 /* BoolItem.swift in Sources */,
Expand Down Expand Up @@ -1541,6 +1565,8 @@
A2172D0F25C9DF43009DC774 /* MockPane.swift in Sources */,
A2172D1F25C9DF43009DC774 /* PickableStringItemTests.swift in Sources */,
A2172D2225C9DF43009DC774 /* BoolItemTests.swift in Sources */,
A2172DA725C9EB2D009DC774 /* QAMenuConfigurationTests.swift in Sources */,
A2172DA825C9EB2D009DC774 /* QAMenu+DismissBehaviorTests.swift in Sources */,
A2172D1525C9DF43009DC774 /* SearchableTests.swift in Sources */,
A2172D1825C9DF43009DC774 /* RootPaneTests.swift in Sources */,
A2172D1225C9DF43009DC774 /* MockPickableItem.swift in Sources */,
Expand All @@ -1553,6 +1579,7 @@
A2172D2A25C9DF43009DC774 /* QAMenuTests.swift in Sources */,
A2172D1625C9DF43009DC774 /* PickerGroupTests.swift in Sources */,
A2172D1B25C9DF43009DC774 /* PickableItemTests.swift in Sources */,
A2172DC025C9F38D009DC774 /* QAMenu+TriggerTests.swift in Sources */,
A2172D1E25C9DF43009DC774 /* PickerGroupTests+Conversions.swift in Sources */,
A2172D1425C9DF43009DC774 /* MockItem.swift in Sources */,
A2172D2125C9DF43009DC774 /* ChildPaneItemTests.swift in Sources */,
Expand Down Expand Up @@ -1607,6 +1634,7 @@
A2969E6D25167D8600EA54D5 /* Catalog.Device+Locale.swift in Sources */,
A2969E6A25167D8600EA54D5 /* Catalog.Device+Accessibility.swift in Sources */,
A2969E6925167D8600EA54D5 /* Catalog+AppInfo.swift in Sources */,
A2172D9F25C9EAEC009DC774 /* Catalog+QAMenuConfiguration.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion Sources/QAMenu/Public/Data Structure/PickerGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ open class PickerGroup: Group, DialogTrigger, NavigationTrigger {
title: Dynamic<String?>? = nil,
options: [PickableItem],
footerText: Dynamic<String?>? = nil,
onPickedOption: @escaping ((_ item: PickableItem, _ result: ((PickResult) -> Void)) -> Void)
onPickedOption: @escaping (_ item: PickableItem, _ result: ((PickResult) -> Void)) -> Void
) {
self.title = title
self.options = options
Expand Down
76 changes: 76 additions & 0 deletions Sources/QAMenu/Public/QAMenu+DismissBehavior.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//
// QAMenu+DismissBehavior.swift
//
// Created by Hans Seiffert on 31.12.21.
//
// ---
// MIT License
//
// Copyright © 2021 Hans Seiffert
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//

import Foundation

// MARK: - QAMenu + DismissBehavior

extension QAMenu {

public enum DismissBehavior: Equatable {
case resetImmediately
case resetAfter(TimeInterval)
case neverReset
}
}

// MARK: - DismissBehavior + QAMenuConfigurationItemStorable

extension QAMenu.DismissBehavior: QAMenuConfigurationItemStorable {

public init?(stringValue: String) {
guard let timerInterval = TimeInterval(stringValue) else {
return nil
}
switch timerInterval {
case -1:
self = .neverReset
case 0:
self = .resetImmediately
case 1...:
self = .resetAfter(timerInterval)
default:
return nil
}
}

public var timerInterval: TimeInterval {
switch self {
case .resetImmediately:
return 0
case .resetAfter(let timeInterval):
return timeInterval
case .neverReset:
return -1
}
}

public var toString: String {
return String(self.timerInterval)
}
}
36 changes: 29 additions & 7 deletions Sources/QAMenu/Public/QAMenu+Trigger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,39 @@

import Foundation

extension QAMenu {
public extension QAMenu {

public struct Trigger: OptionSet {
public let rawValue: Int
enum Trigger: CaseIterable {
case shake

public init(rawValue: Int) {
self.rawValue = rawValue
public init?(stringValue: String) {
guard let instance = Self.allCases.first(where: { $0.key == stringValue }) else {
return nil
}
self = instance
}

public static let shake = Trigger(rawValue: 1 << 0)
public var key: String {
switch self {
case .shake:
return "shake"
}
}
}
}

// MARK: Array<Trigger> + QAMenuConfigurationItemStorable

extension Array: QAMenuConfigurationItemStorable where Element == QAMenu.Trigger {

public init?(stringValue: String) {
let components = stringValue.components(separatedBy: ",")
self = components.compactMap { QAMenu.Trigger(stringValue: $0) }
}

public static let all: Trigger = [.shake]
public var toString: String {
return self
.map { $0.key }
.joined(separator: ",")
}
}
Loading

0 comments on commit bd3e755

Please sign in to comment.