Update icons
Unread badge
This commit is contained in:
parent
ea085e20c7
commit
bad2574647
@ -310,7 +310,7 @@ export class AppSidebarLeft extends SidebarSlider {
|
||||
rootScope.addEventListener('folder_unread', (folder) => {
|
||||
if(folder.id === 1) {
|
||||
// const count = folder.unreadMessagesCount;
|
||||
const count = folder.unreadDialogsCount;
|
||||
const count = folder.unreadPeerIds.size;
|
||||
this.archivedCount.innerText = '' + formatNumber(count, 1);
|
||||
this.archivedCount.classList.toggle('hide', !count);
|
||||
}
|
||||
|
@ -3,26 +3,45 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Telegram Web</title>
|
||||
<meta name="description" content="Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.">
|
||||
<title>{{htmlWebpackPlugin.options.title}}</title>
|
||||
<meta name="description" content="{{htmlWebpackPlugin.options.description}}">
|
||||
<!--<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||
|
||||
<!-- do not paste other icons here, only change these. 'icon' type must be single -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/img/apple-touch-icon.png?v=jw3mK7G9Ry">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/img/favicon-32x32.png?v=jw3mK7G9Ry">
|
||||
<!--<link rel="icon" type="image/png" sizes="192x192" href="assets/img/android-chrome-192x192.png?v=jw3mK7G9Ry">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/img/favicon-16x16.png?v=jw3mK7G9Ry">-->
|
||||
<link rel="manifest" href="site.webmanifest?v=jw3mK7G9Aq">
|
||||
<link rel="mask-icon" href="assets/img/safari-pinned-tab.svg?v=jw3mK7G9Ry" color="#3390ec">
|
||||
<!--<link rel="shortcut icon" href="assets/img/favicon.ico?v=jw3mK7G9Ry">-->
|
||||
<meta name="apple-mobile-web-app-title" content="Telegram WebK">
|
||||
<meta name="application-name" content="Telegram WebK">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-title" content="{{htmlWebpackPlugin.options.title}}">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-title" content="{{htmlWebpackPlugin.options.title}}">
|
||||
<meta name="application-name" content="{{htmlWebpackPlugin.options.title}}">
|
||||
<meta name="msapplication-TileColor" content="#2d89ef">
|
||||
<meta name="msapplication-TileImage" content="assets/img/mstile-144x144.png?v=jw3mK7G9Ry">
|
||||
<meta name="msapplication-config" content="browserconfig.xml?v=jw3mK7G9Ry">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<meta name="color-scheme" content="light">
|
||||
<meta name="google" content="notranslate">
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="{{htmlWebpackPlugin.options.url}}">
|
||||
<meta property="og:title" content="{{htmlWebpackPlugin.options.title}}">
|
||||
<meta property="og:description" content="{{htmlWebpackPlugin.options.description}}">
|
||||
<meta property="og:image" content="assets/img/android-chrome-192x192.png?v=jw3mK7G9Ry">
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:url" content="{{htmlWebpackPlugin.options.url}}">
|
||||
<meta property="twitter:title" content="{{htmlWebpackPlugin.options.title}}">
|
||||
<meta property="twitter:description" content="{{htmlWebpackPlugin.options.description}}">
|
||||
<meta property="twitter:image" content="assets/img/android-chrome-192x192.png?v=jw3mK7G9Ry">
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/img/apple-touch-icon.png?v=jw3mK7G9Ry">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/img/favicon-16x16.png?v=jw3mK7G9Ry">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/img/favicon-32x32.png?v=jw3mK7G9Ry">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="assets/img/android-chrome-192x192.png?v=jw3mK7G9Ry">
|
||||
<link rel="alternate icon" href="assets/img/favicon.ico?v=jw3mK7G9Ry" type="image/x-icon">
|
||||
<link rel="mask-icon" href="assets/img/safari-pinned-tab.svg?v=jw3mK7G9Ry" color="#3390ec">
|
||||
|
||||
<link rel="manifest" id="manifest">
|
||||
|
||||
{{#each htmlWebpackPlugin.files.css}}
|
||||
<link rel="stylesheet" href="{{this}}">
|
||||
{{/each}}
|
||||
|
@ -32,6 +32,9 @@ document.addEventListener('DOMContentLoaded', async() => {
|
||||
|
||||
rootScope.managers = getProxiedManagers();
|
||||
|
||||
const manifest = document.getElementById('manifest') as HTMLLinkElement;
|
||||
manifest.href = `site${IS_APPLE && !IS_APPLE_MOBILE ? '_apple' : ''}.webmanifest?v=jw3mK7G9Aq`;
|
||||
|
||||
singleInstance.start();
|
||||
|
||||
// We listen to the resize event (https://css-tricks.com/the-trick-to-viewport-units-on-mobile/)
|
||||
|
@ -205,7 +205,6 @@ export class AppDialogsManager {
|
||||
}
|
||||
} = {};
|
||||
private showFiltersPromise: Promise<void>;
|
||||
private allUnreadCount: HTMLElement;
|
||||
|
||||
private sliceTimeout: number;
|
||||
|
||||
@ -236,8 +235,6 @@ export class AppDialogsManager {
|
||||
|
||||
this.contextMenu = new DialogsContextMenu(managers);
|
||||
|
||||
this.allUnreadCount = this.folders.menu.querySelector('.badge');
|
||||
|
||||
this.folders.menuScrollContainer = this.folders.menu.parentElement;
|
||||
|
||||
this.onListLengthChange = debounce(this._onListLengthChange, 100, false, true);
|
||||
@ -524,7 +521,6 @@ export class AppDialogsManager {
|
||||
rootScope.addEventListener('dialog_notify_settings', (dialog) => {
|
||||
this.validateDialogForFilter(dialog);
|
||||
this.setUnreadMessagesN({dialog}); // возможно это не нужно, но нужно менять is-muted
|
||||
this.setFiltersUnreadCount();
|
||||
});
|
||||
|
||||
rootScope.addEventListener('dialog_draft', ({dialog, drop, peerId}) => {
|
||||
@ -667,20 +663,6 @@ export class AppDialogsManager {
|
||||
}
|
||||
}
|
||||
|
||||
if(state.notifySettings) {
|
||||
const promises: Promise<any>[] = [];
|
||||
for(const key in state.notifySettings) {
|
||||
assumeType<Exclude<NotifyPeer['_'], 'notifyPeer'>>(key);
|
||||
const promise = this.managers.appNotificationsManager.savePeerSettings({
|
||||
key,
|
||||
settings: state.notifySettings[key]
|
||||
});
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
this.managers.appNotificationsManager.getNotifyPeerTypeSettings();
|
||||
|
||||
await (await loadDialogsPromise).renderPromise;
|
||||
@ -755,13 +737,17 @@ export class AppDialogsManager {
|
||||
};
|
||||
|
||||
private async setFilterUnreadCount(filterId: number) {
|
||||
const unreadSpan = filterId === 0 ? this.allUnreadCount : this.filtersRendered[filterId]?.unread;
|
||||
if(filterId === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const unreadSpan = this.filtersRendered[filterId]?.unread;
|
||||
if(!unreadSpan) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {foundUnmuted, unreadCount} = await this.managers.dialogsStorage.getFolderUnreadCount(filterId);
|
||||
unreadSpan.classList.toggle('badge-gray', !foundUnmuted);
|
||||
const {unreadUnmutedCount, unreadCount} = await this.managers.dialogsStorage.getFolderUnreadCount(filterId);
|
||||
unreadSpan.classList.toggle('badge-gray', !unreadUnmutedCount);
|
||||
unreadSpan.innerText = unreadCount ? '' + unreadCount : '';
|
||||
}
|
||||
|
||||
|
@ -3113,18 +3113,14 @@ export class AppMessagesManager extends AppManager {
|
||||
if(!this.migratedFromTo[migrateFrom] &&
|
||||
!this.migratedToFrom[migrateTo] &&
|
||||
this.appChatsManager.hasChat(migrateTo.toChatId())) {
|
||||
const fromChat = this.appChatsManager.getChat(migrateFrom.toChatId());
|
||||
if(fromChat &&
|
||||
fromChat.migrated_to &&
|
||||
fromChat.migrated_to.channel_id === migrateTo.toChatId()) {
|
||||
this.migratedFromTo[migrateFrom] = migrateTo;
|
||||
this.migratedToFrom[migrateTo] = migrateFrom;
|
||||
const fromChat: Chat.chat = this.appChatsManager.getChat(migrateFrom.toChatId());
|
||||
if(fromChat?.migrated_to && (fromChat.migrated_to as InputChannel.inputChannel).channel_id === migrateTo.toChatId()) {
|
||||
this.migratedFromTo[migrateFrom] = migrateTo;
|
||||
this.migratedToFrom[migrateTo] = migrateFrom;
|
||||
|
||||
//setTimeout(() => {
|
||||
this.rootScope.dispatchEvent('dialog_migrate', {migrateFrom, migrateTo});
|
||||
this.rootScope.dispatchEvent('dialog_migrate', {migrateFrom, migrateTo});
|
||||
|
||||
this.dialogsStorage.dropDialogWithEvent(migrateFrom);
|
||||
//}, 100);
|
||||
this.dialogsStorage.dropDialogWithEvent(migrateFrom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import convertInputKeyToKey from "../../helpers/string/convertInputKeyToKey";
|
||||
import { AppManager } from "./manager";
|
||||
import getPeerId from "./utils/peers/getPeerId";
|
||||
import ctx from "../../environment/ctx";
|
||||
import assumeType from "../../helpers/assumeType";
|
||||
|
||||
type ImSadAboutIt = Promise<PeerNotifySettings> | PeerNotifySettings;
|
||||
export class AppNotificationsManager extends AppManager {
|
||||
@ -50,6 +51,18 @@ export class AppNotificationsManager extends AppManager {
|
||||
this.rootScope.dispatchEvent('notify_settings', update);
|
||||
}
|
||||
});
|
||||
|
||||
return this.appStateManager.getState().then((state) => {
|
||||
if(state.notifySettings) {
|
||||
for(const key in state.notifySettings) {
|
||||
assumeType<Exclude<NotifyPeer['_'], 'notifyPeer'>>(key);
|
||||
this.savePeerSettings({
|
||||
key,
|
||||
settings: state.notifySettings[key]
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public getNotifySettings(peer: InputNotifyPeer): ImSadAboutIt {
|
||||
|
@ -108,7 +108,7 @@ export default function createManagers(appStoragesManager: AppStoragesManager, u
|
||||
|
||||
const promises: Array<Promise<(() => void) | void> | void>[] = [];
|
||||
let names = Object.keys(managers) as (keyof T)[];
|
||||
names.unshift('appUsersManager', 'appChatsManager', 'appMessagesManager', 'dialogsStorage');
|
||||
names.unshift('appUsersManager', 'appChatsManager', 'appNotificationsManager', 'appMessagesManager', 'dialogsStorage');
|
||||
names = filterUnique(names);
|
||||
for(const name of names) {
|
||||
const manager = managers[name];
|
||||
|
@ -82,11 +82,14 @@ export class UiNotificationsManager {
|
||||
private pushInited = false;
|
||||
|
||||
private managers: AppManagers;
|
||||
private setAppBadge: (contents?: any) => Promise<void>;
|
||||
|
||||
construct(managers: AppManagers) {
|
||||
this.managers = managers;
|
||||
|
||||
navigator.vibrate = navigator.vibrate || (navigator as any).mozVibrate || (navigator as any).webkitVibrate;
|
||||
this.setAppBadge = (navigator as any).setAppBadge && (navigator as any).setAppBadge.bind(navigator);
|
||||
this.setAppBadge && this.setAppBadge(0);
|
||||
|
||||
this.notificationsUiSupport = ('Notification' in window) || ('mozNotification' in navigator);
|
||||
|
||||
@ -125,6 +128,14 @@ export class UiNotificationsManager {
|
||||
rootScope.addEventListener('notification_cancel', (str) => {
|
||||
this.cancel(str);
|
||||
});
|
||||
|
||||
if(this.setAppBadge) {
|
||||
rootScope.addEventListener('folder_unread', (folder) => {
|
||||
if(folder.id === 0) {
|
||||
this.setAppBadge(folder.unreadUnmutedPeerIds.size);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
webPushApiManager.addEventListener('push_init', (tokenData) => {
|
||||
this.pushInited = true;
|
||||
@ -280,7 +291,7 @@ export class UiNotificationsManager {
|
||||
private toggleToggler(enable = idleController.isIdle) {
|
||||
if(IS_MOBILE) return;
|
||||
|
||||
const resetTitle = () => {
|
||||
const resetTitle = (isBlink?: boolean) => {
|
||||
this.titleChanged = false;
|
||||
document.title = this.titleBackup;
|
||||
this.setFavicon();
|
||||
@ -297,7 +308,7 @@ export class UiNotificationsManager {
|
||||
if(!count) {
|
||||
this.toggleToggler(false);
|
||||
} else if(this.titleChanged) {
|
||||
resetTitle();
|
||||
resetTitle(true);
|
||||
} else {
|
||||
this.titleChanged = true;
|
||||
document.title = I18n.format('Notifications.Count', true, [count]);
|
||||
|
@ -45,7 +45,8 @@ export type Folder = {
|
||||
dialogs: Dialog[],
|
||||
id: number,
|
||||
unreadMessagesCount: number,
|
||||
unreadDialogsCount: number,
|
||||
unreadPeerIds: Set<PeerId>,
|
||||
unreadUnmutedPeerIds: Set<PeerId>,
|
||||
dispatchUnreadTimeout?: number
|
||||
};
|
||||
|
||||
@ -131,6 +132,7 @@ export default class DialogsStorage extends AppManager {
|
||||
|
||||
this.rootScope.addEventListener('dialog_notify_settings', (dialog) => {
|
||||
this.processDialogForFilters(dialog);
|
||||
this.prepareDialogUnreadCountModifying(dialog)();
|
||||
});
|
||||
|
||||
this.rootScope.addEventListener('chat_update', (chatId) => {
|
||||
@ -287,7 +289,14 @@ export default class DialogsStorage extends AppManager {
|
||||
public getFolder(id: number) {
|
||||
let folder = this.folders[id];
|
||||
if(!folder) {
|
||||
folder = this.folders[id] = {dialogs: [], id, unreadMessagesCount: 0, unreadDialogsCount: 0};
|
||||
folder = this.folders[id] = {
|
||||
dialogs: [],
|
||||
id,
|
||||
unreadMessagesCount: 0,
|
||||
unreadPeerIds: new Set(),
|
||||
unreadUnmutedPeerIds: new Set()
|
||||
};
|
||||
|
||||
defineNotNumerableProperties(folder, ['dispatchUnreadTimeout']);
|
||||
}
|
||||
|
||||
@ -326,14 +335,14 @@ export default class DialogsStorage extends AppManager {
|
||||
const filter = this.filtersStorage.getFilter(filterId);
|
||||
return getDialogIndexKey(filter.orderIndex);
|
||||
}
|
||||
|
||||
public isPeerUnmuted(peerId: PeerId) {
|
||||
return !this.appNotificationsManager.isPeerLocalMuted(peerId, true);
|
||||
}
|
||||
|
||||
public getFolderUnreadCount(filterId: number) {
|
||||
const folder = this.getFolder(filterId);
|
||||
const foundUnmuted = filterId === 0 || !!folder.dialogs.find((dialog) => {
|
||||
return (dialog.unread_count || dialog.pFlags.unread_mark) && !this.appNotificationsManager.isPeerLocalMuted(dialog.peerId, true);
|
||||
});
|
||||
|
||||
return {foundUnmuted, unreadCount: folder.unreadDialogsCount};
|
||||
return {unreadUnmutedCount: folder.unreadUnmutedPeerIds.size, unreadCount: folder.unreadPeerIds.size};
|
||||
}
|
||||
|
||||
public getCachedDialogs(skipMigrated?: boolean) {
|
||||
@ -435,7 +444,7 @@ export default class DialogsStorage extends AppManager {
|
||||
const newDialogIndex = this.setDialogIndexInFilter(dialog, indexKey, filter);
|
||||
|
||||
if(wasDialogIndex === newDialogIndex) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if((!wasDialogIndex && newDialogIndex) || (wasIndex && !newDialogIndex)) {
|
||||
@ -449,6 +458,8 @@ export default class DialogsStorage extends AppManager {
|
||||
if(newDialogIndex) {
|
||||
insertInDescendSortedArray(dialogs, dialog, (dialog) => this.getDialogIndex(dialog, indexKey), -1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public prepareDialogUnreadCountModifying(dialog: Dialog) {
|
||||
@ -469,32 +480,46 @@ export default class DialogsStorage extends AppManager {
|
||||
|
||||
public prepareFolderUnreadCountModifyingByDialog(folderId: number, dialog: Dialog, toggle?: boolean) {
|
||||
const wasUnreadCount = this.appMessagesManager.getDialogUnreadCount(dialog);
|
||||
const wasUnmuted = this.isPeerUnmuted(dialog.peerId);
|
||||
|
||||
if(toggle !== undefined) {
|
||||
this.modifyFolderUnreadCount(folderId, toggle ? wasUnreadCount : -wasUnreadCount, wasUnreadCount ? (toggle ? 1 : -1) : 0);
|
||||
const addMessagesCount = toggle ? wasUnreadCount : -wasUnreadCount;
|
||||
this.modifyFolderUnreadCount(folderId, addMessagesCount, !!wasUnreadCount, wasUnreadCount && wasUnmuted, dialog);
|
||||
return;
|
||||
}
|
||||
|
||||
return () => {
|
||||
const newUnreadCount = this.appMessagesManager.getDialogUnreadCount(dialog);
|
||||
const newUnmuted = this.isPeerUnmuted(dialog.peerId);
|
||||
|
||||
const addMessagesCount = newUnreadCount - wasUnreadCount;
|
||||
const addDialogsCount = (newUnreadCount && !wasUnreadCount) || (!newUnreadCount && wasUnreadCount) ? (wasUnreadCount ? -1 : 1) : 0;
|
||||
this.modifyFolderUnreadCount(folderId, addMessagesCount, addDialogsCount);
|
||||
this.modifyFolderUnreadCount(folderId, addMessagesCount, !!newUnreadCount, newUnreadCount && newUnmuted, dialog);
|
||||
};
|
||||
}
|
||||
|
||||
public modifyFolderUnreadCount(folderId: number, addMessagesCount: number, addDialogsCount: number) {
|
||||
if(!addMessagesCount && !addDialogsCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
public modifyFolderUnreadCount(
|
||||
folderId: number,
|
||||
addMessagesCount: number,
|
||||
toggleDialog: boolean,
|
||||
toggleUnmuted: boolean,
|
||||
dialog: Dialog
|
||||
) {
|
||||
const folder = this.getFolder(folderId);
|
||||
if(addMessagesCount) {
|
||||
folder.unreadMessagesCount = Math.max(0, folder.unreadMessagesCount + addMessagesCount);
|
||||
}
|
||||
|
||||
if(addDialogsCount) {
|
||||
folder.unreadDialogsCount = Math.max(0, folder.unreadDialogsCount + addDialogsCount);
|
||||
const {peerId} = dialog;
|
||||
if(toggleDialog) {
|
||||
folder.unreadPeerIds.add(peerId);
|
||||
} else {
|
||||
folder.unreadPeerIds.delete(peerId);
|
||||
}
|
||||
|
||||
if(toggleUnmuted) {
|
||||
folder.unreadUnmutedPeerIds.add(peerId);
|
||||
} else {
|
||||
folder.unreadUnmutedPeerIds.delete(peerId);
|
||||
}
|
||||
|
||||
if(folder.dispatchUnreadTimeout === undefined) {
|
||||
|
@ -241,6 +241,9 @@ module.exports = {
|
||||
// }),
|
||||
|
||||
new HtmlWebpackPlugin({
|
||||
title: 'Telegram Web',
|
||||
description: 'Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.',
|
||||
url: 'https://web.telegram.org/k/',
|
||||
filename: 'index.html',
|
||||
//template: 'public/index_template.html',
|
||||
template: 'src/index.hbs',
|
||||
|
Loading…
Reference in New Issue
Block a user