feat: implement pick server view category select
This commit is contained in:
parent
738ba832a9
commit
eb7a33932e
|
@ -11,6 +11,11 @@
|
||||||
0FAA101225E105390017CCDE /* PrimaryActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA101125E105390017CCDE /* PrimaryActionButton.swift */; };
|
0FAA101225E105390017CCDE /* PrimaryActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA101125E105390017CCDE /* PrimaryActionButton.swift */; };
|
||||||
0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA101B25E10E760017CCDE /* UIFont.swift */; };
|
0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA101B25E10E760017CCDE /* UIFont.swift */; };
|
||||||
0FAA102725E1126A0017CCDE /* PickServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA102625E1126A0017CCDE /* PickServerViewController.swift */; };
|
0FAA102725E1126A0017CCDE /* PickServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA102625E1126A0017CCDE /* PickServerViewController.swift */; };
|
||||||
|
0FB3D2F725E4C24D00AAD544 /* PickServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D2F625E4C24D00AAD544 /* PickServerViewModel.swift */; };
|
||||||
|
0FB3D2FE25E4CB6400AAD544 /* PickServerTitleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D2FD25E4CB6400AAD544 /* PickServerTitleCell.swift */; };
|
||||||
|
0FB3D30825E524C600AAD544 /* PickServerCategoriesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D30725E524C600AAD544 /* PickServerCategoriesCell.swift */; };
|
||||||
|
0FB3D30F25E525CD00AAD544 /* PickServerCategoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */; };
|
||||||
|
0FB3D31E25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */; };
|
||||||
18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; };
|
18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; };
|
||||||
2D04F42525C255B9003F936F /* APIService+PublicTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */; };
|
2D04F42525C255B9003F936F /* APIService+PublicTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */; };
|
||||||
2D152A8C25C295CC009AA50C /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D152A8B25C295CC009AA50C /* StatusView.swift */; };
|
2D152A8C25C295CC009AA50C /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D152A8B25C295CC009AA50C /* StatusView.swift */; };
|
||||||
|
@ -204,6 +209,11 @@
|
||||||
0FAA101125E105390017CCDE /* PrimaryActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryActionButton.swift; sourceTree = "<group>"; };
|
0FAA101125E105390017CCDE /* PrimaryActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryActionButton.swift; sourceTree = "<group>"; };
|
||||||
0FAA101B25E10E760017CCDE /* UIFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFont.swift; sourceTree = "<group>"; };
|
0FAA101B25E10E760017CCDE /* UIFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFont.swift; sourceTree = "<group>"; };
|
||||||
0FAA102625E1126A0017CCDE /* PickServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerViewController.swift; sourceTree = "<group>"; };
|
0FAA102625E1126A0017CCDE /* PickServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerViewController.swift; sourceTree = "<group>"; };
|
||||||
|
0FB3D2F625E4C24D00AAD544 /* PickServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
0FB3D2FD25E4CB6400AAD544 /* PickServerTitleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerTitleCell.swift; sourceTree = "<group>"; };
|
||||||
|
0FB3D30725E524C600AAD544 /* PickServerCategoriesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoriesCell.swift; sourceTree = "<group>"; };
|
||||||
|
0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoryView.swift; sourceTree = "<group>"; };
|
||||||
|
0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoryCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+PublicTimeline.swift"; sourceTree = "<group>"; };
|
2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+PublicTimeline.swift"; sourceTree = "<group>"; };
|
||||||
2D152A8B25C295CC009AA50C /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = "<group>"; };
|
2D152A8B25C295CC009AA50C /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = "<group>"; };
|
||||||
2D152A9125C2980C009AA50C /* UIFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFont.swift; sourceTree = "<group>"; };
|
2D152A9125C2980C009AA50C /* UIFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFont.swift; sourceTree = "<group>"; };
|
||||||
|
@ -414,11 +424,40 @@
|
||||||
0FAA102525E1125D0017CCDE /* PickServer */ = {
|
0FAA102525E1125D0017CCDE /* PickServer */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
0FB3D31825E525DE00AAD544 /* CollectionViewCell */,
|
||||||
|
0FB3D30D25E525C000AAD544 /* View */,
|
||||||
|
0FB3D2FC25E4CB4B00AAD544 /* TableViewCell */,
|
||||||
0FAA102625E1126A0017CCDE /* PickServerViewController.swift */,
|
0FAA102625E1126A0017CCDE /* PickServerViewController.swift */,
|
||||||
|
0FB3D2F625E4C24D00AAD544 /* PickServerViewModel.swift */,
|
||||||
);
|
);
|
||||||
path = PickServer;
|
path = PickServer;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
0FB3D2FC25E4CB4B00AAD544 /* TableViewCell */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
0FB3D2FD25E4CB6400AAD544 /* PickServerTitleCell.swift */,
|
||||||
|
0FB3D30725E524C600AAD544 /* PickServerCategoriesCell.swift */,
|
||||||
|
);
|
||||||
|
path = TableViewCell;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
0FB3D30D25E525C000AAD544 /* View */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */,
|
||||||
|
);
|
||||||
|
path = View;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
0FB3D31825E525DE00AAD544 /* CollectionViewCell */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */,
|
||||||
|
);
|
||||||
|
path = CollectionViewCell;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
1EBA4F56E920856A3FC84ACB /* Pods */ = {
|
1EBA4F56E920856A3FC84ACB /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1328,6 +1367,7 @@
|
||||||
0FAA0FDF25E0B57E0017CCDE /* WelcomeViewController.swift in Sources */,
|
0FAA0FDF25E0B57E0017CCDE /* WelcomeViewController.swift in Sources */,
|
||||||
DB45FB1D25CA9D23005A8AC7 /* APIService+HomeTimeline.swift in Sources */,
|
DB45FB1D25CA9D23005A8AC7 /* APIService+HomeTimeline.swift in Sources */,
|
||||||
2D7631B325C159F700929FB9 /* Item.swift in Sources */,
|
2D7631B325C159F700929FB9 /* Item.swift in Sources */,
|
||||||
|
0FB3D2F725E4C24D00AAD544 /* PickServerViewModel.swift in Sources */,
|
||||||
2D61335E25C1894B00CAE157 /* APIService.swift in Sources */,
|
2D61335E25C1894B00CAE157 /* APIService.swift in Sources */,
|
||||||
2D38F1F725CD47AC00561493 /* HomeTimelineViewModel+LoadOldestState.swift in Sources */,
|
2D38F1F725CD47AC00561493 /* HomeTimelineViewModel+LoadOldestState.swift in Sources */,
|
||||||
2D5A3D3825CF8D9F002347D6 /* ScrollViewContainer.swift in Sources */,
|
2D5A3D3825CF8D9F002347D6 /* ScrollViewContainer.swift in Sources */,
|
||||||
|
@ -1361,6 +1401,7 @@
|
||||||
DB5086A525CC0B7000C2C187 /* AvatarBarButtonItem.swift in Sources */,
|
DB5086A525CC0B7000C2C187 /* AvatarBarButtonItem.swift in Sources */,
|
||||||
2D38F1E525CD46C100561493 /* HomeTimelineViewModel.swift in Sources */,
|
2D38F1E525CD46C100561493 /* HomeTimelineViewModel.swift in Sources */,
|
||||||
2D76316B25C14D4C00929FB9 /* PublicTimelineViewModel.swift in Sources */,
|
2D76316B25C14D4C00929FB9 /* PublicTimelineViewModel.swift in Sources */,
|
||||||
|
0FB3D2FE25E4CB6400AAD544 /* PickServerTitleCell.swift in Sources */,
|
||||||
2D38F1DF25CD46A400561493 /* HomeTimelineViewController+StatusProvider.swift in Sources */,
|
2D38F1DF25CD46A400561493 /* HomeTimelineViewController+StatusProvider.swift in Sources */,
|
||||||
2D46975E25C2A54100CF4AA9 /* NSLayoutConstraint.swift in Sources */,
|
2D46975E25C2A54100CF4AA9 /* NSLayoutConstraint.swift in Sources */,
|
||||||
2D45E5BF25C9549700A6D639 /* PublicTimelineViewModel+State.swift in Sources */,
|
2D45E5BF25C9549700A6D639 /* PublicTimelineViewModel+State.swift in Sources */,
|
||||||
|
@ -1375,6 +1416,7 @@
|
||||||
DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */,
|
DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */,
|
||||||
DB9D6BE925E4F5340051B173 /* SearchViewController.swift in Sources */,
|
DB9D6BE925E4F5340051B173 /* SearchViewController.swift in Sources */,
|
||||||
2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */,
|
2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */,
|
||||||
|
0FB3D30F25E525CD00AAD544 /* PickServerCategoryView.swift in Sources */,
|
||||||
DB8AF54525C13647002E6C99 /* NeedsDependency.swift in Sources */,
|
DB8AF54525C13647002E6C99 /* NeedsDependency.swift in Sources */,
|
||||||
DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */,
|
DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */,
|
||||||
DB45FADD25CA6F6B005A8AC7 /* APIService+CoreData+MastodonUser.swift in Sources */,
|
DB45FADD25CA6F6B005A8AC7 /* APIService+CoreData+MastodonUser.swift in Sources */,
|
||||||
|
@ -1417,7 +1459,10 @@
|
||||||
2D32EAAC25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift in Sources */,
|
2D32EAAC25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift in Sources */,
|
||||||
2D5A3D6225CFD9CB002347D6 /* HomeTimelineViewController+DebugAction.swift in Sources */,
|
2D5A3D6225CFD9CB002347D6 /* HomeTimelineViewController+DebugAction.swift in Sources */,
|
||||||
DB9D6BFF25E4F5940051B173 /* ProfileViewController.swift in Sources */,
|
DB9D6BFF25E4F5940051B173 /* ProfileViewController.swift in Sources */,
|
||||||
|
0FB3D30825E524C600AAD544 /* PickServerCategoriesCell.swift in Sources */,
|
||||||
2D38F1FE25CD481700561493 /* StatusProvider.swift in Sources */,
|
2D38F1FE25CD481700561493 /* StatusProvider.swift in Sources */,
|
||||||
|
2D5A3D1125CF87AA002347D6 /* AvatarBarButtonItem.swift in Sources */,
|
||||||
|
0FB3D31E25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift in Sources */,
|
||||||
DB45FB0F25CA87D0005A8AC7 /* AuthenticationService.swift in Sources */,
|
DB45FB0F25CA87D0005A8AC7 /* AuthenticationService.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
|
@ -39,6 +39,7 @@ extension SceneCoordinator {
|
||||||
|
|
||||||
enum Scene {
|
enum Scene {
|
||||||
case welcome
|
case welcome
|
||||||
|
case pickServer(viewMode: PickServerViewModel)
|
||||||
case authentication(viewModel: AuthenticationViewModel)
|
case authentication(viewModel: AuthenticationViewModel)
|
||||||
case mastodonPinBasedAuthentication(viewModel: MastodonPinBasedAuthenticationViewModel)
|
case mastodonPinBasedAuthentication(viewModel: MastodonPinBasedAuthenticationViewModel)
|
||||||
case mastodonRegister(viewModel: MastodonRegisterViewModel)
|
case mastodonRegister(viewModel: MastodonRegisterViewModel)
|
||||||
|
@ -136,6 +137,10 @@ private extension SceneCoordinator {
|
||||||
case .welcome:
|
case .welcome:
|
||||||
let _viewController = WelcomeViewController()
|
let _viewController = WelcomeViewController()
|
||||||
viewController = _viewController
|
viewController = _viewController
|
||||||
|
case .pickServer(let viewModel):
|
||||||
|
let _viewController = PickServerViewController()
|
||||||
|
_viewController.viewModel = viewModel
|
||||||
|
viewController = _viewController
|
||||||
case .authentication(let viewModel):
|
case .authentication(let viewModel):
|
||||||
let _viewController = AuthenticationViewController()
|
let _viewController = AuthenticationViewController()
|
||||||
_viewController.viewModel = viewModel
|
_viewController.viewModel = viewModel
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// UIFont.swift
|
// UIFont.swift
|
||||||
// Mastodon
|
// Mastodon
|
||||||
//
|
//
|
||||||
// Created by 高原 on 2021/2/20.
|
// Created by BradGao on 2021/2/20.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
|
@ -35,4 +35,28 @@ extension UIView {
|
||||||
layer.cornerCurve = .continuous
|
layer.cornerCurve = .continuous
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func applyShadow(
|
||||||
|
color: UIColor,
|
||||||
|
alpha: Float,
|
||||||
|
x: CGFloat,
|
||||||
|
y: CGFloat,
|
||||||
|
blur: CGFloat,
|
||||||
|
spread: CGFloat = 0) -> Self
|
||||||
|
{
|
||||||
|
layer.masksToBounds = false
|
||||||
|
layer.shadowColor = color.cgColor
|
||||||
|
layer.shadowOpacity = alpha
|
||||||
|
layer.shadowOffset = CGSize(width: x, height: y)
|
||||||
|
layer.shadowRadius = blur / 2.0
|
||||||
|
if spread == 0 {
|
||||||
|
layer.shadowPath = nil
|
||||||
|
} else {
|
||||||
|
let dx = -spread
|
||||||
|
let rect = bounds.insetBy(dx: dx, dy: dx)
|
||||||
|
layer.shadowPath = UIBezierPath(rect: rect).cgPath
|
||||||
|
}
|
||||||
|
return self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,12 @@ internal enum L10n {
|
||||||
internal enum ServerPicker {
|
internal enum ServerPicker {
|
||||||
/// Pick a Server,\nany server.
|
/// Pick a Server,\nany server.
|
||||||
internal static let title = L10n.tr("Localizable", "Scene.ServerPicker.Title")
|
internal static let title = L10n.tr("Localizable", "Scene.ServerPicker.Title")
|
||||||
|
internal enum Button {
|
||||||
|
internal enum Category {
|
||||||
|
/// All
|
||||||
|
internal static let all = L10n.tr("Localizable", "Scene.ServerPicker.Button.Category.All")
|
||||||
|
}
|
||||||
|
}
|
||||||
internal enum Input {
|
internal enum Input {
|
||||||
/// Find a server or join your own...
|
/// Find a server or join your own...
|
||||||
internal static let placeholder = L10n.tr("Localizable", "Scene.ServerPicker.Input.Placeholder")
|
internal static let placeholder = L10n.tr("Localizable", "Scene.ServerPicker.Input.Placeholder")
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
"Scene.ServerPicker.Input.Placeholder" = "Find a server or join your own...";
|
"Scene.ServerPicker.Input.Placeholder" = "Find a server or join your own...";
|
||||||
"Scene.ServerPicker.Title" = "Pick a Server,
|
"Scene.ServerPicker.Title" = "Pick a Server,
|
||||||
any server.";
|
any server.";
|
||||||
|
"Scene.ServerPicker.Button.Category.All" = "All";
|
||||||
"Scene.ServerRules.Button.Confirm" = "I Agree";
|
"Scene.ServerRules.Button.Confirm" = "I Agree";
|
||||||
"Scene.ServerRules.Prompt" = "By continuing, you're subject to the terms of service and privacy policy for %@.";
|
"Scene.ServerRules.Prompt" = "By continuing, you're subject to the terms of service and privacy policy for %@.";
|
||||||
"Scene.ServerRules.Subtitle" = "These rules are set by the admins of %@.";
|
"Scene.ServerRules.Subtitle" = "These rules are set by the admins of %@.";
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
//
|
||||||
|
// PickServerCategoryCollectionViewCell.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by BradGao on 2021/2/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class PickServerCategoryCollectionViewCell: UICollectionViewCell {
|
||||||
|
|
||||||
|
var category: PickServerViewModel.Category? {
|
||||||
|
didSet {
|
||||||
|
categoryView.category = category
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var categoryView: PickServerCategoryView = {
|
||||||
|
let view = PickServerCategoryView()
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
override var isSelected: Bool {
|
||||||
|
didSet {
|
||||||
|
categoryView.selected = isSelected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: .zero)
|
||||||
|
configure()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
configure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerCategoryCollectionViewCell {
|
||||||
|
private func configure() {
|
||||||
|
contentView.addSubview(categoryView)
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
categoryView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||||
|
categoryView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||||
|
categoryView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),
|
||||||
|
contentView.bottomAnchor.constraint(equalTo: categoryView.bottomAnchor, constant: 10),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,12 +2,21 @@
|
||||||
// PickServerViewController.swift
|
// PickServerViewController.swift
|
||||||
// Mastodon
|
// Mastodon
|
||||||
//
|
//
|
||||||
// Created by 高原 on 2021/2/20.
|
// Created by BradGao on 2021/2/20.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Combine
|
||||||
|
|
||||||
class PickServerViewController: UIViewController {
|
final class PickServerViewController: UIViewController, NeedsDependency {
|
||||||
|
|
||||||
|
private var disposeBag = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
||||||
|
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
||||||
|
|
||||||
|
var viewModel: PickServerViewModel!
|
||||||
|
|
||||||
let titleLabel: UILabel = {
|
let titleLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = .boldSystemFont(ofSize: 34)
|
label.font = .boldSystemFont(ofSize: 34)
|
||||||
|
@ -18,4 +27,63 @@ class PickServerViewController: UIViewController {
|
||||||
label.numberOfLines = 0
|
label.numberOfLines = 0
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
let tableView: UITableView = {
|
||||||
|
let tableView = ControlContainableTableView()
|
||||||
|
tableView.register(PickServerTitleCell.self, forCellReuseIdentifier: String(describing: PickServerTitleCell.self))
|
||||||
|
tableView.register(PickServerCategoriesCell.self, forCellReuseIdentifier: String(describing: PickServerCategoriesCell.self))
|
||||||
|
// tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self))
|
||||||
|
tableView.rowHeight = UITableView.automaticDimension
|
||||||
|
tableView.separatorStyle = .none
|
||||||
|
tableView.backgroundColor = .clear
|
||||||
|
|
||||||
|
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
|
return tableView
|
||||||
|
}()
|
||||||
|
|
||||||
|
let nextStepButton: PrimaryActionButton = {
|
||||||
|
let button = PrimaryActionButton(type: .system)
|
||||||
|
button.setTitle(L10n.Button.signUp, for: .normal)
|
||||||
|
button.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerViewController {
|
||||||
|
|
||||||
|
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||||
|
return .darkContent
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
view.backgroundColor = Asset.Colors.Background.onboardingBackground.color
|
||||||
|
|
||||||
|
view.addSubview(nextStepButton)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
nextStepButton.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor, constant: 12),
|
||||||
|
view.readableContentGuide.trailingAnchor.constraint(equalTo: nextStepButton.trailingAnchor, constant: 12),
|
||||||
|
view.bottomAnchor.constraint(equalTo: nextStepButton.bottomAnchor, constant: 34),
|
||||||
|
])
|
||||||
|
|
||||||
|
view.addSubview(tableView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
tableView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||||
|
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||||
|
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||||
|
nextStepButton.topAnchor.constraint(equalTo: tableView.bottomAnchor, constant: 7)
|
||||||
|
])
|
||||||
|
|
||||||
|
switch viewModel.mode {
|
||||||
|
case .SignIn:
|
||||||
|
nextStepButton.setTitle(L10n.Common.Controls.Actions.signIn, for: .normal)
|
||||||
|
case .SignUp:
|
||||||
|
nextStepButton.setTitle(L10n.Common.Controls.Actions.continue, for: .normal)
|
||||||
|
}
|
||||||
|
|
||||||
|
tableView.delegate = viewModel
|
||||||
|
tableView.dataSource = viewModel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
//
|
||||||
|
// PickServerViewModel.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by BradGao on 2021/2/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import Combine
|
||||||
|
import MastodonSDK
|
||||||
|
|
||||||
|
class PickServerViewModel: NSObject {
|
||||||
|
enum PickServerMode {
|
||||||
|
case SignUp
|
||||||
|
case SignIn
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Section: CaseIterable {
|
||||||
|
case title
|
||||||
|
case categories
|
||||||
|
case serverList
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Category {
|
||||||
|
// `All` means search for all categories
|
||||||
|
case All
|
||||||
|
// `Some` means search for specific category
|
||||||
|
case Some(Mastodon.Entity.Category)
|
||||||
|
|
||||||
|
var title: String {
|
||||||
|
switch self {
|
||||||
|
case .All:
|
||||||
|
return L10n.Scene.ServerPicker.Button.Category.all
|
||||||
|
case .Some(let masCategory):
|
||||||
|
switch masCategory.category {
|
||||||
|
case .academia:
|
||||||
|
return "AC"
|
||||||
|
case .activism:
|
||||||
|
return "AT"
|
||||||
|
case .food:
|
||||||
|
return "F"
|
||||||
|
case .furry:
|
||||||
|
return "FU"
|
||||||
|
case .games:
|
||||||
|
return "G"
|
||||||
|
case .general:
|
||||||
|
return "GE"
|
||||||
|
case .journalism:
|
||||||
|
return "JO"
|
||||||
|
case .lgbt:
|
||||||
|
return "LG"
|
||||||
|
case .regional:
|
||||||
|
return "📍"
|
||||||
|
case .art:
|
||||||
|
return "🎨"
|
||||||
|
case .music:
|
||||||
|
return "🎼"
|
||||||
|
case .tech:
|
||||||
|
return "📱"
|
||||||
|
case ._other:
|
||||||
|
return "UN"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mode: PickServerMode
|
||||||
|
let context: AppContext
|
||||||
|
|
||||||
|
var categories = [Category]()
|
||||||
|
let selectCategoryIndex = CurrentValueSubject<Int, Never>(0)
|
||||||
|
|
||||||
|
let searchText = CurrentValueSubject<String?, Never>(nil)
|
||||||
|
|
||||||
|
let allServers = CurrentValueSubject<[Mastodon.Entity.Instance], Error>([])
|
||||||
|
let searchedServers = CurrentValueSubject<[Mastodon.Entity.Instance], Error>([])
|
||||||
|
|
||||||
|
let nextButtonEnable = CurrentValueSubject<Bool, Never>(false)
|
||||||
|
|
||||||
|
init(context: AppContext, mode: PickServerMode) {
|
||||||
|
self.context = context
|
||||||
|
self.mode = mode
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
configure()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func configure() {
|
||||||
|
let masCategories = context.apiService.stubCategories()
|
||||||
|
categories.append(.All)
|
||||||
|
categories.append(contentsOf: masCategories.map { Category.Some($0) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerViewModel: UITableViewDelegate {
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||||
|
if section == 0 {
|
||||||
|
return 20
|
||||||
|
}
|
||||||
|
else if section == 1 {
|
||||||
|
return 10
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerViewModel: UITableViewDataSource {
|
||||||
|
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||||
|
return UIView()
|
||||||
|
}
|
||||||
|
|
||||||
|
func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
|
return Self.Section.allCases.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
let section = Self.Section.allCases[section]
|
||||||
|
switch section {
|
||||||
|
case .title,
|
||||||
|
.categories:
|
||||||
|
return 1
|
||||||
|
case .serverList:
|
||||||
|
return searchedServers.value.count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
|
||||||
|
let section = Self.Section.allCases[indexPath.section]
|
||||||
|
switch section {
|
||||||
|
case .title:
|
||||||
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerTitleCell.self), for: indexPath) as! PickServerTitleCell
|
||||||
|
return cell
|
||||||
|
case .categories:
|
||||||
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerCategoriesCell.self), for: indexPath) as! PickServerCategoriesCell
|
||||||
|
cell.dataSource = self
|
||||||
|
cell.delegate = self
|
||||||
|
return cell
|
||||||
|
case .serverList:
|
||||||
|
return UITableViewCell(style: .default, reuseIdentifier: "1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerViewModel: PickServerCategoriesDataSource, PickServerCategoriesDelegate {
|
||||||
|
func numberOfCategories() -> Int {
|
||||||
|
return categories.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func category(at index: Int) -> Category {
|
||||||
|
return categories[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
func selectedIndex() -> Int {
|
||||||
|
return selectCategoryIndex.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func pickServerCategoriesCell(didSelect index: Int) {
|
||||||
|
selectCategoryIndex.send(index)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
//
|
||||||
|
// PickServerCategoriesCell.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by BradGao on 2021/2/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import MastodonSDK
|
||||||
|
|
||||||
|
protocol PickServerCategoriesDataSource: class {
|
||||||
|
func numberOfCategories() -> Int
|
||||||
|
func category(at index: Int) -> PickServerViewModel.Category
|
||||||
|
func selectedIndex() -> Int
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol PickServerCategoriesDelegate: class {
|
||||||
|
func pickServerCategoriesCell(didSelect index: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
final class PickServerCategoriesCell: UITableViewCell {
|
||||||
|
|
||||||
|
weak var dataSource: PickServerCategoriesDataSource!
|
||||||
|
weak var delegate: PickServerCategoriesDelegate!
|
||||||
|
|
||||||
|
let collectionView: UICollectionView = {
|
||||||
|
let flowLayout = UICollectionViewFlowLayout()
|
||||||
|
flowLayout.scrollDirection = .horizontal
|
||||||
|
let view = ControlContainableCollectionView(frame: .zero, collectionViewLayout: flowLayout)
|
||||||
|
view.backgroundColor = .clear
|
||||||
|
view.showsHorizontalScrollIndicator = false
|
||||||
|
view.register(PickServerCategoryCollectionViewCell.self, forCellWithReuseIdentifier: String(describing: PickServerCategoryCollectionViewCell.self))
|
||||||
|
view.showsVerticalScrollIndicator = false
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerCategoriesCell {
|
||||||
|
|
||||||
|
private func _init() {
|
||||||
|
self.selectionStyle = .none
|
||||||
|
backgroundColor = .clear
|
||||||
|
|
||||||
|
contentView.addSubview(collectionView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
collectionView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||||
|
collectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||||
|
collectionView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||||
|
collectionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||||
|
|
||||||
|
collectionView.heightAnchor.constraint(equalToConstant: 80),
|
||||||
|
])
|
||||||
|
|
||||||
|
collectionView.delegate = self
|
||||||
|
collectionView.dataSource = self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerCategoriesCell: UICollectionViewDelegateFlowLayout {
|
||||||
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
|
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredHorizontally)
|
||||||
|
delegate.pickServerCategoriesCell(didSelect: indexPath.row)
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
|
||||||
|
return UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
|
||||||
|
return 16
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
|
||||||
|
return CGSize(width: 60, height: 80)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerCategoriesCell: UICollectionViewDataSource {
|
||||||
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
|
return dataSource.numberOfCategories()
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
let category = dataSource.category(at: indexPath.row)
|
||||||
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: PickServerCategoryCollectionViewCell.self), for: indexPath) as! PickServerCategoryCollectionViewCell
|
||||||
|
cell.category = category
|
||||||
|
|
||||||
|
// Select the default category by default
|
||||||
|
if indexPath.row == dataSource.selectedIndex() {
|
||||||
|
// Use `[]` as the scrollPosition to avoid contentOffset change
|
||||||
|
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: [])
|
||||||
|
cell.isSelected = true
|
||||||
|
}
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
//
|
||||||
|
// PickServerTitleCell.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by BradGao on 2021/2/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class PickServerTitleCell: UITableViewCell {
|
||||||
|
|
||||||
|
let titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: UIFont.boldSystemFont(ofSize: 34))
|
||||||
|
label.textColor = Asset.Colors.Label.black.color
|
||||||
|
label.text = L10n.Scene.ServerPicker.title
|
||||||
|
label.adjustsFontForContentSizeCategory = true
|
||||||
|
label.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
label.numberOfLines = 0
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerTitleCell {
|
||||||
|
|
||||||
|
private func _init() {
|
||||||
|
self.selectionStyle = .none
|
||||||
|
backgroundColor = .clear
|
||||||
|
|
||||||
|
contentView.addSubview(titleLabel)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
titleLabel.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||||
|
contentView.readableContentGuide.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
|
||||||
|
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||||
|
titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
//
|
||||||
|
// PickServerCategoryView.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by BradGao on 2021/2/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import MastodonSDK
|
||||||
|
|
||||||
|
class PickServerCategoryView: UIView {
|
||||||
|
var category: PickServerViewModel.Category? {
|
||||||
|
didSet {
|
||||||
|
updateCategory()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var selected: Bool = false {
|
||||||
|
didSet {
|
||||||
|
updateSelectStatus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var bgShadowView: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
var bgView: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
view.layer.masksToBounds = true
|
||||||
|
view.layer.cornerRadius = 30
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.textAlignment = .center
|
||||||
|
label.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
init() {
|
||||||
|
super.init(frame: .zero)
|
||||||
|
configure()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
configure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PickServerCategoryView {
|
||||||
|
private func configure() {
|
||||||
|
// bgShadowView.backgroundColor = nil
|
||||||
|
// addSubview(bgShadowView)
|
||||||
|
// bgShadowView.addSubview(bgView)
|
||||||
|
addSubview(bgView)
|
||||||
|
addSubview(titleLabel)
|
||||||
|
|
||||||
|
bgView.backgroundColor = .white
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
// bgShadowView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
|
||||||
|
// bgShadowView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
|
||||||
|
// bgShadowView.topAnchor.constraint(equalTo: self.topAnchor),
|
||||||
|
// bgShadowView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
|
||||||
|
|
||||||
|
bgView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
|
||||||
|
bgView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
|
||||||
|
bgView.topAnchor.constraint(equalTo: self.topAnchor),
|
||||||
|
bgView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
|
||||||
|
|
||||||
|
titleLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor),
|
||||||
|
titleLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateCategory() {
|
||||||
|
guard let category = category else { return }
|
||||||
|
titleLabel.text = category.title
|
||||||
|
switch category {
|
||||||
|
case .All:
|
||||||
|
titleLabel.font = UIFont.systemFont(ofSize: 17)
|
||||||
|
case .Some:
|
||||||
|
titleLabel.font = UIFont.systemFont(ofSize: 28)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateSelectStatus() {
|
||||||
|
if selected {
|
||||||
|
bgView.backgroundColor = Asset.Colors.lightBrandBlue.color
|
||||||
|
bgView.applyShadow(color: Asset.Colors.lightBrandBlue.color, alpha: 1, x: 0, y: 0, blur: 4.0)
|
||||||
|
if case .All = category {
|
||||||
|
titleLabel.textColor = .white
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bgView.backgroundColor = .white
|
||||||
|
bgView.applyShadow(color: Asset.Colors.lightBrandBlue.color, alpha: 0, x: 0, y: 0, blur: 0.0)
|
||||||
|
if case .All = category {
|
||||||
|
titleLabel.textColor = Asset.Colors.lightBackground.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
// PrimaryActionButton.swift
|
// PrimaryActionButton.swift
|
||||||
// Mastodon
|
// Mastodon
|
||||||
//
|
//
|
||||||
// Created by 高原 on 2021/2/20.
|
// Created by BradGao on 2021/2/20.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// WelcomeViewController.swift
|
// WelcomeViewController.swift
|
||||||
// Mastodon
|
// Mastodon
|
||||||
//
|
//
|
||||||
// Created by 高原 on 2021/2/20.
|
// Created by BradGao on 2021/2/20.
|
||||||
//
|
//
|
||||||
|
|
||||||
import os.log
|
import os.log
|
||||||
|
@ -88,8 +88,8 @@ extension WelcomeViewController {
|
||||||
signInButton.topAnchor.constraint(equalTo: signUpButton.bottomAnchor, constant: 5)
|
signInButton.topAnchor.constraint(equalTo: signUpButton.bottomAnchor, constant: 5)
|
||||||
])
|
])
|
||||||
|
|
||||||
signInButton.addTarget(self, action: #selector(WelcomeViewController.signInButtonPressed(_:)), for: .touchUpInside)
|
signUpButton.addTarget(self, action: #selector(signUpButtonDidClicked(_:)), for: .touchUpInside)
|
||||||
signUpButton.addTarget(self, action: #selector(WelcomeViewController.signUpButtonPressed(_:)), for: .touchUpInside)
|
signInButton.addTarget(self, action: #selector(signInButtonDidClicked(_:)), for: .touchUpInside)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
@ -119,3 +119,15 @@ extension WelcomeViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension WelcomeViewController {
|
||||||
|
@objc
|
||||||
|
private func signUpButtonDidClicked(_ sender: UIButton) {
|
||||||
|
coordinator.present(scene: .pickServer(viewMode: PickServerViewModel(context: context, mode: .SignUp)), from: self, transition: .show)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
private func signInButtonDidClicked(_ sender: UIButton) {
|
||||||
|
coordinator.present(scene: .pickServer(viewMode: PickServerViewModel(context: context, mode: .SignIn)), from: self, transition: .show)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue