mirror of
https://github.com/mastodon/mastodon-ios
synced 2025-04-11 22:58:02 +02:00
"Welcome back" screen cleanup (IOS-226) (#1282)
* Update texts (IOS-226) * Remove next-button (IOS-226) * Tap on row to login (IOS-226) * Make text use blurple and no disclosure indicator (IOS-226) * Fix separator lines (IOS-226) Well. Configurations don't work with custom UI-elements (or I'm just stupid), that's why I had to fall back to good ol UITableViewCell with UIKit-components
This commit is contained in:
parent
906b13c03d
commit
8d97b5a51e
@ -306,8 +306,8 @@
|
||||
}
|
||||
},
|
||||
"login": {
|
||||
"title": "Welcome back",
|
||||
"subtitle": "Log you in on the server you created your account on.",
|
||||
"title": "Welcome Back",
|
||||
"subtitle": "Log in with the server where you created your account.",
|
||||
"server_search_field": {
|
||||
"placeholder": "Enter URL or search for your server"
|
||||
}
|
||||
|
@ -306,8 +306,8 @@
|
||||
}
|
||||
},
|
||||
"login": {
|
||||
"title": "Welcome back",
|
||||
"subtitle": "Log you in on the server you created your account on.",
|
||||
"title": "Welcome Back",
|
||||
"subtitle": "Log in with the server where you created your account.",
|
||||
"server_search_field": {
|
||||
"placeholder": "Enter URL or search for your server"
|
||||
}
|
||||
|
@ -608,10 +608,6 @@ extension SceneCoordinator: MastodonLoginViewControllerDelegate {
|
||||
func backButtonPressed(_ viewController: MastodonLoginViewController) {
|
||||
viewController.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
|
||||
func nextButtonPressed(_ viewController: MastodonLoginViewController) {
|
||||
viewController.login()
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - SettingsCoordinatorDelegate
|
||||
|
@ -1,12 +1,58 @@
|
||||
//
|
||||
// MastodonLoginServerTableViewCell.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by Nathan Mattes on 11.11.22.
|
||||
//
|
||||
// Copyright © 2024 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import MastodonAsset
|
||||
|
||||
class MastodonLoginServerTableViewCell: UITableViewCell {
|
||||
static let reuseIdentifier = "MastodonLoginServerTableViewCell"
|
||||
static let reuseIdentifier = "MastodonLoginServerTableViewCell"
|
||||
|
||||
let separator: UIView
|
||||
let titleLabel: UILabel
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
|
||||
separator = UIView.separatorLine
|
||||
separator.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
titleLabel = UILabel()
|
||||
titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
titleLabel.textColor = Asset.Colors.Brand.blurple.color
|
||||
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
backgroundColor = Asset.Scene.Onboarding.textFieldBackground.color
|
||||
|
||||
contentView.addSubview(titleLabel)
|
||||
contentView.addSubview(separator)
|
||||
setupConstraints()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||
|
||||
override func prepareForReuse() {
|
||||
titleLabel.text = nil
|
||||
}
|
||||
|
||||
private func setupConstraints() {
|
||||
let separatorHeight = UIView.separatorLineHeight(of: contentView)
|
||||
let constraints = [
|
||||
separator.heightAnchor.constraint(equalToConstant: separatorHeight),
|
||||
|
||||
separator.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 18),
|
||||
contentView.trailingAnchor.constraint(equalTo: separator.trailingAnchor),
|
||||
contentView.bottomAnchor.constraint(equalTo: separator.bottomAnchor),
|
||||
|
||||
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 14),
|
||||
titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
|
||||
contentView.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
|
||||
separator.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 13),
|
||||
]
|
||||
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
}
|
||||
|
||||
public func configure(domain: String, separatorHidden: Bool = false) {
|
||||
titleLabel.text = domain
|
||||
separator.isHidden = separatorHidden
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ class MastodonLoginView: UIView {
|
||||
tableView.backgroundColor = Asset.Scene.Onboarding.textFieldBackground.color
|
||||
tableView.keyboardDismissMode = .onDrag
|
||||
tableView.layer.cornerRadius = 10
|
||||
tableView.separatorStyle = .none
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
|
@ -15,7 +15,6 @@ import MastodonLocalization
|
||||
|
||||
protocol MastodonLoginViewControllerDelegate: AnyObject {
|
||||
func backButtonPressed(_ viewController: MastodonLoginViewController)
|
||||
func nextButtonPressed(_ viewController: MastodonLoginViewController)
|
||||
}
|
||||
|
||||
enum MastodonLoginViewSection: Hashable {
|
||||
@ -24,10 +23,6 @@ enum MastodonLoginViewSection: Hashable {
|
||||
|
||||
class MastodonLoginViewController: UIViewController, NeedsDependency {
|
||||
|
||||
enum RightBarButtonState {
|
||||
case normal, disabled, loading
|
||||
}
|
||||
|
||||
weak var delegate: MastodonLoginViewControllerDelegate?
|
||||
var dataSource: UITableViewDiffableDataSource<MastodonLoginViewSection, Mastodon.Entity.Server>?
|
||||
let viewModel: MastodonLoginViewModel
|
||||
@ -59,21 +54,13 @@ class MastodonLoginViewController: UIViewController, NeedsDependency {
|
||||
override func loadView() {
|
||||
let loginView = MastodonLoginView()
|
||||
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||
title: L10n.Common.Controls.Actions.next,
|
||||
style: .plain,
|
||||
target: self,
|
||||
action: #selector(nextButtonPressed(_:))
|
||||
)
|
||||
|
||||
navigationItem.leftBarButtonItem?.target = self
|
||||
navigationItem.leftBarButtonItem?.action = #selector(backButtonPressed(_:))
|
||||
|
||||
loginView.searchTextField.addTarget(self, action: #selector(MastodonLoginViewController.textfieldDidChange(_:)), for: .editingChanged)
|
||||
loginView.tableView.delegate = self
|
||||
loginView.tableView.register(MastodonLoginServerTableViewCell.self, forCellReuseIdentifier: MastodonLoginServerTableViewCell.reuseIdentifier)
|
||||
setRightBarButtonState(.disabled)
|
||||
|
||||
|
||||
view = loginView
|
||||
}
|
||||
|
||||
@ -85,22 +72,24 @@ class MastodonLoginViewController: UIViewController, NeedsDependency {
|
||||
|
||||
let dataSource = UITableViewDiffableDataSource<MastodonLoginViewSection, Mastodon.Entity.Server>(tableView: contentView.tableView) { [weak self] tableView, indexPath, itemIdentifier in
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: MastodonLoginServerTableViewCell.reuseIdentifier, for: indexPath) as? MastodonLoginServerTableViewCell,
|
||||
let self = self else {
|
||||
let self else {
|
||||
fatalError("Wrong cell")
|
||||
}
|
||||
|
||||
let server = self.viewModel.filteredServers[indexPath.row]
|
||||
var configuration = cell.defaultContentConfiguration()
|
||||
configuration.text = server.domain
|
||||
|
||||
cell.contentConfiguration = configuration
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
|
||||
cell.backgroundColor = Asset.Scene.Onboarding.textFieldBackground.color
|
||||
let isLastServer: Bool
|
||||
|
||||
if let lastServer = self.viewModel.filteredServers.last {
|
||||
isLastServer = (lastServer == server)
|
||||
} else {
|
||||
isLastServer = false
|
||||
}
|
||||
|
||||
cell.configure(domain: server.domain, separatorHidden: isLastServer)
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
|
||||
contentView.tableView.dataSource = dataSource
|
||||
self.dataSource = dataSource
|
||||
|
||||
@ -131,15 +120,7 @@ class MastodonLoginViewController: UIViewController, NeedsDependency {
|
||||
delegate?.backButtonPressed(self)
|
||||
}
|
||||
|
||||
@objc func nextButtonPressed(_ sender: Any) {
|
||||
contentView.searchTextField.resignFirstResponder()
|
||||
delegate?.nextButtonPressed(self)
|
||||
setRightBarButtonState(.loading)
|
||||
}
|
||||
|
||||
@objc func login() {
|
||||
guard let server = viewModel.selectedServer else { return }
|
||||
|
||||
func login(on server: Mastodon.Entity.Server) {
|
||||
authenticationViewModel
|
||||
.authenticated.sink { (domain, account) in
|
||||
Task { @MainActor in
|
||||
@ -177,9 +158,7 @@ class MastodonLoginViewController: UIViewController, NeedsDependency {
|
||||
case .failure(let error):
|
||||
let alert = UIAlertController.standardAlert(of: error)
|
||||
self.present(alert, animated: true)
|
||||
self.setRightBarButtonState(.normal)
|
||||
case .finished:
|
||||
self.setRightBarButtonState(.normal)
|
||||
break
|
||||
}
|
||||
} receiveValue: { [weak self] info in
|
||||
@ -203,17 +182,16 @@ class MastodonLoginViewController: UIViewController, NeedsDependency {
|
||||
|
||||
@objc func textfieldDidChange(_ textField: UITextField) {
|
||||
viewModel.filterServers(withText: textField.text)
|
||||
|
||||
|
||||
|
||||
if let text = textField.text,
|
||||
let domain = AuthenticationViewModel.parseDomain(from: text) {
|
||||
|
||||
viewModel.selectedServer = .init(domain: domain, instance: .init(domain: domain))
|
||||
setRightBarButtonState(.normal)
|
||||
} else {
|
||||
viewModel.selectedServer = nil
|
||||
setRightBarButtonState(.disabled)
|
||||
let selectedServer = Mastodon.Entity.Server(domain: domain, instance: .init(domain: domain))
|
||||
if viewModel.filteredServers.contains(where: { $0 == selectedServer }) == false {
|
||||
viewModel.filteredServers.insert(selectedServer, at: 0)
|
||||
}
|
||||
}
|
||||
|
||||
serversUpdated(viewModel)
|
||||
}
|
||||
|
||||
// MARK: - Notifications
|
||||
@ -239,25 +217,6 @@ class MastodonLoginViewController: UIViewController, NeedsDependency {
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
private func setRightBarButtonState(_ state: RightBarButtonState) {
|
||||
switch state {
|
||||
case .normal:
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||
title: L10n.Common.Controls.Actions.next,
|
||||
style: .plain,
|
||||
target: self,
|
||||
action: #selector(nextButtonPressed(_:))
|
||||
)
|
||||
case .disabled:
|
||||
navigationItem.rightBarButtonItem?.isEnabled = false
|
||||
case .loading:
|
||||
let activityIndicator = UIActivityIndicatorView(style: .medium)
|
||||
activityIndicator.startAnimating()
|
||||
let barButtonItem = UIBarButtonItem(customView: activityIndicator)
|
||||
navigationItem.rightBarButtonItem = barButtonItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - OnboardingViewControllerAppearance
|
||||
@ -266,14 +225,10 @@ extension MastodonLoginViewController: OnboardingViewControllerAppearance { }
|
||||
// MARK: - UITableViewDelegate
|
||||
extension MastodonLoginViewController: UITableViewDelegate {
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let server = viewModel.filteredServers[indexPath.row]
|
||||
viewModel.selectedServer = server
|
||||
|
||||
contentView.searchTextField.text = server.domain
|
||||
viewModel.filterServers(withText: " ")
|
||||
|
||||
setRightBarButtonState(.normal)
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
|
||||
let selectedServer = viewModel.filteredServers[indexPath.row]
|
||||
login(on: selectedServer)
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,7 +241,7 @@ extension MastodonLoginViewController: MastodonLoginViewModelDelegate {
|
||||
snapshot.appendItems(viewModel.filteredServers)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.dataSource?.apply(snapshot, animatingDifferences: false)
|
||||
self.dataSource?.applySnapshotUsingReloadData(snapshot)
|
||||
let numberOfResults = viewModel.filteredServers.count
|
||||
self.contentView.updateCorners(numberOfResults: numberOfResults)
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ protocol MastodonLoginViewModelDelegate: AnyObject {
|
||||
class MastodonLoginViewModel {
|
||||
|
||||
private var serverList: [Mastodon.Entity.Server] = []
|
||||
var selectedServer: Mastodon.Entity.Server?
|
||||
var filteredServers: [Mastodon.Entity.Server] = []
|
||||
|
||||
weak var appContext: AppContext?
|
||||
|
@ -863,10 +863,10 @@ public enum L10n {
|
||||
}
|
||||
}
|
||||
public enum Login {
|
||||
/// Log you in on the server you created your account on.
|
||||
public static let subtitle = L10n.tr("Localizable", "Scene.Login.Subtitle", fallback: "Log you in on the server you created your account on.")
|
||||
/// Welcome back
|
||||
public static let title = L10n.tr("Localizable", "Scene.Login.Title", fallback: "Welcome back")
|
||||
/// Log in with the server where you created your account.
|
||||
public static let subtitle = L10n.tr("Localizable", "Scene.Login.Subtitle", fallback: "Log in with the server where you created your account.")
|
||||
/// Welcome Back
|
||||
public static let title = L10n.tr("Localizable", "Scene.Login.Title", fallback: "Welcome Back")
|
||||
public enum ServerSearchField {
|
||||
/// Enter URL or search for your server
|
||||
public static let placeholder = L10n.tr("Localizable", "Scene.Login.ServerSearchField.Placeholder", fallback: "Enter URL or search for your server")
|
||||
|
@ -307,8 +307,8 @@ uploaded to Mastodon.";
|
||||
"Scene.HomeTimeline.TimelinePill.PostSent" = "Post Sent";
|
||||
"Scene.HomeTimeline.Title" = "Home";
|
||||
"Scene.Login.ServerSearchField.Placeholder" = "Enter URL or search for your server";
|
||||
"Scene.Login.Subtitle" = "Log you in on the server you created your account on.";
|
||||
"Scene.Login.Title" = "Welcome back";
|
||||
"Scene.Login.Subtitle" = "Log in with the server where you created your account.";
|
||||
"Scene.Login.Title" = "Welcome Back";
|
||||
"Scene.Notification.FollowRequest.Accept" = "Accept";
|
||||
"Scene.Notification.FollowRequest.Accepted" = "Accepted";
|
||||
"Scene.Notification.FollowRequest.Reject" = "reject";
|
||||
|
Loading…
x
Reference in New Issue
Block a user