Skip to content

Commit

Permalink
Global controllers rewrite
Browse files Browse the repository at this point in the history
Fix select/deselect button switching
Replace DZNEmptyDataSet with BlankSlate
Add confirmation alert for all package removal attempts
Models are now with generics
  • Loading branch information
danpashin committed Jun 19, 2024
1 parent 9fbb4fb commit 826cf38
Show file tree
Hide file tree
Showing 53 changed files with 875 additions and 814 deletions.
1 change: 0 additions & 1 deletion twackup-gui/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ target "Twackup" do
platform :ios, "14.0"
use_frameworks! :linkage => :static

pod "DZNEmptyDataSet"
pod "StyledTextKit"

post_install do |installer|
Expand Down
6 changes: 1 addition & 5 deletions twackup-gui/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
PODS:
- DZNEmptyDataSet (1.8.1)
- StyledTextKit (0.2.0)

DEPENDENCIES:
- DZNEmptyDataSet
- StyledTextKit

SPEC REPOS:
trunk:
- DZNEmptyDataSet
- StyledTextKit

SPEC CHECKSUMS:
DZNEmptyDataSet: 9525833b9e68ac21c30253e1d3d7076cc828eaa7
StyledTextKit: dbfb29a59922c6f18897a0266acd139b7c9e712b

PODFILE CHECKSUM: 0333d228da71984d961f27bce3f4f90e02f0018b
PODFILE CHECKSUM: 344bd33b6be452101823bffd5448fc64f3ec1453

