Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
9.5 KiB
276 lines
9.5 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
*/ |
|
|
|
import PopupElement from '.'; |
|
import filterUnique from '../../helpers/array/filterUnique'; |
|
import {attachClickEvent} from '../../helpers/dom/clickEvent'; |
|
import shake from '../../helpers/dom/shake'; |
|
import toggleDisability from '../../helpers/dom/toggleDisability'; |
|
import safeAssign from '../../helpers/object/safeAssign'; |
|
import {ChatlistsChatlistInvite, ChatlistsChatlistUpdates, DialogFilter, Peer} from '../../layer'; |
|
import getPeerId from '../../lib/appManagers/utils/peers/getPeerId'; |
|
import I18n, {i18n, _i18n} from '../../lib/langPack'; |
|
import wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText'; |
|
import AppSelectPeers from '../appSelectPeers'; |
|
import Button from '../button'; |
|
import showLimitPopup from './limit'; |
|
|
|
const CLASS_NAME = 'popup-chatlist-invite'; |
|
export default class PopupSharedFolderInvite extends PopupElement { |
|
private selector: AppSelectPeers; |
|
private chatlistInvite: ChatlistsChatlistInvite; |
|
private slug: string; |
|
private filter: DialogFilter.dialogFilterChatlist; |
|
private deleting: boolean; |
|
private updating: boolean; |
|
|
|
constructor(options: Partial<{ |
|
chatlistInvite: PopupSharedFolderInvite['chatlistInvite'], |
|
slug: PopupSharedFolderInvite['slug'], |
|
filter: PopupSharedFolderInvite['filter'], |
|
deleting: PopupSharedFolderInvite['deleting'], |
|
updating: PopupSharedFolderInvite['updating'] |
|
}>) { |
|
super('popup-forward ' + CLASS_NAME, { |
|
closable: true, |
|
overlayClosable: true, |
|
body: true, |
|
footer: true, |
|
title: true, |
|
withConfirm: true |
|
}); |
|
|
|
safeAssign(this, options); |
|
|
|
this.construct(); |
|
} |
|
|
|
public async construct() { |
|
const n = document.createElement('div'); |
|
n.classList.add('menu-horizontal-scrollable'); |
|
|
|
const nav = document.createElement('nav'); |
|
nav.classList.add('menu-horizontal-div'); |
|
|
|
const {chatlistInvite, deleting, updating} = this; |
|
const isAlready = chatlistInvite?._ === 'chatlists.chatlistInviteAlready'; |
|
const isJoining = isAlready && !!chatlistInvite.missing_peers.length; |
|
const filter = this.filter ??= isAlready ? await this.managers.filtersStorage.getFilter(chatlistInvite.filter_id) as DialogFilter.dialogFilterChatlist : undefined; |
|
|
|
this.title.append(i18n(deleting ? 'SharedFolder.Link.TitleRemove' : (isJoining ? 'SharedFolder.Link.TitleAdd' : 'SharedFolder.Link.Title'))); |
|
|
|
let leaveSuggestionsPeerIds: PeerId[]; |
|
if(deleting) { |
|
const peers = await this.managers.filtersStorage.getLeaveChatlistSuggestions(this.filter.id); |
|
leaveSuggestionsPeerIds = peers.map((peer) => getPeerId(peer)); |
|
} |
|
|
|
const makeItem = () => { |
|
const item = document.createElement('div'); |
|
item.classList.add('menu-horizontal-div-item'); |
|
const span = document.createElement('span'); |
|
item.append(span); |
|
nav.append(item); |
|
return span; |
|
}; |
|
|
|
makeItem().append(i18n('FilterAllChats')); |
|
const activeItem = makeItem(); |
|
activeItem.parentElement.classList.add('active'); |
|
activeItem.append( |
|
wrapEmojiText(filter ? filter.title : (chatlistInvite as ChatlistsChatlistInvite.chatlistsChatlistInvite).title), |
|
document.createElement('i') |
|
); |
|
makeItem().append(i18n('FilterPersonal')); |
|
|
|
const shadow = document.createElement('div'); |
|
shadow.classList.add('inner-shadow', 'inner-shadow-inset'); |
|
|
|
n.append(nav, shadow); |
|
|
|
const description = document.createElement('div'); |
|
description.classList.add(CLASS_NAME + '-description', 'subtitle'); |
|
let descriptionAddI18n: I18n.IntlElement |
|
if(deleting) { |
|
_i18n(description, 'SharedFolder.Link.DescriptionRemove', [wrapEmojiText(filter.title)]); |
|
} else if(!isJoining) { |
|
_i18n(description, isAlready ? 'SharedFolder.Link.DescriptionAlready' : 'SharedFolder.Link.Description'); |
|
} else { |
|
descriptionAddI18n = new I18n.IntlElement(); |
|
} |
|
|
|
const counterI18n = new I18n.IntlElement(); |
|
|
|
const onSelectionChange = (length: number) => { |
|
if(alreadyPeerIds && isJoining) { |
|
length = Math.max(0, length - alreadyPeerIds.length); |
|
} |
|
|
|
counterI18n.update({ |
|
key: deleting ? 'SharedFolder.Link.ChatsRemove' : (isJoining ? 'SharedFolder.Link.ChatsAdd' : (isAlready ? 'SharedFolder.Link.ChatsAlready' : 'SharedFolder.Link.Chats')), |
|
args: [i18n('Chats', [length])] |
|
}); |
|
|
|
selectAllI18n?.update({ |
|
key: (shouldDeselect = length === peerIds.length) ? 'DeselectAll' : 'SelectAll' |
|
}); |
|
|
|
descriptionAddI18n?.update({ |
|
key: 'SharedFolder.Link.DescriptionAdd', |
|
args: [i18n('Chats', [length]), wrapEmojiText(filter.title)] |
|
}); |
|
|
|
if(selectAllI18n) { |
|
if(length) addFolderText.dataset.badge = '' + length; |
|
addFolderText.classList.toggle('has-badge', !!length); |
|
} |
|
|
|
if(deleting) { |
|
addFolderI18n.update({ |
|
key: length ? 'SharedFolder.Link.Remove' : 'SharedFolder.Link.TitleRemove' |
|
}); |
|
} |
|
|
|
if(!deleting) { |
|
toggleDisability([this.btnConfirm], !length); |
|
} |
|
}; |
|
|
|
let shouldDeselect: boolean; |
|
this.selector = new AppSelectPeers({ |
|
appendTo: this.body, |
|
onChange: onSelectionChange, |
|
onFirstRender: () => { |
|
this.show(); |
|
this.selector.checkForTriggers(); // ! due to zero height before mounting |
|
}, |
|
multiSelect: true, |
|
noSearch: true, |
|
sectionNameLangPackKey: counterI18n.element, |
|
avatarSize: 'abitbigger', |
|
managers: this.managers, |
|
peerType: [], |
|
getSubtitleForElement: async(peerId) => { |
|
if(alreadyPeerIds?.includes(peerId)) { |
|
const isBroadcast = await this.managers.appPeersManager.isBroadcast(peerId); |
|
return i18n(isBroadcast ? 'SharedFolder.Link.ChannelAlready' : 'SharedFolder.Link.ChatAlready'); |
|
} |
|
}, |
|
processElementAfter: (peerId, dialogElement) => { |
|
if(alreadyPeerIds?.includes(peerId)) { |
|
dialogElement.dom.containerEl.classList.add('already'); |
|
} |
|
} |
|
}); |
|
|
|
let selectAllI18n: I18n.IntlElement; |
|
if(!isAlready || isJoining) { |
|
selectAllI18n = new I18n.IntlElement(); |
|
selectAllI18n.element.classList.add('sidebar-left-section-name-right'); |
|
this.selector.section.title.append(selectAllI18n.element); |
|
|
|
attachClickEvent(selectAllI18n.element, () => { |
|
if(shouldDeselect) { |
|
this.selector.removeBatch(peerIds); |
|
} else { |
|
this.selector.addBatch(peerIds); |
|
} |
|
}, {listenerSetter: this.listenerSetter}); |
|
} |
|
|
|
let peerIds: PeerId[]; |
|
if(chatlistInvite) { |
|
const peers = isJoining ? chatlistInvite.missing_peers : (isAlready ? chatlistInvite.already_peers : chatlistInvite.peers); |
|
peerIds = peers.map((peer) => getPeerId(peer)); |
|
} else { |
|
peerIds = filter.includePeerIds; |
|
} |
|
|
|
let alreadyPeerIds: PeerId[]; |
|
if(isAlready) { |
|
alreadyPeerIds = chatlistInvite.already_peers.map((peer) => getPeerId(peer)); |
|
} |
|
|
|
if(alreadyPeerIds) { |
|
const _remove = this.selector.remove.bind(this.selector); |
|
this.selector.remove = (...args) => { |
|
const peerId = args[0].toPeerId(); |
|
if(alreadyPeerIds.includes(peerId)) { |
|
const container = this.selector.getElementByPeerId(peerId); |
|
shake(container); |
|
return false; |
|
} |
|
|
|
return _remove(...args); |
|
}; |
|
} |
|
|
|
this.scrollable = this.selector.scrollable; |
|
this.attachScrollableListeners(); |
|
|
|
this.scrollable.container.prepend(n, description); |
|
|
|
this.btnConfirm.classList.add(`${CLASS_NAME}-button`); |
|
const addFolderI18n = new I18n.IntlElement({ |
|
key: deleting ? 'SharedFolder.Link.Remove' : (isJoining ? 'SharedFolder.Link.Join' : (isAlready ? 'OK' : 'SharedFolder.Link.Title')) |
|
}); |
|
const addFolderText = addFolderI18n.element; |
|
addFolderText.classList.add(`${CLASS_NAME}-button-text`); |
|
this.btnConfirm.append(addFolderText); |
|
this.footer.append(this.btnConfirm); |
|
|
|
attachClickEvent(this.btnConfirm, () => { |
|
if(isAlready && !isJoining) { |
|
this.hide(); |
|
return; |
|
} |
|
|
|
let promise: Promise<any>; |
|
|
|
const toggle = toggleDisability([this.btnConfirm], true); |
|
|
|
const peerIds = [...this.selector.selected] as PeerId[]; |
|
if(updating) { |
|
promise = this.managers.filtersStorage.joinChatlistUpdates(this.filter.id, peerIds); |
|
} else if(chatlistInvite) { |
|
promise = this.managers.filtersStorage.joinChatlistInvite( |
|
this.slug, |
|
peerIds |
|
).catch((error: ApiError) => { |
|
if(error.type === 'DIALOG_FILTERS_TOO_MUCH') { |
|
showLimitPopup('folders'); |
|
this.hide(); |
|
} else { |
|
throw error; |
|
} |
|
}); |
|
} else { |
|
promise = this.managers.filtersStorage.leaveChatlist(this.filter.id, peerIds); |
|
} |
|
|
|
promise.then(() => { |
|
this.hide(); |
|
}, (error: ApiError) => { |
|
toggle(); |
|
throw error; |
|
}); |
|
}, {listenerSetter: this.listenerSetter}); |
|
|
|
const totalPeerIds = alreadyPeerIds ? peerIds.concat(alreadyPeerIds) : peerIds; |
|
const initial = deleting ? leaveSuggestionsPeerIds : totalPeerIds |
|
this.selector.addInitial(initial); |
|
this.selector.renderResultsFunc(deleting ? filterUnique(leaveSuggestionsPeerIds.concat(totalPeerIds)) : totalPeerIds); |
|
|
|
if(!initial.length) { |
|
onSelectionChange(0); |
|
} |
|
// if(isAlready && !isJoining) { |
|
// this.selector.list.classList.add('disable-hover'); |
|
// } |
|
|
|
this.body.append(this.footer); |
|
} |
|
}
|
|
|