Skip to content

Commit

Permalink
Merge pull request #4786 from vector-im/gil/4497_space_preview_bottom…
Browse files Browse the repository at this point in the history
…_sheet

[Spaces] M10.6 Space preview bottom sheet #4497
  • Loading branch information
gileluard authored Sep 15, 2021
2 parents 4fabc24 + a0fbe8a commit 8219473
Show file tree
Hide file tree
Showing 27 changed files with 998 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"images" : [
{
"filename" : "space_type_icon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "space_type_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "space_type_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1688,6 +1688,9 @@ Tap the + to start adding people.";
"space_participants_action_remove" = "Remove from this space";
"space_participants_action_ban" = "Ban from this space";

"space_private_join_rule" = "Private space";
"space_public_join_rule" = "Public space";

// Mark: Avatar

"space_avatar_view_accessibility_label" = "avatar";
Expand Down
1 change: 1 addition & 0 deletions Riot/Generated/Images.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ internal enum Asset {
internal static let spaceMenuMembers = ImageAsset(name: "space_menu_members")
internal static let spaceMenuRooms = ImageAsset(name: "space_menu_rooms")
internal static let spaceRoomIcon = ImageAsset(name: "space_room_icon")
internal static let spaceTypeIcon = ImageAsset(name: "space_type_icon")
internal static let spaceUserIcon = ImageAsset(name: "space_user_icon")
internal static let spacesMore = ImageAsset(name: "spaces_more")
internal static let tabFavourites = ImageAsset(name: "tab_favourites")
Expand Down
5 changes: 5 additions & 0 deletions Riot/Generated/Storyboards.swift
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ internal enum StoryboardScene {

internal static let initialScene = InitialSceneType<Riot.SpaceChildRoomDetailViewController>(storyboard: SpaceChildRoomDetailViewController.self)
}
internal enum SpaceDetailViewController: StoryboardType {
internal static let storyboardName = "SpaceDetailViewController"

internal static let initialScene = InitialSceneType<Riot.SpaceDetailViewController>(storyboard: SpaceDetailViewController.self)
}
internal enum SpaceExploreRoomViewController: StoryboardType {
internal static let storyboardName = "SpaceExploreRoomViewController"

Expand Down
8 changes: 8 additions & 0 deletions Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4730,6 +4730,14 @@ internal enum VectorL10n {
internal static var spaceParticipantsActionRemove: String {
return VectorL10n.tr("Vector", "space_participants_action_remove")
}
/// Private space
internal static var spacePrivateJoinRule: String {
return VectorL10n.tr("Vector", "space_private_join_rule")
}
/// Public space
internal static var spacePublicJoinRule: String {
return VectorL10n.tr("Vector", "space_public_join_rule")
}
/// space
internal static var spaceTag: String {
return VectorL10n.tr("Vector", "space_tag")
Expand Down
7 changes: 3 additions & 4 deletions Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,7 @@ + (RecentsDataSourceState *)computeStateWithCells:(NSArray<id<MXKRecentCellDataS
}
else if (room.summary.membership == MXMembershipInvite)
{
if (!MXSDKOptions.sharedInstance.autoAcceptRoomInvites)
if (room.summary.roomType != MXRoomTypeSpace && !MXSDKOptions.sharedInstance.autoAcceptRoomInvites)
{
[invitesCellDataArray addObject:recentCellDataStoring];
}
Expand All @@ -1301,8 +1301,7 @@ + (RecentsDataSourceState *)computeStateWithCells:(NSArray<id<MXKRecentCellDataS
else if (recentCellDataStoring.isSuggestedRoom)
{
MXRoomSummary *roomSummary = [mxSession roomSummaryWithRoomId:recentCellDataStoring.spaceChildInfo.childRoomId];
BOOL isJoined = roomSummary.membership == MXMembershipJoin || roomSummary.membershipTransitionState == MXMembershipTransitionStateJoined;
if (!isJoined)
if (!roomSummary.isJoined)
{
[suggestedRoomCellDataArray addObject:recentCellDataStoring];
}
Expand Down Expand Up @@ -1360,7 +1359,7 @@ + (RecentsDataSourceState *)computeStateWithCells:(NSArray<id<MXKRecentCellDataS
// Keep only the invites, the favourites and the rooms without tag and room type different from space
if (room.summary.membership == MXMembershipInvite)
{
if (!MXSDKOptions.sharedInstance.autoAcceptRoomInvites)
if (room.summary.roomType != MXRoomTypeSpace && !MXSDKOptions.sharedInstance.autoAcceptRoomInvites)
{
[invitesCellDataArray addObject:recentCellDataStoring];
}
Expand Down
19 changes: 19 additions & 0 deletions Riot/Modules/SideMenu/SideMenuCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ final class SideMenuCoordinator: NSObject, SideMenuCoordinatorType {
private let sideMenuViewController: SideMenuViewController

let spaceMenuPresenter = SpaceMenuPresenter()
let spaceDetailPresenter = SpaceDetailPresenter()

private var exploreRoomCoordinator: ExploreRoomCoordinator?
private var membersCoordinator: SpaceMembersCoordinator?
Expand Down Expand Up @@ -244,6 +245,14 @@ final class SideMenuCoordinator: NSObject, SideMenuCoordinatorType {
self.spaceMenuPresenter.present(forSpaceWithId: spaceId, from: self.sideMenuViewController, sourceView: sourceView, session: session, animated: true)
}

private func showSpaceDetail(forSpaceWithId spaceId: String, from sourceView: UIView?) {
guard let session = self.parameters.userSessionsService.mainUserSession?.matrixSession else {
return
}
self.spaceDetailPresenter.delegate = self
self.spaceDetailPresenter.present(forSpaceWithId: spaceId, from: self.sideMenuViewController, sourceView: sourceView, session: session, animated: true)
}

// MARK: UserSessions management

private func registerUserSessionsServiceNotifications() {
Expand Down Expand Up @@ -311,6 +320,10 @@ extension SideMenuCoordinator: SpaceListCoordinatorDelegate {
self.parameters.appNavigator.navigate(to: .space(spaceId))
}

func spaceListCoordinator(_ coordinator: SpaceListCoordinatorType, didSelectInviteWithId spaceId: String, from sourceView: UIView?) {
self.showSpaceDetail(forSpaceWithId: spaceId, from: sourceView)
}

func spaceListCoordinator(_ coordinator: SpaceListCoordinatorType, didPressMoreForSpaceWithId spaceId: String, from sourceView: UIView) {
self.showMenu(forSpaceWithId: spaceId, from: sourceView)
}
Expand All @@ -330,6 +343,12 @@ extension SideMenuCoordinator: SpaceMenuPresenterDelegate {
}
}

extension SideMenuCoordinator: SpaceDetailPresenterDelegate {
func spaceDetailPresenterDidComplete(_ presenter: SpaceDetailPresenter) {
self.spaceListCoordinator?.revertItemSelection()
}
}

// MARK: - ExploreRoomCoordinatorDelegate
extension SideMenuCoordinator: ExploreRoomCoordinatorDelegate {
func exploreRoomCoordinatorDidComplete(_ coordinator: ExploreRoomCoordinatorType) {
Expand Down
111 changes: 111 additions & 0 deletions Riot/Modules/Spaces/SpaceDetail/SpaceDetailPresenter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//
// 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

/// Presenter for space detail screen
class SpaceDetailPresenter: NSObject {

// MARK: - Constants

enum Actions {
case exploreRooms
case exploreMembers
}

// MARK: - Properties

public weak var delegate: SpaceDetailPresenterDelegate?

// MARK: Private

private weak var presentingViewController: UIViewController?
private var viewModel: SpaceDetailViewModel!
private weak var sourceView: UIView?
private lazy var slidingModalPresenter: SlidingModalPresenter = {
return SlidingModalPresenter()
}()
private weak var selectedSpace: MXSpace?
private var session: MXSession!
private var spaceId: String!

// MARK: - Public

func present(forSpaceWithId spaceId: String,
from viewController: UIViewController,
sourceView: UIView?,
session: MXSession,
animated: Bool) {
self.session = session
self.spaceId = spaceId

self.viewModel = SpaceDetailViewModel(session: session, spaceId: spaceId)
self.viewModel.coordinatorDelegate = self
self.presentingViewController = viewController
self.sourceView = sourceView
self.selectedSpace = session.spaceService.getSpace(withId: spaceId)

self.show(with: session)
}

func dismiss(animated: Bool, completion: (() -> Void)?) {
self.presentingViewController?.dismiss(animated: animated, completion: completion)
}

// MARK: - Private

private func show(with session: MXSession) {
let viewController = SpaceDetailViewController.instantiate(mediaManager: session.mediaManager, viewModel: self.viewModel)
self.present(viewController, animated: true)
}

private func present(_ viewController: SpaceDetailViewController, animated: Bool) {

if UIDevice.current.isPhone {
guard let rootViewController = self.presentingViewController else {
MXLog.error("[SpaceDetailPresenter] present no rootViewController found")
return
}

slidingModalPresenter.present(viewController, from: rootViewController.presentedViewController ?? rootViewController, animated: true, completion: nil)
} else {
// Configure source view when view controller is presented with a popover
viewController.modalPresentationStyle = .popover
if let sourceView = self.sourceView, let popoverPresentationController = viewController.popoverPresentationController {
popoverPresentationController.sourceView = sourceView
popoverPresentationController.sourceRect = sourceView.bounds
}

self.presentingViewController?.present(viewController, animated: animated, completion: nil)
}
}
}

// MARK: - SpaceDetailModelViewModelCoordinatorDelegate

extension SpaceDetailPresenter: SpaceDetailModelViewModelCoordinatorDelegate {
func spaceDetailViewModelDidCancel(_ viewModel: SpaceDetailViewModelType) {
self.dismiss(animated: true, completion: nil)
}

func spaceDetailViewModelDidDismiss(_ viewModel: SpaceDetailViewModelType) {
self.delegate?.spaceDetailPresenterDidComplete(self)
}
}

protocol SpaceDetailPresenterDelegate: AnyObject {
func spaceDetailPresenterDidComplete(_ presenter: SpaceDetailPresenter)
}
26 changes: 26 additions & 0 deletions Riot/Modules/Spaces/SpaceDetail/SpaceDetailViewAction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// 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

/// `SpaceDetailViewController` view actions exposed to view model
enum SpaceDetailViewAction {
case loadData
case join
case leave
case dismiss
case dismissed
}
Loading

0 comments on commit 8219473

Please sign in to comment.