diff --git a/src/components/audio.ts b/src/components/audio.ts index fbd483a6..361011f5 100644 --- a/src/components/audio.ts +++ b/src/components/audio.ts @@ -8,6 +8,19 @@ import { DocumentAttribute } from "../layer"; import { Download } from "../lib/appManagers/appDownloadManager"; import mediaSizes from "../helpers/mediaSizes"; import { isSafari } from "../helpers/userAgent"; +import appMessagesManager from "../lib/appManagers/appMessagesManager"; +import $rootScope from "../lib/rootScope"; + +$rootScope.$on('messages_media_read', e => { + const mids = e.detail; + + mids.forEach(mid => { + (Array.from(document.querySelectorAll('audio-element[message-id="' + mid + '"]')) as AudioElement[]).forEach(elem => { + //console.log('updating avatar:', elem); + elem.classList.remove('is-unread'); + }); + }); +}); // https://github.com/LonamiWebs/Telethon/blob/4393ec0b83d511b6a20d8a20334138730f084375/telethon/utils.py#L1285 export function decodeWaveform(waveform: Uint8Array | number[]) { @@ -42,9 +55,16 @@ export function decodeWaveform(waveform: Uint8Array | number[]) { return result; } -function wrapVoiceMessage(doc: MyDocument, audioEl: AudioElement) { +function wrapVoiceMessage(doc: MyDocument, audioEl: AudioElement, mid: number) { audioEl.classList.add('is-voice'); + const message = appMessagesManager.getMessage(mid); + const isOut = message.fromID == $rootScope.myID && message.peerID != $rootScope.myID; + let isUnread = message && message.pFlags.media_unread; + if(isUnread) { + audioEl.classList.add('is-unread'); + } + const barWidth = 2; const barMargin = mediaSizes.isMobile ? 2 : 1; const barHeightMin = mediaSizes.isMobile ? 3 : 2; @@ -143,6 +163,12 @@ function wrapVoiceMessage(doc: MyDocument, audioEl: AudioElement) { } audioEl.addAudioListener('playing', () => { + if(isUnread && !isOut && audioEl.classList.contains('is-unread')) { + audioEl.classList.remove('is-unread'); + appMessagesManager.readMessages([mid]); + isUnread = false; + } + //rects.forEach(node => node.classList.remove('active')); start(); }); @@ -310,7 +336,7 @@ export default class AudioElement extends HTMLElement { this.append(downloadDiv); } - const onTypeLoad = doc.type == 'voice' ? wrapVoiceMessage(doc, this) : wrapAudio(doc, this); + const onTypeLoad = doc.type == 'voice' ? wrapVoiceMessage(doc, this, mid) : wrapAudio(doc, this); const audioTimeDiv = this.querySelector('.audio-time') as HTMLDivElement; audioTimeDiv.innerHTML = durationStr; diff --git a/src/lib/appManagers/appMessagesManager.ts b/src/lib/appManagers/appMessagesManager.ts index 2a6f969e..36784117 100644 --- a/src/lib/appManagers/appMessagesManager.ts +++ b/src/lib/appManagers/appMessagesManager.ts @@ -3389,10 +3389,10 @@ export class AppMessagesManager { } public readMessages(messageIDs: number[]) { - var splitted = appMessagesIDsManager.splitMessageIDsByChannels(messageIDs); + const splitted = appMessagesIDsManager.splitMessageIDsByChannels(messageIDs); Object.keys(splitted.msgIDs).forEach((channelID: number | string) => { channelID = +channelID; - let msgIDs = splitted.msgIDs[channelID]; + const msgIDs = splitted.msgIDs[channelID]; if(channelID > 0) { apiManager.invokeApi('channels.readMessageContents', { @@ -3821,8 +3821,8 @@ export class AppMessagesManager { } case 'updateChannelReadMessagesContents': { - var channelID: number = update.channel_id; - var newMessages: any[] = []; + const channelID: number = update.channel_id; + const newMessages: number[] = []; update.messages.forEach((msgID: number) => { newMessages.push(appMessagesIDsManager.getFullMessageID(msgID, channelID)); }); @@ -3830,16 +3830,15 @@ export class AppMessagesManager { } case 'updateReadMessagesContents': { - var messages: any[] = update.messages; - var len = messages.length; - var i; - var messageID: number, message; - for(i = 0; i < len; i++) { - messageID = messages[i]; - if(message = this.messagesStorage[messageID]) { + const messages: number[] = update.messages; + for(const messageID of messages) { + const message = this.messagesStorage[messageID]; + if(message) { delete message.pFlags.media_unread; } } + + $rootScope.$broadcast('messages_media_read', messages); break; } diff --git a/src/lib/rootScope.ts b/src/lib/rootScope.ts index 881617a7..8587aeb7 100644 --- a/src/lib/rootScope.ts +++ b/src/lib/rootScope.ts @@ -37,6 +37,7 @@ type BroadcastEvents = { 'messages_pending': void, 'messages_read': void, 'messages_downloaded': number[], + 'messages_media_read': number[], 'stickers_installed': StickerSet.stickerSet, 'stickers_deleted': StickerSet.stickerSet, diff --git a/src/scss/partials/_audio.scss b/src/scss/partials/_audio.scss index 1773d4d5..032c026f 100644 --- a/src/scss/partials/_audio.scss +++ b/src/scss/partials/_audio.scss @@ -347,7 +347,7 @@ //overflow: visible!important; fill: #CBCBCB; - &.active { + &.active, .audio.is-unread & { fill: $color-blue; } } @@ -393,4 +393,18 @@ } } } + + &.is-voice.is-unread { + .audio-time { + &:after { + content: " "; + width: .5rem; + height: .5rem; + background-color: $color-blue; + border-radius: 50%; + margin-left: .375rem; + display: inline-block; + } + } + } } \ No newline at end of file diff --git a/src/scss/partials/_chatBubble.scss b/src/scss/partials/_chatBubble.scss index 83d8123f..f3a24e69 100644 --- a/src/scss/partials/_chatBubble.scss +++ b/src/scss/partials/_chatBubble.scss @@ -1400,6 +1400,17 @@ $bubble-margin: .25rem; &-download:empty { display: none; } + + &.is-unread { + rect { + //fill: #68AB5A; + fill: #B8DDA9; + } + + .audio-time:after { + background-color: #68AB5A; + } + } } &.is-message-empty.is-group-last {