Skip to content

Commit

Permalink
Add loading indicator (#2450)
Browse files Browse the repository at this point in the history
  • Loading branch information
zeitschlag committed Jan 16, 2025
1 parent ba50b2b commit 5f6475b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 7 deletions.
67 changes: 62 additions & 5 deletions deltachat-ios/Chat/AppPickerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@ class AppPickerViewController: UIViewController {
weak var delegate: AppPickerViewControllerDelegate?
let webView: WKWebView
var defaultCloseButton: UIBarButtonItem?
let downloadingView: DownloadingView

init(url: URL = URL(string: "https://webxdc.org/apps/")!) {
webView = WKWebView(frame: .zero)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.load(URLRequest(url: url))

downloadingView = DownloadingView()
downloadingView.translatesAutoresizingMaskIntoConstraints = false
downloadingView.isHidden = true

super.init(nibName: nil, bundle: nil)

webView.navigationDelegate = self
view.addSubview(webView)
view.addSubview(downloadingView)
view.backgroundColor = .systemBackground
setupConstraints()
let closeButton = UIBarButtonItem(image: UIImage(systemName: "xmark"), style: .plain, target: self, action: #selector(AppPickerViewController.close(_:)))
Expand All @@ -38,6 +44,11 @@ class AppPickerViewController: UIViewController {
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
view.trailingAnchor.constraint(equalTo: webView.trailingAnchor),
view.bottomAnchor.constraint(equalTo: webView.bottomAnchor),

downloadingView.topAnchor.constraint(equalTo: view.topAnchor),
downloadingView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
view.trailingAnchor.constraint(equalTo: downloadingView.trailingAnchor),
view.bottomAnchor.constraint(equalTo: downloadingView.bottomAnchor),
]

NSLayoutConstraint.activate(constraints)
Expand All @@ -48,6 +59,21 @@ class AppPickerViewController: UIViewController {
@objc func close(_ sender: Any) {
dismiss(animated: true)
}

@objc func showLoading() {
title = String.localized("Downloading...")
downloadingView.isHidden = false
downloadingView.activityIndicator.startAnimating()
downloadingView.activityIndicator.hidesWhenStopped = true
navigationItem.leftBarButtonItem = nil
}

@objc func hideLoading() {
title = String.localized("webxdc_apps")
downloadingView.isHidden = true
downloadingView.activityIndicator.stopAnimating()
navigationItem.leftBarButtonItem = defaultCloseButton
}
}

extension AppPickerViewController: WKNavigationDelegate {
Expand All @@ -62,20 +88,20 @@ extension AppPickerViewController: WKNavigationDelegate {
guard let self else { return }
// show spinner instead of close-button
await MainActor.run {
let activityIndicator = UIActivityIndicatorView(style: .medium)
activityIndicator.startAnimating()
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: activityIndicator)
self.showLoading()
}

guard let (data, _) = try? await URLSession.shared.data(from: url),
let filepath = FileHelper.saveData(data: data, name: url.lastPathComponent)
else {
await MainActor.run { self.navigationItem.leftBarButtonItem = self.defaultCloseButton }
await MainActor.run {
self.hideLoading()
}
return decisionHandler(.cancel)
}

if #available(iOS 16.0, *) {
try await Task.sleep(for: .seconds(5))
try await Task.sleep(for: .seconds(2))
}

let fileURL = NSURL(fileURLWithPath: filepath)
Expand All @@ -96,3 +122,34 @@ extension AppPickerViewController: WKNavigationDelegate {
}
}
}

class DownloadingView: UIView {
let activityIndicator: UIActivityIndicatorView
private let blurView: UIVisualEffectView

init() {
activityIndicator = UIActivityIndicatorView(style: .large)
activityIndicator.color = .white
activityIndicator.translatesAutoresizingMaskIntoConstraints = false

blurView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blurView.translatesAutoresizingMaskIntoConstraints = false

super.init(frame: .zero)

addSubview(blurView)
addSubview(activityIndicator)

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

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

required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
2 changes: 0 additions & 2 deletions deltachat-ios/Chat/ChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1482,8 +1482,6 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate {
let appPicker = AppPickerViewController()
appPicker.delegate = self
let navigationController = UINavigationController(rootViewController: appPicker)
navigationController.navigationBar.standardAppearance.backgroundEffect = UIBlurEffect(style: .extraLight)
navigationController.navigationBar.scrollEdgeAppearance = navigationController.navigationBar.standardAppearance
navigationController.isModalInPresentation = true

if #available(iOS 15.0, *), let sheet = navigationController.sheetPresentationController {
Expand Down

0 comments on commit 5f6475b

Please sign in to comment.