Merge pull request #788 from vector-im/pl-composer

Disable composer when user lacks powerlevel needed to send messages
This commit is contained in:
R Midhun Suresh 2022-07-07 17:35:29 +05:30 committed by GitHub
commit eac75644e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 15 deletions

View file

@ -37,9 +37,9 @@ export class RoomViewModel extends ViewModel {
this._sendError = null; this._sendError = null;
this._composerVM = null; this._composerVM = null;
if (room.isArchived) { if (room.isArchived) {
this._composerVM = new ArchivedViewModel(this.childOptions({archivedRoom: room})); this._composerVM = this.track(new ArchivedViewModel(this.childOptions({archivedRoom: room})));
} else { } else {
this._composerVM = new ComposerViewModel(this); this._recreateComposerOnPowerLevelChange();
} }
this._clearUnreadTimout = null; this._clearUnreadTimout = null;
this._closeUrl = this.urlCreator.urlUntilSegment("session"); this._closeUrl = this.urlCreator.urlUntilSegment("session");
@ -67,6 +67,30 @@ export class RoomViewModel extends ViewModel {
this._clearUnreadAfterDelay(); this._clearUnreadAfterDelay();
} }
async _recreateComposerOnPowerLevelChange() {
const powerLevelObservable = await this._room.observePowerLevels();
const canSendMessage = () => powerLevelObservable.get().canSendType("m.room.message");
let oldCanSendMessage = canSendMessage();
const recreateComposer = newCanSendMessage => {
this._composerVM = this.disposeTracked(this._composerVM);
if (newCanSendMessage) {
this._composerVM = this.track(new ComposerViewModel(this));
}
else {
this._composerVM = this.track(new LowerPowerLevelViewModel());
}
this.emitChange("powerLevelObservable")
};
this.track(powerLevelObservable.subscribe(() => {
const newCanSendMessage = canSendMessage();
if (oldCanSendMessage !== newCanSendMessage) {
recreateComposer(newCanSendMessage);
oldCanSendMessage = newCanSendMessage;
}
}));
recreateComposer(oldCanSendMessage);
}
async _clearUnreadAfterDelay() { async _clearUnreadAfterDelay() {
if (this._room.isArchived || this._clearUnreadTimout) { if (this._room.isArchived || this._clearUnreadTimout) {
return; return;
@ -362,6 +386,16 @@ class ArchivedViewModel extends ViewModel {
} }
get kind() { get kind() {
return "archived"; return "disabled";
}
}
class LowerPowerLevelViewModel extends ViewModel {
get description() {
return this.i18n`You do not have the powerlevel necessary to send messages`;
}
get kind() {
return "disabled";
} }
} }

View file

@ -894,12 +894,12 @@ button.link {
width: 100%; width: 100%;
} }
.RoomArchivedView { .DisabledComposerView {
padding: 12px; padding: 12px;
background-color: var(--background-color-secondary); background-color: var(--background-color-secondary);
} }
.RoomArchivedView h3 { .DisabledComposerView h3 {
margin: 0; margin: 0;
} }

View file

@ -16,8 +16,8 @@ limitations under the License.
import {TemplateView} from "../../general/TemplateView"; import {TemplateView} from "../../general/TemplateView";
export class RoomArchivedView extends TemplateView { export class DisabledComposerView extends TemplateView {
render(t) { render(t) {
return t.div({className: "RoomArchivedView"}, t.h3(vm => vm.description)); return t.div({className: "DisabledComposerView"}, t.h3(vm => vm.description));
} }
} }

View file

@ -21,7 +21,7 @@ import {Menu} from "../../general/Menu.js";
import {TimelineView} from "./TimelineView"; import {TimelineView} from "./TimelineView";
import {TimelineLoadingView} from "./TimelineLoadingView.js"; import {TimelineLoadingView} from "./TimelineLoadingView.js";
import {MessageComposer} from "./MessageComposer.js"; import {MessageComposer} from "./MessageComposer.js";
import {RoomArchivedView} from "./RoomArchivedView.js"; import {DisabledComposerView} from "./DisabledComposerView.js";
import {AvatarView} from "../../AvatarView.js"; import {AvatarView} from "../../AvatarView.js";
export class RoomView extends TemplateView { export class RoomView extends TemplateView {
@ -32,12 +32,6 @@ export class RoomView extends TemplateView {
} }
render(t, vm) { render(t, vm) {
let bottomView;
if (vm.composerViewModel.kind === "composer") {
bottomView = new MessageComposer(vm.composerViewModel, this._viewClassForTile);
} else if (vm.composerViewModel.kind === "archived") {
bottomView = new RoomArchivedView(vm.composerViewModel);
}
return t.main({className: "RoomView middle"}, [ return t.main({className: "RoomView middle"}, [
t.div({className: "RoomHeader middle-header"}, [ t.div({className: "RoomHeader middle-header"}, [
t.a({className: "button-utility close-middle", href: vm.closeUrl, title: vm.i18n`Close room`}), t.a({className: "button-utility close-middle", href: vm.closeUrl, title: vm.i18n`Close room`}),
@ -58,7 +52,15 @@ export class RoomView extends TemplateView {
new TimelineView(timelineViewModel, this._viewClassForTile) : new TimelineView(timelineViewModel, this._viewClassForTile) :
new TimelineLoadingView(vm); // vm is just needed for i18n new TimelineLoadingView(vm); // vm is just needed for i18n
}), }),
t.view(bottomView), t.mapView(vm => vm.composerViewModel,
composerViewModel => {
switch (composerViewModel?.kind) {
case "composer":
return new MessageComposer(vm.composerViewModel, this._viewClassForTile);
case "disabled":
return new DisabledComposerView(vm.composerViewModel);
}
}),
]) ])
]); ]);
} }