Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(polls): Allow to browse poll drafts
Signed-off-by: Ivan Sein <[email protected]>
  • Loading branch information
Ivansss committed Jan 15, 2025
commit fd2758f42cef0f5bf1a5288575be4cb8ccf57af2
4 changes: 4 additions & 0 deletions NextcloudTalk.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@
2C7A12422017872600864818 /* AddParticipantsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C7A12402017872600864818 /* AddParticipantsTableViewController.m */; };
2C7A12432017872600864818 /* AddParticipantsTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C7A12412017872600864818 /* AddParticipantsTableViewController.xib */; };
2C7F47AA20289B9600081CC7 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2C7F47AC20289B9600081CC7 /* Localizable.strings */; };
2C8001D92D3529AF00DDBADC /* PollDraftsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8001D82D3529AF00DDBADC /* PollDraftsViewController.swift */; };
2C84BCCC29EEB9C6001BA6DA /* CallReactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C84BCCB29EEB9C6001BA6DA /* CallReactionView.swift */; };
2C84BCCE29EEDCE8001BA6DA /* CallReactionView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C84BCCD29EEDCE8001BA6DA /* CallReactionView.xib */; };
2C8A2BC9221F094F00DE6D2C /* DirectoryTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C8A2BC8221F094F00DE6D2C /* DirectoryTableViewController.m */; };
Expand Down Expand Up @@ -1009,6 +1010,7 @@
2C7A12402017872600864818 /* AddParticipantsTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AddParticipantsTableViewController.m; sourceTree = "<group>"; };
2C7A12412017872600864818 /* AddParticipantsTableViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AddParticipantsTableViewController.xib; sourceTree = "<group>"; };
2C7F47AB20289B9600081CC7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
2C8001D82D3529AF00DDBADC /* PollDraftsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollDraftsViewController.swift; sourceTree = "<group>"; };
2C84BCCB29EEB9C6001BA6DA /* CallReactionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallReactionView.swift; sourceTree = "<group>"; };
2C84BCCD29EEDCE8001BA6DA /* CallReactionView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CallReactionView.xib; sourceTree = "<group>"; };
2C8A2BC7221F094F00DE6D2C /* DirectoryTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DirectoryTableViewController.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1408,6 +1410,7 @@
2C5BFBF92891598900E75118 /* PollResultTableViewCell.swift */,
2C5BFBFA2891598900E75118 /* PollResultTableViewCell.xib */,
2C5BFBEE288A947800E75118 /* PollVotingView.swift */,
2C8001D82D3529AF00DDBADC /* PollDraftsViewController.swift */,
);
name = Polls;
sourceTree = "<group>";
Expand Down Expand Up @@ -2904,6 +2907,7 @@
2CB6ACCA26401D5200D3D641 /* GeoLocationRichObject.m in Sources */,
2C78EF9C1F826B22008AFA74 /* NCCallController.m in Sources */,
1F1B50442B9095D100B0F2F4 /* FederatedCapabilities.m in Sources */,
2C8001D92D3529AF00DDBADC /* PollDraftsViewController.swift in Sources */,
2C5BFBF628902E0300E75118 /* PollFooterView.swift in Sources */,
2C4D7D761F30F7B600FF4A0D /* ARDUtilities.m in Sources */,
1FF4DA7E2C0237D000C1B952 /* DirectoryTableViewCell.swift in Sources */,
Expand Down
41 changes: 38 additions & 3 deletions NextcloudTalk/PollCreationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import UIKit

