Skip to content

Commit

Permalink
Merge branch 'develop' into alfogrillo/sync_polls_rules
Browse files Browse the repository at this point in the history
  • Loading branch information
alfogrillo committed Jan 31, 2023
2 parents 9b31462 + b1a1cb1 commit 8d734b9
Show file tree
Hide file tree
Showing 24 changed files with 233 additions and 28 deletions.
3 changes: 3 additions & 0 deletions Config/AppConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class AppConfiguration: CommonConfiguration {
override func setupSettings() {
super.setupSettings()
setupAppSettings()
#if DEBUG
CryptoSDKConfiguration.shared.setup()
#endif
}

private func setupAppSettings() {
Expand Down
6 changes: 0 additions & 6 deletions Config/CommonConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,6 @@ class CommonConfiguration: NSObject, Configurable {
MXKeyProvider.sharedInstance().delegate = EncryptionKeyManager.shared

sdkOptions.enableNewClientInformationFeature = RiotSettings.shared.enableClientInformationFeature

#if DEBUG
if sdkOptions.isCryptoSDKAvailable {
sdkOptions.enableCryptoSDK = RiotSettings.shared.enableCryptoSDK
}
#endif
}

private func makeASCIIUserAgent() -> String? {
Expand Down
55 changes: 55 additions & 0 deletions Config/CryptoSDKConfiguration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Copyright 2023 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

#if DEBUG

/// Configuration for enabling / disabling Matrix Crypto SDK
@objcMembers class CryptoSDKConfiguration: NSObject {
static let shared = CryptoSDKConfiguration()

func setup() {
guard MXSDKOptions.sharedInstance().isCryptoSDKAvailable else {
return
}

let isEnabled = RiotSettings.shared.enableCryptoSDK
MXSDKOptions.sharedInstance().enableCryptoSDK = isEnabled

MXLog.debug("[CryptoSDKConfiguration] setup: Crypto SDK is \(isEnabled ? "enabled" : "disabled")")
}

func enable() {
guard MXSDKOptions.sharedInstance().isCryptoSDKAvailable else {
return
}

RiotSettings.shared.enableCryptoSDK = true
MXSDKOptions.sharedInstance().enableCryptoSDK = true

MXLog.debug("[CryptoSDKConfiguration] enabling Crypto SDK")
}

func disable() {
RiotSettings.shared.enableCryptoSDK = false
MXSDKOptions.sharedInstance().enableCryptoSDK = false

MXLog.debug("[CryptoSDKConfiguration] disabling Crypto SDK")
}
}

#endif
2 changes: 2 additions & 0 deletions Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -2000,6 +2000,7 @@ Tap the + to start adding people.";
"home_context_menu_normal_priority" = "Normal priority";
"home_context_menu_leave" = "Leave";
"home_context_menu_mark_as_read" = "Mark as read";
"home_context_menu_mark_as_unread" = "Mark as unread";
"home_syncing" = "Syncing";

// MARK: - Favourites
Expand Down Expand Up @@ -2226,6 +2227,7 @@ Tap the + to start adding people.";
"voice_broadcast_connection_error_title" = "Connection error";
"voice_broadcast_connection_error_message" = "Unfortunately we’re unable to start a recording right now. Please try again later.";
"voice_broadcast_recorder_connection_error" = "Connection error - Recording paused";
"voice_broadcast_playback_unable_to_decrypt" = "Unable to decrypt this voice broadcast.";

// MARK: - Version check

Expand Down
8 changes: 8 additions & 0 deletions Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2515,6 +2515,10 @@ public class VectorL10n: NSObject {
public static var homeContextMenuMarkAsRead: String {
return VectorL10n.tr("Vector", "home_context_menu_mark_as_read")
}
/// Mark as unread
public static var homeContextMenuMarkAsUnread: String {
return VectorL10n.tr("Vector", "home_context_menu_mark_as_unread")
}
/// Mute
public static var homeContextMenuMute: String {
return VectorL10n.tr("Vector", "home_context_menu_mute")
Expand Down Expand Up @@ -9243,6 +9247,10 @@ public class VectorL10n: NSObject {
public static var voiceBroadcastPlaybackLockScreenPlaceholder: String {
return VectorL10n.tr("Vector", "voice_broadcast_playback_lock_screen_placeholder")
}
/// Unable to decrypt this voice broadcast.
public static var voiceBroadcastPlaybackUnableToDecrypt: String {
return VectorL10n.tr("Vector", "voice_broadcast_playback_unable_to_decrypt")
}
/// Connection error - Recording paused
public static var voiceBroadcastRecorderConnectionError: String {
return VectorL10n.tr("Vector", "voice_broadcast_recorder_connection_error")
Expand Down
5 changes: 5 additions & 0 deletions Riot/Modules/Application/LegacyAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -2183,6 +2183,11 @@ - (void)logoutSendingRequestServer:(BOOL)sendLogoutServerRequest
// Clear cache
[self clearCache];

// Reset Crypto SDK configuration (labs flag for which crypto module to use)
#if DEBUG
[CryptoSDKConfiguration.shared disable];
#endif

// Reset key backup banner preferences
[SecureBackupBannerPreferences.shared reset];

Expand Down
5 changes: 5 additions & 0 deletions Riot/Modules/Common/Recents/RecentsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -2471,6 +2471,11 @@ - (void)roomContextActionService:(id<RoomContextActionServiceProtocol>)service s
editedRoomId = nil;
}

-(void)roomContextActionServiceDidMarkRoom:(id<RoomContextActionServiceProtocol>)service
{
[self refreshRecentsTable];
}

#pragma mark - RecentCellContextMenuProviderDelegate

- (void)recentCellContextMenuProviderDidStartShowingPreview:(RecentCellContextMenuProvider *)menuProvider
Expand Down
7 changes: 5 additions & 2 deletions Riot/Modules/Common/Recents/Views/RecentTableViewCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ - (void)render:(MXKCellData *)cellData
self.missedNotifAndUnreadIndicator.hidden = YES;
self.missedNotifAndUnreadBadgeBgView.hidden = YES;
self.missedNotifAndUnreadBadgeBgViewWidthConstraint.constant = 0;
self.missedNotifAndUnreadBadgeLabel.text = @"";

roomCellData = (id<MXKRecentCellDataStoring>)cellData;
if (roomCellData)
Expand All @@ -93,10 +94,10 @@ - (void)render:(MXKCellData *)cellData
// Notify unreads and bing
if (roomCellData.hasUnread)
{
self.missedNotifAndUnreadIndicator.hidden = NO;

if (0 < roomCellData.notificationCount)
{
self.missedNotifAndUnreadIndicator.hidden = NO;
self.missedNotifAndUnreadIndicator.backgroundColor = roomCellData.highlightCount ? ThemeService.shared.theme.noticeColor : ThemeService.shared.theme.noticeSecondaryColor;

self.missedNotifAndUnreadBadgeBgView.hidden = NO;
Expand All @@ -109,7 +110,9 @@ - (void)render:(MXKCellData *)cellData
}
else
{
self.missedNotifAndUnreadIndicator.backgroundColor = ThemeService.shared.theme.unreadRoomIndentColor;
self.missedNotifAndUnreadBadgeBgView.hidden = NO;
self.missedNotifAndUnreadBadgeBgView.backgroundColor = ThemeService.shared.theme.tintColor;
self.missedNotifAndUnreadBadgeBgViewWidthConstraint.constant = 20;
}

// Use bold font for the room title
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class RoomActionProvider: RoomActionProviderProtocol {

var menu: UIMenu {
if service.isRoomJoined {
var children = service.hasUnread ? [self.markAsReadAction] : []
var children = service.hasUnread ? [self.markAsReadAction] : [self.markAsUnreadAction]
children.append(contentsOf: [
self.directChatAction,
self.notificationsAction,
Expand Down Expand Up @@ -113,6 +113,14 @@ class RoomActionProvider: RoomActionProviderProtocol {
self.service.markAsRead()
}
}
private var markAsUnreadAction: UIAction {
return UIAction(
title: VectorL10n.homeContextMenuMarkAsUnread,
image: UIImage(systemName: "envelope.badge")) { [weak self] action in
guard let self = self else { return }
self.service.markAsUnread()
}
}

private var leaveAction: UIAction {
let image = UIImage(systemName: "rectangle.righthalf.inset.fill.arrow.right")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class RoomContextActionService: NSObject, RoomContextActionServiceProtocol {
self.room = room
self.delegate = delegate
self.isRoomJoined = room.summary?.isJoined ?? false
self.hasUnread = room.summary?.hasAnyUnread ?? false
self.hasUnread = (room.summary?.hasAnyUnread ?? false) || room.isMarkedAsUnread
self.roomMembership = room.summary?.membership ?? .unknown
self.session = room.mxSession
self.unownedRoomService = UnownedRoomContextActionService(roomId: room.roomId, canonicalAlias: room.summary?.aliases?.first, session: self.session, delegate: delegate)
Expand Down Expand Up @@ -108,6 +108,11 @@ class RoomContextActionService: NSObject, RoomContextActionServiceProtocol {

func markAsRead() {
room.markAllAsRead()
self.delegate?.roomContextActionServiceDidMarkRoom(self)
}
func markAsUnread() {
room.setUnread()
self.delegate?.roomContextActionServiceDidMarkRoom(self)
}

// MARK: - Private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Foundation
func roomContextActionService(_ service: RoomContextActionServiceProtocol, showRoomNotificationSettingsForRoomWithId roomId: String)
func roomContextActionServiceDidJoinRoom(_ service: RoomContextActionServiceProtocol)
func roomContextActionServiceDidLeaveRoom(_ service: RoomContextActionServiceProtocol)
func roomContextActionServiceDidMarkRoom(_ service: RoomContextActionServiceProtocol)
}

/// `RoomContextActionServiceProtocol` classes are meant to be called by a `RoomActionProviderProtocol` instance so it provides the implementation of the menu actions.
Expand Down
3 changes: 2 additions & 1 deletion Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellData.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ - (NSString*)lastEventDate

- (BOOL)hasUnread
{
return (roomSummary.localUnreadEventCount != 0);
bool isRoomUnread = [[self mxSession] isRoomMarkedAsUnread:roomSummary.roomId];
return (roomSummary.localUnreadEventCount != 0 || isRoomUnread);
}

- (NSString *)roomIdentifier
Expand Down
18 changes: 16 additions & 2 deletions Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m
Original file line number Diff line number Diff line change
Expand Up @@ -1053,8 +1053,22 @@ - (NSAttributedString *)attributedStringFromEvent:(MXEvent*)event
else if ([event.decryptionError.domain isEqualToString:MXDecryptingErrorDomain]
&& event.decryptionError.code == MXDecryptingErrorUnknownInboundSessionIdCode)
{
// Make the unknown inbound session id error description more user friendly
errorDescription = [VectorL10n noticeCryptoErrorUnknownInboundSessionId];
// Hide the decryption error for VoiceBroadcast chunks
BOOL isVoiceBroadcastChunk = NO;
if ([event.relatesTo.relationType isEqualToString:MXEventRelationTypeReference]) {
MXEvent *startEvent = [mxSession.store eventWithEventId:event.relatesTo.eventId
inRoom:event.roomId];

if (startEvent) {
isVoiceBroadcastChunk = (startEvent.eventType == MXEventTypeCustom && [startEvent.type isEqualToString:VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType]);
}
}
if (isVoiceBroadcastChunk) {
displayText = nil;
} else {
// Make the unknown inbound session id error description more user friendly
errorDescription = [VectorL10n noticeCryptoErrorUnknownInboundSessionId];
}
}
else if ([event.decryptionError.domain isEqualToString:MXDecryptingErrorDomain]
&& event.decryptionError.code == MXDecryptingErrorDuplicateMessageIndexCode)
Expand Down
5 changes: 5 additions & 0 deletions Riot/Modules/Room/MXKRoomViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,11 @@ - (void)viewDidAppear:(BOOL)animated
[self.roomDataSource.room.summary markAllAsReadLocally];

[self updateCurrentEventIdAtTableBottom:YES];

if (!self.isContextPreview)
{
[self.roomDataSource.room resetUnread];
}
}

- (void)viewWillDisappear:(BOOL)animated
Expand Down
3 changes: 1 addition & 2 deletions Riot/Modules/Settings/SettingsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -3400,8 +3400,7 @@ - (void)toggleEnableCryptoSDKFeature:(UISwitch *)sender
[confirmationAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n continue] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
MXStrongifyAndReturnIfNil(self);

RiotSettings.shared.enableCryptoSDK = isEnabled;
MXSDKOptions.sharedInstance.enableCryptoSDK = isEnabled;
[CryptoSDKConfiguration.shared enable];
[[AppDelegate theDelegate] reloadMatrixSessions:YES];
}]];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public protocol VoiceBroadcastAggregatorDelegate: AnyObject {
func voiceBroadcastAggregator(_ aggregator: VoiceBroadcastAggregator, didReceiveChunk: VoiceBroadcastChunk)
func voiceBroadcastAggregator(_ aggregator: VoiceBroadcastAggregator, didReceiveState: VoiceBroadcastInfoState)
func voiceBroadcastAggregatorDidUpdateData(_ aggregator: VoiceBroadcastAggregator)
func voiceBroadcastAggregator(_ aggregator: VoiceBroadcastAggregator, didUpdateUndecryptableEventList events: Set<MXEvent>)
}

/**
Expand All @@ -58,6 +59,7 @@ public class VoiceBroadcastAggregator {
private var referenceEventsListener: Any?

private var events: [MXEvent] = []
private var undecryptableEvents: Set<MXEvent> = []

public private(set) var voiceBroadcast: VoiceBroadcast! {
didSet {
Expand All @@ -84,7 +86,7 @@ public class VoiceBroadcastAggregator {

try buildVoiceBroadcastStartContent()
}

private func buildVoiceBroadcastStartContent() throws {
guard let event = session.store.event(withEventId: voiceBroadcastStartEventId, inRoom: room.roomId),
let eventContent = VoiceBroadcastInfo(fromJSON: event.content),
Expand Down Expand Up @@ -118,7 +120,11 @@ public class VoiceBroadcastAggregator {

@objc private func eventDidDecrypt(sender: Notification) {
guard let event = sender.object as? MXEvent else { return }


if undecryptableEvents.remove(event) != nil {
delegate?.voiceBroadcastAggregator(self, didUpdateUndecryptableEventList: undecryptableEvents)
}

self.handleEvent(event: event)
}

Expand All @@ -138,8 +144,19 @@ public class VoiceBroadcastAggregator {
private func updateVoiceBroadcast(event: MXEvent) {
guard event.sender == self.voiceBroadcastSenderId,
let relatedEventId = event.relatesTo?.eventId,
relatedEventId == self.voiceBroadcastStartEventId,
event.content[VoiceBroadcastSettings.voiceBroadcastContentKeyChunkType] != nil else {
relatedEventId == self.voiceBroadcastStartEventId else {
return
}

// Handle decryption errors
if event.decryptionError != nil {
self.undecryptableEvents.insert(event)
self.delegate?.voiceBroadcastAggregator(self, didUpdateUndecryptableEventList: self.undecryptableEvents)

return
}

guard event.content[VoiceBroadcastSettings.voiceBroadcastContentKeyChunkType] != nil else {
return
}

Expand Down Expand Up @@ -192,15 +209,22 @@ public class VoiceBroadcastAggregator {
}

self.events.removeAll()
self.undecryptableEvents.removeAll()
self.voiceBroadcastLastChunkSequence = 0

let filteredChunk = response.chunk.filter { event in
event.sender == self.voiceBroadcastSenderId &&
event.content[VoiceBroadcastSettings.voiceBroadcastContentKeyChunkType] != nil
}

self.events.append(contentsOf: filteredChunk)


let decryptionFailure = response.chunk.filter { event in
event.sender == self.voiceBroadcastSenderId &&
event.decryptionError != nil
}
self.undecryptableEvents.formUnion(decryptionFailure)
self.delegate?.voiceBroadcastAggregator(self, didUpdateUndecryptableEventList: self.undecryptableEvents)

let eventTypes = [VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType, kMXEventTypeStringRoomMessage]
self.referenceEventsListener = self.room.listen(toEventsOfTypes: eventTypes, onEvent: { [weak self] event, direction, roomState in
self?.handleEvent(event: event, direction: direction, roomState: roomState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
broadcastState: voiceBroadcastAggregator.voiceBroadcastState,
playbackState: .stopped,
playingState: VoiceBroadcastPlayingState(duration: Float(voiceBroadcastAggregator.voiceBroadcast.duration), isLive: false, canMoveForward: false, canMoveBackward: false),
bindings: VoiceBroadcastPlaybackViewStateBindings(progress: 0))
bindings: VoiceBroadcastPlaybackViewStateBindings(progress: 0),
decryptionState: VoiceBroadcastPlaybackDecryptionState(errorCount: 0))
super.init(initialViewState: viewState)

displayLink = CADisplayLink(target: WeakTarget(self, selector: #selector(handleDisplayLinkTick)), selector: WeakTarget.triggerSelector)
Expand Down Expand Up @@ -486,6 +487,17 @@ extension VoiceBroadcastPlaybackViewModel: VoiceBroadcastAggregatorDelegate {
handleVoiceBroadcastChunksProcessing()
}
}

func voiceBroadcastAggregator(_ aggregator: VoiceBroadcastAggregator, didUpdateUndecryptableEventList events: Set<MXEvent>) {
state.decryptionState.errorCount = events.count
if events.count > 0 {
MXLog.debug("[VoiceBroadcastPlaybackViewModel] voice broadcast decryption error count: \(events.count)/\(aggregator.voiceBroadcast.chunks.count)")

if [.playing, .buffering].contains(state.playbackState) {
pause()
}
}
}
}


Expand Down
Loading

0 comments on commit 8d734b9

Please sign in to comment.