mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-24 21:45:20 +00:00
Mechanical style fixes across the enabled rule set, mostly via swiftlint --fix (trailing_comma, comma, colon, trailing_newline, comment_spacing, unused_closure_parameter, unneeded_break_in_switch, opening_brace) plus hand fixes: - non_optional_string_data_conversion (45): .data(using: .utf8)! and ?? Data() fallbacks replaced with the non-optional Data(_.utf8), including two production sites (NIP-44 HKDF info constant and the announce canonicalization context/nickname bytes — byte-identical output, only the impossible-nil handling is gone). - switch_case_alignment: LocationChannel had a misindented closing brace; also repaired an --fix artifact in BLEService's .none case. - redundant_string_enum_value: TrustLevel raw values equal to the case names (encoded form unchanged). - unused_optional_binding: let _ = binds replaced with != nil / is Bool. - static_over_final_class: PreviewView.layerClass. - Resolved the BinaryProtocolTests TODO by documenting that 8-byte recipient ID truncation is the fixed wire-field size, not a bug. The 4 remaining violations are all todo markers for a shared test-helpers module (tracked in #1088) and one Reuse note. Co-authored-by: jack <jackjackbits@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
127 lines
4.5 KiB
Swift
127 lines
4.5 KiB
Swift
//
|
|
// BitchatApp.swift
|
|
// bitchat
|
|
//
|
|
// This is free and unencumbered software released into the public domain.
|
|
// For more information, see <https://unlicense.org>
|
|
//
|
|
|
|
import SwiftUI
|
|
import UserNotifications
|
|
|
|
@main
|
|
struct BitchatApp: App {
|
|
static let bundleID = Bundle.main.bundleIdentifier ?? "chat.bitchat"
|
|
static let groupID = "group.\(bundleID)"
|
|
|
|
@StateObject private var runtime: AppRuntime
|
|
@AppStorage(AppTheme.storageKey) private var appThemeRawValue = AppTheme.matrix.rawValue
|
|
#if os(iOS)
|
|
@Environment(\.scenePhase) var scenePhase
|
|
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
|
#elseif os(macOS)
|
|
@NSApplicationDelegateAdaptor(MacAppDelegate.self) var appDelegate
|
|
#endif
|
|
|
|
init() {
|
|
_runtime = StateObject(wrappedValue: AppRuntime())
|
|
UNUserNotificationCenter.current().delegate = NotificationDelegate.shared
|
|
}
|
|
|
|
var body: some Scene {
|
|
WindowGroup {
|
|
ContentView()
|
|
.environment(\.appTheme, AppTheme(rawValue: appThemeRawValue) ?? .matrix)
|
|
.environmentObject(runtime.publicChatModel)
|
|
.environmentObject(runtime.privateInboxModel)
|
|
.environmentObject(runtime.privateConversationModel)
|
|
.environmentObject(runtime.verificationModel)
|
|
.environmentObject(runtime.conversationUIModel)
|
|
.environmentObject(runtime.locationChannelsModel)
|
|
.environmentObject(runtime.peerListModel)
|
|
.environmentObject(runtime.appChromeModel)
|
|
.onAppear {
|
|
appDelegate.runtime = runtime
|
|
runtime.start()
|
|
}
|
|
.onOpenURL { url in
|
|
runtime.handleOpenURL(url)
|
|
}
|
|
#if os(iOS)
|
|
.onChange(of: scenePhase) { newPhase in
|
|
runtime.handleScenePhaseChange(newPhase)
|
|
}
|
|
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
|
|
runtime.handleDidBecomeActiveNotification()
|
|
}
|
|
#elseif os(macOS)
|
|
.onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification)) { _ in
|
|
runtime.handleMacDidBecomeActiveNotification()
|
|
}
|
|
#endif
|
|
}
|
|
#if os(macOS)
|
|
.windowStyle(.hiddenTitleBar)
|
|
.windowResizability(.contentSize)
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#if os(iOS)
|
|
final class AppDelegate: NSObject, UIApplicationDelegate {
|
|
weak var runtime: AppRuntime?
|
|
|
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
|
true
|
|
}
|
|
|
|
func applicationWillTerminate(_ application: UIApplication) {
|
|
runtime?.applicationWillTerminate()
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if os(macOS)
|
|
import AppKit
|
|
|
|
final class MacAppDelegate: NSObject, NSApplicationDelegate {
|
|
weak var runtime: AppRuntime?
|
|
|
|
func applicationWillTerminate(_ notification: Notification) {
|
|
runtime?.applicationWillTerminate()
|
|
}
|
|
|
|
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
|
true
|
|
}
|
|
}
|
|
#endif
|
|
|
|
final class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
|
|
static let shared = NotificationDelegate()
|
|
weak var runtime: AppRuntime?
|
|
|
|
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
|
|
let identifier = response.notification.request.identifier
|
|
let userInfo = response.notification.request.content.userInfo
|
|
|
|
Task { @MainActor in
|
|
self.runtime?.handleNotificationResponse(identifier: identifier, userInfo: userInfo)
|
|
}
|
|
completionHandler()
|
|
}
|
|
|
|
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
|
|
let identifier = notification.request.identifier
|
|
let userInfo = notification.request.content.userInfo
|
|
|
|
Task {
|
|
let options = await self.runtime?.presentationOptions(
|
|
forNotificationIdentifier: identifier,
|
|
userInfo: userInfo
|
|
) ?? [.banner, .sound]
|
|
completionHandler(options)
|
|
}
|
|
}
|
|
}
|