diff --git a/.eslintrc.json b/.eslintrc.json index 6aa5dcd..adea023 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -33,7 +33,8 @@ "off" ], "no-unused-vars": [ - "warn" + "warn", + { "argsIgnorePattern": "^_" } ] } } diff --git a/src/index.ts b/src/index.ts index c35abda..5d868f1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import $ from "jquery"; +import jQuery from "jquery"; // Helpers @@ -113,7 +113,7 @@ class Typer { } } -$(document).ready(() => { - let typer = new Typer($(".head-line .typed").get(0), 500, 3000); +jQuery(($) => { + const typer = new Typer($(".head-line .typed").get(0), 500, 3000); typer.type(); }); diff --git a/src/lib/js/main.ts b/src/lib/js/main.ts index 0481cef..a9894f5 100644 --- a/src/lib/js/main.ts +++ b/src/lib/js/main.ts @@ -1,3 +1,3 @@ -import $ from "jquery"; +import jQuery from "jquery"; -$(document).ready(() => $("html").removeClass("no-js")); +jQuery(($) => $("html").removeClass("no-js")); diff --git a/src/music/MusicPlayer.tsx b/src/music/MusicPlayer.tsx index 22cb10d..a3c5f31 100644 --- a/src/music/MusicPlayer.tsx +++ b/src/music/MusicPlayer.tsx @@ -18,16 +18,16 @@ type MusicPlayerProps = { source?: string; }; -class MusicPlayer extends React.Component { +class MusicPlayer extends React.Component { private audioState: AudioState; constructor(props: MusicPlayerProps) { super(props); - let context = new AudioContext(); - let source = new Audio(); - let sourceNode = context.createMediaElementSource(source); - let volume = context.createGain(); + const context = new AudioContext(); + const source = new Audio(); + const sourceNode = context.createMediaElementSource(source); + const volume = context.createGain(); sourceNode.connect(volume); volume.connect(context.destination); @@ -53,9 +53,9 @@ class MusicPlayer extends React.Component { } componentDidUpdate() { - let context = this.audioState.audioContext; - let source = this.audioState.audioSource; - let volume = this.audioState.audioVolume; + const context = this.audioState.audioContext; + const source = this.audioState.audioSource; + const volume = this.audioState.audioVolume; // First, set the audio source (if it changed) if (this.props.source && source.src != this.props.source) { diff --git a/src/music/components/controls.tsx b/src/music/components/controls.tsx index 7aa35b6..851cce1 100644 --- a/src/music/components/controls.tsx +++ b/src/music/components/controls.tsx @@ -1,16 +1,15 @@ import React from "react"; -import Redux from "redux"; import { connect } from "react-redux"; import { State } from "../store"; -import { Title, togglePlay } from "../store/music/types"; +import { Title } from "../store/music/types"; import Indicator from "./indicator"; type ControlProps = { title: Title; }; -class Controls extends React.Component { +class Controls extends React.Component { render() { return (
diff --git a/src/music/components/indicator.tsx b/src/music/components/indicator.tsx index 544d221..b033f4f 100644 --- a/src/music/components/indicator.tsx +++ b/src/music/components/indicator.tsx @@ -2,8 +2,8 @@ import React from "react"; import { connect } from "react-redux"; import classNames from "classnames"; -import { State } from "../store"; -import { MusicState, togglePlay } from "../store/music/types"; +import { Dispatch, State } from "../store"; +import { togglePlay } from "../store/music/types"; type IndicatorProps = { muted: boolean; @@ -16,13 +16,13 @@ type IndicatorDispatch = { type Props = IndicatorProps & IndicatorDispatch; -class Indicator extends React.Component { +class Indicator extends React.Component { click() { this.props.play(); } render() { - let classes = classNames({ + const classes = classNames({ btn: true, "col-auto": true, fas: true, @@ -49,7 +49,7 @@ function mapStateToProps(state: State): IndicatorProps { }; } -function mapDispatchToProps(dispatch: Redux.Dispatch): IndicatorDispatch { +function mapDispatchToProps(dispatch: Dispatch): IndicatorDispatch { return { play: () => { dispatch(togglePlay()); diff --git a/src/music/components/visualizer.tsx b/src/music/components/visualizer.tsx index ebb7bfe..53dfdf3 100644 --- a/src/music/components/visualizer.tsx +++ b/src/music/components/visualizer.tsx @@ -1,6 +1,8 @@ import React from "react"; import * as three from "three"; +import { State } from "../store"; + type VisualizerProps = { audioContext: AudioContext; audioSource: AudioNode; @@ -13,8 +15,8 @@ class CanvasDrawer { private analyserData: Float32Array; private boxes: Array; - private camera: three.Camera; - private renderer: three.Renderer; + private camera: three.PerspectiveCamera; + private renderer: three.WebGLRenderer; private scene: three.Scene; private angle: number; @@ -34,13 +36,13 @@ class CanvasDrawer { // Make a bunch of boxes to represent the bars this.boxes = Array(analyser.frequencyBinCount); - let width = 2 / analyser.frequencyBinCount; + const width = 2 / analyser.frequencyBinCount; for (let freq = 0; freq < analyser.frequencyBinCount; freq++) { - let geometry = new three.BoxGeometry(1, 1, 1); - let material = new three.MeshLambertMaterial({ + const geometry = new three.BoxGeometry(1, 1, 1); + const material = new three.MeshLambertMaterial({ color: new three.Color(0x99d1ce), }); - let cube = new three.Mesh(geometry, material); + const cube = new three.Mesh(geometry, material); cube.scale.set(width, 1e-6, width); cube.position.set(-1 + freq * width, 0, 0); @@ -50,10 +52,10 @@ class CanvasDrawer { } // Add lights for shadowing - let ambientLight = new three.AmbientLight(0xffffff, 0.4); + const ambientLight = new three.AmbientLight(0xffffff, 0.4); this.scene.add(ambientLight); - let directionalLight = new three.DirectionalLight(0xffffff, 1); + const directionalLight = new three.DirectionalLight(0xffffff, 1); directionalLight.position.set(-1, 0.3, -1); directionalLight.castShadow = true; this.scene.add(directionalLight); @@ -94,12 +96,12 @@ class CanvasDrawer { // Set our animation frame to 0, so that if we stop, we don't try to cancel a past animation frame this.animationFrame = 0; // Update elapsed time - let elapsed = time - this.lastTime; + const elapsed = time - this.lastTime; this.lastTime = time; - let camera = this.camera; - let renderer = this.renderer; - let scene = this.scene; + const camera = this.camera; + const renderer = this.renderer; + const scene = this.scene; this.scaleBoxes(); this.rotateCamera(elapsed); @@ -109,7 +111,7 @@ class CanvasDrawer { } scaleBoxes() { - let analyser = this.analyser; + const analyser = this.analyser; analyser.getFloatFrequencyData(this.analyserData); @@ -133,8 +135,8 @@ class CanvasDrawer { this.angle += 0.1 * (elapsed / 1000); } - let camera = this.camera; - let angle = this.angle; + const camera = this.camera; + const angle = this.angle; camera.position.x = 1.01 * Math.sin(angle); camera.position.z = 1.01 * Math.cos(angle); @@ -144,7 +146,7 @@ class CanvasDrawer { } resize() { - let canvas = this.canvas; + const canvas = this.canvas; if (canvas.parentElement === null) { throw Error("Could not access canvas parent for size calculation"); } @@ -160,7 +162,7 @@ class CanvasDrawer { } // The remaining space we want to fill - let remainingHeight = canvas.parentElement.clientHeight - combinedHeight; + const remainingHeight = canvas.parentElement.clientHeight - combinedHeight; canvas.height = remainingHeight; canvas.width = canvas.parentElement.clientWidth; @@ -176,7 +178,7 @@ class CanvasDrawer { } } -class Visualizer extends React.Component { +class Visualizer extends React.Component { private analyser: AnalyserNode; private canvas: React.RefObject; private drawer: CanvasDrawer; @@ -186,7 +188,7 @@ class Visualizer extends React.Component { this.canvas = React.createRef(); } - render() { + render(): React.ReactNode { return ( { ); } - componentDidMount() { + componentDidMount(): void { if (this.canvas.current === null) { throw Error("Failed to create canvas; aborting"); } @@ -209,7 +211,7 @@ class Visualizer extends React.Component { this.drawer = new CanvasDrawer(this.analyser, this.canvas.current); } - componentWillUnmount() { + componentWillUnmount(): void { this.drawer.stop(); this.props.audioSource.disconnect(this.analyser); } diff --git a/src/music/index.tsx b/src/music/index.tsx index a5c2917..bc31bdd 100644 --- a/src/music/index.tsx +++ b/src/music/index.tsx @@ -5,6 +5,7 @@ import { Provider } from "react-redux"; import { store } from "./store"; import MusicPlayer from "./MusicPlayer"; import { setSource, setTitle } from "./store/music/types"; +// @ts-ignore - mp3 files have no types. import mseq from "./Mseq_-_Journey.mp3"; const rootElement = document.getElementById("playerUI"); diff --git a/src/music/store/index.ts b/src/music/store/index.ts index f523735..8b2344d 100644 --- a/src/music/store/index.ts +++ b/src/music/store/index.ts @@ -13,5 +13,8 @@ const rootReducer = combineReducers({ export const store = createStore( rootReducer, + // @ts-ignore - These properties are set by the devtools extension window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ); + +export type Dispatch = typeof store.dispatch; diff --git a/src/music/store/music/types.ts b/src/music/store/music/types.ts index 39555fc..3ddc95e 100644 --- a/src/music/store/music/types.ts +++ b/src/music/store/music/types.ts @@ -18,11 +18,11 @@ export interface MusicState { source?: string; } -export const setTitle: (title: Title) => Action = createAction( +export const setTitle: (_title: Title) => Action = createAction( "set currently playing title" ); -export const setPlayTime: (time: number) => Action = createAction( +export const setPlayTime: (_time: number) => Action = createAction( "set the play time" ); @@ -30,6 +30,6 @@ export const toggleMute: () => Action = createAction("toggle mute"); export const togglePlay: () => Action = createAction("toggle play"); -export const setSource: (source: string) => Action = createAction( +export const setSource: (_source: string) => Action = createAction( "set the title" );