format
This commit is contained in:
@@ -192,6 +192,7 @@
|
|||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
@@ -245,6 +246,7 @@
|
|||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ import UIKit
|
|||||||
|
|
||||||
@UIApplicationMain
|
@UIApplicationMain
|
||||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
|
||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
|
||||||
func application(
|
func application(
|
||||||
_ application: UIApplication,
|
_: UIApplication,
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
|
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
window = UIWindow(frame: UIScreen.main.bounds)
|
window = UIWindow(frame: UIScreen.main.bounds)
|
||||||
window?.rootViewController = ViewController()
|
window?.rootViewController = ViewController()
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
//TODO: Anilist support?
|
// TODO: Anilist support?
|
||||||
//TODO: Properly avoid swallowing of input from UICollectionView used for scrolling
|
// TODO: Properly avoid swallowing of input from UICollectionView used for scrolling
|
||||||
//TODO: Convert between state for normal and scrolling page turn
|
// TODO: Convert between state for normal and scrolling page turn
|
||||||
//TODO: Support reading with scrolling and landscape mode
|
// TODO: Support reading with scrolling and landscape mode
|
||||||
//FIXME: Update comicCollectionView when switching between landscape and portrait mode
|
// FIXME: Update comicCollectionView when switching between landscape and portrait mode
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
@@ -103,8 +103,8 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
var imageView = UIImageView()
|
var imageView = UIImageView()
|
||||||
var mode = PageTurnMode.leftToRight
|
var mode = PageTurnMode.leftToRight
|
||||||
var metadata: Metadata!
|
var metadata: Metadata!
|
||||||
var currentPage: Int! = nil
|
var currentPage: Int!
|
||||||
var progress = ProgressIndices.init(v: 0, c: 0, i: 0)
|
var progress = ProgressIndices(v: 0, c: 0, i: 0)
|
||||||
var currentPath: URL!
|
var currentPath: URL!
|
||||||
|
|
||||||
var changedOrientation = false
|
var changedOrientation = false
|
||||||
@@ -136,7 +136,7 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
var comics: [Comic] = []
|
var comics: [Comic] = []
|
||||||
@IBOutlet var comicCollectionView: UICollectionView!
|
@IBOutlet var comicCollectionView: UICollectionView!
|
||||||
|
|
||||||
let imageLoader = ImageLoader.init()
|
let imageLoader = ImageLoader()
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
@@ -198,7 +198,8 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
comicCollectionView.delegate = self
|
comicCollectionView.delegate = self
|
||||||
comicCollectionView.backgroundColor = .white
|
comicCollectionView.backgroundColor = .white
|
||||||
comicCollectionView.register(
|
comicCollectionView.register(
|
||||||
ComicImageCell.self, forCellWithReuseIdentifier: "ComicImageCell")
|
ComicImageCell.self, forCellWithReuseIdentifier: "ComicImageCell"
|
||||||
|
)
|
||||||
homeView.addSubview(comicCollectionView)
|
homeView.addSubview(comicCollectionView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,13 +233,13 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
metadata = try JSONDecoder().decode(
|
metadata = try JSONDecoder().decode(
|
||||||
Metadata.self,
|
Metadata.self,
|
||||||
from:
|
from:
|
||||||
Data(
|
Data(
|
||||||
try String(
|
String(
|
||||||
contentsOfFile: dir.appendingPathComponent(
|
contentsOfFile: dir.appendingPathComponent(
|
||||||
"metadata.json"
|
"metadata.json"
|
||||||
)
|
)
|
||||||
.path
|
.path
|
||||||
).utf8)
|
).utf8)
|
||||||
)
|
)
|
||||||
loadLocalState()
|
loadLocalState()
|
||||||
comics.append(
|
comics.append(
|
||||||
@@ -304,11 +305,11 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var newMetadata = Metadata.init(
|
var newMetadata = Metadata(
|
||||||
title: "",
|
title: "",
|
||||||
original_language: "",
|
original_language: "",
|
||||||
last_volume: MetaValue.init(main: 0, bonus: nil),
|
last_volume: MetaValue(main: 0, bonus: nil),
|
||||||
last_chapter: MetaValue.init(main: 0, bonus: nil),
|
last_chapter: MetaValue(main: 0, bonus: nil),
|
||||||
chapter_count: 0,
|
chapter_count: 0,
|
||||||
publication_demographic: "",
|
publication_demographic: "",
|
||||||
status: "",
|
status: "",
|
||||||
@@ -351,19 +352,23 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
newMetadata.chapter_count += 1
|
newMetadata.chapter_count += 1
|
||||||
assert(volume > currentVolume)
|
assert(volume > currentVolume)
|
||||||
newMetadata.volumes.append(
|
newMetadata.volumes.append(
|
||||||
VolumeMetadata.init(
|
VolumeMetadata(
|
||||||
volume: MetaValue.init(main: volume, bonus: nil), name: nil,
|
volume: MetaValue(main: volume, bonus: nil), name: nil,
|
||||||
chapters: [
|
chapters: [
|
||||||
ChapterMetadata.init(
|
ChapterMetadata(
|
||||||
chapter: MetaValue.init(
|
chapter: MetaValue(
|
||||||
main: chapter.0, bonus: chapter.1),
|
main: chapter.0, bonus: chapter.1
|
||||||
|
),
|
||||||
name: "",
|
name: "",
|
||||||
images: [
|
images: [
|
||||||
ImageMetadata.init(
|
ImageMetadata(
|
||||||
doublePage: doublePage, fileName: fileName,
|
doublePage: doublePage, fileName: fileName,
|
||||||
firstPage: page)
|
firstPage: page
|
||||||
])
|
),
|
||||||
]))
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
))
|
||||||
} else if chapter != currentChapter {
|
} else if chapter != currentChapter {
|
||||||
newMetadata.chapter_count += 1
|
newMetadata.chapter_count += 1
|
||||||
if chapter.0 == currentChapter.0 {
|
if chapter.0 == currentChapter.0 {
|
||||||
@@ -372,37 +377,43 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
assert(chapter.0 == currentChapter.0 + 1)
|
assert(chapter.0 == currentChapter.0 + 1)
|
||||||
}
|
}
|
||||||
newMetadata.volumes[newMetadata.volumes.count - 1].chapters.append(
|
newMetadata.volumes[newMetadata.volumes.count - 1].chapters.append(
|
||||||
ChapterMetadata.init(
|
ChapterMetadata(
|
||||||
chapter: MetaValue.init(main: chapter.0, bonus: chapter.1),
|
chapter: MetaValue(main: chapter.0, bonus: chapter.1),
|
||||||
name: "",
|
name: "",
|
||||||
images: [
|
images: [
|
||||||
ImageMetadata.init(
|
ImageMetadata(
|
||||||
doublePage: doublePage, fileName: fileName,
|
doublePage: doublePage, fileName: fileName,
|
||||||
firstPage: page)
|
firstPage: page
|
||||||
]))
|
),
|
||||||
|
]
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
newMetadata.volumes[newMetadata.volumes.count - 1].chapters[
|
newMetadata.volumes[newMetadata.volumes.count - 1].chapters[
|
||||||
newMetadata.volumes[newMetadata.volumes.count - 1].chapters.count - 1
|
newMetadata.volumes[newMetadata.volumes.count - 1].chapters.count - 1
|
||||||
].images.append(
|
].images.append(
|
||||||
ImageMetadata.init(
|
ImageMetadata(
|
||||||
doublePage: doublePage, fileName: fileName, firstPage: page)
|
doublePage: doublePage, fileName: fileName, firstPage: page
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newMetadata.chapter_count += 1
|
newMetadata.chapter_count += 1
|
||||||
newMetadata.volumes.append(
|
newMetadata.volumes.append(
|
||||||
VolumeMetadata.init(
|
VolumeMetadata(
|
||||||
volume: MetaValue.init(main: volume, bonus: nil), name: nil,
|
volume: MetaValue(main: volume, bonus: nil), name: nil,
|
||||||
chapters: [
|
chapters: [
|
||||||
ChapterMetadata.init(
|
ChapterMetadata(
|
||||||
chapter: MetaValue.init(main: chapter.0, bonus: chapter.1),
|
chapter: MetaValue(main: chapter.0, bonus: chapter.1),
|
||||||
name: "",
|
name: "",
|
||||||
images: [
|
images: [
|
||||||
ImageMetadata.init(
|
ImageMetadata(
|
||||||
doublePage: doublePage, fileName: fileName,
|
doublePage: doublePage, fileName: fileName,
|
||||||
firstPage: page)
|
firstPage: page
|
||||||
])
|
),
|
||||||
]))
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
))
|
||||||
}
|
}
|
||||||
currentVolume = volume
|
currentVolume = volume
|
||||||
currentChapter = chapter
|
currentChapter = chapter
|
||||||
@@ -434,20 +445,23 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
if screenSize.width > screenSize.height {
|
if screenSize.width > screenSize.height {
|
||||||
scrollOffset.y *= (screenSize.height / screenSize.width)
|
scrollOffset.y *= (screenSize.height / screenSize.width)
|
||||||
}
|
}
|
||||||
var newProgress: ReadProgress =
|
var newProgress =
|
||||||
ReadProgress.leftToRight(
|
ReadProgress.leftToRight(
|
||||||
volumeIndex: progress.v, chapterIndex: progress.c,
|
volumeIndex: progress.v, chapterIndex: progress.c,
|
||||||
imageIndex: progress.i)
|
imageIndex: progress.i
|
||||||
|
)
|
||||||
|
|
||||||
switch mode {
|
switch mode {
|
||||||
case .leftToRight:
|
case .leftToRight:
|
||||||
newProgress = ReadProgress.leftToRight(
|
newProgress = ReadProgress.leftToRight(
|
||||||
volumeIndex: progress.v, chapterIndex: progress.c,
|
volumeIndex: progress.v, chapterIndex: progress.c,
|
||||||
imageIndex: progress.i)
|
imageIndex: progress.i
|
||||||
case .rightToLeft: newProgress = ReadProgress.rightToLeft(
|
)
|
||||||
volumeIndex: progress.v, chapterIndex: progress.c,
|
case .rightToLeft: newProgress = ReadProgress.rightToLeft(
|
||||||
imageIndex: progress.i)
|
volumeIndex: progress.v, chapterIndex: progress.c,
|
||||||
case .scroll: newProgress = ReadProgress.scroll(scrollOffset)
|
imageIndex: progress.i
|
||||||
|
)
|
||||||
|
case .scroll: newProgress = ReadProgress.scroll(scrollOffset)
|
||||||
}
|
}
|
||||||
queue.async {
|
queue.async {
|
||||||
do {
|
do {
|
||||||
@@ -465,23 +479,23 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
|
|
||||||
func loadLocalState() {
|
func loadLocalState() {
|
||||||
do {
|
do {
|
||||||
let json = Data(
|
let json = try Data(
|
||||||
try String(
|
String(
|
||||||
contentsOfFile: currentPath.appendingPathComponent("state.json").path
|
contentsOfFile: currentPath.appendingPathComponent("state.json").path
|
||||||
).utf8)
|
).utf8)
|
||||||
let local = try JSONDecoder().decode(LocalState.self, from: json)
|
let local = try JSONDecoder().decode(LocalState.self, from: json)
|
||||||
switch local.progress {
|
switch local.progress {
|
||||||
case .leftToRight(let volumeIndex, let chapterIndex, let imageIndex):
|
case let .leftToRight(volumeIndex, chapterIndex, imageIndex):
|
||||||
progress.v = volumeIndex
|
progress.v = volumeIndex
|
||||||
progress.c = chapterIndex
|
progress.c = chapterIndex
|
||||||
progress.i = imageIndex
|
progress.i = imageIndex
|
||||||
mode = .leftToRight
|
mode = .leftToRight
|
||||||
case .rightToLeft(let volumeIndex, let chapterIndex, let imageIndex):
|
case let .rightToLeft(volumeIndex, chapterIndex, imageIndex):
|
||||||
progress.v = volumeIndex
|
progress.v = volumeIndex
|
||||||
progress.c = chapterIndex
|
progress.c = chapterIndex
|
||||||
progress.i = imageIndex
|
progress.i = imageIndex
|
||||||
mode = .rightToLeft
|
mode = .rightToLeft
|
||||||
case .scroll(let point):
|
case let .scroll(point):
|
||||||
if scrollPos == nil {
|
if scrollPos == nil {
|
||||||
scrollPos = point
|
scrollPos = point
|
||||||
let screenSize = UIScreen.main.bounds.size
|
let screenSize = UIScreen.main.bounds.size
|
||||||
@@ -491,13 +505,13 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
if let indexPath = scrollingCollectionView.indexPathForItem(at: scrollOffset) {
|
if let indexPath = scrollingCollectionView.indexPathForItem(at: scrollOffset) {
|
||||||
var theProgress = ProgressIndices(v: 0, c: 0, i: 0)
|
var theProgress = ProgressIndices(v: 0, c: 0, i: 0)
|
||||||
for _ in 0...indexPath.item {
|
for _ in 0 ... indexPath.item {
|
||||||
theProgress = getProgressIndicesFromTurn(
|
theProgress = getProgressIndicesFromTurn(
|
||||||
turn: .next, progress: theProgress)
|
turn: .next, progress: theProgress
|
||||||
|
)
|
||||||
}
|
}
|
||||||
progress = theProgress
|
progress = theProgress
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
mode = .scroll
|
mode = .scroll
|
||||||
}
|
}
|
||||||
@@ -521,11 +535,12 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
setupTapZones()
|
setupTapZones()
|
||||||
}
|
}
|
||||||
|
|
||||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
func scrollViewDidScroll(_: UIScrollView) {
|
||||||
if scrollingCollectionView.isHidden { return }
|
if scrollingCollectionView.isHidden { return }
|
||||||
let centerPoint = CGPoint(
|
let centerPoint = CGPoint(
|
||||||
x: scrollingCollectionView.bounds.midX + scrollingCollectionView.contentOffset.x,
|
x: scrollingCollectionView.bounds.midX + scrollingCollectionView.contentOffset.x,
|
||||||
y: scrollingCollectionView.bounds.midY + scrollingCollectionView.contentOffset.y)
|
y: scrollingCollectionView.bounds.midY + scrollingCollectionView.contentOffset.y
|
||||||
|
)
|
||||||
|
|
||||||
if let indexPath = scrollingCollectionView.indexPathForItem(at: centerPoint) {
|
if let indexPath = scrollingCollectionView.indexPathForItem(at: centerPoint) {
|
||||||
let (chapter, page) = chapterAndPages[indexPath.item]
|
let (chapter, page) = chapterAndPages[indexPath.item]
|
||||||
@@ -544,7 +559,7 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !hasSetContentOffset && scrollPos != nil {
|
if !hasSetContentOffset, scrollPos != nil {
|
||||||
let screenSize = UIScreen.main.bounds.size
|
let screenSize = UIScreen.main.bounds.size
|
||||||
var offset = scrollPos!
|
var offset = scrollPos!
|
||||||
if screenSize.width > screenSize.height {
|
if screenSize.width > screenSize.height {
|
||||||
@@ -597,17 +612,17 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
var count = 0
|
var count = 0
|
||||||
if let enumerator = fileManager.enumerator(
|
if let enumerator = fileManager.enumerator(
|
||||||
at: currentPath, includingPropertiesForKeys: [.isDirectoryKey],
|
at: currentPath, includingPropertiesForKeys: [.isDirectoryKey],
|
||||||
options: [.skipsHiddenFiles])
|
options: [.skipsHiddenFiles]
|
||||||
{
|
) {
|
||||||
for case let dir as URL in enumerator {
|
for case let dir as URL in enumerator {
|
||||||
do {
|
do {
|
||||||
if let enumerator = fileManager.enumerator(
|
if let enumerator = fileManager.enumerator(
|
||||||
at: dir, includingPropertiesForKeys: [.isRegularFileKey],
|
at: dir, includingPropertiesForKeys: [.isRegularFileKey],
|
||||||
options: [.skipsHiddenFiles])
|
options: [.skipsHiddenFiles]
|
||||||
{
|
) {
|
||||||
for case let file as URL in enumerator {
|
for case let file as URL in enumerator {
|
||||||
let resourceValues = try file.resourceValues(forKeys: [
|
let resourceValues = try file.resourceValues(forKeys: [
|
||||||
.isRegularFileKey
|
.isRegularFileKey,
|
||||||
])
|
])
|
||||||
if resourceValues.isRegularFile == true {
|
if resourceValues.isRegularFile == true {
|
||||||
count += 1
|
count += 1
|
||||||
@@ -628,14 +643,16 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
layout.minimumInteritemSpacing = 0
|
layout.minimumInteritemSpacing = 0
|
||||||
layout.minimumLineSpacing = 0
|
layout.minimumLineSpacing = 0
|
||||||
scrollingCollectionView = UICollectionView(
|
scrollingCollectionView = UICollectionView(
|
||||||
frame: view.bounds, collectionViewLayout: layout)
|
frame: view.bounds, collectionViewLayout: layout
|
||||||
|
)
|
||||||
scrollingCollectionView.translatesAutoresizingMaskIntoConstraints = false
|
scrollingCollectionView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
scrollingCollectionView.dataSource = self
|
scrollingCollectionView.dataSource = self
|
||||||
scrollingCollectionView.delegate = self
|
scrollingCollectionView.delegate = self
|
||||||
scrollingCollectionView.backgroundColor = .white
|
scrollingCollectionView.backgroundColor = .white
|
||||||
scrollingCollectionView.isHidden = true
|
scrollingCollectionView.isHidden = true
|
||||||
scrollingCollectionView.register(
|
scrollingCollectionView.register(
|
||||||
ScrollingImageCell.self, forCellWithReuseIdentifier: "ScrollingImageCell")
|
ScrollingImageCell.self, forCellWithReuseIdentifier: "ScrollingImageCell"
|
||||||
|
)
|
||||||
readerView.addSubview(scrollingCollectionView)
|
readerView.addSubview(scrollingCollectionView)
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
@@ -949,8 +966,8 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func gestureRecognizer(
|
func gestureRecognizer(
|
||||||
_ gestureRecognizer: UIGestureRecognizer,
|
_: UIGestureRecognizer,
|
||||||
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
|
shouldRecognizeSimultaneouslyWith _: UIGestureRecognizer
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -965,13 +982,13 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
|
func scrollViewDidEndDecelerating(_: UIScrollView) {
|
||||||
if scrollingCollectionView.isHidden { return }
|
if scrollingCollectionView.isHidden { return }
|
||||||
updateInfo()
|
updateInfo()
|
||||||
saveLocalState()
|
saveLocalState()
|
||||||
}
|
}
|
||||||
|
|
||||||
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
|
func scrollViewDidEndDragging(_: UIScrollView, willDecelerate decelerate: Bool) {
|
||||||
if scrollingCollectionView.isHidden { return }
|
if scrollingCollectionView.isHidden { return }
|
||||||
if !decelerate {
|
if !decelerate {
|
||||||
updateInfo()
|
updateInfo()
|
||||||
@@ -1044,8 +1061,7 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
let scaling = UIView.ContentMode.scaleAspectFit
|
let scaling = UIView.ContentMode.scaleAspectFit
|
||||||
var newProgress = progress
|
var newProgress = progress
|
||||||
newProgress = getProgressIndicesFromTurn(turn: turn, progress: newProgress)
|
newProgress = getProgressIndicesFromTurn(turn: turn, progress: newProgress)
|
||||||
if newProgress.v == progress.v && newProgress.c == progress.c && newProgress.i == progress.i
|
if newProgress.v == progress.v, newProgress.c == progress.c, newProgress.i == progress.i {
|
||||||
{
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
progress = newProgress
|
progress = newProgress
|
||||||
@@ -1058,7 +1074,7 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _ in 0...preloadCount {
|
for _ in 0 ... preloadCount {
|
||||||
newProgress = getProgressIndicesFromTurn(turn: .next, progress: newProgress)
|
newProgress = getProgressIndicesFromTurn(turn: .next, progress: newProgress)
|
||||||
if let path = getImagePath(progress: newProgress) {
|
if let path = getImagePath(progress: newProgress) {
|
||||||
imageLoader.preloadImage(at: path, scaling: scaling)
|
imageLoader.preloadImage(at: path, scaling: scaling)
|
||||||
@@ -1106,7 +1122,8 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
metadata.volumes[progress.v].chapters[lastChapterIndex].images.count - 1
|
metadata.volumes[progress.v].chapters[lastChapterIndex].images.count - 1
|
||||||
|
|
||||||
let lastImage = metadata.volumes[progress.v].chapters[lastChapterIndex].images[
|
let lastImage = metadata.volumes[progress.v].chapters[lastChapterIndex].images[
|
||||||
lastImageIndex]
|
lastImageIndex
|
||||||
|
]
|
||||||
var lastPageString = ""
|
var lastPageString = ""
|
||||||
if lastImage.doublePage {
|
if lastImage.doublePage {
|
||||||
lastPageString = String(lastImage.firstPage + 1)
|
lastPageString = String(lastImage.firstPage + 1)
|
||||||
@@ -1150,37 +1167,39 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
switch turn {
|
switch turn {
|
||||||
case .next:
|
case .next:
|
||||||
if metadata.volumes[v].chapters[c].images.count > i + 1 {
|
if metadata.volumes[v].chapters[c].images.count > i + 1 {
|
||||||
return ProgressIndices.init(v: v, c: c, i: i + 1)
|
return ProgressIndices(v: v, c: c, i: i + 1)
|
||||||
}
|
}
|
||||||
if metadata.volumes[v].chapters.count > c + 1 {
|
if metadata.volumes[v].chapters.count > c + 1 {
|
||||||
return ProgressIndices.init(v: v, c: c + 1, i: 0)
|
return ProgressIndices(v: v, c: c + 1, i: 0)
|
||||||
}
|
}
|
||||||
if metadata.volumes.count > v + 1 {
|
if metadata.volumes.count > v + 1 {
|
||||||
return ProgressIndices.init(v: v + 1, c: 0, i: 0)
|
return ProgressIndices(v: v + 1, c: 0, i: 0)
|
||||||
}
|
}
|
||||||
case .previous:
|
case .previous:
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
return ProgressIndices.init(v: v, c: c, i: i - 1)
|
return ProgressIndices(v: v, c: c, i: i - 1)
|
||||||
}
|
}
|
||||||
if c > 0 {
|
if c > 0 {
|
||||||
return ProgressIndices.init(
|
return ProgressIndices(
|
||||||
v: v, c: c - 1, i: metadata.volumes[v].chapters[c - 1].images.count - 1)
|
v: v, c: c - 1, i: metadata.volumes[v].chapters[c - 1].images.count - 1
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if v > 0 {
|
if v > 0 {
|
||||||
return ProgressIndices.init(
|
return ProgressIndices(
|
||||||
v: v - 1, c: metadata.volumes[v - 1].chapters.count - 1,
|
v: v - 1, c: metadata.volumes[v - 1].chapters.count - 1,
|
||||||
i: metadata.volumes[v - 1].chapters[
|
i: metadata.volumes[v - 1].chapters[
|
||||||
metadata.volumes[v - 1].chapters.count - 1
|
metadata.volumes[v - 1].chapters.count - 1
|
||||||
].images.count - 1)
|
].images.count - 1
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ProgressIndices.init(v: v, c: c, i: i)
|
return ProgressIndices(v: v, c: c, i: i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMetadata(path: URL) -> Metadata? {
|
func getMetadata(path: URL) -> Metadata? {
|
||||||
do {
|
do {
|
||||||
let json = Data(
|
let json = try Data(
|
||||||
try String(contentsOfFile: path.appendingPathComponent("metadata.json").path)
|
String(contentsOfFile: path.appendingPathComponent("metadata.json").path)
|
||||||
.utf8)
|
.utf8)
|
||||||
let metadata = try JSONDecoder().decode(Metadata.self, from: json)
|
let metadata = try JSONDecoder().decode(Metadata.self, from: json)
|
||||||
return metadata
|
return metadata
|
||||||
@@ -1193,14 +1212,14 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setImages(path: URL) {
|
func setImages(path _: URL) {
|
||||||
let scaling: UIView.ContentMode!
|
let scaling: UIView.ContentMode!
|
||||||
if mode == .scroll {
|
if mode == .scroll {
|
||||||
scaling = UIView.ContentMode.scaleAspectFill
|
scaling = UIView.ContentMode.scaleAspectFill
|
||||||
} else { scaling = UIView.ContentMode.scaleAspectFit }
|
} else { scaling = UIView.ContentMode.scaleAspectFit }
|
||||||
imageLoader.loadImage(
|
imageLoader.loadImage(
|
||||||
at:
|
at:
|
||||||
getImagePath(progress: progress),
|
getImagePath(progress: progress),
|
||||||
scaling: scaling
|
scaling: scaling
|
||||||
) { [weak self] image in
|
) { [weak self] image in
|
||||||
self?.imageView.image = image
|
self?.imageView.image = image
|
||||||
@@ -1208,7 +1227,7 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newProgress = progress
|
var newProgress = progress
|
||||||
for _ in 0...preloadCount {
|
for _ in 0 ... preloadCount {
|
||||||
newProgress = getProgressIndicesFromTurn(turn: .next, progress: newProgress)
|
newProgress = getProgressIndicesFromTurn(turn: .next, progress: newProgress)
|
||||||
imageLoader.preloadImage(at: getImagePath(progress: newProgress), scaling: scaling)
|
imageLoader.preloadImage(at: getImagePath(progress: newProgress), scaling: scaling)
|
||||||
}
|
}
|
||||||
@@ -1245,8 +1264,8 @@ func getGlobalState() -> GlobalState {
|
|||||||
let fileManager = FileManager.default
|
let fileManager = FileManager.default
|
||||||
if let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
|
if let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
|
||||||
do {
|
do {
|
||||||
let json = Data(
|
let json = try Data(
|
||||||
try String(
|
String(
|
||||||
contentsOfFile: documentsURL.appendingPathComponent("state.json").path
|
contentsOfFile: documentsURL.appendingPathComponent("state.json").path
|
||||||
).utf8)
|
).utf8)
|
||||||
return try JSONDecoder().decode(GlobalState.self, from: json)
|
return try JSONDecoder().decode(GlobalState.self, from: json)
|
||||||
@@ -1268,9 +1287,8 @@ func getDocumentsURL() -> URL? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
|
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
|
||||||
|
|
||||||
func collectionView(
|
func collectionView(
|
||||||
_ collectionView: UICollectionView, numberOfItemsInSection section: Int
|
_ collectionView: UICollectionView, numberOfItemsInSection _: Int
|
||||||
)
|
)
|
||||||
-> Int
|
-> Int
|
||||||
{
|
{
|
||||||
@@ -1287,7 +1305,8 @@ extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFl
|
|||||||
if collectionView == comicCollectionView {
|
if collectionView == comicCollectionView {
|
||||||
let cell =
|
let cell =
|
||||||
collectionView.dequeueReusableCell(
|
collectionView.dequeueReusableCell(
|
||||||
withReuseIdentifier: "ComicImageCell", for: indexPath)
|
withReuseIdentifier: "ComicImageCell", for: indexPath
|
||||||
|
)
|
||||||
as! ComicImageCell
|
as! ComicImageCell
|
||||||
cell.imageView.image = comics[indexPath.item].cover
|
cell.imageView.image = comics[indexPath.item].cover
|
||||||
return cell
|
return cell
|
||||||
@@ -1295,7 +1314,8 @@ extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFl
|
|||||||
// let scaling = UIView.ContentMode.scaleAspectFill
|
// let scaling = UIView.ContentMode.scaleAspectFill
|
||||||
let cell =
|
let cell =
|
||||||
collectionView.dequeueReusableCell(
|
collectionView.dequeueReusableCell(
|
||||||
withReuseIdentifier: "ScrollingImageCell", for: indexPath)
|
withReuseIdentifier: "ScrollingImageCell", for: indexPath
|
||||||
|
)
|
||||||
as! ScrollingImageCell
|
as! ScrollingImageCell
|
||||||
if metadata == nil {
|
if metadata == nil {
|
||||||
return cell
|
return cell
|
||||||
@@ -1303,20 +1323,21 @@ extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFl
|
|||||||
// TODO: Fix scrolling again
|
// TODO: Fix scrolling again
|
||||||
return cell
|
return cell
|
||||||
} else {
|
} else {
|
||||||
assert(false)
|
assertionFailure()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Xcode profiling sucks:
|
// Xcode profiling sucks:
|
||||||
return
|
return
|
||||||
collectionView.dequeueReusableCell(
|
collectionView.dequeueReusableCell(
|
||||||
withReuseIdentifier: "ScrollingImageCell", for: indexPath)
|
withReuseIdentifier: "ScrollingImageCell", for: indexPath
|
||||||
|
)
|
||||||
as! ScrollingImageCell
|
as! ScrollingImageCell
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(
|
func collectionView(
|
||||||
_ collectionView: UICollectionView,
|
_ collectionView: UICollectionView,
|
||||||
layout collectionViewLayout: UICollectionViewLayout,
|
layout _: UICollectionViewLayout,
|
||||||
sizeForItemAt indexPath: IndexPath
|
sizeForItemAt _: IndexPath
|
||||||
) -> CGSize {
|
) -> CGSize {
|
||||||
if collectionView == comicCollectionView {
|
if collectionView == comicCollectionView {
|
||||||
let spacing: CGFloat = 8
|
let spacing: CGFloat = 8
|
||||||
@@ -1331,7 +1352,7 @@ extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFl
|
|||||||
// TODO: Fix scrolling again
|
// TODO: Fix scrolling again
|
||||||
return CGSize()
|
return CGSize()
|
||||||
} else {
|
} else {
|
||||||
assert(false)
|
assertionFailure()
|
||||||
}
|
}
|
||||||
// Xcode profiling sucks:
|
// Xcode profiling sucks:
|
||||||
return CGSize()
|
return CGSize()
|
||||||
@@ -1367,7 +1388,8 @@ class ScrollingImageCell: UICollectionViewCell {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
@available(*, unavailable)
|
||||||
|
required init?(coder _: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1390,7 +1412,8 @@ class ComicImageCell: UICollectionViewCell {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
@available(*, unavailable)
|
||||||
|
required init?(coder _: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1403,7 +1426,7 @@ enum Rotation {
|
|||||||
class ImageLoader {
|
class ImageLoader {
|
||||||
private let cache = NSCache<NSString, UIImage>()
|
private let cache = NSCache<NSString, UIImage>()
|
||||||
private let horCache = NSCache<NSString, UIImage>()
|
private let horCache = NSCache<NSString, UIImage>()
|
||||||
private var loadingTasks: [String: [((UIImage?) -> Void)]] = [:]
|
private var loadingTasks: [String: [(UIImage?) -> Void]] = [:]
|
||||||
var size: [String: CGSize] = [:]
|
var size: [String: CGSize] = [:]
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@@ -1421,9 +1444,9 @@ class ImageLoader {
|
|||||||
) {
|
) {
|
||||||
let screenSize = UIScreen.main.bounds.size
|
let screenSize = UIScreen.main.bounds.size
|
||||||
let rotation: Rotation!
|
let rotation: Rotation!
|
||||||
if screenSize.width > screenSize.height {
|
if screenSize.width > screenSize.height {
|
||||||
rotation = Rotation.horizontal
|
rotation = Rotation.horizontal
|
||||||
} else { rotation = Rotation.vertical }
|
} else { rotation = Rotation.vertical }
|
||||||
|
|
||||||
if rotation == .vertical {
|
if rotation == .vertical {
|
||||||
if let cached = cache.object(forKey: path.path as NSString) {
|
if let cached = cache.object(forKey: path.path as NSString) {
|
||||||
@@ -1455,9 +1478,11 @@ class ImageLoader {
|
|||||||
if completion == nil || rotation == .vertical {
|
if completion == nil || rotation == .vertical {
|
||||||
let vertical = CGSize(
|
let vertical = CGSize(
|
||||||
width: min(screenSize.width, screenSize.height),
|
width: min(screenSize.width, screenSize.height),
|
||||||
height: max(screenSize.height, screenSize.width))
|
height: max(screenSize.height, screenSize.width)
|
||||||
|
)
|
||||||
let vScaledSize = aspectSize(
|
let vScaledSize = aspectSize(
|
||||||
for: image.size, in: vertical, scaling: scaling)
|
for: image.size, in: vertical, scaling: scaling
|
||||||
|
)
|
||||||
let vScaleImage = resizeImage(image, to: vScaledSize)
|
let vScaleImage = resizeImage(image, to: vScaledSize)
|
||||||
guard let cost = imageByteSize(vScaleImage) else { return }
|
guard let cost = imageByteSize(vScaleImage) else { return }
|
||||||
self.cache.setObject(vScaleImage, forKey: path.path as NSString, cost: cost)
|
self.cache.setObject(vScaleImage, forKey: path.path as NSString, cost: cost)
|
||||||
@@ -1469,9 +1494,11 @@ class ImageLoader {
|
|||||||
if completion == nil || rotation == .horizontal {
|
if completion == nil || rotation == .horizontal {
|
||||||
let horizontal = CGSize(
|
let horizontal = CGSize(
|
||||||
width: max(screenSize.width, screenSize.height),
|
width: max(screenSize.width, screenSize.height),
|
||||||
height: min(screenSize.height, screenSize.width))
|
height: min(screenSize.height, screenSize.width)
|
||||||
|
)
|
||||||
let hScaledSize = aspectSize(
|
let hScaledSize = aspectSize(
|
||||||
for: image.size, in: horizontal, scaling: scaling)
|
for: image.size, in: horizontal, scaling: scaling
|
||||||
|
)
|
||||||
let hScaleImage = resizeImage(image, to: hScaledSize)
|
let hScaleImage = resizeImage(image, to: hScaledSize)
|
||||||
guard let cost = imageByteSize(hScaleImage) else { return }
|
guard let cost = imageByteSize(hScaleImage) else { return }
|
||||||
self.horCache.setObject(hScaleImage, forKey: path.path as NSString, cost: cost)
|
self.horCache.setObject(hScaleImage, forKey: path.path as NSString, cost: cost)
|
||||||
|
|||||||
Reference in New Issue
Block a user