@objcMembers class PollCreationViewController: UITableViewController, UITextFieldDelegate {
@objcMembers class PollCreationViewController: UITableViewController, UITextFieldDelegate, PollDraftsViewControllerDelegate {

enum PollCreationSection: Int {
case kPollCreationSectionQuestion = 0
Expand All @@ -23,6 +23,7 @@ import UIKit
let kQuestionTextFieldTag = 9999

var room: NCRoom
var draftsAvailable: Bool = false
var question: String = ""
var options: [String] = ["", ""]
var privateSwitch = UISwitch()
Expand All @@ -39,6 +40,7 @@ import UIKit

init(room: NCRoom) {
self.room = room
self.draftsAvailable = room.canModerate && NCDatabaseManager.sharedInstance().serverHasTalkCapability(kCapabilityTalkPollsDrafts, forAccountId: room.accountId)

super.init(style: .insetGrouped)
self.initPollCreationView()
Expand All @@ -50,6 +52,20 @@ import UIKit
self.creatingPollIndicatorView = UIActivityIndicatorView()
self.creatingPollIndicatorView.color = NCAppBranding.themeTextColor()

if draftsAvailable {
let menuAction = UIAction(title: NSLocalizedString("Browse poll drafts", comment: ""), image: UIImage(systemName: "doc")) { _ in
self.presentPollDraftsView()
}

let menu = UIMenu(title: "", options: .displayInline, children: [menuAction])
let menuButton = UIBarButtonItem(
image: UIImage(systemName: "ellipsis.circle"),
menu: menu
)

navigationItem.rightBarButtonItem = menuButton
}

self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: NCAppBranding.themeTextColor()]
self.navigationController?.navigationBar.tintColor = NCAppBranding.themeTextColor()
self.navigationController?.navigationBar.barTintColor = NCAppBranding.themeColor()
Expand Down Expand Up @@ -87,6 +103,26 @@ import UIKit
self.dismiss(animated: true, completion: nil)
}

func presentPollDraftsView() {
let pollDraftsVC = PollDraftsViewController(room: room)
pollDraftsVC.delegate = self
let navController = UINavigationController(rootViewController: pollDraftsVC)
present(navController, animated: true, completion: nil)
}

func didSelectPollDraft(question: String, options: [String], resultMode: NCPollResultMode, maxVotes: Int) {
// End editing for any textfield
self.view.endEditing(true)

// Assign poll draft values
self.question = question
self.options = options
self.privateSwitch.isOn = resultMode == .hidden
self.multipleSwitch.isOn = maxVotes == 0
self.tableView.reloadData()
self.checkIfPollIsReadyToCreate()
}

func showCreationError() {
let alert = UIAlertController(title: NSLocalizedString("Creating poll failed", comment: ""),
message: NSLocalizedString("An error occurred while creating the poll", comment: ""),
Expand Down Expand Up @@ -130,8 +166,7 @@ import UIKit
footerView.frame = CGRect(x: 0, y: 0, width: 0, height: PollFooterView.heightForOption)
footerView.secondaryButtonContainerView.isHidden = true

if room.canModerate,
NCDatabaseManager.sharedInstance().serverHasTalkCapability(kCapabilityTalkPollsDrafts, forAccountId: room.accountId) {
if draftsAvailable {
footerView.secondaryButton.setTitle(NSLocalizedString("Save as draft", comment: ""), for: .normal)
footerView.secondaryButton.setButtonStyle(style: .secondary)
footerView.secondaryButton.setButtonAction(target: self, selector: #selector(createPollDraftButtonPressed))
Expand Down
100 changes: 100 additions & 0 deletions NextcloudTalk/PollDraftsViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
// SPDX-License-Identifier: GPL-3.0-or-later
//

import UIKit

protocol PollDraftsViewControllerDelegate: AnyObject {
func didSelectPollDraft(question: String, options: [String], resultMode: NCPollResultMode, maxVotes: Int)
}

class PollDraftsViewController: UITableViewController {

weak var delegate: PollDraftsViewControllerDelegate?

var room: NCRoom
var drafts: [NCPoll] = []
let activityIndicator = UIActivityIndicatorView(style: .medium)

init(room: NCRoom) {
self.room = room
super.init(style: .insetGrouped)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()

self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: NCAppBranding.themeTextColor()]
self.navigationController?.navigationBar.tintColor = NCAppBranding.themeTextColor()
self.navigationController?.navigationBar.barTintColor = NCAppBranding.themeColor()
self.navigationController?.navigationBar.isTranslucent = false
self.navigationItem.title = NSLocalizedString("Poll drafts", comment: "")

let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.titleTextAttributes = [.foregroundColor: NCAppBranding.themeTextColor()]
appearance.backgroundColor = NCAppBranding.themeColor()
self.navigationItem.standardAppearance = appearance
self.navigationItem.compactAppearance = appearance
self.navigationItem.scrollEdgeAppearance = appearance

setupActivityIndicator()
getPollDrafts()
}

// MARK: - Activity Indicator
private func setupActivityIndicator() {
tableView.backgroundView = activityIndicator
activityIndicator.startAnimating()
}

// MARK: - Poll drafts
private func getPollDrafts() {
NCAPIController.sharedInstance().getPollDrafts(inRoom: room.token, for: room.account) { drafts, error, _ in
if error == nil, let drafts {
var draftsArray: [NCPoll] = []
let draftDicts: [[String: Any]] = drafts.compactMap { $0 as? [String: Any] }
for draftDict in draftDicts {
if let draft = NCPoll.initWithPollDictionary(draftDict) {
draftsArray.append(draft)
}
}
self.drafts = draftsArray
self.tableView.reloadData()
}

self.activityIndicator.stopAnimating()
}
}

// MARK: - TableView DataSource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return drafts.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "PollDraftCellIdentifier"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) ?? UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)
let draft = drafts[indexPath.row]

cell.imageView?.image = UIImage(systemName: "chart.bar")
cell.imageView?.tintColor = UIColor.label
cell.textLabel?.text = draft.question
cell.detailTextLabel?.text = NSLocalizedString("Poll draft", comment: "") + " • " + String.localizedStringWithFormat(NSLocalizedString("%d options", comment: "Number of options in a poll"), draft.options.count)

return cell
}

// MARK: - TableView Delegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
dismiss(animated: true) {
let draft = self.drafts[indexPath.row]
self.delegate?.didSelectPollDraft(question: draft.question, options: draft.options.compactMap { $0 as? String }, resultMode: draft.resultMode, maxVotes: draft.maxVotes)
}
}
}