Fix fonts and edition on replies

This commit is contained in:
aringenbach 2022-05-04 12:17:21 +02:00
parent 3bf55d5479
commit 8b46be6cd4
10 changed files with 45 additions and 19 deletions

View file

@ -228,6 +228,18 @@ typedef enum : NSUInteger {
*/
- (NSAttributedString*)renderHTMLString:(NSString*)htmlString forEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState;
/**
Render a random html string into an attributed string with the font and the text color
that correspond to the passed event.
@param htmlString the HTLM string to render.
@param event the event associated to the string.
@param roomState the room state right before the event.
@param isEditMode wether string will be used for edition in the composer
@return an attributed string.
*/
- (NSAttributedString*)renderHTMLString:(NSString*)htmlString forEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState isEditMode:(BOOL)isEditMode;
/**
Same as [self renderString:forEvent:] but add a prefix.
The prefix will be rendered with 'prefixTextFont' and 'prefixTextColor'.

View file

@ -1750,11 +1750,17 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=\"(.*?)\">([^<]*)</a>";
}
- (NSAttributedString*)renderHTMLString:(NSString*)htmlString forEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState
{
return [self renderHTMLString:htmlString forEvent:event withRoomState:roomState isEditMode:NO];
}
- (NSAttributedString*)renderHTMLString:(NSString*)htmlString forEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState isEditMode:(BOOL)isEditMode
{
NSString *html = htmlString;
// Special treatment for "In reply to" message
if (event.isReplyEvent || (!RiotSettings.shared.enableThreads && event.isInThread))
// Note: `isEditMode` fixes an issue where editing a reply would display an "In reply to" span instead of a mention.
if (!isEditMode && (event.isReplyEvent || (!RiotSettings.shared.enableThreads && event.isInThread)))
{
html = [self renderReplyTo:html withRoomState:roomState];
}

View file

@ -35,7 +35,7 @@ class PillAttachmentView: UIView {
// MARK: - Private Enums
private enum Constants {
static let pillLabelFont: UIFont = ThemeService.shared().theme.fonts.body
static let pillLabelFont: UIFont = UIFont.systemFont(ofSize: 15)
static let commonVerticalMargin: CGFloat = 2.0
static let commonHorizontalMargin: CGFloat = 4.0
static let avatarSideLength: CGFloat = 16.0

View file

@ -29,6 +29,7 @@ import MatrixSDK
static let roomMemberKey: String = "roomMember"
static let isCurrentUserKey: String = "isCurrentUser"
static let alphaKey: String = "alpha"
static let pillVerticalOffset: CGFloat = -7.5
}
// MARK: - Init
@ -41,7 +42,7 @@ import MatrixSDK
self.roomMember = roomMember
self.isCurrentUser = isCurrentUser
let pillSize = PillAttachmentView.size(forRoomMember: roomMember)
self.bounds = CGRect(origin: CGPoint(x: 0.0, y: -6.5), size: pillSize)
self.bounds = CGRect(origin: CGPoint(x: 0.0, y: Constants.pillVerticalOffset), size: pillSize)
}
// MARK: - NSCoding

View file

@ -15,6 +15,7 @@
//
import Foundation
import UIKit
/// Provides utilities funcs to handle Pills inside attributed strings.
@available (iOS 15.0, *)
@ -26,12 +27,15 @@ class StringPillsUtils: NSObject {
/// - Parameters:
/// - attributedString: message string to update
/// - session: current session
/// - event: the event
/// - roomState: room state for message
/// - isEditMode: whether this string will be used in the composer
/// - Returns: new attributed string with pills
static func insertPills(in attributedString: NSAttributedString,
withSession session: MXSession,
event: MXEvent,
andRoomState roomState: MXRoomState) -> NSAttributedString {
andRoomState roomState: MXRoomState,
isEditMode: Bool = false) -> NSAttributedString {
let newAttr = NSMutableAttributedString(attributedString: attributedString)
let totalRange = NSRange(location: 0, length: newAttr.length)
@ -40,7 +44,7 @@ class StringPillsUtils: NSObject {
let roomMember = roomState.members.member(withUserId: userId) {
let isCurrentUser = roomMember.userId == session.myUserId && event.sender != session.myUserId
let attachmentString = mentionPill(withRoomMember: roomMember,
andUrl: url,
andUrl: isEditMode ? nil : url,
isCurrentUser: isCurrentUser)
newAttr.replaceCharacters(in: range, with: attachmentString)
}
@ -83,6 +87,7 @@ class StringPillsUtils: NSObject {
isCurrentUser: Bool) -> NSAttributedString {
let attachment = PillTextAttachment(withRoomMember: roomMember, isCurrentUser: isCurrentUser)
let string = NSMutableAttributedString(attachment: attachment)
string.addAttribute(.font, value: UIFont.systemFont(ofSize: 15.0), range: .init(location: 0, length: string.length))
if let url = url {
string.addAttribute(.link, value: url, range: .init(location: 0, length: string.length))
}

View file

@ -159,23 +159,25 @@ extension RoomDataSource {
let replyEventParts = parser.parse(event)
let body: String = replyEventParts?.formattedBodyParts?.replyText ?? replyEventParts?.bodyParts.replyText ?? ""
let attributed = eventFormatter.renderHTMLString(body, for: event, with: self.roomState)
let attributed = eventFormatter.renderHTMLString(body, for: event, with: self.roomState, isEditMode: true)
if let attributed = attributed, #available(iOS 15.0, *) {
editableTextMessage = StringPillsUtils.insertPills(in: attributed,
withSession: self.mxSession,
event: event,
andRoomState: self.roomState)
andRoomState: self.roomState,
isEditMode: true)
} else {
editableTextMessage = attributed
}
} else {
let body: String = event.content["formatted_body"] as? String ?? event.content["body"] as? String ?? ""
let attributed = eventFormatter.renderHTMLString(body, for: event, with: self.roomState)
let attributed = eventFormatter.renderHTMLString(body, for: event, with: self.roomState, isEditMode: true)
if let attributed = attributed, #available(iOS 15.0, *) {
editableTextMessage = StringPillsUtils.insertPills(in: attributed,
withSession: self.mxSession,
event: event,
andRoomState: self.roomState)
andRoomState: self.roomState,
isEditMode: true)
} else {
editableTextMessage = attributed
}

View file

@ -31,17 +31,17 @@ extension RoomViewController {
newAttributedString.append(StringPillsUtils.mentionPill(withRoomMember: roomMember,
isCurrentUser: false))
let empty = NSAttributedString(string: " ",
attributes: [.font: inputToolbar.textDefaultFont ?? ThemeService.shared().theme.fonts.body])
attributes: [.font: inputToolbar.textDefaultFont])
newAttributedString.append(empty)
} else if roomMember.userId == self.mainSession.myUser.userId {
let selfMentionString = NSAttributedString(string: "/me ",
attributes: [.font: inputToolbar.textDefaultFont ?? ThemeService.shared().theme.fonts.body])
attributes: [.font: inputToolbar.textDefaultFont])
newAttributedString.append(selfMentionString)
} else {
newAttributedString.append(StringPillsUtils.mentionPill(withRoomMember: roomMember,
isCurrentUser: false))
let colon = NSAttributedString(string: ": ",
attributes: [.font: inputToolbar.textDefaultFont ?? ThemeService.shared().theme.fonts.body])
attributes: [.font: inputToolbar.textDefaultFont])
newAttributedString.append(colon)
}
@ -58,7 +58,7 @@ extension RoomViewController {
self.setupRoomDataSource { roomDataSource in
guard let roomDataSource = roomDataSource as? RoomDataSource else { return }
if self.inputToolbar?.sendMode == RoomInputToolbarViewSendModeReply, let eventModified = eventModified {
if self.inputToolbar?.sendMode == .reply, let eventModified = eventModified {
roomDataSource.sendReply(to: eventModified,
withAttributedTextMessage: attributedTextMsg) { response in
switch response {
@ -68,7 +68,7 @@ extension RoomViewController {
MXLog.error("[RoomViewController] sendAttributedTextMessage failed while updating event: \(eventModified.eventId ?? "N/A")")
}
}
} else if self.inputToolbar?.sendMode == RoomInputToolbarViewSendModeEdit, let eventModified = eventModified {
} else if self.inputToolbar?.sendMode == .edit, let eventModified = eventModified {
roomDataSource.replaceAttributedTextMessage(
for: eventModified,
withAttributedTextMessage: attributedTextMsg,

View file

@ -24,12 +24,12 @@
/**
Destination of the message in the composer
*/
typedef enum : NSUInteger
typedef NS_ENUM(NSUInteger, RoomInputToolbarViewSendMode)
{
RoomInputToolbarViewSendModeSend,
RoomInputToolbarViewSendModeReply,
RoomInputToolbarViewSendModeEdit
} RoomInputToolbarViewSendMode;
};
@protocol RoomInputToolbarViewDelegate <MXKRoomInputToolbarViewDelegate>
@ -116,7 +116,7 @@ typedef enum : NSUInteger
*/
@property (nonatomic) NSAttributedString *attributedTextMessage;
@property (nonatomic, readonly) UIFont *textDefaultFont;
@property (nonatomic, readonly, nonnull) UIFont *textDefaultFont;
/**
Adds a voice message toolbar view to be displayed inside this input toolbar

View file

@ -185,7 +185,7 @@ static const NSTimeInterval kActionMenuComposerHeightAnimationDuration = .3;
}
else
{
return ThemeService.shared.theme.fonts.body;
return [UIFont systemFontOfSize:15.f];
}
}

View file

@ -90,7 +90,7 @@ static NSString *const kEventFormatterTimeFormat = @"HH:mm";
{
if (roomState && event.eventType == MXEventTypeRoomMessage)
{
string = [StringPillsUtils insertPillsIn:string withSession:mxSession event:event andRoomState:roomState];
string = [StringPillsUtils insertPillsIn:string withSession:mxSession event:event andRoomState:roomState isEditMode:NO];
}
}