Browse Source

Shared media voice tab

Fix colored animated emoji
master
morethanwords 4 years ago
parent
commit
b9ca65650f
  1. 39
      src/components/appSearchSuper..ts
  2. 3
      src/components/sidebarLeft/index.ts
  3. 10
      src/components/sidebarRight/tabs/sharedMedia.ts
  4. 48
      src/lib/lottieLoader.ts
  5. 30
      src/scss/partials/_rightSidebar.scss
  6. 2
      src/scss/style.scss

39
src/components/appSearchSuper..ts

@ -112,8 +112,9 @@ export default class AppSearchSuper {
public groupByMonth? = true; public groupByMonth? = true;
public hideEmptyTabs? = true; public hideEmptyTabs? = true;
public onChangeTab?: (mediaTab: SearchSuperMediaTab) => void; public onChangeTab?: (mediaTab: SearchSuperMediaTab) => void;
public showSender? = false;
constructor(options: Pick<AppSearchSuper, 'mediaTabs' | 'scrollable' | 'searchGroups' | 'asChatList' | 'groupByMonth' | 'hideEmptyTabs' | 'onChangeTab'>) { constructor(options: Pick<AppSearchSuper, 'mediaTabs' | 'scrollable' | 'searchGroups' | 'asChatList' | 'groupByMonth' | 'hideEmptyTabs' | 'onChangeTab' | 'showSender'>) {
safeAssign(this, options); safeAssign(this, options);
this.container = document.createElement('div'); this.container = document.createElement('div');
@ -401,25 +402,26 @@ export default class AppSearchSuper {
return filtered; return filtered;
} }
public async performSearchResult(messages: any[], type: SearchSuperType, append = true) { public async performSearchResult(messages: any[], mediaTab: SearchSuperMediaTab, append = true) {
const elemsToAppend: {element: HTMLElement, message: any}[] = []; const elemsToAppend: {element: HTMLElement, message: any}[] = [];
const sharedMediaDiv: HTMLElement = this.tabs[type]; const sharedMediaDiv: HTMLElement = mediaTab.contentTab;
const promises: Promise<any>[] = []; const promises: Promise<any>[] = [];
const middleware = this.middleware.get(); const middleware = this.middleware.get();
let inputFilter = mediaTab.inputFilter;
await getHeavyAnimationPromise(); await getHeavyAnimationPromise();
let searchGroup: SearchGroup; let searchGroup: SearchGroup;
if(type === 'inputMessagesFilterPhotoVideo' && !!this.searchContext.query.trim()) { if(inputFilter === 'inputMessagesFilterPhotoVideo' && !!this.searchContext.query.trim()) {
type = 'inputMessagesFilterEmpty'; inputFilter = 'inputMessagesFilterEmpty';
searchGroup = this.searchGroupMedia; searchGroup = this.searchGroupMedia;
sharedMediaDiv.append(searchGroup.container); sharedMediaDiv.append(searchGroup.container);
} else if(type === 'inputMessagesFilterEmpty') { } else if(inputFilter === 'inputMessagesFilterEmpty') {
searchGroup = this.searchGroups.messages; searchGroup = this.searchGroups.messages;
} }
// https://core.telegram.org/type/MessagesFilter // https://core.telegram.org/type/MessagesFilter
switch(type) { switch(inputFilter) {
case 'inputMessagesFilterEmpty': { case 'inputMessagesFilterEmpty': {
for(const message of messages) { for(const message of messages) {
const {dialog, dom} = appDialogsManager.addDialogNew({ const {dialog, dom} = appDialogsManager.addDialogNew({
@ -488,17 +490,20 @@ export default class AppSearchSuper {
case 'inputMessagesFilterMusic': case 'inputMessagesFilterMusic':
case 'inputMessagesFilterDocument': { case 'inputMessagesFilterDocument': {
for(const message of messages) { for(const message of messages) {
const showSender = this.showSender || message.media.document.type === 'voice';
const div = wrapDocument({ const div = wrapDocument({
message, message,
withTime: !this.asChatList, withTime: !showSender,
fontWeight: 400, fontWeight: 400,
voiceAsMusic: true, voiceAsMusic: true,
showSender: this.asChatList, showSender: showSender,
searchContext: this.copySearchContext(type) searchContext: this.copySearchContext(inputFilter)
}); });
if(message.media.document.type === 'audio') {
if(['audio', 'voice'].includes(message.media.document.type)) {
div.classList.add('audio-48'); div.classList.add('audio-48');
} }
elemsToAppend.push({element: div, message}); elemsToAppend.push({element: div, message});
} }
break; break;
@ -589,10 +594,10 @@ export default class AppSearchSuper {
title = RichTextProcessor.wrapPlainText(webpage.display_url.split('/', 1)[0]); title = RichTextProcessor.wrapPlainText(webpage.display_url.split('/', 1)[0]);
} }
let sender = this.asChatList ? `<div class="subtitle sender">${appMessagesManager.getSenderToPeerText(message)}</div>` : ''; let sender = this.showSender ? `<div class="subtitle sender">${appMessagesManager.getSenderToPeerText(message)}</div>` : '';
let titleAdditionHTML = ''; let titleAdditionHTML = '';
if(this.asChatList) { if(this.showSender) {
titleAdditionHTML = `<div class="sent-time">${formatDateAccordingToToday(new Date(message.date * 1000))}</div>`; titleAdditionHTML = `<div class="sent-time">${formatDateAccordingToToday(new Date(message.date * 1000))}</div>`;
} }
@ -634,7 +639,7 @@ export default class AppSearchSuper {
const method = append ? 'append' : 'prepend'; const method = append ? 'append' : 'prepend';
elemsToAppend.forEach(details => { elemsToAppend.forEach(details => {
const {element, message} = details; const {element, message} = details;
const monthContainer = this.getMonthContainerByTimestamp(this.groupByMonth ? message.date : 0, type); const monthContainer = this.getMonthContainerByTimestamp(this.groupByMonth ? message.date : 0, inputFilter);
element.classList.add('search-super-item'); element.classList.add('search-super-item');
element.dataset.mid = '' + message.mid; element.dataset.mid = '' + message.mid;
element.dataset.peerId = '' + message.peerId; element.dataset.peerId = '' + message.peerId;
@ -643,7 +648,7 @@ export default class AppSearchSuper {
} }
//if(type !== 'inputMessagesFilterEmpty') { //if(type !== 'inputMessagesFilterEmpty') {
this.afterPerforming(type === 'inputMessagesFilterEmpty' ? 1 : messages.length, sharedMediaDiv); this.afterPerforming(inputFilter === 'inputMessagesFilterEmpty' ? 1 : messages.length, sharedMediaDiv);
//} //}
} }
@ -957,7 +962,7 @@ export default class AppSearchSuper {
this.usedFromHistory[type] = used; this.usedFromHistory[type] = used;
//if(messages.length) { //if(messages.length) {
return this.performSearchResult(messages, type).finally(() => { return this.performSearchResult(messages, mediaTab).finally(() => {
setTimeout(() => { setTimeout(() => {
this.scrollable.checkForTriggers(); this.scrollable.checkForTriggers();
}, 0); }, 0);
@ -1030,7 +1035,7 @@ export default class AppSearchSuper {
} }
//if(value.history.length) { //if(value.history.length) {
return this.performSearchResult(this.filterMessagesByType(value.history, type), type); return this.performSearchResult(this.filterMessagesByType(value.history, type), mediaTab);
//} //}
}).catch(err => { }).catch(err => {
this.log.error('load error:', err); this.log.error('load error:', err);

3
src/components/sidebarLeft/index.ts

@ -230,7 +230,8 @@ export class AppSidebarLeft extends SidebarSlider {
scrollable, scrollable,
searchGroups: this.searchGroups, searchGroups: this.searchGroups,
asChatList: true, asChatList: true,
hideEmptyTabs: false hideEmptyTabs: false,
showSender: true
}); });
searchContainer.prepend(searchSuper.nav.parentElement.parentElement); searchContainer.prepend(searchSuper.nav.parentElement.parentElement);

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

@ -777,6 +777,10 @@ export default class AppSharedMediaTab extends SliderSuperTab {
inputFilter: 'inputMessagesFilterMusic', inputFilter: 'inputMessagesFilterMusic',
name: 'SharedMusicTab2', name: 'SharedMusicTab2',
type: 'music' type: 'music'
}, {
inputFilter: 'inputMessagesFilterVoice',
name: 'SharedVoiceTab2',
type: 'voice'
}], }],
scrollable: this.scrollable, scrollable: this.scrollable,
onChangeTab: (mediaTab) => { onChangeTab: (mediaTab) => {
@ -864,8 +868,8 @@ export default class AppSharedMediaTab extends SliderSuperTab {
if(!this.historiesStorage[peerId]) return; if(!this.historiesStorage[peerId]) return;
mids = mids.slice().reverse(); // ! because it will be ascend sorted array mids = mids.slice().reverse(); // ! because it will be ascend sorted array
for(const type of this.searchSuper.mediaTabs) { for(const mediaTab of this.searchSuper.mediaTabs) {
const inputFilter = type.inputFilter; const inputFilter = mediaTab.inputFilter;
const filtered = this.searchSuper.filterMessagesByType(mids.map(mid => appMessagesManager.getMessageByPeer(peerId, mid)), inputFilter); const filtered = this.searchSuper.filterMessagesByType(mids.map(mid => appMessagesManager.getMessageByPeer(peerId, mid)), inputFilter);
if(filtered.length) { if(filtered.length) {
if(this.historiesStorage[peerId][inputFilter]) { if(this.historiesStorage[peerId][inputFilter]) {
@ -874,7 +878,7 @@ export default class AppSharedMediaTab extends SliderSuperTab {
if(this.peerId === peerId && this.searchSuper.usedFromHistory[inputFilter] !== -1) { if(this.peerId === peerId && this.searchSuper.usedFromHistory[inputFilter] !== -1) {
this.searchSuper.usedFromHistory[inputFilter] += filtered.length; this.searchSuper.usedFromHistory[inputFilter] += filtered.length;
this.searchSuper.performSearchResult(filtered, inputFilter, false); this.searchSuper.performSearchResult(filtered, mediaTab, false);
} }
break; break;

48
src/lib/lottieLoader.ts

@ -507,6 +507,13 @@ class QueryableWorker extends EventListenerBase<any> {
} }
} }
type LottieShape = {
c: {
k: number[]
},
ty: 'st' | 'fl',
it?: LottieShape[]
};
class LottieLoader { class LottieLoader {
public isWebAssemblySupported = typeof(WebAssembly) !== 'undefined'; public isWebAssemblySupported = typeof(WebAssembly) !== 'undefined';
public loadPromise: Promise<void> = !this.isWebAssemblySupported ? Promise.reject() : undefined; public loadPromise: Promise<void> = !this.isWebAssemblySupported ? Promise.reject() : undefined;
@ -604,18 +611,16 @@ class LottieLoader {
}); });
} }
private applyReplacements(object: any, toneIndex: number) { private applyReplacements(object: {
layers: Array<{shapes: LottieShape[]}>
}, toneIndex: number) {
const replacements = LottieLoader.COLORREPLACEMENTS[Math.max(toneIndex - 1, 0)]; const replacements = LottieLoader.COLORREPLACEMENTS[Math.max(toneIndex - 1, 0)];
const iterateIt = (it: any) => { const applyTo = (smth: LottieShape) => {
for(let smth of it) { const k = smth.c.k;
switch(smth.ty) { const color = convert(k[2]) | (convert(k[1]) << 8) | (convert(k[0]) << 16);
case 'st':
case 'fl':
let k = smth.c.k;
let color = convert(k[2]) | (convert(k[1]) << 8) | (convert(k[0]) << 16);
let foundReplacement = replacements.find(p => p[0] === color); const foundReplacement = replacements.find(p => p[0] === color);
if(foundReplacement) { if(foundReplacement) {
k[0] = ((foundReplacement[1] >> 16) & 255) / 255; k[0] = ((foundReplacement[1] >> 16) & 255) / 255;
k[1] = ((foundReplacement[1] >> 8) & 255) / 255; k[1] = ((foundReplacement[1] >> 8) & 255) / 255;
@ -623,22 +628,43 @@ class LottieLoader {
} }
//console.log('foundReplacement!', foundReplacement, color.toString(16), k); //console.log('foundReplacement!', foundReplacement, color.toString(16), k);
};
const checkSmth = (smth: LottieShape) => {
switch(smth.ty) {
case 'st':
case 'fl':
applyTo(smth);
break; break;
} }
if(smth.hasOwnProperty('it')) { if(smth.hasOwnProperty('it')) {
iterateIt(smth.it); iterateIt(smth.it);
} }
};
const iterateIt = (it: LottieShape['it']) => {
for(const smth of it) {
checkSmth(smth);
} }
}; };
for(let layer of object.layers) { try {
for(const layer of object.layers) {
if(!layer.shapes) continue; if(!layer.shapes) continue;
for(let shape of layer.shapes) { for(const shape of layer.shapes) {
if(!shape.it) {
checkSmth(shape);
continue;
}
iterateIt(shape.it); iterateIt(shape.it);
} }
} }
} catch(err) {
this.log.warn('cant apply replacements', err, object, toneIndex);
}
} }
public loadAnimationFromURL(params: Omit<RLottieOptions, 'animationData'>, url: string): Promise<RLottiePlayer> { public loadAnimationFromURL(params: Omit<RLottieOptions, 'animationData'>, url: string): Promise<RLottiePlayer> {

30
src/scss/partials/_rightSidebar.scss

@ -193,6 +193,9 @@
} }
&-tabs { &-tabs {
width: auto;
flex: 1 1 auto;
//margin-top: 36px; //margin-top: 36px;
i { i {
padding-right: 1.5rem !important; padding-right: 1.5rem !important;
@ -222,6 +225,7 @@
.scrollable { .scrollable {
position: relative; position: relative;
display: flex;
} }
} }
@ -282,6 +286,19 @@
display: none; display: none;
} }
.document-name, .audio-title, .title {
display: flex;
justify-content: space-between;
}
.sent-time {
flex: 0 0 auto;
margin-left: 8px;
margin-top: 3px;
font-size: 12px;
color: var(--secondary-text-color);
}
&-content-media { &-content-media {
.search-super-month-name { .search-super-month-name {
border: none; border: none;
@ -500,19 +517,6 @@
} }
} }
.document-name, .audio-title, .title {
display: flex;
justify-content: space-between;
}
.sent-time {
flex: 0 0 auto;
margin-left: 8px;
margin-top: 3px;
font-size: 12px;
color: var(--secondary-text-color);
}
.search-group.is-short { .search-group.is-short {
li:nth-child(n + 4) { li:nth-child(n + 4) {
display: none; display: none;

2
src/scss/style.scss

@ -213,13 +213,13 @@ html.night {
@import "partials/crop"; @import "partials/crop";
@import "partials/sidebar"; @import "partials/sidebar";
@import "partials/profile"; @import "partials/profile";
@import "partials/slider";
@import "partials/leftSidebar"; @import "partials/leftSidebar";
@import "partials/rightSidebar"; @import "partials/rightSidebar";
@import "partials/mediaViewer"; @import "partials/mediaViewer";
@import "partials/ckin"; @import "partials/ckin";
@import "partials/emojiDropdown"; @import "partials/emojiDropdown";
@import "partials/scrollable"; @import "partials/scrollable";
@import "partials/slider";
@import "partials/selector"; @import "partials/selector";
@import "partials/gifsMasonry"; @import "partials/gifsMasonry";
@import "partials/preloader"; @import "partials/preloader";

Loading…
Cancel
Save