Compare commits
3 Commits
cca2a03b2f
...
8ee916411e
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 8ee916411e | |
Shadowfacts | 9d845bf6c1 | |
Shadowfacts | 9a2c24942a |
|
@ -156,7 +156,7 @@ class SegmentedPageViewController<Page: SegmentedPageViewControllerPage>: UIView
|
||||||
// MARK: TabbedPageViewController
|
// MARK: TabbedPageViewController
|
||||||
|
|
||||||
func selectNextPage() {
|
func selectNextPage() {
|
||||||
guard currentIndex < pageControllers.count - 1 else { return }
|
guard currentIndex < pages.count - 1 else { return }
|
||||||
selectPage(pages[currentIndex + 1], animated: true)
|
selectPage(pages[currentIndex + 1], animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,11 @@ class TimelineLikeController<Item> {
|
||||||
guard state == .notLoadedInitial || state == .idle else {
|
guard state == .notLoadedInitial || state == .idle else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state = .restoringInitial
|
let token = LoadAttemptToken()
|
||||||
|
state = .restoringInitial(token, hasAddedLoadingIndicator: false)
|
||||||
|
let loadingIndicator = DeferredLoadingIndicator(owner: self, state: state, addedIndicatorState: .restoringInitial(token, hasAddedLoadingIndicator: true))
|
||||||
await doRestore()
|
await doRestore()
|
||||||
|
await loadingIndicator.end()
|
||||||
state = .idle
|
state = .idle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +201,7 @@ class TimelineLikeController<Item> {
|
||||||
enum State: Equatable, CustomDebugStringConvertible {
|
enum State: Equatable, CustomDebugStringConvertible {
|
||||||
case notLoadedInitial
|
case notLoadedInitial
|
||||||
case idle
|
case idle
|
||||||
case restoringInitial
|
case restoringInitial(LoadAttemptToken, hasAddedLoadingIndicator: Bool)
|
||||||
case loadingInitial(LoadAttemptToken, hasAddedLoadingIndicator: Bool)
|
case loadingInitial(LoadAttemptToken, hasAddedLoadingIndicator: Bool)
|
||||||
case loadingNewer(LoadAttemptToken)
|
case loadingNewer(LoadAttemptToken)
|
||||||
case loadingOlder(LoadAttemptToken, hasAddedLoadingIndicator: Bool)
|
case loadingOlder(LoadAttemptToken, hasAddedLoadingIndicator: Bool)
|
||||||
|
@ -210,8 +213,8 @@ class TimelineLikeController<Item> {
|
||||||
return "notLoadedInitial"
|
return "notLoadedInitial"
|
||||||
case .idle:
|
case .idle:
|
||||||
return "idle"
|
return "idle"
|
||||||
case .restoringInitial:
|
case .restoringInitial(let token, let hasAddedLoadingIndicator):
|
||||||
return "restoringInitial"
|
return "restoringInitial(\(ObjectIdentifier(token)), hasAddedLoadingIndicator: \(hasAddedLoadingIndicator))"
|
||||||
case .loadingInitial(let token, let hasAddedLoadingIndicator):
|
case .loadingInitial(let token, let hasAddedLoadingIndicator):
|
||||||
return "loadingInitial(\(ObjectIdentifier(token)), hasAddedLoadingIndicator: \(hasAddedLoadingIndicator))"
|
return "loadingInitial(\(ObjectIdentifier(token)), hasAddedLoadingIndicator: \(hasAddedLoadingIndicator))"
|
||||||
case .loadingNewer(let token):
|
case .loadingNewer(let token):
|
||||||
|
@ -234,13 +237,13 @@ class TimelineLikeController<Item> {
|
||||||
}
|
}
|
||||||
case .idle:
|
case .idle:
|
||||||
switch to {
|
switch to {
|
||||||
case .restoringInitial, .loadingInitial(_, _), .loadingNewer(_), .loadingOlder(_, _), .loadingGap(_, _):
|
case .restoringInitial(_, _), .loadingInitial(_, _), .loadingNewer(_), .loadingOlder(_, _), .loadingGap(_, _):
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case .restoringInitial:
|
case .restoringInitial(let token, let hasAddedLoadingIndicator):
|
||||||
return to == .idle
|
return to == .idle || (!hasAddedLoadingIndicator && to == .restoringInitial(token, hasAddedLoadingIndicator: true))
|
||||||
case .loadingInitial(let token, let hasAddedLoadingIndicator):
|
case .loadingInitial(let token, let hasAddedLoadingIndicator):
|
||||||
return to == .notLoadedInitial || to == .idle || (!hasAddedLoadingIndicator && to == .loadingInitial(token, hasAddedLoadingIndicator: true))
|
return to == .notLoadedInitial || to == .idle || (!hasAddedLoadingIndicator && to == .loadingInitial(token, hasAddedLoadingIndicator: true))
|
||||||
case .loadingNewer(_):
|
case .loadingNewer(_):
|
||||||
|
@ -256,14 +259,14 @@ class TimelineLikeController<Item> {
|
||||||
switch event {
|
switch event {
|
||||||
case .addLoadingIndicator:
|
case .addLoadingIndicator:
|
||||||
switch self {
|
switch self {
|
||||||
case .loadingInitial(_, _), .loadingOlder(_, _):
|
case .restoringInitial(_, _), .loadingInitial(_, _), .loadingOlder(_, _):
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case .removeLoadingIndicator:
|
case .removeLoadingIndicator:
|
||||||
switch self {
|
switch self {
|
||||||
case .loadingInitial(_, hasAddedLoadingIndicator: true), .loadingOlder(_, hasAddedLoadingIndicator: true):
|
case .restoringInitial(_, hasAddedLoadingIndicator: true), .loadingInitial(_, hasAddedLoadingIndicator: true), .loadingOlder(_, hasAddedLoadingIndicator: true):
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
@ -344,6 +347,7 @@ class TimelineLikeController<Item> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
class DeferredLoadingIndicator {
|
class DeferredLoadingIndicator {
|
||||||
private let owner: TimelineLikeController<Item>
|
private let owner: TimelineLikeController<Item>
|
||||||
private let addedIndicatorState: State
|
private let addedIndicatorState: State
|
||||||
|
@ -352,19 +356,18 @@ class TimelineLikeController<Item> {
|
||||||
init(owner: TimelineLikeController<Item>, state: State, addedIndicatorState: State) {
|
init(owner: TimelineLikeController<Item>, state: State, addedIndicatorState: State) {
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
self.addedIndicatorState = addedIndicatorState
|
self.addedIndicatorState = addedIndicatorState
|
||||||
self.task = Task {
|
self.task = Task { @MainActor in
|
||||||
try await Task.sleep(nanoseconds: 150 * NSEC_PER_MSEC)
|
try await Task.sleep(nanoseconds: 150 * NSEC_PER_MSEC)
|
||||||
guard await state == owner.state else {
|
guard state == owner.state else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await owner.emit(event: .addLoadingIndicator)
|
await owner.emit(event: .addLoadingIndicator)
|
||||||
await owner.transition(to: addedIndicatorState)
|
owner.transition(to: addedIndicatorState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func end() async {
|
func end() async {
|
||||||
let state = await owner.state
|
if owner.state == addedIndicatorState {
|
||||||
if state == addedIndicatorState {
|
|
||||||
await owner.emit(event: .removeLoadingIndicator)
|
await owner.emit(event: .removeLoadingIndicator)
|
||||||
} else {
|
} else {
|
||||||
task.cancel()
|
task.cancel()
|
||||||
|
|
|
@ -43,9 +43,6 @@ class StatusCardView: UIView {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func commonInit() {
|
private func commonInit() {
|
||||||
// self.clipsToBounds = true
|
|
||||||
// self.layer.borderWidth = 0.5
|
|
||||||
// self.layer.borderColor = UIColor.lightGray.cgColor
|
|
||||||
self.layer.shadowColor = UIColor.black.cgColor
|
self.layer.shadowColor = UIColor.black.cgColor
|
||||||
self.layer.shadowRadius = 5
|
self.layer.shadowRadius = 5
|
||||||
self.layer.shadowOpacity = 0.2
|
self.layer.shadowOpacity = 0.2
|
||||||
|
@ -57,11 +54,12 @@ class StatusCardView: UIView {
|
||||||
titleLabel.font = UIFont(descriptor: UIFontDescriptor.preferredFontDescriptor(withTextStyle: .subheadline).withSymbolicTraits(.traitBold)!, size: 0)
|
titleLabel.font = UIFont(descriptor: UIFontDescriptor.preferredFontDescriptor(withTextStyle: .subheadline).withSymbolicTraits(.traitBold)!, size: 0)
|
||||||
titleLabel.adjustsFontForContentSizeCategory = true
|
titleLabel.adjustsFontForContentSizeCategory = true
|
||||||
titleLabel.numberOfLines = 2
|
titleLabel.numberOfLines = 2
|
||||||
|
titleLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||||
|
|
||||||
descriptionLabel = UILabel()
|
descriptionLabel = UILabel()
|
||||||
descriptionLabel.font = UIFont(descriptor: .preferredFontDescriptor(withTextStyle: .caption1), size: 0)
|
descriptionLabel.font = UIFont(descriptor: .preferredFontDescriptor(withTextStyle: .caption1), size: 0)
|
||||||
descriptionLabel.adjustsFontForContentSizeCategory = true
|
descriptionLabel.adjustsFontForContentSizeCategory = true
|
||||||
descriptionLabel.numberOfLines = 2
|
descriptionLabel.numberOfLines = 3
|
||||||
descriptionLabel.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
|
descriptionLabel.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
|
||||||
|
|
||||||
domainLabel = UILabel()
|
domainLabel = UILabel()
|
||||||
|
|
Loading…
Reference in New Issue