mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-30 08:12:40 +00:00
Merge pull request #7097 from vector-im/mauroromito/fullscreen_mode_hidden_on_landscape_iphone
Rich Text Composer: On iPhone in Landscape mode the fullscreen toggle should be hidden
This commit is contained in:
commit
8bd53e2e7c
10 changed files with 52 additions and 20 deletions
|
@ -36,7 +36,6 @@
|
|||
<outlet property="userSuggestionContainerView" destination="oni-F4-X1U" id="0js-Ji-8Mm"/>
|
||||
<outlet property="view" destination="iN0-l3-epB" id="ieV-u7-rXU"/>
|
||||
<outletCollection property="toolbarContainerConstraints" destination="T1Y-r9-bYV" id="wax-9P-KGn"/>
|
||||
<outletCollection property="toolbarContainerConstraints" destination="ave-fu-X1D" id="gBl-7F-srT"/>
|
||||
<outletCollection property="toolbarContainerConstraints" destination="pRw-S0-6WL" id="q4S-0g-sqQ"/>
|
||||
<outletCollection property="toolbarContainerConstraints" destination="QO8-nF-xys" id="aQe-20-4Pq"/>
|
||||
<outletCollection property="toolbarContainerConstraints" destination="acJ-g8-R7x" id="uEo-Ez-seV"/>
|
||||
|
|
|
@ -43,9 +43,12 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
|
|||
private var voiceMessageBottomConstraint: NSLayoutConstraint?
|
||||
private var hostingViewController: VectorHostingController!
|
||||
private var wysiwygViewModel = WysiwygComposerViewModel(textColor: ThemeService.shared().theme.colors.primaryContent)
|
||||
private var viewModel: ComposerViewModelProtocol = ComposerViewModel(
|
||||
initialViewState: ComposerViewState(textFormattingEnabled: RiotSettings.shared.enableWysiwygTextFormatting,
|
||||
bindings: ComposerBindings(focused: false)))
|
||||
private var viewModel: ComposerViewModelProtocol!
|
||||
|
||||
private var isLandscapePhone: Bool {
|
||||
let device = UIDevice.current
|
||||
return device.isPhone && device.orientation.isLandscape
|
||||
}
|
||||
|
||||
// MARK: Public
|
||||
|
||||
|
@ -99,6 +102,9 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
|
|||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
viewModel = ComposerViewModel(
|
||||
initialViewState: ComposerViewState(textFormattingEnabled: RiotSettings.shared.enableWysiwygTextFormatting,
|
||||
isLandscapePhone: isLandscapePhone, bindings: ComposerBindings(focused: false)))
|
||||
|
||||
viewModel.callback = { [weak self] result in
|
||||
self?.handleViewModelResult(result)
|
||||
|
@ -153,6 +159,7 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
|
|||
},
|
||||
|
||||
wysiwygViewModel.$maximised
|
||||
.dropFirst()
|
||||
.removeDuplicates()
|
||||
.sink { [weak self] value in
|
||||
guard let self = self else { return }
|
||||
|
@ -229,6 +236,7 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
|
|||
}
|
||||
|
||||
@objc private func deviceDidRotate(_ notification: Notification) {
|
||||
viewModel.isLandscapePhone = isLandscapePhone
|
||||
DispatchQueue.main.async {
|
||||
self.updateTextViewHeight()
|
||||
}
|
||||
|
@ -286,9 +294,14 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
|
|||
private func updateTextViewHeight() {
|
||||
let height = UIScreen.main.bounds.height
|
||||
let barOffset: CGFloat = 68
|
||||
let toolbarHeight: CGFloat = 82
|
||||
let toolbarHeight: CGFloat = 96
|
||||
let finalHeight = height - keyboardHeight - toolbarHeight - barOffset
|
||||
wysiwygViewModel.maxExpandedHeight = finalHeight
|
||||
if finalHeight < 200 {
|
||||
wysiwygViewModel.maxCompressedHeight = finalHeight > wysiwygViewModel.minHeight ? finalHeight : wysiwygViewModel.minHeight
|
||||
} else {
|
||||
wysiwygViewModel.maxCompressedHeight = 200
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - HtmlRoomInputToolbarViewProtocol
|
||||
|
@ -337,9 +350,6 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
|
|||
set {
|
||||
self.viewModel.textFormattingEnabled = newValue
|
||||
self.wysiwygViewModel.plainTextMode = !newValue
|
||||
if !newValue {
|
||||
self.wysiwygViewModel.maximised = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,9 @@ enum MockComposerScreenState: MockScreenState, CaseIterable {
|
|||
let bindings = ComposerBindings(focused: false)
|
||||
|
||||
switch self {
|
||||
case .send: viewModel = ComposerViewModel(initialViewState: ComposerViewState(textFormattingEnabled: true, bindings: bindings))
|
||||
case .edit: viewModel = ComposerViewModel(initialViewState: ComposerViewState(sendMode: .edit, textFormattingEnabled: true, bindings: bindings))
|
||||
case .reply: viewModel = ComposerViewModel(initialViewState: ComposerViewState(eventSenderDisplayName: "TestUser", sendMode: .reply, textFormattingEnabled: true, bindings: bindings))
|
||||
case .send: viewModel = ComposerViewModel(initialViewState: ComposerViewState(textFormattingEnabled: true, isLandscapePhone: false, bindings: bindings))
|
||||
case .edit: viewModel = ComposerViewModel(initialViewState: ComposerViewState(sendMode: .edit, textFormattingEnabled: true, isLandscapePhone: false, bindings: bindings))
|
||||
case .reply: viewModel = ComposerViewModel(initialViewState: ComposerViewState(eventSenderDisplayName: "TestUser", sendMode: .reply, textFormattingEnabled: true, isLandscapePhone: false, bindings: bindings))
|
||||
}
|
||||
|
||||
let wysiwygviewModel = WysiwygComposerViewModel(minHeight: 20, maxCompressedHeight: 360)
|
||||
|
|
|
@ -34,8 +34,8 @@ struct FormatItem {
|
|||
enum FormatType {
|
||||
case bold
|
||||
case italic
|
||||
case strikethrough
|
||||
case underline
|
||||
case strikethrough
|
||||
}
|
||||
|
||||
extension FormatType: CaseIterable, Identifiable {
|
||||
|
|
|
@ -20,6 +20,7 @@ struct ComposerViewState: BindableState {
|
|||
var eventSenderDisplayName: String?
|
||||
var sendMode: ComposerSendMode = .send
|
||||
var textFormattingEnabled: Bool
|
||||
var isLandscapePhone: Bool
|
||||
var placeholder: String?
|
||||
|
||||
var bindings: ComposerBindings
|
||||
|
@ -47,6 +48,10 @@ extension ComposerViewState {
|
|||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var isMinimiseForced: Bool {
|
||||
isLandscapePhone || !textFormattingEnabled
|
||||
}
|
||||
}
|
||||
|
||||
struct ComposerBindings {
|
||||
|
|
|
@ -23,8 +23,13 @@ final class ComposerViewModelTests: XCTestCase {
|
|||
var context: ComposerViewModel.Context!
|
||||
|
||||
override func setUpWithError() throws {
|
||||
viewModel = ComposerViewModel(initialViewState: ComposerViewState(textFormattingEnabled: true,
|
||||
bindings: ComposerBindings(focused: false)))
|
||||
viewModel = ComposerViewModel(
|
||||
initialViewState: ComposerViewState(
|
||||
textFormattingEnabled: true,
|
||||
isLandscapePhone: false,
|
||||
bindings: ComposerBindings(focused: false)
|
||||
)
|
||||
)
|
||||
context = viewModel.context
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
// limitations under the License.
|
||||
//
|
||||
|
||||
import DSBottomSheet
|
||||
import SwiftUI
|
||||
import WysiwygComposer
|
||||
|
||||
|
@ -22,7 +21,6 @@ struct Composer: View {
|
|||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
@ObservedObject private var viewModel: ComposerViewModelType.Context
|
||||
@ObservedObject private var wysiwygViewModel: WysiwygComposerViewModel
|
||||
private let resizeAnimationDuration: Double
|
||||
|
@ -36,9 +34,8 @@ struct Composer: View {
|
|||
|
||||
private let horizontalPadding: CGFloat = 12
|
||||
private let borderHeight: CGFloat = 40
|
||||
private let minTextViewHeight: CGFloat = 22
|
||||
private var verticalPadding: CGFloat {
|
||||
(borderHeight - minTextViewHeight) / 2
|
||||
(borderHeight - wysiwygViewModel.minHeight) / 2
|
||||
}
|
||||
|
||||
private var topPadding: CGFloat {
|
||||
|
@ -46,7 +43,7 @@ struct Composer: View {
|
|||
}
|
||||
|
||||
private var cornerRadius: CGFloat {
|
||||
if viewModel.viewState.shouldDisplayContext || wysiwygViewModel.idealHeight > minTextViewHeight {
|
||||
if viewModel.viewState.shouldDisplayContext || wysiwygViewModel.idealHeight > wysiwygViewModel.minHeight {
|
||||
return 14
|
||||
} else {
|
||||
return borderHeight / 2
|
||||
|
@ -119,7 +116,7 @@ struct Composer: View {
|
|||
wysiwygViewModel.setup()
|
||||
}
|
||||
}
|
||||
if viewModel.viewState.textFormattingEnabled {
|
||||
if !viewModel.viewState.isMinimiseForced {
|
||||
Button {
|
||||
wysiwygViewModel.maximised.toggle()
|
||||
} label: {
|
||||
|
@ -233,6 +230,11 @@ struct Composer: View {
|
|||
}
|
||||
.padding(.horizontal, horizontalPadding)
|
||||
.padding(.bottom, 4)
|
||||
.onChange(of: viewModel.viewState.isMinimiseForced) { newValue in
|
||||
if wysiwygViewModel.maximised && newValue {
|
||||
wysiwygViewModel.maximised = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,15 @@ final class ComposerViewModel: ComposerViewModelType, ComposerViewModelProtocol
|
|||
}
|
||||
}
|
||||
|
||||
var isLandscapePhone: Bool {
|
||||
get {
|
||||
state.isLandscapePhone
|
||||
}
|
||||
set {
|
||||
state.isLandscapePhone = newValue
|
||||
}
|
||||
}
|
||||
|
||||
var isFocused: Bool {
|
||||
state.bindings.focused
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ protocol ComposerViewModelProtocol {
|
|||
var eventSenderDisplayName: String? { get set }
|
||||
var placeholder: String? { get set }
|
||||
var isFocused: Bool { get }
|
||||
var isLandscapePhone: Bool { get set }
|
||||
|
||||
func dismissKeyboard()
|
||||
func showKeyboard()
|
||||
|
|
1
changelog.d/7096.change
Normal file
1
changelog.d/7096.change
Normal file
|
@ -0,0 +1 @@
|
|||
Rich Text Editor: on iPhones when in landscape mode the fullscreen mode is disabled.
|
Loading…
Reference in a new issue