123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- //
- // SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- // SPDX-License-Identifier: GPL-3.0-or-later
- //
- import UIKit
- enum NewRoomOption: Int {
- case createNewRoom = 0
- case joinOpenRoom
- }
- @objcMembers class NewRoomTableViewController: UITableViewController,
- UINavigationControllerDelegate,
- UISearchResultsUpdating {
- var account: TalkAccount
- var indexes: [String] = [""]
- var contacts: [String: [NCUser]] = [:]
- var searchController: UISearchController
- let resultTableViewController = ContactsSearchResultTableViewController(style: .insetGrouped)
- var searchTimer: Timer?
- var searchRequest: URLSessionTask?
- init(account: TalkAccount) {
- self.account = account
- self.searchController = UISearchController(searchResultsController: resultTableViewController)
- super.init(style: .insetGrouped)
- }
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
- self.navigationItem.hidesSearchBarWhenScrolling = false
- self.getPossibleContacts()
- }
- override func viewDidLoad() {
- super.viewDidLoad()
- NCAppBranding.styleViewController(self)
- self.navigationItem.title = NSLocalizedString("New conversation", comment: "")
- self.resultTableViewController.tableView.delegate = self
- self.searchController.searchResultsUpdater = self
- self.searchController.searchBar.tintColor = NCAppBranding.themeTextColor()
- self.navigationItem.searchController = searchController
- self.navigationItem.searchController?.searchBar.searchTextField.backgroundColor = NCUtils.searchbarBGColor(forColor: NCAppBranding.themeColor())
- if #available(iOS 16.0, *) {
- self.navigationItem.preferredSearchBarPlacement = .stacked
- }
- if let searchTextField = searchController.searchBar.value(forKey: "searchField") as? UITextField {
- searchTextField.tintColor = NCAppBranding.themeTextColor()
- searchTextField.textColor = NCAppBranding.themeTextColor()
- DispatchQueue.main.async {
- // Search bar placeholder
- searchTextField.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("Search", comment: ""),
- attributes: [NSAttributedString.Key.foregroundColor: NCAppBranding.themeTextColor().withAlphaComponent(0.5)])
- // Search bar search icon
- if let searchImageView = searchTextField.leftView as? UIImageView {
- searchImageView.image = searchImageView.image?.withRenderingMode(.alwaysTemplate)
- searchImageView.tintColor = NCAppBranding.themeTextColor().withAlphaComponent(0.5)
- }
- // Search bar search clear button
- if let clearButton = searchTextField.value(forKey: "_clearButton") as? UIButton {
- let clearButtonImage = clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate)
- clearButton.setImage(clearButtonImage, for: .normal)
- clearButton.setImage(clearButtonImage, for: .highlighted)
- clearButton.tintColor = NCAppBranding.themeTextColor()
- }
- }
- }
- self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(self.cancelButtonPressed))
- self.navigationItem.leftBarButtonItem?.tintColor = NCAppBranding.themeTextColor()
- self.tableView.register(UINib(nibName: kContactsTableCellNibName, bundle: nil), forCellReuseIdentifier: kContactCellIdentifier)
- }
- func cancelButtonPressed() {
- self.dismiss(animated: true, completion: nil)
- }
- // MARK: - New room options
- func getNewRoomOptions() -> [NewRoomOption] {
- var options = [NewRoomOption]()
- // New group room
- if NCSettingsController.sharedInstance().canCreateGroupAndPublicRooms() {
- options.append(.createNewRoom)
- }
- // List open rooms
- if NCDatabaseManager.sharedInstance().serverHasTalkCapability(kCapabilityListableRooms, forAccountId: self.account.accountId) {
- options.append(.joinOpenRoom)
- }
- return options
- }
- // MARK: - Contacts
- func getPossibleContacts() {
- NCAPIController.sharedInstance().getContactsFor(account, forRoom: "new", groupRoom: false, withSearchParam: "") { indexes, _, contactList, error in
- if error == nil, let indexes = indexes as? [String], let contactList = contactList as? [NCUser] {
- let storedContacts = NCContact.contacts(forAccountId: self.account.accountId, contains: nil)
- let combinedContactList = NCUser.combineUsersArray(storedContacts, withUsersArray: contactList)
- if let combinedContacts = NCUser.indexedUsers(fromUsersArray: combinedContactList) {
- let combinedIndexes = Array(combinedContacts.keys).sorted { $0.localizedCaseInsensitiveCompare($1) == .orderedAscending }
- self.indexes.append(contentsOf: combinedIndexes)
- self.contacts = combinedContacts
- self.tableView.reloadData()
- }
- }
- }
- }
- // MARK: - Search
- func updateSearchResults(for searchController: UISearchController) {
- self.searchTimer?.invalidate()
- self.resultTableViewController.showSearchingUI()
- DispatchQueue.main.async {
- self.searchTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.searchForContacts), userInfo: nil, repeats: false)
- }
- }
- func searchForContacts() {
- if let searchTerm = self.searchController.searchBar.text, !searchTerm.isEmpty {
- self.searchForContactsWithSearchParameter(searchTerm)
- }
- }
- func searchForContactsWithSearchParameter(_ searchParameter: String) {
- searchRequest?.cancel()
- searchRequest = NCAPIController.sharedInstance().getContactsFor(account, forRoom: "new", groupRoom: false, withSearchParam: searchParameter) { indexes, contacts, contactList, error in
- if error == nil, let contactList = contactList as? [NCUser] {
- let storedContacts = NCContact.contacts(forAccountId: self.account.accountId, contains: searchParameter)
- let combinedContactList = NCUser.combineUsersArray(storedContacts, withUsersArray: contactList)
- if let combinedContacts = NCUser.indexedUsers(fromUsersArray: combinedContactList) {
- let combinedIndexes = Array(combinedContacts.keys).sorted { $0.localizedCaseInsensitiveCompare($1) == .orderedAscending }
- self.resultTableViewController.setSearchResultContacts(combinedContacts, indexes: combinedIndexes)
- }
- }
- }
- }
- // MARK: - TableView
- override func numberOfSections(in tableView: UITableView) -> Int {
- return indexes.count
- }
- override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
- return indexes
- }
- override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
- return indexes[section]
- }
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- if section == 0 {
- return getNewRoomOptions().count
- } else {
- let index = indexes[section]
- return contacts[index]?.count ?? 0
- }
- }
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- if indexPath.section == 0 {
- let options = getNewRoomOptions()
- let option = options[indexPath.row]
- var newRoomOptionCell = UITableViewCell()
- switch option {
- case .createNewRoom:
- newRoomOptionCell = tableView.dequeueReusableCell(withIdentifier: "NewGroupRoomCellIdentifier") ?? UITableViewCell(style: .default, reuseIdentifier: "NewGroupRoomCellIdentifier")
- newRoomOptionCell.textLabel?.text = NSLocalizedString("Create a new conversation", comment: "")
- newRoomOptionCell.imageView?.image = UIImage(systemName: "bubble")
- case .joinOpenRoom:
- newRoomOptionCell = tableView.dequeueReusableCell(withIdentifier: "ListOpenRoomsCellIdentifier") ?? UITableViewCell(style: .default, reuseIdentifier: "ListOpenRoomsCellIdentifier")
- newRoomOptionCell.textLabel?.text = NSLocalizedString("Join open conversations", comment: "")
- newRoomOptionCell.imageView?.image = UIImage(systemName: "list.bullet")
- }
- newRoomOptionCell.imageView?.tintColor = .secondaryLabel
- newRoomOptionCell.imageView?.contentMode = .scaleAspectFit
- newRoomOptionCell.textLabel?.numberOfLines = 0
- return newRoomOptionCell
- } else {
- let index = indexes[indexPath.section]
- let contactsForIndex = contacts[index]
- guard let contact = contactsForIndex?[indexPath.row] else {
- return UITableViewCell()
- }
- let contactCell = tableView.dequeueReusableCell(withIdentifier: kContactCellIdentifier) as? ContactsTableViewCell ??
- ContactsTableViewCell(style: .default, reuseIdentifier: kContactCellIdentifier)
- contactCell.labelTitle.text = contact.name
- let contactType = contact.source as String
- contactCell.contactImage.setActorAvatar(forId: contact.userId, withType: contactType, withDisplayName: contact.name, withRoomToken: nil)
- return contactCell
- }
- }
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- if searchController.isActive && !resultTableViewController.contacts.isEmpty {
- let index = resultTableViewController.indexes[indexPath.section]
- let contactsForIndex = resultTableViewController.contacts[index]
- guard let contact = contactsForIndex?[indexPath.row] else { return }
- self.createRoomWithContact(contact)
- } else if indexPath.section == 0 {
- let options = getNewRoomOptions()
- let option = options[indexPath.row]
- if option == .createNewRoom {
- self.presentCreateRoomViewController()
- } else if option == .joinOpenRoom {
- self.presentJoinOpenRoomsViewController()
- }
- } else {
- let index = indexes[indexPath.section]
- let contactsForIndex = contacts[index]
- guard let contact = contactsForIndex?[indexPath.row] else { return }
- self.createRoomWithContact(contact)
- }
- tableView.deselectRow(at: indexPath, animated: true)
- }
- // MARK: - Actions
- func presentCreateRoomViewController() {
- let viewController = RoomCreationTableViewController(account: account)
- let navController = NCNavigationController(rootViewController: viewController)
- self.present(navController, animated: true)
- }
- func presentJoinOpenRoomsViewController() {
- let viewController = OpenConversationsTableViewController()
- let navController = NCNavigationController(rootViewController: viewController)
- self.present(navController, animated: true)
- }
- func createRoomWithContact(_ contact: NCUser) {
- NCAPIController.sharedInstance().createRoom(forAccount: account, withInvite: contact.userId, ofType: .oneToOne, andName: nil) { room, error in
- if let token = room?.token, error == nil {
- self.navigationController?.dismiss(animated: true) {
- NotificationCenter.default.post(name: NSNotification.Name.NCSelectedUserForChat, object: self, userInfo: ["token": token])
- }
- }
- }
- }
- }
|