Mute options
Set local timeout by nearest mute_until
This commit is contained in:
parent
ef981bff5d
commit
b15c51d5d1
@ -49,6 +49,7 @@ import { NULL_PEER_ID } from "../../lib/mtproto/mtproto_config";
|
|||||||
import IS_GROUP_CALL_SUPPORTED from "../../environment/groupCallSupport";
|
import IS_GROUP_CALL_SUPPORTED from "../../environment/groupCallSupport";
|
||||||
import IS_CALL_SUPPORTED from "../../environment/callSupport";
|
import IS_CALL_SUPPORTED from "../../environment/callSupport";
|
||||||
import { CallType } from "../../lib/calls/types";
|
import { CallType } from "../../lib/calls/types";
|
||||||
|
import PopupMute from "../popups/mute";
|
||||||
|
|
||||||
type ButtonToVerify = {element?: HTMLElement, verify: () => boolean};
|
type ButtonToVerify = {element?: HTMLElement, verify: () => boolean};
|
||||||
|
|
||||||
@ -319,15 +320,13 @@ export default class ChatTopbar {
|
|||||||
}, */{
|
}, */{
|
||||||
icon: 'mute',
|
icon: 'mute',
|
||||||
text: 'ChatList.Context.Mute',
|
text: 'ChatList.Context.Mute',
|
||||||
onClick: () => {
|
onClick: this.onMuteClick,
|
||||||
this.appMessagesManager.mutePeer(this.peerId);
|
|
||||||
},
|
|
||||||
verify: () => this.chat.type === 'chat' && rootScope.myId !== this.peerId && !this.appNotificationsManager.isPeerLocalMuted(this.peerId, false)
|
verify: () => this.chat.type === 'chat' && rootScope.myId !== this.peerId && !this.appNotificationsManager.isPeerLocalMuted(this.peerId, false)
|
||||||
}, {
|
}, {
|
||||||
icon: 'unmute',
|
icon: 'unmute',
|
||||||
text: 'ChatList.Context.Unmute',
|
text: 'ChatList.Context.Unmute',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
this.appMessagesManager.mutePeer(this.peerId);
|
this.appMessagesManager.togglePeerMute(this.peerId);
|
||||||
},
|
},
|
||||||
verify: () => this.chat.type === 'chat' && rootScope.myId !== this.peerId && this.appNotificationsManager.isPeerLocalMuted(this.peerId, false)
|
verify: () => this.chat.type === 'chat' && rootScope.myId !== this.peerId && this.appNotificationsManager.isPeerLocalMuted(this.peerId, false)
|
||||||
}, {
|
}, {
|
||||||
@ -544,9 +543,7 @@ export default class ChatTopbar {
|
|||||||
this.openPinned(true);
|
this.openPinned(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.attachClickEvent(this.btnMute, () => {
|
this.attachClickEvent(this.btnMute, this.onMuteClick);
|
||||||
this.appMessagesManager.mutePeer(this.peerId);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.attachClickEvent(this.btnJoin, () => {
|
this.attachClickEvent(this.btnJoin, () => {
|
||||||
const middleware = this.chat.bubbles.getMiddleware();
|
const middleware = this.chat.bubbles.getMiddleware();
|
||||||
@ -649,6 +646,10 @@ export default class ChatTopbar {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onMuteClick = () => {
|
||||||
|
new PopupMute(this.peerId);
|
||||||
|
};
|
||||||
|
|
||||||
private onResize = () => {
|
private onResize = () => {
|
||||||
this.setUtilsWidth(true);
|
this.setUtilsWidth(true);
|
||||||
this.setFloating();
|
this.setFloating();
|
||||||
|
@ -18,6 +18,7 @@ import PopupPeer from "./popups/peer";
|
|||||||
import AppChatFoldersTab from "./sidebarLeft/tabs/chatFolders";
|
import AppChatFoldersTab from "./sidebarLeft/tabs/chatFolders";
|
||||||
import appSidebarLeft from "./sidebarLeft";
|
import appSidebarLeft from "./sidebarLeft";
|
||||||
import { toastNew } from "./toast";
|
import { toastNew } from "./toast";
|
||||||
|
import PopupMute from "./popups/mute";
|
||||||
|
|
||||||
export default class DialogsContextMenu {
|
export default class DialogsContextMenu {
|
||||||
private element: HTMLElement;
|
private element: HTMLElement;
|
||||||
@ -123,11 +124,11 @@ export default class DialogsContextMenu {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private onUnmuteClick = () => {
|
private onUnmuteClick = () => {
|
||||||
appMessagesManager.mutePeer(this.selectedId, false);
|
appMessagesManager.togglePeerMute(this.selectedId, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onMuteClick = () => {
|
private onMuteClick = () => {
|
||||||
appMessagesManager.mutePeer(this.selectedId, true);
|
new PopupMute(this.selectedId);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onUnreadClick = () => {
|
private onUnreadClick = () => {
|
||||||
|
@ -156,7 +156,7 @@ export default class PeerProfile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//let checked = this.notificationsCheckbox.checked;
|
//let checked = this.notificationsCheckbox.checked;
|
||||||
appMessagesManager.mutePeer(this.peerId);
|
appMessagesManager.togglePeerMute(this.peerId);
|
||||||
});
|
});
|
||||||
|
|
||||||
rootScope.addEventListener('dialog_notify_settings', (dialog) => {
|
rootScope.addEventListener('dialog_notify_settings', (dialog) => {
|
||||||
|
77
src/components/popups/mute.ts
Normal file
77
src/components/popups/mute.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* https://github.com/morethanwords/tweb
|
||||||
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||||
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
import tsNow from "../../helpers/tsNow";
|
||||||
|
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||||
|
import { LangPackKey } from "../../lib/langPack";
|
||||||
|
import { MUTE_UNTIL } from "../../lib/mtproto/mtproto_config";
|
||||||
|
import RadioField from "../radioField";
|
||||||
|
import Row, { RadioFormFromRows } from "../row";
|
||||||
|
import { SettingSection } from "../sidebarLeft";
|
||||||
|
import PopupPeer from "./peer";
|
||||||
|
|
||||||
|
export default class PopupMute extends PopupPeer {
|
||||||
|
constructor(peerId: PeerId) {
|
||||||
|
super('popup-mute', {
|
||||||
|
peerId,
|
||||||
|
titleLangKey: 'Notifications',
|
||||||
|
buttons: [{
|
||||||
|
langKey: 'ChatList.Context.Mute',
|
||||||
|
callback: () => {
|
||||||
|
appMessagesManager.mutePeer(peerId, time === -1 ? MUTE_UNTIL : tsNow(true) + time);
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
body: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const ONE_HOUR = 3600;
|
||||||
|
const times: {time: number, langKey: LangPackKey}[] = [{
|
||||||
|
time: ONE_HOUR,
|
||||||
|
langKey: 'ChatList.Mute.1Hour'
|
||||||
|
}, {
|
||||||
|
time: ONE_HOUR * 4,
|
||||||
|
langKey: 'ChatList.Mute.4Hours'
|
||||||
|
}, {
|
||||||
|
time: ONE_HOUR * 8,
|
||||||
|
langKey: 'ChatList.Mute.8Hours'
|
||||||
|
}, {
|
||||||
|
time: ONE_HOUR * 24,
|
||||||
|
langKey: 'ChatList.Mute.1Day'
|
||||||
|
}, {
|
||||||
|
time: ONE_HOUR * 24 * 3,
|
||||||
|
langKey: 'ChatList.Mute.3Days'
|
||||||
|
}, {
|
||||||
|
time: -1,
|
||||||
|
langKey: 'ChatList.Mute.Forever'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const name = 'mute-time';
|
||||||
|
const rows = times.map((time) => {
|
||||||
|
const row = new Row({
|
||||||
|
radioField: new RadioField({
|
||||||
|
langKey: time.langKey,
|
||||||
|
name,
|
||||||
|
value: '' + time.time
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return row;
|
||||||
|
});
|
||||||
|
|
||||||
|
let time: number;
|
||||||
|
const radioForm = RadioFormFromRows(rows, (value) => {
|
||||||
|
time = +value;
|
||||||
|
});
|
||||||
|
|
||||||
|
rows[rows.length - 1].radioField.checked = true;
|
||||||
|
|
||||||
|
const section = new SettingSection({noShadow: true, noDelimiter: true});
|
||||||
|
section.content.append(radioForm);
|
||||||
|
this.body.append(section.container);
|
||||||
|
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
}
|
@ -90,7 +90,7 @@ export default class AppEditContactTab extends SliderSuperTab {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
appMessagesManager.mutePeer(this.peerId);
|
appMessagesManager.togglePeerMute(this.peerId);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.listenerSetter.add(rootScope)('notify_settings', (update) => {
|
this.listenerSetter.add(rootScope)('notify_settings', (update) => {
|
||||||
|
@ -814,6 +814,12 @@ const lang = {
|
|||||||
"ChatList.Filter.Exclude.LimitReached": "Sorry, you can only add up to 100 individual chats. Try using chat types.",
|
"ChatList.Filter.Exclude.LimitReached": "Sorry, you can only add up to 100 individual chats. Try using chat types.",
|
||||||
"ChatList.Filter.Confirm.Remove.Header": "Remove Folder",
|
"ChatList.Filter.Confirm.Remove.Header": "Remove Folder",
|
||||||
"ChatList.Filter.Confirm.Remove.Text": "Are you sure you want to remove this folder? Your chats will not be deleted.",
|
"ChatList.Filter.Confirm.Remove.Text": "Are you sure you want to remove this folder? Your chats will not be deleted.",
|
||||||
|
"ChatList.Mute.1Hour": "For 1 Hour",
|
||||||
|
"ChatList.Mute.4Hours": "For 4 Hours",
|
||||||
|
"ChatList.Mute.8Hours": "For 8 Hours",
|
||||||
|
"ChatList.Mute.1Day": "For 1 Day",
|
||||||
|
"ChatList.Mute.3Days": "For 3 Days",
|
||||||
|
"ChatList.Mute.Forever": "Forever",
|
||||||
"Channel.DescriptionHolderDescrpiton": "You can provide an optional description for your channel.",
|
"Channel.DescriptionHolderDescrpiton": "You can provide an optional description for your channel.",
|
||||||
"CreateGroup.NameHolder": "Group Name",
|
"CreateGroup.NameHolder": "Group Name",
|
||||||
"Date.Today": "Today",
|
"Date.Today": "Today",
|
||||||
|
@ -5127,16 +5127,12 @@ export class AppMessagesManager {
|
|||||||
return pendingMessage;
|
return pendingMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutePeer(peerId: PeerId, mute?: boolean) {
|
public mutePeer(peerId: PeerId, muteUntil: number) {
|
||||||
const settings: InputPeerNotifySettings = {
|
const settings: InputPeerNotifySettings = {
|
||||||
_: 'inputPeerNotifySettings'
|
_: 'inputPeerNotifySettings'
|
||||||
};
|
};
|
||||||
|
|
||||||
if(mute === undefined) {
|
settings.mute_until = muteUntil;
|
||||||
mute = !appNotificationsManager.isPeerLocalMuted(peerId, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.mute_until = mute ? MUTE_UNTIL : 0;
|
|
||||||
|
|
||||||
return appNotificationsManager.updateNotifySettings({
|
return appNotificationsManager.updateNotifySettings({
|
||||||
_: 'inputNotifyPeer',
|
_: 'inputNotifyPeer',
|
||||||
@ -5144,6 +5140,14 @@ export class AppMessagesManager {
|
|||||||
}, settings);
|
}, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public togglePeerMute(peerId: PeerId, mute?: boolean) {
|
||||||
|
if(mute === undefined) {
|
||||||
|
mute = !appNotificationsManager.isPeerLocalMuted(peerId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.mutePeer(peerId, mute ? MUTE_UNTIL : 0);
|
||||||
|
}
|
||||||
|
|
||||||
public canSendToPeer(peerId: PeerId, threadId?: number, action: ChatRights = 'send_messages') {
|
public canSendToPeer(peerId: PeerId, threadId?: number, action: ChatRights = 'send_messages') {
|
||||||
if(peerId.isAnyChat()) {
|
if(peerId.isAnyChat()) {
|
||||||
//const isChannel = appPeersManager.isChannel(peerId);
|
//const isChannel = appPeersManager.isChannel(peerId);
|
||||||
|
@ -29,6 +29,8 @@ import appRuntimeManager from "./appRuntimeManager";
|
|||||||
import appStateManager from "./appStateManager";
|
import appStateManager from "./appStateManager";
|
||||||
import appUsersManager from "./appUsersManager";
|
import appUsersManager from "./appUsersManager";
|
||||||
import IS_VIBRATE_SUPPORTED from "../../environment/vibrateSupport";
|
import IS_VIBRATE_SUPPORTED from "../../environment/vibrateSupport";
|
||||||
|
import { MUTE_UNTIL } from "../mtproto/mtproto_config";
|
||||||
|
import throttle from "../../helpers/schedulers/throttle";
|
||||||
|
|
||||||
type MyNotification = Notification & {
|
type MyNotification = Notification & {
|
||||||
hidden?: boolean,
|
hidden?: boolean,
|
||||||
@ -91,6 +93,9 @@ export class AppNotificationsManager {
|
|||||||
|
|
||||||
private getNotifyPeerTypePromise: Promise<any>;
|
private getNotifyPeerTypePromise: Promise<any>;
|
||||||
|
|
||||||
|
private checkMuteUntilTimeout: number;
|
||||||
|
private checkMuteUntilThrottled: () => void;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
navigator.vibrate = navigator.vibrate || navigator.mozVibrate || navigator.webkitVibrate;
|
navigator.vibrate = navigator.vibrate || navigator.mozVibrate || navigator.webkitVibrate;
|
||||||
@ -103,6 +108,8 @@ export class AppNotificationsManager {
|
|||||||
this.notifySoundEl.id = 'notify-sound';
|
this.notifySoundEl.id = 'notify-sound';
|
||||||
document.body.append(this.notifySoundEl);
|
document.body.append(this.notifySoundEl);
|
||||||
|
|
||||||
|
this.checkMuteUntilThrottled = throttle(this.checkMuteUntil, 1000, false);
|
||||||
|
|
||||||
rootScope.addEventListener('instance_deactivated', () => {
|
rootScope.addEventListener('instance_deactivated', () => {
|
||||||
this.stop();
|
this.stop();
|
||||||
});
|
});
|
||||||
@ -414,6 +421,45 @@ export class AppNotificationsManager {
|
|||||||
this.prevFavicon = href;
|
this.prevFavicon = href;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private checkMuteUntil = () => {
|
||||||
|
if(this.checkMuteUntilTimeout !== undefined) {
|
||||||
|
clearTimeout(this.checkMuteUntilTimeout);
|
||||||
|
this.checkMuteUntilTimeout = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timestamp = tsNow(true);
|
||||||
|
let closestMuteUntil = MUTE_UNTIL;
|
||||||
|
for(const peerId in this.peerSettings.notifyPeer) {
|
||||||
|
const peerNotifySettings = this.peerSettings.notifyPeer[peerId];
|
||||||
|
if(peerNotifySettings instanceof Promise) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const muteUntil = peerNotifySettings.mute_until;
|
||||||
|
if(muteUntil === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(muteUntil <= timestamp) {
|
||||||
|
// ! do not delete it because peer's unique settings will be overwritten in getPeerLocalSettings with type's settings
|
||||||
|
// delete peerNotifySettings.mute_until;
|
||||||
|
|
||||||
|
rootScope.dispatchEvent('updateNotifySettings', {
|
||||||
|
_: 'updateNotifySettings',
|
||||||
|
peer: {
|
||||||
|
_: 'notifyPeer',
|
||||||
|
peer: appPeersManager.getOutputPeer(peerId.toPeerId())
|
||||||
|
},
|
||||||
|
notify_settings: peerNotifySettings
|
||||||
|
});
|
||||||
|
} else if(muteUntil < closestMuteUntil) {
|
||||||
|
closestMuteUntil = muteUntil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.checkMuteUntilTimeout = window.setTimeout(this.checkMuteUntil, (closestMuteUntil - timestamp) * 1000);
|
||||||
|
};
|
||||||
|
|
||||||
public savePeerSettings({key, peerId, settings}: {
|
public savePeerSettings({key, peerId, settings}: {
|
||||||
key?: Exclude<NotifyPeer['_'], 'notifyPeer'>,
|
key?: Exclude<NotifyPeer['_'], 'notifyPeer'>,
|
||||||
peerId?: PeerId,
|
peerId?: PeerId,
|
||||||
@ -429,6 +475,8 @@ export class AppNotificationsManager {
|
|||||||
|
|
||||||
if(!peerId) {
|
if(!peerId) {
|
||||||
rootScope.dispatchEvent('notify_peer_type_settings', {key, settings});
|
rootScope.dispatchEvent('notify_peer_type_settings', {key, settings});
|
||||||
|
} else {
|
||||||
|
this.checkMuteUntilThrottled();
|
||||||
}
|
}
|
||||||
|
|
||||||
//rootScope.broadcast('notify_settings', {peerId: peerId});
|
//rootScope.broadcast('notify_settings', {peerId: peerId});
|
||||||
@ -436,7 +484,7 @@ export class AppNotificationsManager {
|
|||||||
|
|
||||||
public isMuted(peerNotifySettings: PeerNotifySettings) {
|
public isMuted(peerNotifySettings: PeerNotifySettings) {
|
||||||
return peerNotifySettings._ === 'peerNotifySettings' &&
|
return peerNotifySettings._ === 'peerNotifySettings' &&
|
||||||
((peerNotifySettings.mute_until * 1000) > tsNow() || peerNotifySettings.silent);
|
(peerNotifySettings.silent || (peerNotifySettings.mute_until !== undefined && (peerNotifySettings.mute_until * 1000) > tsNow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPeerMuted(peerId: PeerId) {
|
public getPeerMuted(peerId: PeerId) {
|
||||||
|
24
src/scss/partials/popups/_mute.scss
Normal file
24
src/scss/partials/popups/_mute.scss
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* https://github.com/morethanwords/tweb
|
||||||
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
||||||
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
.popup-mute {
|
||||||
|
.popup-container {
|
||||||
|
width: 16rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-body {
|
||||||
|
margin: 0 -.625rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-left-section {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -321,6 +321,7 @@ $chat-input-inner-padding-handhelds: .25rem;
|
|||||||
@import "partials/popups/groupCall";
|
@import "partials/popups/groupCall";
|
||||||
@import "partials/popups/call";
|
@import "partials/popups/call";
|
||||||
@import "partials/popups/sponsored";
|
@import "partials/popups/sponsored";
|
||||||
|
@import "partials/popups/mute";
|
||||||
|
|
||||||
@import "partials/pages/pages";
|
@import "partials/pages/pages";
|
||||||
@import "partials/pages/authCode";
|
@import "partials/pages/authCode";
|
||||||
|
Loading…
Reference in New Issue
Block a user