mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-29 07:42:40 +00:00
Merge branch 'release/1.8.9/master'
This commit is contained in:
commit
751fe14ed3
28 changed files with 426 additions and 146 deletions
17
CHANGES.md
17
CHANGES.md
|
@ -1,3 +1,20 @@
|
|||
## Changes in 1.8.9 (2022-03-28)
|
||||
|
||||
🙌 Improvements
|
||||
|
||||
- Upgrade MatrixSDK version ([v0.23.1](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.23.1)).
|
||||
- Update suggested room preview to behave the same way in all cases ([#5771](https://github.com/vector-im/element-ios/issues/5771))
|
||||
- Add "Invite people" to the space menu in the left panel and update menu order ([#5810](https://github.com/vector-im/element-ios/issues/5810))
|
||||
|
||||
🐛 Bugfixes
|
||||
|
||||
- Sync Spaces order with web ([#5134](https://github.com/vector-im/element-ios/issues/5134))
|
||||
- Fixed "Add Space" error message ([#5797](https://github.com/vector-im/element-ios/issues/5797))
|
||||
- Authentication: Ensure the login button is always visible ([#5875](https://github.com/vector-im/element-ios/issues/5875))
|
||||
- Room: Fix typing performance by avoiding expensive UI operations ([#5906](https://github.com/vector-im/element-ios/issues/5906))
|
||||
- Push notifications: show space preview if user taps invite notification ([#5915](https://github.com/vector-im/element-ios/issues/5915))
|
||||
|
||||
|
||||
## Changes in 1.8.8 (2022-03-22)
|
||||
|
||||
✨ Features
|
||||
|
|
|
@ -15,5 +15,5 @@
|
|||
//
|
||||
|
||||
// Version
|
||||
MARKETING_VERSION = 1.8.8
|
||||
CURRENT_PROJECT_VERSION = 1.8.8
|
||||
MARKETING_VERSION = 1.8.9
|
||||
CURRENT_PROJECT_VERSION = 1.8.9
|
||||
|
|
2
Podfile
2
Podfile
|
@ -13,7 +13,7 @@ use_frameworks!
|
|||
# - `{ :specHash => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for MatrixSDK repo. Used by Fastfile during CI
|
||||
#
|
||||
# Warning: our internal tooling depends on the name of this variable name, so be sure not to change it
|
||||
$matrixSDKVersion = '= 0.23.0'
|
||||
$matrixSDKVersion = '= 0.23.1'
|
||||
# $matrixSDKVersion = :local
|
||||
# $matrixSDKVersion = { :branch => 'develop'}
|
||||
# $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } }
|
||||
|
|
16
Podfile.lock
16
Podfile.lock
|
@ -56,16 +56,16 @@ PODS:
|
|||
- LoggerAPI (1.9.200):
|
||||
- Logging (~> 1.1)
|
||||
- Logging (1.4.0)
|
||||
- MatrixSDK (0.23.0):
|
||||
- MatrixSDK/Core (= 0.23.0)
|
||||
- MatrixSDK/Core (0.23.0):
|
||||
- MatrixSDK (0.23.1):
|
||||
- MatrixSDK/Core (= 0.23.1)
|
||||
- MatrixSDK/Core (0.23.1):
|
||||
- AFNetworking (~> 4.0.0)
|
||||
- GZIP (~> 1.3.0)
|
||||
- libbase58 (~> 0.1.4)
|
||||
- OLMKit (~> 3.2.5)
|
||||
- Realm (= 10.16.0)
|
||||
- SwiftyBeaver (= 1.9.5)
|
||||
- MatrixSDK/JingleCallStack (0.23.0):
|
||||
- MatrixSDK/JingleCallStack (0.23.1):
|
||||
- JitsiMeetSDK (= 3.10.2)
|
||||
- MatrixSDK/Core
|
||||
- OLMKit (3.2.5):
|
||||
|
@ -115,8 +115,8 @@ DEPENDENCIES:
|
|||
- KeychainAccess (~> 4.2.2)
|
||||
- KTCenterFlowLayout (~> 1.3.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixSDK (= 0.23.0)
|
||||
- MatrixSDK/JingleCallStack (= 0.23.0)
|
||||
- MatrixSDK (= 0.23.1)
|
||||
- MatrixSDK/JingleCallStack (= 0.23.1)
|
||||
- OLMKit
|
||||
- PostHog (~> 1.4.4)
|
||||
- ReadMoreTextView (~> 3.0.1)
|
||||
|
@ -208,7 +208,7 @@ SPEC CHECKSUMS:
|
|||
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
|
||||
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
|
||||
Logging: beeb016c9c80cf77042d62e83495816847ef108b
|
||||
MatrixSDK: 5934f25944388513d7a379cd5e191a231ceed45f
|
||||
MatrixSDK: 54d16aa08f3043fb1bcf639ef1ac5c589100f39f
|
||||
OLMKit: 9fb4799c4a044dd2c06bda31ec31a12191ad30b5
|
||||
PostHog: 4b6321b521569092d4ef3a02238d9435dbaeb99f
|
||||
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
|
||||
|
@ -225,6 +225,6 @@ SPEC CHECKSUMS:
|
|||
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||
|
||||
PODFILE CHECKSUM: 426c919fd3f444aa747155bfcc20f9092573f1aa
|
||||
PODFILE CHECKSUM: 820f04e07aa252459ecfa88d04da729daca4fcbb
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
|
|
@ -36,3 +36,5 @@
|
|||
"onboarding_avatar_accessibility_label" = "Profile picture";
|
||||
|
||||
"image_picker_action_files" = "Choose from files";
|
||||
|
||||
"spaces_feature_not_available" = "This feature isn't available here. For now, you can do this with %@ on your computer.";
|
||||
|
|
|
@ -70,6 +70,10 @@ public extension VectorL10n {
|
|||
static var onboardingPersonalizationSkip: String {
|
||||
return VectorL10n.tr("Untranslated", "onboarding_personalization_skip")
|
||||
}
|
||||
/// 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
|
||||
|
||||
|
|
|
@ -108,10 +108,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@param pushNotificationService PushNotificationService object.
|
||||
@param roomId Room identifier to be navigated.
|
||||
@param userId ID of sender of the notification.
|
||||
*/
|
||||
- (void)pushNotificationService:(PushNotificationService *)pushNotificationService
|
||||
shouldNavigateToRoomWithId:(NSString *)roomId
|
||||
threadId:(nullable NSString *)threadId;
|
||||
threadId:(nullable NSString *)threadId
|
||||
sender:(nullable NSString *)userId;
|
||||
|
||||
@end;
|
||||
|
||||
|
|
|
@ -364,6 +364,7 @@ Matrix session observer used to detect new opened sessions.
|
|||
NSString *actionIdentifier = [response actionIdentifier];
|
||||
NSString *roomId = content.userInfo[@"room_id"];
|
||||
NSString *threadId = content.userInfo[@"thread_id"];
|
||||
NSString *userId = content.userInfo[@"user_id"];
|
||||
|
||||
if ([actionIdentifier isEqualToString:@"inline-reply"])
|
||||
{
|
||||
|
@ -403,7 +404,7 @@ Matrix session observer used to detect new opened sessions.
|
|||
}
|
||||
else if ([actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier])
|
||||
{
|
||||
[self notifyNavigateToRoomById:roomId threadId:threadId];
|
||||
[self notifyNavigateToRoomById:roomId threadId:threadId sender:userId];
|
||||
completionHandler();
|
||||
}
|
||||
else
|
||||
|
@ -567,11 +568,11 @@ Matrix session observer used to detect new opened sessions.
|
|||
|
||||
#pragma mark - Delegate Notifiers
|
||||
|
||||
- (void)notifyNavigateToRoomById:(NSString *)roomId threadId:(NSString *)threadId
|
||||
- (void)notifyNavigateToRoomById:(NSString *)roomId threadId:(NSString *)threadId sender:(NSString *)userId
|
||||
{
|
||||
if ([_delegate respondsToSelector:@selector(pushNotificationService:shouldNavigateToRoomWithId:threadId:)])
|
||||
if ([_delegate respondsToSelector:@selector(pushNotificationService:shouldNavigateToRoomWithId:threadId:sender:)])
|
||||
{
|
||||
[_delegate pushNotificationService:self shouldNavigateToRoomWithId:roomId threadId:threadId];
|
||||
[_delegate pushNotificationService:self shouldNavigateToRoomWithId:roomId threadId:threadId sender:userId];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1108,6 +1108,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
- (void)pushNotificationService:(PushNotificationService *)pushNotificationService
|
||||
shouldNavigateToRoomWithId:(NSString *)roomId
|
||||
threadId:(NSString *)threadId
|
||||
sender:(NSString *)userId
|
||||
{
|
||||
if (roomId)
|
||||
{
|
||||
|
@ -1123,7 +1124,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
}
|
||||
|
||||
_lastNavigatedRoomIdFromPush = roomId;
|
||||
[self navigateToRoomById:roomId threadId:threadId];
|
||||
[self navigateToRoomById:roomId threadId:threadId sender:userId];
|
||||
}
|
||||
|
||||
#pragma mark - Badge Count
|
||||
|
@ -2912,7 +2913,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
|
||||
#pragma mark - Matrix Rooms handling
|
||||
|
||||
- (void)navigateToRoomById:(NSString *)roomId threadId:(NSString *)threadId
|
||||
- (void)navigateToRoomById:(NSString *)roomId threadId:(NSString *)threadId sender:(NSString *)userId
|
||||
{
|
||||
if (roomId.length)
|
||||
{
|
||||
|
@ -2949,7 +2950,8 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
[self showRoom:roomId
|
||||
threadId:threadId
|
||||
andEventId:nil
|
||||
withMatrixSession:dedicatedAccount.mxSession];
|
||||
withMatrixSession:dedicatedAccount.mxSession
|
||||
sender:userId];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2967,7 +2969,6 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
{
|
||||
NSString *roomId = parameters.roomId;
|
||||
MXSession *mxSession = parameters.mxSession;
|
||||
BOOL restoreInitialDisplay = parameters.presentationParameters.restoreInitialDisplay;
|
||||
|
||||
if (roomId && mxSession)
|
||||
{
|
||||
|
@ -2978,21 +2979,38 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
[Analytics.shared trackViewRoom:room];
|
||||
}
|
||||
|
||||
// Indicates that spaces are not supported
|
||||
if (room.summary.roomType == MXRoomTypeSpace)
|
||||
if (!room)
|
||||
{
|
||||
|
||||
[self.spaceFeatureUnavailablePresenter presentUnavailableFeatureFrom:self.presentedViewController animated:YES];
|
||||
|
||||
if (completion)
|
||||
{
|
||||
completion();
|
||||
}
|
||||
MXWeakify(self);
|
||||
[mxSession.matrixRestClient roomSummaryWith:roomId via:@[] success:^(MXPublicRoom *room) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
if ([room.roomTypeString isEqualToString:MXRoomTypeStringSpace])
|
||||
{
|
||||
SpacePreviewNavigationParameters *spacePreviewNavigationParameters = [[SpacePreviewNavigationParameters alloc] initWithPublicRoom:room mxSession:mxSession senderId:parameters.senderId presentationParameters:parameters.presentationParameters];
|
||||
[self showSpacePreviewWithParameters:spacePreviewNavigationParameters];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self finaliseShowRoomWithParameters:parameters completion:completion];
|
||||
}
|
||||
} failure:^(NSError *error) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
[self finaliseShowRoomWithParameters:parameters completion:completion];
|
||||
}];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[self finaliseShowRoomWithParameters:parameters completion:completion];
|
||||
}
|
||||
|
||||
- (void)finaliseShowRoomWithParameters:(RoomNavigationParameters*)parameters completion:(void (^)(void))completion
|
||||
{
|
||||
NSString *roomId = parameters.roomId;
|
||||
BOOL restoreInitialDisplay = parameters.presentationParameters.restoreInitialDisplay;
|
||||
|
||||
void (^selectRoom)(void) = ^() {
|
||||
// Select room to display its details (dispatch this action in order to let TabBarController end its refresh)
|
||||
|
||||
|
@ -3021,10 +3039,10 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
|
||||
- (void)showRoom:(NSString*)roomId andEventId:(NSString*)eventId withMatrixSession:(MXSession*)mxSession
|
||||
{
|
||||
[self showRoom:roomId threadId:nil andEventId:eventId withMatrixSession:mxSession];
|
||||
[self showRoom:roomId threadId:nil andEventId:eventId withMatrixSession:mxSession sender:nil];
|
||||
}
|
||||
|
||||
- (void)showRoom:(NSString*)roomId threadId:(NSString*)threadId andEventId:(NSString*)eventId withMatrixSession:(MXSession*)mxSession
|
||||
- (void)showRoom:(NSString*)roomId threadId:(NSString*)threadId andEventId:(NSString*)eventId withMatrixSession:(MXSession*)mxSession sender:(NSString*)userId
|
||||
{
|
||||
// Ask to restore initial display
|
||||
ScreenPresentationParameters *presentationParameters = [[ScreenPresentationParameters alloc] initWithRestoreInitialDisplay:YES];
|
||||
|
@ -3038,6 +3056,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
RoomNavigationParameters *parameters = [[RoomNavigationParameters alloc] initWithRoomId:roomId
|
||||
eventId:eventId
|
||||
mxSession:mxSession
|
||||
senderId:userId
|
||||
threadParameters:threadParameters
|
||||
presentationParameters:presentationParameters];
|
||||
|
||||
|
@ -3097,6 +3116,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
|||
|
||||
void(^showSpace)(void) = ^{
|
||||
[self.spaceDetailPresenter presentForSpaceWithPublicRoom:parameters.publicRoom
|
||||
senderId:parameters.senderId
|
||||
from:presentingViewController
|
||||
sourceView:sourceView
|
||||
session:parameters.mxSession
|
||||
|
|
|
@ -58,6 +58,9 @@ class RoomNavigationParameters: NSObject {
|
|||
/// If `true`, the room settings screen will be initially displayed. Default `false`
|
||||
let showSettingsInitially: Bool
|
||||
|
||||
/// ID of the sender of the notification. Default `nil`
|
||||
let senderId: String?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(roomId: String,
|
||||
|
@ -71,6 +74,24 @@ class RoomNavigationParameters: NSObject {
|
|||
self.threadParameters = threadParameters
|
||||
self.presentationParameters = presentationParameters
|
||||
self.showSettingsInitially = false
|
||||
self.senderId = nil
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
init(roomId: String,
|
||||
eventId: String?,
|
||||
mxSession: MXSession,
|
||||
senderId: String?,
|
||||
threadParameters: ThreadParameters?,
|
||||
presentationParameters: ScreenPresentationParameters) {
|
||||
self.roomId = roomId
|
||||
self.eventId = eventId
|
||||
self.mxSession = mxSession
|
||||
self.threadParameters = threadParameters
|
||||
self.presentationParameters = presentationParameters
|
||||
self.showSettingsInitially = false
|
||||
self.senderId = senderId
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
@ -86,7 +107,8 @@ class RoomNavigationParameters: NSObject {
|
|||
self.presentationParameters = presentationParameters
|
||||
self.showSettingsInitially = showSettingsInitially
|
||||
self.threadParameters = nil
|
||||
|
||||
self.senderId = nil
|
||||
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,28 @@ class SpacePreviewNavigationParameters: SpaceNavigationParameters {
|
|||
/// The data for the room preview
|
||||
let publicRoom: MXPublicRoom
|
||||
|
||||
/// The ID of the sender of the invite
|
||||
let senderId: String?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(publicRoom: MXPublicRoom,
|
||||
mxSession: MXSession,
|
||||
presentationParameters: ScreenPresentationParameters) {
|
||||
self.publicRoom = publicRoom
|
||||
self.senderId = nil
|
||||
|
||||
super.init(roomId: publicRoom.roomId,
|
||||
mxSession: mxSession,
|
||||
presentationParameters: presentationParameters)
|
||||
}
|
||||
|
||||
init(publicRoom: MXPublicRoom,
|
||||
mxSession: MXSession,
|
||||
senderId: String?,
|
||||
presentationParameters: ScreenPresentationParameters) {
|
||||
self.publicRoom = publicRoom
|
||||
self.senderId = senderId
|
||||
|
||||
super.init(roomId: publicRoom.roomId,
|
||||
mxSession: mxSession,
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
@property (weak, nonatomic) IBOutlet UIButton *skipButton;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *forgotPasswordButton;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *submitButtonMinLeadingConstraint;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *serverOptionsContainer;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *customServersTickButton;
|
||||
@property (weak, nonatomic) IBOutlet UIView *customServersContainer;
|
||||
|
|
|
@ -1058,17 +1058,6 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
|
|||
}
|
||||
|
||||
self.forgotPasswordButton.hidden = !showForgotPasswordButton;
|
||||
|
||||
// Adjust minimum leading constraint of the submit button
|
||||
if (self.forgotPasswordButton.isHidden)
|
||||
{
|
||||
self.submitButtonMinLeadingConstraint.constant = 19;
|
||||
}
|
||||
else
|
||||
{
|
||||
CGRect frame = self.forgotPasswordButton.frame;
|
||||
self.submitButtonMinLeadingConstraint.constant = frame.origin.x + frame.size.width + 10;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)afterSetPinFlowCompletedWithCredentials:(MXCredentials*)credentials
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" 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="retina5_9" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
@ -44,7 +44,6 @@
|
|||
<outlet property="softLogoutClearDataContainer" destination="vX2-5Y-rQc" id="mgK-41-cnX"/>
|
||||
<outlet property="softLogoutClearDataLabel" destination="QYL-Lo-tmH" id="ks9-5X-xfs"/>
|
||||
<outlet property="submitButton" destination="k3J-Eg-itz" id="fiZ-wK-6YM"/>
|
||||
<outlet property="submitButtonMinLeadingConstraint" destination="bEB-EO-b14" id="Iz5-ks-nSX"/>
|
||||
<outlet property="view" destination="5rn-KE-plm" id="bFJ-yJ-vc0"/>
|
||||
<outlet property="welcomeImageView" destination="d8r-TX-pwX" id="vzD-zK-EeC"/>
|
||||
</connections>
|
||||
|
@ -91,7 +90,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Currently we do not support authentication flows defined by this homeserver" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="54b-4O-ip9" userLabel="noFlowLabel">
|
||||
<rect key="frame" x="28" y="8" width="319.33333333333331" height="33.666666666666664"/>
|
||||
<rect key="frame" x="28" y="8" width="319" height="33.666666666666664"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -129,63 +128,73 @@
|
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Gg0-TE-OGb">
|
||||
<rect key="frame" x="0.0" y="360" width="375" height="125"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" hasAttributedTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AJ2-lJ-NUq">
|
||||
<rect key="frame" x="19" y="33" width="122" height="30"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCForgotPasswordButton"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="1mr-dZ-KtP"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<attributedString key="attributedTitle">
|
||||
<fragment content="Forgot password?">
|
||||
<attributes>
|
||||
<color key="NSColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<font key="NSFont" size="15" name="HelveticaNeue"/>
|
||||
</attributes>
|
||||
</fragment>
|
||||
</attributedString>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="UVJ-Re-xe2"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wEJ-AF-rdH">
|
||||
<rect key="frame" x="11" y="33" width="106" height="30"/>
|
||||
<color key="backgroundColor" red="0.028153735480000001" green="0.82494870580000002" blue="0.051896891280000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCSkipButton"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="HIX-iq-vTC"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
|
||||
<inset key="contentEdgeInsets" minX="30" minY="0.0" maxX="30" maxY="0.0"/>
|
||||
<state key="normal" title="Skip">
|
||||
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="iEr-Vf-f6P"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="k3J-Eg-itz" userLabel="SubmitBtn">
|
||||
<rect key="frame" x="258" y="33" width="106" height="30"/>
|
||||
<color key="backgroundColor" red="0.028153735480000001" green="0.82494870580000002" blue="0.051896891280000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCLoginButton"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="3ST-q4-gu8"/>
|
||||
<constraint firstAttribute="height" constant="30" id="rR8-KH-2z5"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
|
||||
<inset key="contentEdgeInsets" minX="30" minY="0.0" maxX="30" maxY="0.0"/>
|
||||
<state key="normal" title="Log In">
|
||||
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="Ocd-Ag-6hf"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FIn-2w-e6H">
|
||||
<rect key="frame" x="0.0" y="68" width="375" height="178"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="7OO-nL-hff">
|
||||
<rect key="frame" x="11" y="33" width="353" height="65"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillProportionally" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="Oeh-7N-HNr">
|
||||
<rect key="frame" x="0.0" y="0.0" width="106" height="30"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="k3J-Eg-itz" userLabel="SubmitBtn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="106" height="30"/>
|
||||
<color key="backgroundColor" red="0.028153735480000001" green="0.82494870580000002" blue="0.051896891280000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCLoginButton"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="BPY-Sb-k8F"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="L9J-9d-puh"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
|
||||
<inset key="contentEdgeInsets" minX="30" minY="0.0" maxX="30" maxY="0.0"/>
|
||||
<state key="normal" title="Log In">
|
||||
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="Ocd-Ag-6hf"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wEJ-AF-rdH">
|
||||
<rect key="frame" x="0.0" y="0.0" width="0.0" height="30"/>
|
||||
<color key="backgroundColor" red="0.028153735480000001" green="0.82494870580000002" blue="0.051896891280000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCSkipButton"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
|
||||
<inset key="contentEdgeInsets" minX="30" minY="0.0" maxX="30" maxY="0.0"/>
|
||||
<state key="normal" title="Skip">
|
||||
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="iEr-Vf-f6P"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="k3J-Eg-itz" firstAttribute="height" secondItem="wEJ-AF-rdH" secondAttribute="height" id="hhT-7b-PVV"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" hasAttributedTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AJ2-lJ-NUq">
|
||||
<rect key="frame" x="0.0" y="35" width="122" height="30"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCForgotPasswordButton"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="1mr-dZ-KtP"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<attributedString key="attributedTitle">
|
||||
<fragment content="Forgot password?">
|
||||
<attributes>
|
||||
<color key="NSColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<font key="NSFont" size="15" name="HelveticaNeue"/>
|
||||
</attributes>
|
||||
</fragment>
|
||||
</attributedString>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="UVJ-Re-xe2"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FIn-2w-e6H" userLabel="Server Options">
|
||||
<rect key="frame" x="0.0" y="103" width="375" height="178"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" hasAttributedTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6yx-o1-vbD">
|
||||
<rect key="frame" x="19" y="5" width="337" height="30"/>
|
||||
|
@ -333,8 +342,8 @@
|
|||
<constraint firstAttribute="trailing" secondItem="6yx-o1-vbD" secondAttribute="trailing" constant="19" id="rWk-Mp-KPS"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vX2-5Y-rQc">
|
||||
<rect key="frame" x="0.0" y="96" width="375" height="170"/>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vX2-5Y-rQc" userLabel="Soft Logout">
|
||||
<rect key="frame" x="0.0" y="148" width="375" height="170"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QYL-Lo-tmH">
|
||||
<rect key="frame" x="10" y="0.0" width="355" height="121"/>
|
||||
|
@ -384,21 +393,16 @@ Clear it if you're finished using this device, or want to sign in to another acc
|
|||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCOptionsContainer"/>
|
||||
<constraints>
|
||||
<constraint firstItem="FIn-2w-e6H" firstAttribute="leading" secondItem="Gg0-TE-OGb" secondAttribute="leading" id="3G8-Tb-KaN"/>
|
||||
<constraint firstItem="wEJ-AF-rdH" firstAttribute="width" secondItem="k3J-Eg-itz" secondAttribute="width" id="7sB-YJ-eX4"/>
|
||||
<constraint firstAttribute="trailing" secondItem="vX2-5Y-rQc" secondAttribute="trailing" id="DPh-Jx-WP1"/>
|
||||
<constraint firstItem="FIn-2w-e6H" firstAttribute="top" secondItem="7OO-nL-hff" secondAttribute="bottom" constant="5" id="Ilt-ab-dEa"/>
|
||||
<constraint firstItem="vX2-5Y-rQc" firstAttribute="top" secondItem="7OO-nL-hff" secondAttribute="bottom" constant="50" id="LTk-s1-SEs"/>
|
||||
<constraint firstItem="7OO-nL-hff" firstAttribute="leading" secondItem="Gg0-TE-OGb" secondAttribute="leading" constant="11" id="Otw-gC-R6C"/>
|
||||
<constraint firstItem="vX2-5Y-rQc" firstAttribute="top" secondItem="Gg0-TE-OGb" secondAttribute="top" priority="100" id="QSG-jB-VcV"/>
|
||||
<constraint firstItem="wEJ-AF-rdH" firstAttribute="centerY" secondItem="k3J-Eg-itz" secondAttribute="centerY" id="Vze-EI-oXj"/>
|
||||
<constraint firstAttribute="trailing" secondItem="k3J-Eg-itz" secondAttribute="trailing" constant="11" id="ZyA-Tq-Sfq"/>
|
||||
<constraint firstItem="k3J-Eg-itz" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Gg0-TE-OGb" secondAttribute="leading" constant="150" id="bEB-EO-b14"/>
|
||||
<constraint firstItem="vX2-5Y-rQc" firstAttribute="top" secondItem="k3J-Eg-itz" secondAttribute="bottom" constant="33" id="db7-2y-vPZ"/>
|
||||
<constraint firstItem="AJ2-lJ-NUq" firstAttribute="centerY" secondItem="k3J-Eg-itz" secondAttribute="centerY" id="dcE-Vs-7Rt"/>
|
||||
<constraint firstItem="7OO-nL-hff" firstAttribute="top" secondItem="Gg0-TE-OGb" secondAttribute="top" constant="33" id="e4H-ld-bD7"/>
|
||||
<constraint firstAttribute="trailing" secondItem="FIn-2w-e6H" secondAttribute="trailing" id="kFj-6g-v3H"/>
|
||||
<constraint firstItem="vX2-5Y-rQc" firstAttribute="leading" secondItem="Gg0-TE-OGb" secondAttribute="leading" id="kYN-Lj-zYP"/>
|
||||
<constraint firstAttribute="height" priority="700" constant="300" id="lXv-gM-CjN"/>
|
||||
<constraint firstItem="k3J-Eg-itz" firstAttribute="top" secondItem="Gg0-TE-OGb" secondAttribute="top" constant="33" id="mor-t9-7Ke"/>
|
||||
<constraint firstItem="FIn-2w-e6H" firstAttribute="top" secondItem="k3J-Eg-itz" secondAttribute="bottom" constant="5" id="oTS-5o-MMW"/>
|
||||
<constraint firstItem="wEJ-AF-rdH" firstAttribute="leading" secondItem="Gg0-TE-OGb" secondAttribute="leading" constant="11" id="sax-RY-aOJ"/>
|
||||
<constraint firstItem="AJ2-lJ-NUq" firstAttribute="leading" secondItem="Gg0-TE-OGb" secondAttribute="leading" constant="19" id="xFm-Bs-yzw"/>
|
||||
<constraint firstAttribute="trailing" secondItem="7OO-nL-hff" secondAttribute="trailing" constant="11" id="pPK-AD-wiD"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TjK-XL-dQS">
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewControllerDataReadyNotification";
|
||||
|
||||
@interface RecentsViewController () <CreateRoomCoordinatorBridgePresenterDelegate, RoomsDirectoryCoordinatorBridgePresenterDelegate, RoomNotificationSettingsCoordinatorBridgePresenterDelegate, DialpadViewControllerDelegate, ExploreRoomCoordinatorBridgePresenterDelegate>
|
||||
@interface RecentsViewController () <CreateRoomCoordinatorBridgePresenterDelegate, RoomsDirectoryCoordinatorBridgePresenterDelegate, RoomNotificationSettingsCoordinatorBridgePresenterDelegate, DialpadViewControllerDelegate, ExploreRoomCoordinatorBridgePresenterDelegate, SpaceChildRoomDetailBridgePresenterDelegate>
|
||||
{
|
||||
// Tell whether a recents refresh is pending (suspended during editing mode).
|
||||
BOOL isRefreshPending;
|
||||
|
@ -83,6 +83,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
|
||||
@property (nonatomic, strong) RoomNotificationSettingsCoordinatorBridgePresenter *roomNotificationSettingsCoordinatorBridgePresenter;
|
||||
|
||||
@property (nonatomic, strong) SpaceChildRoomDetailBridgePresenter *spaceChildPresenter;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RecentsViewController
|
||||
|
@ -2170,18 +2172,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
[self showRoomWithRoomId:roomId inMatrixSession:matrixSession];
|
||||
}
|
||||
|
||||
- (void)recentListViewController:(MXKRecentListViewController *)recentListViewController didSelectSuggestedRoom:(MXSpaceChildInfo *)childInfo
|
||||
- (void)recentListViewController:(MXKRecentListViewController *)recentListViewController didSelectSuggestedRoom:(MXSpaceChildInfo *)childInfo from:(UIView* _Nullable)sourceView
|
||||
{
|
||||
Analytics.shared.joinedRoomTrigger = AnalyticsJoinedRoomTriggerSpaceHierarchy;
|
||||
|
||||
RoomPreviewData *previewData = [[RoomPreviewData alloc] initWithSpaceChildInfo:childInfo andSession:self.mainSession];
|
||||
[self startActivityIndicator];
|
||||
MXWeakify(self);
|
||||
[previewData peekInRoom:^(BOOL succeeded) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
[self stopActivityIndicator];
|
||||
[self showRoomPreviewWithData:previewData];
|
||||
}];
|
||||
self.spaceChildPresenter = [[SpaceChildRoomDetailBridgePresenter alloc] initWithSession:self.mainSession childInfo:childInfo];
|
||||
self.spaceChildPresenter.delegate = self;
|
||||
[self.spaceChildPresenter presentFrom:self sourceView:sourceView animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - UISearchBarDelegate
|
||||
|
@ -2432,6 +2429,23 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
|||
self.roomNotificationSettingsCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
||||
#pragma mark - SpaceChildRoomDetailBridgePresenterDelegate
|
||||
- (void)spaceChildRoomDetailBridgePresenterDidCancel:(SpaceChildRoomDetailBridgePresenter *)coordinator
|
||||
{
|
||||
[self.spaceChildPresenter dismissWithAnimated:YES completion:^{
|
||||
self.spaceChildPresenter = nil;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)spaceChildRoomDetailBridgePresenter:(SpaceChildRoomDetailBridgePresenter *)coordinator didOpenRoomWith:(NSString *)roomId
|
||||
{
|
||||
[self showRoomWithRoomId:roomId inMatrixSession:self.mainSession];
|
||||
|
||||
[self.spaceChildPresenter dismissWithAnimated:YES completion:^{
|
||||
self.spaceChildPresenter = nil;
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Activity Indicator
|
||||
|
||||
- (BOOL)providesCustomActivityIndicator {
|
||||
|
|
|
@ -605,7 +605,8 @@
|
|||
if (renderedCellData.isSuggestedRoom)
|
||||
{
|
||||
[self.delegate recentListViewController:self
|
||||
didSelectSuggestedRoom:renderedCellData.roomSummary.spaceChildInfo];
|
||||
didSelectSuggestedRoom:renderedCellData.roomSummary.spaceChildInfo
|
||||
from:roomCollectionViewCell];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -41,8 +41,9 @@ limitations under the License.
|
|||
|
||||
@param recentListViewController the `MXKRecentListViewController` instance.
|
||||
@param childInfo the `MXSpaceChildInfo` instance that describes the selected room.
|
||||
@param sourceView the view the modal has to be presented from.
|
||||
*/
|
||||
-(void)recentListViewController:(MXKRecentListViewController *)recentListViewController didSelectSuggestedRoom:(MXSpaceChildInfo *)childInfo;
|
||||
-(void)recentListViewController:(MXKRecentListViewController *)recentListViewController didSelectSuggestedRoom:(MXSpaceChildInfo *)childInfo from:(UIView* _Nullable)sourceView;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -442,7 +442,8 @@
|
|||
if (recentCellData.isSuggestedRoom)
|
||||
{
|
||||
[_delegate recentListViewController:self
|
||||
didSelectSuggestedRoom:recentCellData.roomSummary.spaceChildInfo];
|
||||
didSelectSuggestedRoom:recentCellData.roomSummary.spaceChildInfo
|
||||
from:selectedCell];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1043,6 +1043,10 @@
|
|||
|
||||
- (void)setRoomTitleViewClass:(Class)roomTitleViewClass
|
||||
{
|
||||
if ([self.titleView.class isEqual:roomTitleViewClass]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanity check: accept only MXKRoomTitleView classes or sub-classes
|
||||
NSParameterAssert([roomTitleViewClass isSubclassOfClass:MXKRoomTitleView.class]);
|
||||
|
||||
|
|
|
@ -162,6 +162,9 @@ static CGSize kThreadListBarButtonItemImageSize;
|
|||
// A flag indicating whether a room has been left
|
||||
BOOL isRoomLeft;
|
||||
|
||||
// The last known frame of the view used to detect whether size-related layout change is needed
|
||||
CGRect lastViewBounds;
|
||||
|
||||
// Tell whether the room has a Jitsi call or not.
|
||||
BOOL hasJitsiCall;
|
||||
|
||||
|
@ -225,7 +228,7 @@ static CGSize kThreadListBarButtonItemImageSize;
|
|||
// When layout of the screen changes (e.g. height), we no longer know whether
|
||||
// to autoscroll to the bottom again or not. Instead we need to capture the
|
||||
// scroll state just before the layout change, and restore it after the layout.
|
||||
@property (nonatomic) BOOL shouldScrollToBottomAfterLayout;
|
||||
@property (nonatomic) BOOL wasScrollAtBottomBeforeLayout;
|
||||
|
||||
/// Handles all banners that should be displayed at the top of the timeline but that should not scroll with the timeline
|
||||
@property (weak, nonatomic, nullable) IBOutlet UIStackView *topBannersStackView;
|
||||
|
@ -694,12 +697,14 @@ static CGSize kThreadListBarButtonItemImageSize;
|
|||
|
||||
- (void)viewWillLayoutSubviews {
|
||||
[super viewWillLayoutSubviews];
|
||||
self.shouldScrollToBottomAfterLayout = self.isBubblesTableScrollViewAtTheBottom;
|
||||
self.wasScrollAtBottomBeforeLayout = self.isBubblesTableScrollViewAtTheBottom;
|
||||
}
|
||||
|
||||
- (void)viewDidLayoutSubviews
|
||||
{
|
||||
[super viewDidLayoutSubviews];
|
||||
BOOL didViewChangeBounds = !CGRectEqualToRect(lastViewBounds, self.view.bounds);
|
||||
lastViewBounds = self.view.bounds;
|
||||
|
||||
UIEdgeInsets contentInset = self.bubblesTableView.contentInset;
|
||||
contentInset.bottom = self.view.safeAreaInsets.bottom;
|
||||
|
@ -763,9 +768,9 @@ static CGSize kThreadListBarButtonItemImageSize;
|
|||
}
|
||||
|
||||
// re-scroll to the bottom, if at bottom before the most recent layout
|
||||
if (self.shouldScrollToBottomAfterLayout)
|
||||
if (self.wasScrollAtBottomBeforeLayout && didViewChangeBounds)
|
||||
{
|
||||
self.shouldScrollToBottomAfterLayout = NO;
|
||||
self.wasScrollAtBottomBeforeLayout = NO;
|
||||
[self scrollBubblesTableViewToBottomAnimated:NO];
|
||||
}
|
||||
|
||||
|
@ -1378,6 +1383,10 @@ static CGSize kThreadListBarButtonItemImageSize;
|
|||
|
||||
- (void)setRoomTitleViewClass:(Class)roomTitleViewClass
|
||||
{
|
||||
if ([self.titleView.class isEqual:roomTitleViewClass]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanity check: accept only MXKRoomTitleView classes or sub-classes
|
||||
NSParameterAssert([roomTitleViewClass isSubclassOfClass:MXKRoomTitleView.class]);
|
||||
|
||||
|
|
|
@ -320,6 +320,36 @@ final class SideMenuCoordinator: NSObject, SideMenuCoordinatorType {
|
|||
self.spaceSettingsCoordinator = coordinator
|
||||
}
|
||||
|
||||
func showSpaceInvite(spaceId: String, session: MXSession) {
|
||||
guard let space = session.spaceService.getSpace(withId: spaceId), let spaceRoom = space.room else {
|
||||
MXLog.error("[SideMenuCoordinator] showSpaceInvite: failed to find space with id \(spaceId)")
|
||||
return
|
||||
}
|
||||
|
||||
spaceRoom.state { [weak self] roomState in
|
||||
guard let self = self else { return }
|
||||
|
||||
guard let powerLevels = roomState?.powerLevels, let userId = session.myUserId else {
|
||||
MXLog.error("[SpaceMembersCoordinator] spaceMemberListCoordinatorShowInvite: failed to find powerLevels for room")
|
||||
return
|
||||
}
|
||||
let userPowerLevel = powerLevels.powerLevelOfUser(withUserID: userId)
|
||||
|
||||
guard userPowerLevel >= powerLevels.invite else {
|
||||
let alert = UIAlertController(title: VectorL10n.spacesInvitePeople, message: VectorL10n.spaceInviteNotEnoughPermission, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: VectorL10n.ok, style: .default, handler: nil))
|
||||
self.sideMenuViewController.present(alert, animated: true)
|
||||
return
|
||||
}
|
||||
|
||||
let coordinator = ContactsPickerCoordinator(session: session, room: spaceRoom, initialSearchText: nil, actualParticipants: nil, invitedParticipants: nil, userParticipant: nil)
|
||||
coordinator.delegate = self
|
||||
coordinator.start()
|
||||
self.add(childCoordinator: coordinator)
|
||||
self.sideMenuViewController.present(coordinator.toPresentable(), animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
private func resetExploringSpaceIfNeeded() {
|
||||
if sideMenuNavigationViewController.presentedViewController == nil {
|
||||
Analytics.shared.exploringSpace = nil
|
||||
|
@ -430,13 +460,15 @@ extension SideMenuCoordinator: SpaceMenuPresenterDelegate {
|
|||
}
|
||||
}
|
||||
case .addSpace:
|
||||
AppDelegate.theDelegate().showAlert(withTitle: VectorL10n.spacesAddSpace, message: VectorL10n.spacesComingSoonDetail(AppInfo.current.displayName))
|
||||
AppDelegate.theDelegate().showAlert(withTitle: VectorL10n.spacesAddSpace, message: VectorL10n.spacesFeatureNotAvailable(AppInfo.current.displayName))
|
||||
case .settings:
|
||||
if #available(iOS 14.0, *) {
|
||||
self.showSpaceSettings(spaceId: spaceId, session: session)
|
||||
} else {
|
||||
AppDelegate.theDelegate().showAlert(withTitle: VectorL10n.settingsTitle, message: VectorL10n.spacesComingSoonDetail(AppInfo.current.displayName))
|
||||
AppDelegate.theDelegate().showAlert(withTitle: VectorL10n.settingsTitle, message: VectorL10n.spacesFeatureNotAvailable(AppInfo.current.displayName))
|
||||
}
|
||||
case .invite:
|
||||
self.showSpaceInvite(spaceId: spaceId, session: session)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -511,6 +543,19 @@ extension SideMenuCoordinator: CreateRoomCoordinatorDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - ContactsPickerCoordinatorDelegate
|
||||
extension SideMenuCoordinator: ContactsPickerCoordinatorDelegate {
|
||||
func contactsPickerCoordinatorDidStartLoading(_ coordinator: ContactsPickerCoordinatorProtocol) {
|
||||
}
|
||||
|
||||
func contactsPickerCoordinatorDidEndLoading(_ coordinator: ContactsPickerCoordinatorProtocol) {
|
||||
}
|
||||
|
||||
func contactsPickerCoordinatorDidClose(_ coordinator: ContactsPickerCoordinatorProtocol) {
|
||||
remove(childCoordinator: coordinator)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UIAdaptivePresentationControllerDelegate
|
||||
extension SideMenuCoordinator: UIAdaptivePresentationControllerDelegate {
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ class SpaceDetailPresenter: NSObject {
|
|||
}()
|
||||
private var session: MXSession!
|
||||
private var spaceId: String!
|
||||
private var senderId: String?
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
|
@ -59,15 +60,16 @@ class SpaceDetailPresenter: NSObject {
|
|||
self.show(with: session)
|
||||
}
|
||||
|
||||
@objc func present(forSpaceWithPublicRoom publicRoom: MXPublicRoom,
|
||||
@objc func present(forSpaceWithPublicRoom publicRoom: MXPublicRoom, senderId: String?,
|
||||
from viewController: UIViewController,
|
||||
sourceView: UIView?,
|
||||
session: MXSession,
|
||||
animated: Bool) {
|
||||
self.session = session
|
||||
self.spaceId = publicRoom.roomId
|
||||
self.senderId = senderId
|
||||
|
||||
self.viewModel = SpaceDetailViewModel(session: session, publicRoom: publicRoom)
|
||||
self.viewModel = SpaceDetailViewModel(session: session, publicRoom: publicRoom, senderId: senderId)
|
||||
self.viewModel.coordinatorDelegate = self
|
||||
self.presentingViewController = viewController
|
||||
self.sourceView = sourceView
|
||||
|
|
|
@ -26,6 +26,7 @@ class SpaceDetailViewModel: SpaceDetailViewModelType {
|
|||
|
||||
private let session: MXSession
|
||||
private let spaceId: String
|
||||
private let senderId: String?
|
||||
private let publicRoom: MXPublicRoom?
|
||||
private var spaceGraphObserver: Any?
|
||||
|
||||
|
@ -35,12 +36,14 @@ class SpaceDetailViewModel: SpaceDetailViewModelType {
|
|||
self.session = session
|
||||
self.spaceId = spaceId
|
||||
self.publicRoom = nil
|
||||
self.senderId = nil
|
||||
}
|
||||
|
||||
init(session: MXSession, publicRoom: MXPublicRoom) {
|
||||
init(session: MXSession, publicRoom: MXPublicRoom, senderId: String?) {
|
||||
self.session = session
|
||||
self.publicRoom = publicRoom
|
||||
self.spaceId = publicRoom.roomId
|
||||
self.senderId = senderId
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
@ -76,14 +79,21 @@ class SpaceDetailViewModel: SpaceDetailViewModelType {
|
|||
|
||||
private func loadData() {
|
||||
if let publicRoom = self.publicRoom {
|
||||
let sender: MXUser?
|
||||
if let senderId = self.senderId {
|
||||
sender = session.user(withUserId: senderId)
|
||||
} else {
|
||||
sender = nil
|
||||
}
|
||||
|
||||
self.update(viewState: .loaded(SpaceDetailLoadedParameters(spaceId: publicRoom.roomId,
|
||||
displayName: publicRoom.displayname(),
|
||||
topic: publicRoom.topic,
|
||||
avatarUrl: publicRoom.avatarUrl,
|
||||
joinRule: publicRoom.worldReadable ? .public : .private,
|
||||
membership: .unknown,
|
||||
inviterId: nil,
|
||||
inviter: nil,
|
||||
membership: self.senderId != nil ? .invite : .unknown,
|
||||
inviterId: self.senderId,
|
||||
inviter: sender,
|
||||
membersCount: UInt(publicRoom.numJoinedMembers))))
|
||||
} else {
|
||||
guard let space = self.session.spaceService.getSpace(withId: self.spaceId), let summary = space.summary else {
|
||||
|
|
|
@ -184,7 +184,7 @@ final class SpaceListViewModel: SpaceListViewModelType {
|
|||
var index = 0
|
||||
for itemViewData in viewDataList {
|
||||
if itemViewData.spaceId == self.selectedItemId {
|
||||
newSelection = IndexPath(row: index, section: sections.count - 1)
|
||||
newSelection = IndexPath(row: index, section: spacesSectionIndex)
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ enum SpaceMenuListItemAction {
|
|||
case addSpace
|
||||
case settings
|
||||
case leaveSpace
|
||||
case invite
|
||||
}
|
||||
|
||||
/// Style of the `SpaceMenuListViewCell`
|
||||
|
|
|
@ -27,6 +27,7 @@ class SpaceMenuPresenter: NSObject {
|
|||
case addRoom
|
||||
case addSpace
|
||||
case settings
|
||||
case invite
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
@ -117,6 +118,8 @@ extension SpaceMenuPresenter: SpaceMenuModelViewModelCoordinatorDelegate {
|
|||
self.delegate?.spaceMenuPresenter(self, didCompleteWith: .addSpace, forSpaceWithId: self.spaceId, with: self.session)
|
||||
case .settings:
|
||||
self.delegate?.spaceMenuPresenter(self, didCompleteWith: .settings, forSpaceWithId: self.spaceId, with: self.session)
|
||||
case .invite:
|
||||
self.delegate?.spaceMenuPresenter(self, didCompleteWith: .invite, forSpaceWithId: self.spaceId, with: self.session)
|
||||
default:
|
||||
MXLog.error("[SpaceMenuPresenter] spaceListViewModel didSelectItem: invalid action \(action)")
|
||||
}
|
||||
|
|
|
@ -25,11 +25,12 @@ class SpaceMenuViewModel: SpaceMenuViewModelType {
|
|||
weak var viewDelegate: SpaceMenuViewModelViewDelegate?
|
||||
|
||||
private let spaceMenuItems: [SpaceMenuListItemViewData] = [
|
||||
SpaceMenuListItemViewData(action: .exploreSpaceMembers, style: .normal, title: VectorL10n.roomDetailsPeople, icon: Asset.Images.spaceMenuMembers.image, value: nil),
|
||||
SpaceMenuListItemViewData(action: .invite, style: .normal, title: VectorL10n.spacesInvitePeople, icon: Asset.Images.spaceInviteUser.image, value: nil),
|
||||
SpaceMenuListItemViewData(action: .exploreSpaceRooms, style: .normal, title: VectorL10n.spacesExploreRooms, icon: Asset.Images.spaceMenuRooms.image, value: nil),
|
||||
SpaceMenuListItemViewData(action: .exploreSpaceMembers, style: .normal, title: VectorL10n.roomDetailsPeople, icon: Asset.Images.spaceMenuMembers.image, value: nil),
|
||||
SpaceMenuListItemViewData(action: .settings, style: .normal, title: VectorL10n.sideMenuActionSettings, icon: Asset.Images.sideMenuActionIconSettings.image, value: nil),
|
||||
SpaceMenuListItemViewData(action: .addRoom, style: .normal, title: VectorL10n.spacesAddRoom, icon: Asset.Images.spaceMenuPlusIcon.image, value: nil),
|
||||
SpaceMenuListItemViewData(action: .addSpace, style: .normal, title: VectorL10n.spacesAddSpace, icon: Asset.Images.spaceMenuPlusIcon.image, value: nil, isBeta: true),
|
||||
SpaceMenuListItemViewData(action: .settings, style: .normal, title: VectorL10n.sideMenuActionSettings, icon: Asset.Images.sideMenuActionIconSettings.image, value: nil),
|
||||
SpaceMenuListItemViewData(action: .leaveSpace, style: .destructive, title: VectorL10n.leave, icon: Asset.Images.spaceMenuLeave.image, value: nil)
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright 2021 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
|
||||
|
||||
@objc protocol SpaceChildRoomDetailBridgePresenterDelegate {
|
||||
func spaceChildRoomDetailBridgePresenter(_ coordinator: SpaceChildRoomDetailBridgePresenter, didOpenRoomWith roomId: String)
|
||||
func spaceChildRoomDetailBridgePresenterDidCancel(_ coordinator: SpaceChildRoomDetailBridgePresenter)
|
||||
}
|
||||
|
||||
/// SpaceChildRoomDetailBridgePresenter enables to start SpaceChildRoomDetailCoordinator from a view controller.
|
||||
/// This bridge is used while waiting for global usage of coordinator pattern.
|
||||
/// It breaks the Coordinator abstraction and it has been introduced for Objective-C compatibility (mainly for integration in legacy view controllers). Each bridge should be removed once the underlying Coordinator has
|
||||
/// been integrated by another Coordinator.
|
||||
@objcMembers
|
||||
final class SpaceChildRoomDetailBridgePresenter: NSObject {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let session: MXSession
|
||||
private let childInfo: MXSpaceChildInfo
|
||||
private var coordinator: SpaceChildRoomDetailCoordinator?
|
||||
private lazy var slidingModalPresenter: SlidingModalPresenter = {
|
||||
return SlidingModalPresenter()
|
||||
}()
|
||||
|
||||
// MARK: Public
|
||||
|
||||
weak var delegate: SpaceChildRoomDetailBridgePresenterDelegate?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(session: MXSession, childInfo: MXSpaceChildInfo) {
|
||||
self.session = session
|
||||
self.childInfo = childInfo
|
||||
super.init()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
// NOTE: Default value feature is not compatible with Objective-C.
|
||||
// func present(from viewController: UIViewController, animated: Bool) {
|
||||
// self.present(from: viewController, animated: animated)
|
||||
// }
|
||||
|
||||
func present(from viewController: UIViewController, sourceView: UIView?, animated: Bool) {
|
||||
let coordinator = SpaceChildRoomDetailCoordinator(parameters: SpaceChildRoomDetailCoordinatorParameters(session: session, childInfo: childInfo))
|
||||
coordinator.delegate = self
|
||||
coordinator.start()
|
||||
|
||||
self.coordinator = coordinator
|
||||
|
||||
if UIDevice.current.isPhone || sourceView == nil {
|
||||
slidingModalPresenter.present(coordinator.toSlidingPresentable(), from: viewController, animated: animated, completion: nil)
|
||||
} else {
|
||||
let presentable = coordinator.toPresentable()
|
||||
presentable.modalPresentationStyle = .popover
|
||||
if let sourceView = sourceView, let popoverPresentationController = presentable.popoverPresentationController {
|
||||
popoverPresentationController.sourceView = sourceView
|
||||
popoverPresentationController.sourceRect = sourceView.bounds
|
||||
}
|
||||
|
||||
viewController.present(presentable, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
func dismiss(animated: Bool, completion: (() -> Void)?) {
|
||||
guard let coordinator = self.coordinator else {
|
||||
return
|
||||
}
|
||||
coordinator.toPresentable().dismiss(animated: animated) {
|
||||
self.coordinator = nil
|
||||
|
||||
if let completion = completion {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SpaceChildRoomDetailCoordinatorDelegate
|
||||
extension SpaceChildRoomDetailBridgePresenter: SpaceChildRoomDetailCoordinatorDelegate {
|
||||
func spaceChildRoomDetailCoordinator(_ coordinator: SpaceChildRoomDetailCoordinatorType, didOpenRoomWith roomId: String) {
|
||||
delegate?.spaceChildRoomDetailBridgePresenter(self, didOpenRoomWith: roomId)
|
||||
}
|
||||
|
||||
func spaceChildRoomDetailCoordinatorDidCancel(_ coordinator: SpaceChildRoomDetailCoordinatorType) {
|
||||
delegate?.spaceChildRoomDetailBridgePresenterDidCancel(self)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UIAdaptivePresentationControllerDelegate
|
||||
extension SpaceChildRoomDetailBridgePresenter: UIAdaptivePresentationControllerDelegate {
|
||||
|
||||
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
|
||||
delegate?.spaceChildRoomDetailBridgePresenterDidCancel(self)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue