// /* * Copyright (c) 2023 BWI GmbH * * 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 MatrixSDK @objc class BWIAnalyticsHelper: NSObject { @objc static let shared = BWIAnalyticsHelper() private let serialQueue = DispatchQueue(label: "de.bwi.analyticshelper.serialQueue") @objc func getRoomDeviceCount(room: MXRoom, completion: @escaping(Int) -> ()) { // only ask for devices per room if a refresh is needed -> room.mxSession.crypto.devices is costly in large rooms. And even with that performance win don't do it on Mainthread serialQueue.async { if LazyRoomDevices.shared.areDevicesCurrent(room: room) { completion(LazyRoomDevices.shared.deviceCount(room: room)) return } room.members { roomMembers in var noOfDevices = 0 for member in roomMembers?.joinedMembers ?? [MXRoomMember]() { noOfDevices += room.mxSession.crypto.devices(forUser: member.userId).count } LazyRoomDevices.shared.setDeviceCount(room: room, deviceCount: noOfDevices) completion(noOfDevices) } lazyLoadedMembers: { _ in completion(0) } failure: { error in MXLog.error("[RoomAnalyticsHelper] Failed loading room", context: error) completion(0) } } } @objc func getForwardingType(event: MXEvent) -> String? { guard let messageType: MXMessageType = event.messageType else { return nil } switch messageType { case .text: return "text" case .image: return "image" case .video: return "video" case .audio: if (event.content["org.matrix.msc2516.voice"] != nil) || (event.content["org.matrix.msc3245.voice"] != nil) { return "voice_message" } else { return "audio" } case .emote: return nil case .notice: return nil case .location: return "location" case .file: return "file" case .custom(_): return nil } } // MARK: custom dimensions @objc func dimensionForDeviceCount(_ deviceCount: Int) -> String { if deviceCount <= 0 { return "Undefiniert" } if deviceCount <= 10 { return "1 bis 10" } if deviceCount <= 100 { return "11 bis 100" } if deviceCount <= 200 { return "101 bis 200" } if deviceCount <= 500 { return "201 bis 500" } if deviceCount <= 1000 { return "501 bis 1000" } if deviceCount <= 2500 { return "1001 bis 2500" } else { return "mehr als 2500" } } @objc func getRoomAdminCount(room: MXRoom, completion: @escaping(Int) -> ()) { room.state { (state) in room.members { roomMembers in var noOfAdmins = 0 let powerLevels = state?.powerLevels for member in roomMembers?.joinedMembers ?? [MXRoomMember]() { if let powerLevel = state?.powerLevelOfUser(withUserID: member.userId) { if powerLevel >= 100 { noOfAdmins += 1 } } } completion(noOfAdmins) } lazyLoadedMembers: { _ in completion(0) } failure: { error in MXLog.error("[RoomAnalyticsHelper] Failed loading room", context: error) completion(0) } } } }