mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
WIP
This commit is contained in:
parent
9398240c18
commit
ef1b189813
11 changed files with 177 additions and 17 deletions
|
@ -123,7 +123,7 @@ extern NSTimeInterval const kResizeComposerAnimationDuration;
|
|||
|
||||
@property (nonatomic) CGFloat wysiwygTranslation;
|
||||
|
||||
@property (nonatomic, strong) ComposerLinkActionBridgePresenter *composerLinkActionBridgePresenter;
|
||||
@property (nonatomic, strong, nullable) ComposerLinkActionBridgePresenter *composerLinkActionBridgePresenter;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -245,9 +245,10 @@ extension RoomViewController {
|
|||
}
|
||||
|
||||
@objc func didSendLinkAction(_ linkAction: LinkActionWrapper) {
|
||||
composerLinkActionBridgePresenter = ComposerLinkActionBridgePresenter(linkAction: linkAction)
|
||||
composerLinkActionBridgePresenter.delegate = self
|
||||
composerLinkActionBridgePresenter.present(from: self, animated: true)
|
||||
let presenter = ComposerLinkActionBridgePresenter(linkAction: linkAction)
|
||||
presenter.delegate = self
|
||||
composerLinkActionBridgePresenter = presenter
|
||||
presenter.present(from: self, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,5 +290,17 @@ private extension RoomViewController {
|
|||
}
|
||||
|
||||
extension RoomViewController: ComposerLinkActionBridgePresenterDelegate {
|
||||
func didDismissInteractively() {
|
||||
self.cleanup()
|
||||
}
|
||||
|
||||
func didCancel() {
|
||||
self.composerLinkActionBridgePresenter?.dismiss(animated: true) { [weak self] in
|
||||
self?.cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
private func cleanup() {
|
||||
self.composerLinkActionBridgePresenter = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ enum MockAppScreens {
|
|||
MockSpaceSelectorScreenState.self,
|
||||
MockComposerScreenState.self,
|
||||
MockComposerCreateActionListScreenState.self,
|
||||
MockComposerLinkActionScreenState.self,
|
||||
MockVoiceBroadcastPlaybackScreenState.self
|
||||
]
|
||||
}
|
||||
|
|
|
@ -33,11 +33,16 @@ enum MockComposerCreateActionListScreenState: MockScreenState, CaseIterable {
|
|||
case .fullList:
|
||||
actions = ComposerCreateAction.allCases
|
||||
}
|
||||
let viewModel = ComposerCreateActionListViewModel(initialViewState: ComposerCreateActionListViewState(
|
||||
actions: actions,
|
||||
wysiwygEnabled: true,
|
||||
isScrollingEnabled: false,
|
||||
bindings: ComposerCreateActionListBindings(textFormattingEnabled: true)))
|
||||
let viewModel = ComposerCreateActionListViewModel(
|
||||
initialViewState: ComposerCreateActionListViewState(
|
||||
actions: actions,
|
||||
wysiwygEnabled: true,
|
||||
isScrollingEnabled: false,
|
||||
bindings: ComposerCreateActionListBindings(
|
||||
textFormattingEnabled: true
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
return (
|
||||
[viewModel],
|
||||
|
|
|
@ -18,10 +18,10 @@ import Foundation
|
|||
import WysiwygComposer
|
||||
|
||||
protocol ComposerLinkActionBridgePresenterDelegate: AnyObject {
|
||||
|
||||
func didCancel()
|
||||
func didDismissInteractively()
|
||||
}
|
||||
|
||||
|
||||
final class ComposerLinkActionBridgePresenter: NSObject {
|
||||
private var coordinator: ComposerLinkActionCoordinator?
|
||||
private var linkAction: LinkAction
|
||||
|
@ -35,9 +35,28 @@ final class ComposerLinkActionBridgePresenter: NSObject {
|
|||
|
||||
func present(from viewController: UIViewController, animated: Bool) {
|
||||
let composerLinkActionCoordinator = ComposerLinkActionCoordinator(linkAction: linkAction)
|
||||
composerLinkActionCoordinator.callback = { [weak self] action in
|
||||
switch action {
|
||||
case .didTapCancel:
|
||||
self?.delegate?.didCancel()
|
||||
case .didDismissInteractively:
|
||||
self?.delegate?.didDismissInteractively()
|
||||
}
|
||||
}
|
||||
let presentable = composerLinkActionCoordinator.toPresentable()
|
||||
viewController.present(presentable, animated: animated, completion: nil)
|
||||
composerLinkActionCoordinator.start()
|
||||
coordinator = composerLinkActionCoordinator
|
||||
}
|
||||
|
||||
func dismiss(animated: Bool, completion: (() -> Void)?) {
|
||||
guard let coordinator = coordinator else {
|
||||
return
|
||||
}
|
||||
// Dismiss modal
|
||||
coordinator.toPresentable().dismiss(animated: animated) {
|
||||
self.coordinator = nil
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import WysiwygComposer
|
||||
|
||||
enum ComposerLinkActionCoordinatorAction {
|
||||
case didTapCancel
|
||||
case didDismissInteractively
|
||||
}
|
||||
|
||||
final class ComposerLinkActionCoordinator: NSObject, Coordinator, Presentable {
|
||||
var childCoordinators: [Coordinator] = []
|
||||
|
||||
private let hostingController: UIViewController
|
||||
private let viewModel: ComposerLinkActionViewModel
|
||||
|
||||
var callback: ((ComposerLinkActionCoordinatorAction) -> Void)?
|
||||
|
||||
init(linkAction: LinkAction) {
|
||||
viewModel = ComposerLinkActionViewModel(from: linkAction)
|
||||
hostingController = VectorHostingController(rootView: ComposerLinkActionView(viewModel: viewModel.context))
|
||||
super.init()
|
||||
hostingController.presentationController?.delegate = self
|
||||
}
|
||||
|
||||
func start() {
|
||||
viewModel.callback = { [weak self] result in
|
||||
switch result {
|
||||
case .cancel:
|
||||
self?.callback?(.didTapCancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
hostingController
|
||||
}
|
||||
}
|
||||
|
||||
extension ComposerLinkActionCoordinator: UIAdaptivePresentationControllerDelegate {
|
||||
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
|
||||
self.callback?(.didDismissInteractively)
|
||||
}
|
||||
}
|
|
@ -16,13 +16,25 @@
|
|||
|
||||
import SwiftUI
|
||||
|
||||
enum MockComposerLinkActionScreenState: MockScreenState, CaseIterable {
|
||||
enum MockComposerLinkActionScreenState: MockScreenState, CaseIterable {
|
||||
case edit
|
||||
case createWithText
|
||||
case create
|
||||
|
||||
var screenType: Any.Type {
|
||||
ComposerLinkActionView.self
|
||||
}
|
||||
|
||||
var screenView: ([Any], AnyView) {
|
||||
let viewModel = ComposerLinkActionViewModel(initialViewState: .init())
|
||||
let viewModel: ComposerLinkActionViewModel
|
||||
switch self {
|
||||
case .createWithText:
|
||||
viewModel = .init(from: .createWithText)
|
||||
case .create:
|
||||
viewModel = .init(from: .create)
|
||||
case .edit:
|
||||
viewModel = .init(from: .edit(link: "https://element.io"))
|
||||
}
|
||||
return (
|
||||
[viewModel],
|
||||
AnyView(ComposerLinkActionView(viewModel: viewModel.context))
|
||||
|
|
|
@ -16,13 +16,16 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
enum ComposerLinkActionViewAction {
|
||||
enum ComposerLinkActionViewAction: Equatable {
|
||||
case cancel
|
||||
}
|
||||
|
||||
enum ComposerLinkActionViewModelResult: Equatable {
|
||||
case cancel
|
||||
}
|
||||
|
||||
// MARK: View
|
||||
|
||||
struct ComposerLinkActionViewState: BindableState {
|
||||
let title: String
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -17,10 +17,31 @@
|
|||
import SwiftUI
|
||||
|
||||
struct ComposerLinkActionView: View {
|
||||
@Environment(\.theme) private var theme: ThemeSwiftUI
|
||||
@ObservedObject private var viewModel: ComposerLinkActionViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
||||
NavigationView {
|
||||
VStack {}
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button(VectorL10n.cancel, action: {
|
||||
viewModel.send(viewAction: .cancel)
|
||||
})
|
||||
}
|
||||
ToolbarItem(placement: .principal) {
|
||||
Text(viewModel.viewState.title)
|
||||
.font(.headline)
|
||||
.foregroundColor(theme.colors.primaryContent)
|
||||
}
|
||||
}
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.introspectNavigationController { navigationController in
|
||||
ThemeService.shared().theme.applyStyle(onNavigationBar: navigationController.navigationBar)
|
||||
}
|
||||
}
|
||||
.accentColor(theme.colors.accent)
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
||||
init(viewModel: ComposerLinkActionViewModel.Context) {
|
||||
|
|
|
@ -15,11 +15,39 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import WysiwygComposer
|
||||
|
||||
typealias ComposerLinkActionViewModelType = StateStoreViewModel<ComposerLinkActionViewState, ComposerLinkActionViewAction>
|
||||
|
||||
final class ComposerLinkActionViewModel: ComposerLinkActionViewModelType, ComposerLinkActionViewModelProtocol {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
// MARK: Public
|
||||
|
||||
var callback: ((ComposerLinkActionViewModelResult) -> Void)?
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
init(from linkAction: LinkAction) {
|
||||
let initialViewState: ComposerLinkActionViewState
|
||||
// TODO: Add translations
|
||||
switch linkAction {
|
||||
case .edit:
|
||||
initialViewState = .init(title: "Edit Link")
|
||||
case .createWithText, .create:
|
||||
initialViewState = .init(title: "Create a Link")
|
||||
}
|
||||
|
||||
super.init(initialViewState: initialViewState)
|
||||
}
|
||||
|
||||
override func process(viewAction: ComposerLinkActionViewAction) {
|
||||
switch viewAction {
|
||||
case .cancel:
|
||||
callback?(.cancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
|
Loading…
Reference in a new issue