/
ContentView.swift
125 lines (113 loc) · 4.7 KB
/
ContentView.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//
// ContentView.swift
// RChat
//
// Created by Andrew Morgan on 23/11/2020.
//
import SwiftUI
import UserNotifications
import RealmSwift
struct ContentView: View {
@EnvironmentObject var state: AppState
@AppStorage("shouldRemindOnlineUser") var shouldRemindOnlineUser = false
@AppStorage("onlineUserReminderHours") var onlineUserReminderHours = 8.0
@State private var showingProfileView = false
var body: some View {
NavigationView {
ZStack {
VStack {
if state.loggedIn {
if (state.user != nil) && !state.user!.isProfileSet || showingProfileView {
SetProfileView(isPresented: $showingProfileView)
.environment(\.realmConfiguration, app.currentUser!.configuration(partitionValue: "user=\(state.user?._id ?? "")"))
} else {
ConversationListView()
.environment(\.realmConfiguration, app.currentUser!.configuration(partitionValue: "user=\(state.user?._id ?? "")"))
.navigationBarTitle("Chats", displayMode: .inline)
.navigationBarItems(
trailing: state.loggedIn && !state.shouldIndicateActivity ? UserAvatarView(
photo: state.user?.userPreferences?.avatarImage,
online: true) { showingProfileView.toggle() } : nil
)
}
} else {
LoginView()
}
Spacer()
if let error = state.error {
Text("Error: \(error)")
.foregroundColor(Color.red)
}
}
if state.busyCount > 0 {
OpaqueProgressView("Working With Realm")
}
}
}
.currentDeviceNavigationViewStyle(alwaysStacked: !state.loggedIn)
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
if let user = state.user {
if user.presenceState == .onLine && shouldRemindOnlineUser {
addNotification(timeInHours: Int(onlineUserReminderHours))
}
}
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
clearNotifications()
}
}
func addNotification(timeInHours: Int) {
let center = UNUserNotificationCenter.current()
let addRequest = {
let content = UNMutableNotificationContent()
content.title = "Still logged in"
content.subtitle = "You've been offline in the background for " +
"\(onlineUserReminderHours) \(onlineUserReminderHours == 1 ? "hour" : "hours")"
content.sound = UNNotificationSound.default
let trigger = UNTimeIntervalNotificationTrigger(
timeInterval: onlineUserReminderHours * 3600,
repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString,
content: content,
trigger: trigger)
center.add(request)
}
center.getNotificationSettings { settings in
if settings.authorizationStatus == .authorized {
addRequest()
} else {
center.requestAuthorization(options: [.alert, .badge, .sound]) { success, _ in
if success {
addRequest()
}
}
}
}
}
func clearNotifications() {
let center = UNUserNotificationCenter.current()
center.removeAllDeliveredNotifications()
center.removeAllPendingNotificationRequests()
}
}
extension View {
public func currentDeviceNavigationViewStyle(alwaysStacked: Bool) -> AnyView {
if UIDevice.current.userInterfaceIdiom == .pad && !alwaysStacked {
return AnyView(self.navigationViewStyle(DefaultNavigationViewStyle()))
} else {
return AnyView(self.navigationViewStyle(StackNavigationViewStyle()))
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
AppearancePreviews(
Group {
ContentView()
.environmentObject(AppState())
Landscape(ContentView()
.environmentObject(AppState()))
}
)
}
}