Skip to content

Commit

Permalink
Replace ObjC hud with Swift one
Browse files Browse the repository at this point in the history
  • Loading branch information
danpashin committed Jun 15, 2024
1 parent 9850c84 commit 2e9b9c7
Show file tree
Hide file tree
Showing 11 changed files with 470 additions and 729 deletions.
24 changes: 12 additions & 12 deletions twackup-gui/Twackup.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@
0B88C3172930CE3900BA5312 /* Metadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B88C3162930CE3900BA5312 /* Metadata.swift */; };
0B88C31C2930DE8C00BA5312 /* KeyValueLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B88C31B2930DE8C00BA5312 /* KeyValueLabelView.swift */; };
0B88C31E2930DEA200BA5312 /* PackageDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B88C31D2930DEA200BA5312 /* PackageDetailView.swift */; };
0BAAD9922937BE360089C8FB /* RJTHudProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BAAD98F2937BE350089C8FB /* RJTHudProgressView.m */; };
0BAAD9932937BE360089C8FB /* RJTHud.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BAAD9902937BE350089C8FB /* RJTHud.m */; };
0BAAD99729388D310089C8FB /* DebsListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BAAD99629388D310089C8FB /* DebsListVC.swift */; };
0BAAD99C293893EF0089C8FB /* DpkgDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BAAD99B293893EF0089C8FB /* DpkgDataProvider.swift */; };
0BAC44D429562BDE0038074C /* DebsListModel+DZNEmptyDataSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BAC44D329562BDE0038074C /* DebsListModel+DZNEmptyDataSet.swift */; };
Expand All @@ -70,6 +68,9 @@
0BE87E902C1E0565009C95A7 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BE87E8F2C1E0565009C95A7 /* Result.swift */; };
0BE87E932C1E05CE009C95A7 /* NukeUI in Frameworks */ = {isa = PBXBuildFile; productRef = 0BE87E922C1E05CE009C95A7 /* NukeUI */; };
0BE87E952C1E2214009C95A7 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 0BE87E942C1E2214009C95A7 /* Localizable.xcstrings */; };
0BE87E982C1E23A2009C95A7 /* Hud.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BE87E962C1E23A2009C95A7 /* Hud.swift */; };
0BE87E992C1E23A2009C95A7 /* HudCircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BE87E972C1E23A2009C95A7 /* HudCircularProgressView.swift */; };
0BE87E9D2C1E23D3009C95A7 /* UIWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BE87E9C2C1E23D3009C95A7 /* UIWindow.swift */; };
0BF07A502941027800EEC8FC /* SplitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BF07A4F2941027800EEC8FC /* SplitController.swift */; };
0BF07A62294335F700EEC8FC /* FFILogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BF07A61294335F700EEC8FC /* FFILogger.swift */; };
0BF07A6429433BE100EEC8FC /* LogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BF07A6329433BE100EEC8FC /* LogViewController.swift */; };
Expand Down Expand Up @@ -133,10 +134,6 @@
0B88C31B2930DE8C00BA5312 /* KeyValueLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueLabelView.swift; sourceTree = "<group>"; };
0B88C31D2930DEA200BA5312 /* PackageDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackageDetailView.swift; sourceTree = "<group>"; };
0B9EB5E1294B8C7700DED54D /* .swiftlint.yml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = "<group>"; };
0BAAD98E2937BE350089C8FB /* RJTHudProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RJTHudProgressView.h; sourceTree = "<group>"; };
0BAAD98F2937BE350089C8FB /* RJTHudProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RJTHudProgressView.m; sourceTree = "<group>"; };
0BAAD9902937BE350089C8FB /* RJTHud.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RJTHud.m; sourceTree = "<group>"; };
0BAAD9912937BE350089C8FB /* RJTHud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RJTHud.h; sourceTree = "<group>"; };
0BAAD9952937BE840089C8FB /* Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Bridging-Header.h"; path = "Twackup/Bridging-Header.h"; sourceTree = "<group>"; };
0BAAD99629388D310089C8FB /* DebsListVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebsListVC.swift; sourceTree = "<group>"; };
0BAAD99B293893EF0089C8FB /* DpkgDataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DpkgDataProvider.swift; sourceTree = "<group>"; };
Expand All @@ -149,6 +146,9 @@
0BE7803F294DC60C00AE77CE /* DpkgListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DpkgListModel.swift; sourceTree = "<group>"; };
0BE87E8F2C1E0565009C95A7 /* Result.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = "<group>"; };
0BE87E942C1E2214009C95A7 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
0BE87E962C1E23A2009C95A7 /* Hud.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hud.swift; sourceTree = "<group>"; };
0BE87E972C1E23A2009C95A7 /* HudCircularProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HudCircularProgressView.swift; sourceTree = "<group>"; };
0BE87E9C2C1E23D3009C95A7 /* UIWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIWindow.swift; sourceTree = "<group>"; };
0BF07A4F2941027800EEC8FC /* SplitController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitController.swift; sourceTree = "<group>"; };
0BF07A61294335F700EEC8FC /* FFILogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FFILogger.swift; sourceTree = "<group>"; };
0BF07A6329433BE100EEC8FC /* LogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -411,10 +411,9 @@
0BAAD9942937BE3A0089C8FB /* HUD */ = {
isa = PBXGroup;
children = (
0BAAD9912937BE350089C8FB /* RJTHud.h */,
0BAAD9902937BE350089C8FB /* RJTHud.m */,
0BAAD98E2937BE350089C8FB /* RJTHudProgressView.h */,
0BAAD98F2937BE350089C8FB /* RJTHudProgressView.m */,
0BE87E9C2C1E23D3009C95A7 /* UIWindow.swift */,
0BE87E962C1E23A2009C95A7 /* Hud.swift */,
0BE87E972C1E23A2009C95A7 /* HudCircularProgressView.swift */,
);
path = HUD;
sourceTree = "<group>";
Expand Down Expand Up @@ -627,15 +626,15 @@
0B88C31E2930DEA200BA5312 /* PackageDetailView.swift in Sources */,
0B85ABB7294C8E4C00B6C5CF /* DetailedLabelSUI.swift in Sources */,
0B86CDCD2C199FA500F3B4A0 /* Jailbreaks.swift in Sources */,
0BAAD9922937BE360089C8FB /* RJTHudProgressView.m in Sources */,
0B88C3152930CE2E00BA5312 /* PackageListModel.swift in Sources */,
0B0DBB6F2934FA58002F3BB2 /* String.swift in Sources */,
0B50FF6E2949B80900CF4BCF /* CapacityBarLabel.swift in Sources */,
0B5B328C2943827500B51274 /* PackagesRebuilder.swift in Sources */,
0B2636F02948EC0A003EA806 /* CapacityBarView.swift in Sources */,
0B5D3F972934CB2C00AE50F2 /* PackageDataProvider.swift in Sources */,
0BE87E982C1E23A2009C95A7 /* Hud.swift in Sources */,
0BE87E992C1E23A2009C95A7 /* HudCircularProgressView.swift in Sources */,
0B86616D2930ADA300EA4301 /* MainTabbarController.swift in Sources */,
0BAAD9932937BE360089C8FB /* RJTHud.m in Sources */,
0B50FF702949B82900CF4BCF /* CapacityView.swift in Sources */,
0B6BB2F1294A599D001E3B43 /* ProxiedObservedObject.swift in Sources */,
0B2636E62948B92E003EA806 /* SettingsViewController.swift in Sources */,
Expand All @@ -662,6 +661,7 @@
0B86CDF92C19AC4E00F3B4A0 /* dyn.c in Sources */,
0B0DBB72293501DE002F3BB2 /* Package.swift in Sources */,
0B86616B2930ADA300EA4301 /* SceneDelegate.swift in Sources */,
0BE87E9D2C1E23D3009C95A7 /* UIWindow.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion twackup-gui/Twackup/Bridging-Header.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#define Twackup_Bridging_Header_h

#import "twackup.h"
#import "RJTHUD.h"
#import "libroot.h"
#import <UIKit/UIScrollView.h>

@interface UIScrollView (Private)
@property (assign, nonatomic, readonly, getter=_minimumContentOffset) CGPoint minimumContentOffset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,13 @@ class DpkgDetailVC: PackageDetailVC, RebuildPackageDetailedViewDelegate {
override var detailView: PackageDetailedView { _container }

nonisolated func rebuild(_ package: FFIPackage) {
Task(priority: .userInitiated) {
let hud = await RJTHud.show()
Task {
let hud = await Hud.show()

Task(priority: .utility) {
let rebuilder = PackagesRebuilder(mainModel: mainModel)
await rebuilder.rebuild(packages: [package])
let rebuilder = PackagesRebuilder(mainModel: mainModel)
await rebuilder.rebuild(packages: [package])

Task(priority: .userInitiated) {
await hud?.hide(animated: true)
}
}
await hud?.hide(animated: true)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class DpkgListVC: SelectablePackageListVC {
let dpkgModel: DpkgListModel

private var rebuildHUD: RJTHud?
private var rebuildHUD: Hud?

private lazy var rebuildAllBarBtn: UIBarButtonItem = {
let title = "debs-rebuildall-btn".localized
Expand Down Expand Up @@ -99,9 +99,9 @@ class DpkgListVC: SelectablePackageListVC {
func rebuild(packages: [Package]) {
guard !packages.isEmpty else { return }

rebuildHUD = RJTHud.show()
rebuildHUD = Hud.show()
rebuildHUD?.text = "rebuild-packages-status-title".localized
rebuildHUD?.style = .spinner
rebuildHUD?.style = .arcRotate

Task(priority: .medium) {
let rebuilder = PackagesRebuilder(mainModel: model.mainModel) { progress in
Expand All @@ -116,7 +116,7 @@ class DpkgListVC: SelectablePackageListVC {
}

func updateProgress(_ progress: Progress) {
let hud = RJTHud.show()
let hud = Hud.show()
hud?.detailedText = String(
format: "rebuild-packages-status".localized,
progress.completedUnitCount,
Expand Down
248 changes: 248 additions & 0 deletions twackup-gui/Twackup/Sources/Views/HUD/Hud.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
//
// HudCircularProgressView.swift
// iAppsDRM
//
// Created by Daniil on 10.01.2024.
//

import UIKit

final class Hud: UIView {
enum Style {
case arc, arcRotate, textOnly
}

var progress: CGFloat {
get {
progressView.progress
}
set {
setProgress(newValue, animated: false)
}
}

var style: Style = .arcRotate {
didSet {
updateProgressView()
}
}

var text: String? {
didSet {
setText(text, for: textLabel)
}
}

var detailedText: String? {
didSet {
setText(detailedText, for: detailedTextLabel)
}
}

var blurStyle: UIBlurEffect.Style = .systemThickMaterial {
didSet {
blurView.effect = UIBlurEffect(style: blurStyle)
}
}

var cornerRadius: CGFloat = 24.0 {
didSet {
blurView.layer.cornerRadius = cornerRadius
}
}

private lazy var blurView: UIVisualEffectView = {
let view = UIVisualEffectView(effect: UIBlurEffect(style: blurStyle))
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.masksToBounds = true
view.layer.cornerRadius = cornerRadius
view.layer.cornerCurve = .continuous
view.backgroundColor = .init(white: 1.0, alpha: 0.3)

view.contentView.layoutMargins = UIEdgeInsets(top: 24.0, left: 24.0, bottom: 24.0, right: 24.0)

return view
}()

private(set) lazy var progressView: HudCircularProgressView = {
HudCircularProgressView(frame: CGRect(x: 0.0, y: 0.0, width: 66.0, height: 66.0))
}()

private lazy var textLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 1
label.textAlignment = .center
label.textColor = .label
label.font = UIFont.boldSystemFont(ofSize: UIFont.buttonFontSize)

return label
}()

private lazy var detailedTextLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.textAlignment = .center
label.textColor = .secondaryLabel
label.font = UIFont.boldSystemFont(ofSize: UIFont.systemFontSize)

return label
}()

private lazy var stackView: UIStackView = {
let view = UIStackView(arrangedSubviews: [progressView, textLabel, detailedTextLabel])
view.translatesAutoresizingMaskIntoConstraints = false
view.axis = .vertical
view.alignment = .center
view.spacing = 10.0
view.setCustomSpacing(24.0, after: progressView)

return view
}()

override init(frame: CGRect) {
super.init(frame: .zero)

tintColor = .systemGray

layer.shadowOpacity = 0.2
layer.shadowRadius = 10.0
layer.shadowOffset = CGSize(width: 0.0, height: 10.0)
layer.shadowColor = UIColor.black.cgColor

let blurContent = blurView.contentView
let blurContentMargins = blurContent.layoutMarginsGuide

blurContent.addSubview(stackView)
addSubview(blurView)

NSLayoutConstraint.activate([
blurView.topAnchor.constraint(equalTo: topAnchor),
blurView.bottomAnchor.constraint(equalTo: bottomAnchor),
blurView.leadingAnchor.constraint(equalTo: leadingAnchor),
blurView.trailingAnchor.constraint(equalTo: trailingAnchor),

stackView.topAnchor.constraint(equalTo: blurContentMargins.topAnchor),
stackView.bottomAnchor.constraint(equalTo: blurContentMargins.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: blurContentMargins.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: blurContentMargins.trailingAnchor)
])
}

@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

static func show() -> Self? {
guard
let scene = UIWindow.focusedScene,
let keyWindow = scene.windows.first(where: { $0.isKeyWindow })
else { return nil }

let hud = Self()
hud.show(on: keyWindow, animated: true)

return hud
}

override func layoutSubviews() {
super.layoutSubviews()

layer.shadowPath = CGPath(
roundedRect: bounds,
cornerWidth: cornerRadius,
cornerHeight: cornerRadius,
transform: nil
)
}

override func tintColorDidChange() {
super.tintColorDidChange()

progressView.tintColor = tintColor
}

override func didMoveToSuperview() {
super.didMoveToSuperview()

if let superview {
translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
centerXAnchor.constraint(equalTo: superview.centerXAnchor),
centerYAnchor.constraint(equalTo: superview.centerYAnchor)
])

updateProgressView()
}
}

// MARK: - Public methods

func show(on view: UIView, animated: Bool = true) {
if animated {
alpha = 0.0
view.addSubview(self)

UIView.animate(withDuration: 0.25) { [self] in
alpha = 1.0
}
} else {
view.addSubview(self)
}
}

func hide(animated: Bool = true, delaySec: TimeInterval? = nil) async {
if let delaySec {
try? await Task.sleep(nanoseconds: UInt64(delaySec) * 1_000_000_000)
}

if animated {
UIView.animate(withDuration: 0.5) { [self] in
alpha = 0.0
} completion: { [self] _ in
progressView.stopAnimation()
removeFromSuperview()
}
} else {
progressView.stopAnimation()
removeFromSuperview()
}
}

func setProgress(_ progress: CGFloat, animated: Bool) {
progressView.setProgress(progress, animated: animated)
}

// MARK: - Private methods

private func updateProgressView() {
let isAlreadyAnimating = progressView.isAnimating

switch style {
case .arc:
progressView.animationStyle = .arc
progressView.runAnimation()

case .arcRotate:
progressView.animationStyle = .arcRotate
progressView.runAnimation()

default:
progressView.stopAnimation()
}

if isAlreadyAnimating != progressView.isAnimating {
progressView.invalidateIntrinsicContentSize()
}
}

private func setText(_ text: String?, for label: UILabel) {
let textTransition = CATransition()
textTransition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
textTransition.type = .fade
textTransition.duration = 0.5
label.layer.add(textTransition, forKey: "textChangeAnimation")
label.text = text
}
}
Loading

0 comments on commit 2e9b9c7

Please sign in to comment.