Browse Source

Fix scrolling to last bubble in outer chats

Avoid opening the same profile
Show write menu on touch devices
master
Eduard Kuzmenko 4 years ago
parent
commit
9458e82a96
  1. 15
      src/components/chat/bubbles.ts
  2. 2
      src/components/chat/chat.ts
  3. 2
      src/components/chat/input.ts
  4. 14
      src/components/sidebarRight/tabs/sharedMedia.ts
  5. 3
      src/index.hbs
  6. 12
      src/lib/appManagers/appImManager.ts
  7. 2
      src/lib/appManagers/appMessagesManager.ts
  8. 2
      src/lib/appManagers/appNotificationsManager.ts
  9. 2
      src/lib/rootScope.ts
  10. 8
      src/pages/pageSignIn.ts
  11. 4
      src/scss/partials/_badge.scss
  12. 51
      src/scss/partials/_chatBubble.scss
  13. 12
      src/scss/partials/_leftSidebar.scss
  14. 1
      src/scss/style.scss

15
src/components/chat/bubbles.ts

@ -423,12 +423,14 @@ export default class ChatBubbles {
public constructPeerHelpers() { public constructPeerHelpers() {
// will call when message is sent (only 1) // will call when message is sent (only 1)
this.listenerSetter.add(rootScope, 'history_append', (e) => { this.listenerSetter.add(rootScope, 'history_append', (e) => {
let details = e; const {peerId, storage, mid} = e;
if(peerId !== this.peerId || storage !== this.chat.getMessagesStorage()) return;
if(!this.scrollable.loadedAll.bottom) { if(!this.scrollable.loadedAll.bottom) {
this.chat.setMessageId(); this.chat.setMessageId();
} else { } else {
this.renderNewMessagesByIds([details.messageId], true); this.renderNewMessagesByIds([mid], true);
} }
}); });
@ -1180,6 +1182,11 @@ export default class ChatBubbles {
} }
mids = mids.filter(mid => !this.bubbles[mid]); mids = mids.filter(mid => !this.bubbles[mid]);
// ! should scroll even without new messages
/* if(!mids.length) {
return;
} */
const promise = this.performHistoryResult(mids, false, true); const promise = this.performHistoryResult(mids, false, true);
if(scrolledDown) { if(scrolledDown) {
promise.then(() => { promise.then(() => {
@ -1540,9 +1547,9 @@ export default class ChatBubbles {
animationIntersector.unlockGroup(CHAT_ANIMATION_GROUP); animationIntersector.unlockGroup(CHAT_ANIMATION_GROUP);
animationIntersector.checkAnimations(false, CHAT_ANIMATION_GROUP/* , true */); animationIntersector.checkAnimations(false, CHAT_ANIMATION_GROUP/* , true */);
fastRaf(() => { //fastRaf(() => {
this.lazyLoadQueue.unlock(); this.lazyLoadQueue.unlock();
}); //});
//if(dialog && lastMsgID && lastMsgID !== topMessage && (this.bubbles[lastMsgID] || this.firstUnreadBubble)) { //if(dialog && lastMsgID && lastMsgID !== topMessage && (this.bubbles[lastMsgID] || this.firstUnreadBubble)) {
if(savedPosition) { if(savedPosition) {

2
src/components/chat/chat.ts

@ -322,4 +322,4 @@ export default class Chat extends EventListenerBase<{
public isAnyGroup() { public isAnyGroup() {
return this.peerId === rootScope.myId || this.peerId === REPLIES_PEER_ID || this.appPeersManager.isAnyGroup(this.peerId); return this.peerId === rootScope.myId || this.peerId === REPLIES_PEER_ID || this.appPeersManager.isAnyGroup(this.peerId);
} }
} }

2
src/components/chat/input.ts

@ -158,7 +158,7 @@ export default class ChatInput {
this.goDownBtn = Button('bubbles-go-down btn-corner btn-circle z-depth-1 hide', {icon: 'arrow_down'}); this.goDownBtn = Button('bubbles-go-down btn-corner btn-circle z-depth-1 hide', {icon: 'arrow_down'});
this.goDownUnreadBadge = document.createElement('span'); this.goDownUnreadBadge = document.createElement('span');
this.goDownUnreadBadge.classList.add('badge', 'badge-24', 'badge-green'); this.goDownUnreadBadge.classList.add('badge', 'badge-24', 'badge-primary');
this.goDownBtn.append(this.goDownUnreadBadge); this.goDownBtn.append(this.goDownUnreadBadge);
this.inputContainer.append(this.goDownBtn); this.inputContainer.append(this.goDownBtn);

14
src/components/sidebarRight/tabs/sharedMedia.ts

@ -335,7 +335,7 @@ class PeerProfileAvatars {
} else { } else {
const promises: [Promise<ChatFull>, ReturnType<AppMessagesManager['getSearch']>] = [] as any; const promises: [Promise<ChatFull>, ReturnType<AppMessagesManager['getSearch']>] = [] as any;
if(!listLoader.current) { if(!listLoader.current) {
promises.push(appProfileManager.getChatFull(peerId)); promises.push(appProfileManager.getChatFull(-peerId));
} }
promises.push(appMessagesManager.getSearch({ promises.push(appMessagesManager.getSearch({
@ -767,6 +767,7 @@ export default class AppSharedMediaTab extends SliderSuperTab {
private searchSuper: AppSearchSuper; private searchSuper: AppSearchSuper;
private profile: PeerProfile; private profile: PeerProfile;
peerChanged: boolean;
constructor(slider: SidebarSlider) { constructor(slider: SidebarSlider) {
super(slider, false); super(slider, false);
@ -1054,10 +1055,11 @@ export default class AppSharedMediaTab extends SliderSuperTab {
} }
public setPeer(peerId: number, threadId = 0) { public setPeer(peerId: number, threadId = 0) {
if(this.peerId === peerId && this.threadId === peerId) return; if(this.peerId === peerId && this.threadId === threadId) return false;
this.peerId = peerId; this.peerId = peerId;
this.threadId = threadId; this.threadId = threadId;
this.peerChanged = true;
if(this.init) { if(this.init) {
this.init(); this.init();
@ -1071,9 +1073,17 @@ export default class AppSharedMediaTab extends SliderSuperTab {
}); });
this.profile.setPeer(peerId, threadId); this.profile.setPeer(peerId, threadId);
return true;
} }
public fillProfileElements() { public fillProfileElements() {
if(!this.peerChanged) {
return;
}
this.peerChanged = false;
this.cleanupHTML(); this.cleanupHTML();
this.profile.fillProfileElements(); this.profile.fillProfileElements();

3
src/index.hbs

@ -7,13 +7,14 @@
<meta name="description" content="Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed."> <meta name="description" content="Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.">
<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, maximum-scale=1.0, user-scalable=no" />
<!-- 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="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="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="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="icon" type="image/png" sizes="16x16" href="/assets/img/favicon-16x16.png?v=jw3mK7G9Ry">-->
<link rel="manifest" href="/assets/img/site.webmanifest?v=jw3mK7G9Ry"> <link rel="manifest" href="/assets/img/site.webmanifest?v=jw3mK7G9Ry">
<link rel="mask-icon" href="/assets/img/safari-pinned-tab.svg?v=jw3mK7G9Ry" color="#3390ec"> <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"> <!--<link rel="shortcut icon" href="/assets/img/favicon.ico?v=jw3mK7G9Ry">-->
<meta name="apple-mobile-web-app-title" content="Telegram WebK"> <meta name="apple-mobile-web-app-title" content="Telegram WebK">
<meta name="application-name" content="Telegram WebK"> <meta name="application-name" content="Telegram WebK">
<meta name="msapplication-TileColor" content="#2d89ef"> <meta name="msapplication-TileColor" content="#2d89ef">

12
src/lib/appManagers/appImManager.ts

@ -695,9 +695,11 @@ export class AppImManager {
searchTab.close(); searchTab.close();
} }
appSidebarRight.sharedMediaTab.setPeer(this.chat.peerId, this.chat.threadId); const isSet = appSidebarRight.sharedMediaTab.setPeer(this.chat.peerId, this.chat.threadId);
appSidebarRight.sharedMediaTab.loadSidebarMedia(true); if(isSet) {
appSidebarRight.sharedMediaTab.fillProfileElements(); appSidebarRight.sharedMediaTab.loadSidebarMedia(true);
appSidebarRight.sharedMediaTab.fillProfileElements();
}
/* setTimeout(() => { /* setTimeout(() => {
appSidebarRight.sharedMediaTab.loadSidebarMedia(false); appSidebarRight.sharedMediaTab.loadSidebarMedia(false);
@ -837,9 +839,7 @@ export class AppImManager {
if(!peerId) return ''; if(!peerId) return '';
if(peerId < 0) { // not human if(peerId < 0) { // not human
const chat = appPeersManager.getPeer(peerId); const chatInfo = await appProfileManager.getChatFull(-peerId) as any;
const chatInfo = await appProfileManager.getChatFull(chat.id) as any;
this.chat.log('chatInfo res:', chatInfo); this.chat.log('chatInfo res:', chatInfo);
const participants_count = chatInfo.participants_count || (chatInfo.participants && chatInfo.participants.participants && chatInfo.participants.participants.length) || 1; const participants_count = chatInfo.participants_count || (chatInfo.participants && chatInfo.participants.participants && chatInfo.participants.participants.length) || 1;

2
src/lib/appManagers/appMessagesManager.ts

@ -1401,7 +1401,7 @@ export class AppMessagesManager {
this.saveMessages([message], {storage, isOutgoing: true}); this.saveMessages([message], {storage, isOutgoing: true});
setTimeout(() => { setTimeout(() => {
this.setDialogTopMessage(message); this.setDialogTopMessage(message);
rootScope.broadcast('history_append', {peerId, messageId, my: true}); rootScope.broadcast('history_append', {storage, peerId, mid: messageId});
}, 0); }, 0);
} }

2
src/lib/appManagers/appNotificationsManager.ts

@ -237,7 +237,7 @@ export class AppNotificationsManager {
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.beginPath(); ctx.beginPath();
ctx.arc(canvas.width / 2, canvas.height / 2, canvas.width / 2, 0, 2 * Math.PI, false); ctx.arc(canvas.width / 2, canvas.height / 2, canvas.width / 2, 0, 2 * Math.PI, false);
ctx.fillStyle = '#5b8af1'; ctx.fillStyle = '#3390ec';
ctx.fill(); ctx.fill();
let fontSize = 24; let fontSize = 24;

2
src/lib/rootScope.ts

@ -44,7 +44,7 @@ export type BroadcastEvents = {
'dialogs_multiupdate': {[peerId: string]: Dialog}, 'dialogs_multiupdate': {[peerId: string]: Dialog},
'dialogs_archived_unread': {count: number}, 'dialogs_archived_unread': {count: number},
'history_append': {peerId: number, messageId: number, my?: boolean}, 'history_append': {storage: MessagesStorage, peerId: number, mid: number},
'history_update': {storage: MessagesStorage, peerId: number, mid: number}, 'history_update': {storage: MessagesStorage, peerId: number, mid: number},
'history_reply_markup': {peerId: number}, 'history_reply_markup': {peerId: number},
'history_multiappend': AppMessagesManager['newMessagesToHandle'], 'history_multiappend': AppMessagesManager['newMessagesToHandle'],

8
src/pages/pageSignIn.ts

@ -31,7 +31,7 @@ type Country = _Country & {
}; };
//import _countries from '../countries_pretty.json'; //import _countries from '../countries_pretty.json';
let btnNext: HTMLButtonElement = null; let btnNext: HTMLButtonElement = null, btnQr: HTMLButtonElement;
let onFirstMount = () => { let onFirstMount = () => {
if(Modes.test) { if(Modes.test) {
@ -362,7 +362,7 @@ let onFirstMount = () => {
attachClickEvent(btnNext, onSubmit); attachClickEvent(btnNext, onSubmit);
const btnQr = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Login'}); btnQr = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Login.QR.Login'});
let qrMounted = false; let qrMounted = false;
btnQr.addEventListener('click', () => { btnQr.addEventListener('click', () => {
@ -494,6 +494,10 @@ const page = new Page('page-sign', true, onFirstMount, () => {
btnNext.removeAttribute('disabled'); btnNext.removeAttribute('disabled');
} }
if(btnQr) {
btnQr.removeAttribute('disabled');
}
appStateManager.pushToState('authState', {_: 'authStateSignIn'}); appStateManager.pushToState('authState', {_: 'authStateSignIn'});
appStateManager.saveState(); appStateManager.saveState();
}); });

4
src/scss/partials/_badge.scss

@ -45,10 +45,6 @@
padding: 0; padding: 0;
} */ } */
&-green {
background-color: $color-green;
}
&-primary { &-primary {
background-color: var(--primary-color); background-color: var(--primary-color);
} }

51
src/scss/partials/_chatBubble.scss

@ -2094,9 +2094,9 @@ $bubble-margin: .25rem;
width: 100%; width: 100%;
&-row { &-row {
margin-top: 5px; margin-top: .3125rem;
overflow: hidden; overflow: hidden;
height: 40px; min-height: 2.5rem;
display: flex; display: flex;
&:last-child { &:last-child {
@ -2106,44 +2106,61 @@ $bubble-margin: .25rem;
} }
&-button { &-button {
display: flex; padding: .5625rem 0;
justify-content: center;
align-items: center;
border-radius: 6px; border-radius: 6px;
//background-color: rgba(0, 0, 0, .23);
background: var(--message-highlightning-color);
z-index: 2; z-index: 2;
font-size: 14px; font-size: .875rem;
user-select: none; user-select: none;
text-align: center; text-align: center;
color: white !important; color: #fff !important;
outline: none; outline: none;
border: none; border: none;
width: 100%; width: 100%;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
transition: background-color .35s ease;
overflow: hidden; overflow: hidden;
//line-height: var(--line-height);
background: var(--message-highlightning-color);
&:before {
content: " ";
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border-radius: inherit;
opacity: 0;
z-index: -1;
background-color: #fff;
@include animation-level(2) {
transition: opacity .35s ease;
}
}
@include hover() { @include hover() {
background-color: rgba(0, 0, 0, .06); &:before {
opacity: var(--hover-alpha);
}
} }
& + & { & + & {
margin-left: 5px; margin-left: .3125rem;
} }
&.is-link:before { &.is-link:before {
content: $tgico-arrow-next; content: $tgico-arrow-next;
position: absolute; position: absolute;
right: 2px; right: .125rem;
top: 2px; top: .125rem;
display: block; display: block;
transform: rotate(-45deg); transform: rotate(-45deg);
} }
/* img.emoji { img.emoji {
vertical-align: middle !important; margin: 0 .125rem;
} */ }
} }
} }

12
src/scss/partials/_leftSidebar.scss

@ -364,18 +364,16 @@
position: fixed !important; position: fixed !important;
z-index: 1; z-index: 1;
&:not(.is-hidden) {
transform: translateZ(0);
}
} }
}
@include respond-to(not-handhelds) { html:not(.no-touch) & {
html.no-touch &:hover .btn-corner:not(.is-hidden) {
transform: translateZ(0); transform: translateZ(0);
} }
} }
html.no-touch &:hover .btn-corner:not(.is-hidden) {
transform: translateZ(0);
}
} }
.connection-status { .connection-status {

1
src/scss/style.scss

@ -9,7 +9,6 @@ $border-radius: 8px;
$border-radius-medium: 10px; $border-radius-medium: 10px;
$border-radius-big: 12px; $border-radius-big: 12px;
$color-green: #4DCD5E;
$hover-alpha: .08; $hover-alpha: .08;
//$small-screen: 720px; //$small-screen: 720px;

Loading…
Cancel
Save