Build iOS App / Build .ipa and publish source (push) Successful in 34s
- After a merge, the app returns to the landing page but the inbox kept stale PRs. Add an inboxNeedsRefresh flag set on merge success; InboxView reloads on next appearance when it's set. - The PR content (incl. the Checks/workflow tab) is now pull-to-refreshable via .refreshable on the content ScrollView, so workflow status can be updated by pulling down. Bump to 3.4.
70 lines
2.5 KiB
Swift
70 lines
2.5 KiB
Swift
import Foundation
|
|
import SwiftUI
|
|
|
|
enum MergeGateMode: String, CaseIterable, Identifiable {
|
|
case warn = "Warn on red (allow merge with confirm)"
|
|
case block = "Block merge when CI is red"
|
|
|
|
var id: String { rawValue }
|
|
}
|
|
|
|
/// Central settings: instance + token (Keychain) and app preferences.
|
|
@MainActor
|
|
final class SettingsStore: ObservableObject {
|
|
static let shared = SettingsStore()
|
|
|
|
@Published var instanceURL: String {
|
|
didSet { KeychainHelper.set(instanceURL, key: "instanceURL") }
|
|
}
|
|
@Published var token: String {
|
|
didSet { KeychainHelper.set(token, key: "token") }
|
|
}
|
|
@Published var mergeGateMode: MergeGateMode {
|
|
didSet { UserDefaults.standard.set(mergeGateMode.rawValue,
|
|
forKey: "mergeGateMode") }
|
|
}
|
|
@Published var deleteBranchAfterMerge: Bool {
|
|
didSet { UserDefaults.standard.set(deleteBranchAfterMerge,
|
|
forKey: "deleteBranchAfterMerge") }
|
|
}
|
|
/// Repos to monitor for the inbox. Empty = monitor all accessible repos.
|
|
/// Stored as full names (e.g. "luis/config-nixos").
|
|
@Published var monitoredRepos: [String] {
|
|
didSet { UserDefaults.standard.set(monitoredRepos,
|
|
forKey: "monitoredRepos") }
|
|
}
|
|
/// Set when a PR is merged, so the inbox knows to reload on next appearance
|
|
/// (otherwise a just-merged PR could linger as stale in the list).
|
|
@Published var inboxNeedsRefresh = false
|
|
|
|
private init() {
|
|
instanceURL = KeychainHelper.get("instanceURL") ?? "https://gitea.bueso.eu"
|
|
token = KeychainHelper.get("token") ?? ""
|
|
let raw = UserDefaults.standard.string(forKey: "mergeGateMode")
|
|
mergeGateMode = MergeGateMode(rawValue: raw ?? "") ?? .warn
|
|
deleteBranchAfterMerge = UserDefaults.standard.bool(forKey: "deleteBranchAfterMerge")
|
|
monitoredRepos = UserDefaults.standard.stringArray(forKey: "monitoredRepos") ?? []
|
|
}
|
|
|
|
var isConfigured: Bool {
|
|
!token.isEmpty && !instanceURL.isEmpty
|
|
}
|
|
|
|
var baseURL: URL? {
|
|
URL(string: instanceURL.hasSuffix("/") ?
|
|
String(instanceURL.dropLast()) : instanceURL)
|
|
}
|
|
|
|
func client() -> GiteaClient? {
|
|
guard let base = baseURL else { return nil }
|
|
return GiteaClient(instanceURL: base, token: token)
|
|
}
|
|
|
|
func logout() {
|
|
KeychainHelper.delete("instanceURL")
|
|
KeychainHelper.delete("token")
|
|
instanceURL = "https://gitea.bueso.eu"
|
|
token = ""
|
|
}
|
|
}
|