Merge pull request #5873 from matrix-org/travis/dnd
Labs: Add quick/cheap "do not disturb" flag
This commit is contained in:
commit
bf70666f9b
5 changed files with 64 additions and 0 deletions
|
@ -117,6 +117,32 @@ limitations under the License.
|
||||||
.mx_UserMenu_headerButtons {
|
.mx_UserMenu_headerButtons {
|
||||||
// No special styles: the rest of the layout happens to make it work.
|
// No special styles: the rest of the layout happens to make it work.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_UserMenu_dnd {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 8px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
mask-position: center;
|
||||||
|
mask-size: contain;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
background: $muted-fg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mx_UserMenu_dnd_noisy::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/notifications.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mx_UserMenu_dnd_muted::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/roomlist/notifications-off.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mx_UserMenu_minimized {
|
&.mx_UserMenu_minimized {
|
||||||
|
|
|
@ -383,6 +383,10 @@ export const Notifier = {
|
||||||
// don't bother notifying as user was recently active in this room
|
// don't bother notifying as user was recently active in this room
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (SettingsStore.getValue("doNotDisturb")) {
|
||||||
|
// Don't bother the user if they didn't ask to be bothered
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.isEnabled()) {
|
if (this.isEnabled()) {
|
||||||
this._displayPopupNotification(ev, room);
|
this._displayPopupNotification(ev, room);
|
||||||
|
|
|
@ -74,6 +74,7 @@ interface IState {
|
||||||
export default class UserMenu extends React.Component<IProps, IState> {
|
export default class UserMenu extends React.Component<IProps, IState> {
|
||||||
private dispatcherRef: string;
|
private dispatcherRef: string;
|
||||||
private themeWatcherRef: string;
|
private themeWatcherRef: string;
|
||||||
|
private dndWatcherRef: string;
|
||||||
private buttonRef: React.RefObject<HTMLButtonElement> = createRef();
|
private buttonRef: React.RefObject<HTMLButtonElement> = createRef();
|
||||||
private tagStoreRef: fbEmitter.EventSubscription;
|
private tagStoreRef: fbEmitter.EventSubscription;
|
||||||
|
|
||||||
|
@ -89,6 +90,9 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||||
if (SettingsStore.getValue("feature_spaces")) {
|
if (SettingsStore.getValue("feature_spaces")) {
|
||||||
SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdate);
|
SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force update is the easiest way to trigger the UI update (we don't store state for this)
|
||||||
|
this.dndWatcherRef = SettingsStore.watchSetting("doNotDisturb", null, () => this.forceUpdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
private get hasHomePage(): boolean {
|
private get hasHomePage(): boolean {
|
||||||
|
@ -103,6 +107,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
if (this.themeWatcherRef) SettingsStore.unwatchSetting(this.themeWatcherRef);
|
if (this.themeWatcherRef) SettingsStore.unwatchSetting(this.themeWatcherRef);
|
||||||
|
if (this.dndWatcherRef) SettingsStore.unwatchSetting(this.dndWatcherRef);
|
||||||
if (this.dispatcherRef) defaultDispatcher.unregister(this.dispatcherRef);
|
if (this.dispatcherRef) defaultDispatcher.unregister(this.dispatcherRef);
|
||||||
OwnProfileStore.instance.off(UPDATE_EVENT, this.onProfileUpdate);
|
OwnProfileStore.instance.off(UPDATE_EVENT, this.onProfileUpdate);
|
||||||
this.tagStoreRef.remove();
|
this.tagStoreRef.remove();
|
||||||
|
@ -288,6 +293,12 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||||
this.setState({contextMenuPosition: null}); // also close the menu
|
this.setState({contextMenuPosition: null}); // also close the menu
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onDndToggle = (ev) => {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const current = SettingsStore.getValue("doNotDisturb");
|
||||||
|
SettingsStore.setValue("doNotDisturb", null, SettingLevel.DEVICE, !current);
|
||||||
|
};
|
||||||
|
|
||||||
private renderContextMenu = (): React.ReactNode => {
|
private renderContextMenu = (): React.ReactNode => {
|
||||||
if (!this.state.contextMenuPosition) return null;
|
if (!this.state.contextMenuPosition) return null;
|
||||||
|
|
||||||
|
@ -534,6 +545,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||||
{/* masked image in CSS */}
|
{/* masked image in CSS */}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
let dnd;
|
||||||
if (this.state.selectedSpace) {
|
if (this.state.selectedSpace) {
|
||||||
name = (
|
name = (
|
||||||
<div className="mx_UserMenu_doubleName">
|
<div className="mx_UserMenu_doubleName">
|
||||||
|
@ -560,6 +572,16 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
isPrototype = true;
|
isPrototype = true;
|
||||||
|
} else if (SettingsStore.getValue("feature_dnd")) {
|
||||||
|
const isDnd = SettingsStore.getValue("doNotDisturb");
|
||||||
|
dnd = <AccessibleButton
|
||||||
|
onClick={this.onDndToggle}
|
||||||
|
className={classNames({
|
||||||
|
"mx_UserMenu_dnd": true,
|
||||||
|
"mx_UserMenu_dnd_noisy": !isDnd,
|
||||||
|
"mx_UserMenu_dnd_muted": isDnd,
|
||||||
|
})}
|
||||||
|
/>;
|
||||||
}
|
}
|
||||||
if (this.props.isMinimized) {
|
if (this.props.isMinimized) {
|
||||||
name = null;
|
name = null;
|
||||||
|
@ -595,6 +617,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
{name}
|
{name}
|
||||||
|
{dnd}
|
||||||
{buttons}
|
{buttons}
|
||||||
</div>
|
</div>
|
||||||
</ContextMenuButton>
|
</ContextMenuButton>
|
||||||
|
|
|
@ -786,6 +786,7 @@
|
||||||
"%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
|
"%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
|
||||||
"Change notification settings": "Change notification settings",
|
"Change notification settings": "Change notification settings",
|
||||||
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.",
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.",
|
||||||
|
"Show options to enable 'Do not disturb' mode": "Show options to enable 'Do not disturb' mode",
|
||||||
"Send and receive voice messages (in development)": "Send and receive voice messages (in development)",
|
"Send and receive voice messages (in development)": "Send and receive voice messages (in development)",
|
||||||
"Render LaTeX maths in messages": "Render LaTeX maths in messages",
|
"Render LaTeX maths in messages": "Render LaTeX maths in messages",
|
||||||
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.",
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.",
|
||||||
|
|
|
@ -128,6 +128,12 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
default: false,
|
default: false,
|
||||||
controller: new ReloadOnChangeController(),
|
controller: new ReloadOnChangeController(),
|
||||||
},
|
},
|
||||||
|
"feature_dnd": {
|
||||||
|
isFeature: true,
|
||||||
|
displayName: _td("Show options to enable 'Do not disturb' mode"),
|
||||||
|
supportedLevels: LEVELS_FEATURE,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
"feature_voice_messages": {
|
"feature_voice_messages": {
|
||||||
isFeature: true,
|
isFeature: true,
|
||||||
displayName: _td("Send and receive voice messages (in development)"),
|
displayName: _td("Send and receive voice messages (in development)"),
|
||||||
|
@ -226,6 +232,10 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
"doNotDisturb": {
|
||||||
|
supportedLevels: [SettingLevel.DEVICE],
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
"mjolnirRooms": {
|
"mjolnirRooms": {
|
||||||
supportedLevels: [SettingLevel.ACCOUNT],
|
supportedLevels: [SettingLevel.ACCOUNT],
|
||||||
default: [],
|
default: [],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue