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:
Michael Telatynski 2023-01-12 13:25:14 +00:00 committed by GitHub
parent 7a36ba0fde
commit 030b7e90bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
683 changed files with 3459 additions and 3013 deletions

View file

@ -30,7 +30,7 @@ export class ManagedPlayback extends Playback {
return super.play();
}
public destroy() {
public destroy(): void {
this.manager.destroyPlaybackInstance(this);
super.destroy();
}

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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) {

View file

@ -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

View file

@ -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());
};

View file

@ -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();