Add video and link to joinmastodon.org communities for new users
This commit is contained in:
parent
841d9e2926
commit
0811bf7274
|
@ -68,6 +68,7 @@
|
|||
"app-icon.rainbow-brutalist" = "Rainbow Brutalist";
|
||||
"app-icon.classic" = "Classic";
|
||||
"app-icon.rainbow" = "Rainbow";
|
||||
"add-identity.get-started" = "Get started";
|
||||
"add-identity.instance-url" = "Instance URL";
|
||||
"add-identity.log-in" = "Log in";
|
||||
"add-identity.browse" = "Browse";
|
||||
|
|
|
@ -228,6 +228,7 @@
|
|||
D0F4362D25C10B9600E4F896 /* AddIdentityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F4362C25C10B9600E4F896 /* AddIdentityViewController.swift */; };
|
||||
D0FCC105259C4E61000B67DF /* NewStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */; };
|
||||
D0FCC106259C4E62000B67DF /* NewStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */; };
|
||||
D0FCD6AD261AB2DD00113701 /* InstancePickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FCD6AC261AB2DD00113701 /* InstancePickerViewController.swift */; };
|
||||
D0FE1C8F253686F9003EF1EB /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FE1C8E253686F9003EF1EB /* PlayerView.swift */; };
|
||||
D0FE1C9825368A9D003EF1EB /* PlayerCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FE1C9725368A9D003EF1EB /* PlayerCache.swift */; };
|
||||
D0FE7C8025C4C79F00203957 /* PreviewViewModels in Frameworks */ = {isa = PBXBuildFile; productRef = D0FE7C7F25C4C79F00203957 /* PreviewViewModels */; };
|
||||
|
@ -469,6 +470,7 @@
|
|||
D0F0B135251AA12700942152 /* CollectionItem+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CollectionItem+Extensions.swift"; sourceTree = "<group>"; };
|
||||
D0F4362C25C10B9600E4F896 /* AddIdentityViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddIdentityViewController.swift; sourceTree = "<group>"; };
|
||||
D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewStatusViewController.swift; sourceTree = "<group>"; };
|
||||
D0FCD6AC261AB2DD00113701 /* InstancePickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstancePickerViewController.swift; sourceTree = "<group>"; };
|
||||
D0FE1C8E253686F9003EF1EB /* PlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerView.swift; sourceTree = "<group>"; };
|
||||
D0FE1C9725368A9D003EF1EB /* PlayerCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerCache.swift; sourceTree = "<group>"; };
|
||||
D9E658692601CF76007C426E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
|
@ -803,6 +805,7 @@
|
|||
D08B8D49253FC36500B1EBEF /* ImageNavigationController.swift */,
|
||||
D08B8D41253F92B600B1EBEF /* ImagePageViewController.swift */,
|
||||
D08B8D3C253F929E00B1EBEF /* ImageViewController.swift */,
|
||||
D0FCD6AC261AB2DD00113701 /* InstancePickerViewController.swift */,
|
||||
D035F86825B7F2ED00DC75ED /* MainNavigationViewController.swift */,
|
||||
D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */,
|
||||
D097F4C025BFA04C00859F2C /* NotificationsViewController.swift */,
|
||||
|
@ -1240,6 +1243,7 @@
|
|||
D00702312555F4AE00F38136 /* ConversationView.swift in Sources */,
|
||||
D0BEB21124FA2A91001B0F04 /* EditFilterView.swift in Sources */,
|
||||
D08B8D4A253FC36500B1EBEF /* ImageNavigationController.swift in Sources */,
|
||||
D0FCD6AD261AB2DD00113701 /* InstancePickerViewController.swift in Sources */,
|
||||
D0070252255921B100F38136 /* AccountFieldView.swift in Sources */,
|
||||
D0030982250C6C8500EACB32 /* URL+Extensions.swift in Sources */,
|
||||
D0BE97A325CF44310057E161 /* CGRect+Extensions.swift in Sources */,
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
import Combine
|
||||
import Mastodon
|
||||
import SafariServices
|
||||
import SDWebImage
|
||||
import SwiftUI
|
||||
import ViewModels
|
||||
import WebKit
|
||||
|
||||
final class AddIdentityViewController: UIViewController {
|
||||
private let viewModel: AddIdentityViewModel
|
||||
|
@ -26,7 +26,11 @@ final class AddIdentityViewController: UIViewController {
|
|||
private let activityIndicator = UIActivityIndicatorView(style: .large)
|
||||
private let joinButton = CapsuleButton()
|
||||
private let browseButton = CapsuleButton()
|
||||
private let whatIsMastodonButton = UIButton(type: .system)
|
||||
private let whatIsMastodonBackgroundView = UIView()
|
||||
private let whatIsMastodonStackView = UIStackView()
|
||||
private let whatIsMastodonLabel = UILabel()
|
||||
private let whatIsMastodonVideoView: WKWebView
|
||||
private let getStartedButton = CapsuleButton()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
init(viewModel: AddIdentityViewModel, rootViewModel: RootViewModel, displayWelcome: Bool) {
|
||||
|
@ -34,6 +38,12 @@ final class AddIdentityViewController: UIViewController {
|
|||
self.rootViewModel = rootViewModel
|
||||
self.displayWelcome = displayWelcome
|
||||
|
||||
let configuration = WKWebViewConfiguration()
|
||||
|
||||
configuration.allowsInlineMediaPlayback = true
|
||||
|
||||
whatIsMastodonVideoView = WKWebView(frame: .zero, configuration: configuration)
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
|
@ -55,7 +65,7 @@ final class AddIdentityViewController: UIViewController {
|
|||
|
||||
private extension AddIdentityViewController {
|
||||
static let verticalSpacing: CGFloat = 20
|
||||
static let whatIsMastodonURL = URL(string: "https://joinmastodon.org")!
|
||||
static let whatIsMastodonVideoURL = URL(string: "https://www.youtube.com/embed/IPSbNdBmWKE?playsinline=1")!
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
func configureViews() {
|
||||
|
@ -134,14 +144,40 @@ private extension AddIdentityViewController {
|
|||
for: .touchUpInside)
|
||||
browseButton.isHidden_stackViewSafe = true
|
||||
|
||||
whatIsMastodonButton.setTitle(NSLocalizedString("add-identity.what-is-mastodon", comment: ""), for: .normal)
|
||||
whatIsMastodonButton.addAction(
|
||||
whatIsMastodonBackgroundView.backgroundColor = .secondarySystemBackground
|
||||
whatIsMastodonBackgroundView.clipsToBounds = true
|
||||
whatIsMastodonBackgroundView.layer.cornerRadius = .defaultCornerRadius
|
||||
|
||||
whatIsMastodonStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
whatIsMastodonStackView.axis = .vertical
|
||||
whatIsMastodonStackView.spacing = .defaultSpacing * 2
|
||||
|
||||
whatIsMastodonLabel.adjustsFontForContentSizeCategory = true
|
||||
whatIsMastodonLabel.font = .preferredFont(forTextStyle: .headline)
|
||||
whatIsMastodonLabel.textAlignment = .center
|
||||
whatIsMastodonLabel.text = NSLocalizedString("add-identity.what-is-mastodon", comment: "")
|
||||
|
||||
getStartedButton.setTitle(NSLocalizedString("add-identity.get-started", comment: ""), for: .normal)
|
||||
getStartedButton.addAction(
|
||||
UIAction { [weak self] _ in
|
||||
self?.present(SFSafariViewController(url: Self.whatIsMastodonURL), animated: true)
|
||||
self?.urlTextField.resignFirstResponder()
|
||||
self?.present(
|
||||
UINavigationController(rootViewController: InstancePickerViewController {
|
||||
self?.viewModel.urlFieldText = $1
|
||||
self?.urlTextField.text = $1
|
||||
self?.urlTextField.becomeFirstResponder()
|
||||
self?.dismiss(animated: true)
|
||||
}),
|
||||
animated: true)
|
||||
},
|
||||
for: .touchUpInside)
|
||||
|
||||
for button in [logInButton, joinButton, browseButton, whatIsMastodonButton] {
|
||||
whatIsMastodonVideoView.scrollView.isScrollEnabled = false
|
||||
whatIsMastodonVideoView.clipsToBounds = true
|
||||
whatIsMastodonVideoView.layer.cornerRadius = .defaultCornerRadius
|
||||
whatIsMastodonVideoView.load(.init(url: Self.whatIsMastodonVideoURL))
|
||||
|
||||
for button in [logInButton, joinButton, browseButton] {
|
||||
button.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +199,11 @@ private extension AddIdentityViewController {
|
|||
buttonsStackView.addArrangedSubview(joinButton)
|
||||
buttonsStackView.addArrangedSubview(browseButton)
|
||||
buttonsStackView.addArrangedSubview(UIView())
|
||||
stackView.addArrangedSubview(whatIsMastodonButton)
|
||||
stackView.addArrangedSubview(whatIsMastodonBackgroundView)
|
||||
whatIsMastodonBackgroundView.addSubview(whatIsMastodonStackView)
|
||||
whatIsMastodonStackView.addArrangedSubview(whatIsMastodonLabel)
|
||||
whatIsMastodonStackView.addArrangedSubview(whatIsMastodonVideoView)
|
||||
whatIsMastodonStackView.addArrangedSubview(getStartedButton)
|
||||
}
|
||||
|
||||
func setupConstraints() {
|
||||
|
@ -183,7 +223,17 @@ private extension AddIdentityViewController {
|
|||
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
|
||||
stackView.widthAnchor.constraint(equalTo: scrollView.readableContentGuide.widthAnchor),
|
||||
stackView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
|
||||
instanceImageViewWidthConstraint
|
||||
instanceImageViewWidthConstraint,
|
||||
whatIsMastodonStackView.leadingAnchor.constraint(equalTo: whatIsMastodonBackgroundView.leadingAnchor,
|
||||
constant: .defaultSpacing * 2),
|
||||
whatIsMastodonStackView.topAnchor.constraint(equalTo: whatIsMastodonBackgroundView.topAnchor,
|
||||
constant: .defaultSpacing * 2),
|
||||
whatIsMastodonStackView.trailingAnchor.constraint(equalTo: whatIsMastodonBackgroundView.trailingAnchor,
|
||||
constant: -.defaultSpacing * 2),
|
||||
whatIsMastodonStackView.bottomAnchor.constraint(equalTo: whatIsMastodonBackgroundView.bottomAnchor,
|
||||
constant: -.defaultSpacing * 2),
|
||||
whatIsMastodonVideoView.widthAnchor.constraint(equalTo: whatIsMastodonVideoView.heightAnchor,
|
||||
multiplier: 16 / 9)
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -213,7 +263,7 @@ private extension AddIdentityViewController {
|
|||
promptLabel.alpha = 0
|
||||
urlTextField.alpha = 0
|
||||
logInButton.alpha = 0
|
||||
whatIsMastodonButton.alpha = 0
|
||||
whatIsMastodonBackgroundView.alpha = 0
|
||||
|
||||
UIView.animate(withDuration: .longAnimationDuration * 2) {
|
||||
self.welcomeLabel.alpha = 1
|
||||
|
@ -228,14 +278,13 @@ private extension AddIdentityViewController {
|
|||
UIView.animate(withDuration: .longAnimationDuration) {
|
||||
self.urlTextField.alpha = 1
|
||||
} completion: { _ in
|
||||
self.urlTextField.becomeFirstResponder()
|
||||
UIView.animate(withDuration: .longAnimationDuration) {
|
||||
self.logInButton.alpha = 1
|
||||
} completion: { _ in
|
||||
self.whatIsMastodonButton.isHidden_stackViewSafe = false
|
||||
self.whatIsMastodonButton.alpha = 0
|
||||
UIView.animate(withDuration: .longAnimationDuration) {
|
||||
self.whatIsMastodonButton.alpha = 1
|
||||
self.whatIsMastodonBackgroundView.alpha = 1
|
||||
} completion: { _ in
|
||||
self.urlTextField.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -244,7 +293,6 @@ private extension AddIdentityViewController {
|
|||
}
|
||||
} else {
|
||||
welcomeLabel.isHidden_stackViewSafe = true
|
||||
whatIsMastodonButton.isHidden_stackViewSafe = !displayWelcome
|
||||
urlTextField.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
|
@ -281,13 +329,10 @@ private extension AddIdentityViewController {
|
|||
}
|
||||
|
||||
self.browseButton.isHidden_stackViewSafe = !isPublicTimelineAvailable || loading
|
||||
self.whatIsMastodonButton.isHidden_stackViewSafe = true
|
||||
} else {
|
||||
self.instanceStackView.isHidden_stackViewSafe = true
|
||||
self.joinButton.isHidden_stackViewSafe = true
|
||||
self.browseButton.isHidden_stackViewSafe = true
|
||||
self.whatIsMastodonButton.isHidden_stackViewSafe =
|
||||
!self.displayWelcome || self.logInButton.alpha < 1 || loading
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright © 2021 Metabolist. All rights reserved.
|
||||
|
||||
import Combine
|
||||
import UIKit
|
||||
import WebKit
|
||||
|
||||
final class InstancePickerViewController: UIViewController {
|
||||
private let selectionAction: (InstancePickerViewController, String) -> Void
|
||||
private let webView: WKWebView
|
||||
private let backButton: UIBarButtonItem
|
||||
private let forwardButton: UIBarButtonItem
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
init(selectionAction: @escaping (InstancePickerViewController, String) -> Void) {
|
||||
let webView = WKWebView()
|
||||
|
||||
webView.allowsBackForwardNavigationGestures = true
|
||||
self.webView = webView
|
||||
self.selectionAction = selectionAction
|
||||
backButton = UIBarButtonItem(title: nil, image: UIImage(systemName: "chevron.backward"),
|
||||
primaryAction: UIAction { _ in webView.goBack() })
|
||||
forwardButton = UIBarButtonItem(title: nil, image: UIImage(systemName: "chevron.forward"),
|
||||
primaryAction: UIAction { _ in webView.goForward() })
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
view = webView
|
||||
webView.navigationDelegate = self
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem(
|
||||
systemItem: .done,
|
||||
primaryAction: UIAction { [weak self] _ in self?.presentingViewController?.dismiss(animated: true) })
|
||||
navigationItem.rightBarButtonItems = [forwardButton, backButton]
|
||||
|
||||
webView.publisher(for: \.canGoBack)
|
||||
.sink { [weak self] in self?.backButton.isEnabled = $0 }
|
||||
.store(in: &cancellables)
|
||||
|
||||
webView.publisher(for: \.canGoForward)
|
||||
.sink { [weak self] in self?.forwardButton.isEnabled = $0 }
|
||||
.store(in: &cancellables)
|
||||
|
||||
webView.publisher(for: \.title)
|
||||
.sink { [weak self] in self?.navigationItem.title = $0 }
|
||||
.store(in: &cancellables)
|
||||
|
||||
webView.load(.init(url: Self.url))
|
||||
}
|
||||
}
|
||||
|
||||
extension InstancePickerViewController: WKNavigationDelegate {
|
||||
func webView(_ webView: WKWebView,
|
||||
decidePolicyFor navigationAction: WKNavigationAction,
|
||||
preferences: WKWebpagePreferences,
|
||||
decisionHandler: @escaping (WKNavigationActionPolicy, WKWebpagePreferences) -> Void) {
|
||||
if webView.url?.host == "joinmastodon.org",
|
||||
let url = navigationAction.request.url,
|
||||
let host = url.host,
|
||||
host != "joinmastodon.org",
|
||||
url.pathComponents == ["/", "about"] {
|
||||
decisionHandler(.cancel, preferences)
|
||||
selectionAction(self, host)
|
||||
} else {
|
||||
decisionHandler(.allow, preferences)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension InstancePickerViewController {
|
||||
static let url = URL(string: "https://joinmastodon.org/communities")!
|
||||
}
|
Loading…
Reference in New Issue