Browse Source

Temp

master
Eduard Kuzmenko 4 years ago
parent
commit
bb1ea43c9b
  1. 22
      src/components/chat/input.ts
  2. 14
      src/components/chat/pinnedMessage.ts
  3. 6
      src/components/chat/selection.ts
  4. 6
      src/components/chat/sendContextMenu.ts
  5. 28
      src/components/chat/topbar.ts
  6. 4
      src/components/inputField.ts
  7. 56
      src/components/popups/datePicker.ts
  8. 4
      src/components/popups/index.ts
  9. 30
      src/components/popups/newMedia.ts
  10. 12
      src/components/sidebarLeft/tabs/archivedTab.ts
  11. 10
      src/index.hbs
  12. 54
      src/lang.ts
  13. 35
      src/lib/appManagers/appDialogsManager.ts
  14. 8
      src/lib/langPack.ts
  15. 36
      src/scss/partials/_chat.scss
  16. 13
      src/scss/partials/_chatPinned.scss

22
src/components/chat/input.ts

@ -38,6 +38,7 @@ import { debounce } from '../../helpers/schedulers';
import { tsNow } from '../../helpers/date'; import { tsNow } from '../../helpers/date';
import appNavigationController from '../appNavigationController'; import appNavigationController from '../appNavigationController';
import { isMobile } from '../../helpers/userAgent'; import { isMobile } from '../../helpers/userAgent';
import { i18n } from '../../lib/langPack';
const RECORD_MIN_TIME = 500; const RECORD_MIN_TIME = 500;
const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.'; const POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\'t allowed in this group.';
@ -117,6 +118,9 @@ export default class ChatInput {
public saveDraftDebounced: () => void; public saveDraftDebounced: () => void;
public fakeRowsWrapper: HTMLDivElement;
private fakePinnedControlBtn: HTMLElement;
constructor(private chat: Chat, private appMessagesManager: AppMessagesManager, private appDocsManager: AppDocsManager, private appChatsManager: AppChatsManager, private appPeersManager: AppPeersManager, private appWebPagesManager: AppWebPagesManager, private appImManager: AppImManager, private appDraftsManager: AppDraftsManager, private serverTimeManager: ServerTimeManager, private appNotificationsManager: AppNotificationsManager) { constructor(private chat: Chat, private appMessagesManager: AppMessagesManager, private appDocsManager: AppDocsManager, private appChatsManager: AppChatsManager, private appPeersManager: AppPeersManager, private appWebPagesManager: AppWebPagesManager, private appImManager: AppImManager, private appDraftsManager: AppDraftsManager, private serverTimeManager: ServerTimeManager, private appNotificationsManager: AppNotificationsManager) {
this.listenerSetter = new ListenerSetter(); this.listenerSetter = new ListenerSetter();
} }
@ -132,7 +136,7 @@ export default class ChatInput {
this.rowsWrapper = document.createElement('div'); this.rowsWrapper = document.createElement('div');
this.rowsWrapper.classList.add('rows-wrapper', 'chat-input-wrapper'); this.rowsWrapper.classList.add('rows-wrapper', 'chat-input-wrapper');
const fakeRowsWrapper = document.createElement('div'); const fakeRowsWrapper = this.fakeRowsWrapper = document.createElement('div');
fakeRowsWrapper.classList.add('fake-wrapper', 'fake-rows-wrapper'); fakeRowsWrapper.classList.add('fake-wrapper', 'fake-rows-wrapper');
const fakeSelectionWrapper = document.createElement('div'); const fakeSelectionWrapper = document.createElement('div');
@ -274,7 +278,7 @@ export default class ChatInput {
this.attachMenuButtons = [{ this.attachMenuButtons = [{
icon: 'photo', icon: 'photo',
text: 'Photo or Video', text: 'Chat.Input.Attach.PhotoOrVideo',
onClick: () => { onClick: () => {
this.fileInput.value = ''; this.fileInput.value = '';
this.fileInput.setAttribute('accept', 'image/*, video/*'); this.fileInput.setAttribute('accept', 'image/*, video/*');
@ -284,7 +288,7 @@ export default class ChatInput {
verify: (peerId: number) => peerId > 0 || this.appChatsManager.hasRights(peerId, 'send_media') verify: (peerId: number) => peerId > 0 || this.appChatsManager.hasRights(peerId, 'send_media')
}, { }, {
icon: 'document', icon: 'document',
text: 'Document', text: 'Chat.Input.Attach.Document',
onClick: () => { onClick: () => {
this.fileInput.value = ''; this.fileInput.value = '';
this.fileInput.removeAttribute('accept'); this.fileInput.removeAttribute('accept');
@ -501,6 +505,10 @@ export default class ChatInput {
this.pinnedControlBtn = Button('btn-primary btn-transparent text-bold pinned-container-button', {icon: 'unpin'}); this.pinnedControlBtn = Button('btn-primary btn-transparent text-bold pinned-container-button', {icon: 'unpin'});
container.append(this.pinnedControlBtn); container.append(this.pinnedControlBtn);
const fakeContainer = container.cloneNode(true);
this.fakePinnedControlBtn = fakeContainer.firstChild as HTMLElement;
this.fakeRowsWrapper.append(fakeContainer);
this.listenerSetter.add(this.pinnedControlBtn, 'click', () => { this.listenerSetter.add(this.pinnedControlBtn, 'click', () => {
const peerId = this.chat.peerId; const peerId = this.chat.peerId;
@ -690,7 +698,13 @@ export default class ChatInput {
this.attachMenu.toggleAttribute('disabled', !visible.length); this.attachMenu.toggleAttribute('disabled', !visible.length);
this.updateSendBtn(); this.updateSendBtn();
} else if(this.pinnedControlBtn) { } else if(this.pinnedControlBtn) {
this.pinnedControlBtn.append(this.appPeersManager.canPinMessage(this.chat.peerId) ? 'Unpin all messages' : 'Don\'t show pinned messages'); if(this.appPeersManager.canPinMessage(this.chat.peerId)) {
this.pinnedControlBtn.append(i18n('Chat.Input.UnpinAll'));
this.fakePinnedControlBtn.append(i18n('Chat.Input.UnpinAll'));
} else {
this.pinnedControlBtn.append(i18n('Chat.Pinned.DontShow'));
this.fakePinnedControlBtn.append(i18n('Chat.Pinned.DontShow'));
}
} }
} }

14
src/components/chat/pinnedMessage.ts

@ -12,6 +12,7 @@ import ListenerSetter from "../../helpers/listenerSetter";
import ButtonIcon from "../buttonIcon"; import ButtonIcon from "../buttonIcon";
import { debounce } from "../../helpers/schedulers"; import { debounce } from "../../helpers/schedulers";
import { getHeavyAnimationPromise } from "../../hooks/useHeavyAnimationCheck"; import { getHeavyAnimationPromise } from "../../hooks/useHeavyAnimationCheck";
import { i18n } from "../../lib/langPack";
class AnimatedSuper { class AnimatedSuper {
static DURATION = 200; static DURATION = 200;
@ -243,6 +244,8 @@ export default class ChatPinnedMessage {
private isStatic = false; private isStatic = false;
private debug = false;
constructor(private topbar: ChatTopbar, private chat: Chat, private appMessagesManager: AppMessagesManager, private appPeersManager: AppPeersManager) { constructor(private topbar: ChatTopbar, private chat: Chat, private appMessagesManager: AppMessagesManager, private appPeersManager: AppPeersManager) {
this.listenerSetter = new ListenerSetter(); this.listenerSetter = new ListenerSetter();
@ -267,8 +270,7 @@ export default class ChatPinnedMessage {
this.pinnedMessageContainer.divAndCaption.content.prepend(this.animatedMedia.container); this.pinnedMessageContainer.divAndCaption.content.prepend(this.animatedMedia.container);
this.animatedCounter = new AnimatedCounter(true); this.animatedCounter = new AnimatedCounter(true);
this.pinnedMessageContainer.divAndCaption.title.innerHTML = 'Pinned Message '; this.pinnedMessageContainer.divAndCaption.title.append(i18n('PinnedMessage'), ' ', this.animatedCounter.container);
this.pinnedMessageContainer.divAndCaption.title.append(this.animatedCounter.container);
this.btnOpen = ButtonIcon('pinlist pinned-container-close pinned-message-pinlist', {noRipple: true}); this.btnOpen = ButtonIcon('pinlist pinned-container-close pinned-message-pinlist', {noRipple: true});
this.pinnedMessageContainer.divAndCaption.container.prepend(this.btnOpen); this.pinnedMessageContainer.divAndCaption.container.prepend(this.btnOpen);
@ -459,7 +461,7 @@ export default class ChatPinnedMessage {
this.loadedTop = (this.offsetIndex + this.mids.length) === this.count; this.loadedTop = (this.offsetIndex + this.mids.length) === this.count;
this.loadedBottom = !this.offsetIndex; this.loadedBottom = !this.offsetIndex;
this.chat.log('[PM]: getCurrentIndex result:', mid, result, backLimited, this.offsetIndex, this.loadedTop, this.loadedBottom); this.debug && this.chat.log('[PM]: getCurrentIndex result:', mid, result, backLimited, this.offsetIndex, this.loadedTop, this.loadedBottom);
} catch(err) { } catch(err) {
this.chat.log.error('[PM]: getCurrentIndex error', err); this.chat.log.error('[PM]: getCurrentIndex error', err);
} }
@ -503,7 +505,7 @@ export default class ChatPinnedMessage {
public async handleFollowingPinnedMessage() { public async handleFollowingPinnedMessage() {
this.locked = true; this.locked = true;
this.chat.log('[PM]: handleFollowingPinnedMessage'); this.debug && this.chat.log('[PM]: handleFollowingPinnedMessage');
try { try {
this.setScrollDownListener(); this.setScrollDownListener();
@ -519,7 +521,7 @@ export default class ChatPinnedMessage {
await this.getCurrentIndexPromise; await this.getCurrentIndexPromise;
} }
this.chat.log('[PM]: handleFollowingPinnedMessage: unlock'); this.debug && this.chat.log('[PM]: handleFollowingPinnedMessage: unlock');
this.locked = false; this.locked = false;
/* // подождём, пока скролл остановится /* // подождём, пока скролл остановится
@ -576,7 +578,7 @@ export default class ChatPinnedMessage {
const fromTop = pinnedIndex > this.wasPinnedIndex; const fromTop = pinnedIndex > this.wasPinnedIndex;
this.chat.log('[PM]: setPinnedMessage: fromTop', fromTop, pinnedIndex, this.wasPinnedIndex); this.debug && this.chat.log('[PM]: setPinnedMessage: fromTop', fromTop, pinnedIndex, this.wasPinnedIndex);
const writeTo = this.animatedSubtitle.getRow(pinnedIndex); const writeTo = this.animatedSubtitle.getRow(pinnedIndex);
const writeMediaTo = this.animatedMedia.getRow(pinnedIndex); const writeMediaTo = this.animatedMedia.getRow(pinnedIndex);

6
src/components/chat/selection.ts

@ -350,7 +350,7 @@ export default class ChatSelection {
if(this.chat.type === 'scheduled') { if(this.chat.type === 'scheduled') {
this.selectionSendNowBtn = Button('btn-primary btn-transparent btn-short text-bold selection-container-send', {icon: 'send2'}); this.selectionSendNowBtn = Button('btn-primary btn-transparent btn-short text-bold selection-container-send', {icon: 'send2'});
_i18n(this.selectionSendNowBtn, 'Chat.Context.Scheduled.SendNow'); this.selectionSendNowBtn.append(i18n('Chat.Context.Scheduled.SendNow'));
this.listenerSetter.add(this.selectionSendNowBtn, 'click', () => { this.listenerSetter.add(this.selectionSendNowBtn, 'click', () => {
new PopupSendNow(this.bubbles.peerId, [...this.selectedMids], () => { new PopupSendNow(this.bubbles.peerId, [...this.selectedMids], () => {
this.cancelSelection(); this.cancelSelection();
@ -358,7 +358,7 @@ export default class ChatSelection {
}); });
} else { } else {
this.selectionForwardBtn = Button('btn-primary btn-transparent text-bold selection-container-forward', {icon: 'forward'}); this.selectionForwardBtn = Button('btn-primary btn-transparent text-bold selection-container-forward', {icon: 'forward'});
_i18n(this.selectionForwardBtn, 'Forward'); this.selectionForwardBtn.append(i18n('Forward'));
this.listenerSetter.add(this.selectionForwardBtn, 'click', () => { this.listenerSetter.add(this.selectionForwardBtn, 'click', () => {
new PopupForward(this.bubbles.peerId, [...this.selectedMids], () => { new PopupForward(this.bubbles.peerId, [...this.selectedMids], () => {
this.cancelSelection(); this.cancelSelection();
@ -367,7 +367,7 @@ export default class ChatSelection {
} }
this.selectionDeleteBtn = Button('btn-primary btn-transparent danger text-bold selection-container-delete', {icon: 'delete'}); this.selectionDeleteBtn = Button('btn-primary btn-transparent danger text-bold selection-container-delete', {icon: 'delete'});
_i18n(this.selectionDeleteBtn, 'Delete'); this.selectionDeleteBtn.append(i18n('Delete'));
this.listenerSetter.add(this.selectionDeleteBtn, 'click', () => { this.listenerSetter.add(this.selectionDeleteBtn, 'click', () => {
new PopupDeleteMessages(this.bubbles.peerId, [...this.selectedMids], this.chat.type, () => { new PopupDeleteMessages(this.bubbles.peerId, [...this.selectedMids], this.chat.type, () => {
this.cancelSelection(); this.cancelSelection();

6
src/components/chat/sendContextMenu.ts

@ -19,17 +19,17 @@ export default class SendMenu {
}) { }) {
this.sendMenuButtons = [{ this.sendMenuButtons = [{
icon: 'mute', icon: 'mute',
text: 'Send Without Sound', text: 'Chat.Send.WithoutSound',
onClick: options.onSilentClick, onClick: options.onSilentClick,
verify: () => this.type === 'schedule' verify: () => this.type === 'schedule'
}, { }, {
icon: 'schedule', icon: 'schedule',
text: 'Schedule Message', text: 'Chat.Send.ScheduledMessage',
onClick: options.onScheduleClick, onClick: options.onScheduleClick,
verify: () => this.type === 'schedule' verify: () => this.type === 'schedule'
}, { }, {
icon: 'schedule', icon: 'schedule',
text: 'Set a reminder', text: 'Chat.Send.SetReminder',
onClick: options.onScheduleClick, onClick: options.onScheduleClick,
verify: () => this.type === 'reminder' verify: () => this.type === 'reminder'
}]; }];

28
src/components/chat/topbar.ts

@ -23,6 +23,7 @@ import appNavigationController from "../appNavigationController";
import { LEFT_COLUMN_ACTIVE_CLASSNAME } from "../sidebarLeft"; import { LEFT_COLUMN_ACTIVE_CLASSNAME } from "../sidebarLeft";
import AppPrivateSearchTab from "../sidebarRight/tabs/search"; import AppPrivateSearchTab from "../sidebarRight/tabs/search";
import PeerTitle from "../peerTitle"; import PeerTitle from "../peerTitle";
import { i18n } from "../../lib/langPack";
export default class ChatTopbar { export default class ChatTopbar {
container: HTMLDivElement; container: HTMLDivElement;
@ -203,14 +204,14 @@ export default class ChatTopbar {
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: 'select', icon: 'select',
text: 'Select Messages', text: 'Chat.Menu.SelectMessages',
onClick: () => { onClick: () => {
this.chat.selection.toggleSelection(true, true); this.chat.selection.toggleSelection(true, true);
}, },
verify: () => !this.chat.selection.isSelecting && !!Object.keys(this.chat.bubbles.bubbles).length verify: () => !this.chat.selection.isSelecting && !!Object.keys(this.chat.bubbles.bubbles).length
}, { }, {
icon: 'select', icon: 'select',
text: 'Clear Selection', text: 'Chat.Menu.ClearSelection',
onClick: () => { onClick: () => {
this.chat.selection.cancelSelection(); this.chat.selection.cancelSelection();
}, },
@ -250,7 +251,7 @@ export default class ChatTopbar {
this.pinnedMessage = new ChatPinnedMessage(this, this.chat, this.appMessagesManager, this.appPeersManager); this.pinnedMessage = new ChatPinnedMessage(this, this.chat, this.appMessagesManager, this.appPeersManager);
this.btnJoin = Button('btn-primary btn-color-primary chat-join hide'); this.btnJoin = Button('btn-primary btn-color-primary chat-join hide');
this.btnJoin.append('SUBSCRIBE'); this.btnJoin.append(i18n('Chat.Subscribe'));
this.btnPinned = ButtonIcon('pinlist'); this.btnPinned = ButtonIcon('pinlist');
this.btnMute = ButtonIcon('mute'); this.btnMute = ButtonIcon('mute');
@ -437,9 +438,9 @@ export default class ChatTopbar {
} }
public setTitle(count?: number) { public setTitle(count?: number) {
let title = ''; let titleEl: HTMLElement;
if(this.chat.type === 'pinned') { if(this.chat.type === 'pinned') {
title = [count > 1 ? count : false, 'Pinned Messages'].filter(Boolean).join(' '); titleEl = i18n('PinnedMessagesCount', [count]);
if(count === undefined) { if(count === undefined) {
this.appMessagesManager.getSearchCounters(this.peerId, [{_: 'inputMessagesFilterPinned'}]).then(result => { this.appMessagesManager.getSearchCounters(this.peerId, [{_: 'inputMessagesFilterPinned'}]).then(result => {
@ -460,9 +461,11 @@ export default class ChatTopbar {
} }
} else if(this.chat.type === 'scheduled') { } else if(this.chat.type === 'scheduled') {
if(this.peerId === rootScope.myId) { if(this.peerId === rootScope.myId) {
title = [count > 1 ? count : false, 'Reminders'].filter(Boolean).join(' '); //title = [count > 1 ? count : false, 'Reminders'].filter(Boolean).join(' ');
titleEl = i18n('Reminders');
} else { } else {
title = [count > 1 ? count : false, 'Scheduled Messages'].filter(Boolean).join(' '); titleEl = i18n('ScheduledMessages');
//title = [count > 1 ? count : false, 'Scheduled Messages'].filter(Boolean).join(' ');
} }
if(count === undefined) { if(count === undefined) {
@ -471,7 +474,7 @@ export default class ChatTopbar {
}); });
} }
} else if(this.chat.type === 'discussion') { } else if(this.chat.type === 'discussion') {
title = [count > 1 ? count : false, 'Comments'].filter(Boolean).join(' '); titleEl = i18n('Chat.Title.Comments', [count]);
if(count === undefined) { if(count === undefined) {
Promise.all([ Promise.all([
@ -482,15 +485,14 @@ export default class ChatTopbar {
}); });
} }
} else if(this.chat.type === 'chat') { } else if(this.chat.type === 'chat') {
this.title.innerHTML = ''; titleEl = new PeerTitle({
this.title.append(new PeerTitle({
peerId: this.peerId, peerId: this.peerId,
dialog: true, dialog: true,
}).element); }).element;
return;
} }
this.title.innerHTML = title; this.title.textContent = '';
this.title.append(titleEl);
} }
public setMutedState() { public setMutedState() {

4
src/components/inputField.ts

@ -97,7 +97,7 @@ class InputField {
} }
this.container.innerHTML = ` this.container.innerHTML = `
<div ${placeholder ? `data-placeholder="${placeholder}"` : ''} contenteditable="true" class="input-field-input"></div> <div contenteditable="true" class="input-field-input"></div>
`; `;
input = this.container.firstElementChild as HTMLElement; input = this.container.firstElementChild as HTMLElement;
@ -139,11 +139,11 @@ class InputField {
input = this.container.firstElementChild as HTMLElement; input = this.container.firstElementChild as HTMLElement;
input.addEventListener('input', () => checkAndSetRTL(input)); input.addEventListener('input', () => checkAndSetRTL(input));
}
if(placeholder) { if(placeholder) {
_i18n(input, placeholder, undefined, 'placeholder'); _i18n(input, placeholder, undefined, 'placeholder');
} }
}
if(label) { if(label) {
this.label = document.createElement('label'); this.label = document.createElement('label');

56
src/components/popups/datePicker.ts

@ -1,6 +1,7 @@
import PopupElement, { PopupOptions } from "."; import PopupElement, { PopupOptions } from ".";
import { getFullDate, months } from "../../helpers/date"; import { getFullDate } from "../../helpers/date";
import mediaSizes from "../../helpers/mediaSizes"; import mediaSizes from "../../helpers/mediaSizes";
import I18n from "../../lib/langPack";
import InputField from "../inputField"; import InputField from "../inputField";
export default class PopupDatePicker extends PopupElement { export default class PopupDatePicker extends PopupElement {
@ -33,14 +34,14 @@ export default class PopupDatePicker extends PopupElement {
showOverflowMonths: true showOverflowMonths: true
}> & PopupOptions = {}) { }> & PopupOptions = {}) {
super('popup-date-picker', options.noButtons ? [] : [{ super('popup-date-picker', options.noButtons ? [] : [{
text: 'JUMP TO DATE', langKey: 'JumpToDate',
callback: () => { callback: () => {
if(this.onPick) { if(this.onPick) {
this.onPick(this.selectedDate.getTime() / 1000 | 0); this.onPick(this.selectedDate.getTime() / 1000 | 0);
} }
} }
}, { }, {
text: 'CANCEL', langKey: 'Cancel',
isCancel: true isCancel: true
}], {body: true, overlayClosable: true, ...options}); }], {body: true, overlayClosable: true, ...options});
@ -257,11 +258,20 @@ export default class PopupDatePicker extends PopupElement {
} }
public setTitle() { public setTitle() {
const splitted = this.selectedDate.toString().split(' ', 3); //const splitted = this.selectedDate.toString().split(' ', 3);
this.title.innerText = splitted[0] + ', ' + splitted[1] + ' ' + splitted[2]; //this.title.innerText = splitted[0] + ', ' + splitted[1] + ' ' + splitted[2];
this.title.textContent = '';
this.title.append(new I18n.IntlDateElement({
date: this.selectedDate,
options: {
day: 'numeric',
month: 'long',
weekday: 'short'
}
}).element);
} }
private renderElement(disabled: boolean, innerText = '') { private renderElement(disabled: boolean, innerText: string | HTMLElement = '') {
const el = document.createElement('button'); const el = document.createElement('button');
el.classList.add('btn-icon', 'date-picker-month-date'); el.classList.add('btn-icon', 'date-picker-month-date');
@ -270,15 +280,23 @@ export default class PopupDatePicker extends PopupElement {
} }
if(innerText) { if(innerText) {
el.innerText = innerText; el.append(innerText);
} }
return el; return el;
} }
public setMonth() { public setMonth() {
const monthName = months[this.selectedMonth.getMonth()]; const firstDate = new Date(this.selectedMonth);
this.monthTitle.innerText = (this.timeDiv && mediaSizes.isMobile ? monthName.slice(0, 3) : monthName) + ' ' + this.selectedMonth.getFullYear();
const options: Intl.DateTimeFormatOptions = {
year: 'numeric',
month: this.timeDiv && mediaSizes.isMobile ? 'short' : 'long'
};
this.monthTitle.textContent = '';
this.monthTitle.append(new I18n.IntlDateElement({date: firstDate, options}).element);
//this.monthTitle.innerText = (this.timeDiv && mediaSizes.isMobile ? monthName.slice(0, 3) : monthName) + ' ' + this.selectedMonth.getFullYear();
if(this.month) { if(this.month) {
this.month.remove(); this.month.remove();
@ -287,19 +305,23 @@ export default class PopupDatePicker extends PopupElement {
this.month = document.createElement('div'); this.month = document.createElement('div');
this.month.classList.add('date-picker-month'); this.month.classList.add('date-picker-month');
const days = ['M', 'T', 'W', 'T', 'F', 'S', 'S']; const weekStartDate = new Date();
this.month.append(...days.map(s => { const day = weekStartDate.getDay();
const el = this.renderElement(true, s); if(day !== 1) {
weekStartDate.setHours(-24 * (day - 1));
}
for(let i = 0; i < 7; ++i) {
const el = this.renderElement(true, new I18n.IntlDateElement({date: weekStartDate, options: {weekday: 'narrow'}}).element);
el.classList.remove('date-picker-month-date'); el.classList.remove('date-picker-month-date');
el.classList.add('date-picker-month-day'); el.classList.add('date-picker-month-day');
return el; this.month.append(el);
})); weekStartDate.setDate(weekStartDate.getDate() + 1);
}
const firstDate = new Date(this.selectedMonth);
// 0 - sunday // 0 - sunday
let dayIndex = firstDate.getDay() - 1; let dayIndex = firstDate.getDay() - 1;
if(dayIndex === -1) dayIndex = days.length - 1; if(dayIndex === -1) dayIndex = 7 - 1;
const clonedDate = new Date(firstDate.getTime()); const clonedDate = new Date(firstDate.getTime());
clonedDate.setDate(clonedDate.getDate() - dayIndex - 1); clonedDate.setDate(clonedDate.getDate() - dayIndex - 1);

4
src/components/popups/index.ts

@ -17,7 +17,7 @@ export type PopupButton = {
export type PopupOptions = Partial<{ export type PopupOptions = Partial<{
closable: true, closable: true,
overlayClosable: true, overlayClosable: true,
withConfirm: string, withConfirm: LangPackKey,
body: true body: true
}>; }>;
@ -69,7 +69,7 @@ export default class PopupElement {
if(options.withConfirm) { if(options.withConfirm) {
this.btnConfirm = document.createElement('button'); this.btnConfirm = document.createElement('button');
this.btnConfirm.classList.add('btn-primary', 'btn-color-primary'); this.btnConfirm.classList.add('btn-primary', 'btn-color-primary');
this.btnConfirm.innerText = options.withConfirm; this.btnConfirm.append(i18n(options.withConfirm));
this.header.append(this.btnConfirm); this.header.append(this.btnConfirm);
ripple(this.btnConfirm); ripple(this.btnConfirm);
} }

30
src/components/popups/newMedia.ts

@ -10,6 +10,7 @@ import CheckboxField from "../checkboxField";
import SendContextMenu from "../chat/sendContextMenu"; import SendContextMenu from "../chat/sendContextMenu";
import { createPosterForVideo, createPosterFromVideo, onVideoLoad } from "../../helpers/files"; import { createPosterForVideo, createPosterFromVideo, onVideoLoad } from "../../helpers/files";
import { MyDocument } from "../../lib/appManagers/appDocsManager"; import { MyDocument } from "../../lib/appManagers/appDocsManager";
import I18n, { i18n, LangPackKey } from "../../lib/langPack";
type SendFileParams = Partial<{ type SendFileParams = Partial<{
file: File, file: File,
@ -43,7 +44,7 @@ export default class PopupNewMedia extends PopupElement {
inputField: InputField; inputField: InputField;
constructor(private chat: Chat, files: File[], willAttachType: PopupNewMedia['willAttach']['type']) { constructor(private chat: Chat, files: File[], willAttachType: PopupNewMedia['willAttach']['type']) {
super('popup-send-photo popup-new-media', null, {closable: true, withConfirm: 'SEND'}); super('popup-send-photo popup-new-media', null, {closable: true, withConfirm: 'PreviewSender.Send'});
this.willAttach.type = willAttachType; this.willAttach.type = willAttachType;
@ -75,7 +76,7 @@ export default class PopupNewMedia extends PopupElement {
scrollable.container.append(this.mediaContainer); scrollable.container.append(this.mediaContainer);
this.inputField = new InputField({ this.inputField = new InputField({
placeholder: 'Add a caption...', placeholder: 'PreviewSender.CaptionPlaceholder',
label: 'Caption', label: 'Caption',
name: 'photo-caption', name: 'photo-caption',
maxLength: MAX_LENGTH_CAPTION, maxLength: MAX_LENGTH_CAPTION,
@ -90,7 +91,7 @@ export default class PopupNewMedia extends PopupElement {
if(files.length > 1) { if(files.length > 1) {
this.groupCheckboxField = new CheckboxField({ this.groupCheckboxField = new CheckboxField({
text: 'Group items', text: 'PreviewSender.GroupItems',
name: 'group-items' name: 'group-items'
}); });
this.container.append(this.groupCheckboxField.label, this.inputField.container); this.container.append(this.groupCheckboxField.label, this.inputField.container);
@ -138,7 +139,7 @@ export default class PopupNewMedia extends PopupElement {
let caption = this.inputField.value; let caption = this.inputField.value;
if(caption.length > MAX_LENGTH_CAPTION) { if(caption.length > MAX_LENGTH_CAPTION) {
toast('Caption is too long.'); toast(I18n.format('Error.PreviewSender.CaptionTooLong', true));
return; return;
} }
@ -350,8 +351,11 @@ export default class PopupNewMedia extends PopupElement {
this.mediaContainer.innerHTML = ''; this.mediaContainer.innerHTML = '';
if(files.length) { if(files.length) {
let key: LangPackKey;
const args: any[] = [];
if(willAttach.type === 'document') { if(willAttach.type === 'document') {
this.title.innerText = 'Send ' + (files.length > 1 ? files.length + ' Files' : 'File'); key = 'PreviewSender.SendFile';
args.push(files.length);
container.classList.add('is-document'); container.classList.add('is-document');
} else { } else {
container.classList.add('is-media'); container.classList.add('is-media');
@ -363,14 +367,22 @@ export default class PopupNewMedia extends PopupElement {
else if(file.type.indexOf('video/') === 0) ++foundVideos; else if(file.type.indexOf('video/') === 0) ++foundVideos;
}); });
if(foundPhotos && foundVideos && willAttach.group) { const sum = foundPhotos + foundVideos;
this.title.innerText = 'Send Album'; if(sum > 1 && willAttach.group) {
key = 'PreviewSender.SendAlbum';
const albumsLength = Math.ceil(sum / 10);
args.push(albumsLength);
} else if(foundPhotos) { } else if(foundPhotos) {
this.title.innerText = 'Send ' + (foundPhotos > 1 ? foundPhotos + ' Photos' : 'Photo'); key = 'PreviewSender.SendPhoto';
args.push(foundPhotos);
} else if(foundVideos) { } else if(foundVideos) {
this.title.innerText = 'Send ' + (foundVideos > 1 ? foundVideos + ' Videos' : 'Video'); key = 'PreviewSender.SendVideo';
args.push(foundVideos);
} }
} }
this.title.textContent = '';
this.title.append(i18n(key, args));
} }
if(willAttach.type === 'media') { if(willAttach.type === 'media') {

12
src/components/sidebarLeft/tabs/archivedTab.ts

@ -2,6 +2,7 @@ import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
import { SliderSuperTab } from "../../slider"; import { SliderSuperTab } from "../../slider";
export default class AppArchivedTab extends SliderSuperTab { export default class AppArchivedTab extends SliderSuperTab {
public static filterId = 1;
public loadedAll: boolean; public loadedAll: boolean;
public loadDialogsPromise: Promise<any>; public loadDialogsPromise: Promise<any>;
public wasFilterId: number; public wasFilterId: number;
@ -11,13 +12,14 @@ export default class AppArchivedTab extends SliderSuperTab {
this.setTitle('ArchivedChats'); this.setTitle('ArchivedChats');
//this.scrollable = new Scrollable(this.container, 'CLA', 500); //this.scrollable = new Scrollable(this.container, 'CLA', 500);
this.scrollable.append(appDialogsManager.chatListArchived); const chatList = appDialogsManager.chatLists[AppArchivedTab.filterId];
this.scrollable.append(chatList);
this.scrollable.container.addEventListener('scroll', appDialogsManager.onChatsRegularScroll); this.scrollable.container.addEventListener('scroll', appDialogsManager.onChatsRegularScroll);
this.scrollable.setVirtualContainer(appDialogsManager.chatListArchived); this.scrollable.setVirtualContainer(chatList);
this.scrollable.onScrolledBottom = appDialogsManager.onChatsScroll; this.scrollable.onScrolledBottom = appDialogsManager.onChatsScroll;
///this.scroll.attachSentinels(); ///this.scroll.attachSentinels();
appDialogsManager.setListClickListener(appDialogsManager.chatListArchived, null, true); appDialogsManager.setListClickListener(chatList, null, true);
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
setTimeout(appDialogsManager.scroll.checkForTriggers, 0); setTimeout(appDialogsManager.scroll.checkForTriggers, 0);
@ -32,7 +34,7 @@ export default class AppArchivedTab extends SliderSuperTab {
this.wasFilterId = appDialogsManager.filterId; this.wasFilterId = appDialogsManager.filterId;
appDialogsManager.scroll = this.scrollable; appDialogsManager.scroll = this.scrollable;
appDialogsManager.filterId = 1; appDialogsManager.filterId = AppArchivedTab.filterId;
appDialogsManager.onTabChange(); appDialogsManager.onTabChange();
} }
@ -48,7 +50,7 @@ export default class AppArchivedTab extends SliderSuperTab {
} }
onCloseAfterTimeout() { onCloseAfterTimeout() {
appDialogsManager.chatListArchived.innerHTML = ''; appDialogsManager.chatLists[AppArchivedTab.filterId].innerHTML = '';
return super.onCloseAfterTimeout(); return super.onCloseAfterTimeout();
} }
} }

10
src/index.hbs

@ -106,15 +106,9 @@
<div class="sidebar-content transition zoom-fade"> <div class="sidebar-content transition zoom-fade">
<div class="transition-item active" id="chatlist-container"> <div class="transition-item active" id="chatlist-container">
<div class="folders-tabs-scrollable menu-horizontal-scrollable hide"> <div class="folders-tabs-scrollable menu-horizontal-scrollable hide">
<nav class="menu-horizontal-div" id="folders-tabs"> <nav class="menu-horizontal-div" id="folders-tabs"></nav>
<div class="menu-horizontal-div-item rp"><span><span class="text-super">All</span><div class="badge badge-20 badge-blue"></div><i></i></span></div>
</nav>
</div>
<div class="tabs-container" id="folders-container">
<div>
<ul id="dialogs" class="chatlist chatlist-72"></ul>
</div>
</div> </div>
<div class="tabs-container" id="folders-container"></div>
</div> </div>
<div class="transition-item sidebar-search" id="search-container"></div> <div class="transition-item sidebar-search" id="search-container"></div>
<button class="btn-circle rp btn-corner tgico-newchat_filled btn-menu-toggle" id="new-menu"></button> <button class="btn-circle rp btn-corner tgico-newchat_filled btn-menu-toggle" id="new-menu"></button>

54
src/lang.ts

@ -24,6 +24,12 @@ const lang = {
"EditProfile.Username.Help": "You can choose a username on Telegram. If you do, people will be able to find you by this username and contact you without needing your phone number.\n\nYou can use a–z, 0–9 and underscores. Minimum length is 5 characters.", "EditProfile.Username.Help": "You can choose a username on Telegram. If you do, people will be able to find you by this username and contact you without needing your phone number.\n\nYou can use a–z, 0–9 and underscores. Minimum length is 5 characters.",
"ExceptionModal.Search.Placeholder": "Add exception...", "ExceptionModal.Search.Placeholder": "Add exception...",
"ChatList.Menu.Archived": "Archived", "ChatList.Menu.Archived": "Archived",
"Chat.Menu.SelectMessages": "Select Messages",
"Chat.Menu.ClearSelection": "Clear Selection",
"Chat.Input.UnpinAll": "Unpin All Messages",
"Chat.Input.Attach.PhotoOrVideo": "Photo or Video",
"Chat.Input.Attach.Document": "Document",
"Chat.Subscribe": "SUBSCRIBE",
"Chat.Selection.MessagesCount": { "Chat.Selection.MessagesCount": {
"one_value": "%d Message", "one_value": "%d Message",
"other_value": "%d Messages", "other_value": "%d Messages",
@ -49,6 +55,13 @@ const lang = {
"Message.Context.Selection.SendNow": "Send Now selected", "Message.Context.Selection.SendNow": "Send Now selected",
"Checkbox.Enabled": "Enabled", "Checkbox.Enabled": "Enabled",
"Checkbox.Disabled": "Disabled", "Checkbox.Disabled": "Disabled",
"Error.PreviewSender.CaptionTooLong": "Caption is too long.",
"PreviewSender.GroupItems": "Group items",
"PreviewSender.Send": "SEND",
"PreviewSender.SendAlbum": {
"one_value": "Send Album",
"other_value": "Send %d Albums"
},
"Privacy.Devices": { "Privacy.Devices": {
"one_value": "%1$d device", "one_value": "%1$d device",
"other_value": "%1$d devices" "other_value": "%1$d devices"
@ -155,6 +168,12 @@ const lang = {
"BlockedUsersInfo": "Blocked users will not be able to contact you and will not see your Last Seen time.", "BlockedUsersInfo": "Blocked users will not be able to contact you and will not see your Last Seen time.",
"BlockedEmpty": "None", "BlockedEmpty": "None",
"TwoStepVerification": "Two-Step Verification", "TwoStepVerification": "Two-Step Verification",
"PinnedMessage": "Pinned Message",
"PinnedMessagesCount": {
"one_value": "Pinned Message",
"other_value": "%1$d Pinned Messages"
},
//"PreviousPinnedMessage": "Previous Message",
"PrivacyExceptions": "Exceptions", "PrivacyExceptions": "Exceptions",
"PrivacyLastSeen": "Last Seen & Online", "PrivacyLastSeen": "Last Seen & Online",
"PrivacySettings": "Privacy and Security", "PrivacySettings": "Privacy and Security",
@ -168,6 +187,8 @@ const lang = {
"PrivacyProfilePhotoTitle": "Who can see my profile photos & videos?", "PrivacyProfilePhotoTitle": "Who can see my profile photos & videos?",
"PrivacyP2PHeader": "Peer-to-Peer", "PrivacyP2PHeader": "Peer-to-Peer",
"PrivacyForwardsTitle": "Who can add a link to my account when forwarding my messages?", "PrivacyForwardsTitle": "Who can add a link to my account when forwarding my messages?",
"Reminders": "Reminders",
"ScheduledMessages": "Scheduled Messages",
"LastSeenTitle": "Who can see your Last Seen time?", "LastSeenTitle": "Who can see your Last Seen time?",
"SessionsTitle": "Active Sessions", "SessionsTitle": "Active Sessions",
"CurrentSession": "This device", "CurrentSession": "This device",
@ -197,6 +218,10 @@ const lang = {
"GroupAddMembers": "Add Members", "GroupAddMembers": "Add Members",
"SendMessageTo": "Add people...", "SendMessageTo": "Add people...",
"SelectChat": "Select Chat", "SelectChat": "Select Chat",
"JumpToDate": "Jump to Date",
"Caption": "Caption",
"Message": "Message",
"Poll": "Poll",
// * macos // * macos
"AccountSettings.Filters": "Chat Folders", "AccountSettings.Filters": "Chat Folders",
@ -216,8 +241,20 @@ const lang = {
"Chat.Service.BotPermissionAllowed": "You allowed this bot to message you when you logged in on %@", "Chat.Service.BotPermissionAllowed": "You allowed this bot to message you when you logged in on %@",
"Chat.Poll.Unvote": "Retract Vote", "Chat.Poll.Unvote": "Retract Vote",
"Chat.Poll.Stop": "Stop Poll", "Chat.Poll.Stop": "Stop Poll",
"Chat.Poll.Stop.Confirm.Header": "Stop Poll?", /* "Chat.Poll.Stop.Confirm.Header": "Stop Poll?",
"Chat.Poll.Stop.Confirm.Text": "If you stop this poll now, nobody will be able to vote in it anymore. This action cannot be undone.", "Chat.Poll.Stop.Confirm.Text": "If you stop this poll now, nobody will be able to vote in it anymore. This action cannot be undone.", */
/* "Chat.Pinned.UnpinAll": {
"one_value": "Unpin %d Message",
"other_value": "Unpin All %d Messages"
}, */
"Chat.Pinned.DontShow": "Don't Show Pinned Messages",
"Chat.Title.Comments": {
"one_value": "%d Comment",
"other_value": "%d Comments"
},
"Chat.Send.WithoutSound": "Send Without Sound",
"Chat.Send.SetReminder": "Set a Reminder",
"Chat.Send.ScheduledMessage": "Schedule Message",
"ChatList.Context.Mute": "Mute", "ChatList.Context.Mute": "Mute",
"ChatList.Context.Unmute": "Unmute", "ChatList.Context.Unmute": "Unmute",
"ChatList.Context.Pin": "Pin", "ChatList.Context.Pin": "Pin",
@ -254,6 +291,19 @@ const lang = {
"Stickers.SuggestStickers": "Suggest Stickers by Emoji", "Stickers.SuggestStickers": "Suggest Stickers by Emoji",
"ShareModal.Search.ForwardPlaceholder": "Forward to...", "ShareModal.Search.ForwardPlaceholder": "Forward to...",
"InstalledStickers.LoopAnimated": "Loop Animated Stickers", "InstalledStickers.LoopAnimated": "Loop Animated Stickers",
"PreviewSender.CaptionPlaceholder": "Add a caption...",
"PreviewSender.SendFile": {
"one_value": "Send File",
"other_value": "Send %d Files"
},
"PreviewSender.SendPhoto": {
"one_value": "Send Photo",
"other_value": "Send %d Photos"
},
"PreviewSender.SendVideo": {
"one_value": "Send Video",
"other_value": "Send %d Videos"
},
"PrivacyAndSecurity.Item.On": "On", "PrivacyAndSecurity.Item.On": "On",
"PrivacyAndSecurity.Item.Off": "Off", "PrivacyAndSecurity.Item.Off": "Off",
"PrivacySettings.VoiceCalls": "Calls", "PrivacySettings.VoiceCalls": "Calls",

35
src/lib/appManagers/appDialogsManager.ts

@ -177,9 +177,7 @@ class ConnectionStatusComponent {
} }
export class AppDialogsManager { export class AppDialogsManager {
public _chatList = document.getElementById('dialogs') as HTMLUListElement; public chatList: HTMLUListElement;
public chatList = this._chatList;
public chatListArchived: HTMLUListElement;
public doms: {[peerId: number]: DialogDom} = {}; public doms: {[peerId: number]: DialogDom} = {};
@ -196,7 +194,7 @@ export class AppDialogsManager {
public contextMenu = new DialogsContextMenu(); public contextMenu = new DialogsContextMenu();
public chatLists: {[filterId: number]: HTMLUListElement}; public chatLists: {[filterId: number]: HTMLUListElement};
public filterId = 0; public filterId: number;
private folders: {[k in 'menu' | 'container' | 'menuScrollContainer']: HTMLElement} = { private folders: {[k in 'menu' | 'container' | 'menuScrollContainer']: HTMLElement} = {
menu: document.getElementById('folders-tabs'), menu: document.getElementById('folders-tabs'),
menuScrollContainer: null, menuScrollContainer: null,
@ -223,12 +221,8 @@ export class AppDialogsManager {
private lastActiveElements: Set<HTMLElement> = new Set(); private lastActiveElements: Set<HTMLElement> = new Set();
constructor() { constructor() {
this.chatListArchived = this.createChatList();
this.chatListArchived.id = 'dialogs-archived';
this.chatLists = { this.chatLists = {
0: this.chatList, 1: this.createChatList()
1: this.chatListArchived
}; };
this.chatsPreloader = putPreloader(null, true); this.chatsPreloader = putPreloader(null, true);
@ -245,7 +239,6 @@ export class AppDialogsManager {
this.scroll.container.addEventListener('scroll', this.onChatsRegularScroll); this.scroll.container.addEventListener('scroll', this.onChatsRegularScroll);
this.scroll.onScrolledTop = this.onChatsScrollTop; this.scroll.onScrolledTop = this.onChatsScrollTop;
this.scroll.onScrolledBottom = this.onChatsScroll; this.scroll.onScrolledBottom = this.onChatsScroll;
this.scroll.setVirtualContainer(this.chatList);
//this.scroll.attachSentinels(); //this.scroll.attachSentinels();
/* if(isTouchSupported && isSafari) { /* if(isTouchSupported && isSafari) {
@ -270,7 +263,16 @@ export class AppDialogsManager {
}); });
} */ } */
this.setListClickListener(this.chatList, null, true); this.filterId = 0;
this.addFilter({
id: this.filterId,
title: '',
titleEl: i18n('ChatList.Filter.All'),
orderIndex: 0
});
this.chatList = this.chatLists[this.filterId];
this.scroll.setVirtualContainer(this.chatList);
/* if(testScroll) { /* if(testScroll) {
let i = 0; let i = 0;
@ -523,12 +525,6 @@ export class AppDialogsManager {
new ConnectionStatusComponent(this.chatsContainer); new ConnectionStatusComponent(this.chatsContainer);
this.chatsContainer.append(bottomPart); this.chatsContainer.append(bottomPart);
/* const mutationObserver = new MutationObserver((mutationList, observer) => {
});
mutationObserver.observe */
} }
private getOffset(side: 'top' | 'bottom'): {index: number, pos: number} { private getOffset(side: 'top' | 'bottom'): {index: number, pos: number} {
@ -667,7 +663,7 @@ export class AppDialogsManager {
} }
} }
private addFilter(filter: DialogFilter) { private addFilter(filter: Pick<DialogFilter, 'title' | 'id' | 'orderIndex'> & Partial<{titleEl: HTMLElement}>) {
if(this.filtersRendered[filter.id]) return; if(this.filtersRendered[filter.id]) return;
const menuTab = document.createElement('div'); const menuTab = document.createElement('div');
@ -675,7 +671,8 @@ export class AppDialogsManager {
const span = document.createElement('span'); const span = document.createElement('span');
const titleSpan = document.createElement('span'); const titleSpan = document.createElement('span');
titleSpan.classList.add('text-super'); titleSpan.classList.add('text-super');
titleSpan.innerHTML = RichTextProcessor.wrapEmojiText(filter.title); if(filter.titleEl) titleSpan.append(filter.titleEl);
else titleSpan.innerHTML = RichTextProcessor.wrapEmojiText(filter.title);
const unreadSpan = document.createElement('div'); const unreadSpan = document.createElement('div');
unreadSpan.classList.add('badge', 'badge-20', 'badge-blue'); unreadSpan.classList.add('badge', 'badge-20', 'badge-blue');
const i = document.createElement('i'); const i = document.createElement('i');

8
src/lib/langPack.ts

@ -264,7 +264,13 @@ namespace I18n {
this.element.textContent = ''; this.element.textContent = '';
this.element.append(...format(this.key, false, this.args)); this.element.append(...format(this.key, false, this.args));
} else { } else {
(this.element as HTMLInputElement)[this.property] = format(this.key, true, this.args); // @ts-ignore
const v = this.element[this.property];
const formatted = format(this.key, true, this.args);
// * hasOwnProperty won't work here
if(v === undefined) this.element.dataset[this.property] = formatted;
else (this.element as HTMLInputElement)[this.property] = formatted;
} }
} }
} }

36
src/scss/partials/_chat.scss

@ -364,6 +364,20 @@ $chat-helper-size: 39px;
transition: opacity .1s 0s; transition: opacity .1s 0s;
} }
.pinned-container {
width: auto;
/* width: 17.125rem;
.chat-input.can-pin & {
width: 13.125rem;
} */
&-button {
height: 2.5rem;
padding: 0 .625rem;
}
}
.bubbles.is-selecting ~ & { .bubbles.is-selecting ~ & {
.new-message-wrapper { .new-message-wrapper {
pointer-events: none; pointer-events: none;
@ -704,12 +718,15 @@ $chat-helper-size: 39px;
.rows-wrapper, .fake-rows-wrapper { .rows-wrapper, .fake-rows-wrapper {
.chat-input.type-pinned & { .chat-input.type-pinned & {
width: auto;
}
/* .chat-input.type-pinned & {
width: 17.125rem; width: 17.125rem;
} }
.chat-input.type-pinned.can-pin & { .chat-input.type-pinned.can-pin & {
width: 13.125rem; width: 13.125rem;
} } */
} }
.fake-rows-wrapper { .fake-rows-wrapper {
@ -717,6 +734,10 @@ $chat-helper-size: 39px;
left: var(--padding-horizontal); left: var(--padding-horizontal);
top: 0; top: 0;
width: calc(100% - var(--chat-input-size) - (var(--padding-horizontal) * 2) - .5625rem); width: calc(100% - var(--chat-input-size) - (var(--padding-horizontal) * 2) - .5625rem);
.pinned-container {
padding: 0 .5rem;
}
} }
.rows-wrapper { .rows-wrapper {
@ -877,19 +898,6 @@ $chat-helper-size: 39px;
} }
} }
.pinned-container {
width: 17.125rem;
.chat-input.can-pin & {
width: 13.125rem;
}
&-button {
height: 2.5rem;
padding: 0;
}
}
.btn-icon { .btn-icon {
flex: 0 0 auto; flex: 0 0 auto;
font-size: 24px; font-size: 24px;

13
src/scss/partials/_chatPinned.scss

@ -283,7 +283,6 @@
&.is-media { &.is-media {
.pinned-message-title, .pinned-message-subtitle { .pinned-message-title, .pinned-message-subtitle {
transform: translateX(2.5rem); transform: translateX(2.5rem);
width: calc(100% - 2.5rem);
//overflow: hidden !important; //overflow: hidden !important;
} }
} }
@ -294,7 +293,11 @@
} }
&:not(.is-floating) { &:not(.is-floating) {
width: 15.5rem; //width: 15.5rem;
.pinned-message-content {
margin-right: 2.5rem;
}
.pinned-message-close { .pinned-message-close {
display: flex; display: flex;
@ -303,6 +306,12 @@
} }
&.is-floating { &.is-floating {
&.is-media {
.pinned-message-title, .pinned-message-subtitle {
width: calc(100% - 2.5rem);
}
}
.chat:not(.type-discussion) & { .chat:not(.type-discussion) & {
.pinned-container-wrapper { .pinned-container-wrapper {
padding-right: 3rem; padding-right: 3rem;

Loading…
Cancel
Save