element-ios/Riot/Modules/Pills/PillTextAttachment.swift
2022-05-11 09:45:16 +02:00

85 lines
3 KiB
Swift

//
// 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 UIKit
import MatrixSDK
/// Text attachment for pills display.
@available (iOS 15.0, *)
@objcMembers
class PillTextAttachment: NSTextAttachment {
// MARK: - Properties
/// Return `PillTextAttachmentData` contained in the text attachment.
var data: PillTextAttachmentData? {
get {
guard let contents = contents else { return nil }
return try? Self.serializationService.deserialize(contents)
}
set {
guard let newValue = newValue else {
contents = nil
return
}
contents = try? Self.serializationService.serialize(newValue)
}
}
private static let serializationService: SerializationServiceType = SerializationService()
// MARK: - Init
override init(data contentData: Data?, ofType uti: String?) {
super.init(data: contentData, ofType: uti)
updateBounds()
}
/// Create a Mention Pill text attachment for given room member.
///
/// - Parameters:
/// - roomMember: the room member
/// - isHighlighted: whether this pill should be highlighted
/// - font: the text font
convenience init?(withRoomMember roomMember: MXRoomMember,
isHighlighted: Bool,
font: UIFont) {
let data = PillTextAttachmentData(matrixItemId: roomMember.userId,
displayName: roomMember.displayname,
avatarUrl: roomMember.avatarUrl,
isHighlighted: isHighlighted,
alpha: 1.0,
font: font)
guard let encodedData = try? Self.serializationService.serialize(data) else { return nil }
self.init(data: encodedData, ofType: PillsFormatter.pillUTType)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
updateBounds()
}
}
// MARK: - Private
@available (iOS 15.0, *)
private extension PillTextAttachment {
func updateBounds() {
guard let data = data else { return }
let pillSize = PillAttachmentViewProvider.size(forDisplayText: data.displayText, andFont: data.font)
// Offset to align pill centerY with text centerY.
let offset = data.font.descender + (data.font.lineHeight - pillSize.height) / 2.0
self.bounds = CGRect(origin: CGPoint(x: 0.0, y: offset), size: pillSize)
}
}