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_CALL_SUPPORTED from "../../environment/callSupport";
|
||||
import { CallType } from "../../lib/calls/types";
|
||||
import PopupMute from "../popups/mute";
|
||||
|
||||
type ButtonToVerify = {element?: HTMLElement, verify: () => boolean};
|
||||
|
||||
@ -319,15 +320,13 @@ export default class ChatTopbar {
|
||||
}, */{
|
||||
icon: 'mute',
|
||||
text: 'ChatList.Context.Mute',
|
||||
onClick: () => {
|
||||
this.appMessagesManager.mutePeer(this.peerId);
|
||||
},
|
||||
onClick: this.onMuteClick,
|
||||
verify: () => this.chat.type === 'chat' && rootScope.myId !== this.peerId && !this.appNotificationsManager.isPeerLocalMuted(this.peerId, false)
|
||||
}, {
|
||||
icon: 'unmute',
|
||||
text: 'ChatList.Context.Unmute',
|
||||
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)
|
||||
}, {
|
||||
@ -544,9 +543,7 @@ export default class ChatTopbar {
|
||||
this.openPinned(true);
|
||||
});
|
||||
|
||||
this.attachClickEvent(this.btnMute, () => {
|
||||
this.appMessagesManager.mutePeer(this.peerId);
|
||||
});
|
||||
this.attachClickEvent(this.btnMute, this.onMuteClick);
|
||||
|
||||
this.attachClickEvent(this.btnJoin, () => {
|
||||
const middleware = this.chat.bubbles.getMiddleware();
|
||||
@ -649,6 +646,10 @@ export default class ChatTopbar {
|
||||
});
|
||||
}
|
||||
|
||||
private onMuteClick = () => {
|
||||
new PopupMute(this.peerId);
|
||||
};
|
||||
|
||||
private onResize = () => {
|
||||
this.setUtilsWidth(true);
|
||||
this.setFloating();
|
||||
|
@ -18,6 +18,7 @@ import PopupPeer from "./popups/peer";
|
||||
import AppChatFoldersTab from "./sidebarLeft/tabs/chatFolders";
|
||||
import appSidebarLeft from "./sidebarLeft";
|
||||
import { toastNew } from "./toast";
|
||||
import PopupMute from "./popups/mute";
|
||||
|
||||
export default class DialogsContextMenu {
|
||||
private element: HTMLElement;
|
||||
@ -123,11 +124,11 @@ export default class DialogsContextMenu {
|
||||
};
|
||||
|
||||
private onUnmuteClick = () => {
|
||||
appMessagesManager.mutePeer(this.selectedId, false);
|
||||
appMessagesManager.togglePeerMute(this.selectedId, false);
|
||||
};
|
||||
|
||||
private onMuteClick = () => {
|
||||
appMessagesManager.mutePeer(this.selectedId, true);
|
||||
new PopupMute(this.selectedId);
|
||||
};
|
||||
|
||||
private onUnreadClick = () => {
|
||||
|
@ -156,7 +156,7 @@ export default class PeerProfile {
|
||||
}
|
||||
|
||||
//let checked = this.notificationsCheckbox.checked;
|
||||
appMessagesManager.mutePeer(this.peerId);
|
||||
appMessagesManager.togglePeerMute(this.peerId);
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
appMessagesManager.mutePeer(this.peerId);
|
||||
appMessagesManager.togglePeerMute(this.peerId);
|
||||
});
|
||||
|
||||
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.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.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.",
|
||||
"CreateGroup.NameHolder": "Group Name",
|
||||
"Date.Today": "Today",
|
||||
|
@ -5127,16 +5127,12 @@ export class AppMessagesManager {
|
||||
return pendingMessage;
|
||||
}
|
||||
|
||||
public mutePeer(peerId: PeerId, mute?: boolean) {
|
||||
public mutePeer(peerId: PeerId, muteUntil: number) {
|
||||
const settings: InputPeerNotifySettings = {
|
||||
_: 'inputPeerNotifySettings'
|
||||
};
|
||||
|
||||
if(mute === undefined) {
|
||||
mute = !appNotificationsManager.isPeerLocalMuted(peerId, false);
|
||||
}
|
||||
|
||||
settings.mute_until = mute ? MUTE_UNTIL : 0;
|
||||
settings.mute_until = muteUntil;
|
||||
|
||||
return appNotificationsManager.updateNotifySettings({
|
||||
_: 'inputNotifyPeer',
|
||||
@ -5144,6 +5140,14 @@ export class AppMessagesManager {
|
||||
}, 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') {
|
||||
if(peerId.isAnyChat()) {
|
||||
//const isChannel = appPeersManager.isChannel(peerId);
|
||||
|
@ -29,6 +29,8 @@ import appRuntimeManager from "./appRuntimeManager";
|
||||
import appStateManager from "./appStateManager";
|
||||
import appUsersManager from "./appUsersManager";
|
||||
import IS_VIBRATE_SUPPORTED from "../../environment/vibrateSupport";
|
||||
import { MUTE_UNTIL } from "../mtproto/mtproto_config";
|
||||
import throttle from "../../helpers/schedulers/throttle";
|
||||
|
||||
type MyNotification = Notification & {
|
||||
hidden?: boolean,
|
||||
@ -91,6 +93,9 @@ export class AppNotificationsManager {
|
||||
|
||||
private getNotifyPeerTypePromise: Promise<any>;
|
||||
|
||||
private checkMuteUntilTimeout: number;
|
||||
private checkMuteUntilThrottled: () => void;
|
||||
|
||||
constructor() {
|
||||
// @ts-ignore
|
||||
navigator.vibrate = navigator.vibrate || navigator.mozVibrate || navigator.webkitVibrate;
|
||||
@ -103,6 +108,8 @@ export class AppNotificationsManager {
|
||||
this.notifySoundEl.id = 'notify-sound';
|
||||
document.body.append(this.notifySoundEl);
|
||||
|
||||
this.checkMuteUntilThrottled = throttle(this.checkMuteUntil, 1000, false);
|
||||
|
||||
rootScope.addEventListener('instance_deactivated', () => {
|
||||
this.stop();
|
||||
});
|
||||
@ -414,6 +421,45 @@ export class AppNotificationsManager {
|
||||
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}: {
|
||||
key?: Exclude<NotifyPeer['_'], 'notifyPeer'>,
|
||||
peerId?: PeerId,
|
||||
@ -429,6 +475,8 @@ export class AppNotificationsManager {
|
||||
|
||||
if(!peerId) {
|
||||
rootScope.dispatchEvent('notify_peer_type_settings', {key, settings});
|
||||
} else {
|
||||
this.checkMuteUntilThrottled();
|
||||
}
|
||||
|
||||
//rootScope.broadcast('notify_settings', {peerId: peerId});
|
||||
@ -436,7 +484,7 @@ export class AppNotificationsManager {
|
||||
|
||||
public isMuted(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) {
|
||||
|
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/call";
|
||||
@import "partials/popups/sponsored";
|
||||
@import "partials/popups/mute";
|
||||
|
||||
@import "partials/pages/pages";
|
||||
@import "partials/pages/authCode";
|
||||
|
Loading…
Reference in New Issue
Block a user