mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-27 22:10:57 -04:00
Library free space detection
This commit is contained in:
parent
a76b45eb4c
commit
d841c3b982
@ -13,6 +13,7 @@ import DZNEmptyDataSet
|
|||||||
|
|
||||||
class LibraryBooksController: CoreDataCollectionBaseController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, LibraryCollectionCellDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
|
class LibraryBooksController: CoreDataCollectionBaseController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, LibraryCollectionCellDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
|
||||||
private(set) var itemWidth: CGFloat = 0.0
|
private(set) var itemWidth: CGFloat = 0.0
|
||||||
|
private(set) var freeDiskSpace: Int64 = 0
|
||||||
var isCloudTab = true {
|
var isCloudTab = true {
|
||||||
didSet {
|
didSet {
|
||||||
title = isCloudTab ? Localized.Library.cloudTitle : Localized.Library.localTitle
|
title = isCloudTab ? Localized.Library.cloudTitle : Localized.Library.localTitle
|
||||||
@ -32,6 +33,22 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView
|
|||||||
itemWidth = (collectionViewWidth - 1 * (itemsPerRow - 1)) / itemsPerRow
|
itemWidth = (collectionViewWidth - 1 * (itemsPerRow - 1)) / itemsPerRow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAvailableDiskSpace() -> Int64 {
|
||||||
|
let docDirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
|
||||||
|
let systemAttributes = try! FileManager.default.attributesOfFileSystem(forPath: docDirPath)
|
||||||
|
return (systemAttributes[FileAttributeKey.systemFreeSize] as! NSNumber).int64Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBookSpaceStatus(fileSize: Int64) -> SpaceStatus {
|
||||||
|
if (0.8 * Double(freeDiskSpace)) > Double(fileSize) {
|
||||||
|
return .enough
|
||||||
|
} else if freeDiskSpace < fileSize{
|
||||||
|
return .notEnough
|
||||||
|
} else {
|
||||||
|
return .caution
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Override
|
// MARK: - Override
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
@ -39,7 +56,10 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView
|
|||||||
|
|
||||||
configureBarButtons()
|
configureBarButtons()
|
||||||
configureCollectionViewLayout()
|
configureCollectionViewLayout()
|
||||||
if isCloudTab { configureRefreshControl() }
|
if isCloudTab {
|
||||||
|
freeDiskSpace = getAvailableDiskSpace()
|
||||||
|
configureRefreshControl()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
@ -172,6 +192,7 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView
|
|||||||
].flatMap({$0}).joined(separator: " ")
|
].flatMap({$0}).joined(separator: " ")
|
||||||
cell.descriptionLabel.text = book.desc
|
cell.descriptionLabel.text = book.desc
|
||||||
cell.hasPicLabel.isHidden = !book.hasPic
|
cell.hasPicLabel.isHidden = !book.hasPic
|
||||||
|
cell.spaceStatus = getBookSpaceStatus(fileSize: book.fileSize)
|
||||||
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
@ -194,7 +215,7 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView
|
|||||||
guard let indexPath = collectionView.indexPath(for: cell) else {return}
|
guard let indexPath = collectionView.indexPath(for: cell) else {return}
|
||||||
let book = fetchedResultController.object(at: indexPath)
|
let book = fetchedResultController.object(at: indexPath)
|
||||||
|
|
||||||
let procedure = AlertProcedure.Library.more(context: self, book: book)
|
let procedure = AlertProcedure.Library.more(context: self, book: book, spaceStatus: cell.spaceStatus)
|
||||||
procedure.alert.modalPresentationStyle = .popover
|
procedure.alert.modalPresentationStyle = .popover
|
||||||
procedure.alert.popoverPresentationController?.sourceView = cell.moreButton
|
procedure.alert.popoverPresentationController?.sourceView = cell.moreButton
|
||||||
procedure.alert.popoverPresentationController?.sourceRect = cell.moreButton.bounds
|
procedure.alert.popoverPresentationController?.sourceRect = cell.moreButton.bounds
|
||||||
|
@ -154,6 +154,31 @@ class LibraryCollectionCell: UICollectionViewCell {
|
|||||||
delegate?.didTapMoreButton(cell: self)
|
delegate?.didTapMoreButton(cell: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var spaceStatus: SpaceStatus = .enough {
|
||||||
|
didSet {
|
||||||
|
switch spaceStatus {
|
||||||
|
case .enough:
|
||||||
|
titleLabel.textColor = UIColor.black
|
||||||
|
subtitleLabel.textColor = UIColor.black
|
||||||
|
descriptionLabel.textColor = UIColor.black
|
||||||
|
hasPicLabel.textColor = UIColor.orange
|
||||||
|
hasPicLabel.layer.borderColor = UIColor.orange.cgColor
|
||||||
|
case .caution:
|
||||||
|
titleLabel.textColor = UIColor.orange
|
||||||
|
subtitleLabel.textColor = UIColor.orange
|
||||||
|
descriptionLabel.textColor = UIColor.orange
|
||||||
|
hasPicLabel.textColor = UIColor.orange
|
||||||
|
hasPicLabel.layer.borderColor = UIColor.orange.cgColor
|
||||||
|
case .notEnough:
|
||||||
|
titleLabel.textColor = UIColor.gray
|
||||||
|
subtitleLabel.textColor = UIColor.gray
|
||||||
|
descriptionLabel.textColor = UIColor.gray
|
||||||
|
hasPicLabel.textColor = UIColor.gray
|
||||||
|
hasPicLabel.layer.borderColor = UIColor.gray.cgColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
weak var delegate: LibraryCollectionCellDelegate?
|
weak var delegate: LibraryCollectionCellDelegate?
|
||||||
@IBOutlet weak var imageView: UIImageView!
|
@IBOutlet weak var imageView: UIImageView!
|
||||||
@IBOutlet weak var titleLabel: UILabel!
|
@IBOutlet weak var titleLabel: UILabel!
|
||||||
@ -163,6 +188,11 @@ class LibraryCollectionCell: UICollectionViewCell {
|
|||||||
@IBOutlet weak var moreButton: UIButton!
|
@IBOutlet weak var moreButton: UIButton!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum SpaceStatus {
|
||||||
|
case enough, caution, notEnough
|
||||||
|
}
|
||||||
|
|
||||||
protocol LibraryCollectionCellDelegate: class {
|
protocol LibraryCollectionCellDelegate: class {
|
||||||
func didTapMoreButton(cell: LibraryCollectionCell)
|
func didTapMoreButton(cell: LibraryCollectionCell)
|
||||||
}
|
}
|
||||||
|
@ -60,13 +60,3 @@ extension Bundle {
|
|||||||
return (Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String) ?? "Unknown"
|
return (Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String) ?? "Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension UIDevice {
|
|
||||||
class var availableDiskSpace: (freeSize: Int64, totalSize: Int64)? {
|
|
||||||
let docDirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
|
|
||||||
guard let systemAttributes = try? FileManager.default.attributesOfFileSystem(forPath: docDirPath),
|
|
||||||
let freeSize = (systemAttributes[FileAttributeKey.systemFreeSize] as? NSNumber)?.int64Value,
|
|
||||||
let totalSize = (systemAttributes[FileAttributeKey.systemSize] as? NSNumber)?.int64Value else {return nil}
|
|
||||||
return (freeSize, totalSize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -228,17 +228,6 @@ class Book: NSManagedObject {
|
|||||||
stateRaw = Int16(newValue.rawValue)
|
stateRaw = Int16(newValue.rawValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var spaceState: BookSpaceState {
|
|
||||||
guard let freeSpaceInBytes = UIDevice.availableDiskSpace?.freeSize else {return .enough}
|
|
||||||
if (0.8 * Double(freeSpaceInBytes)) > Double(fileSize) {
|
|
||||||
return .enough
|
|
||||||
} else if freeSpaceInBytes < fileSize{
|
|
||||||
return .notEnough
|
|
||||||
} else {
|
|
||||||
return .caution
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BookState: Int, CustomStringConvertible {
|
enum BookState: Int, CustomStringConvertible {
|
||||||
@ -253,8 +242,3 @@ enum BookState: Int, CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum BookSpaceState: Int {
|
|
||||||
case enough, caution, notEnough
|
|
||||||
}
|
|
||||||
|
@ -114,11 +114,20 @@ extension AlertProcedure {
|
|||||||
return alert
|
return alert
|
||||||
}
|
}
|
||||||
|
|
||||||
static func more(context: UIViewController, book: Book) -> AlertProcedure {
|
static func more(context: UIViewController, book: Book, spaceStatus: SpaceStatus) -> AlertProcedure {
|
||||||
assert(Thread.isMainThread)
|
assert(Thread.isMainThread)
|
||||||
let alert = AlertProcedure(presentAlertFrom: context, withPreferredStyle: .actionSheet, waitForDismissal: true)
|
let alert = AlertProcedure(presentAlertFrom: context, withPreferredStyle: .actionSheet, waitForDismissal: true)
|
||||||
alert.title = book.title
|
alert.title = book.title
|
||||||
alert.message = book.desc
|
alert.message = {
|
||||||
|
switch spaceStatus {
|
||||||
|
case .enough:
|
||||||
|
return book.desc
|
||||||
|
case .caution:
|
||||||
|
return "Caution: This book will take up more than 80% of the free space on your device!"
|
||||||
|
case .notEnough:
|
||||||
|
return "You cannot start downloading, because your device does not have enough free space for this book."
|
||||||
|
}
|
||||||
|
}()
|
||||||
if book.state == .cloud {
|
if book.state == .cloud {
|
||||||
alert.add(actionWithTitle: Localized.Library.download, style: .default) { _ in
|
alert.add(actionWithTitle: Localized.Library.download, style: .default) { _ in
|
||||||
Network.shared.start(bookID: book.id)
|
Network.shared.start(bookID: book.id)
|
||||||
@ -137,6 +146,7 @@ extension AlertProcedure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
alert.add(actionWithTitle: Localized.Common.cancel, style: .cancel) { _ in alert.finish() }
|
alert.add(actionWithTitle: Localized.Common.cancel, style: .cancel) { _ in alert.finish() }
|
||||||
|
alert.actions.first?.isEnabled = spaceStatus != .notEnough
|
||||||
return alert
|
return alert
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user