some changes
This commit is contained in:
parent
aafa1f00bb
commit
7bd087ec0e
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
@ -11,6 +11,7 @@ import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
|||||||
import initEmoticonsDropdown, { EMOTICONSSTICKERGROUP } from "./emoticonsDropdown";
|
import initEmoticonsDropdown, { EMOTICONSSTICKERGROUP } from "./emoticonsDropdown";
|
||||||
import lottieLoader from "../lib/lottieLoader";
|
import lottieLoader from "../lib/lottieLoader";
|
||||||
import { Layouter, RectPart } from "./groupedLayout";
|
import { Layouter, RectPart } from "./groupedLayout";
|
||||||
|
import Recorder from '../opus-recorder/dist/recorder.min';
|
||||||
|
|
||||||
export class ChatInput {
|
export class ChatInput {
|
||||||
public pageEl = document.getElementById('page-chats') as HTMLDivElement;
|
public pageEl = document.getElementById('page-chats') as HTMLDivElement;
|
||||||
@ -19,6 +20,7 @@ export class ChatInput {
|
|||||||
public inputMessageContainer = document.getElementsByClassName('input-message-container')[0] as HTMLDivElement;
|
public inputMessageContainer = document.getElementsByClassName('input-message-container')[0] as HTMLDivElement;
|
||||||
public inputScroll = new Scrollable(this.inputMessageContainer);
|
public inputScroll = new Scrollable(this.inputMessageContainer);
|
||||||
public btnSend = document.getElementById('btn-send') as HTMLButtonElement;
|
public btnSend = document.getElementById('btn-send') as HTMLButtonElement;
|
||||||
|
public btnCancelRecord = this.btnSend.previousElementSibling as HTMLButtonElement;
|
||||||
public emoticonsDropdown: HTMLDivElement = null;
|
public emoticonsDropdown: HTMLDivElement = null;
|
||||||
public emoticonsTimeout: number = 0;
|
public emoticonsTimeout: number = 0;
|
||||||
public toggleEmoticons: HTMLButtonElement;
|
public toggleEmoticons: HTMLButtonElement;
|
||||||
@ -26,6 +28,8 @@ export class ChatInput {
|
|||||||
public lastUrl = '';
|
public lastUrl = '';
|
||||||
public lastTimeType = 0;
|
public lastTimeType = 0;
|
||||||
|
|
||||||
|
private inputContainer = this.btnSend.parentElement as HTMLDivElement;
|
||||||
|
|
||||||
public attachMenu: {
|
public attachMenu: {
|
||||||
container?: HTMLButtonElement,
|
container?: HTMLButtonElement,
|
||||||
media?: HTMLDivElement,
|
media?: HTMLDivElement,
|
||||||
@ -53,6 +57,18 @@ export class ChatInput {
|
|||||||
public editMsgID = 0;
|
public editMsgID = 0;
|
||||||
public noWebPage = false;
|
public noWebPage = false;
|
||||||
|
|
||||||
|
private recorder = new Recorder({
|
||||||
|
//encoderBitRate: 32,
|
||||||
|
//encoderPath: "../dist/encoderWorker.min.js",
|
||||||
|
encoderSampleRate: 48000,
|
||||||
|
monitorGain: 0,
|
||||||
|
numberOfChannels: 1,
|
||||||
|
recordingGain: 1
|
||||||
|
});
|
||||||
|
private recording = false;
|
||||||
|
private recordCanceled = false;
|
||||||
|
private recordTimeEl = this.inputContainer.querySelector('.record-time') as HTMLDivElement;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.toggleEmoticons = this.pageEl.querySelector('.toggle-emoticons') as HTMLButtonElement;
|
this.toggleEmoticons = this.pageEl.querySelector('.toggle-emoticons') as HTMLButtonElement;
|
||||||
|
|
||||||
@ -443,10 +459,101 @@ export class ChatInput {
|
|||||||
|
|
||||||
this.btnSend.addEventListener('click', () => {
|
this.btnSend.addEventListener('click', () => {
|
||||||
if(this.btnSend.classList.contains('tgico-send')) {
|
if(this.btnSend.classList.contains('tgico-send')) {
|
||||||
this.sendMessage();
|
if(this.recording) {
|
||||||
|
this.recorder.stop();
|
||||||
|
} else {
|
||||||
|
this.sendMessage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.recorder.start().then(() => {
|
||||||
|
this.recordCanceled = false;
|
||||||
|
this.btnSend.classList.add('tgico-send');
|
||||||
|
this.inputContainer.classList.add('is-recording');
|
||||||
|
this.recording = true;
|
||||||
|
|
||||||
|
let startTime = Date.now();
|
||||||
|
let r = () => {
|
||||||
|
if(!this.recording) return;
|
||||||
|
|
||||||
|
let diff = Date.now() - startTime;
|
||||||
|
let ms = diff % 1000;
|
||||||
|
|
||||||
|
let formatted = ('' + (diff / 1000)).toHHMMSS() + ',' + ('00' + Math.round(ms / 10)).slice(-2);
|
||||||
|
|
||||||
|
this.recordTimeEl.innerText = formatted;
|
||||||
|
|
||||||
|
window.requestAnimationFrame(r);
|
||||||
|
};
|
||||||
|
|
||||||
|
r();
|
||||||
|
}).catch((e: Error) => {
|
||||||
|
console.error('Recorder start error:', e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.btnCancelRecord.addEventListener('click', () => {
|
||||||
|
this.recordCanceled = true;
|
||||||
|
this.recorder.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.recorder.onstop = () => {
|
||||||
|
this.recording = false;
|
||||||
|
this.inputContainer.classList.remove('is-recording');
|
||||||
|
this.btnSend.classList.remove('tgico-send');
|
||||||
|
};
|
||||||
|
|
||||||
|
this.recorder.ondataavailable = (typedArray: Uint8Array) => {
|
||||||
|
if(this.recordCanceled) return;
|
||||||
|
|
||||||
|
const dataBlob = new Blob([typedArray], {type: 'audio/ogg'});
|
||||||
|
const fileName = new Date().toISOString() + ".opus";
|
||||||
|
console.log('Recorder data received', typedArray, dataBlob);
|
||||||
|
|
||||||
|
/* var url = URL.createObjectURL( dataBlob );
|
||||||
|
|
||||||
|
var audio = document.createElement('audio');
|
||||||
|
audio.controls = true;
|
||||||
|
audio.src = url;
|
||||||
|
|
||||||
|
var link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = fileName;
|
||||||
|
link.innerHTML = link.download;
|
||||||
|
|
||||||
|
var li = document.createElement('li');
|
||||||
|
li.appendChild(link);
|
||||||
|
li.appendChild(audio);
|
||||||
|
|
||||||
|
document.body.append(li);
|
||||||
|
|
||||||
|
return; */
|
||||||
|
|
||||||
|
let peerID = appImManager.peerID;
|
||||||
|
appMessagesManager.sendFile(peerID, dataBlob, {
|
||||||
|
isVoiceMessage: true,
|
||||||
|
duration: 0,
|
||||||
|
isMedia: true
|
||||||
|
});
|
||||||
|
|
||||||
|
/* const url = URL.createObjectURL(dataBlob);
|
||||||
|
|
||||||
|
var audio = document.createElement('audio');
|
||||||
|
audio.controls = true;
|
||||||
|
audio.src = url;
|
||||||
|
|
||||||
|
var link = document.createElement('a');
|
||||||
|
link.href = url;
|
||||||
|
link.download = fileName;
|
||||||
|
link.innerHTML = link.download;
|
||||||
|
|
||||||
|
var li = document.createElement('li');
|
||||||
|
li.appendChild(link);
|
||||||
|
li.appendChild(audio);
|
||||||
|
|
||||||
|
recordingslist.appendChild(li); */
|
||||||
|
};
|
||||||
|
|
||||||
let emoticonsDisplayTimeout = 0;
|
let emoticonsDisplayTimeout = 0;
|
||||||
this.toggleEmoticons.onmouseover = (e) => {
|
this.toggleEmoticons.onmouseover = (e) => {
|
||||||
clearTimeout(this.emoticonsTimeout);
|
clearTimeout(this.emoticonsTimeout);
|
||||||
|
@ -597,6 +597,7 @@ export class AppMessagesManager {
|
|||||||
height: number,
|
height: number,
|
||||||
objectURL: string,
|
objectURL: string,
|
||||||
isRoundMessage: boolean,
|
isRoundMessage: boolean,
|
||||||
|
isVoiceMessage: boolean,
|
||||||
duration: number,
|
duration: number,
|
||||||
background: boolean
|
background: boolean
|
||||||
}> = {}) {
|
}> = {}) {
|
||||||
@ -661,6 +662,25 @@ export class AppMessagesManager {
|
|||||||
attachType = 'audio';
|
attachType = 'audio';
|
||||||
apiFileName = 'audio.' + (fileType.split('/')[1] == 'ogg' ? 'ogg' : 'mp3');
|
apiFileName = 'audio.' + (fileType.split('/')[1] == 'ogg' ? 'ogg' : 'mp3');
|
||||||
actionName = 'sendMessageUploadAudioAction';
|
actionName = 'sendMessageUploadAudioAction';
|
||||||
|
|
||||||
|
let flags = 0;
|
||||||
|
if(options.isVoiceMessage) {
|
||||||
|
flags |= 1 << 10;
|
||||||
|
flags |= 1 << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
let attribute = {
|
||||||
|
_: 'documentAttributeAudio',
|
||||||
|
flags: flags,
|
||||||
|
pFlags: { // that's only for client, not going to telegram
|
||||||
|
voice: options.isVoiceMessage
|
||||||
|
},
|
||||||
|
waveform: new Uint8Array([0, 0, 0, 0, 0, 0, 128, 35, 8, 25, 34, 132, 16, 66, 8, 0, 0, 0, 0, 0, 0, 0, 96, 60, 254, 255, 255, 79, 223, 255, 63, 183, 226, 107, 255, 255, 255, 255, 191, 188, 255, 255, 246, 255, 255, 255, 255, 63, 155, 117, 135, 24, 249, 191, 167, 51, 149, 0, 0, 0, 0, 0, 0]),
|
||||||
|
voice: options.isVoiceMessage,
|
||||||
|
duration: options.duration || 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
attributes.push(attribute);
|
||||||
} else if(fileType.indexOf('video/') === 0) {
|
} else if(fileType.indexOf('video/') === 0) {
|
||||||
attachType = 'video';
|
attachType = 'video';
|
||||||
apiFileName = 'video.mp4';
|
apiFileName = 'video.mp4';
|
||||||
|
5
src/lib/opusProcessor.ts
Normal file
5
src/lib/opusProcessor.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export class OpusProcessor {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new OpusProcessor();
|
@ -101,22 +101,83 @@ $time-background: rgba(0, 0, 0, .35);
|
|||||||
color: #a2acb4;
|
color: #a2acb4;
|
||||||
display: block; /* For Firefox By Ariel Flesler */
|
display: block; /* For Firefox By Ariel Flesler */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#btn-record-cancel {
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transition: width .1s .1s, margin-right .1s .1s, visibility 0s .1s, opacity .1s 0s;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-circle {
|
#btn-send {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
font-size: 1.5rem;
|
|
||||||
line-height: 1.5rem;
|
|
||||||
color: #9e9e9e;
|
color: #9e9e9e;
|
||||||
background-color: #fff;
|
|
||||||
align-self: flex-end;
|
align-self: flex-end;
|
||||||
|
|
||||||
&.tgico-send {
|
&.tgico-send {
|
||||||
color: $color-blue;
|
color: $color-blue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#btn-record-cancel, #btn-send {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-time {
|
||||||
|
height: 44px;
|
||||||
|
line-height: 44px;
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: " ";
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background-color: #e53935;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 .5rem;
|
||||||
|
display: inline-block;
|
||||||
|
animation: recordBlink 1.25s infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.os-scrollbar-handle {
|
&.is-recording {
|
||||||
background: rgba(0, 0, 0, 0.2);
|
#btn-record-cancel {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
margin-right: .5rem;
|
||||||
|
transition: width .1s, margin-right .1s, visibility 0s .1s, opacity .1s .1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#attach-file {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-time {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.is-recording) {
|
||||||
|
#btn-record-cancel {
|
||||||
|
margin-right: 0;
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes recordBlink {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: .2;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,7 +722,7 @@
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
.tgico-largeplay:before {
|
.tgico-largeplay:before {
|
||||||
content: "\e929";
|
content: $tgico-largeplay;
|
||||||
margin-right: -2px;
|
margin-right: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@
|
|||||||
content: "\e938";
|
content: "\e938";
|
||||||
}
|
}
|
||||||
.tgico-largeplay:before {
|
.tgico-largeplay:before {
|
||||||
content: "\e939";
|
content: $tgico-largeplay;
|
||||||
}
|
}
|
||||||
.tgico-livelocation:before {
|
.tgico-livelocation:before {
|
||||||
content: "\e93a";
|
content: "\e93a";
|
||||||
|
@ -6,3 +6,4 @@ $tgico-checks: "\e901";
|
|||||||
$tgico-sending: "\e95f";
|
$tgico-sending: "\e95f";
|
||||||
$tgico-close: "\e91b";
|
$tgico-close: "\e91b";
|
||||||
$tgico-next: "\e94a";
|
$tgico-next: "\e94a";
|
||||||
|
$tgico-largeplay: "\e939";
|
||||||
|
@ -65,7 +65,8 @@ module.exports = merge(common, {
|
|||||||
|| file.includes('.webmanifest')
|
|| file.includes('.webmanifest')
|
||||||
|| file.includes('.wasm')
|
|| file.includes('.wasm')
|
||||||
|| file.includes('rlottie')
|
|| file.includes('rlottie')
|
||||||
|| file.includes('pako')) return;
|
|| file.includes('pako')
|
||||||
|
|| file.includes('Worker.min.js')) return;
|
||||||
|
|
||||||
let p = path.resolve(buildDir + file);
|
let p = path.resolve(buildDir + file);
|
||||||
if(!newlyCreatedAssets[file] && ['.gz', '.js'].find(ext => file.endsWith(ext)) !== undefined) {
|
if(!newlyCreatedAssets[file] && ['.gz', '.js'].find(ext => file.endsWith(ext)) !== undefined) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user