diff --git a/Config/AppConfiguration.swift b/Config/AppConfiguration.swift index 7f9e29b5f..70b1d78d5 100644 --- a/Config/AppConfiguration.swift +++ b/Config/AppConfiguration.swift @@ -33,7 +33,7 @@ class AppConfiguration: CommonConfiguration { // Get additional events (modular widget, voice broadcast...) MXKAppSettings.standard()?.addSupportedEventTypes([kWidgetMatrixEventTypeString, kWidgetModularEventTypeString, - VoiceBroadcastSettings.eventType]) + VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType]) // Hide undecryptable messages that were sent while the user was not in the room MXKAppSettings.standard()?.hidePreJoinedUndecryptableEvents = true diff --git a/Riot/Modules/Room/CellData/RoomBubbleCellData.h b/Riot/Modules/Room/CellData/RoomBubbleCellData.h index cc76d4880..a6fbf8943 100644 --- a/Riot/Modules/Room/CellData/RoomBubbleCellData.h +++ b/Riot/Modules/Room/CellData/RoomBubbleCellData.h @@ -37,7 +37,8 @@ typedef NS_ENUM(NSInteger, RoomBubbleCellDataTag) RoomBubbleCellDataTagPoll, RoomBubbleCellDataTagLocation, RoomBubbleCellDataTagLiveLocation, - RoomBubbleCellDataTagVoiceBroadcast + RoomBubbleCellDataTagVoiceBroadcastPlayback, + RoomBubbleCellDataTagVoiceBroadcastRecord }; /** diff --git a/Riot/Modules/Room/CellData/RoomBubbleCellData.m b/Riot/Modules/Room/CellData/RoomBubbleCellData.m index 301b87328..a2341b644 100644 --- a/Riot/Modules/Room/CellData/RoomBubbleCellData.m +++ b/Riot/Modules/Room/CellData/RoomBubbleCellData.m @@ -183,13 +183,23 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat self.displayTimestampForSelectedComponentOnLeftWhenPossible = NO; } } - else if ([event.type isEqualToString:VoiceBroadcastSettings.eventType]) + else if ([event.type isEqualToString:VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType]) { - self.tag = RoomBubbleCellDataTagVoiceBroadcast; + MXEvent *roomVoiceBroadcastInfoEvent = [roomState stateEventsWithType:VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType].lastObject; + + VoiceBroadcastInfo *lastVoiceBroadcastInfo = [VoiceBroadcastInfo modelFromJSON: roomVoiceBroadcastInfoEvent.content]; + + if ([VoiceBroadcastInfo isStartedFor:lastVoiceBroadcastInfo.state] && + [event.sender isEqualToString: self.mxSession.myUserId] && + [lastVoiceBroadcastInfo.deviceId isEqualToString:self.mxSession.myDeviceId]) { + self.tag = RoomBubbleCellDataTagVoiceBroadcastRecord; + } else { + self.tag = RoomBubbleCellDataTagVoiceBroadcastPlayback; + } + self.collapsable = NO; self.collapsed = NO; - MXLogDebug(@"VB incoming initWithEvent") break; } @@ -205,7 +215,7 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat } else if (event.content[VoiceBroadcastSettings.voiceBroadcastContentKeyChunkType]) { - self.tag = RoomBubbleCellDataTagVoiceBroadcast; + self.tag = RoomBubbleCellDataTagVoiceBroadcastPlayback; self.collapsable = NO; self.collapsed = NO; } @@ -315,7 +325,7 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat } break; - case RoomBubbleCellDataTagVoiceBroadcast: + case RoomBubbleCellDataTagVoiceBroadcastPlayback: if (RiotSettings.shared.enableVoiceBroadcast == YES && [VoiceBroadcastInfo isStartedFor:[VoiceBroadcastInfo modelFromJSON:self.events.lastObject.content].state]) { @@ -1072,7 +1082,7 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat case RoomBubbleCellDataTagLiveLocation: shouldAddEvent = NO; break; - case RoomBubbleCellDataTagVoiceBroadcast: + case RoomBubbleCellDataTagVoiceBroadcastPlayback: shouldAddEvent = NO; break; default: @@ -1143,7 +1153,7 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat { shouldAddEvent = NO; } - } else if ([event.type isEqualToString:VoiceBroadcastSettings.eventType]) { + } else if ([event.type isEqualToString:VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType]) { shouldAddEvent = NO; } break; diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 2bf4c421b..d0d5bf22a 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -3239,7 +3239,7 @@ static CGSize kThreadListBarButtonItemImageSize; } } } - else if (bubbleData.tag == RoomBubbleCellDataTagVoiceBroadcast) + else if (bubbleData.tag == RoomBubbleCellDataTagVoiceBroadcastPlayback) { if (bubbleData.isIncoming) { diff --git a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastAggregator.swift b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastAggregator.swift index 3efa9662f..d54f6a066 100644 --- a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastAggregator.swift +++ b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastAggregator.swift @@ -42,7 +42,7 @@ public class VoiceBroadcastAggregator { private let voiceBroadcastBuilder: VoiceBroadcastBuilder private var voiceBroadcastInfoStartEventContent: VoiceBroadcastInfo! - private var voiceBroadcastUserId: String! + private var voiceBroadcastSenderId: String! private var referenceEventsListener: Any? @@ -76,13 +76,13 @@ public class VoiceBroadcastAggregator { private func buildVoiceBroadcastStartContent() throws { guard let event = session.store.event(withEventId: voiceBroadcastStartEventId, inRoom: room.roomId), let eventContent = VoiceBroadcastInfo(fromJSON: event.content), - let userId = event.stateKey + let senderId = event.stateKey else { throw VoiceBroadcastAggregatorError.invalidVoiceBroadcastStartEvent } voiceBroadcastInfoStartEventContent = eventContent - voiceBroadcastUserId = userId + voiceBroadcastSenderId = senderId voiceBroadcast = voiceBroadcastBuilder.build(mediaManager: session.mediaManager, voiceBroadcastStartEventId: voiceBroadcastStartEventId, @@ -113,11 +113,10 @@ public class VoiceBroadcastAggregator { self.events.append(contentsOf: response.chunk) - - let eventTypes = [VoiceBroadcastSettings.eventType, kMXEventTypeStringRoomMessage] + let eventTypes = [VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType, kMXEventTypeStringRoomMessage] self.referenceEventsListener = self.room.listen(toEventsOfTypes: eventTypes) { [weak self] event, direction, state in guard let self = self, - event.senderKey == self.voiceBroadcastUserId, + event.sender == self.voiceBroadcastSenderId, let relatedEventId = event.relatesTo?.eventId, relatedEventId == self.voiceBroadcastStartEventId, event.content[VoiceBroadcastSettings.voiceBroadcastContentKeyChunkType] != nil else { diff --git a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastInfo.h b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastInfo.h index 2b759102e..36b963e47 100644 --- a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastInfo.h +++ b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastInfo.h @@ -22,21 +22,25 @@ NS_ASSUME_NONNULL_BEGIN @interface VoiceBroadcastInfo : MXJSONModel +/// The device id from which the broadcast has been started +@property (nonatomic) NSString *deviceId; + /// The voice broadcast state (started - paused - resumed - stopped). @property (nonatomic) NSString *state; /// The length of the voice chunks in seconds. Only required on the started state event. @property (nonatomic) NSInteger chunkLength; -/// The event id of the started voice broadcast info state event. +/// The event id of the started voice broadcast info state event. @property (nonatomic, strong, nullable) NSString* eventId; /// The event used to build the MXBeaconInfo. @property (nonatomic, readonly, nullable) MXEvent *originalEvent; -- (instancetype)initWithState:(NSString *)state - chunkLength:(NSInteger)chunkLength - eventId:(NSString *)eventId; +- (instancetype)initWithDeviceId:(NSString *)deviceId + state:(NSString *)state + chunkLength:(NSInteger)chunkLength + eventId:(NSString *)eventId; @end diff --git a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastInfo.m b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastInfo.m index 14f3c80c3..237a9a720 100644 --- a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastInfo.m +++ b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastInfo.m @@ -19,12 +19,14 @@ @implementation VoiceBroadcastInfo -- (instancetype)initWithState:(NSString *)state - chunkLength:(NSInteger)chunkLength - eventId:(NSString *)eventId +- (instancetype)initWithDeviceId:(NSString *)deviceId + state:(NSString *)state + chunkLength:(NSInteger)chunkLength + eventId:(NSString *)eventId { if (self = [super init]) { + _deviceId = deviceId; _state = state; _chunkLength = chunkLength; _eventId = eventId; @@ -35,6 +37,9 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary { + NSString *deviceId; + MXJSONModelSetString(deviceId, JSONDictionary[VoiceBroadcastSettings.voiceBroadcastContentKeyDeviceId]); + NSString *state; MXJSONModelSetString(state, JSONDictionary[VoiceBroadcastSettings.voiceBroadcastContentKeyState]); @@ -56,13 +61,15 @@ } } - return [[VoiceBroadcastInfo alloc] initWithState:state chunkLength:chunkLength eventId:eventId]; + return [[VoiceBroadcastInfo alloc] initWithDeviceId:deviceId state:state chunkLength:chunkLength eventId:eventId]; } - (NSDictionary *)JSONDictionary { NSMutableDictionary *JSONDictionary = [NSMutableDictionary dictionary]; + JSONDictionary[VoiceBroadcastSettings.voiceBroadcastContentKeyDeviceId] = self.deviceId; + JSONDictionary[VoiceBroadcastSettings.voiceBroadcastContentKeyState] = self.state; if (_eventId) { diff --git a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastService.swift b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastService.swift index 01dd4e80e..a48f77d6b 100644 --- a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastService.swift +++ b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastService.swift @@ -130,6 +130,9 @@ public class VoiceBroadcastService: NSObject { let stateKey = userId let voiceBroadcastInfo = VoiceBroadcastInfo() + + voiceBroadcastInfo.deviceId = self.room.mxSession.myDeviceId + voiceBroadcastInfo.state = state.rawValue if state != VoiceBroadcastInfo.State.started { @@ -148,7 +151,7 @@ public class VoiceBroadcastService: NSObject { return nil } - return self.room.sendStateEvent(.custom(VoiceBroadcastSettings.eventType), + return self.room.sendStateEvent(.custom(VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType), content: stateEventContent, stateKey: stateKey) { [weak self] response in guard let self = self else { return } diff --git a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastSettings.swift b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastSettings.swift index 9d17da35b..425cc03f4 100644 --- a/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastSettings.swift +++ b/Riot/Modules/VoiceBroadcast/VoiceBroadcastSDK/VoiceBroadcastSettings.swift @@ -19,8 +19,9 @@ import Foundation /// Voice Broadcast settings. @objcMembers final class VoiceBroadcastSettings: NSObject { - static let eventType = "io.element.voice_broadcast_info" + static let voiceBroadcastInfoContentKeyType = "io.element.voice_broadcast_info" + static let voiceBroadcastContentKeyDeviceId = "device_id" static let voiceBroadcastContentKeyState = "state" static let voiceBroadcastContentKeyChunkLength = "chunk_length" static let voiceBroadcastContentKeyChunkType = "io.element.voice_broadcast_chunk" diff --git a/Riot/Modules/VoiceBroadcast/VoiceBroadcastServiceProvider.swift b/Riot/Modules/VoiceBroadcast/VoiceBroadcastServiceProvider.swift index 579ef45d4..e39c838b7 100644 --- a/Riot/Modules/VoiceBroadcast/VoiceBroadcastServiceProvider.swift +++ b/Riot/Modules/VoiceBroadcast/VoiceBroadcastServiceProvider.swift @@ -66,7 +66,7 @@ class VoiceBroadcastServiceProvider { /// - completion: Completion block that will return the lastest voice broadcast info state event of the room. private func getLastVoiceBroadcastInfo(for room: MXRoom, completion: @escaping (MXEvent?) -> Void) { room.state { roomState in - completion(roomState?.stateEvents(with: .custom(VoiceBroadcastSettings.eventType))?.last ?? nil) + completion(roomState?.stateEvents(with: .custom(VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType))?.last ?? nil) } } diff --git a/Riot/Utils/EventFormatter.m b/Riot/Utils/EventFormatter.m index 85bfbe000..80efe2f99 100644 --- a/Riot/Utils/EventFormatter.m +++ b/Riot/Utils/EventFormatter.m @@ -272,7 +272,7 @@ static NSString *const kEventFormatterTimeFormat = @"HH:mm"; // Build the attributed string with the right font and color for the events return [self renderString:displayText forEvent:event]; } - } else if ([event.type isEqualToString:VoiceBroadcastSettings.eventType]) { + } else if ([event.type isEqualToString:VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType]) { MXLogDebug(@"VB incoming build string") } }