Skip to content

Commit

Permalink
element-hq/element-ios/issues/5114 - Added poll event methods, poll a…
Browse files Browse the repository at this point in the history
…ggregator and model builder
  • Loading branch information
stefanceriu committed Nov 15, 2021
1 parent 8093a86 commit 82136ea
Show file tree
Hide file tree
Showing 19 changed files with 1,358 additions and 19 deletions.
83 changes: 76 additions & 7 deletions MatrixSDK.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions MatrixSDK/Aggregations/MXAggregations.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ NS_ASSUME_NONNULL_BEGIN
- (MXHTTPOperation*)reactionsEventsForEvent:(NSString*)eventId
inRoom:(NSString*)roomId
from:(nullable NSString*)from
limit:(NSUInteger)limit
limit:(NSInteger)limit
success:(void (^)(MXAggregationPaginatedResponse *paginatedResponse))success
failure:(void (^)(NSError *error))failure;

Expand Down Expand Up @@ -168,7 +168,7 @@ NS_ASSUME_NONNULL_BEGIN
isEncrypted:(BOOL)isEncrypted
inRoom:(NSString*)roomId
from:(nullable NSString*)from
limit:(NSUInteger)limit
limit:(NSInteger)limit
success:(void (^)(MXAggregationPaginatedResponse *paginatedResponse))success
failure:(void (^)(NSError *error))failure;

Expand All @@ -191,7 +191,7 @@ NS_ASSUME_NONNULL_BEGIN
- (MXHTTPOperation*)referenceEventsForEvent:(NSString*)eventId
inRoom:(NSString*)roomId
from:(nullable NSString*)from
limit:(NSUInteger)limit
limit:(NSInteger)limit
success:(void (^)(MXAggregationPaginatedResponse *paginatedResponse))success
failure:(void (^)(NSError *error))failure;

Expand Down
6 changes: 3 additions & 3 deletions MatrixSDK/Aggregations/MXAggregations.m
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ - (void)removeListener:(id)listener
- (MXHTTPOperation*)reactionsEventsForEvent:(NSString*)eventId
inRoom:(NSString*)roomId
from:(nullable NSString*)from
limit:(NSUInteger)limit
limit:(NSInteger)limit
success:(void (^)(MXAggregationPaginatedResponse *paginatedResponse))success
failure:(void (^)(NSError *error))failure
{
Expand Down Expand Up @@ -126,7 +126,7 @@ - (MXHTTPOperation*)replaceEventsForEvent:(NSString*)eventId
isEncrypted:(BOOL)isEncrypted
inRoom:(NSString*)roomId
from:(nullable NSString*)from
limit:(NSUInteger)limit
limit:(NSInteger)limit
success:(void (^)(MXAggregationPaginatedResponse *paginatedResponse))success
failure:(void (^)(NSError *error))failure
{
Expand All @@ -137,7 +137,7 @@ - (MXHTTPOperation*)replaceEventsForEvent:(NSString*)eventId
- (MXHTTPOperation*)referenceEventsForEvent:(NSString*)eventId
inRoom:(NSString*)roomId
from:(nullable NSString*)from
limit:(NSUInteger)limit
limit:(NSInteger)limit
success:(void (^)(MXAggregationPaginatedResponse *paginatedResponse))success
failure:(void (^)(NSError *error))failure
{
Expand Down
18 changes: 18 additions & 0 deletions MatrixSDK/Data/MXRoom.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#import "MXEvent.h"
#import "MXJSONModels.h"
#import "MXEventContentPollStart.h"
#import "MXRoomSummary.h"
#import "MXRoomMember.h"
#import "MXReceiptData.h"
Expand Down Expand Up @@ -931,6 +932,23 @@ FOUNDATION_EXPORT NSInteger const kMXRoomAlreadyJoinedErrorCode;
success:(void (^)(NSString *eventId))success
failure:(void (^)(NSError *error))failure NS_REFINED_FOR_SWIFT;

#pragma mark - Polls

- (MXHTTPOperation *)sendPollStartWithContent:(MXEventContentPollStart *)content
localEcho:(MXEvent **)localEcho
success:(void (^)(NSString *))success
failure:(void (^)(NSError *))failure;

- (MXHTTPOperation*)sendPollResponseForEvent:(MXEvent *)pollEvent
withAnswerIdentifiers:(NSArray<NSString *> *)answerIdentifiers
localEcho:(MXEvent **)localEcho
success:(void (^)(NSString *eventId))success
failure:(void (^)(NSError *error))failure;

- (MXHTTPOperation*)sendPollEndForEvent:(MXEvent *)pollEvent
localEcho:(MXEvent **)localEcho
success:(void (^)(NSString *eventId))success
failure:(void (^)(NSError *error))failure;

#pragma mark - Events listeners on the live timeline
/**
Expand Down
88 changes: 83 additions & 5 deletions MatrixSDK/Data/MXRoom.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@

#import "MXRoomSync.h"

#import "MXEventContentPollStart.h"

NSString *const kMXRoomDidFlushDataNotification = @"kMXRoomDidFlushDataNotification";
NSString *const kMXRoomInitialSyncNotification = @"kMXRoomInitialSyncNotification";
NSInteger const kMXRoomAlreadyJoinedErrorCode = 9001;
Expand Down Expand Up @@ -618,11 +620,11 @@ - (MXHTTPOperation*)sendEventOfType:(MXEventTypeString)eventTypeString
NSDictionary *contentCopyToEncrypt = nil;

// Store the "m.relates_to" data and remove them from event clear content before encrypting the event content
if (contentCopy[@"m.relates_to"])
if (contentCopy[kMXEventRelationRelatesToKey])
{
relatesToJSON = contentCopy[@"m.relates_to"];
relatesToJSON = contentCopy[kMXEventRelationRelatesToKey];
NSMutableDictionary *updatedContent = [contentCopy mutableCopy];
updatedContent[@"m.relates_to"] = nil;
updatedContent[kMXEventRelationRelatesToKey] = nil;
contentCopyToEncrypt = [updatedContent copy];
}
else
Expand Down Expand Up @@ -673,7 +675,7 @@ - (MXHTTPOperation*)sendEventOfType:(MXEventTypeString)eventTypeString
if (relatesToJSON)
{
NSMutableDictionary *updatedEncryptedContent = [encryptedContent mutableCopy];
updatedEncryptedContent[@"m.relates_to"] = relatesToJSON;
updatedEncryptedContent[kMXEventRelationRelatesToKey] = relatesToJSON;
finalEncryptedContent = [updatedEncryptedContent copy];
}
else
Expand Down Expand Up @@ -1968,7 +1970,7 @@ - (MXHTTPOperation*)sendReplyToEvent:(MXEvent*)eventToReply
msgContent[@"msgtype"] = kMXMessageTypeText;
msgContent[@"body"] = replyToBody;
msgContent[@"formatted_body"] = replyToFormattedBody;
msgContent[@"m.relates_to"] = relatesToDict;
msgContent[kMXEventRelationRelatesToKey] = relatesToDict;

operation = [self sendMessageWithContent:msgContent
localEcho:localEcho
Expand Down Expand Up @@ -2274,6 +2276,82 @@ - (BOOL)canReplyToEvent:(MXEvent *)eventToReply
return canReplyToEvent;
}

#pragma mark - Polls

- (MXHTTPOperation *)sendPollStartWithContent:(MXEventContentPollStart *)content
localEcho:(MXEvent **)localEcho
success:(void (^)(NSString *))success
failure:(void (^)(NSError *))failure
{
NSParameterAssert(content);

if(content.question.length == 0) {
MXLogError(@"[MXRoom] Cannot send poll with empty question.");
return nil;
}

if(content.answerOptions.count < 2) {
MXLogError(@"[MXRoom] Cannot send poll with less than 2 answer options.");
return nil;
}

for(MXEventContentPollStartAnswerOption *answerOption in content.answerOptions) {
if(answerOption.text.length == 0) {
MXLogError(@"[MXRoom] Cannot send poll with empty answer option.");
return nil;
}
}

return [self sendEventOfType:kMXEventTypeStringPollStart content:content.JSONDictionary localEcho:localEcho success:success failure:failure];
}

- (MXHTTPOperation *)sendPollResponseForEvent:(MXEvent *)pollStartEvent
withAnswerIdentifiers:(NSArray<NSString *> *)answerIdentifiers
localEcho:(MXEvent **)localEcho
success:(void (^)(NSString *))success
failure:(void (^)(NSError *))failure
{
NSParameterAssert(pollStartEvent);
NSAssert([pollStartEvent.type isEqualToString:kMXEventTypeStringPollStart], @"Invalid event type");
NSParameterAssert(answerIdentifiers);

for(NSString *answerIdentifier in answerIdentifiers) {
if(answerIdentifier.length == 0) {
MXLogError(@"[MXRoom] Cannot send poll answer with empty identifier.");
return nil;
}
}

MXEventContentRelatesTo *relatesTo = [[MXEventContentRelatesTo alloc] initWithRelationType:MXEventRelationTypeReference
eventId:pollStartEvent.eventId];

NSDictionary *content = @{
kMXEventRelationRelatesToKey: relatesTo.JSONDictionary,
kMXMessageContentKeyExtensiblePollResponse: @{ kMXMessageContentKeyExtensiblePollAnswers: answerIdentifiers }
};

return [self sendEventOfType:kMXEventTypeStringPollResponse content:content localEcho:localEcho success:success failure:failure];
}

- (MXHTTPOperation *)sendPollEndForEvent:(MXEvent *)pollStartEvent
localEcho:(MXEvent **)localEcho
success:(void (^)(NSString *))success
failure:(void (^)(NSError *))failure
{
NSParameterAssert(pollStartEvent);
NSAssert([pollStartEvent.type isEqualToString:kMXEventTypeStringPollStart], @"Invalid event type");

MXEventContentRelatesTo *relatesTo = [[MXEventContentRelatesTo alloc] initWithRelationType:MXEventRelationTypeReference
eventId:pollStartEvent.eventId];

NSDictionary *content = @{
kMXEventRelationRelatesToKey: relatesTo.JSONDictionary,
kMXMessageContentKeyExtensiblePollEnd: @{}
};

return [self sendEventOfType:kMXEventTypeStringPollEnd content:content localEcho:localEcho success:success failure:failure];
}

#pragma mark - Message order preserving
/**
Make sure that `block` will be called in the order expected by the end user.
Expand Down
51 changes: 51 additions & 0 deletions MatrixSDK/JSONModels/Event/Content/MXEventContentPollStart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// Copyright 2021 The Matrix.org Foundation C.I.C
//
// 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/Foundation.h>

#import "MXJSONModel.h"

NS_ASSUME_NONNULL_BEGIN

@interface MXEventContentPollStartAnswerOption: MXJSONModel

@property (nonatomic, readonly) NSString *uuid;

@property (nonatomic, readonly) NSString *text;

- (instancetype)initWithUUID:(NSString *)uuid
text:(NSString *)text;

@end

@interface MXEventContentPollStart : MXJSONModel

@property (nonatomic, readonly) NSString *question;

@property (nonatomic, readonly) NSString *kind;

@property (nonatomic, readonly) NSNumber *maxSelections;

@property (nonatomic, readonly) NSArray<MXEventContentPollStartAnswerOption *> *answerOptions;

- (instancetype)initWithQuestion:(NSString *)question
kind:(NSString *)kind
maxSelections:(NSNumber *)maxSelections
answerOptions:(NSArray<MXEventContentPollStartAnswerOption *> *)answerOptions;

@end

NS_ASSUME_NONNULL_END
110 changes: 110 additions & 0 deletions MatrixSDK/JSONModels/Event/Content/MXEventContentPollStart.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//
// Copyright 2021 The Matrix.org Foundation C.I.C
//
// 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 "MXEventContentPollStart.h"
#import "MXEvent.h"

@implementation MXEventContentPollStart

- (instancetype)initWithQuestion:(NSString *)question
kind:(NSString *)kind
maxSelections:(NSNumber *)maxSelections
answerOptions:(NSArray<MXEventContentPollStartAnswerOption *> *)answerOptions
{
if (self = [super init]) {
_question = question;
_kind = kind;
_maxSelections = maxSelections;
_answerOptions = answerOptions;
}

return self;
}

+ (instancetype)modelFromJSON:(NSDictionary *)JSONDictionary
{
NSDictionary *content = JSONDictionary[kMXMessageContentKeyExtensiblePollStart];

NSString *question, *kind;
MXJSONModelSetString(question, content[kMXMessageContentKeyExtensiblePollQuestion]);
MXJSONModelSetString(kind, content[kMXMessageContentKeyExtensiblePollKind]);

NSNumber *maxSelections;
MXJSONModelSetNumber(maxSelections, content[kMXMessageContentKeyExtensiblePollMaxSelections]);

NSArray<MXEventContentPollStartAnswerOption *> *answerOptions = [MXEventContentPollStartAnswerOption modelsFromJSON:content[kMXMessageContentKeyExtensiblePollAnswers]];

return [[MXEventContentPollStart alloc] initWithQuestion:question
kind:kind
maxSelections:maxSelections
answerOptions:answerOptions];
}

- (NSDictionary *)JSONDictionary
{
NSMutableDictionary *content = [NSMutableDictionary dictionary];

content[kMXMessageContentKeyExtensiblePollQuestion] = self.question;
content[kMXMessageContentKeyExtensiblePollKind] = self.kind;
content[kMXMessageContentKeyExtensiblePollMaxSelections] = self.maxSelections;

NSMutableArray *answerOptions = [NSMutableArray arrayWithCapacity:self.answerOptions.count];
for (MXEventContentPollStartAnswerOption *answerOption in self.answerOptions)
{
[answerOptions addObject:answerOption.JSONDictionary];
}

content[kMXMessageContentKeyExtensiblePollAnswers] = answerOptions;

return @{kMXMessageContentKeyExtensiblePollStart: content};
}

@end


@implementation MXEventContentPollStartAnswerOption

- (instancetype)initWithUUID:(NSString *)uuid text:(NSString *)text
{
if (self = [super init])
{
_uuid = uuid;
_text = text;
}

return self;
}

+ (instancetype)modelFromJSON:(NSDictionary *)JSONDictionary
{
NSString *uuid, *text;
MXJSONModelSetString(uuid, JSONDictionary[kMXMessageContentKeyExtensiblePollAnswerId]);
MXJSONModelSetString(text, JSONDictionary[kMXMessageContentKeyExtensibleText]);

return [[MXEventContentPollStartAnswerOption alloc] initWithUUID:uuid text:text];
}

- (NSDictionary *)JSONDictionary
{
NSMutableDictionary *JSONDictionary = [NSMutableDictionary dictionary];

JSONDictionary[kMXMessageContentKeyExtensiblePollAnswerId] = self.uuid;
JSONDictionary[kMXMessageContentKeyExtensibleText] = self.text;

return JSONDictionary;
}

@end
7 changes: 7 additions & 0 deletions MatrixSDK/JSONModels/Event/Content/MXEventContentRelatesTo.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) NSString *eventId;
@property (nonatomic, readonly, nullable) NSString *key;

- (instancetype)initWithRelationType:(NSString *)relationType
eventId:(NSString *)eventId;

- (instancetype)initWithRelationType:(NSString *)relationType
eventId:(NSString *)eventId
key:(nullable NSString *)key;

@end

NS_ASSUME_NONNULL_END
Loading

0 comments on commit 82136ea

Please sign in to comment.