Browse Source

Empty folder placeholder

Increased dialog load limit to 200
master
Eduard Kuzmenko 3 years ago
parent
commit
901b9cecf0
  1. 2
      src/components/sidebarLeft/tabs/chatFolders.ts
  2. 30
      src/components/wrappers.ts
  3. 2
      src/lang.ts
  4. 95
      src/lib/appManagers/appDialogsManager.ts
  5. 4
      src/lib/appManagers/appMessagesManager.ts
  6. 15
      src/scss/partials/_button.scss
  7. 50
      src/scss/partials/_leftSidebar.scss

2
src/components/sidebarLeft/tabs/chatFolders.ts

@ -121,7 +121,7 @@ export default class AppChatFoldersTab extends SliderSuperTab {
caption.classList.add('caption'); caption.classList.add('caption');
i18n_({element: caption, key: 'ChatList.Filter.Header'}); i18n_({element: caption, key: 'ChatList.Filter.Header'});
this.createFolderBtn = Button('btn-primary btn-color-primary btn-create-folder', { this.createFolderBtn = Button('btn-primary btn-color-primary btn-control tgico', {
text: 'ChatList.Filter.NewTitle', text: 'ChatList.Filter.NewTitle',
icon: 'add' icon: 'add'
}); });

30
src/components/wrappers.ts

@ -39,6 +39,7 @@ import renderImageFromUrl from '../helpers/dom/renderImageFromUrl';
import sequentialDom from '../helpers/sequentialDom'; import sequentialDom from '../helpers/sequentialDom';
import { fastRaf } from '../helpers/schedulers'; import { fastRaf } from '../helpers/schedulers';
import appDownloadManager from '../lib/appManagers/appDownloadManager'; import appDownloadManager from '../lib/appManagers/appDownloadManager';
import appStickersManager from '../lib/appManagers/appStickersManager';
const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB const MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB
@ -1097,6 +1098,35 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o
return loadPromise; return loadPromise;
} }
export function wrapLocalSticker({emoji, width, height}: {
doc?: MyDocument,
url?: string,
emoji?: string,
width: number,
height: number,
}) {
const container = document.createElement('div');
const doc = appStickersManager.getAnimatedEmojiSticker(emoji);
if(doc) {
wrapSticker({
doc,
div: container,
loop: false,
play: true,
width,
height,
emoji
}).then(() => {
// this.animation = player;
});
} else {
container.classList.add('media-sticker-wrapper');
}
return {container};
}
export function wrapReply(title: string, subtitle: string, message?: any) { export function wrapReply(title: string, subtitle: string, message?: any) {
const replyContainer = new ReplyContainer('reply'); const replyContainer = new ReplyContainer('reply');
replyContainer.fill(title, subtitle, message); replyContainer.fill(title, subtitle, message);

2
src/lang.ts

@ -406,6 +406,8 @@ const lang = {
"Open": "Open", "Open": "Open",
"OpenUrlTitle": "Open Link", "OpenUrlTitle": "Open Link",
"OpenUrlAlert2": "Do you want to open %1$s?", "OpenUrlAlert2": "Do you want to open %1$s?",
"FilterNoChatsToDisplay": "Folder is empty",
"FilterNoChatsToDisplayInfo": "No chats currently belong to this folder.",
// * macos // * macos
"AccountSettings.Filters": "Chat Folders", "AccountSettings.Filters": "Chat Folders",

95
src/lib/appManagers/appDialogsManager.ts

@ -16,7 +16,7 @@ import { isSafari } from "../../helpers/userAgent";
import { logger, LogTypes } from "../logger"; import { logger, LogTypes } from "../logger";
import { RichTextProcessor } from "../richtextprocessor"; import { RichTextProcessor } from "../richtextprocessor";
import rootScope from "../rootScope"; import rootScope from "../rootScope";
import { positionElementByIndex, replaceContent } from "../../helpers/dom"; import { attachClickEvent, positionElementByIndex, replaceContent } from "../../helpers/dom";
import apiUpdatesManager from "./apiUpdatesManager"; import apiUpdatesManager from "./apiUpdatesManager";
import appPeersManager from './appPeersManager'; import appPeersManager from './appPeersManager';
import appImManager from "./appImManager"; import appImManager from "./appImManager";
@ -33,9 +33,13 @@ import App from "../../config/app";
import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug"; import DEBUG, { MOUNT_CLASS_TO } from "../../config/debug";
import appNotificationsManager from "./appNotificationsManager"; import appNotificationsManager from "./appNotificationsManager";
import PeerTitle from "../../components/peerTitle"; import PeerTitle from "../../components/peerTitle";
import { i18n } from "../langPack"; import { i18n, _i18n } from "../langPack";
import findUpTag from "../../helpers/dom/findUpTag"; import findUpTag from "../../helpers/dom/findUpTag";
import { LazyLoadQueueIntersector } from "../../components/lazyLoadQueue"; import { LazyLoadQueueIntersector } from "../../components/lazyLoadQueue";
import lottieLoader from "../lottieLoader";
import { wrapLocalSticker } from "../../components/wrappers";
import AppEditFolderTab from "../../components/sidebarLeft/tabs/editFolder";
import appSidebarLeft from "../../components/sidebarLeft";
export type DialogDom = { export type DialogDom = {
avatarEl: AvatarElement, avatarEl: AvatarElement,
@ -343,14 +347,9 @@ export class AppDialogsManager {
}); });
rootScope.on('dialog_drop', (e) => { rootScope.on('dialog_drop', (e) => {
const {peerId, dialog} = e; const {peerId} = e;
const dom = this.getDialogDom(peerId);
if(dom) {
dom.listEl.remove();
delete this.doms[peerId];
}
this.deleteDialog(peerId);
this.setFiltersUnreadCount(); this.setFiltersUnreadCount();
}); });
@ -537,6 +536,8 @@ export class AppDialogsManager {
new ConnectionStatusComponent(this.chatsContainer); new ConnectionStatusComponent(this.chatsContainer);
this.chatsContainer.append(bottomPart); this.chatsContainer.append(bottomPart);
lottieLoader.loadLottieWorkers();
} }
private getOffset(side: 'top' | 'bottom'): {index: number, pos: number} { private getOffset(side: 'top' | 'bottom'): {index: number, pos: number} {
@ -565,6 +566,20 @@ export class AppDialogsManager {
return (!topOffset.index || index <= topOffset.index) && (!bottomOffset.index || index >= bottomOffset.index); return (!topOffset.index || index <= topOffset.index) && (!bottomOffset.index || index >= bottomOffset.index);
} }
private deleteDialog(peerId: number) {
const dom = this.getDialogDom(peerId);
if(dom) {
dom.listEl.remove();
delete this.doms[peerId];
this.onListLengthChange();
return true;
}
return false;
}
private updateDialog(dialog: Dialog) { private updateDialog(dialog: Dialog) {
if(!dialog) { if(!dialog) {
return; return;
@ -576,17 +591,13 @@ export class AppDialogsManager {
if(ret) { if(ret) {
const idx = appMessagesManager.getDialogByPeerId(dialog.peerId)[1]; const idx = appMessagesManager.getDialogByPeerId(dialog.peerId)[1];
positionElementByIndex(ret.dom.listEl, this.chatList, idx); positionElementByIndex(ret.dom.listEl, this.chatList, idx);
this.onListLengthChange();
} else { } else {
return; return;
} }
} }
} else { } else {
const dom = this.getDialogDom(dialog.peerId); this.deleteDialog(dialog.peerId);
if(dom) {
dom.listEl.remove();
delete this.doms[dialog.peerId];
}
return; return;
} }
@ -668,9 +679,7 @@ export class AppDialogsManager {
// если больше не подходит по фильтру, удаляем // если больше не подходит по фильтру, удаляем
if(folder.findIndex((dialog) => dialog.peerId === peerId) === -1) { if(folder.findIndex((dialog) => dialog.peerId === peerId) === -1) {
const listEl = this.doms[peerId].listEl; this.deleteDialog(peerId);
listEl.remove();
delete this.doms[peerId];
} }
} }
} }
@ -806,6 +815,8 @@ export class AppDialogsManager {
}); });
}); });
} }
this.onListLengthChange();
this.log.debug('getDialogs ' + loadCount + ' dialogs by offset:', offsetIndex, result, this.chatList.childElementCount); this.log.debug('getDialogs ' + loadCount + ' dialogs by offset:', offsetIndex, result, this.chatList.childElementCount);
@ -825,6 +836,48 @@ export class AppDialogsManager {
}); });
} }
private onListLengthChange = () => {
const emptyFolder = this.chatList.parentElement.querySelector('.empty-folder');
if(this.scroll.loadedAll.bottom && !this.chatList.childElementCount) {
if(emptyFolder) {
return;
}
const BASE_CLASS = 'empty-folder';
const div = document.createElement('div');
div.classList.add(BASE_CLASS);
div.append(wrapLocalSticker({
emoji: '📂',
width: 128,
height: 128
}).container);
const header = document.createElement('div');
header.classList.add(BASE_CLASS + '-header');
_i18n(header, 'FilterNoChatsToDisplay');
const subtitle = document.createElement('div');
subtitle.classList.add(BASE_CLASS + '-subtitle');
_i18n(subtitle, 'FilterNoChatsToDisplayInfo');
const button = Button('btn-primary btn-color-primary btn-control tgico', {
text: 'FilterHeaderEdit',
icon: 'settings'
});
attachClickEvent(button, () => {
new AppEditFolderTab(appSidebarLeft).open(appMessagesManager.filtersStorage.filters[this.filterId]);
});
div.append(header, subtitle, button);
this.chatList.parentElement.append(div);
} else if(emptyFolder) {
emptyFolder.remove();
}
};
public onChatsRegularScroll = () => { public onChatsRegularScroll = () => {
if(this.sliceTimeout) clearTimeout(this.sliceTimeout); if(this.sliceTimeout) clearTimeout(this.sliceTimeout);
this.sliceTimeout = window.setTimeout(() => { this.sliceTimeout = window.setTimeout(() => {
@ -900,9 +953,8 @@ export class AppDialogsManager {
sliced.push(...sliceFromEnd); sliced.push(...sliceFromEnd);
sliced.forEach(el => { sliced.forEach(el => {
el.remove();
const peerId = +el.dataset.peerId; const peerId = +el.dataset.peerId;
delete this.doms[peerId]; this.deleteDialog(peerId);
}); });
//this.log('[slicer] elements', firstElement, lastElement, rect, sliced, sliceFromStart.length, sliceFromEnd.length); //this.log('[slicer] elements', firstElement, lastElement, rect, sliced, sliceFromStart.length, sliceFromEnd.length);
@ -1024,8 +1076,7 @@ export class AppDialogsManager {
const needIndex = index - offset; const needIndex = index - offset;
if(needIndex > currentOrder.length) { if(needIndex > currentOrder.length) {
dom.listEl.remove(); this.deleteDialog(dialog.peerId);
delete this.doms[dialog.peerId];
return; return;
} }

4
src/lib/appManagers/appMessagesManager.ts

@ -1540,7 +1540,7 @@ export class AppMessagesManager {
} }
public async refreshConversations() { public async refreshConversations() {
const limit = 100, outDialogs: Dialog[] = []; const limit = 200, outDialogs: Dialog[] = [];
for(let folderId = 0; folderId < 2; ++folderId) { for(let folderId = 0; folderId < 2; ++folderId) {
let offsetDate = 0; let offsetDate = 0;
for(;;) { for(;;) {
@ -1575,7 +1575,7 @@ export class AppMessagesManager {
} }
public async getConversationsAll(query = '', folderId = 0) { public async getConversationsAll(query = '', folderId = 0) {
const limit = 100, outDialogs: Dialog[] = []; const limit = 200, outDialogs: Dialog[] = [];
for(; folderId < 2; ++folderId) { for(; folderId < 2; ++folderId) {
let offsetIndex = 0; let offsetIndex = 0;
for(;;) { for(;;) {

15
src/scss/partials/_button.scss

@ -300,6 +300,21 @@
} }
} }
.btn-control {
width: auto;
height: 40px;
align-items: center;
margin: 15px auto 1rem;
border-radius: 30px;
padding: 0 24px 0 12px;
display: flex;
&.tgico:before {
font-size: 1.5rem;
margin-right: .375rem;
}
}
// ! example: multiselect input, button in pinned messages chat, settings, chat background tab // ! example: multiselect input, button in pinned messages chat, settings, chat background tab
.btn-transparent { .btn-transparent {
color: var(--primary-text-color); color: var(--primary-text-color);

50
src/scss/partials/_leftSidebar.scss

@ -606,21 +606,6 @@
} */ } */
} }
.btn-primary {
width: auto;
height: 40px;
align-items: center;
margin: 15px auto 1rem;
border-radius: 30px;
padding: 0 24px 0 12px;
display: flex;
}
.tgico-add:before {
font-size: 24px;
margin-right: 6px;
}
.row { .row {
.btn-primary { .btn-primary {
height: 30px; height: 30px;
@ -1159,3 +1144,38 @@
padding-bottom: .5rem; padding-bottom: .5rem;
} }
} }
.empty-folder {
top: 40%;
transform: translateY(-50%);
text-align: center;
line-height: var(--line-height);
user-select: none;
.media-sticker-wrapper {
width: 128px;
height: 128px;
margin: 0 auto 1.9375rem;
position: relative;
}
&-header {
font-size: 1.25rem;
font-weight: 500;
}
&-subtitle {
color: var(--secondary-text-color);
font-size: .875rem;
margin-top: .3125rem;
}
.btn-control {
margin-top: 1.75rem;
padding: 0 1.0625rem 0 .8125rem;
&:before {
margin-right: .625rem;
}
}
}

Loading…
Cancel
Save