tlater/nix-flake-rework #2
|
@ -33,7 +33,8 @@
|
|||
"off"
|
||||
],
|
||||
"no-unused-vars": [
|
||||
"warn"
|
||||
"warn",
|
||||
{ "argsIgnorePattern": "^_" }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import $ from "jquery";
|
||||
import jQuery from "jquery";
|
||||
|
||||
$(document).ready(() => $("html").removeClass("no-js"));
|
||||
jQuery(($) => $("html").removeClass("no-js"));
|
||||
|
|
|
@ -18,16 +18,16 @@ type MusicPlayerProps = {
|
|||
source?: string;
|
||||
};
|
||||
|
||||
class MusicPlayer extends React.Component<MusicPlayerProps, {}> {
|
||||
class MusicPlayer extends React.Component<MusicPlayerProps, State> {
|
||||
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<MusicPlayerProps, {}> {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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<ControlProps, {}> {
|
||||
class Controls extends React.Component<ControlProps, State> {
|
||||
render() {
|
||||
return (
|
||||
<div id="playerControls" className="container-fluid fixed-bottom">
|
||||
|
|
|
@ -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<Props, {}> {
|
||||
class Indicator extends React.Component<Props, State> {
|
||||
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<any>): IndicatorDispatch {
|
||||
function mapDispatchToProps(dispatch: Dispatch): IndicatorDispatch {
|
||||
return {
|
||||
play: () => {
|
||||
dispatch(togglePlay());
|
||||
|
|
|
@ -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<three.Mesh>;
|
||||
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<VisualizerProps, {}> {
|
||||
class Visualizer extends React.Component<VisualizerProps, State> {
|
||||
private analyser: AnalyserNode;
|
||||
private canvas: React.RefObject<HTMLCanvasElement>;
|
||||
private drawer: CanvasDrawer;
|
||||
|
@ -186,7 +188,7 @@ class Visualizer extends React.Component<VisualizerProps, {}> {
|
|||
this.canvas = React.createRef();
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
return (
|
||||
<canvas
|
||||
id="visualizer"
|
||||
|
@ -196,7 +198,7 @@ class Visualizer extends React.Component<VisualizerProps, {}> {
|
|||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount(): void {
|
||||
if (this.canvas.current === null) {
|
||||
throw Error("Failed to create canvas; aborting");
|
||||
}
|
||||
|
@ -209,7 +211,7 @@ class Visualizer extends React.Component<VisualizerProps, {}> {
|
|||
this.drawer = new CanvasDrawer(this.analyser, this.canvas.current);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
this.drawer.stop();
|
||||
this.props.audioSource.disconnect(this.analyser);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -13,5 +13,8 @@ const rootReducer = combineReducers<State>({
|
|||
|
||||
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;
|
||||
|
|
|
@ -18,11 +18,11 @@ export interface MusicState {
|
|||
source?: string;
|
||||
}
|
||||
|
||||
export const setTitle: (title: Title) => Action<null, null> = createAction(
|
||||
export const setTitle: (_title: Title) => Action<null, null> = createAction(
|
||||
"set currently playing title"
|
||||
);
|
||||
|
||||
export const setPlayTime: (time: number) => Action<null, null> = createAction(
|
||||
export const setPlayTime: (_time: number) => Action<null, null> = createAction(
|
||||
"set the play time"
|
||||
);
|
||||
|
||||
|
@ -30,6 +30,6 @@ export const toggleMute: () => Action<null, null> = createAction("toggle mute");
|
|||
|
||||
export const togglePlay: () => Action<null, null> = createAction("toggle play");
|
||||
|
||||
export const setSource: (source: string) => Action<null, null> = createAction(
|
||||
export const setSource: (_source: string) => Action<null, null> = createAction(
|
||||
"set the title"
|
||||
);
|
||||
|
|
Reference in a new issue