Update Reactions component (#6244)

* Update Reactions component

- Done
This commit is contained in:
Gil Eluard 2022-06-15 16:08:43 +02:00 committed by GitHub
parent db149ef1f5
commit 4f18e40ea3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 411 additions and 177 deletions

View file

@ -3,7 +3,7 @@ GEM
specs:
CFPropertyList (3.0.5)
rexml
activesupport (6.1.5)
activesupport (6.1.6)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@ -17,20 +17,20 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.568.0)
aws-sdk-core (3.130.0)
aws-partitions (1.598.0)
aws-sdk-core (3.131.1)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.55.0)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.57.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.113.0)
aws-sdk-s3 (1.114.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.4.0)
aws-sigv4 (1.5.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.0.3)
@ -75,7 +75,7 @@ GEM
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
concurrent-ruby (1.1.9)
concurrent-ruby (1.1.10)
declarative (0.0.20)
digest-crc (0.6.4)
rake (>= 12.0.0, < 14.0.0)
@ -86,7 +86,7 @@ GEM
escape (0.0.4)
ethon (0.15.0)
ffi (>= 1.15.0)
excon (0.92.1)
excon (0.92.3)
faraday (1.10.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@ -106,8 +106,8 @@ GEM
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.3)
multipart-post (>= 1.2, < 3)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
@ -116,7 +116,7 @@ GEM
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.6)
fastlane (2.205.0)
fastlane (2.206.2)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@ -165,9 +165,9 @@ GEM
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.16.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-core (0.4.2)
google-apis-androidpublisher_v3 (0.22.0)
google-apis-core (>= 0.5, < 2.a)
google-apis-core (0.5.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@ -176,19 +176,19 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.10.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-playcustomapp_v1 (0.7.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-storage_v1 (0.11.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-iamcredentials_v1 (0.11.0)
google-apis-core (>= 0.5, < 2.a)
google-apis-playcustomapp_v1 (0.8.0)
google-apis-core (>= 0.5, < 2.a)
google-apis-storage_v1 (0.15.0)
google-apis-core (>= 0.5, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.5.0)
faraday (>= 0.17.3, < 2.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.2.0)
google-cloud-storage (1.36.1)
google-cloud-storage (1.36.2)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
@ -196,7 +196,7 @@ GEM
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.1.2)
googleauth (1.1.3)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
@ -205,14 +205,14 @@ GEM
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-accept (1.7.0)
http-cookie (1.0.4)
http-cookie (1.0.5)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (1.10.0)
concurrent-ruby (~> 1.0)
jmespath (1.6.1)
json (2.6.1)
jwt (2.3.0)
json (2.6.2)
jwt (2.4.1)
memoist (0.16.2)
mime-types (3.4.1)
mime-types-data (~> 3.2015)
@ -230,9 +230,9 @@ GEM
optparse (0.1.1)
os (1.1.4)
plist (3.6.0)
public_suffix (4.0.6)
public_suffix (4.0.7)
rake (13.0.6)
representable (3.1.1)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
@ -271,7 +271,7 @@ GEM
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.8.1)
unf_ext (0.0.8.2)
unicode-display_width (1.8.0)
webrick (1.7.0)
word_wrap (1.0.0)
@ -289,7 +289,7 @@ GEM
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
zeitwerk (2.5.4)
zeitwerk (2.6.0)
PLATFORMS
ruby

View file

@ -88,8 +88,8 @@ abstract_target 'RiotPods' do
import_SwiftUI_pods
pod 'DGCollectionViewLeftAlignFlowLayout', '~> 1.0.4'
pod 'UICollectionViewRightAlignedLayout', '~> 0.0.3'
pod 'UICollectionViewLeftAlignedLayout', '~> 1.0.2'
pod 'KTCenterFlowLayout', '~> 1.3.1'
pod 'ZXingObjC', '~> 3.6.5'
pod 'FlowCommoniOS', '~> 1.12.0'

View file

@ -18,7 +18,6 @@ PODS:
- BlueCryptor (1.0.32)
- BlueECC (1.2.5)
- BlueRSA (1.0.200)
- DGCollectionViewLeftAlignFlowLayout (1.0.4)
- Down (0.11.0)
- DSBottomSheet (0.3.0)
- DSWaveformImage (6.1.1)
@ -95,6 +94,7 @@ PODS:
- LoggerAPI (~> 1.7)
- SwiftLint (0.44.0)
- SwiftyBeaver (1.9.5)
- UICollectionViewLeftAlignedLayout (1.0.2)
- UICollectionViewRightAlignedLayout (0.0.3)
- WeakDictionary (2.0.2)
- zxcvbn-ios (1.0.4)
@ -104,7 +104,6 @@ PODS:
DEPENDENCIES:
- AnalyticsEvents (from `https://github.com/matrix-org/matrix-analytics-events.git`, branch `release/swift`)
- DGCollectionViewLeftAlignFlowLayout (~> 1.0.4)
- Down (~> 0.11.0)
- DSBottomSheet (~> 0.3)
- DSWaveformImage (~> 6.1.1)
@ -128,6 +127,7 @@ DEPENDENCIES:
- SwiftGen (~> 6.3)
- SwiftJWT (~> 3.6.200)
- SwiftLint (~> 0.44.0)
- UICollectionViewLeftAlignedLayout (~> 1.0.2)
- UICollectionViewRightAlignedLayout (~> 0.0.3)
- WeakDictionary (~> 2.0)
- zxcvbn-ios
@ -139,7 +139,6 @@ SPEC REPOS:
- BlueCryptor
- BlueECC
- BlueRSA
- DGCollectionViewLeftAlignFlowLayout
- Down
- DSBottomSheet
- DSWaveformImage
@ -171,6 +170,7 @@ SPEC REPOS:
- SwiftJWT
- SwiftLint
- SwiftyBeaver
- UICollectionViewLeftAlignedLayout
- UICollectionViewRightAlignedLayout
- WeakDictionary
- zxcvbn-ios
@ -192,7 +192,6 @@ SPEC CHECKSUMS:
BlueCryptor: b0aee3d9b8f367b49b30de11cda90e1735571c24
BlueECC: 0d18e93347d3ec6d41416de21c1ffa4d4cd3c2cc
BlueRSA: dfeef51db96bcc4edec654956c1581adbda4e6a3
DGCollectionViewLeftAlignFlowLayout: a0fa58797373ded039cafba8133e79373d048399
Down: b6ba1bc985c9d2f4e15e3b293d2207766fa12612
DSBottomSheet: ca0ac37eb5af2dd54663f86b84382ed90a59be2a
DSWaveformImage: 3c718a0cf99291887ee70d1d0c18d80101d3d9ce
@ -224,11 +223,12 @@ SPEC CHECKSUMS:
SwiftJWT: 88c412708f58c169d431d344c87bc79a87c830ae
SwiftLint: e96c0a8c770c7ebbc4d36c55baf9096bb65c4584
SwiftyBeaver: 84069991dd5dca07d7069100985badaca7f0ce82
UICollectionViewLeftAlignedLayout: 830bf6fa5bab9f9b464f62e3384f9d2e00b3c0f6
UICollectionViewRightAlignedLayout: 823eef8c567eba4a44c21bc2ffcb0d0d5f361e2d
WeakDictionary: 8cd038acd77e5d54ca4ebaec3d20853d732b45e0
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
PODFILE CHECKSUM: 85cc09610c3fbaa9f796ac56eef074b96cad686b
PODFILE CHECKSUM: 09a329a72d63d74eb5f75df15305cc05c0587f01
COCOAPODS: 1.11.2
COCOAPODS: 1.11.3

View file

@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "reactions_more_action.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "reactions_more_action@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "reactions_more_action@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -79,16 +79,6 @@
"authentication_recaptcha_message" = "This server would like to make sure you are not a robot";
// MARK: Spaces WIP
"spaces_feature_not_available" = "This feature isn't available here. For now, you can do this with %@ on your computer.";
"leave_space_action" = "Leave space";
"leave_space_and_one_room" = "Leave space and 1 room";
"leave_space_and_more_rooms" = "Leave space and %@ rooms";
"leave_space_selection_title" = "SELECT ROOMS";
"leave_space_selection_all_rooms" = "Select all rooms";
"leave_space_selection_no_rooms" = "Select no rooms";
// MARK: Password Validation
"password_validation_info_header" = "Your password should meet the criteria below:";
"password_validation_error_header" = "Given password does not meet the criteria below:";

View file

@ -1947,6 +1947,8 @@ Tap the + to start adding people.";
"space_settings_update_failed_message" = "Failed to update space settings. Do you want to retry?";
"space_settings_current_address_message" = "Your space is viewable at\n%@";
"spaces_feature_not_available" = "This feature isn't available here. For now, you can do this with %@ on your computer.";
// Mark: - Space Creation
"spaces_creation_hint" = "Spaces are a new way to group rooms and people.";
@ -2007,6 +2009,19 @@ Tap the + to start adding people.";
"spaces_add_room_missing_permission_message" = "You do not have permissions to add rooms to this space.";
"spaces_add_space" = "Add space";
// Mark: Leave space
"leave_space_action" = "Leave space";
"leave_space_and_one_room" = "Leave space and 1 room";
"leave_space_and_more_rooms" = "Leave space and %@ rooms";
"leave_space_selection_title" = "SELECT ROOMS";
"leave_space_selection_all_rooms" = "Select all rooms";
"leave_space_selection_no_rooms" = "Select no rooms";
// MARK: Reactions
"room_event_action_reaction_more" = "%@ more";
// Mark: Avatar
"space_avatar_view_accessibility_label" = "avatar";

View file

@ -1362,33 +1362,6 @@
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</pre>
</li>
<li>
<b>DGCollectionViewLeftAlignFlowLayout</b> (<a href="https://github.com/Digipolitan/collection-view-left-align-flow-layout">https://github.com/Digipolitan/collection-view-left-align-flow-layout</a>)
<br/><br/>This is a simple layout that align does not try to fulfill the lines but stick elements to the left.
<br/><br/>DGCollectionViewLeftAlignFlowLayout is licensed under the BSD 3-Clause license.
<br/>Copyright (c) 2017, Digipolitan All rights reserved.
<br/><br/>Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
<br/><br/>- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
<br/><br/>- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
<br/><br/>- Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
<br/><br/>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<br/><br/>
</li>
<li>
<b>KTCenterFlowLayout</b> (<a href="https://github.com/keighl/KTCenterFlowLayout">https://github.com/keighl/KTCenterFlowLayout</a>)
<br/><br/>KTCenterFlowLayout is a subclass of UICollectionViewFlowLayout which Aligns cells to the center of a collection view.
@ -1927,6 +1900,8 @@ Library.
</li>
<li>
<b>UICollectionViewRightAlignedLayout</b> (<a href="https://github.com/mokagio/UICollectionViewRightAlignedLayout">https://github.com/mokagio/UICollectionViewRightAlignedLayout</a>)
<br/>
<b>UICollectionViewLeftAlignedLayout</b> (<a href="https://github.com/mokagio/UICollectionViewLeftAlignedLayout">https://github.com/mokagio/UICollectionViewLeftAlignedLayout</a>)
<br/><br/>
The MIT License (MIT)
<br/><br/>

View file

@ -32,6 +32,13 @@ extern NSString *const kMXKRoomBubbleCellRiotEditButtonPressed;
*/
extern NSString *const kMXKRoomBubbleCellTapOnReceiptsContainer;
/**
Action identifier used when the user tapped on the add reaction button.
The 'userInfo' dictionary contains a 'NSString' object under the 'kMXKRoomBubbleCellEventIdKey' key, representing the event id of the event associated with the reactions.
*/
extern NSString *const kMXKRoomBubbleCellTapOnAddReaction;
/**
Action identifier used when the user perform a long press on reactions view.

View file

@ -29,6 +29,7 @@
NSString *const kMXKRoomBubbleCellRiotEditButtonPressed = @"kMXKRoomBubbleCellRiotEditButtonPressed";
NSString *const kMXKRoomBubbleCellTapOnReceiptsContainer = @"kMXKRoomBubbleCellTapOnReceiptsContainer";
NSString *const kMXKRoomBubbleCellTapOnAddReaction = @"kMXKRoomBubbleCellTapOnAddReaction";
NSString *const kMXKRoomBubbleCellLongPressOnReactionView = @"kMXKRoomBubbleCellLongPressOnReactionView";
NSString *const kMXKRoomBubbleCellKeyVerificationIncomingRequestAcceptPressed = @"kMXKRoomBubbleCellKeyVerificationAcceptPressed";
NSString *const kMXKRoomBubbleCellKeyVerificationIncomingRequestDeclinePressed = @"kMXKRoomBubbleCellKeyVerificationDeclinePressed";

View file

@ -236,6 +236,7 @@ internal class Asset: NSObject {
internal static let modIcon = ImageAsset(name: "mod_icon")
internal static let moreReactions = ImageAsset(name: "more_reactions")
internal static let notifications = ImageAsset(name: "notifications")
internal static let reactionsMoreAction = ImageAsset(name: "reactions_more_action")
internal static let roomAccessInfoHeaderIcon = ImageAsset(name: "room_access_info_header_icon")
internal static let scrollup = ImageAsset(name: "scrollup")
internal static let roomsEmptyScreenArtwork = ImageAsset(name: "rooms_empty_screen_artwork")

View file

@ -2699,10 +2699,22 @@ public class VectorL10n: NSObject {
public static var leave: String {
return VectorL10n.tr("Vector", "leave")
}
/// Leave space
public static var leaveSpaceAction: String {
return VectorL10n.tr("Vector", "leave_space_action")
}
/// Leave all rooms and spaces
public static var leaveSpaceAndAllRoomsAction: String {
return VectorL10n.tr("Vector", "leave_space_and_all_rooms_action")
}
/// Leave space and %@ rooms
public static func leaveSpaceAndMoreRooms(_ p1: String) -> String {
return VectorL10n.tr("Vector", "leave_space_and_more_rooms", p1)
}
/// Leave space and 1 room
public static var leaveSpaceAndOneRoom: String {
return VectorL10n.tr("Vector", "leave_space_and_one_room")
}
/// Are you sure you want to leave %@? Do you also want to leave all rooms and spaces of this space?
public static func leaveSpaceMessage(_ p1: String) -> String {
return VectorL10n.tr("Vector", "leave_space_message", p1)
@ -2715,6 +2727,18 @@ public class VectorL10n: NSObject {
public static var leaveSpaceOnlyAction: String {
return VectorL10n.tr("Vector", "leave_space_only_action")
}
/// Select all rooms
public static var leaveSpaceSelectionAllRooms: String {
return VectorL10n.tr("Vector", "leave_space_selection_all_rooms")
}
/// Select no rooms
public static var leaveSpaceSelectionNoRooms: String {
return VectorL10n.tr("Vector", "leave_space_selection_no_rooms")
}
/// SELECT ROOMS
public static var leaveSpaceSelectionTitle: String {
return VectorL10n.tr("Vector", "leave_space_selection_title")
}
/// Leave %@
public static func leaveSpaceTitle(_ p1: String) -> String {
return VectorL10n.tr("Vector", "leave_space_title", p1)
@ -5015,6 +5039,10 @@ public class VectorL10n: NSObject {
public static var roomEventActionReactionHistory: String {
return VectorL10n.tr("Vector", "room_event_action_reaction_history")
}
/// %@ more
public static func roomEventActionReactionMore(_ p1: String) -> String {
return VectorL10n.tr("Vector", "room_event_action_reaction_more", p1)
}
/// Show all
public static var roomEventActionReactionShowAll: String {
return VectorL10n.tr("Vector", "room_event_action_reaction_show_all")
@ -7647,6 +7675,10 @@ public class VectorL10n: NSObject {
public static func spacesExploreRoomsRoomNumber(_ p1: String) -> String {
return VectorL10n.tr("Vector", "spaces_explore_rooms_room_number", p1)
}
/// This feature isn't available here. For now, you can do this with %@ on your computer.
public static func spacesFeatureNotAvailable(_ p1: String) -> String {
return VectorL10n.tr("Vector", "spaces_feature_not_available", p1)
}
/// Home
public static var spacesHomeSpaceTitle: String {
return VectorL10n.tr("Vector", "spaces_home_space_title")

View file

@ -202,30 +202,6 @@ public extension VectorL10n {
static var imagePickerActionFiles: String {
return VectorL10n.tr("Untranslated", "image_picker_action_files")
}
/// Leave space
static var leaveSpaceAction: String {
return VectorL10n.tr("Untranslated", "leave_space_action")
}
/// Leave space and %@ rooms
static func leaveSpaceAndMoreRooms(_ p1: String) -> String {
return VectorL10n.tr("Untranslated", "leave_space_and_more_rooms", p1)
}
/// Leave space and 1 room
static var leaveSpaceAndOneRoom: String {
return VectorL10n.tr("Untranslated", "leave_space_and_one_room")
}
/// Select all rooms
static var leaveSpaceSelectionAllRooms: String {
return VectorL10n.tr("Untranslated", "leave_space_selection_all_rooms")
}
/// Select no rooms
static var leaveSpaceSelectionNoRooms: String {
return VectorL10n.tr("Untranslated", "leave_space_selection_no_rooms")
}
/// SELECT ROOMS
static var leaveSpaceSelectionTitle: String {
return VectorL10n.tr("Untranslated", "leave_space_selection_title")
}
/// Contain a lower-case letter.
static var passwordValidationErrorContainLowercaseLetter: String {
return VectorL10n.tr("Untranslated", "password_validation_error_contain_lowercase_letter")
@ -258,10 +234,6 @@ public extension VectorL10n {
static var passwordValidationInfoHeader: String {
return VectorL10n.tr("Untranslated", "password_validation_info_header")
}
/// This feature isn't available here. For now, you can do this with %@ on your computer.
static func spacesFeatureNotAvailable(_ p1: String) -> String {
return VectorL10n.tr("Untranslated", "spaces_feature_not_available", p1)
}
}
// swiftlint:enable function_parameter_count identifier_name line_length type_body_length

View file

@ -1077,6 +1077,11 @@ const CGFloat kTypingCellHeight = 24;
[self setShowAllReactions:NO forEvent:eventId];
}
- (void)roomReactionsViewModel:(RoomReactionsViewModel *)viewModel didTapAddReactionForEventId:(NSString * _Nonnull)eventId
{
[self.delegate dataSource:self didRecognizeAction:kMXKRoomBubbleCellTapOnAddReaction inCell:nil userInfo:@{ kMXKRoomBubbleCellEventIdKey: eventId }];
}
- (void)setShowAllReactions:(BOOL)showAllReactions forEvent:(NSString*)eventId
{
id<MXKRoomBubbleCellDataStoring> cellData = [self cellDataOfEventWithEventId:eventId];

View file

@ -2443,6 +2443,35 @@ static CGSize kThreadListBarButtonItemImageSize;
[self updateLiveLocationBannerViewVisibility];
}
- (void)showEmojiPickerForEventId:(NSString *)eventId
{
EmojiPickerCoordinatorBridgePresenter *emojiPickerCoordinatorBridgePresenter = [[EmojiPickerCoordinatorBridgePresenter alloc] initWithSession:self.mainSession roomId:self.roomDataSource.roomId eventId:eventId];
emojiPickerCoordinatorBridgePresenter.delegate = self;
NSInteger cellRow = [self.roomDataSource indexOfCellDataWithEventId:eventId];
UIView *sourceView;
CGRect sourceRect = CGRectNull;
if (cellRow >= 0)
{
NSIndexPath *cellIndexPath = [NSIndexPath indexPathForRow:cellRow inSection:0];
UITableViewCell *cell = [self.bubblesTableView cellForRowAtIndexPath:cellIndexPath];
sourceView = cell;
if ([cell isKindOfClass:[MXKRoomBubbleTableViewCell class]])
{
MXKRoomBubbleTableViewCell *roomBubbleTableViewCell = (MXKRoomBubbleTableViewCell*)cell;
NSInteger bubbleComponentIndex = [roomBubbleTableViewCell.bubbleData bubbleComponentIndexForEventId:eventId];
sourceRect = [roomBubbleTableViewCell componentFrameInContentViewForIndex:bubbleComponentIndex];
}
}
[emojiPickerCoordinatorBridgePresenter presentFrom:self sourceView:sourceView sourceRect:sourceRect animated:YES];
self.emojiPickerCoordinatorBridgePresenter = emojiPickerCoordinatorBridgePresenter;
}
#pragma mark - Jitsi
- (void)showJitsiCallWithWidget:(Widget*)widget
@ -3390,6 +3419,14 @@ static CGSize kThreadListBarButtonItemImageSize;
[self showReactionHistoryForEventId:tappedEventId animated:YES];
}
}
else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellTapOnAddReaction])
{
NSString *tappedEventId = userInfo[kMXKRoomBubbleCellEventIdKey];
if (tappedEventId)
{
[self showEmojiPickerForEventId:tappedEventId];
}
}
else if ([actionIdentifier isEqualToString:RoomDirectCallStatusCell.callBackAction])
{
MXEvent *callInviteEvent = userInfo[kMXKRoomBubbleCellEventKey];
@ -7136,32 +7173,8 @@ static CGSize kThreadListBarButtonItemImageSize;
- (void)reactionsMenuViewModelDidTapMoreReactions:(ReactionsMenuViewModel *)viewModel forEventId:(NSString *)eventId
{
[self hideContextualMenuAnimated:YES];
EmojiPickerCoordinatorBridgePresenter *emojiPickerCoordinatorBridgePresenter = [[EmojiPickerCoordinatorBridgePresenter alloc] initWithSession:self.mainSession roomId:self.roomDataSource.roomId eventId:eventId];
emojiPickerCoordinatorBridgePresenter.delegate = self;
NSInteger cellRow = [self.roomDataSource indexOfCellDataWithEventId:eventId];
UIView *sourceView;
CGRect sourceRect = CGRectNull;
if (cellRow >= 0)
{
NSIndexPath *cellIndexPath = [NSIndexPath indexPathForRow:cellRow inSection:0];
UITableViewCell *cell = [self.bubblesTableView cellForRowAtIndexPath:cellIndexPath];
sourceView = cell;
if ([cell isKindOfClass:[MXKRoomBubbleTableViewCell class]])
{
MXKRoomBubbleTableViewCell *roomBubbleTableViewCell = (MXKRoomBubbleTableViewCell*)cell;
NSInteger bubbleComponentIndex = [roomBubbleTableViewCell.bubbleData bubbleComponentIndexForEventId:eventId];
sourceRect = [roomBubbleTableViewCell componentFrameInContentViewForIndex:bubbleComponentIndex];
}
}
[emojiPickerCoordinatorBridgePresenter presentFrom:self sourceView:sourceView sourceRect:sourceRect animated:YES];
self.emojiPickerCoordinatorBridgePresenter = emojiPickerCoordinatorBridgePresenter;
[self showEmojiPickerForEventId:eventId];
}
#pragma mark -

View file

@ -25,6 +25,7 @@ final class RoomReactionActionViewCell: UICollectionViewCell, NibReusable, Thema
// MARK: Outlets
@IBOutlet private weak var reactionBackgroundView: UIView!
@IBOutlet private weak var actionLabel: UILabel!
// MARK: Private
@ -33,6 +34,19 @@ final class RoomReactionActionViewCell: UICollectionViewCell, NibReusable, Thema
// MARK: Public
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.reactionBackgroundView.layer.masksToBounds = true
}
override func layoutSubviews() {
super.layoutSubviews()
self.reactionBackgroundView.layer.cornerRadius = self.reactionBackgroundView.bounds.midY
}
// MARK: - Life cycle
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
@ -54,6 +68,14 @@ final class RoomReactionActionViewCell: UICollectionViewCell, NibReusable, Thema
self.updateViews()
}
func fill(actionIcon: UIImage) {
let attachment = NSTextAttachment()
attachment.image = actionIcon.vc_resized(with: CGSize(width: self.actionLabel.bounds.size.height, height: self.actionLabel.bounds.size.height))?.withRenderingMode(.alwaysTemplate)
self.actionLabel.attributedText = NSAttributedString(attachment: attachment)
self.updateViews()
}
func update(theme: Theme) {
self.theme = theme
self.updateViews()
@ -62,6 +84,9 @@ final class RoomReactionActionViewCell: UICollectionViewCell, NibReusable, Thema
// MARK: - Private
private func updateViews() {
self.actionLabel.textColor = self.theme?.tintColor
self.actionLabel.textColor = self.theme?.textSecondaryColor
self.reactionBackgroundView.layer.borderWidth = 0.0
self.reactionBackgroundView.backgroundColor = self.theme?.headerBackgroundColor
}
}

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -11,17 +11,17 @@
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="RoomReactionActionViewCell" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="66" height="22"/>
<rect key="frame" x="0.0" y="0.0" width="101" height="22"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="66" height="22"/>
<rect key="frame" x="0.0" y="0.0" width="101" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jjn-uq-kYN">
<rect key="frame" x="1" y="1" width="64" height="20"/>
<rect key="frame" x="1" y="1" width="99" height="20"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="Show all" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gyn-ux-gmi">
<rect key="frame" x="6" y="4" width="52" height="12"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="Show all" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gyn-ux-gmi">
<rect key="frame" x="6" y="4" width="87" height="12"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@ -29,8 +29,8 @@
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="gyn-ux-gmi" firstAttribute="leading" secondItem="jjn-uq-kYN" secondAttribute="leading" constant="6" id="7hb-HC-Usg"/>
<constraint firstAttribute="trailing" secondItem="gyn-ux-gmi" secondAttribute="trailing" constant="6" id="HAk-8U-Qky"/>
<constraint firstItem="gyn-ux-gmi" firstAttribute="leading" secondItem="jjn-uq-kYN" secondAttribute="leading" constant="6" id="OZ2-Xd-9f3"/>
<constraint firstItem="gyn-ux-gmi" firstAttribute="top" secondItem="jjn-uq-kYN" secondAttribute="top" constant="4" id="et3-mn-8dh"/>
<constraint firstAttribute="bottom" secondItem="gyn-ux-gmi" secondAttribute="bottom" constant="4" id="thv-mo-0kv"/>
</constraints>
@ -44,11 +44,12 @@
<constraint firstItem="jjn-uq-kYN" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="1" id="iT6-rk-qd6"/>
<constraint firstAttribute="trailing" secondItem="jjn-uq-kYN" secondAttribute="trailing" constant="1" id="ztM-7J-Dnf"/>
</constraints>
<size key="customSize" width="443" height="170"/>
<size key="customSize" width="478" height="170"/>
<connections>
<outlet property="actionLabel" destination="gyn-ux-gmi" id="qme-DX-UAc"/>
<outlet property="reactionBackgroundView" destination="jjn-uq-kYN" id="vKf-Un-6PZ"/>
</connections>
<point key="canvasLocation" x="-459.4202898550725" y="-207.58928571428569"/>
<point key="canvasLocation" x="-431.15942028985512" y="-207.58928571428569"/>
</collectionViewCell>
</objects>
</document>

View file

@ -0,0 +1,84 @@
/*
Copyright 2019 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 UIKit
import Reusable
final class RoomReactionImageViewCell: UICollectionViewCell, NibReusable, Themable {
// MARK: - Constants
// MARK: - Properties
// MARK: Outlets
@IBOutlet private weak var reactionBackgroundView: UIView!
@IBOutlet private weak var imageView: UIImageView!
// MARK: Private
private var theme: Theme?
// MARK: Public
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.reactionBackgroundView.layer.masksToBounds = true
}
override func layoutSubviews() {
super.layoutSubviews()
self.reactionBackgroundView.layer.cornerRadius = self.reactionBackgroundView.bounds.midY
}
// MARK: - Life cycle
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
/*
On iOS 12, there are issues with self-sizing cells as described in Apple release notes (https://developer.apple.com/documentation/ios_release_notes/ios_12_release_notes) :
"You might encounter issues with systemLayoutSizeFitting(_:) when using a UICollectionViewCell subclass that requires updateConstraints().
(42138227) Workaround: Don't call the cell's setNeedsUpdateConstraints() method unless you need to support live constraint changes.
If you need to support live constraint changes, call updateConstraintsIfNeeded() before calling systemLayoutSizeFitting(_:)."
*/
self.updateConstraintsIfNeeded()
return super.preferredLayoutAttributesFitting(layoutAttributes)
}
// MARK: - Public
func fill(actionIcon: UIImage) {
imageView.image = actionIcon.withRenderingMode(.alwaysTemplate)
self.updateViews()
}
func update(theme: Theme) {
self.theme = theme
self.updateViews()
}
// MARK: - Private
private func updateViews() {
self.imageView.tintColor = self.theme?.textSecondaryColor
self.reactionBackgroundView.layer.borderWidth = 0.0
self.reactionBackgroundView.backgroundColor = self.theme?.headerBackgroundColor
}
}

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="RoomReactionImageViewCell" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="36" height="22"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="36" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jjn-uq-kYN">
<rect key="frame" x="1" y="1" width="34" height="20"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="reactions_more_action" translatesAutoresizingMaskIntoConstraints="NO" id="gWS-UB-Zf1">
<rect key="frame" x="10" y="4" width="14" height="12"/>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="gWS-UB-Zf1" secondAttribute="trailing" constant="10" id="5NC-Dj-QXa"/>
<constraint firstItem="gWS-UB-Zf1" firstAttribute="top" secondItem="jjn-uq-kYN" secondAttribute="top" constant="4" id="91m-qv-rXG"/>
<constraint firstItem="gWS-UB-Zf1" firstAttribute="leading" secondItem="jjn-uq-kYN" secondAttribute="leading" constant="10" id="S70-6f-4Bu"/>
<constraint firstAttribute="bottom" secondItem="gWS-UB-Zf1" secondAttribute="bottom" constant="4" id="qbj-YU-fJJ"/>
</constraints>
</view>
</subviews>
</view>
<viewLayoutGuide key="safeArea" id="ZTg-uK-7eu"/>
<constraints>
<constraint firstItem="jjn-uq-kYN" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" constant="1" id="E5H-9a-us9"/>
<constraint firstAttribute="bottom" secondItem="jjn-uq-kYN" secondAttribute="bottom" constant="1" id="Ggm-1f-3EB"/>
<constraint firstItem="jjn-uq-kYN" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="1" id="iT6-rk-qd6"/>
<constraint firstAttribute="trailing" secondItem="jjn-uq-kYN" secondAttribute="trailing" constant="1" id="ztM-7J-Dnf"/>
</constraints>
<size key="customSize" width="413" height="170"/>
<connections>
<outlet property="imageView" destination="gWS-UB-Zf1" id="gqb-hn-Q4X"/>
<outlet property="reactionBackgroundView" destination="jjn-uq-kYN" id="vKf-Un-6PZ"/>
</connections>
<point key="canvasLocation" x="-478.26086956521743" y="-207.58928571428569"/>
</collectionViewCell>
</objects>
<resources>
<image name="reactions_more_action" width="14.5" height="14"/>
</resources>
</document>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>

View file

@ -17,9 +17,9 @@
import Foundation
import MatrixSDK
import Reusable
import DGCollectionViewLeftAlignFlowLayout
import UIKit
import UICollectionViewRightAlignedLayout
import UICollectionViewLeftAlignedLayout
/// RoomReactionsView items alignment
enum RoomReactionsViewAlignment {
@ -46,7 +46,9 @@ final class RoomReactionsView: UIView, NibOwnerLoadable {
// MARK: Private
private var reactionsViewData: [RoomReactionViewData] = []
private var remainingViewData: [RoomReactionViewData] = []
private var showAllButtonState: RoomReactionsViewState.ShowAllButtonState = .none
private var showAddReaction: Bool = false
private var theme: Theme?
// MARK: Public
@ -105,6 +107,7 @@ final class RoomReactionsView: UIView, NibOwnerLoadable {
self.collectionView.register(cellType: RoomReactionViewCell.self)
self.collectionView.register(cellType: RoomReactionActionViewCell.self)
self.collectionView.register(cellType: RoomReactionImageViewCell.self)
self.collectionView.reloadData()
}
@ -130,7 +133,7 @@ final class RoomReactionsView: UIView, NibOwnerLoadable {
switch alignment {
case .left:
collectionViewLayout = DGCollectionViewLeftAlignFlowLayout()
collectionViewLayout = UICollectionViewLeftAlignedLayout()
case .right:
collectionViewLayout = UICollectionViewRightAlignedLayout()
}
@ -151,22 +154,28 @@ final class RoomReactionsView: UIView, NibOwnerLoadable {
self.viewModel?.process(viewAction: .longPress)
}
private func fill(reactionsViewData: [RoomReactionViewData], showAllButtonState: RoomReactionsViewState.ShowAllButtonState) {
private func fill(reactionsViewData: [RoomReactionViewData], remainingViewData: [RoomReactionViewData], showAllButtonState: RoomReactionsViewState.ShowAllButtonState, showAddReaction: Bool) {
self.reactionsViewData = reactionsViewData
self.remainingViewData = remainingViewData
self.showAllButtonState = showAllButtonState
self.showAddReaction = showAddReaction
self.collectionView.reloadData()
self.collectionView.collectionViewLayout.invalidateLayout()
}
private func actionButtonString() -> String {
private func actionButtonString(at indexPath: IndexPath) -> String {
let actionString: String
switch self.showAllButtonState {
case .showAll:
actionString = VectorL10n.roomEventActionReactionShowAll
case .showLess:
actionString = VectorL10n.roomEventActionReactionShowLess
case .none:
actionString = ""
if indexPath.row == self.reactionsViewData.count && self.showAllButtonState != .none {
switch self.showAllButtonState {
case .showAll:
actionString = VectorL10n.roomEventActionReactionMore("\(remainingViewData.count)")
case .showLess:
actionString = VectorL10n.roomEventActionReactionShowLess
case .none:
actionString = ""
}
} else {
actionString = VectorL10n.add.capitalized
}
return actionString
@ -178,7 +187,10 @@ extension RoomReactionsView: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// "Show all" or "Show less" is a cell in the same section as reactions cells
let additionalItems = self.showAllButtonState == .none ? 0 : 1
var additionalItems = self.showAllButtonState == .none ? 0 : 1
if self.showAddReaction {
additionalItems += 1
}
return self.reactionsViewData.count + additionalItems
}
@ -196,16 +208,29 @@ extension RoomReactionsView: UICollectionViewDataSource {
return cell
} else {
let cell: RoomReactionActionViewCell = collectionView.dequeueReusableCell(for: indexPath)
if indexPath.row == self.reactionsViewData.count && self.showAllButtonState != .none {
let cell: RoomReactionActionViewCell = collectionView.dequeueReusableCell(for: indexPath)
if let theme = self.theme {
cell.update(theme: theme)
if let theme = self.theme {
cell.update(theme: theme)
}
let actionString = self.actionButtonString(at: indexPath)
cell.fill(actionString: actionString)
return cell
} else {
let cell: RoomReactionImageViewCell = collectionView.dequeueReusableCell(for: indexPath)
if let theme = self.theme {
cell.update(theme: theme)
}
cell.fill(actionIcon: Asset.Images.reactionsMoreAction.image)
return cell
}
let actionString = self.actionButtonString()
cell.fill(actionString: actionString)
return cell
}
}
}
@ -217,13 +242,17 @@ extension RoomReactionsView: UICollectionViewDelegate {
if indexPath.row < self.reactionsViewData.count {
self.viewModel?.process(viewAction: .tapReaction(index: indexPath.row))
} else {
switch self.showAllButtonState {
case .showAll:
self.viewModel?.process(viewAction: .tapShowAction(action: .showAll))
case .showLess:
self.viewModel?.process(viewAction: .tapShowAction(action: .showLess))
case .none:
break
if indexPath.row == self.reactionsViewData.count && self.showAllButtonState != .none {
switch self.showAllButtonState {
case .showAll:
self.viewModel?.process(viewAction: .tapShowAction(action: .showAll))
case .showLess:
self.viewModel?.process(viewAction: .tapShowAction(action: .showLess))
case .none:
break
}
} else {
self.viewModel?.process(viewAction: .tapShowAction(action: .addReaction))
}
}
}
@ -234,8 +263,8 @@ extension RoomReactionsView: RoomReactionsViewModelViewDelegate {
func roomReactionsViewModel(_ viewModel: RoomReactionsViewModel, didUpdateViewState viewState: RoomReactionsViewState) {
switch viewState {
case .loaded(reactionsViewData: let reactionsViewData, showAllButtonState: let showAllButtonState):
self.fill(reactionsViewData: reactionsViewData, showAllButtonState: showAllButtonState)
case .loaded(reactionsViewData: let reactionsViewData, remainingViewData: let remainingViewData, showAllButtonState: let showAllButtonState, showAddReaction: let showAddReaction):
self.fill(reactionsViewData: reactionsViewData, remainingViewData: remainingViewData, showAllButtonState: showAllButtonState, showAddReaction: showAddReaction)
}
}
}

View file

@ -69,6 +69,8 @@ import Foundation
self.viewModelDelegate?.roomReactionsViewModel(self, didShowAllTappedForEventId: self.eventId)
case .tapShowAction(.showLess):
self.viewModelDelegate?.roomReactionsViewModel(self, didShowLessTappedForEventId: self.eventId)
case .tapShowAction(.addReaction):
self.viewModelDelegate?.roomReactionsViewModel(self, didTapAddReactionForEventId: self.eventId)
case .longPress:
self.viewModelDelegate?.roomReactionsViewModel(self, didLongPressForEventId: self.eventId)
}
@ -76,6 +78,10 @@ import Foundation
func loadData() {
var reactions = self.aggregatedReactions.reactions
.map { (reactionCount) -> RoomReactionViewData in
RoomReactionViewData(emoji: reactionCount.reaction, countString: "\(reactionCount.count)", isCurrentUserReacted: reactionCount.myUserHasReacted)
}
var remainingReactions: [RoomReactionViewData] = []
var showAllButtonState: RoomReactionsViewState.ShowAllButtonState = .none
// Limit displayed reactions if required
@ -83,16 +89,13 @@ import Foundation
if self.showAll == true {
showAllButtonState = .showLess
} else {
remainingReactions = Array(reactions[Constants.maxItemsWhenLimited..<reactions.count])
reactions = Array(reactions[0..<Constants.maxItemsWhenLimited])
showAllButtonState = .showAll
}
}
let reactionsViewData = reactions.map { (reactionCount) -> RoomReactionViewData in
return RoomReactionViewData(emoji: reactionCount.reaction, countString: "\(reactionCount.count)", isCurrentUserReacted: reactionCount.myUserHasReacted)
}
self.viewDelegate?.roomReactionsViewModel(self, didUpdateViewState: .loaded(reactionsViewData: reactionsViewData, showAllButtonState: showAllButtonState))
self.viewDelegate?.roomReactionsViewModel(self, didUpdateViewState: .loaded(reactionsViewData: reactions, remainingViewData: remainingReactions, showAllButtonState: showAllButtonState, showAddReaction: reactions.count > 0))
}
// MARK: - Hashable

View file

@ -26,11 +26,12 @@ enum RoomReactionsViewAction {
enum ShowAction {
case showAll
case showLess
case addReaction
}
}
enum RoomReactionsViewState {
case loaded(reactionsViewData: [RoomReactionViewData], showAllButtonState: ShowAllButtonState)
case loaded(reactionsViewData: [RoomReactionViewData], remainingViewData: [RoomReactionViewData], showAllButtonState: ShowAllButtonState, showAddReaction: Bool)
enum ShowAllButtonState {
case none
@ -44,6 +45,7 @@ enum RoomReactionsViewState {
func roomReactionsViewModel(_ viewModel: RoomReactionsViewModel, didRemoveReaction reactionCount: MXReactionCount, forEventId eventId: String)
func roomReactionsViewModel(_ viewModel: RoomReactionsViewModel, didShowAllTappedForEventId eventId: String)
func roomReactionsViewModel(_ viewModel: RoomReactionsViewModel, didShowLessTappedForEventId eventId: String)
func roomReactionsViewModel(_ viewModel: RoomReactionsViewModel, didTapAddReactionForEventId eventId: String)
func roomReactionsViewModel(_ viewModel: RoomReactionsViewModel, didLongPressForEventId eventId: String)
}

1
changelog.d/5370.change Normal file
View file

@ -0,0 +1 @@
Update Reactions component