COCOAPODS: 1.15.2
113 changes: 69 additions & 44 deletions twackup-gui/Twackup.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
{
"originHash" : "839d123f1900edaad890380425ae489268bb665e6f7d1f35eee14d76b0126426",
"originHash" : "03268da808f69f46a11c728919d5ae418587344e0bf31a559a25c07b2d55fcf7",
"pins" : [
{
"identity" : "blankslate",
"kind" : "remoteSourceControl",
"location" : "https://github.com/liam-i/BlankSlate",
"state" : {
"revision" : "db6e0bddbb77182079a40dcb780aa4a85f93d784",
"version" : "0.7.1"
}
},
{
"identity" : "nuke",
"kind" : "remoteSourceControl",
Expand Down
35 changes: 26 additions & 9 deletions twackup-gui/Twackup/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -317,53 +317,53 @@
}
}
},
"debs-selectall-btn" : {
"debs-share-btn" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Select all"
"value" : "Share"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выбрать все"
"value" : "Поделиться"
}
}
}
},
"debs-share-btn" : {
"debs-short-title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Share"
"value" : "Rebuilt"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Поделиться"
"value" : "Собранные"
}
}
}
},
"debs-short-title" : {
"Deselect All" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rebuilt"
"value" : "Deselect all"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Собранные"
"value" : "Отменить выбор"
}
}
}
Expand Down Expand Up @@ -827,6 +827,23 @@
}
}
},
"Select All" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Select all"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Выбрать все"
}
}
}
},
"settings-app-version-label" : {
"localizations" : {
"en" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,23 @@ final class DpkgProgressNotifier: @unchecked Sendable {

private func startProcessing(_ package: FFIPackage) {
subscribers.forEach { subscriber in
Task(priority: .utility) {
Task(priority: .high) {
await subscriber.startProcessing(package: package)
}
}
}

private func finishedProcessing(_ package: FFIPackage, debURL: URL) {
subscribers.forEach { subscriber in
Task(priority: .utility) {
Task(priority: .high) {
await subscriber.finishedProcessing(package: package, debURL: debURL)
}
}
}

private func finishedAll() {
subscribers.forEach { subscriber in
Task(priority: .utility) {
Task(priority: .high) {
await subscriber.finishedAll()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
//

final class FFIPackage: Package, Sendable {
static func == (lhs: FFIPackage, rhs: FFIPackage) -> Bool {
lhs.id == rhs.id && lhs.version == rhs.version
}

private let pkg: TwPackage_t

let id: String
Expand Down Expand Up @@ -75,8 +79,9 @@ final class FFIPackage: Package, Sendable {
tw_package_release(pkg.inner)
}

func isEqualTo(_ other: Package) -> Bool {
id == other.id && version == other.version
func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(version)
}
}

Expand Down
12 changes: 12 additions & 0 deletions twackup-gui/Twackup/Sources/Helpers/Sequence.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// Sequence.swift
// Twackup
//
// Created by Daniil on 16.06.2024.
//

extension Sequence {
func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {
sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }
}
}
47 changes: 47 additions & 0 deletions twackup-gui/Twackup/Sources/Helpers/UnfairLock.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// UnfairLock.swift
// Twackup
//
// Created by Daniil on 16.06.2024.
//

final class UnfairLock<Value> {
private let lock = UnsafeMutablePointer<os_unfair_lock>.allocate(capacity: 1)

private var _value: Value

var value: Value {
get { whileLocked { _value } }
set { whileLocked { _value = newValue } }
}

init(value: Value) {
_value = value
lock.initialize(to: .init())
}

deinit {
lock.deinitialize(count: 1)
lock.deallocate()
}

func whileLocked<T>(_ action: () -> T) -> T {
os_unfair_lock_lock(lock)
defer { os_unfair_lock_unlock(lock) }
return action()
}
}

@propertyWrapper
struct UnfairLockWrap<Value> {
private let lock: UnfairLock<Value>

var wrappedValue: Value {
get { lock.value }
set { lock.value = newValue }
}

init(wrappedValue: Value) {
lock = UnfairLock(value: wrappedValue)
}
}
6 changes: 1 addition & 5 deletions twackup-gui/Twackup/Sources/Models/Database/Database.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ actor Database {
return try backroundContext.fetch(request).map { DebPackage(object: $0) }
}

func fetch(package: Package) throws -> DebPackage? {
func fetch<P: Package>(package: P) throws -> DebPackage? {
let request = DebPackageObject.fetchRequest(package: package)
guard let object = try backroundContext.fetch(request).first else {
return nil
Expand Down Expand Up @@ -102,10 +102,6 @@ actor Database {
_ = await execute(request: request, context: backroundContext)
}

func delete(packages: [Package]) async throws {
try await delete(packages: packages.compactMap { $0.asDEB })
}

func packagesSize() -> Int64 {
let request = DebPackageObject.debsSizeRequest()
guard let results = try? backroundContext.fetch(request) as? [[String: Int64]] else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import CoreData

final class DebPackage: Package, Sendable {
static func == (lhs: DebPackage, rhs: DebPackage) -> Bool {
lhs.id == rhs.id && lhs.version == rhs.version
}

let databaseID: NSManagedObjectID

let id: String
Expand Down Expand Up @@ -49,4 +53,9 @@ final class DebPackage: Package, Sendable {

debSize = Measurement(value: Double(object.debSize), unit: .bytes)
}

func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(version)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import CoreData

struct BuildedPackage: @unchecked Sendable {
let package: Package
let package: any Package

let debURL: URL
}
Expand All @@ -23,7 +23,7 @@ class DebPackageObject: NSManagedObject {
return request
}

class func fetchRequest(package: Package) -> NSFetchRequest<DebPackageObject> {
class func fetchRequest<P: Package>(package: P) -> NSFetchRequest<DebPackageObject> {
let request = NSFetchRequest<DebPackageObject>(entityName: entityName)
request.predicate = NSPredicate(format: "id == %@ && version == %@", package.id, package.version)
return request
Expand Down Expand Up @@ -65,7 +65,7 @@ class DebPackageObject: NSManagedObject {
relPath = file.path.deletePrefix(Dpkg.defaultSaveDirectory.path)
}

func fillFrom(package: Package) {
func fillFrom<P: Package>(package: P) {
assert(!package.name.isEmpty)
name = package.name
id = package.id
Expand Down
2 changes: 0 additions & 2 deletions twackup-gui/Twackup/Sources/Models/MainModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ class MainModel: @unchecked Sendable {

let dpkg: Dpkg

let logger = FFILogger.shared

let preferences: Preferences

private(set) lazy var databasePackageProvider = DatabasePackageProvider(database)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Daniil on 28.11.2022.
//

class DatabasePackageProvider: PackageDataProvider, @unchecked Sendable {
class DatabasePackageProvider: PackageDataProvider<DebPackage>, @unchecked Sendable {
private let database: Database

init(_ database: Database) {
Expand All @@ -14,38 +14,32 @@ class DatabasePackageProvider: PackageDataProvider, @unchecked Sendable {
super.init()
}

func reload() async throws {
override func reload() async throws {
allPackages = try await database.fetchPackages()
}

func deletePackages(at indexes: [Int]) async -> Bool {
let toDelete = packages.enumerated().filter { indexes.contains($0.offset) }.map { $0.element }
func deletePackages(at indexes: [Int]) async throws {
let toDelete = packages.enumerated().filter { indexes.contains($0.offset) }.map(\.element)
if toDelete.isEmpty {
return false
return
}

// refactor to use of SET
allPackages = allPackages.filter { package in
!toDelete.contains { $0.isEqualTo(package) }
}

do {
try await database.delete(packages: toDelete)
} catch {
await FFILogger.shared.log(error.localizedDescription, level: .warning)
return false
}

applyFilter(currentFilter)
try await delete(packages: toDelete)
}

return true
func deletePackage(at index: Int) async throws {
try await deletePackages(at: [index])
}

func deletePackage(at index: Int) async -> Bool {
await deletePackages(at: [index])
func delete(packages: [DebPackage]) async throws {
let snapshot = Set(allPackages).subtracting(Set(packages))
try await database.delete(packages: packages)

allPackages = snapshot.sorted(by: \.name)
applyFilter(currentFilter)
}

func deleteAll() async -> Bool {
await deletePackages(at: allPackages.indices.map { $0 })
func deleteAll() async throws {
try await delete(packages: allPackages)
}
}
Loading

0 comments on commit 826cf38

Please sign in to comment.