mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Various tweaks (#381)
* Add the message delivery status to the plain timeline styler and display it outside of the main content * Fix glitchy timeline scroll to bottom button * Fixed bubbled reactions padding * Simplified the emoji picker, double tapping a timeline item directly opens it now and added a context menu option. Linked it to rust side reaction sending * Fix the sliding sync cold cache: treat invalidated rooms as filled * Make splash screen view full screen * Fix the offline indicator popping up when first setting up the network monitor * Expose presentationDetents on the NavigationStackCoordinator and start using them for the EmojiPicker * Fix link tint color * Linked TimelineReactionsView reaction sending * Remove now unused/unnecessary classes * Add changelog * Fix formatting issue
This commit is contained in:
@@ -1,70 +0,0 @@
|
||||
//
|
||||
// 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 Foundation
|
||||
|
||||
struct Benchmark {
|
||||
private static var trackingIdentifiers = [String: CFAbsoluteTime]()
|
||||
|
||||
public static var trackingEnabled = false
|
||||
|
||||
static func startTrackingForIdentifier(_ identifier: String, message: String? = nil) {
|
||||
guard trackingEnabled else {
|
||||
return
|
||||
}
|
||||
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
trackingIdentifiers[identifier] = startTime
|
||||
|
||||
if let message {
|
||||
MXLog.verbose("⏰ \(message).")
|
||||
}
|
||||
}
|
||||
|
||||
static func logElapsedDurationForIdentifier(_ identifier: String, message: String? = nil) {
|
||||
guard trackingEnabled else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let start = trackingIdentifiers[identifier] else {
|
||||
assertionFailure("⏰ Invalid tracking identifier")
|
||||
return
|
||||
}
|
||||
|
||||
let elapsedTime = CFAbsoluteTimeGetCurrent() - start
|
||||
if let message {
|
||||
MXLog.verbose("⏰ \(message). Elapsed time: \(elapsedTime.round(to: 4)) seconds.")
|
||||
} else {
|
||||
MXLog.verbose("⏰ Elapsed time: \(elapsedTime.round(to: 4)) seconds.")
|
||||
}
|
||||
}
|
||||
|
||||
static func endTrackingForIdentifier(_ identifier: String, message: String? = nil) {
|
||||
guard trackingEnabled else {
|
||||
return
|
||||
}
|
||||
|
||||
logElapsedDurationForIdentifier(identifier, message: message)
|
||||
trackingIdentifiers[identifier] = nil
|
||||
}
|
||||
}
|
||||
|
||||
private extension Double {
|
||||
func round(to places: Int) -> Double {
|
||||
let divisor = pow(10.0, Double(places))
|
||||
return (self * divisor).rounded() / divisor
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
//
|
||||
// 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 Foundation
|
||||
import UIKit
|
||||
import Vision
|
||||
|
||||
enum ImageAnonymizerError: Error {
|
||||
case noCgImageBased
|
||||
}
|
||||
|
||||
enum ImageAnonymizer {
|
||||
private static var allowedTextItems: [String] = [
|
||||
"#",
|
||||
"@",
|
||||
"%",
|
||||
"&",
|
||||
"+",
|
||||
"-",
|
||||
"_",
|
||||
"\"",
|
||||
"?",
|
||||
"*"
|
||||
]
|
||||
|
||||
static func anonymizedImage(from image: UIImage,
|
||||
confidenceLevel: Float = 0.5,
|
||||
fillColor: UIColor = .red) async throws -> UIImage {
|
||||
guard let cgImage = image.cgImage else {
|
||||
throw ImageAnonymizerError.noCgImageBased
|
||||
}
|
||||
|
||||
// create a handler with cgImage
|
||||
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
|
||||
var observations: [VNDetectedObjectObservation] = []
|
||||
|
||||
// create a text request
|
||||
let textRequest = VNRecognizeTextRequest { request, error in
|
||||
guard let results = request.results as? [VNRecognizedTextObservation],
|
||||
error == nil else {
|
||||
return
|
||||
}
|
||||
observations.append(contentsOf: results)
|
||||
}
|
||||
textRequest.recognitionLevel = .accurate
|
||||
textRequest.revision = VNRecognizeTextRequestRevision2
|
||||
|
||||
// create a face request
|
||||
let faceRequest = VNDetectFaceRectanglesRequest { request, error in
|
||||
guard let results = request.results as? [VNFaceObservation],
|
||||
error == nil else {
|
||||
return
|
||||
}
|
||||
observations.append(contentsOf: results)
|
||||
}
|
||||
// revision3 doesn't work!
|
||||
faceRequest.revision = VNDetectFaceRectanglesRequestRevision2
|
||||
|
||||
#if targetEnvironment(simulator)
|
||||
// Avoid `Could not create inference context` errors on Apple Silicon
|
||||
// https://www.caseyliss.com/2022/6/20/feedback-is-broken-stop-trying-to-make-radar-happen
|
||||
faceRequest.usesCPUOnly = true
|
||||
#endif
|
||||
|
||||
// perform requests
|
||||
try handler.perform([
|
||||
textRequest,
|
||||
faceRequest
|
||||
])
|
||||
|
||||
return render(image: image,
|
||||
confidenceLevel: confidenceLevel,
|
||||
fillColor: fillColor,
|
||||
observations: observations)
|
||||
}
|
||||
|
||||
private static func render(image: UIImage,
|
||||
confidenceLevel: Float,
|
||||
fillColor: UIColor,
|
||||
observations: [VNDetectedObjectObservation]) -> UIImage {
|
||||
let size = image.size
|
||||
let result = UIGraphicsImageRenderer(size: size).image { rendererContext in
|
||||
// first draw self
|
||||
image.draw(in: CGRect(origin: .zero, size: size))
|
||||
// set fill color
|
||||
fillColor.setFill()
|
||||
for observation in observations {
|
||||
guard observation.confidence >= confidenceLevel else {
|
||||
// ensure observation's confidence level
|
||||
continue
|
||||
}
|
||||
if let textObservation = observation as? VNRecognizedTextObservation,
|
||||
let text = textObservation.topCandidates(1).first?.string {
|
||||
if Double(text) != nil || Self.allowedTextItems.contains(text) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
let box = observation.boundingBox
|
||||
// boc is normalized (and in starts from the lower left corner)
|
||||
// convert it to a rect in the image
|
||||
let rect = CGRect(x: box.minX * size.width,
|
||||
y: size.height - box.maxY * size.height,
|
||||
width: box.width * size.width,
|
||||
height: box.height * size.height)
|
||||
rendererContext.fill(rect)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ class NetworkMonitor {
|
||||
init() {
|
||||
queue = DispatchQueue(label: "io.element.elementx.networkmonitor")
|
||||
pathMonitor = NWPathMonitor()
|
||||
reachabilityPublisher = CurrentValueSubject<Bool, Never>(pathMonitor.currentPath.status == .satisfied)
|
||||
reachabilityPublisher = CurrentValueSubject<Bool, Never>(true)
|
||||
|
||||
pathMonitor.pathUpdateHandler = { [weak self] path in
|
||||
DispatchQueue.main.async {
|
||||
|
||||
Reference in New Issue
Block a user