mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Disable the composer when you don't have the power to post. (#4076)
This commit is contained in:
@@ -40,6 +40,7 @@ struct RoomScreenViewState: BindableState {
|
||||
!pinnedEventsBannerState.isEmpty && lastScrollDirection != .top
|
||||
}
|
||||
|
||||
var canSendMessage = true
|
||||
var canJoinCall = false
|
||||
var hasOngoingCall: Bool
|
||||
var shouldShowCallButton = true
|
||||
|
||||
@@ -340,6 +340,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
}
|
||||
|
||||
let ownUserID = roomProxy.ownUserID
|
||||
state.canSendMessage = await (try? roomProxy.canUser(userID: ownUserID, sendMessage: .roomMessage).get()) == true
|
||||
state.canJoinCall = await (try? roomProxy.canUserJoinCall(userID: ownUserID).get()) == true
|
||||
state.canAcceptKnocks = await (try? roomProxy.canUserInvite(userID: ownUserID).get()) == true
|
||||
state.canDeclineKnocks = await (try? roomProxy.canUserKick(userID: ownUserID).get()) == true
|
||||
|
||||
@@ -42,7 +42,7 @@ struct RoomScreen: View {
|
||||
roomContext.send(viewAction: .footerViewAction(action))
|
||||
}
|
||||
|
||||
composerToolbar
|
||||
composer
|
||||
.padding(.bottom, composerToolbarContext.composerFormattingEnabled ? 8 : 12)
|
||||
.background {
|
||||
if composerToolbarContext.composerFormattingEnabled {
|
||||
@@ -188,6 +188,19 @@ struct RoomScreen: View {
|
||||
timelineContext.isScrolledToBottom && timelineContext.viewState.timelineState.isLive
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var composer: some View {
|
||||
if roomContext.viewState.canSendMessage {
|
||||
composerToolbar
|
||||
} else {
|
||||
Text(L10n.screenRoomTimelineNoPermissionToPost)
|
||||
.font(.compound.bodyLG)
|
||||
.foregroundStyle(.compound.textDisabled)
|
||||
.multilineTextAlignment(.center)
|
||||
.padding(.vertical, 10) // Matches the MessageComposerStyleModifier
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var loadingIndicator: some View {
|
||||
if timelineContext.viewState.showLoading {
|
||||
@@ -257,28 +270,50 @@ struct RoomScreen: View {
|
||||
// MARK: - Previews
|
||||
|
||||
struct RoomScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let roomProxyMock = JoinedRoomProxyMock(.init(id: "stable_id",
|
||||
name: "Preview room",
|
||||
hasOngoingCall: true))
|
||||
static let roomViewModel = RoomScreenViewModel.mock(roomProxyMock: roomProxyMock)
|
||||
static let timelineViewModel = TimelineViewModel(roomProxy: roomProxyMock,
|
||||
timelineController: MockTimelineController(),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
mediaPlayerProvider: MediaPlayerProviderMock(),
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
||||
clientProxy: ClientProxyMock(.init()))
|
||||
static let viewModels = makeViewModels()
|
||||
static let readOnlyViewModels = makeViewModels(canSendMessage: false)
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
RoomScreen(roomViewModel: roomViewModel,
|
||||
timelineViewModel: timelineViewModel,
|
||||
RoomScreen(roomViewModel: viewModels.room,
|
||||
timelineViewModel: viewModels.timeline,
|
||||
composerToolbar: ComposerToolbar.mock())
|
||||
}
|
||||
.previewDisplayName("Normal")
|
||||
|
||||
NavigationStack {
|
||||
RoomScreen(roomViewModel: readOnlyViewModels.room,
|
||||
timelineViewModel: readOnlyViewModels.timeline,
|
||||
composerToolbar: ComposerToolbar.mock())
|
||||
}
|
||||
.previewDisplayName("Read-only")
|
||||
.snapshotPreferences(expect: readOnlyViewModels.room.context.$viewState.map { !$0.canSendMessage })
|
||||
}
|
||||
|
||||
static func makeViewModels(canSendMessage: Bool = true) -> ViewModels {
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(id: "stable_id",
|
||||
name: "Preview room",
|
||||
hasOngoingCall: true,
|
||||
canUserSendMessage: canSendMessage))
|
||||
let roomViewModel = RoomScreenViewModel.mock(roomProxyMock: roomProxyMock)
|
||||
let timelineViewModel = TimelineViewModel(roomProxy: roomProxyMock,
|
||||
timelineController: MockTimelineController(),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
mediaPlayerProvider: MediaPlayerProviderMock(),
|
||||
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
||||
clientProxy: ClientProxyMock(.init()))
|
||||
|
||||
return .init(room: roomViewModel, timeline: timelineViewModel)
|
||||
}
|
||||
|
||||
struct ViewModels {
|
||||
let room: RoomScreenViewModelProtocol
|
||||
let timeline: TimelineViewModelProtocol
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user