wip
This commit is contained in:
parent
ee2f68e33b
commit
22b6f415d2
|
@ -133,6 +133,9 @@
|
||||||
54F0B81C282316F5003664BD /* RegisterAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F0B81B282316F5003664BD /* RegisterAccount.swift */; };
|
54F0B81C282316F5003664BD /* RegisterAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F0B81B282316F5003664BD /* RegisterAccount.swift */; };
|
||||||
6E9488F6997650B805476F25 /* Pods_another_im.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F29121F912380F72CCE51747 /* Pods_another_im.framework */; };
|
6E9488F6997650B805476F25 /* Pods_another_im.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F29121F912380F72CCE51747 /* Pods_another_im.framework */; };
|
||||||
7D40218FEAB3BA882811A682 /* Pods_Monal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C40963CED187B2F1B4B88F7 /* Pods_Monal.framework */; };
|
7D40218FEAB3BA882811A682 /* Pods_Monal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C40963CED187B2F1B4B88F7 /* Pods_Monal.framework */; };
|
||||||
|
7E1C0AC72CEF68C000B8FEC0 /* MainTabScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E1C0AC62CEF68C000B8FEC0 /* MainTabScreen.swift */; };
|
||||||
|
7E1C0ACB2CEF6C7800B8FEC0 /* ContactsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E1C0AC92CEF6C7800B8FEC0 /* ContactsScreen.swift */; };
|
||||||
|
7E1C0ACC2CEF6C7800B8FEC0 /* AddContactOrChannelScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E1C0AC82CEF6C7800B8FEC0 /* AddContactOrChannelScreen.swift */; };
|
||||||
7E6AF38F2CEB9110004328B5 /* MonalXmppWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E6AF38E2CEB9110004328B5 /* MonalXmppWrapper.swift */; };
|
7E6AF38F2CEB9110004328B5 /* MonalXmppWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E6AF38E2CEB9110004328B5 /* MonalXmppWrapper.swift */; };
|
||||||
7E6AF3902CEB982F004328B5 /* sworim.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 2601D9CA0FBF25EF004DB939 /* sworim.sqlite */; };
|
7E6AF3902CEB982F004328B5 /* sworim.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 2601D9CA0FBF25EF004DB939 /* sworim.sqlite */; };
|
||||||
7E71758D2CECC5C70059F30B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7E71758B2CECC5C70059F30B /* Localizable.strings */; };
|
7E71758D2CECC5C70059F30B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7E71758B2CECC5C70059F30B /* Localizable.strings */; };
|
||||||
|
@ -635,6 +638,9 @@
|
||||||
79A6AA4819B69B5FFFA28236 /* Pods-NotificationService.appstore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.appstore.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.appstore.xcconfig"; sourceTree = "<group>"; };
|
79A6AA4819B69B5FFFA28236 /* Pods-NotificationService.appstore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.appstore.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.appstore.xcconfig"; sourceTree = "<group>"; };
|
||||||
7D281334DB441077E42E3E89 /* Pods-another.im.appstore-quicksy.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-another.im.appstore-quicksy.xcconfig"; path = "Target Support Files/Pods-another.im/Pods-another.im.appstore-quicksy.xcconfig"; sourceTree = "<group>"; };
|
7D281334DB441077E42E3E89 /* Pods-another.im.appstore-quicksy.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-another.im.appstore-quicksy.xcconfig"; path = "Target Support Files/Pods-another.im/Pods-another.im.appstore-quicksy.xcconfig"; sourceTree = "<group>"; };
|
||||||
7D6715099247A9CCC180EE30 /* Pods-MonalUITests.beta.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonalUITests.beta.xcconfig"; path = "Target Support Files/Pods-MonalUITests/Pods-MonalUITests.beta.xcconfig"; sourceTree = "<group>"; };
|
7D6715099247A9CCC180EE30 /* Pods-MonalUITests.beta.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MonalUITests.beta.xcconfig"; path = "Target Support Files/Pods-MonalUITests/Pods-MonalUITests.beta.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
7E1C0AC62CEF68C000B8FEC0 /* MainTabScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabScreen.swift; sourceTree = "<group>"; };
|
||||||
|
7E1C0AC82CEF6C7800B8FEC0 /* AddContactOrChannelScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactOrChannelScreen.swift; sourceTree = "<group>"; };
|
||||||
|
7E1C0AC92CEF6C7800B8FEC0 /* ContactsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsScreen.swift; sourceTree = "<group>"; };
|
||||||
7E6AF38E2CEB9110004328B5 /* MonalXmppWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonalXmppWrapper.swift; sourceTree = "<group>"; };
|
7E6AF38E2CEB9110004328B5 /* MonalXmppWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonalXmppWrapper.swift; sourceTree = "<group>"; };
|
||||||
7E6E446D2CECB76500505D5C /* another.im.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = another.im.entitlements; sourceTree = "<group>"; };
|
7E6E446D2CECB76500505D5C /* another.im.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = another.im.entitlements; sourceTree = "<group>"; };
|
||||||
7E7175892CECC5C70059F30B /* launchscreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = launchscreen.storyboard; sourceTree = "<group>"; };
|
7E7175892CECC5C70059F30B /* launchscreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = launchscreen.storyboard; sourceTree = "<group>"; };
|
||||||
|
@ -1460,6 +1466,15 @@
|
||||||
path = Enter;
|
path = Enter;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
7E1C0ACA2CEF6C7800B8FEC0 /* Contacts */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7E1C0AC82CEF6C7800B8FEC0 /* AddContactOrChannelScreen.swift */,
|
||||||
|
7E1C0AC92CEF6C7800B8FEC0 /* ContactsScreen.swift */,
|
||||||
|
);
|
||||||
|
path = Contacts;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
7E71758C2CECC5C70059F30B /* Strings */ = {
|
7E71758C2CECC5C70059F30B /* Strings */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1474,6 +1489,7 @@
|
||||||
7E995F222CEAC5D2005B30EE /* RootView.swift */,
|
7E995F222CEAC5D2005B30EE /* RootView.swift */,
|
||||||
7E8D7AF92CECEDB3009AD3DF /* SharedComponents */,
|
7E8D7AF92CECEDB3009AD3DF /* SharedComponents */,
|
||||||
54D8CBD8978DA29C88226FBB /* Enter */,
|
54D8CBD8978DA29C88226FBB /* Enter */,
|
||||||
|
D7FD95FF8F72ECE4DBEE1095 /* Main */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1707,6 +1723,15 @@
|
||||||
path = localization;
|
path = localization;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
D7FD95FF8F72ECE4DBEE1095 /* Main */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7E1C0AC62CEF68C000B8FEC0 /* MainTabScreen.swift */,
|
||||||
|
7E1C0ACA2CEF6C7800B8FEC0 /* Contacts */,
|
||||||
|
);
|
||||||
|
path = Main;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
D91581D0612C23AB5B3F867C /* Frameworks */ = {
|
D91581D0612C23AB5B3F867C /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -2607,6 +2632,7 @@
|
||||||
7E8D7B1D2CECEE79009AD3DF /* EdgeInsets+Extensions.swift in Sources */,
|
7E8D7B1D2CECEE79009AD3DF /* EdgeInsets+Extensions.swift in Sources */,
|
||||||
7E8D7B1E2CECEE79009AD3DF /* Binding+Extensions.swift in Sources */,
|
7E8D7B1E2CECEE79009AD3DF /* Binding+Extensions.swift in Sources */,
|
||||||
7E8D7B1F2CECEE79009AD3DF /* UIApplication+Extensions.swift in Sources */,
|
7E8D7B1F2CECEE79009AD3DF /* UIApplication+Extensions.swift in Sources */,
|
||||||
|
7E1C0AC72CEF68C000B8FEC0 /* MainTabScreen.swift in Sources */,
|
||||||
7E8D7B202CECEE79009AD3DF /* View+Debug.swift in Sources */,
|
7E8D7B202CECEE79009AD3DF /* View+Debug.swift in Sources */,
|
||||||
7E8D7B212CECEE79009AD3DF /* Map+Extensions.swift in Sources */,
|
7E8D7B212CECEE79009AD3DF /* Map+Extensions.swift in Sources */,
|
||||||
7E8D7B222CECEE79009AD3DF /* View+Flip.swift in Sources */,
|
7E8D7B222CECEE79009AD3DF /* View+Flip.swift in Sources */,
|
||||||
|
@ -2621,6 +2647,8 @@
|
||||||
7E8D7AFB2CECEDB3009AD3DF /* SharedSectionTitle.swift in Sources */,
|
7E8D7AFB2CECEDB3009AD3DF /* SharedSectionTitle.swift in Sources */,
|
||||||
7E8D7AFC2CECEDB3009AD3DF /* SharedNavigationBar.swift in Sources */,
|
7E8D7AFC2CECEDB3009AD3DF /* SharedNavigationBar.swift in Sources */,
|
||||||
7E8D7AFD2CECEDB3009AD3DF /* UniversalInputCollection.swift in Sources */,
|
7E8D7AFD2CECEDB3009AD3DF /* UniversalInputCollection.swift in Sources */,
|
||||||
|
7E1C0ACB2CEF6C7800B8FEC0 /* ContactsScreen.swift in Sources */,
|
||||||
|
7E1C0ACC2CEF6C7800B8FEC0 /* AddContactOrChannelScreen.swift in Sources */,
|
||||||
7E8D7AFE2CECEDB3009AD3DF /* LoadingScreen.swift in Sources */,
|
7E8D7AFE2CECEDB3009AD3DF /* LoadingScreen.swift in Sources */,
|
||||||
7E995F252CEAC5D2005B30EE /* RootView.swift in Sources */,
|
7E995F252CEAC5D2005B30EE /* RootView.swift in Sources */,
|
||||||
7E6AF38F2CEB9110004328B5 /* MonalXmppWrapper.swift in Sources */,
|
7E6AF38F2CEB9110004328B5 /* MonalXmppWrapper.swift in Sources */,
|
||||||
|
|
|
@ -13,9 +13,4 @@ struct AnotherIMApp: App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppDelegate: NSObject, UIApplicationDelegate {
|
class AppDelegate: NSObject, UIApplicationDelegate {}
|
||||||
// func application(_: UIApplication, willFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
|
||||||
// // [IPC initializeForProcess:@"MainApp"];
|
|
||||||
// // [MLProcessLock initializeForProcess:@"MainApp"];
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AddContactOrChannelScreen: View {
|
||||||
|
@EnvironmentObject var wrapper: MonalXmppWrapper
|
||||||
|
@Environment(\.router) var router
|
||||||
|
|
||||||
|
enum Field {
|
||||||
|
case account
|
||||||
|
case contact
|
||||||
|
}
|
||||||
|
|
||||||
|
@FocusState private var focus: Field?
|
||||||
|
|
||||||
|
// @State private var ownerCredentials: Credentials?
|
||||||
|
@State private var contactJID: String = ""
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
// Background color
|
||||||
|
Color.Material.Background.light
|
||||||
|
.ignoresSafeArea()
|
||||||
|
|
||||||
|
// Content
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// Header
|
||||||
|
SharedNavigationBar(
|
||||||
|
leftButton: .init(
|
||||||
|
image: Image(systemName: "xmark"),
|
||||||
|
action: {
|
||||||
|
router.dismissScreen()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
centerText: .init(text: L10n.Contacts.Add.title),
|
||||||
|
rightButton: .init(
|
||||||
|
image: Image(systemName: "plus.viewfinder"),
|
||||||
|
action: {
|
||||||
|
print("Scan QR-code")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Content
|
||||||
|
VStack(spacing: 16) {
|
||||||
|
// Explanation text
|
||||||
|
Text(L10n.Contacts.Add.explanation)
|
||||||
|
.font(.body3)
|
||||||
|
.foregroundColor(.Material.Shape.separator)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.padding(.top, 16)
|
||||||
|
|
||||||
|
// Account selector
|
||||||
|
HStack(spacing: 0) {
|
||||||
|
Text("Use account:")
|
||||||
|
.font(.body2)
|
||||||
|
.foregroundColor(.Material.Text.main)
|
||||||
|
.frame(alignment: .leading)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
// UniversalInputCollection.DropDownMenu(
|
||||||
|
// prompt: "Use account",
|
||||||
|
// elements: activeClientsCredentials,
|
||||||
|
// selected: $ownerCredentials,
|
||||||
|
// focus: $focus,
|
||||||
|
// fieldType: .account
|
||||||
|
// )
|
||||||
|
|
||||||
|
// Contact text input
|
||||||
|
HStack(spacing: 0) {
|
||||||
|
Text("Contact JID:")
|
||||||
|
.font(.body2)
|
||||||
|
.foregroundColor(.Material.Text.main)
|
||||||
|
.frame(alignment: .leading)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
// UniversalInputCollection.TextField(
|
||||||
|
// prompt: "Contact or channel JID",
|
||||||
|
// text: $contactJID,
|
||||||
|
// focus: $focus,
|
||||||
|
// fieldType: .contact,
|
||||||
|
// contentType: .emailAddress,
|
||||||
|
// keyboardType: .emailAddress,
|
||||||
|
// submitLabel: .done,
|
||||||
|
// action: {
|
||||||
|
// focus = .account
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
|
||||||
|
// Save button
|
||||||
|
Button {
|
||||||
|
Task {
|
||||||
|
await save()
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Text(L10n.Global.save)
|
||||||
|
}
|
||||||
|
.buttonStyle(PrimaryButtonStyle())
|
||||||
|
// .disabled(!inputValid)
|
||||||
|
.padding(.top)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
// if let exists = activeClientsCredentials.first {
|
||||||
|
// ownerCredentials = exists
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// private var activeClientsCredentials: [Credentials] {
|
||||||
|
// clientsStore.clients
|
||||||
|
// .filter { $0.state != .disabled }
|
||||||
|
// .map { $0.credentials }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private var inputValid: Bool {
|
||||||
|
// ownerCredentials != nil && !contactJID.isEmpty && UniversalInputCollection.Validators.isEmail(contactJID)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
private func save() async {
|
||||||
|
// guard let ownerCredentials = ownerCredentials else { return }
|
||||||
|
|
||||||
|
router.showModal {
|
||||||
|
LoadingScreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
defer {
|
||||||
|
router.dismissModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
// try await clientsStore.addRoster(ownerCredentials, contactJID: contactJID, name: nil, groups: [])
|
||||||
|
router.dismissScreen()
|
||||||
|
} catch {
|
||||||
|
router.showAlert(
|
||||||
|
.alert,
|
||||||
|
title: L10n.Global.Error.title,
|
||||||
|
subtitle: L10n.Contacts.Add.serverError
|
||||||
|
) {
|
||||||
|
Button(L10n.Global.ok, role: .cancel) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
202
Monal/another.im/Views/Main/Contacts/ContactsScreen.swift
Normal file
202
Monal/another.im/Views/Main/Contacts/ContactsScreen.swift
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ContactsScreen: View {
|
||||||
|
@EnvironmentObject var wrapper: MonalXmppWrapper
|
||||||
|
@Environment(\.router) var router
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
// Background color
|
||||||
|
Color.Material.Background.light
|
||||||
|
.ignoresSafeArea()
|
||||||
|
|
||||||
|
// Content
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// Header
|
||||||
|
SharedNavigationBar(
|
||||||
|
centerText: .init(text: L10n.Contacts.title),
|
||||||
|
rightButton: .init(
|
||||||
|
image: Image(systemName: "plus"),
|
||||||
|
action: {
|
||||||
|
router.showScreen(.fullScreenCover) { _ in
|
||||||
|
AddContactOrChannelScreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Contacts list
|
||||||
|
// if !clientsStore.actualRosters.isEmpty {
|
||||||
|
// List {
|
||||||
|
// ForEach(elements.indices, id: \.self) { index in
|
||||||
|
// let element = elements[index]
|
||||||
|
// if let roster = element as? Roster {
|
||||||
|
// ContactsScreenRow(
|
||||||
|
// roster: roster
|
||||||
|
// )
|
||||||
|
// } else if let bareJid = element as? String {
|
||||||
|
// SharedSectionTitle(text: bareJid)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// .listStyle(.plain)
|
||||||
|
// .background(Color.Material.Background.light)
|
||||||
|
// } else {
|
||||||
|
// Spacer()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var elements: [Any] {
|
||||||
|
[]
|
||||||
|
// if clientsStore.clients.filter({ $0.credentials.isActive }).count == 1 {
|
||||||
|
// return clientsStore.actualRosters
|
||||||
|
// } else {
|
||||||
|
// var result: [Any] = []
|
||||||
|
// for roster in clientsStore.actualRosters {
|
||||||
|
// if result.isEmpty {
|
||||||
|
// result.append(roster.bareJid)
|
||||||
|
// } else if let last = result.last as? Roster, last.bareJid != roster.bareJid {
|
||||||
|
// result.append(roster.bareJid)
|
||||||
|
// }
|
||||||
|
// result.append(roster)
|
||||||
|
// }
|
||||||
|
// return result
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct ContactsScreenRow: View {
|
||||||
|
@EnvironmentObject var wrapper: MonalXmppWrapper
|
||||||
|
@Environment(\.router) var router
|
||||||
|
|
||||||
|
// var roster: Roster
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Text("nothing for now")
|
||||||
|
// SharedListRow(
|
||||||
|
// iconType: .charCircle(roster.name?.firstLetter ?? roster.contactBareJid.firstLetter),
|
||||||
|
// text: roster.contactBareJid,
|
||||||
|
// controlType: .none
|
||||||
|
// )
|
||||||
|
// .onTapGesture {
|
||||||
|
// startChat()
|
||||||
|
// }
|
||||||
|
// .swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
||||||
|
// Button {
|
||||||
|
// router.showAlert(.confirmationDialog, title: L10n.Contacts.deleteContact, subtitle: L10n.Contacts.Delete.message) {
|
||||||
|
// deleteConfirmation
|
||||||
|
// }
|
||||||
|
// } label: {
|
||||||
|
// Label("", systemImage: "trash")
|
||||||
|
// }
|
||||||
|
// .tint(Color.red)
|
||||||
|
// }
|
||||||
|
// .contextMenu {
|
||||||
|
// Button(L10n.Contacts.sendMessage, systemImage: "message") {
|
||||||
|
// startChat()
|
||||||
|
// }
|
||||||
|
// Divider()
|
||||||
|
//
|
||||||
|
// Button(L10n.Contacts.editContact) {
|
||||||
|
// print("Edit contact")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Button(L10n.Contacts.selectContact) {
|
||||||
|
// print("Select contact")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Divider()
|
||||||
|
// Button(L10n.Contacts.deleteContact, systemImage: "trash", role: .destructive) {
|
||||||
|
// router.showAlert(.confirmationDialog, title: L10n.Contacts.deleteContact, subtitle: L10n.Contacts.Delete.message) {
|
||||||
|
// deleteConfirmation
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder private var deleteConfirmation: some View {
|
||||||
|
Button(role: .destructive) {
|
||||||
|
Task {
|
||||||
|
await deleteFromDevice()
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Text(L10n.Contacts.Delete.deleteFromDevice)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(role: .destructive) {
|
||||||
|
Task {
|
||||||
|
await deleteCompletely()
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Text(L10n.Contacts.Delete.deleteCompletely)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(role: .cancel) {} label: {
|
||||||
|
Text(L10n.Global.cancel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func deleteFromDevice() async {
|
||||||
|
router.showModal {
|
||||||
|
LoadingScreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
defer {
|
||||||
|
router.dismissModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
//var roster = roster
|
||||||
|
//try? await roster.setLocallyDeleted(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func deleteCompletely() async {
|
||||||
|
router.showModal {
|
||||||
|
LoadingScreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
defer {
|
||||||
|
router.dismissModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
// try await clientsStore.deleteRoster(roster)
|
||||||
|
} catch {
|
||||||
|
router.showAlert(
|
||||||
|
.alert,
|
||||||
|
title: L10n.Global.Error.title,
|
||||||
|
subtitle: L10n.Contacts.Delete.error
|
||||||
|
) {
|
||||||
|
Button(L10n.Global.ok, role: .cancel) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func startChat() {
|
||||||
|
Task {
|
||||||
|
router.showModal {
|
||||||
|
LoadingScreen()
|
||||||
|
}
|
||||||
|
defer {
|
||||||
|
router.dismissModal()
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
// let (messages, attachments, settings) = try await clientsStore.conversationStores(for: roster)
|
||||||
|
// router.showScreen(.push) { _ in
|
||||||
|
// ConversationScreen(messagesStore: messages, attachments: attachments, settings: settings)
|
||||||
|
// .navigationBarHidden(true)
|
||||||
|
// }
|
||||||
|
} catch {
|
||||||
|
router.showAlert(
|
||||||
|
.alert,
|
||||||
|
title: L10n.Global.Error.title,
|
||||||
|
subtitle: L10n.Conversation.startError
|
||||||
|
) {
|
||||||
|
Button(L10n.Global.ok, role: .cancel) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
118
Monal/another.im/Views/Main/MainTabScreen.swift
Normal file
118
Monal/another.im/Views/Main/MainTabScreen.swift
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
import Foundation
|
||||||
|
import SwiftfulRouting
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
private enum Tab {
|
||||||
|
case chats
|
||||||
|
case contacts
|
||||||
|
case settings
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MainTabScreen: View {
|
||||||
|
@EnvironmentObject var wrapper: MonalXmppWrapper
|
||||||
|
|
||||||
|
@State private var selectedTab: Tab = .chats
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
// Background color
|
||||||
|
Color.Material.Background.light
|
||||||
|
.ignoresSafeArea()
|
||||||
|
|
||||||
|
// Content
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
switch selectedTab {
|
||||||
|
case .chats:
|
||||||
|
Text("chats")
|
||||||
|
// ChatsListScreen()
|
||||||
|
|
||||||
|
case .contacts:
|
||||||
|
Text("contacts")
|
||||||
|
// ContactsScreen()
|
||||||
|
|
||||||
|
case .settings:
|
||||||
|
Text("settings")
|
||||||
|
// SettingsScreen()
|
||||||
|
// .environment(\.settingsParent, .main)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tab bar
|
||||||
|
TabBar(selectedTab: $selectedTab)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onLoad {
|
||||||
|
wrapper.reconnectAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct TabBar: View {
|
||||||
|
@Binding var selectedTab: Tab
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
Rectangle()
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.frame(height: 0.2)
|
||||||
|
.foregroundColor(.Material.Shape.separator)
|
||||||
|
HStack(spacing: 0) {
|
||||||
|
TabBarButton(buttonType: .contacts, selectedTab: $selectedTab)
|
||||||
|
TabBarButton(buttonType: .chats, selectedTab: $selectedTab)
|
||||||
|
TabBarButton(buttonType: .settings, selectedTab: $selectedTab)
|
||||||
|
}
|
||||||
|
.background(Color.Material.Background.dark)
|
||||||
|
}
|
||||||
|
.frame(height: 50)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct TabBarButton: View {
|
||||||
|
let buttonType: Tab
|
||||||
|
|
||||||
|
@Binding var selectedTab: Tab
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
VStack(spacing: 2) {
|
||||||
|
buttonImg
|
||||||
|
.foregroundColor(buttonType == selectedTab ? .Material.Elements.active : .Material.Elements.inactive)
|
||||||
|
.font(.system(size: 24, weight: .light))
|
||||||
|
.symbolRenderingMode(.hierarchical)
|
||||||
|
Text(buttonTitle)
|
||||||
|
.font(.sub1)
|
||||||
|
.foregroundColor(buttonType == selectedTab ? .Material.Text.main : .Material.Elements.inactive)
|
||||||
|
}
|
||||||
|
Rectangle()
|
||||||
|
.foregroundColor(.white.opacity(0.01))
|
||||||
|
.onTapGesture {
|
||||||
|
selectedTab = buttonType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttonImg: Image {
|
||||||
|
switch buttonType {
|
||||||
|
case .contacts:
|
||||||
|
return Image(systemName: "person.2.fill")
|
||||||
|
|
||||||
|
case .chats:
|
||||||
|
return Image(systemName: "bubble.left.fill")
|
||||||
|
|
||||||
|
case .settings:
|
||||||
|
return Image(systemName: "gearshape.fill")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttonTitle: String {
|
||||||
|
switch buttonType {
|
||||||
|
case .contacts:
|
||||||
|
return L10n.Tabs.Name.contacts
|
||||||
|
|
||||||
|
case .chats:
|
||||||
|
return L10n.Tabs.Name.conversations
|
||||||
|
|
||||||
|
case .settings:
|
||||||
|
return L10n.Tabs.Name.settings
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,8 +6,9 @@ struct RootView: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if wrapper.accountsAvailability == .someEnabled {
|
if wrapper.accountsAvailability == .someEnabled {
|
||||||
// main flow here
|
RouterView { _ in
|
||||||
Text("Test ME!")
|
MainTabScreen()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
RouterView { _ in
|
RouterView { _ in
|
||||||
WelcomeScreen()
|
WelcomeScreen()
|
||||||
|
|
|
@ -14,12 +14,13 @@ final class MonalXmppWrapper: ObservableObject {
|
||||||
private let db: DataLayer
|
private let db: DataLayer
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
xmpp = MLXMPPManager.sharedInstance()
|
|
||||||
db = DataLayer.sharedInstance()
|
|
||||||
|
|
||||||
// here is some inits (just for now)
|
// here is some inits (just for now)
|
||||||
MLProcessLock.initialize(forProcess: "MainApp")
|
MLProcessLock.initialize(forProcess: "MainApp")
|
||||||
|
|
||||||
|
// init monalxmpp components
|
||||||
|
xmpp = MLXMPPManager.sharedInstance()
|
||||||
|
db = DataLayer.sharedInstance()
|
||||||
|
|
||||||
checkAccountsOnLoad()
|
checkAccountsOnLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +32,10 @@ final class MonalXmppWrapper: ObservableObject {
|
||||||
throw AimErrors.loginError
|
throw AimErrors.loginError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reconnectAll() {
|
||||||
|
xmpp.reconnectAll()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Accounts
|
// MARK: - Accounts
|
||||||
|
@ -50,7 +55,7 @@ private extension MonalXmppWrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Login from Login screen
|
// MARK: - Try login from Login screen
|
||||||
private final class LoginTry {
|
private final class LoginTry {
|
||||||
weak var xmpp: MLXMPPManager?
|
weak var xmpp: MLXMPPManager?
|
||||||
|
|
||||||
|
@ -61,7 +66,7 @@ private final class LoginTry {
|
||||||
self.xmpp = xmpp
|
self.xmpp = xmpp
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Добавить автовключение отключенных аккаунтов при попытке ввести тот же JID\
|
// TODO: Добавить автовключение отключенных аккаунтов при попытке ввести тот же JID
|
||||||
// Обработать кейс когда бесячий monalxmpp возвращает nil при попытке добавить тот же JID
|
// Обработать кейс когда бесячий monalxmpp возвращает nil при попытке добавить тот же JID
|
||||||
func tryLogin(_ login: String, _ password: String) async -> Bool {
|
func tryLogin(_ login: String, _ password: String) async -> Bool {
|
||||||
async let notify = await withCheckedContinuation { [weak self] continuation in
|
async let notify = await withCheckedContinuation { [weak self] continuation in
|
||||||
|
|
Loading…
Reference in a new issue