Implement UI and logic, not completed yet

This commit is contained in:
ismailgulek
2020-09-18 18:56:58 +03:00
parent 70a555cbfc
commit 6d07d55cfa
10 changed files with 455 additions and 147 deletions
@@ -23,25 +23,51 @@ final class RoomInfoListViewController: UIViewController {
// MARK: - Constants
private enum Constants {
static let aConstant: Int = 666
static let defaultStyleCellReuseIdentifier = "default"
}
// MARK: - Properties
// MARK: Outlets
@IBOutlet private weak var scrollView: UIScrollView!
@IBOutlet private weak var informationLabel: UILabel!
@IBOutlet private weak var doneButton: UIButton!
@IBOutlet private weak var mainTableView: UITableView!
// MARK: Private
private var viewModel: RoomInfoListViewModelType!
private var theme: Theme!
private var keyboardAvoider: KeyboardAvoider?
private var errorPresenter: MXKErrorPresentation!
private var activityPresenter: ActivityIndicatorPresenter!
private lazy var closeButton: UIButton = {
return UIButton()
}()
private enum RowType {
case `default`
case basicInfo
case textView
}
private struct Row {
var type: RowType
var icon: UIImage?
var text: String?
var accessoryType: UITableViewCell.AccessoryType = .none
var action: (() -> Void)?
}
private struct Section {
var header: String?
var rows: [Row]
var footer: String?
}
private var sections: [Section] = [] {
didSet {
mainTableView.reloadData()
}
}
// MARK: - Setup
@@ -60,7 +86,6 @@ final class RoomInfoListViewController: UIViewController {
// Do any additional setup after loading the view.
self.setupViews()
self.keyboardAvoider = KeyboardAvoider(scrollViewContainerView: self.view, scrollView: self.scrollView)
self.activityPresenter = ActivityIndicatorPresenter()
self.errorPresenter = MXKErrorAlertPresentation()
@@ -72,39 +97,74 @@ final class RoomInfoListViewController: UIViewController {
self.viewModel.process(viewAction: .loadData)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.keyboardAvoider?.startAvoiding()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.keyboardAvoider?.stopAvoiding()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return self.theme.statusBarStyle
}
// MARK: - Private
private func updateSections() {
var tmpSections: [Section] = []
let row_0_0 = Row(type: .basicInfo, text: nil, accessoryType: .none, action: nil)
let section0 = Section(header: nil,
rows: [row_0_0],
footer: nil)
tmpSections.append(section0)
if viewModel.isEncrypted {
let section1 = Section(header: "Security",
rows: [],
footer: "Messages in this room are end to end encrypted")
tmpSections.append(section1)
}
let row_2_0 = Row(type: .default, icon: Asset.Images.settingsIcon.image, text: "Settings", accessoryType: .disclosureIndicator) {
self.viewModel.process(viewAction: .navigate(target: .settings))
}
let row_2_2 = Row(type: .default, icon: Asset.Images.userIcon.image, text: "\(viewModel.numberOfMembers) members", accessoryType: .disclosureIndicator) {
self.viewModel.process(viewAction: .navigate(target: .members))
}
let row_2_3 = Row(type: .default, icon: Asset.Images.scrollup.image, text: "Uploads", accessoryType: .disclosureIndicator) {
self.viewModel.process(viewAction: .navigate(target: .uploads))
}
let section2 = Section(header: "Other",
rows: [row_2_0,
row_2_2,
row_2_3],
footer: nil)
let row_3_0 = Row(type: .default, icon: Asset.Images.roomActionLeave.image, text: "Leave Room", accessoryType: .none) {
// no-op
}
let section3 = Section(header: nil,
rows: [row_3_0],
footer: nil)
tmpSections.append(section2)
tmpSections.append(section3)
sections = tmpSections
}
private func update(theme: Theme) {
self.theme = theme
self.view.backgroundColor = theme.headerBackgroundColor
self.mainTableView.backgroundColor = theme.headerBackgroundColor
if let navigationBar = self.navigationController?.navigationBar {
theme.applyStyle(onNavigationBar: navigationBar)
}
// TODO: Set view colors here
self.informationLabel.textColor = theme.textPrimaryColor
self.doneButton.backgroundColor = theme.backgroundColor
theme.applyStyle(onButton: self.doneButton)
self.closeButton.backgroundColor = theme.backgroundColor
theme.applyStyle(onButton: self.closeButton)
mainTableView.reloadData()
}
private func registerThemeServiceDidChangeThemeNotification() {
@@ -117,24 +177,28 @@ final class RoomInfoListViewController: UIViewController {
private func setupViews() {
let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in
self?.cancelButtonAction()
// self?.cancelButtonAction()
}
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
self.title = "Template"
self.title = ""
self.scrollView.keyboardDismissMode = .interactive
self.informationLabel.text = "VectorL10n.roomInfoListTitle"
mainTableView.register(cellType: TextViewTableViewCell.self)
mainTableView.register(cellType: RoomInfoBasicTableViewCell.self)
mainTableView.register(headerFooterViewType: TableViewHeaderFooterView.self)
mainTableView.sectionHeaderHeight = UITableView.automaticDimension
mainTableView.estimatedSectionHeaderHeight = 50
mainTableView.sectionFooterHeight = UITableView.automaticDimension
mainTableView.estimatedSectionFooterHeight = 50
}
private func render(viewState: RoomInfoListViewState) {
switch viewState {
case .loading:
self.renderLoading()
case .loaded(let displayName):
self.renderLoaded(displayName: displayName)
case .loaded:
self.renderLoaded()
case .error(let error):
self.render(error: error)
}
@@ -142,37 +206,180 @@ final class RoomInfoListViewController: UIViewController {
private func renderLoading() {
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
self.informationLabel.text = "Fetch display name"
}
private func renderLoaded(displayName: String) {
private func renderLoaded() {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.informationLabel.text = "You display name: \(displayName)"
self.updateSections()
}
private func render(error: Error) {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: nil)
}
// MARK: - Actions
@IBAction private func doneButtonAction(_ sender: Any) {
self.viewModel.process(viewAction: .complete)
}
private func cancelButtonAction() {
@IBAction private func closeButtonAction(_ sender: Any) {
self.viewModel.process(viewAction: .cancel)
}
}
// MARK: - UITableViewDataSource
extension RoomInfoListViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].rows.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let row = sections[indexPath.section].rows[indexPath.row]
switch row.type {
case .default:
var cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: Constants.defaultStyleCellReuseIdentifier)
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: Constants.defaultStyleCellReuseIdentifier)
}
if let icon = row.icon {
cell.imageView?.image = MXKTools.resize(icon, to: CGSize(width: 20, height: 20))?.vc_tintedImage(usingColor: theme.textSecondaryColor)
}
cell.textLabel?.font = .systemFont(ofSize: 17)
cell.detailTextLabel?.font = .systemFont(ofSize: 16)
cell.textLabel?.text = row.text
if row.accessoryType == .checkmark {
cell.accessoryView = UIImageView(image: Asset.Images.checkmark.image)
} else {
cell.accessoryView = nil
cell.accessoryType = row.accessoryType
}
cell.textLabel?.textColor = theme.textPrimaryColor
cell.detailTextLabel?.textColor = theme.textSecondaryColor
cell.backgroundColor = theme.backgroundColor
cell.contentView.backgroundColor = .clear
cell.tintColor = theme.tintColor
return cell
case .basicInfo:
let cell: RoomInfoBasicTableViewCell = tableView.dequeueReusableCell(for: indexPath)
cell.configure(withViewModel: viewModel.basicInfoViewModel)
cell.selectionStyle = .none
cell.update(theme: theme)
return cell
case .textView:
let cell: TextViewTableViewCell = tableView.dequeueReusableCell(for: indexPath)
cell.textView.textContainer.lineFragmentPadding = 0
cell.textView.textAlignment = .center
cell.textView.contentInset = .zero
cell.textView.textContainerInset = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
cell.textView.font = .systemFont(ofSize: 17)
cell.textView.text = row.text
cell.textView.isEditable = false
cell.textView.isScrollEnabled = false
cell.textView.backgroundColor = .clear
cell.selectionStyle = .none
cell.contentView.backgroundColor = theme.headerBackgroundColor
cell.update(theme: theme)
return cell
}
}
}
// MARK: - UITableViewDelegate
extension RoomInfoListViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = theme.backgroundColor
cell.selectedBackgroundView = UIView()
cell.selectedBackgroundView?.backgroundColor = theme.selectedBackgroundColor
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].header
}
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return sections[section].footer
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let header = sections[section].header else {
return nil
}
let view: TableViewHeaderFooterView? = tableView.dequeueReusableHeaderFooterView()
view?.textView.text = header
view?.textView.font = .systemFont(ofSize: 13)
view?.textViewInsets = UIEdgeInsets(top: 16, left: 16, bottom: 8, right: 16)
view?.update(theme: theme)
return view
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
guard let footer = sections[section].footer else {
return nil
}
let view: TableViewHeaderFooterView? = tableView.dequeueReusableHeaderFooterView()
view?.textView.text = footer
view?.textView.font = .systemFont(ofSize: 13)
view?.update(theme: theme)
return view
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let row = sections[indexPath.section].rows[indexPath.row]
row.action?()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let row = sections[indexPath.section].rows[indexPath.row]
switch row.type {
default:
return UITableView.automaticDimension
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if sections[section].header == nil {
return 18
}
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
if sections[section].footer == nil {
return 18
}
return UITableView.automaticDimension
}
}
// MARK: - RoomInfoListViewModelViewDelegate
extension RoomInfoListViewController: RoomInfoListViewModelViewDelegate {
func roomInfoListViewModel(_ viewModel: RoomInfoListViewModelType, didUpdateViewState viewSate: RoomInfoListViewState) {
self.render(viewState: viewSate)
}
}