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

TPTweak 2.0 #14

Merged
merged 5 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@

# 2.0.0
- Minimizable TPTweakViewController with `TPTweakViewController.presentMinimizableTweaks`
- Hold navigation controller to peep the background(only available on non minimizable mode)
- now every option will have completions
- add Settings menu for setting up TPTweakViewController
- add an empty state message on the favourite page
- fix the favorite page not reflecting the latest value after modifying one of the cells.

# 1.2.0
- Add Search functionality ([#11](https://github.com/tokopedia/ios-tptweak/pull/11))
Expand Down
2 changes: 1 addition & 1 deletion Example/Example/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 Tokopedia. All rights reserved.
// Copyright 2022-2024 Tokopedia. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion Example/Example/TPTweakEntry+Extension.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 Tokopedia. All rights reserved.
// Copyright 2022-2024 Tokopedia. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion Example/Example/TrackingHistoryViewController.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 Tokopedia. All rights reserved.
// Copyright 2022-2024 Tokopedia. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion Example/Example/ViewController.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 Tokopedia. All rights reserved.
// Copyright 2022-2024 Tokopedia. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2022 Tokopedia
Copyright 2022-2024 Tokopedia

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ https://github.com/tokopedia/ios-tptweak

or manually add to your `Package.swift`
```swift
.package(url: "https://github.com/tokopedia/ios-tptweak", from: "1.0.0"),
.package(url: "https://github.com/tokopedia/ios-tptweak", from: "2.0.0"),
```

# Cocoapods
add this to your `Podfile`
```
pod 'TPTweak', '~> 1.0.0'
pod 'TPTweak', '~> 2.0.0'
```

# Nomenclature
Expand Down Expand Up @@ -178,7 +178,7 @@ TPTweakEntry.enableTracking.setValue(true)

# License
```
Copyright 2022 Tokopedia. All rights reserved.
Copyright 2022-2024 Tokopedia. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
46 changes: 38 additions & 8 deletions Sources/TPTweak/TPTweakEntry.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 Tokopedia. All rights reserved.
// Copyright 2022-2024 Tokopedia. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -12,16 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#if canImport(UIKit)
import Foundation
import UIKit

/**
Entry type, pick your poison
*/
public enum TPTweakEntryType {
case `switch`(defaultValue: Bool, closure: ((Bool) -> Void)? = nil)
case action(() -> Void)
case strings(item: [String], selected: String)
case numbers(item: [Double], selected: Double)
case `switch`(defaultValue: Bool, completion: ((Bool) -> Void)? = nil)
case action(accessoryType: UITableViewCell.AccessoryType = .disclosureIndicator, () -> Void)
case strings(item: [String], selected: String, completion: ((String) -> Void)? = nil)
case numbers(item: [Double], selected: Double, completion: ((Double) -> Void)? = nil)
}

/**
Expand All @@ -34,26 +36,31 @@ public struct TPTweakEntry {
public let section: String
/// Cell will be the name of cell on second page table of TPTweak
public let cell: String
/// icon on the left of the cell
public let cellLeftIcon: UIImage?

/// Will only visible on second page / TPTweakPickerViewController
public let footer: String?

/// type of Entry
public let type: TPTweakEntryType

public init(
category: String,
section: String,
cell: String,
footer: String?,
cellLeftIcon: UIImage? = nil,
footer: String? = nil,
type: TPTweakEntryType
) {
self.category = category
self.section = section
self.cell = cell
self.cellLeftIcon = cellLeftIcon
self.footer = footer
self.type = type
}

/**
Read current value of this entry on TPTweak

Expand Down Expand Up @@ -113,4 +120,27 @@ extension TPTweakEntry {
internal static var favourite: TPTweakEntry {
TPTweakEntry(category: "tptweak", section: "internal", cell: "favourite", footer: nil, type: .action({}))
}

internal static var peepOpacity: TPTweakEntry {
TPTweakEntry(
category: "Settings",
section: "Interaction",
cell: "Hold Opacity",
footer: "The opacity when you hold the navigation bar",
type: .numbers(item: [0, 0.25, 0.5, 0.75, 1], selected: 0.25)
)
}

internal static var clearCache: TPTweakEntry {
TPTweakEntry(
category: "Settings",
section: "Miscellaneous",
cell: "Reset",
footer: "This will reset all Tweaks to default value",
type: .action(accessoryType: .none, {
TPTweak.resetAll()
})
)
}
}
#endif
2 changes: 1 addition & 1 deletion Sources/TPTweak/TPTweakOptionsViewController.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 Tokopedia. All rights reserved.
// Copyright 2022-2024 Tokopedia. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
80 changes: 61 additions & 19 deletions Sources/TPTweak/TPTweakPickerViewController.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 Tokopedia. All rights reserved.
// Copyright 2022-2024 Tokopedia. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -69,6 +69,7 @@ internal final class TPTweakPickerViewController: UIViewController {
view.translatesAutoresizingMaskIntoConstraints = false
view.delegate = self
view.dataSource = self
view.keyboardDismissMode = .onDrag
view.register(UITableViewCell.self, forCellReuseIdentifier: "cell")

return view
Expand Down Expand Up @@ -149,13 +150,34 @@ internal final class TPTweakPickerViewController: UIViewController {
favourites.insert(identifier)

TPTweakEntry.favourite.setValue(favourites)
table.reloadData()
}

private func removeFavourite(identifier: String) {
var favourites = TPTweakEntry.favourite.getValue(Set<String>.self) ?? []
favourites.remove(identifier)

TPTweakEntry.favourite.setValue(favourites)

// update data
for (offset, section) in zip(_data.indices, _data) {
for (rowOffset, row) in zip(section.cells.indices, section.cells) where row.identifer == identifier {
// create new cell without the removed favourite
var newCells = section.cells
newCells.removeAll(where: { $0.identifer == identifier })

if newCells.isEmpty {
// if section does not have any cells, remove section
_data.removeAll(where: { $0.name == section.name })
} else {
// update section with new cells
guard let index = _data.firstIndex(where: { $0.name == section.name && $0.footer == section.footer }) else { continue }
_data[index].cells = newCells
}
}
}

table.reloadData()
}

private func createFavouriteSwipeButton(identifier: String) -> UIContextualAction {
Expand All @@ -166,7 +188,7 @@ internal final class TPTweakPickerViewController: UIViewController {
}

if #available(iOS 13.0, *) {
action.image = UIImage(systemName: "star.slash")
action.image = UIImage(systemName: "heart.slash")
}

action.backgroundColor = .systemRed
Expand All @@ -179,7 +201,7 @@ internal final class TPTweakPickerViewController: UIViewController {
}

if #available(iOS 13.0, *) {
action.image = UIImage(systemName: "star")
action.image = UIImage(systemName: "heart")
}

action.backgroundColor = .systemBlue
Expand All @@ -193,7 +215,7 @@ internal final class TPTweakPickerViewController: UIViewController {
if Self.isFavourite(identifier: identifier) {
return UIAction(
title: "Unfavourite",
image: UIImage(systemName: "star.slash"),
image: UIImage(systemName: "heart.slash"),
identifier: nil,
attributes: .destructive
) { [weak self] _ in
Expand All @@ -202,7 +224,7 @@ internal final class TPTweakPickerViewController: UIViewController {
} else {
return UIAction(
title: "Favourite",
image: UIImage(systemName: "star"),
image: UIImage(systemName: "heart"),
identifier: nil
) { [weak self] _ in
self?.setFavourite(identifier: identifier)
Expand All @@ -213,7 +235,22 @@ internal final class TPTweakPickerViewController: UIViewController {

extension TPTweakPickerViewController: UITableViewDataSource, UITableViewDelegate {
internal func numberOfSections(in _: UITableView) -> Int {
data.count
let count = data.count

// handling empty state
if count == 0 {
let emptyLabel = UILabel(frame: .zero)
emptyLabel.text = "You can Favorite a Tweaks by swipe or long press on the cell"
emptyLabel.textAlignment = .center
emptyLabel.numberOfLines = 0
emptyLabel.font = .boldSystemFont(ofSize: 16)

self.table.backgroundView = emptyLabel
} else {
self.table.backgroundView = nil
}

return count
}

internal func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
Expand All @@ -226,12 +263,14 @@ extension TPTweakPickerViewController: UITableViewDataSource, UITableViewDelegat
}

let cellData = data[indexPath.section].cells[indexPath.row]

cell.imageView?.image = cellData.leftIcon

switch cellData.type {
case .action:
cell.textLabel?.text = cellData.name
cell.detailTextLabel?.text = nil
cell.accessoryType = .disclosureIndicator
// custom accessoryType only available for action type
cell.accessoryType = cellData.accessoryType
case .switch:
let switcher = UISwitch()
switcher.isOn = TPTweakStore.read(type: Bool.self, identifier: cellData.identifer) ?? false
Expand All @@ -240,14 +279,14 @@ extension TPTweakPickerViewController: UITableViewDataSource, UITableViewDelegat
cell.textLabel?.text = cellData.name
cell.detailTextLabel?.text = nil
cell.accessoryView = switcher
case let .strings(_, defaultValue):
case let .strings(_, defaultValue, _):
let currentValue = TPTweakStore.read(type: String.self, identifier: cellData.identifer) ?? defaultValue

cell = UITableViewCell(style: .value1, reuseIdentifier: "cell")
cell.detailTextLabel?.text = currentValue
cell.textLabel?.text = cellData.name
cell.accessoryType = .disclosureIndicator
case let .numbers(_, defaultValue):
case let .numbers(_, defaultValue, _):
let currentValue = TPTweakStore.read(type: Double.self, identifier: cellData.identifer) ?? defaultValue

cell = UITableViewCell(style: .value1, reuseIdentifier: "cell")
Expand Down Expand Up @@ -276,16 +315,16 @@ extension TPTweakPickerViewController: UITableViewDataSource, UITableViewDelegat

let cellData = data[indexPath.section].cells[indexPath.row]
switch cellData.type {
case let .action(closure):
closure()
case let .switch(_, closure):
case let .action(_, completion):
completion()
case let .switch(_, completion):
var value = TPTweakStore.read(type: Bool.self, identifier: cellData.identifer) ?? false
value.toggle()

TPTweakStore.set(value, identifier: cellData.identifer)
tableView.reloadRows(at: [indexPath], with: .none) // to update cell value after action
closure?(value)
case let .numbers(item, defaultValue):
completion?(value)
case let .numbers(item, defaultValue, completion):
let viewController = TPTweakOptionsViewController(
title: cellData.name,
data: item.map { TPTweakOptionsViewController<Double>.Cell(name: String($0), value: $0) },
Expand All @@ -295,14 +334,15 @@ extension TPTweakPickerViewController: UITableViewDataSource, UITableViewDelegat
viewController.didChoose = { [weak tableView, weak self] newValue in
TPTweakStore.set(newValue, identifier: cellData.identifer)
tableView?.reloadRows(at: [indexPath], with: .automatic) // to update cell value after action
completion?(newValue)

if let self = self {
self.closeDetail(viewController: viewController) // back to picker
}
}

openDetail(viewController: viewController)
case let .strings(item, defaultValue):
case let .strings(item, defaultValue, completion):
let viewController = TPTweakOptionsViewController(
title: cellData.name,
data: item.map { TPTweakOptionsViewController<String>.Cell(name: $0, value: $0) },
Expand All @@ -312,7 +352,8 @@ extension TPTweakPickerViewController: UITableViewDataSource, UITableViewDelegat
viewController.didChoose = { [weak tableView, weak self] newValue in
TPTweakStore.set(newValue, identifier: cellData.identifer)
tableView?.reloadRows(at: [indexPath], with: .automatic) // to update cell value after action

completion?(newValue)

if let self = self {
self.closeDetail(viewController: viewController) // back to picker
}
Expand All @@ -323,7 +364,6 @@ extension TPTweakPickerViewController: UITableViewDataSource, UITableViewDelegat
}

internal func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

let cellData = data[indexPath.section].cells[indexPath.row]
let action = createFavouriteSwipeButton(identifier: cellData.identifer)
return UISwipeActionsConfiguration(actions: [action])
Expand Down Expand Up @@ -361,14 +401,16 @@ extension TPTweakPickerViewController {
internal struct Section {
internal let name: String
internal let footer: String?
internal let cells: [Cell]
internal var cells: [Cell]
}

internal struct Cell {
internal let name: String
internal let identifer: String
internal let type: TPTweakEntryType
internal let leftIcon: UIImage?
internal let footer: String?
internal let accessoryType: UITableViewCell.AccessoryType
}
}
#endif
Loading
Loading