Skip to content

Commit

Permalink
[spaces] several fixes for pre release
Browse files Browse the repository at this point in the history
- [Space home view inherits title from previously viewed tab](#4851)
- [Home view doesn't refresh when new rooms are created](#4849)
- [Odd error message in Space member list](#4845)
- [Bring leaving space experience in line with Web](#4850)
- [No notification for space invitation](#4840)
- [Remove filter when space is switched](#4852)
- [M10.11 Remove community tab](#4493)
  • Loading branch information
gileluard committed Sep 20, 2021
1 parent a926960 commit c1a542e
Show file tree
Hide file tree
Showing 15 changed files with 265 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "side_menu_notif_icon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
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.
7 changes: 6 additions & 1 deletion Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1696,7 +1696,11 @@ Tap the + to start adding people.";

"spaces_home_space_title" = "Home";
"spaces_left_panel_title" = "Spaces";
"leave_space_message" = "Are you sure you want to leave %@?";
"leave_space_title" = "Leave %@";
"leave_space_message" = "Are you sure you want to leave %@? Do you also want to leave all rooms and spaces of this space?";
"leave_space_message_admin_warning" = "You are admin of this space, ensure that you have transferred admin right to another member before leaving.";
"leave_space_only_action" = "Don't leave any rooms";
"leave_space_and_all_rooms_action" = "Leave all rooms and spaces";
"spaces_explore_rooms" = "Explore rooms";
"spaces_suggested_room" = "Suggested";
"space_tag" = "space";
Expand All @@ -1706,6 +1710,7 @@ Tap the + to start adding people.";
"spaces_no_room_found_detail" = "Some results may be hidden because they’re private and you need an invite to join them.";
"spaces_no_member_found_detail" = "Looking for someone not in %@? For now, you can invite them on web or desktop.";
"spaces_coming_soon_title" = "Coming soon";
"spaces_invites_coming_soon_title" = "Invites coming soon";
"spaces_coming_soon_detail" = "This feature hasn’t been implemented here, but it’s on the way. For now, you can do that with Element on your computer.";
"space_participants_action_remove" = "Remove from this space";
"space_participants_action_ban" = "Ban from this space";
Expand Down
1 change: 1 addition & 0 deletions Riot/Generated/Images.swift
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ internal enum Asset {
internal static let sideMenuActionIconSettings = ImageAsset(name: "side_menu_action_icon_settings")
internal static let sideMenuActionIconShare = ImageAsset(name: "side_menu_action_icon_share")
internal static let sideMenuIcon = ImageAsset(name: "side_menu_icon")
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 spaceHomeIcon = ImageAsset(name: "space_home_icon")
Expand Down
22 changes: 21 additions & 1 deletion Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2078,10 +2078,26 @@ internal enum VectorL10n {
internal static var leave: String {
return VectorL10n.tr("Vector", "leave")
}
/// Are you sure you want to leave %@?
/// Leave all rooms and spaces
internal static var leaveSpaceAndAllRoomsAction: String {
return VectorL10n.tr("Vector", "leave_space_and_all_rooms_action")
}
/// Are you sure you want to leave %@? Do you also want to leave all rooms and spaces of this space?
internal static func leaveSpaceMessage(_ p1: String) -> String {
return VectorL10n.tr("Vector", "leave_space_message", p1)
}
/// You are admin of this space, ensure that you have transferred admin right to another member before leaving.
internal static var leaveSpaceMessageAdminWarning: String {
return VectorL10n.tr("Vector", "leave_space_message_admin_warning")
}
/// Don't leave any rooms
internal static var leaveSpaceOnlyAction: String {
return VectorL10n.tr("Vector", "leave_space_only_action")
}
/// Leave %@
internal static func leaveSpaceTitle(_ p1: String) -> String {
return VectorL10n.tr("Vector", "leave_space_title", p1)
}
/// Less
internal static var less: String {
return VectorL10n.tr("Vector", "less")
Expand Down Expand Up @@ -4870,6 +4886,10 @@ internal enum VectorL10n {
internal static var spacesHomeSpaceTitle: String {
return VectorL10n.tr("Vector", "spaces_home_space_title")
}
/// Invites coming soon
internal static var spacesInvitesComingSoonTitle: String {
return VectorL10n.tr("Vector", "spaces_invites_coming_soon_title")
}
/// Spaces
internal static var spacesLeftPanelTitle: String {
return VectorL10n.tr("Vector", "spaces_left_panel_title")
Expand Down
2 changes: 2 additions & 0 deletions Riot/Modules/Spaces/SpaceList/SpaceListItemViewData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ struct SpaceListItemViewData {
let title: String
let avatarViewData: AvatarViewDataProtocol
let isInvite: Bool
let notificationCount: UInt
let highlightedNotificationCount: UInt
}
7 changes: 5 additions & 2 deletions Riot/Modules/Spaces/SpaceList/SpaceListViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,12 @@ final class SpaceListViewCell: UITableViewCell, Themable, NibReusable {
if viewData.isInvite {
self.badgeLabel.isHidden = false
self.badgeLabel.badgeColor = ThemeService.shared().theme.colors.alert
self.badgeLabel.borderColor = ThemeService.shared().theme.colors.background
self.badgeLabel.text = "!"
} else {
self.badgeLabel.isHidden = true
let notificationCount = viewData.notificationCount + viewData.highlightedNotificationCount
self.badgeLabel.isHidden = notificationCount == 0
self.badgeLabel.badgeColor = viewData.highlightedNotificationCount == 0 ? ThemeService.shared().theme.colors.tertiaryContent : ThemeService.shared().theme.colors.alert
self.badgeLabel.text = "\(notificationCount)"
}
}

Expand All @@ -76,6 +78,7 @@ final class SpaceListViewCell: UITableViewCell, Themable, NibReusable {
self.titleLabel.font = theme.fonts.calloutSB
self.selectionView.backgroundColor = theme.colors.separator
self.moreButton.tintColor = theme.colors.secondaryContent
self.badgeLabel.borderColor = ThemeService.shared().theme.colors.background
}

// MARK: - IBActions
Expand Down
51 changes: 48 additions & 3 deletions Riot/Modules/Spaces/SpaceList/SpaceListViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ final class SpaceListViewModel: SpaceListViewModelType {

private var currentOperation: MXHTTPOperation?
private var sections: [SpaceListSection] = []
private var selectedIndexPath: IndexPath = IndexPath(row: 0, section: 0)
private var selectedIndexPath: IndexPath = IndexPath(row: 0, section: 0) {
didSet {
self.selectedItemId = self.itemId(with: self.selectedIndexPath)
}
}
private var homeIndexPath: IndexPath = IndexPath(row: 0, section: 0)
private var selectedItemId: String = Constants.homeSpaceId

// MARK: Public

Expand Down Expand Up @@ -127,6 +132,30 @@ final class SpaceListViewModel: SpaceListViewModelType {
let homeIndexPath = viewDataList.invites.isEmpty ? IndexPath(row: 0, section: 0) : IndexPath(row: 0, section: 1)
if self.selectedIndexPath.section == self.homeIndexPath.section {
self.selectedIndexPath = homeIndexPath
} else if self.selectedItemId != self.itemId(with: self.selectedIndexPath) {
var newSelection: IndexPath?
let section = sections.last
switch section {
case .home:
break
case .spaces(let viewDataList):
var index = 0
for itemViewData in viewDataList {
if itemViewData.spaceId == self.selectedItemId {
newSelection = IndexPath(row: index, section: sections.count - 1)
}
index += 1
}
case .none:
break
}

if let selection = newSelection {
self.selectedIndexPath = selection
} else {
self.selectedIndexPath = homeIndexPath
self.coordinatorDelegate?.spaceListViewModelDidSelectHomeSpace(self)
}
}
self.homeIndexPath = homeIndexPath
self.update(viewState: .loaded(sections))
Expand All @@ -148,8 +177,9 @@ final class SpaceListViewModel: SpaceListViewModelType {
private func createHomeViewData() -> SpaceListItemViewData {
let avatarViewData = AvatarViewData(matrixItemId: Constants.homeSpaceId, displayName: nil, avatarUrl: nil, mediaManager: self.session.mediaManager, fallbackImage: .image(Asset.Images.spaceHomeIcon.image, .center))

let homeNotificationState = session.spaceService.notificationCounter.homeNotificationState
let homeViewData = SpaceListItemViewData(spaceId: Constants.homeSpaceId,
title: VectorL10n.spacesHomeSpaceTitle, avatarViewData: avatarViewData, isInvite: false)
title: VectorL10n.spacesHomeSpaceTitle, avatarViewData: avatarViewData, isInvite: false, notificationCount: homeNotificationState.allCount, highlightedNotificationCount: homeNotificationState.allHighlightCount)
return homeViewData
}

Expand All @@ -158,7 +188,8 @@ final class SpaceListViewModel: SpaceListViewModelType {
var spaces: [SpaceListItemViewData] = []
session.spaceService.rootSpaceSummaries.forEach { summary in
let avatarViewData = AvatarViewData(matrixItemId: summary.roomId, displayName: summary.displayname, avatarUrl: summary.avatar, mediaManager: self.session.mediaManager, fallbackImage: .matrixItem(summary.roomId, summary.displayname))
let viewData = SpaceListItemViewData(spaceId: summary.roomId, title: summary.displayname, avatarViewData: avatarViewData, isInvite: summary.membership == .invite)
let notificationState = self.session.spaceService.notificationCounter.notificationState(forSpaceWithId: summary.roomId)
let viewData = SpaceListItemViewData(spaceId: summary.roomId, title: summary.displayname, avatarViewData: avatarViewData, isInvite: summary.membership == .invite, notificationCount: notificationState.groupMissedDiscussionsCount, highlightedNotificationCount: notificationState.groupMissedDiscussionsHighlightedCount)
if viewData.isInvite {
invites.append(viewData)
} else {
Expand All @@ -176,4 +207,18 @@ final class SpaceListViewModel: SpaceListViewModelType {
private func cancelOperations() {
self.currentOperation?.cancel()
}

private func itemId(with indexPath: IndexPath) -> String {
guard self.selectedIndexPath.section < self.sections.count else {
return Constants.homeSpaceId
}
let section = self.sections[self.selectedIndexPath.section]
switch section {
case .home:
return Constants.homeSpaceId
case .spaces(let viewDataList):
let spaceViewData = viewDataList[self.selectedIndexPath.row]
return spaceViewData.spaceId
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ final class SpaceMemberListViewController: RoomParticipantsViewController {
// MARK: - Actions

@objc private func onAddParticipantButtonPressed() {
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesComingSoonTitle, message: VectorL10n.spacesComingSoonDetail, animated: true, handler: nil)
self.errorPresenter.presentError(from: self, title: VectorL10n.spacesInvitesComingSoonTitle, message: VectorL10n.spacesComingSoonDetail, animated: true, handler: nil)
}

private func cancelButtonAction() {
Expand Down
87 changes: 78 additions & 9 deletions Riot/Modules/Spaces/SpaceMenu/SpaceMenuViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,29 +75,52 @@ class SpaceMenuViewModel: SpaceMenuViewModelType {
guard let space = self.session.spaceService.getSpace(withId: self.spaceId), let displayName = space.summary?.displayname else {
return
}

var message = VectorL10n.leaveSpaceMessage(displayName)

if let roomState = space.room.dangerousSyncState, let powerLevels = roomState.powerLevels {
let powerLevel = powerLevels.powerLevelOfUser(withUserID: self.session.myUserId)
let roomPowerLevel = RoomPowerLevelHelper.roomPowerLevel(from: powerLevel)
if roomPowerLevel == .admin {
message += "\n\n" + VectorL10n.leaveSpaceMessageAdminWarning
}
}

let alert = UIAlertController(title: nil, message: VectorL10n.leaveSpaceMessage(displayName), preferredStyle: .alert)
let alert = UIAlertController(title: VectorL10n.leaveSpaceTitle(displayName), message: message, preferredStyle: .alert)

alert.addAction(UIAlertAction(title: VectorL10n.leave, style: .destructive, handler: { [weak self] action in
alert.addAction(UIAlertAction(title: VectorL10n.leaveSpaceOnlyAction, style: .default, handler: { [weak self] action in
guard let self = self else {
return
}

self.viewDelegate?.spaceMenuViewModel(self, didUpdateViewState: .loading)

space.room.leave(completion: { [weak self] response in
self.leaveSpace(space)
}))
alert.addAction(UIAlertAction(title: VectorL10n.leaveSpaceAndAllRoomsAction, style: .destructive, handler: { [weak self] action in
guard let self = self, let space = self.session.spaceService.getSpace(withId: self.spaceId) else {
return
}

self.viewDelegate?.spaceMenuViewModel(self, didUpdateViewState: .loading)

let allRoomsAndSpaces = space.childRoomIds + space.childSpaces.map({ space in
space.spaceId
})

self.leaveAllRooms(from: allRoomsAndSpaces, at: 0) { [weak self] error in
guard let self = self else {
return
}

self.viewDelegate?.spaceMenuViewModel(self, didUpdateViewState: .loaded)

if let error = response.error {
if let error = error {
self.viewDelegate?.spaceMenuViewModel(self, didUpdateViewState: .loaded)
self.viewDelegate?.spaceMenuViewModel(self, didUpdateViewState: .error(error))
} else {
self.process(viewAction: .dismiss)
return
}
})

self.leaveSpace(space)
}
}))
alert.addAction(UIAlertAction(title: VectorL10n.cancel, style: .cancel, handler: { [weak self] action in
guard let self = self else {
Expand All @@ -109,4 +132,50 @@ class SpaceMenuViewModel: SpaceMenuViewModelType {

self.viewDelegate?.spaceMenuViewModel(self, didUpdateViewState: .alert(alert))
}

private func leaveAllRooms(from roomIds: [String], at index: Int, completion: @escaping (_ error: Error?) -> Void) {
guard index < roomIds.count, let room = self.session.room(withRoomId: roomIds[index]), !room.isDirect else {
let nextIndex = index+1
if nextIndex < roomIds.count {
self.leaveAllRooms(from: roomIds, at: nextIndex, completion: completion)
} else {
completion(nil)
}
return
}

room.leave { [weak self] response in
guard let self = self else {
return
}

guard response.isSuccess else {
completion(response.error)
return
}

let nextIndex = index+1
if nextIndex < roomIds.count {
self.leaveAllRooms(from: roomIds, at: nextIndex, completion: completion)
} else {
completion(nil)
}
}
}

private func leaveSpace(_ space: MXSpace) {
space.room.leave(completion: { [weak self] response in
guard let self = self else {
return
}

self.viewDelegate?.spaceMenuViewModel(self, didUpdateViewState: .loaded)

if let error = response.error {
self.viewDelegate?.spaceMenuViewModel(self, didUpdateViewState: .error(error))
} else {
self.process(viewAction: .dismiss)
}
})
}
}
1 change: 1 addition & 0 deletions Riot/Modules/TabBar/MasterTabBarController.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,5 +201,6 @@

- (void)masterTabBarControllerDidCompleteAuthentication:(MasterTabBarController *)masterTabBarController;
- (void)masterTabBarController:(MasterTabBarController*)masterTabBarController wantsToDisplayDetailViewController:(UIViewController*)detailViewController;
- (void)masterTabBarController:(MasterTabBarController*)masterTabBarController needsSideMenuIconWithNotification:(BOOL)displayNotification;

@end
Loading

0 comments on commit c1a542e

Please sign in to comment.