Merge pull request #7711 from vector-im/nicolas/update-RTE-2.15

Bump RTE version to 2.18.0
This commit is contained in:
Nicolas Mauri
2023-11-21 12:36:50 +01:00
committed by GitHub
10 changed files with 116 additions and 51 deletions

View File

@@ -26,7 +26,7 @@ KEYCHAIN_ACCESS_GROUP = $(AppIdentifierPrefix)$(BASE_BUNDLE_IDENTIFIER).keychain
BROADCAST_UPLOAD_EXTENSION_BUNDLE_IDENTIFIER = $(BASE_BUNDLE_IDENTIFIER).broadcastUploadExtension
// Build settings
IPHONEOS_DEPLOYMENT_TARGET = 14.0
IPHONEOS_DEPLOYMENT_TARGET = 15.0
SDKROOT = iphoneos
TARGETED_DEVICE_FAMILY = 1,2
SWIFT_VERSION = 5.6

View File

@@ -1,7 +1,7 @@
source 'https://cdn.cocoapods.org/'
# Uncomment this line to define a global platform for your project
platform :ios, '14.0'
platform :ios, '15.0'
# By default, ignore all warnings from any pod
inhibit_all_warnings!

View File

@@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/Cocoanetics/DTCoreText",
"state" : {
"revision" : "9d2d4d2296e5d2d852a7d3c592b817d913a5d020",
"version" : "1.6.27"
"revision" : "b664664825da565b4c2b7a17dbe2369f68ae43d9",
"version" : "1.6.26"
}
},
{
@@ -50,8 +50,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/matrix-org/matrix-wysiwyg-composer-swift",
"state" : {
"revision" : "1100b217c04d096dfe072afb4484660ff794d805",
"version" : "2.2.2"
"revision" : "dfb74c89bf54b41ea000d564d6435ac6444ba6b4",
"version" : "2.18.0"
}
},
{

View File

@@ -47,7 +47,9 @@ class HTMLFormatter: NSObject {
var options: [AnyHashable: Any] = [
DTUseiOS6Attributes: true,
DTDefaultFontDescriptor: font.fontDescriptor,
DTDefaultFontFamily: font.familyName,
DTDefaultFontName: font.fontName,
DTDefaultFontSize: font.pointSize,
DTDefaultLinkDecoration: false,
DTDefaultLinkColor: ThemeService.shared().theme.colors.links,
DTWillFlushBlockCallBack: sanitizeCallback

View File

@@ -200,15 +200,7 @@ extension RoomViewController {
optionalTextView?.becomeFirstResponder()
originalRect = wysiwygInputToolbar.convert(wysiwygInputToolbar.frame, to: view)
}
// This tirggers a SwiftUI update that is handled correctly on iOS 16, but needs to be dispatchted async on older versions
// Dispatching on iOS 16 instead causes some weird SwiftUI update behaviours
if #available(iOS 16, *) {
wysiwygInputToolbar.showKeyboard()
} else {
DispatchQueue.main.async {
wysiwygInputToolbar.showKeyboard()
}
}
roomInputToolbarContainer.removeFromSuperview()
let dimmingView = UIView()
dimmingView.translatesAutoresizingMaskIntoConstraints = false
@@ -235,7 +227,18 @@ extension RoomViewController {
}
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(didPanRoomToolbarContainer(_ :)))
roomInputToolbarContainer.addGestureRecognizer(panGesture)
optionalTextView?.removeFromSuperview()
if let optionalTextView {
// This tirggers a SwiftUI update that is handled correctly on iOS 16, but needs to be dispatchted async on older versions
// Dispatching on iOS 16 instead causes some weird SwiftUI update behaviours
if #available(iOS 16, *) {
wysiwygInputToolbar.showKeyboard()
} else {
DispatchQueue.main.async {
wysiwygInputToolbar.showKeyboard()
}
}
optionalTextView.removeFromSuperview()
}
} else {
let originalRect = wysiwygInputToolbar.convert(wysiwygInputToolbar.frame, to: view)
var optionalTextView: UITextView?
@@ -244,7 +247,6 @@ extension RoomViewController {
optionalTextView = textView
self.view.window?.addSubview(textView)
optionalTextView?.becomeFirstResponder()
wysiwygInputToolbar.showKeyboard()
}
self.roomInputToolbarContainer.removeFromSuperview()
maximisedToolbarDimmingView?.removeFromSuperview()
@@ -257,7 +259,10 @@ extension RoomViewController {
self.view.layoutIfNeeded()
}
roomInputToolbarContainer.gestureRecognizers?.removeAll()
optionalTextView?.removeFromSuperview()
if let optionalTextView {
wysiwygInputToolbar.showKeyboard()
optionalTextView.removeFromSuperview()
}
}
}
@@ -384,8 +389,8 @@ extension RoomViewController: ComposerLinkActionBridgePresenterDelegate {
}
// MARK: - PermalinkReplacer
extension RoomViewController: PermalinkReplacer {
public func replacementForLink(_ url: String, text: String) -> NSAttributedString? {
extension RoomViewController: MentionReplacer {
public func replacementForMention(_ url: String, text: String) -> NSAttributedString? {
guard #available(iOS 15.0, *),
let url = URL(string: url),
let session = roomDataSource.mxSession,

View File

@@ -140,6 +140,20 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
wysiwygViewModel.maxCompressedHeight
}
override func paste(_ sender: Any?) {
let pasteboard = MXKPasteboardManager.shared.pasteboard
let types = pasteboard.types.map { UTI(rawValue: $0) }
// Minimise the composer and dismiss the keyboard if it's an image, a video or a file
if types.contains(where: { $0.conforms(to: .image) || $0.conforms(to: .movie) || $0.conforms(to: .video) || $0.conforms(to: .application) }) {
wysiwygViewModel.maximised = false
DispatchQueue.main.async {
self.viewModel.dismissKeyboard()
}
}
super.paste(sender)
}
// MARK: - Setup
override class func instantiate() -> MXKRoomInputToolbarView! {
@@ -150,8 +164,8 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
return (delegate as? RoomInputToolbarViewDelegate) ?? nil
}
private var permalinkReplacer: PermalinkReplacer? {
return (delegate as? PermalinkReplacer)
private var permalinkReplacer: MentionReplacer? {
return (delegate as? MentionReplacer)
}
override func awakeFromNib() {
@@ -192,6 +206,7 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
}
func showKeyboard() {
self.wysiwygViewModel.textView.becomeFirstResponder()
self.viewModel.showKeyboard()
}
@@ -238,7 +253,7 @@ class WysiwygInputToolbarView: MXKRoomInputToolbarView, NibLoadable, HtmlRoomInp
self?.handleViewModelResult(result)
}
wysiwygViewModel.plainTextMode = !RiotSettings.shared.enableWysiwygTextFormatting
wysiwygViewModel.permalinkReplacer = permalinkReplacer
wysiwygViewModel.mentionReplacer = permalinkReplacer
inputAccessoryViewForKeyboard = UIView(frame: .zero)

View File

@@ -156,7 +156,7 @@ extension FormatItem {
extension FormatType {
/// Convenience method to map it to the external ViewModel action
var action: WysiwygAction {
var action: ComposerAction {
switch self {
case .bold:
return .bold

View File

@@ -32,6 +32,7 @@ struct Composer: View {
@Environment(\.theme) private var theme: ThemeSwiftUI
@State private var isActionButtonShowing = false
@FocusState private var focused: Bool
private let horizontalPadding: CGFloat = 12
private let borderHeight: CGFloat = 40
@@ -58,17 +59,8 @@ struct Composer: View {
viewModel.viewState.shouldDisplayContext ? contextBannerHeight + standardVerticalPadding + verticalComponentSpacing : 0
}
/// Computes the total height of the composer (excluding the RTE formatting bar).
/// This height includes the text view, as well as the context banner
/// and user suggestion list when displayed.
private var composerHeight: CGFloat {
wysiwygViewModel.idealHeight
+ composerTopPadding
+ composerVerticalPadding
// Extra padding added on top of the VStack containing the composer
+ standardVerticalPadding
+ additionalHeightForContextBanner
}
/// the total height of the composer (excluding the RTE formatting bar).
@State private var composerHeight: CGFloat = .zero
private var cornerRadius: CGFloat {
if shouldFixRoundCorner {
@@ -139,20 +131,39 @@ struct Composer: View {
.padding(.horizontal, horizontalPadding)
}
HStack(alignment: shouldFixRoundCorner ? .top : .center, spacing: 0) {
WysiwygComposerView(
focused: $viewModel.focused,
viewModel: wysiwygViewModel
)
.tintColor(theme.colors.accent)
.placeholder(viewModel.viewState.placeholder, color: theme.colors.tertiaryContent)
.onAppear {
if wysiwygViewModel.isContentEmpty {
wysiwygViewModel.setup()
// Use a GeometryReader to force the composer to fill the HStack
GeometryReader { _ in
WysiwygComposerView(
placeholder: viewModel.viewState.placeholder ?? "",
viewModel: wysiwygViewModel,
itemProviderHelper: nil,
keyCommandHandler: handleKeyCommand,
pasteHandler: nil
)
.clipped()
.tint(theme.colors.accent)
.focused($focused)
.onChange(of: focused) { newValue in
viewModel.focused = newValue
}
.onChange(of: viewModel.focused) { newValue in
guard focused != newValue else { return }
focused = newValue
}
.onAppear {
if wysiwygViewModel.isContentEmpty {
wysiwygViewModel.setup()
}
}
}
if !viewModel.viewState.isMinimiseForced {
Button {
wysiwygViewModel.maximised.toggle()
viewModel.focused = true
// Use a dispatched block so the focus state will be up to date when the composer size changes.
DispatchQueue.main.async {
wysiwygViewModel.maximised.toggle()
}
} label: {
Image(toggleButtonImageName)
.resizable()
@@ -167,15 +178,14 @@ struct Composer: View {
.padding(.horizontal, horizontalPadding)
.padding(.top, composerTopPadding)
.padding(.bottom, composerVerticalPadding)
.layoutPriority(1)
}
.clipShape(rect)
.overlay(rect.stroke(borderColor, lineWidth: 1))
.animation(.easeInOut(duration: resizeAnimationDuration), value: wysiwygViewModel.idealHeight)
.padding(.top, standardVerticalPadding)
.onTapGesture {
if viewModel.focused {
viewModel.focused = true
}
viewModel.focused = true
}
}
@@ -218,6 +228,29 @@ struct Composer: View {
}
}
func handleKeyCommand(_ keyCommand: WysiwygKeyCommand) -> Bool {
switch keyCommand {
case .enter:
sendMessageAction(wysiwygViewModel.content)
wysiwygViewModel.clearContent()
return true
case .shiftEnter:
return false
}
}
/// Computes the total height of the composer (excluding the RTE formatting bar).
/// This height includes the text view, as well as the context banner
/// and user suggestion list when displayed.
private func updateComposerHeight(idealHeight: CGFloat) {
composerHeight = idealHeight
+ composerTopPadding
+ composerVerticalPadding
// Extra padding added on top of the VStack containing the composer
+ standardVerticalPadding
+ additionalHeightForContextBanner
}
// MARK: Public
init(
@@ -287,6 +320,15 @@ struct Composer: View {
.onChange(of: wysiwygViewModel.suggestionPattern) { newValue in
sendMentionPattern(pattern: newValue)
}
.onChange(of: wysiwygViewModel.idealHeight) { newValue in
updateComposerHeight(idealHeight: newValue)
}
.onChange(of: viewModel.viewState.shouldDisplayContext) { _ in
updateComposerHeight(idealHeight: wysiwygViewModel.idealHeight)
}
.task {
updateComposerHeight(idealHeight: wysiwygViewModel.idealHeight)
}
}
private func storeCurrentSelection() {

1
changelog.d/7681.bugfix Normal file
View File

@@ -0,0 +1 @@
Editing a message that ends with an emoji now works as expected.

View File

@@ -59,10 +59,10 @@ packages:
branch: 0.0.1
WysiwygComposer:
url: https://github.com/matrix-org/matrix-wysiwyg-composer-swift
version: 2.2.2
version: 2.18.0
DeviceKit:
url: https://github.com/devicekit/DeviceKit
majorVersion: 4.7.0
DTCoreText:
url: https://github.com/Cocoanetics/DTCoreText
version: 1.6.27
version: 1.6.26