mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 15:22:39 +00:00
Implement FAB journeys & rough edge warnings element-ios#5226
- List of Space members with search - Invite interactions - Join room from list - Implement add room button, with rough edge warning.
This commit is contained in:
parent
60f071ee9b
commit
cf453feb02
27 changed files with 335 additions and 32 deletions
23
Riot/Assets/Images.xcassets/Spaces/space_add_room.imageset/Contents.json
vendored
Normal file
23
Riot/Assets/Images.xcassets/Spaces/space_add_room.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "space_add_room.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "space_add_room@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "space_add_room@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Spaces/space_add_room.imageset/space_add_room.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Spaces/space_add_room.imageset/space_add_room.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
Riot/Assets/Images.xcassets/Spaces/space_add_room.imageset/space_add_room@2x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Spaces/space_add_room.imageset/space_add_room@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
BIN
Riot/Assets/Images.xcassets/Spaces/space_add_room.imageset/space_add_room@3x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Spaces/space_add_room.imageset/space_add_room@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
26
Riot/Assets/Images.xcassets/Spaces/space_invite_user.imageset/Contents.json
vendored
Normal file
26
Riot/Assets/Images.xcassets/Spaces/space_invite_user.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "space_invite_user.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "space_invite_user@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "space_invite_user@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Spaces/space_invite_user.imageset/space_invite_user.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Spaces/space_invite_user.imageset/space_invite_user.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 496 B |
BIN
Riot/Assets/Images.xcassets/Spaces/space_invite_user.imageset/space_invite_user@2x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Spaces/space_invite_user.imageset/space_invite_user@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 865 B |
BIN
Riot/Assets/Images.xcassets/Spaces/space_invite_user.imageset/space_invite_user@3x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Spaces/space_invite_user.imageset/space_invite_user@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -268,6 +268,7 @@ Tap the + to start adding people.";
|
|||
"room_participants_remove_third_party_invite_prompt_msg" = "Are you sure you want to revoke this invite?";
|
||||
"room_participants_invite_prompt_title" = "Confirmation";
|
||||
"room_participants_invite_prompt_msg" = "Are you sure you want to invite %@ to this chat?";
|
||||
"room_participants_invite_prompt_to_msg" = "Are you sure you want to invite %@ to %@?";
|
||||
"room_participants_filter_room_members" = "Filter room members";
|
||||
"room_participants_filter_room_members_for_dm" = "Filter members";
|
||||
"room_participants_invite_another_user" = "Search / invite by User ID, Name or email";
|
||||
|
@ -1744,6 +1745,8 @@ Tap the + to start adding people.";
|
|||
|
||||
"space_private_join_rule" = "Private space";
|
||||
"space_public_join_rule" = "Public space";
|
||||
"spaces_invite_people" = "Invite people";
|
||||
"spaces_add_room" = "Add room";
|
||||
|
||||
// Mark: Avatar
|
||||
|
||||
|
|
|
@ -195,7 +195,9 @@ internal enum Asset {
|
|||
internal static let sideMenuNotifIcon = ImageAsset(name: "side_menu_notif_icon")
|
||||
internal static let featureUnavaibleArtwork = ImageAsset(name: "feature_unavaible_artwork")
|
||||
internal static let featureUnavaibleArtworkDark = ImageAsset(name: "feature_unavaible_artwork_dark")
|
||||
internal static let spaceAddRoom = ImageAsset(name: "space_add_room")
|
||||
internal static let spaceHomeIcon = ImageAsset(name: "space_home_icon")
|
||||
internal static let spaceInviteUser = ImageAsset(name: "space_invite_user")
|
||||
internal static let spaceMenuClose = ImageAsset(name: "space_menu_close")
|
||||
internal static let spaceMenuLeave = ImageAsset(name: "space_menu_leave")
|
||||
internal static let spaceMenuMembers = ImageAsset(name: "space_menu_members")
|
||||
|
|
|
@ -3327,6 +3327,10 @@ public class VectorL10n: NSObject {
|
|||
public static var roomParticipantsInvitePromptTitle: String {
|
||||
return VectorL10n.tr("Vector", "room_participants_invite_prompt_title")
|
||||
}
|
||||
/// Are you sure you want to invite %@ to %@?
|
||||
public static func roomParticipantsInvitePromptToMsg(_ p1: String, _ p2: String) -> String {
|
||||
return VectorL10n.tr("Vector", "room_participants_invite_prompt_to_msg", p1, p2)
|
||||
}
|
||||
/// INVITED
|
||||
public static var roomParticipantsInvitedSection: String {
|
||||
return VectorL10n.tr("Vector", "room_participants_invited_section")
|
||||
|
@ -4987,6 +4991,10 @@ public class VectorL10n: NSObject {
|
|||
public static var spaceTag: String {
|
||||
return VectorL10n.tr("Vector", "space_tag")
|
||||
}
|
||||
/// Add room
|
||||
public static var spacesAddRoom: String {
|
||||
return VectorL10n.tr("Vector", "spaces_add_room")
|
||||
}
|
||||
/// Adding rooms coming soon
|
||||
public static var spacesAddRoomsComingSoonTitle: String {
|
||||
return VectorL10n.tr("Vector", "spaces_add_rooms_coming_soon_title")
|
||||
|
@ -5015,6 +5023,10 @@ public class VectorL10n: NSObject {
|
|||
public static var spacesHomeSpaceTitle: String {
|
||||
return VectorL10n.tr("Vector", "spaces_home_space_title")
|
||||
}
|
||||
/// Invite people
|
||||
public static var spacesInvitePeople: String {
|
||||
return VectorL10n.tr("Vector", "spaces_invite_people")
|
||||
}
|
||||
/// Invites coming soon
|
||||
public static var spacesInvitesComingSoonTitle: String {
|
||||
return VectorL10n.tr("Vector", "spaces_invites_coming_soon_title")
|
||||
|
|
|
@ -66,8 +66,9 @@
|
|||
// This will be used by the shared RecentsDataSource instance for sanity checks (see UITableViewDataSource methods).
|
||||
self.recentsTableView.tag = RecentsDataSourceModePeople;
|
||||
|
||||
UIImage *fabImage = self.dataSource.currentSpace == nil ? [UIImage imageNamed:@"people_floating_action"] : [UIImage imageNamed:@"add_member_floating_action"];
|
||||
// Add the (+) button programmatically
|
||||
plusButtonImageView = [self vc_addFABWithImage:[UIImage imageNamed:@"people_floating_action"]
|
||||
plusButtonImageView = [self vc_addFABWithImage:fabImage
|
||||
target:self
|
||||
action:@selector(onPlusButtonPressed)];
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
'RoomParticipantsViewController' instance is used to edit members of the room defined by the property 'mxRoom'.
|
||||
When this property is nil, the view controller is empty.
|
||||
*/
|
||||
@interface RoomParticipantsViewController : MXKViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UIGestureRecognizerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate>
|
||||
@interface RoomParticipantsViewController : MXKViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UIGestureRecognizerDelegate, MXKRoomMemberDetailsViewControllerDelegate>
|
||||
{
|
||||
@protected
|
||||
/**
|
||||
|
@ -91,6 +91,7 @@
|
|||
|
||||
@property (nonatomic) BOOL showCancelBarButtonItem;
|
||||
@property (nonatomic) BOOL showParticipantCustomAccessoryView;
|
||||
@property (nonatomic) BOOL showInviteUserFab;
|
||||
|
||||
/**
|
||||
The delegate for the view controller.
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
self.enableBarTintColorStatusChange = NO;
|
||||
self.rageShakeManager = [RageShakeManager sharedManager];
|
||||
self.showParticipantCustomAccessoryView = YES;
|
||||
self.showInviteUserFab = YES;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
|
@ -141,11 +142,13 @@
|
|||
[self.tableView registerClass:ContactTableViewCell.class forCellReuseIdentifier:@"ParticipantTableViewCellId"];
|
||||
|
||||
|
||||
|
||||
// Add invite members button programmatically
|
||||
[self vc_addFABWithImage:[UIImage imageNamed:@"add_member_floating_action"]
|
||||
target:self
|
||||
action:@selector(onAddParticipantButtonPressed)];
|
||||
if (_showInviteUserFab)
|
||||
{
|
||||
// Add invite members button programmatically
|
||||
[self vc_addFABWithImage:[UIImage imageNamed:@"add_member_floating_action"]
|
||||
target:self
|
||||
action:@selector(onAddParticipantButtonPressed)];
|
||||
}
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
|
|
@ -200,7 +200,8 @@ extension ContactsPickerViewModel: ContactsTableViewControllerDelegate {
|
|||
return
|
||||
}
|
||||
|
||||
let message = VectorL10n.roomParticipantsInvitePromptMsg(contact.displayName)
|
||||
let roomName = room.displayName ?? VectorL10n.spaceTag
|
||||
let message = VectorL10n.roomParticipantsInvitePromptToMsg(contact.displayName, roomName)
|
||||
|
||||
coordinatorDelegate?.contactsPickerViewModel(self, display: message, title: VectorL10n.roomParticipantsInvitePromptTitle, actions: [
|
||||
UIAlertAction(title: MatrixKitL10n.cancel, style: .cancel, handler: nil),
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
//
|
||||
// Copyright 2020 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
|
||||
|
||||
@objc
|
||||
protocol AddItemHeaderViewDelegate: AnyObject {
|
||||
func addItemHeaderView(_ headerView: AddItemHeaderView, didTapButton button: UIButton)
|
||||
}
|
||||
|
||||
@objcMembers
|
||||
final class AddItemHeaderView: UIView, NibLoadable, Themable {
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
private enum Constants {
|
||||
static let buttonHighlightedAlpha: CGFloat = 0.2
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
@IBOutlet private weak var button: UIButton!
|
||||
@IBOutlet private weak var iconBackgroundView: UIView!
|
||||
@IBOutlet private weak var iconView: UIImageView!
|
||||
@IBOutlet private weak var titleLabel: UILabel!
|
||||
|
||||
weak var delegate: AddItemHeaderViewDelegate?
|
||||
|
||||
private var title: String? {
|
||||
didSet {
|
||||
titleLabel.text = title
|
||||
}
|
||||
}
|
||||
private var icon: UIImage? {
|
||||
didSet {
|
||||
iconView.image = icon
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
static func instantiate(title: String?, icon: UIImage?) -> AddItemHeaderView {
|
||||
let view = AddItemHeaderView.loadFromNib()
|
||||
view.icon = icon
|
||||
view.title = title
|
||||
view.update(theme: ThemeService.shared().theme)
|
||||
return view
|
||||
}
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
|
||||
iconBackgroundView.layer.masksToBounds = true
|
||||
iconBackgroundView.layer.cornerRadius = iconBackgroundView.bounds.width / 2
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func update(theme: Theme) {
|
||||
iconBackgroundView.layer.backgroundColor = theme.colors.quinaryContent.cgColor
|
||||
iconView.tintColor = theme.colors.secondaryContent
|
||||
titleLabel.textColor = theme.colors.primaryContent
|
||||
titleLabel.font = theme.fonts.headline
|
||||
}
|
||||
|
||||
// MARK: - Action
|
||||
|
||||
@objc private func buttonAction(_ sender: UIButton) {
|
||||
delegate?.addItemHeaderView(self, didTapButton: button)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?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">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<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"/>
|
||||
<view contentMode="scaleToFill" id="cxh-dz-aGG" customClass="AddItemHeaderView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="77"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="K8C-8y-oEb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="77"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="77" id="JuE-b9-RNu"/>
|
||||
</constraints>
|
||||
<inset key="contentEdgeInsets" minX="20" minY="0.0" maxX="20" maxY="0.0"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="20" maxY="0.0"/>
|
||||
<state key="normal">
|
||||
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<state key="disabled">
|
||||
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="0.5" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5Ob-zl-Yhb">
|
||||
<rect key="frame" x="13" y="17.5" width="42" height="42"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Kik-Yj-tb0">
|
||||
<rect key="frame" x="0.0" y="0.0" width="42" height="42"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="Kik-Yj-tb0" firstAttribute="leading" secondItem="5Ob-zl-Yhb" secondAttribute="leading" id="8x3-3e-gtx"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Kik-Yj-tb0" secondAttribute="trailing" id="AJT-WT-ytj"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Kik-Yj-tb0" secondAttribute="bottom" id="ELg-cy-SKj"/>
|
||||
<constraint firstAttribute="height" constant="42" id="cY8-gc-vLW"/>
|
||||
<constraint firstAttribute="width" constant="42" id="fJr-GR-ahN"/>
|
||||
<constraint firstItem="Kik-Yj-tb0" firstAttribute="top" secondItem="5Ob-zl-Yhb" secondAttribute="top" id="m8Y-Fu-iJd"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Mfm-61-xzF">
|
||||
<rect key="frame" x="69" y="28" width="331" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="Ehk-Sf-ESZ"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="5Ob-zl-Yhb" firstAttribute="centerY" secondItem="cxh-dz-aGG" secondAttribute="centerY" id="7fq-2U-Q7B"/>
|
||||
<constraint firstItem="Mfm-61-xzF" firstAttribute="centerY" secondItem="cxh-dz-aGG" secondAttribute="centerY" id="8Th-Y1-glF"/>
|
||||
<constraint firstItem="5Ob-zl-Yhb" firstAttribute="leading" secondItem="cxh-dz-aGG" secondAttribute="leading" constant="13" id="Ec0-ux-5ZW"/>
|
||||
<constraint firstItem="Ehk-Sf-ESZ" firstAttribute="trailing" secondItem="Mfm-61-xzF" secondAttribute="trailing" constant="14" id="HCD-YR-0ip"/>
|
||||
<constraint firstItem="K8C-8y-oEb" firstAttribute="top" secondItem="cxh-dz-aGG" secondAttribute="top" id="dLb-B4-eBJ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="K8C-8y-oEb" secondAttribute="trailing" id="nXF-QG-u1t"/>
|
||||
<constraint firstItem="K8C-8y-oEb" firstAttribute="leading" secondItem="cxh-dz-aGG" secondAttribute="leading" id="rZm-C4-mTe"/>
|
||||
<constraint firstAttribute="bottom" secondItem="K8C-8y-oEb" secondAttribute="bottom" id="tDj-72-Eek"/>
|
||||
<constraint firstItem="Mfm-61-xzF" firstAttribute="leading" secondItem="5Ob-zl-Yhb" secondAttribute="trailing" constant="14" id="wWl-9y-vew"/>
|
||||
</constraints>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="button" destination="K8C-8y-oEb" id="xU3-t7-lLR"/>
|
||||
<outlet property="iconBackgroundView" destination="5Ob-zl-Yhb" id="O8Y-re-hFp"/>
|
||||
<outlet property="iconView" destination="Kik-Yj-tb0" id="lE3-da-2mt"/>
|
||||
<outlet property="titleLabel" destination="Mfm-61-xzF" id="27Q-vu-oPf"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="114.49275362318842" y="-639.50892857142856"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
|
@ -70,4 +70,8 @@ extension SpaceMemberListCoordinator: SpaceMemberListViewModelCoordinatorDelegat
|
|||
func spaceMemberListViewModelDidCancel(_ viewModel: SpaceMemberListViewModelType) {
|
||||
self.delegate?.spaceMemberListCoordinatorDidCancel(self)
|
||||
}
|
||||
|
||||
func spaceMemberListViewModelShowInvite(_ viewModel: SpaceMemberListViewModelType) {
|
||||
self.delegate?.spaceMemberListCoordinatorShowInvite(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import Foundation
|
|||
protocol SpaceMemberListCoordinatorDelegate: AnyObject {
|
||||
func spaceMemberListCoordinator(_ coordinator: SpaceMemberListCoordinatorType, didSelect member: MXRoomMember, from sourceView: UIView?)
|
||||
func spaceMemberListCoordinatorDidCancel(_ coordinator: SpaceMemberListCoordinatorType)
|
||||
func spaceMemberListCoordinatorShowInvite(_ coordinator: SpaceMemberListCoordinatorType)
|
||||
}
|
||||
|
||||
/// `SpaceMemberListCoordinatorType` is a protocol describing a Coordinator that handle key backup setup passphrase navigation flow.
|
||||
|
|
|
@ -23,4 +23,5 @@ enum SpaceMemberListViewAction {
|
|||
case loadData
|
||||
case complete(_ selectedMember: MXRoomMember, _ sourceView: UIView?)
|
||||
case cancel
|
||||
case invite
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ final class SpaceMemberListViewController: RoomParticipantsViewController {
|
|||
private var activityPresenter: ActivityIndicatorPresenter!
|
||||
private var titleView: MainTitleView!
|
||||
private var emptyView: SearchEmptyView!
|
||||
private let inviteHeaderView = AddItemHeaderView.instantiate(title: VectorL10n.spacesInvitePeople, icon: Asset.Images.spaceInviteUser.image)
|
||||
|
||||
private var emptyViewArtwork: UIImage {
|
||||
return ThemeService.shared().isCurrentThemeDark() ? Asset.Images.peopleEmptyScreenArtworkDark.image : Asset.Images.peopleEmptyScreenArtwork.image
|
||||
|
@ -47,6 +48,7 @@ final class SpaceMemberListViewController: RoomParticipantsViewController {
|
|||
let viewController = SpaceMemberListViewController()
|
||||
viewController.viewModel = viewModel
|
||||
viewController.showParticipantCustomAccessoryView = false
|
||||
viewController.showInviteUserFab = false
|
||||
viewController.theme = ThemeService.shared().theme
|
||||
viewController.emptyView = SearchEmptyView()
|
||||
return viewController
|
||||
|
@ -71,14 +73,21 @@ final class SpaceMemberListViewController: RoomParticipantsViewController {
|
|||
self.viewModel.process(viewAction: .loadData)
|
||||
|
||||
self.title = ""
|
||||
|
||||
self.setupTableViewHeader()
|
||||
}
|
||||
|
||||
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||
return self.theme.statusBarStyle
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
|
||||
private func setupTableViewHeader() {
|
||||
inviteHeaderView.delegate = self
|
||||
tableView.tableHeaderView = inviteHeaderView
|
||||
}
|
||||
|
||||
private func update(theme: Theme) {
|
||||
self.theme = theme
|
||||
|
||||
|
@ -91,6 +100,8 @@ final class SpaceMemberListViewController: RoomParticipantsViewController {
|
|||
theme.applyStyle(onSearchBar: self.searchBarView)
|
||||
self.titleView.update(theme: theme)
|
||||
self.emptyView.update(theme: theme)
|
||||
|
||||
self.inviteHeaderView.update(theme: theme)
|
||||
}
|
||||
|
||||
private func registerThemeServiceDidChangeThemeNotification() {
|
||||
|
@ -154,7 +165,7 @@ final class SpaceMemberListViewController: RoomParticipantsViewController {
|
|||
// MARK: - Actions
|
||||
|
||||
@objc private func onAddParticipantButtonPressed() {
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesInvitesComingSoonTitle, message: VectorL10n.spacesComingSoonDetail, animated: true, handler: nil)
|
||||
self.viewModel.process(viewAction: .invite)
|
||||
}
|
||||
|
||||
private func cancelButtonAction() {
|
||||
|
@ -200,3 +211,10 @@ extension SpaceMemberListViewController: SpaceMemberListViewModelViewDelegate {
|
|||
self.render(viewState: viewSate)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SpaceMemberListViewModelViewDelegate
|
||||
extension SpaceMemberListViewController: AddItemHeaderViewDelegate {
|
||||
func addItemHeaderView(_ headerView: AddItemHeaderView, didTapButton button: UIButton) {
|
||||
self.viewModel.process(viewAction: .invite)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ final class SpaceMemberListViewModel: SpaceMemberListViewModelType {
|
|||
case .cancel:
|
||||
self.cancelOperations()
|
||||
self.coordinatorDelegate?.spaceMemberListViewModelDidCancel(self)
|
||||
case .invite:
|
||||
self.coordinatorDelegate?.spaceMemberListViewModelShowInvite(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ protocol SpaceMemberListViewModelViewDelegate: AnyObject {
|
|||
protocol SpaceMemberListViewModelCoordinatorDelegate: AnyObject {
|
||||
func spaceMemberListViewModel(_ viewModel: SpaceMemberListViewModelType, didSelect member: MXRoomMember, from sourceView: UIView?)
|
||||
func spaceMemberListViewModelDidCancel(_ viewModel: SpaceMemberListViewModelType)
|
||||
func spaceMemberListViewModelShowInvite(_ viewModel: SpaceMemberListViewModelType)
|
||||
}
|
||||
|
||||
/// Protocol describing the view model used by `SpaceMemberListViewController`
|
||||
|
|
|
@ -131,8 +131,34 @@ extension SpaceMembersCoordinator: SpaceMemberListCoordinatorDelegate {
|
|||
func spaceMemberListCoordinatorDidCancel(_ coordinator: SpaceMemberListCoordinatorType) {
|
||||
self.delegate?.spaceMembersCoordinatorDidCancel(self)
|
||||
}
|
||||
|
||||
func spaceMemberListCoordinatorShowInvite(_ coordinator: SpaceMemberListCoordinatorType) {
|
||||
guard let space = parameters.session.spaceService.getSpace(withId: parameters.spaceId), let spaceRoom = space.room else {
|
||||
MXLog.error("[SpaceMembersCoordinator] spaceMemberListCoordinatorShowInvite: failed to find space with id \(parameters.spaceId)")
|
||||
return
|
||||
}
|
||||
|
||||
let coordinator = ContactsPickerCoordinator(session: parameters.session, room: spaceRoom, currentSearchText: nil, actualParticipants: nil, invitedParticipants: nil, userParticipant: nil, navigationRouter: navigationRouter)
|
||||
coordinator.delegate = self
|
||||
coordinator.start()
|
||||
childCoordinators.append(coordinator)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ContactsPickerCoordinatorDelegate
|
||||
extension SpaceMembersCoordinator: ContactsPickerCoordinatorDelegate {
|
||||
func contactsPickerCoordinatorDidStartLoading(_ coordinator: ContactsPickerCoordinatorType) {
|
||||
}
|
||||
|
||||
func contactsPickerCoordinatorDidEndLoading(_ coordinator: ContactsPickerCoordinatorType) {
|
||||
}
|
||||
|
||||
func contactsPickerCoordinatorDidClose(_ coordinator: ContactsPickerCoordinatorType) {
|
||||
childCoordinators.removeLast()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SpaceMemberDetailCoordinatorDelegate
|
||||
extension SpaceMembersCoordinator: SpaceMemberDetailCoordinatorDelegate {
|
||||
func spaceMemberDetailCoordinator(_ coordinator: SpaceMemberDetailCoordinatorType, showRoomWithId roomId: String) {
|
||||
if !UIDevice.current.isPhone, let memberDetailCoordinator = self.memberDetailCoordinator {
|
||||
|
|
|
@ -26,24 +26,24 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GVJ-S7-stu" customClass="SpaceAvatarView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="18" y="11" width="32" height="32"/>
|
||||
<rect key="frame" x="16" y="11" width="40" height="40"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="GVJ-S7-stu" secondAttribute="height" multiplier="1:1" id="87c-7u-7ge"/>
|
||||
<constraint firstAttribute="height" constant="32" id="zvP-oT-8po"/>
|
||||
<constraint firstAttribute="height" constant="40" id="zvP-oT-8po"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XbP-0o-uBP">
|
||||
<rect key="frame" x="66" y="7.5" width="238" height="39"/>
|
||||
<rect key="frame" x="72" y="11.5" width="232" height="39"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gVa-kK-bqa">
|
||||
<rect key="frame" x="0.0" y="0.0" width="198" height="17"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="192" height="17"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xhg-rs-E5l">
|
||||
<rect key="frame" x="202" y="0.0" width="36" height="17"/>
|
||||
<rect key="frame" x="196" y="0.0" width="36" height="17"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -120,7 +120,7 @@
|
|||
<constraint firstItem="4Ic-S2-Ph6" firstAttribute="leading" secondItem="YoL-49-1Hj" secondAttribute="leading" constant="11" id="BzO-a8-pjD"/>
|
||||
<constraint firstAttribute="bottom" secondItem="GVJ-S7-stu" secondAttribute="bottom" constant="11" id="CCO-dh-iNA"/>
|
||||
<constraint firstItem="XbP-0o-uBP" firstAttribute="centerY" secondItem="GVJ-S7-stu" secondAttribute="centerY" id="GUt-0Z-6Px"/>
|
||||
<constraint firstItem="GVJ-S7-stu" firstAttribute="leading" secondItem="YoL-49-1Hj" secondAttribute="leading" constant="18" id="TmX-fw-4A1"/>
|
||||
<constraint firstItem="GVJ-S7-stu" firstAttribute="leading" secondItem="YoL-49-1Hj" secondAttribute="leading" constant="16" id="TmX-fw-4A1"/>
|
||||
<constraint firstAttribute="trailing" secondItem="XbP-0o-uBP" secondAttribute="trailing" constant="16" id="WHX-0h-KAF"/>
|
||||
<constraint firstItem="4Ic-S2-Ph6" firstAttribute="top" secondItem="YoL-49-1Hj" secondAttribute="top" constant="1" id="ZBt-T2-SNc"/>
|
||||
<constraint firstAttribute="bottom" secondItem="4Ic-S2-Ph6" secondAttribute="bottom" constant="1" id="aaA-eT-Ma1"/>
|
||||
|
|
|
@ -26,18 +26,18 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GVJ-S7-stu" customClass="RoomAvatarView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="18" y="11" width="32" height="32"/>
|
||||
<rect key="frame" x="16" y="11" width="40" height="40"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="GVJ-S7-stu" secondAttribute="height" multiplier="1:1" id="87c-7u-7ge"/>
|
||||
<constraint firstAttribute="height" constant="32" id="zvP-oT-8po"/>
|
||||
<constraint firstAttribute="height" constant="40" id="zvP-oT-8po"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XbP-0o-uBP">
|
||||
<rect key="frame" x="66" y="7.5" width="238" height="39"/>
|
||||
<rect key="frame" x="72" y="11.5" width="232" height="39"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gVa-kK-bqa">
|
||||
<rect key="frame" x="0.0" y="0.0" width="198" height="17"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="192" height="17"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -56,13 +56,13 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Description" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cKk-HO-IfB">
|
||||
<rect key="frame" x="41" y="23" width="197" height="16"/>
|
||||
<rect key="frame" x="41" y="23" width="191" height="16"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCallout"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xhg-rs-E5l">
|
||||
<rect key="frame" x="202" y="0.0" width="36" height="17"/>
|
||||
<rect key="frame" x="196" y="0.0" width="36" height="17"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -92,7 +92,7 @@
|
|||
<constraint firstItem="4Ic-S2-Ph6" firstAttribute="leading" secondItem="YoL-49-1Hj" secondAttribute="leading" constant="11" id="BzO-a8-pjD"/>
|
||||
<constraint firstAttribute="bottom" secondItem="GVJ-S7-stu" secondAttribute="bottom" constant="11" id="CCO-dh-iNA"/>
|
||||
<constraint firstItem="XbP-0o-uBP" firstAttribute="centerY" secondItem="GVJ-S7-stu" secondAttribute="centerY" id="GUt-0Z-6Px"/>
|
||||
<constraint firstItem="GVJ-S7-stu" firstAttribute="leading" secondItem="YoL-49-1Hj" secondAttribute="leading" constant="18" id="TmX-fw-4A1"/>
|
||||
<constraint firstItem="GVJ-S7-stu" firstAttribute="leading" secondItem="YoL-49-1Hj" secondAttribute="leading" constant="16" id="TmX-fw-4A1"/>
|
||||
<constraint firstAttribute="trailing" secondItem="XbP-0o-uBP" secondAttribute="trailing" constant="16" id="WHX-0h-KAF"/>
|
||||
<constraint firstItem="4Ic-S2-Ph6" firstAttribute="top" secondItem="YoL-49-1Hj" secondAttribute="top" constant="1" id="ZBt-T2-SNc"/>
|
||||
<constraint firstAttribute="bottom" secondItem="4Ic-S2-Ph6" secondAttribute="bottom" constant="1" id="aaA-eT-Ma1"/>
|
||||
|
|
|
@ -40,9 +40,9 @@ final class SpaceExploreRoomViewController: UIViewController {
|
|||
private var activityPresenter: ActivityIndicatorPresenter!
|
||||
private var titleView: MainTitleView!
|
||||
private var emptyView: RootTabEmptyView!
|
||||
private var plusButtonImageView: UIImageView!
|
||||
private var hasMore: Bool = false
|
||||
|
||||
private let addRoomHeaderView = AddItemHeaderView.instantiate(title: VectorL10n.spacesAddRoom, icon: Asset.Images.spaceAddRoom.image)
|
||||
|
||||
private var itemDataList: [SpaceExploreRoomListItemViewData] = [] {
|
||||
didSet {
|
||||
self.tableView.reloadData()
|
||||
|
@ -124,6 +124,8 @@ final class SpaceExploreRoomViewController: UIViewController {
|
|||
self.tableView.reloadData()
|
||||
self.emptyView.update(theme: theme)
|
||||
theme.applyStyle(onSearchBar: self.tableSearchBar)
|
||||
|
||||
self.addRoomHeaderView.update(theme: theme)
|
||||
}
|
||||
|
||||
private func registerThemeServiceDidChangeThemeNotification() {
|
||||
|
@ -152,9 +154,9 @@ final class SpaceExploreRoomViewController: UIViewController {
|
|||
self.tableView.keyboardDismissMode = .interactive
|
||||
self.setupTableView()
|
||||
|
||||
self.emptyView.fill(with: self.emptyViewArtwork, title: VectorL10n.roomsEmptyViewTitle, informationText: VectorL10n.roomsEmptyViewInformation)
|
||||
self.setupTableViewHeader()
|
||||
|
||||
self.plusButtonImageView = self.vc_addFAB(withImage: Asset.Images.roomsFloatingAction.image, target: self, action: #selector(addRoomAction(semder:)))
|
||||
self.emptyView.fill(with: self.emptyViewArtwork, title: VectorL10n.roomsEmptyViewTitle, informationText: VectorL10n.roomsEmptyViewInformation)
|
||||
|
||||
self.emptyView.frame = CGRect(x: 0, y: self.tableSearchBar.frame.maxY, width: self.view.bounds.width, height: self.view.bounds.height - self.tableSearchBar.frame.maxY)
|
||||
self.emptyView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
|
||||
|
@ -162,6 +164,11 @@ final class SpaceExploreRoomViewController: UIViewController {
|
|||
self.view.insertSubview(self.emptyView, at: 0)
|
||||
}
|
||||
|
||||
private func setupTableViewHeader() {
|
||||
addRoomHeaderView.delegate = self
|
||||
tableView.tableHeaderView = addRoomHeaderView
|
||||
}
|
||||
|
||||
private func setupTableView() {
|
||||
self.tableView.separatorStyle = .none
|
||||
self.tableView.rowHeight = UITableView.automaticDimension
|
||||
|
@ -224,10 +231,6 @@ final class SpaceExploreRoomViewController: UIViewController {
|
|||
self.viewModel.process(viewAction: .cancel)
|
||||
}
|
||||
|
||||
@objc private func addRoomAction(semder: UIView) {
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesAddRoomsComingSoonTitle, message: VectorL10n.spacesComingSoonDetail, animated: true, handler: nil)
|
||||
}
|
||||
|
||||
// MARK: - UISearchBarDelegate
|
||||
|
||||
override func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
|
||||
|
@ -286,3 +289,12 @@ extension SpaceExploreRoomViewController: SpaceExploreRoomViewModelViewDelegate
|
|||
self.render(viewState: viewSate)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SpaceMemberListViewModelViewDelegate
|
||||
extension SpaceExploreRoomViewController: AddItemHeaderViewDelegate {
|
||||
|
||||
func addItemHeaderView(_ headerView: AddItemHeaderView, didTapButton button: UIButton) {
|
||||
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesAddRoomsComingSoonTitle, message: VectorL10n.spacesComingSoonDetail, animated: true, handler: nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue