Files
Felitendo e9be180701 lang: send the strings that missed the catalogue through it
Six user-facing strings were written as literals and never reached the string
catalogue, so they rendered as source text on every device whatever the phone
was set to. They are invisible from here: a missing entry falls back to the
key, which is exactly right in the language the key is written in.

The screen a private store shows when nobody is signed in was all of them at
once: its title, both of its subtitles, and the sign in button, which missed
an entry that was already there by one capital letter. The heartbeat's socket
error was the other pair.

Two more had entries and bypassed them by passing a literal where the helper
belonged: the title of the alert a failed signing puts up, and the OK button
on every alert in the app, which is a real word rather than "OK" in four of
the languages this ships. The signing alert also printed
`localizedDescription`, which for an error conforming to no `LocalizedError`
is "The operation couldn't be completed", the sentence `readableDescription`
exists to replace and that every other install path already uses.
2026-09-03 07:31:19 +02:00

140 lines
3.4 KiB
Swift

//
// UIAlertController+Alerts.swift
// NimbleKit
//
// Created by samara on 28.04.2025.
//
import UIKit.UIAlertController
extension UIAlertController {
/// Presents an alert
/// - Parameters:
/// - presenter: View where its presenting
/// - title: Alert title
/// - message: Alert message
/// - actions: Alert actions
static public func showAlertWithCancel(
_ presenter: UIViewController = UIApplication.topViewController()!,
_ popoverFromView: UIView? = nil,
title: String?,
message: String?,
style: UIAlertController.Style = .alert,
actions: [UIAlertAction]
) {
var actions = actions
actions.append(
UIAlertAction(title: .localized("Cancel"), style: .cancel, handler: nil)
)
showAlert(
presenter,
popoverFromView,
title: title,
message: message,
style: style,
actions: actions
)
}
/// Presents an alert with an OK button
/// - Parameters:
/// - presenter: View where it is presenting
/// - title: Alert title
/// - message: Alert message
/// - style: Alert controller style
/// - isCancel: If true, sets action style to cancel and no handler
/// - action: Closure to run when OK is tapped (ignored if isCancel is true)
static public func showAlertWithOk(
_ presenter: UIViewController = UIApplication.topViewController()!,
_ popoverFromView: UIView? = nil,
title: String?,
message: String?,
style: UIAlertController.Style = .alert,
isCancel: Bool = false,
action: (() -> Void)? = nil
) {
var actions: [UIAlertAction] = []
let alertAction = UIAlertAction(
title: .localized("OK"),
style: isCancel ? .cancel : .default,
handler: { _ in
if !isCancel {
action?()
}
}
)
actions.append(alertAction)
showAlert(
presenter,
popoverFromView,
title: title,
message: message,
style: style,
actions: actions
)
}
/// Presents an alert
/// - Parameters:
/// - presenter: View where its presenting
/// - title: Alert title
/// - message: Alert message
static public func showAlertWithRestart(
_ presenter: UIViewController = UIApplication.topViewController()!,
_ popoverFromView: UIView? = nil,
title: String?,
message: String?,
style: UIAlertController.Style = .alert
) {
var actions: [UIAlertAction] = []
actions.append(
UIAlertAction(title: "Suspend", style: .default) { _ in
UIApplication.shared.suspend()
}
)
actions.append(
UIAlertAction(title: "Later", style: .cancel, handler: nil)
)
showAlert(
presenter,
popoverFromView,
title: title,
message: message,
style: style,
actions: actions
)
}
/// Presents an alert
/// - Parameters:
/// - presenter: View where its presenting
/// - title: Alert title
/// - message: Alert message
/// - actions: Alert actions
static public func showAlert(
_ presenter: UIViewController = UIApplication.topViewController()!,
_ popoverFromView: UIView? = nil,
title: String?,
message: String?,
style: UIAlertController.Style = .alert,
actions: [UIAlertAction]
) {
let alert = Self(title: title, message: message, preferredStyle: style)
actions.forEach { alert.addAction($0) }
if
style == .actionSheet,
let popover = alert.popoverPresentationController,
let view = popoverFromView
{
popover.sourceView = view
popover.sourceRect = view.bounds
popover.permittedArrowDirections = .any
}
presenter.present(alert, animated: true)
}
}