Merge pull request #788 from vector-im/pl-composer
Disable composer when user lacks powerlevel needed to send messages
This commit is contained in:
commit
eac75644e7
4 changed files with 51 additions and 15 deletions
|
@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue