Skip to content
Open
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
4 changes: 4 additions & 0 deletions Scribe.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,7 @@
E9FAC3A02E98972D008E00AC /* IDCommandVariables.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9FAC3882E9894F9008E00AC /* IDCommandVariables.swift */; };
E9FAC3A12E98972D008E00AC /* IDKeyboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9FAC38A2E9894F9008E00AC /* IDKeyboardViewController.swift */; };
E9FAC3A72E989A84008E00AC /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = E9FAC3A62E989A84008E00AC /* SwiftyJSON */; };
E9FEE6CB2EF14351003A9266 /* WrapperCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9FEE6CA2EF1433E003A9266 /* WrapperCell.swift */; };
ED2486F32B0B4E8C0038AE6A /* AboutTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED2486F12B0B4E8C0038AE6A /* AboutTableViewCell.swift */; };
ED2486F42B0B4E8C0038AE6A /* AboutTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = ED2486F22B0B4E8C0038AE6A /* AboutTableViewCell.xib */; };
EDB460212B03B3E400BEA967 /* BaseTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDB460202B03B3E400BEA967 /* BaseTableViewController.swift */; };
Expand Down Expand Up @@ -1246,6 +1247,7 @@
E9FAC3932E989712008E00AC /* Indonesian.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Indonesian.appex; sourceTree = BUILT_PRODUCTS_DIR; };
E9FAC3A42E9898B5008E00AC /* GRDB.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GRDB.swift; path = "/Users/purnamadev/Library/Developer/Xcode/DerivedData/Scribe-dbrvuamymhbpcmeozftkkqqvrdof/SourcePackages/checkouts/GRDB.swift"; sourceTree = "<absolute>"; };
E9FAC3A52E9898B9008E00AC /* GRDB.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GRDB.swift; path = "/Users/purnamadev/Library/Developer/Xcode/DerivedData/Scribe-dbrvuamymhbpcmeozftkkqqvrdof/SourcePackages/checkouts/GRDB.swift"; sourceTree = "<absolute>"; };
E9FEE6CA2EF1433E003A9266 /* WrapperCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrapperCell.swift; sourceTree = "<group>"; };
ED2486F12B0B4E8C0038AE6A /* AboutTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutTableViewCell.swift; sourceTree = "<group>"; };
ED2486F22B0B4E8C0038AE6A /* AboutTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AboutTableViewCell.xib; sourceTree = "<group>"; };
EDB460202B03B3E400BEA967 /* BaseTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTableViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1385,6 +1387,7 @@
1406B7852A2DFCBE001DF45B /* InfoChildTableViewCell */ = {
isa = PBXGroup;
children = (
E9FEE6CA2EF1433E003A9266 /* WrapperCell.swift */,
147797AE2A2CD3370044A53E /* InfoChildTableViewCell.swift */,
147797AF2A2CD3370044A53E /* InfoChildTableViewCell.xib */,
);
Expand Down Expand Up @@ -2651,6 +2654,7 @@
D1CDED832A85A12C00098546 /* NBCommandVariables.swift in Sources */,
D171944927AEF7290038660B /* KeyboardKeys.swift in Sources */,
147797B32A2CD5AB0044A53E /* ParentTableCellModel.swift in Sources */,
E9FEE6CB2EF14351003A9266 /* WrapperCell.swift in Sources */,
1401589B2A45A07200D14E52 /* WikimediaAndScribe.swift in Sources */,
3045396B293B9DC9003AE55B /* ToolTipViewDatasourceable.swift in Sources */,
D1B071A027C6A1AA00FD7DBD /* KeyAltChars.swift in Sources */,
Expand Down
32 changes: 26 additions & 6 deletions Scribe/AboutTab/AboutViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ final class AboutViewController: BaseTableViewController {

private var tipHostingController: UIHostingController<AboutTipCardView>!
private var tableViewOffset: CGFloat?
private let cornerRadius: CGFloat = 12

override func viewDidLoad() {
super.viewDidLoad()
showTipCardView()
title = NSLocalizedString("app.about.title", value: "About", comment: "")

tableView.register(WrapperCell.self,
forCellReuseIdentifier: WrapperCell.reuseIdentifier
)

tableView.register(
UINib(nibName: "AboutTableViewCell", bundle: nil),
forCellReuseIdentifier: AboutTableViewCell.reuseIdentifier
Expand All @@ -48,21 +53,36 @@ final class AboutViewController: BaseTableViewController {
extension AboutViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(
withIdentifier: AboutTableViewCell.reuseIdentifier,
withIdentifier: WrapperCell.reuseIdentifier,
for: indexPath
) as? AboutTableViewCell else {
fatalError("Failed to dequeue AboutTableViewCell.")
) as? WrapperCell else {
fatalError("Failed to dequeue WrapperCell")
}
cell.configureCell(for: dataSet[indexPath.section].section[indexPath.row])
cell.backgroundColor = lightWhiteDarkBlackColor

let section = dataSet[indexPath.section]
let setting = section.section[indexPath.row]

cell.configure(withCellNamed: "AboutTableViewCell", section: setting)

let isFirstRow = indexPath.row == 0
let isLastRow = indexPath.row == section.section.count - 1
WrapperCell.applyCornerRadius(to: cell, isFirst: isFirstRow, isLast: isLastRow)

return cell
}
}
}

// MARK: UITableViewDelegate

extension AboutViewController {
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let section = dataSet[indexPath.section]
let setting = section.section[indexPath.row]

let hasDescription = setting.shortDescription != nil
return hasDescription ? 80.0 : 48.0
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let tableSection = dataSet[indexPath.section]
let section = tableSection.section[indexPath.row]
Expand Down
19 changes: 14 additions & 5 deletions Scribe/SettingsTab/SettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ final class SettingsViewController: UIViewController {

private var sectionHeaderHeight: CGFloat = 0
private let separatorInset = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0)
private let cornerRadius: CGFloat = 12

private let settingsTipCardState: Bool = {
let userDefault = UserDefaults.standard
Expand Down Expand Up @@ -45,6 +46,11 @@ final class SettingsViewController: UIViewController {
title = NSLocalizedString("app.settings.title", value: "Settings", comment: "")
navigationItem.backButtonTitle = title

parentTable.register(
WrapperCell.self,
forCellReuseIdentifier: WrapperCell.reuseIdentifier
)

parentTable.register(
UINib(nibName: "InfoChildTableViewCell", bundle: nil),
forCellReuseIdentifier: InfoChildTableViewCell.reuseIdentifier
Expand Down Expand Up @@ -121,17 +127,20 @@ extension SettingsViewController: UITableViewDataSource {

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(
withIdentifier: InfoChildTableViewCell.reuseIdentifier,
withIdentifier: WrapperCell.reuseIdentifier,
for: indexPath
) as? InfoChildTableViewCell else {
fatalError("Failed to dequeue InfoChildTableViewCell")
) as? WrapperCell else {
fatalError("Failed to dequeue WrapperCell")
}

let section = tableData[indexPath.section]
let setting = section.section[indexPath.row]

cell.configureCell(for: setting)
cell.backgroundColor = lightWhiteDarkBlackColor
cell.configure(withCellNamed: "InfoChildTableViewCell", section: setting)

let isFirstRow = indexPath.row == 0
let isLastRow = indexPath.row == section.section.count - 1
WrapperCell.applyCornerRadius(to: cell, isFirst: isFirstRow, isLast: isLastRow)

return cell
}
Expand Down
118 changes: 118 additions & 0 deletions Scribe/Views/Cells/InfoChildTableViewCell/WrapperCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// SPDX-License-Identifier: GPL-3.0-or-later

import UIKit

protocol RoundableCell {
func applyCornerRadius(corners: CACornerMask, radius: CGFloat)
func removeCornerRadius()
}
/// Generic wrapper cell that can wrap any UITableViewCell with padding and corner radius support
class WrapperCell: UITableViewCell {
static let reuseIdentifier = "WrapperCell"

private let containerView = UIView()
private(set) var wrappedCell: UITableViewCell?

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupViews()
}

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

private func setupViews() {
backgroundColor = .clear
contentView.backgroundColor = .clear
selectionStyle = .none

containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.backgroundColor = lightWhiteDarkBlackColor
contentView.addSubview(containerView)

NSLayoutConstraint.activate([
containerView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
containerView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
containerView.topAnchor.constraint(equalTo: contentView.topAnchor),
containerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
])
}

/// Configure with any cell loaded from XIB
func configure(withCellNamed nibName: String, section: Section) {
wrappedCell?.removeFromSuperview()

guard let cell = Bundle.main.loadNibNamed(
nibName,
owner: nil,
options: nil
)?.first as? UITableViewCell else {
fatalError("Failed to load \(nibName) from XIB")
}

if let infoCell = cell as? InfoChildTableViewCell {
infoCell.configureCell(for: section)
} else if let aboutCell = cell as? AboutTableViewCell {
aboutCell.configureCell(for: section)
}

cell.backgroundColor = .clear
cell.translatesAutoresizingMaskIntoConstraints = false

containerView.addSubview(cell)

NSLayoutConstraint.activate([
cell.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
cell.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
cell.topAnchor.constraint(equalTo: containerView.topAnchor),
cell.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
])

wrappedCell = cell
}

func applyCornerRadius(corners: CACornerMask, radius: CGFloat) {
containerView.layer.maskedCorners = corners
containerView.layer.cornerRadius = radius
containerView.layer.masksToBounds = true
}

func removeCornerRadius() {
containerView.layer.cornerRadius = 0
containerView.layer.masksToBounds = false
}

// MARK: - Static Helper

/// Apply corner radius to a cell based on its position in the section
static func applyCornerRadius(
to cell: UITableViewCell,
isFirst: Bool,
isLast: Bool,
radius: CGFloat = 12
) {
guard let roundableCell = cell as? RoundableCell else { return }

if isFirst && isLast {
roundableCell.applyCornerRadius(
corners: [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner],
radius: radius
)
} else if isFirst {
roundableCell.applyCornerRadius(
corners: [.layerMinXMinYCorner, .layerMaxXMinYCorner],
radius: radius
)
} else if isLast {
roundableCell.applyCornerRadius(
corners: [.layerMinXMaxYCorner, .layerMaxXMaxYCorner],
radius: radius
)
} else {
roundableCell.removeCornerRadius()
}
}
}

extension WrapperCell: RoundableCell {}
52 changes: 43 additions & 9 deletions Scribe/Views/TableViewTemplateViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ final class TableViewTemplateViewController: BaseTableViewController {

private var tableData: [ParentTableCellModel] = []
private var parentSection: Section?
private let cornerRadius: CGFloat = 12

let userDefaults = UserDefaults(suiteName: "group.be.scri.userDefaultsContainer")!

Expand All @@ -35,6 +36,11 @@ final class TableViewTemplateViewController: BaseTableViewController {
override func viewDidLoad() {
super.viewDidLoad()

tableView.register(
WrapperCell.self,
forCellReuseIdentifier: WrapperCell.reuseIdentifier
)

tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 250
tableView.separatorStyle = .none
Expand All @@ -49,10 +55,23 @@ final class TableViewTemplateViewController: BaseTableViewController {

// Refreshes to check for changes when a translation language is selected
override func viewWillAppear(_ animated: Bool) {
for cell in tableView.visibleCells as! [InfoChildTableViewCell] where cell.section?.sectionState == .translateLang {
super.viewWillAppear(animated)

for visibleCell in tableView.visibleCells {
// Cast to wrapper cell first
guard let wrapperCell = visibleCell as? WrapperCell,
let innerCell = wrapperCell.wrappedCell as? InfoChildTableViewCell else { // Cast to specific type
continue
}

// Now check if it's a translate lang section
guard innerCell.section?.sectionState == .translateLang else {
continue
}

let langTranslateLanguage = getKeyInDict(givenValue: (userDefaults.string(forKey: langCode + "TranslateLanguage") ?? "en"), dict: languagesAbbrDict)
let currentLang = "app._global." + langTranslateLanguage.lowercased()
cell.subLabel.text = NSLocalizedString(currentLang, value: langTranslateLanguage, comment: "")
innerCell.subLabel.text = NSLocalizedString(currentLang, value: langTranslateLanguage, comment: "")
}
}
}
Expand All @@ -62,17 +81,32 @@ final class TableViewTemplateViewController: BaseTableViewController {
extension TableViewTemplateViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(
withIdentifier: InfoChildTableViewCell.reuseIdentifier,
withIdentifier: WrapperCell.reuseIdentifier,
for: indexPath
) as? InfoChildTableViewCell else {
fatalError("Failed to dequeue InfoChildTableViewCell.")
) as? WrapperCell else {
fatalError("Failed to dequeue WrapperCell")
}
cell.parentSection = parentSection
cell.configureCell(for: tableData[indexPath.section].section[indexPath.row])
cell.backgroundColor = lightWhiteDarkBlackColor

let section = dataSet[indexPath.section]
let setting = section.section[indexPath.row]

cell.configure(withCellNamed: "InfoChildTableViewCell", section: setting)

let isFirstRow = indexPath.row == 0
let isLastRow = indexPath.row == section.section.count - 1
WrapperCell.applyCornerRadius(to: cell, isFirst: isFirstRow, isLast: isLastRow)

return cell
}
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let section = tableData[indexPath.section]
let setting = section.section[indexPath.row]

// If has description, give it more height
let hasDescription = setting.shortDescription != nil
return hasDescription ? 100.0 : 60.0
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let tableSection = tableData[indexPath.section]
Expand Down
Loading
Loading