wip
This commit is contained in:
parent
ad7a2b4f59
commit
d1e3bc54bf
|
@ -1411,7 +1411,7 @@
|
||||||
name = tools;
|
name = tools;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
29B97314FDCFA39411CA2CEA = {
|
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
8414ADF92A7ABAC900EFFCCC /* Packages */,
|
8414ADF92A7ABAC900EFFCCC /* Packages */,
|
||||||
|
@ -2064,7 +2064,7 @@
|
||||||
eu,
|
eu,
|
||||||
"es-AR",
|
"es-AR",
|
||||||
);
|
);
|
||||||
mainGroup = 29B97314FDCFA39411CA2CEA;
|
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
C1F5C7AD2777638B0001F295 /* XCRemoteSwiftPackageReference "swift-collections" */,
|
C1F5C7AD2777638B0001F295 /* XCRemoteSwiftPackageReference "swift-collections" */,
|
||||||
841898A82957712000FEC77D /* XCRemoteSwiftPackageReference "ViewExtractor" */,
|
841898A82957712000FEC77D /* XCRemoteSwiftPackageReference "ViewExtractor" */,
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct AddContactOrChannelScreen: View {
|
||||||
|
|
||||||
@FocusState private var focus: Field?
|
@FocusState private var focus: Field?
|
||||||
|
|
||||||
// @State private var ownerCredentials: Credentials?
|
@State private var ownerAccount: Account?
|
||||||
@State private var contactJID: String = ""
|
@State private var contactJID: String = ""
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
@ -56,13 +56,13 @@ struct AddContactOrChannelScreen: View {
|
||||||
.frame(alignment: .leading)
|
.frame(alignment: .leading)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
// UniversalInputCollection.DropDownMenu(
|
UniversalInputCollection.DropDownMenu(
|
||||||
// prompt: "Use account",
|
prompt: "Use account",
|
||||||
// elements: activeClientsCredentials,
|
elements: wrapper.accounts,
|
||||||
// selected: $ownerCredentials,
|
selected: $ownerAccount,
|
||||||
// focus: $focus,
|
focus: $focus,
|
||||||
// fieldType: .account
|
fieldType: .account
|
||||||
// )
|
)
|
||||||
|
|
||||||
// Contact text input
|
// Contact text input
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
|
@ -72,18 +72,18 @@ struct AddContactOrChannelScreen: View {
|
||||||
.frame(alignment: .leading)
|
.frame(alignment: .leading)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
// UniversalInputCollection.TextField(
|
UniversalInputCollection.TextField(
|
||||||
// prompt: "Contact or channel JID",
|
prompt: "Contact or channel JID",
|
||||||
// text: $contactJID,
|
text: $contactJID,
|
||||||
// focus: $focus,
|
focus: $focus,
|
||||||
// fieldType: .contact,
|
fieldType: .contact,
|
||||||
// contentType: .emailAddress,
|
contentType: .emailAddress,
|
||||||
// keyboardType: .emailAddress,
|
keyboardType: .emailAddress,
|
||||||
// submitLabel: .done,
|
submitLabel: .done,
|
||||||
// action: {
|
action: {
|
||||||
// focus = .account
|
focus = .account
|
||||||
// }
|
}
|
||||||
// )
|
)
|
||||||
|
|
||||||
// Save button
|
// Save button
|
||||||
Button {
|
Button {
|
||||||
|
@ -94,7 +94,7 @@ struct AddContactOrChannelScreen: View {
|
||||||
Text(L10n.Global.save)
|
Text(L10n.Global.save)
|
||||||
}
|
}
|
||||||
.buttonStyle(PrimaryButtonStyle())
|
.buttonStyle(PrimaryButtonStyle())
|
||||||
// .disabled(!inputValid)
|
.disabled(!inputValid)
|
||||||
.padding(.top)
|
.padding(.top)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
|
@ -102,24 +102,18 @@ struct AddContactOrChannelScreen: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
// if let exists = activeClientsCredentials.first {
|
if let exists = wrapper.accounts.first {
|
||||||
// ownerCredentials = exists
|
ownerAccount = exists
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private var activeClientsCredentials: [Credentials] {
|
private var inputValid: Bool {
|
||||||
// clientsStore.clients
|
ownerAccount != nil && !contactJID.isEmpty && UniversalInputCollection.Validators.isEmail(contactJID)
|
||||||
// .filter { $0.state != .disabled }
|
}
|
||||||
// .map { $0.credentials }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private var inputValid: Bool {
|
|
||||||
// ownerCredentials != nil && !contactJID.isEmpty && UniversalInputCollection.Validators.isEmail(contactJID)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
private func save() async {
|
private func save() async {
|
||||||
// guard let ownerCredentials = ownerCredentials else { return }
|
guard let ownerAccount = ownerAccount else { return }
|
||||||
|
|
||||||
router.showModal {
|
router.showModal {
|
||||||
LoadingScreen()
|
LoadingScreen()
|
||||||
|
|
|
@ -26,44 +26,19 @@ struct ContactsScreen: View {
|
||||||
)
|
)
|
||||||
|
|
||||||
// Contacts list
|
// Contacts list
|
||||||
// if !clientsStore.actualRosters.isEmpty {
|
if !wrapper.contacts.isEmpty {
|
||||||
// List {
|
List {
|
||||||
// ForEach(elements.indices, id: \.self) { index in
|
ForEach(wrapper.contacts) {
|
||||||
// let element = elements[index]
|
ContactsScreenRow(contact: $0)
|
||||||
// if let roster = element as? Roster {
|
}
|
||||||
// ContactsScreenRow(
|
}
|
||||||
// roster: roster
|
.listStyle(.plain)
|
||||||
// )
|
.background(Color.Material.Background.light)
|
||||||
// } else if let bareJid = element as? String {
|
} else {
|
||||||
// SharedSectionTitle(text: bareJid)
|
Spacer()
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// .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
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,49 +46,48 @@ private struct ContactsScreenRow: View {
|
||||||
@EnvironmentObject var wrapper: MonalXmppWrapper
|
@EnvironmentObject var wrapper: MonalXmppWrapper
|
||||||
@Environment(\.router) var router
|
@Environment(\.router) var router
|
||||||
|
|
||||||
// var roster: Roster
|
var contact: Contact
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Text("nothing for now")
|
SharedListRow(
|
||||||
// SharedListRow(
|
iconType: .charCircle(contact.name?.firstLetter ?? contact.contactJid.firstLetter),
|
||||||
// iconType: .charCircle(roster.name?.firstLetter ?? roster.contactBareJid.firstLetter),
|
text: contact.contactJid,
|
||||||
// text: roster.contactBareJid,
|
controlType: .none
|
||||||
// controlType: .none
|
)
|
||||||
// )
|
.onTapGesture {
|
||||||
// .onTapGesture {
|
startChat()
|
||||||
// startChat()
|
}
|
||||||
// }
|
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
||||||
// .swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
Button {
|
||||||
// Button {
|
router.showAlert(.confirmationDialog, title: L10n.Contacts.deleteContact, subtitle: L10n.Contacts.Delete.message) {
|
||||||
// router.showAlert(.confirmationDialog, title: L10n.Contacts.deleteContact, subtitle: L10n.Contacts.Delete.message) {
|
deleteConfirmation
|
||||||
// deleteConfirmation
|
}
|
||||||
// }
|
} label: {
|
||||||
// } label: {
|
Label("", systemImage: "trash")
|
||||||
// Label("", systemImage: "trash")
|
}
|
||||||
// }
|
.tint(Color.red)
|
||||||
// .tint(Color.red)
|
}
|
||||||
// }
|
.contextMenu {
|
||||||
// .contextMenu {
|
Button(L10n.Contacts.sendMessage, systemImage: "message") {
|
||||||
// Button(L10n.Contacts.sendMessage, systemImage: "message") {
|
startChat()
|
||||||
// startChat()
|
}
|
||||||
// }
|
Divider()
|
||||||
// Divider()
|
|
||||||
//
|
Button(L10n.Contacts.editContact) {
|
||||||
// Button(L10n.Contacts.editContact) {
|
print("Edit contact")
|
||||||
// print("Edit contact")
|
}
|
||||||
// }
|
|
||||||
//
|
Button(L10n.Contacts.selectContact) {
|
||||||
// Button(L10n.Contacts.selectContact) {
|
print("Select contact")
|
||||||
// print("Select contact")
|
}
|
||||||
// }
|
|
||||||
//
|
Divider()
|
||||||
// Divider()
|
Button(L10n.Contacts.deleteContact, systemImage: "trash", role: .destructive) {
|
||||||
// Button(L10n.Contacts.deleteContact, systemImage: "trash", role: .destructive) {
|
router.showAlert(.confirmationDialog, title: L10n.Contacts.deleteContact, subtitle: L10n.Contacts.Delete.message) {
|
||||||
// router.showAlert(.confirmationDialog, title: L10n.Contacts.deleteContact, subtitle: L10n.Contacts.Delete.message) {
|
deleteConfirmation
|
||||||
// deleteConfirmation
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder private var deleteConfirmation: some View {
|
@ViewBuilder private var deleteConfirmation: some View {
|
||||||
|
|
|
@ -27,8 +27,7 @@ struct MainTabScreen: View {
|
||||||
// ChatsListScreen()
|
// ChatsListScreen()
|
||||||
|
|
||||||
case .contacts:
|
case .contacts:
|
||||||
Text("contacts")
|
ContactsScreen()
|
||||||
// ContactsScreen()
|
|
||||||
|
|
||||||
case .settings:
|
case .settings:
|
||||||
Text("settings")
|
Text("settings")
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import monalxmpp
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
// MARK: - Account
|
||||||
enum AccountsAvailability {
|
enum AccountsAvailability {
|
||||||
case noAccounts
|
case noAccounts
|
||||||
case allDisabled
|
case allDisabled
|
||||||
|
@ -32,8 +35,22 @@ struct Account: Identifiable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Contact: Identifiable {
|
extension Account: UniversalInputSelectionElement {
|
||||||
let jid: String
|
var icon: Image? { nil }
|
||||||
|
var text: String? { jid }
|
||||||
var id: String { jid }
|
}
|
||||||
|
|
||||||
|
// MARK: - Contact
|
||||||
|
struct Contact: Identifiable {
|
||||||
|
let ownerId: Int
|
||||||
|
let contactJid: String
|
||||||
|
let name: String?
|
||||||
|
|
||||||
|
var id: String { contactJid }
|
||||||
|
|
||||||
|
init?(_ obj: MLContact) {
|
||||||
|
ownerId = obj.accountID.intValue
|
||||||
|
contactJid = obj.contactJid
|
||||||
|
name = obj.nickName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ final class MonalXmppWrapper: ObservableObject {
|
||||||
private let db: DataLayer
|
private let db: DataLayer
|
||||||
|
|
||||||
private var notificationObservers: [AnyObject] = []
|
private var notificationObservers: [AnyObject] = []
|
||||||
private var isInitialized: Bool = false
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// here is some inits (just for now)
|
// here is some inits (just for now)
|
||||||
|
@ -88,33 +87,43 @@ private final class LoginTry {
|
||||||
// MARK: - Handle notifications
|
// MARK: - Handle notifications
|
||||||
private extension MonalXmppWrapper {
|
private extension MonalXmppWrapper {
|
||||||
func subscribeToUpdates() {
|
func subscribeToUpdates() {
|
||||||
|
// General
|
||||||
let generalRefresh = NotificationCenter.default.addObserver(forName: Notification.Name(kMonalRefresh), object: nil, queue: .main) { [weak self] _ in
|
let generalRefresh = NotificationCenter.default.addObserver(forName: Notification.Name(kMonalRefresh), object: nil, queue: .main) { [weak self] _ in
|
||||||
// get accounts
|
self?.refreshAccounts()
|
||||||
let accounts = self?.db.accountList()
|
self?.refreshContacts()
|
||||||
|
}
|
||||||
|
notificationObservers.append(generalRefresh)
|
||||||
|
|
||||||
|
// For contacts
|
||||||
|
let contactRefresh = NotificationCenter.default.addObserver(forName: Notification.Name(kMonalContactRefresh), object: nil, queue: .main) { [weak self] _ in
|
||||||
|
self?.refreshContacts()
|
||||||
|
}
|
||||||
|
let contactRemove = NotificationCenter.default.addObserver(forName: Notification.Name(kMonalContactRemoved), object: nil, queue: .main) { [weak self] _ in
|
||||||
|
self?.refreshContacts()
|
||||||
|
}
|
||||||
|
notificationObservers.append(contentsOf: [contactRefresh, contactRemove])
|
||||||
|
}
|
||||||
|
|
||||||
|
func refreshAccounts() {
|
||||||
|
let accounts = db.accountList()
|
||||||
.compactMap { dict -> Account? in
|
.compactMap { dict -> Account? in
|
||||||
guard let dict = dict as? NSDictionary else { return nil }
|
guard let dict = dict as? NSDictionary else { return nil }
|
||||||
return Account(dict)
|
return Account(dict)
|
||||||
} ?? []
|
|
||||||
self?.accounts = accounts
|
|
||||||
|
|
||||||
// start connect if it initialization process
|
|
||||||
if !(self?.isInitialized ?? true) {
|
|
||||||
self?.xmpp.reconnectAll()
|
|
||||||
self?.isInitialized = true
|
|
||||||
}
|
}
|
||||||
|
self.accounts = accounts
|
||||||
|
xmpp.connectIfNecessary()
|
||||||
|
|
||||||
// mark accounts availability
|
// mark accounts availability
|
||||||
if accounts.isEmpty {
|
if accounts.isEmpty {
|
||||||
self?.accountsAvailability = .noAccounts
|
accountsAvailability = .noAccounts
|
||||||
} else if !accounts.filter({ $0.isEnabled }).isEmpty {
|
} else if accounts.filter({ $0.isEnabled }).isEmpty {
|
||||||
self?.accountsAvailability = .allDisabled
|
accountsAvailability = .allDisabled
|
||||||
} else {
|
} else {
|
||||||
self?.accountsAvailability = .someEnabled
|
accountsAvailability = .someEnabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get contacts for active accounts
|
func refreshContacts() {
|
||||||
//
|
contacts = db.contactList().compactMap { Contact($0) }
|
||||||
}
|
|
||||||
notificationObservers.append(generalRefresh)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue