Files
letro-ios/ElementX/Sources/Other/Extensions/String.swift
Mauro db2b2b7e34 Inlined Timestamp in bubble style for messages that have a bubble (#947)
* web-like solution

* not super polished but working implementation

* polishing the spacing and sizes

* removing unused code

* code improvements

* adding a test case in the preview for RTL

* addressing some PR comments

* added some tests and polished the code

* better naming

* code improvement

* RTL fix

* Revert "RTL fix"

This reverts commit 14e4468a5358769daa57891f4991e9e32da1c985.

* better RTL fix

* updated UI tests

* separated some files

* addressed some PR comments

* some more tests
2023-05-25 10:13:45 +00:00

84 lines
2.9 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 SwiftUI
extension String {
/// Returns the string as an `AttributedString` with the specified character tinted in a different color.
/// - Parameters:
/// - character: The character to be tinted.
/// - color: The color to tint the character. Defaults to the accent color.
/// - Returns: An `AttributedString`.
func tinting(_ character: Character, color: Color = .accentColor) -> AttributedString {
var string = AttributedString(self)
let characterView = string.characters
for index in characterView.indices where characterView[index] == character {
string[index..<characterView.index(after: index)].foregroundColor = color
}
return string
}
/// Calculates a numeric hash same as Element Web
/// See original function here https://github.com/matrix-org/matrix-react-sdk/blob/321dd49db4fbe360fc2ff109ac117305c955b061/src/utils/FormattingUtils.js#L47
var hashCode: Int32 {
var hash: Int32 = 0
for character in self {
let shiftedHash = hash << 5
hash = shiftedHash.subtractingReportingOverflow(hash).partialValue + Int32(character.unicodeScalars[character.unicodeScalars.startIndex].value)
}
return abs(hash)
}
var isASCII: Bool {
allSatisfy(\.isASCII)
}
func asciified() -> String? {
guard !isASCII else {
return self
}
guard !canBeConverted(to: .ascii) else {
return nil
}
let mutableString = NSMutableString(string: self)
guard CFStringTransform(mutableString, nil, "Any-Latin; Latin-ASCII; [:^ASCII:] Remove" as CFString, false) else {
return nil
}
return mutableString.trimmingCharacters(in: .whitespaces)
}
}
extension String {
static func generateBreakableWhitespaceEnd(whitespaceCount: Int, isRTL: Bool) -> String {
guard whitespaceCount > 0 else {
return ""
}
var whiteSpaces = ""
if isRTL {
whiteSpaces = "\u{202e}"
}
// fixed size whitespace of size 1/3 em per character
whiteSpaces += String(repeating: "\u{2004}", count: whitespaceCount)
// braille whitespace, which is non breakable but makes previous whitespaces breakable
return whiteSpaces + "\u{2800}"
}
}