Enable @typescript-eslint/explicit-function-return-type
in /src (#9788)
* Enable `@typescript-eslint/explicit-member-accessibility` on /src * Prettier * Enable `@typescript-eslint/explicit-function-return-type` in /src * Fix types * tsc strict fixes * Delint * Fix test * Fix bad merge
This commit is contained in:
parent
7a36ba0fde
commit
030b7e90bf
683 changed files with 3459 additions and 3013 deletions
|
@ -30,7 +30,7 @@ export class ManagedPlayback extends Playback {
|
|||
return super.play();
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
public destroy(): void {
|
||||
this.manager.destroyPlaybackInstance(this);
|
||||
super.destroy();
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ export class Playback extends EventEmitter implements IDestroyable, PlaybackInte
|
|||
return true; // we don't ever care if the event had listeners, so just return "yes"
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
public destroy(): void {
|
||||
// Dev note: It's critical that we call stop() during cleanup to ensure that downstream callers
|
||||
// are aware of the final clock position before the user triggered an unload.
|
||||
// noinspection JSIgnoredPromiseFromCall - not concerned about being called async here
|
||||
|
@ -159,7 +159,7 @@ export class Playback extends EventEmitter implements IDestroyable, PlaybackInte
|
|||
}
|
||||
}
|
||||
|
||||
public async prepare() {
|
||||
public async prepare(): Promise<void> {
|
||||
// don't attempt to decode the media again
|
||||
// AudioContext.decodeAudioData detaches the array buffer `this.buf`
|
||||
// meaning it cannot be re-read
|
||||
|
@ -190,7 +190,7 @@ export class Playback extends EventEmitter implements IDestroyable, PlaybackInte
|
|||
this.context.decodeAudioData(
|
||||
this.buf,
|
||||
(b) => resolve(b),
|
||||
async (e) => {
|
||||
async (e): Promise<void> => {
|
||||
try {
|
||||
// This error handler is largely for Safari as well, which doesn't support Opus/Ogg
|
||||
// very well.
|
||||
|
@ -232,12 +232,12 @@ export class Playback extends EventEmitter implements IDestroyable, PlaybackInte
|
|||
this.emit(PlaybackState.Stopped); // signal that we're not decoding anymore
|
||||
}
|
||||
|
||||
private onPlaybackEnd = async () => {
|
||||
private onPlaybackEnd = async (): Promise<void> => {
|
||||
await this.context.suspend();
|
||||
this.emit(PlaybackState.Stopped);
|
||||
};
|
||||
|
||||
public async play() {
|
||||
public async play(): Promise<void> {
|
||||
// We can't restart a buffer source, so we need to create a new one if we hit the end
|
||||
if (this.state === PlaybackState.Stopped) {
|
||||
this.disconnectSource();
|
||||
|
@ -256,13 +256,13 @@ export class Playback extends EventEmitter implements IDestroyable, PlaybackInte
|
|||
this.emit(PlaybackState.Playing);
|
||||
}
|
||||
|
||||
private disconnectSource() {
|
||||
private disconnectSource(): void {
|
||||
if (this.element) return; // leave connected, we can (and must) re-use it
|
||||
this.source?.disconnect();
|
||||
this.source?.removeEventListener("ended", this.onPlaybackEnd);
|
||||
}
|
||||
|
||||
private makeNewSourceBuffer() {
|
||||
private makeNewSourceBuffer(): void {
|
||||
if (this.element && this.source) return; // leave connected, we can (and must) re-use it
|
||||
|
||||
if (this.element) {
|
||||
|
@ -276,22 +276,22 @@ export class Playback extends EventEmitter implements IDestroyable, PlaybackInte
|
|||
this.source.connect(this.context.destination);
|
||||
}
|
||||
|
||||
public async pause() {
|
||||
public async pause(): Promise<void> {
|
||||
await this.context.suspend();
|
||||
this.emit(PlaybackState.Paused);
|
||||
}
|
||||
|
||||
public async stop() {
|
||||
public async stop(): Promise<void> {
|
||||
await this.onPlaybackEnd();
|
||||
this.clock.flagStop();
|
||||
}
|
||||
|
||||
public async toggle() {
|
||||
public async toggle(): Promise<void> {
|
||||
if (this.isPlaying) await this.pause();
|
||||
else await this.play();
|
||||
}
|
||||
|
||||
public async skipTo(timeSeconds: number) {
|
||||
public async skipTo(timeSeconds: number): Promise<void> {
|
||||
// Dev note: this function talks a lot about clock desyncs. There is a clock running
|
||||
// independently to the audio context and buffer so that accurate human-perceptible
|
||||
// time can be exposed. The PlaybackClock class has more information, but the short
|
||||
|
|
|
@ -89,7 +89,7 @@ export class PlaybackClock implements IDestroyable {
|
|||
return this.observable;
|
||||
}
|
||||
|
||||
private checkTime = (force = false) => {
|
||||
private checkTime = (force = false): void => {
|
||||
const now = this.timeSeconds; // calculated dynamically
|
||||
if (this.lastCheck !== now || force) {
|
||||
this.observable.update([now, this.durationSeconds]);
|
||||
|
@ -102,7 +102,7 @@ export class PlaybackClock implements IDestroyable {
|
|||
* The placeholders will be overridden once known.
|
||||
* @param {MatrixEvent} event The event to use for placeholders.
|
||||
*/
|
||||
public populatePlaceholdersFrom(event: MatrixEvent) {
|
||||
public populatePlaceholdersFrom(event: MatrixEvent): void {
|
||||
const durationMs = Number(event.getContent()["info"]?.["duration"]);
|
||||
if (Number.isFinite(durationMs)) this.placeholderDuration = durationMs / 1000;
|
||||
}
|
||||
|
@ -112,11 +112,11 @@ export class PlaybackClock implements IDestroyable {
|
|||
* This is to ensure the clock isn't skewed into thinking it is ~0.5s into
|
||||
* a clip when the duration is set.
|
||||
*/
|
||||
public flagLoadTime() {
|
||||
public flagLoadTime(): void {
|
||||
this.clipStart = this.context.currentTime;
|
||||
}
|
||||
|
||||
public flagStart() {
|
||||
public flagStart(): void {
|
||||
if (this.stopped) {
|
||||
this.clipStart = this.context.currentTime;
|
||||
this.stopped = false;
|
||||
|
@ -128,7 +128,7 @@ export class PlaybackClock implements IDestroyable {
|
|||
}
|
||||
}
|
||||
|
||||
public flagStop() {
|
||||
public flagStop(): void {
|
||||
this.stopped = true;
|
||||
|
||||
// Reset the clock time now so that the update going out will trigger components
|
||||
|
@ -136,13 +136,13 @@ export class PlaybackClock implements IDestroyable {
|
|||
this.clipStart = this.context.currentTime;
|
||||
}
|
||||
|
||||
public syncTo(contextTime: number, clipTime: number) {
|
||||
public syncTo(contextTime: number, clipTime: number): void {
|
||||
this.clipStart = contextTime - clipTime;
|
||||
this.stopped = false; // count as a mid-stream pause (if we were stopped)
|
||||
this.checkTime(true);
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
public destroy(): void {
|
||||
this.observable.close();
|
||||
if (this.timerId) clearInterval(this.timerId);
|
||||
}
|
||||
|
|
|
@ -38,13 +38,13 @@ export class PlaybackManager {
|
|||
* instances are paused.
|
||||
* @param playback Optional. The playback to leave untouched.
|
||||
*/
|
||||
public pauseAllExcept(playback?: Playback) {
|
||||
public pauseAllExcept(playback?: Playback): void {
|
||||
this.instances
|
||||
.filter((p) => p !== playback && p.currentState === PlaybackState.Playing)
|
||||
.forEach((p) => p.pause());
|
||||
}
|
||||
|
||||
public destroyPlaybackInstance(playback: ManagedPlayback) {
|
||||
public destroyPlaybackInstance(playback: ManagedPlayback): void {
|
||||
this.instances = this.instances.filter((p) => p !== playback);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,28 +75,28 @@ export class PlaybackQueue {
|
|||
return queue;
|
||||
}
|
||||
|
||||
private persistClocks() {
|
||||
private persistClocks(): void {
|
||||
localStorage.setItem(
|
||||
`mx_voice_message_clocks_${this.room.roomId}`,
|
||||
JSON.stringify(Array.from(this.clockStates.entries())),
|
||||
);
|
||||
}
|
||||
|
||||
private loadClocks() {
|
||||
private loadClocks(): void {
|
||||
const val = localStorage.getItem(`mx_voice_message_clocks_${this.room.roomId}`);
|
||||
if (!!val) {
|
||||
this.clockStates = new Map<string, number>(JSON.parse(val));
|
||||
}
|
||||
}
|
||||
|
||||
public unsortedEnqueue(mxEvent: MatrixEvent, playback: Playback) {
|
||||
public unsortedEnqueue(mxEvent: MatrixEvent, playback: Playback): void {
|
||||
// We don't ever detach our listeners: we expect the Playback to clean up for us
|
||||
this.playbacks.set(mxEvent.getId(), playback);
|
||||
playback.on(UPDATE_EVENT, (state) => this.onPlaybackStateChange(playback, mxEvent, state));
|
||||
playback.clockInfo.liveData.onUpdate((clock) => this.onPlaybackClock(playback, mxEvent, clock));
|
||||
}
|
||||
|
||||
private onPlaybackStateChange(playback: Playback, mxEvent: MatrixEvent, newState: PlaybackState) {
|
||||
private onPlaybackStateChange(playback: Playback, mxEvent: MatrixEvent, newState: PlaybackState): void {
|
||||
// Remember where the user got to in playback
|
||||
const wasLastPlaying = this.currentPlaybackId === mxEvent.getId();
|
||||
if (newState === PlaybackState.Stopped && this.clockStates.has(mxEvent.getId()) && !wasLastPlaying) {
|
||||
|
@ -210,7 +210,7 @@ export class PlaybackQueue {
|
|||
}
|
||||
}
|
||||
|
||||
private onPlaybackClock(playback: Playback, mxEvent: MatrixEvent, clocks: number[]) {
|
||||
private onPlaybackClock(playback: Playback, mxEvent: MatrixEvent, clocks: number[]): void {
|
||||
if (playback.currentState === PlaybackState.Decoding) return; // ignore pre-ready values
|
||||
|
||||
if (playback.currentState !== PlaybackState.Stopped) {
|
||||
|
|
|
@ -43,7 +43,7 @@ class MxVoiceWorklet extends AudioWorkletProcessor {
|
|||
private nextAmplitudeSecond = 0;
|
||||
private amplitudeIndex = 0;
|
||||
|
||||
public process(inputs, outputs, parameters) {
|
||||
public process(inputs, outputs, parameters): boolean {
|
||||
const currentSecond = roundTimeToTargetFreq(currentTime);
|
||||
// We special case the first ping because there's a fairly good chance that we'll miss the zeroth
|
||||
// update. Firefox for instance takes 0.06 seconds (roughly) to call this function for the first
|
||||
|
|
|
@ -141,7 +141,7 @@ export class VoiceMessageRecording implements IDestroyable {
|
|||
this.voiceRecording.destroy();
|
||||
}
|
||||
|
||||
private onDataAvailable = (data: ArrayBuffer) => {
|
||||
private onDataAvailable = (data: ArrayBuffer): void => {
|
||||
const buf = new Uint8Array(data);
|
||||
this.buffer = concat(this.buffer, buf);
|
||||
};
|
||||
|
@ -153,6 +153,6 @@ export class VoiceMessageRecording implements IDestroyable {
|
|||
}
|
||||
}
|
||||
|
||||
export const createVoiceMessageRecording = (matrixClient: MatrixClient) => {
|
||||
export const createVoiceMessageRecording = (matrixClient: MatrixClient): VoiceMessageRecording => {
|
||||
return new VoiceMessageRecording(matrixClient, new VoiceRecording());
|
||||
};
|
||||
|
|
|
@ -110,7 +110,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
return !MediaDeviceHandler.getAudioNoiseSuppression();
|
||||
}
|
||||
|
||||
private async makeRecorder() {
|
||||
private async makeRecorder(): Promise<void> {
|
||||
try {
|
||||
this.recorderStream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: {
|
||||
|
@ -212,14 +212,14 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
return !!Recorder.isRecordingSupported();
|
||||
}
|
||||
|
||||
private onAudioProcess = (ev: AudioProcessingEvent) => {
|
||||
private onAudioProcess = (ev: AudioProcessingEvent): void => {
|
||||
this.processAudioUpdate(ev.playbackTime);
|
||||
|
||||
// We skip the functionality of the worklet regarding waveform calculations: we
|
||||
// should get that information pretty quick during the playback info.
|
||||
};
|
||||
|
||||
private processAudioUpdate = (timeSeconds: number) => {
|
||||
private processAudioUpdate = (timeSeconds: number): void => {
|
||||
if (!this.recording) return;
|
||||
|
||||
this.observable.update({
|
||||
|
@ -260,7 +260,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
/**
|
||||
* {@link https://github.com/chris-rudmin/opus-recorder#instance-fields ref for recorderSeconds}
|
||||
*/
|
||||
public get recorderSeconds() {
|
||||
public get recorderSeconds(): number {
|
||||
return this.recorder.encodedSamplePosition / 48000;
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
}
|
||||
|
||||
public async stop(): Promise<void> {
|
||||
return Singleflight.for(this, "stop").do(async () => {
|
||||
return Singleflight.for(this, "stop").do(async (): Promise<void> => {
|
||||
if (!this.recording) {
|
||||
throw new Error("No recording to stop");
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
|||
});
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
public destroy(): void {
|
||||
// noinspection JSIgnoredPromiseFromCall - not concerned about stop() being called async here
|
||||
this.stop();
|
||||
this.removeAllListeners();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue