From cfeef49ba7cbd10f97e4cfe2f8939eb0c36b9713 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Wed, 23 Dec 2020 17:45:48 -0800 Subject: [PATCH] Implement VerticalScrollbar This gets rid of rc-slider which was way too heavy, was out of date and I never quiet trusted. We only ever used a portion of it any way. Also, this sets us up to have more direct control over the sliders which we will need if we want to support the behavior where you can click once and drag across the EQ sliders to draw a line. --- packages/webamp/css/base-skin.css | 6 +- packages/webamp/css/equalizer-window.css | 17 - packages/webamp/css/playlist-window.css | 11 - packages/webamp/docs/architecture.md | 2 - .../js/components/EqualizerWindow/Band.tsx | 29 +- .../PlaylistWindow/PlaylistScrollBar.tsx | 42 ++ .../components/PlaylistWindow/ScrollBar.tsx | 42 -- .../__snapshots__/index.test.js.snap | 436 ------------------ .../components/PlaylistWindow/index.test.js | 31 -- .../js/components/PlaylistWindow/index.tsx | 4 +- .../webamp/js/components/VerticalSlider.tsx | 97 ++++ packages/webamp/js/skinSelectors.ts | 6 +- packages/webamp/package.json | 2 - 13 files changed, 162 insertions(+), 563 deletions(-) create mode 100644 packages/webamp/js/components/PlaylistWindow/PlaylistScrollBar.tsx delete mode 100644 packages/webamp/js/components/PlaylistWindow/ScrollBar.tsx delete mode 100644 packages/webamp/js/components/PlaylistWindow/__snapshots__/index.test.js.snap delete mode 100644 packages/webamp/js/components/PlaylistWindow/index.test.js create mode 100644 packages/webamp/js/components/VerticalSlider.tsx diff --git a/packages/webamp/css/base-skin.css b/packages/webamp/css/base-skin.css index 6fd42943..944001a7 100644 --- a/packages/webamp/css/base-skin.css +++ b/packages/webamp/css/base-skin.css @@ -109,8 +109,8 @@ #webamp .equalizer-top {background-image: url(data:image/png;base64,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)} #webamp .selected .equalizer-top {background-image: url(data:image/png;base64,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)} #webamp .band {background-image: url(data:image/png;base64,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)} -#webamp .band .rc-slider-handle {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAbklEQVQoU2PU1HT6f//+OYYfPz4w4AIcHAIMiopGDIwcHAL/r967iVMhSCK3pIlh37qlCMUXrt/FquHc8XMM569dp4LiaG8vuA1Lt25jGMwmr9u6j+HDy7dYQwQjNEBhiQ+AwxlfDIJiDgZAMQgAyhp/SXLWaDcAAAAASUVORK5CYII=)} -#webamp .band .rc-slider:active .rc-slider-handle {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAU0lEQVQoU2PU1HT6f/36PgZCQFPTiYGRgYHh/91nL/GqzS1pYti2bCpCsbKUOE4NXlHZVFD8899/uA3sTCBXMjAMdpOxBQmGm0FhiQ+Aw5mUGAQAqm1OKbTaiFMAAAAASUVORK5CYII=)} +#webamp .band .slider-handle {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAbklEQVQoU2PU1HT6f//+OYYfPz4w4AIcHAIMiopGDIwcHAL/r967iVMhSCK3pIlh37qlCMUXrt/FquHc8XMM569dp4LiaG8vuA1Lt25jGMwmr9u6j+HDy7dYQwQjNEBhiQ+AwxlfDIJiDgZAMQgAyhp/SXLWaDcAAAAASUVORK5CYII=)} +#webamp .band:active .slider-handle {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAU0lEQVQoU2PU1HT6f/36PgZCQFPTiYGRgYHh/91nL/GqzS1pYti2bCpCsbKUOE4NXlHZVFD8899/uA3sTCBXMjAMdpOxBQmGm0FhiQ+Aw5mUGAQAqm1OKbTaiFMAAAAASUVORK5CYII=)} #webamp #on {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAMCAYAAAB8xa1IAAAAxUlEQVQ4T2Ncu/XYfwYagnvPHjKUpkYyMIIs8vG0pIlVW7YfZ1i6cS3Dulm9CIuOXLhOVcs+PP/AcO78OYbz164zbFs2FdWi3p6pGJYVl2TDxYoyy8HsvumdYBrEx8YGyRG06ATjTLjBh5vfMbz48ASnocgWI1tKM4tgLoP5jiiLulvaUYKPkI9AhqMHKUGLCKUGqsURIYtIkceZGEBpntoAI3mDLADl4A8v31LbLkQ+6p69/P/x02cYfnz5QXVLYAaCMiwAMGHxARDxJL8AAAAASUVORK5CYII=)} #webamp #on:active {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAMCAYAAAB8xa1IAAAAnklEQVQ4T2Pk4BD4z0AHwEh3i6KLSxgkBCVo4rfemhIGuI+KW3oYjAy1aGJRtLcXpkXnzl+jumVYfQSyCCSBDkA+hgGYPEwMxMfGRlaPEXQwi7iCv8ANrnRYzPDh41cwH5uhyBYjy9PMIpjByL6HOQ6nj5onT0cJPUI+AhmOHqQEfUQoNVAUR6B85OXkxEDzVOcVl8ywbdFcQp4hWx4AUjOKgfyGJgMAAAAASUVORK5CYII=)} #webamp #on.selected {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAMCAYAAAB8xa1IAAAAxElEQVQ4T2Ncu/XYfwYagnvPHjKUpkYyMIIs8vG0pIlVW7YfZ1i6cS3Dulm9CIuOXLhOVcs+PP/AcO78OYbz164zbFs2FdWi3p6pGJYVl2TDxYoyy8HsvumdYBrEx8YGyRG0aFsNwrKrHJ8YXnx4gtNQZIuRLaWZRTAvw3xHlEXdLe0owUfIRyDD0YOUoEWEUgPV4oiQRaTI40wMoDRPbYCRvEEWgHLwh5dvqW0XIh91z17+//jpMww/vvyguiUwA0EZFgA52fEBTNmbaAAAAABJRU5ErkJggg==)} @@ -401,7 +401,7 @@ #webamp .gen-text-z {width: 11px;} #webamp .selected .gen-text-z {width: 11px;} #webamp #title-bar #close {cursor: url(data:image/x-win-bitmap;base64,AAACAAEAICAAAAAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4gAAAAAAAAAAAAAAAAAAAf4AAAAAAAAAAAAAAAAAAB/gAAIgAAAAAAAAAAAAAAAf4AACAAAAAAAAAAAAAcAB/gAAAAAAAAAAAAAAAAHgAf4AAAAAAAAAAAAAAAAB/gPgAAADwAAAAAAAAAAAAf/gAAAAA8AAAAAAAAAAAAH//iIiAAPAAAAAAAAAAAAB//4iIAADwAAAAAAAAAAAAf/iIgAAA8AAAAAAAAAAAAH/4iAAAAAAAAAAAAAAAAAB/iIAAAAAAAAAAAAAAAAAAf4gAAAAAAAAAAAAAAAAAAHiAAAAAAAAAAAAAAAAAAAB4AAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////////////////////////////////////////////////////////////j////w////8P///+HP//3hz//8w8///EP///wHz//8AE///ADP//wBz//8A8///AfP//wP///8H////D////x////8/////f////w==), auto} -#webamp #equalizer-window .band .rc-slider {cursor: url(data:image/x-win-bitmap;base64,AAACAAEAICAAAAAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPcAAAAAAAAAAAAAAAAAAA/3cAAAAAAAAAAAAACHcAAAAAAAAAAAAAAAAAAAj3AAAAAAAAAAAAAAAAAACPcAAAAAAAAAAAAAAAAAAAj3AAAA9wAAAAAAAAAAgACPcAAAAPcAAAAAAAAAAIcAj3AAAAAAAAAAAAAAAACPcPcAAAAAAAAAAAAAAAAAj/cAAAAAAAAAAAAAAAAAAI//d3dwAA/3cAAAAAAAAACP/3d3AAAA9wAAAAAAAAAAj/d3cAAAAAAAAAAAAAAAAI/3dwAAAAAAAAAAAAAAAACPd3AAAAAAAAAAAAAAAAAAj3cAAAAAAAAAAAAAAAAAAIdwAAAAAAAAAAAAAAAAAACHAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////////////////////////////////////////////////////////8////+H///jA///wwP//8P///+Hz//3h4f/8w+H//EPz//wH///8AED//ADA//wB4f/8A/P//Af///wP///8H////D////x////8/////f////w==), auto} +#webamp #equalizer-window .band {cursor: url(data:image/x-win-bitmap;base64,AAACAAEAICAAAAAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPcAAAAAAAAAAAAAAAAAAA/3cAAAAAAAAAAAAACHcAAAAAAAAAAAAAAAAAAAj3AAAAAAAAAAAAAAAAAACPcAAAAAAAAAAAAAAAAAAAj3AAAA9wAAAAAAAAAAgACPcAAAAPcAAAAAAAAAAIcAj3AAAAAAAAAAAAAAAACPcPcAAAAAAAAAAAAAAAAAj/cAAAAAAAAAAAAAAAAAAI//d3dwAA/3cAAAAAAAAACP/3d3AAAA9wAAAAAAAAAAj/d3cAAAAAAAAAAAAAAAAI/3dwAAAAAAAAAAAAAAAACPd3AAAAAAAAAAAAAAAAAAj3cAAAAAAAAAAAAAAAAAAIdwAAAAAAAAAAAAAAAAAACHAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////////////////////////////////////////////////////////8////+H///jA///wwP//8P///+Hz//3h4f/8w+H//EPz//wH///8AED//ADA//wB4f/8A/P//Af///wP///8H////D////x////8/////f////w==), auto} #webamp #equalizer-window .title-bar {cursor: url(data:image/x-win-bitmap;base64,AAACAAEAICAAAAAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD3AAAAAAAAAAAAAAAAAAAP93AAAAAAAAAAAACHcAAAAAAAAAAAAAAAAAAAj3AAAAAAAAAAAAAAAAAACPcAAHAAAAAHAAAAAAAAAAj3AAdwAHcAB3AAAAAAgACPcAAP8AD/AA/wAAAAAIcAj3AAAPAAAAAPAAAAAACPcPcAAAAAAAAAAAAAAAAAj/cAAAAAAAAAAAAAAAAAAI//d3dwAAAP93AAAAAAAACP/3d3AAAAAPcAAAAAAAAAj/d3cAAAAAAAAAAAAAAAAI/3dwAAAAAAAAAAAAAAAACPd3AAAAAAAAAAAAAAAAAAj3cAAAAAAAAAAAAAAAAAAIdwAAAAAAAAAAAAAAAAAACHAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////P////h///jwP//w8D//8M/P/+GMx/3hCEP8wwhD/EOMx/wHz8/8AHA//ADwP/wB+H/8A/z//Af///wP///8H////D////x////8/////f////w==), auto} #webamp #equalizer-window.shade {cursor: url(data:image/x-win-bitmap;base64,AAACAAEAICAAAAAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD3AAAAAAAAAAAAAAAAAAAP93AAAAAAAAAAAACHcAAAAAAAAAAAAAAAAAAAj3AAAAAAAAAAAAAAAAAACPcAAHAAAAAHAAAAAAAAAAj3AAdwAHcAB3AAAAAAgACPcAAP8AD/AA/wAAAAAIcAj3AAAPAAAAAPAAAAAACPcPcAAAAAAAAAAAAAAAAAj/cAAAAAAAAAAAAAAAAAAI//d3dwAAAP93AAAAAAAACP/3d3AAAAAPcAAAAAAAAAj/d3cAAAAAAAAAAAAAAAAI/3dwAAAAAAAAAAAAAAAACPd3AAAAAAAAAAAAAAAAAAj3cAAAAAAAAAAAAAAAAAAIdwAAAAAAAAAAAAAAAAAACHAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////P////h///jwP//w8D//8M/P/+GMx/3hCEP8wwhD/EOMx/wHz8/8AHA//ADwP/wB+H/8A/z//Af///wP///8H////D////x////8/////f////w==), auto} #webamp #equalizer-window.shade input {cursor: url(data:image/x-win-bitmap;base64,AAACAAEAICAAAAAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD3AAAAAAAAAAAAAAAAAAAP93AAAAAAAAAAAACHcAAAAAAAAAAAAAAAAAAAj3AAAAAAAAAAAAAAAAAACPcAAHAAAAAHAAAAAAAAAAj3AAdwAHcAB3AAAAAAgACPcAAP8AD/AA/wAAAAAIcAj3AAAPAAAAAPAAAAAACPcPcAAAAAAAAAAAAAAAAAj/cAAAAAAAAAAAAAAAAAAI//d3dwAAAP93AAAAAAAACP/3d3AAAAAPcAAAAAAAAAj/d3cAAAAAAAAAAAAAAAAI/3dwAAAAAAAAAAAAAAAACPd3AAAAAAAAAAAAAAAAAAj3cAAAAAAAAAAAAAAAAAAIdwAAAAAAAAAAAAAAAAAACHAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////P////h///jwP//w8D//8M/P/+GMx/3hCEP8wwhD/EOMx/wHz8/8AHA//ADwP/wB+H/8A/z//Af///wP///8H////D////x////8/////f////w==), auto} diff --git a/packages/webamp/css/equalizer-window.css b/packages/webamp/css/equalizer-window.css index 6c5acce4..14a689c8 100644 --- a/packages/webamp/css/equalizer-window.css +++ b/packages/webamp/css/equalizer-window.css @@ -195,20 +195,3 @@ top: 38px; } -#webamp .band { - width: 14px; - height: 63px; -} - -#webamp .band .rc-slider { - height: 51px; - width: 14px; - margin-top: 6px; -} - -#webamp .band .rc-slider .rc-slider-handle { - width: 11px; - height: 11px; - margin: -6px 0 0 1px; - position: absolute; -} diff --git a/packages/webamp/css/playlist-window.css b/packages/webamp/css/playlist-window.css index 60d738e2..911d79ca 100644 --- a/packages/webamp/css/playlist-window.css +++ b/packages/webamp/css/playlist-window.css @@ -102,17 +102,6 @@ padding-bottom: 18px; } -#webamp .playlist-scrollbar { - height: 100%; - width: 8px; - margin-left: 5px; -} - -#webamp .playlist-scrollbar-handle { - width: 8x; - height: 18px; -} - #webamp .playlist-bottom { width: 100%; height: 38px; diff --git a/packages/webamp/docs/architecture.md b/packages/webamp/docs/architecture.md index 9ce979cc..3b45bdee 100644 --- a/packages/webamp/docs/architecture.md +++ b/packages/webamp/docs/architecture.md @@ -23,8 +23,6 @@ Coordination between the playing media (which is inherently stateful, and change We use [react-redux] to bind Redux state into our [React components](../js/components/). Any component which is not reusable, and even some that are, are connected using [connect]. This works well for us, since most components are "one off", and connecting most components allows for state changes to result in a mininmal set of react components needing to re-render. This does, however, require that our selectors be performant. -In some places we use [rc-slider](https://github.com/react-component/slider) instead of `` since it gives us more precise control over styling. This is particualarly true for the vertial sliders in the equalizer window. As far as I can tell, there is no way to style the handle of a vertical `` in a way that gives pixel-level accuracy. - ## Media Media (audio files) is managed by our [Media](../js/media/index.ts) class. It encapsulates the Web Audio API complexity. Audio manipulation (volume, balance, EQ) is handled in the main `Media` class, but the audio source is managed in [elementSource.ts](../js/media/elementSource.ts). This class tries to encapsulate some of the complexity required to get the playing of audio files working across all browsers seamlessly. We handle playing audio from a URL source (subject to CORs) and from a local file. Both of these are normalized to a URL before they are passed into our audio aparatus. For local files, we convert the `ArrayBuffer` we get, into a Blob url using `URL.createObjectURL()`. This transformation is handlded inside our Action Creators (see the Redux section above). diff --git a/packages/webamp/js/components/EqualizerWindow/Band.tsx b/packages/webamp/js/components/EqualizerWindow/Band.tsx index 76dcd619..3698867b 100644 --- a/packages/webamp/js/components/EqualizerWindow/Band.tsx +++ b/packages/webamp/js/components/EqualizerWindow/Band.tsx @@ -1,9 +1,9 @@ import { useMemo } from "react"; -import Slider from "rc-slider"; import { Slider as SliderType } from "../../types"; import { useTypedSelector, useActionCreator } from "../../hooks"; import * as Selectors from "../../selectors"; import * as Actions from "../../actionCreators"; +import VerticalSlider from "../VerticalSlider"; interface Props { id: string; @@ -12,9 +12,10 @@ interface Props { } const MAX_VALUE = 100; + // Given a value between 1-100, return the sprite number (0-27) export const spriteNumber = (value: number): number => { - const percent = value / 100; + const percent = value / MAX_VALUE; return Math.round(percent * 27); }; @@ -25,7 +26,10 @@ export const spriteOffsets = (number: number): { x: number; y: number } => { return { x, y }; }; -const Handle = () =>
; +const Handle = () => { + const style = { width: 11, height: 11, marginLeft: 1 }; + return
; +}; export default function Band({ id, onChange, band }: Props) { const sliders = useTypedSelector(Selectors.getSliders); @@ -39,20 +43,17 @@ export default function Band({ id, onChange, band }: Props) { const focusBand = useActionCreator(Actions.focusBand); const usetFocus = useActionCreator(Actions.unsetFocus); - const handleMouseDown = () => focusBand(band); - return (
- focusBand(band)} + onChange={(val) => onChange((1 - val) * MAX_VALUE)} onAfterChange={usetFocus} - handle={Handle} + handle={} />
); diff --git a/packages/webamp/js/components/PlaylistWindow/PlaylistScrollBar.tsx b/packages/webamp/js/components/PlaylistWindow/PlaylistScrollBar.tsx new file mode 100644 index 00000000..1e959d78 --- /dev/null +++ b/packages/webamp/js/components/PlaylistWindow/PlaylistScrollBar.tsx @@ -0,0 +1,42 @@ +import VerticalSlider from "../VerticalSlider"; + +import * as Selectors from "../../selectors"; +import * as Actions from "../../actionCreators"; +import { useTypedSelector, useActionCreator } from "../../hooks"; +import { WINDOWS } from "../../constants"; + +const HANDLE_HEIGHT = 18; + +const Handle = () => ( +
+); + +export default function PlaylistScrollBar() { + const getWindowPixelSize = useTypedSelector(Selectors.getWindowPixelSize); + const playlistHeight = getWindowPixelSize(WINDOWS.PLAYLIST).height; + const playlistScrollPosition = useTypedSelector( + Selectors.getPlaylistScrollPosition + ); + const allTracksAreVisible = useTypedSelector( + Selectors.getAllTracksAreVisible + ); + const setPlaylistScrollPosition = useActionCreator( + Actions.setPlaylistScrollPosition + ); + return ( +
+ setPlaylistScrollPosition(val * 100)} + handle={} + disabled={allTracksAreVisible} + /> +
+ ); +} diff --git a/packages/webamp/js/components/PlaylistWindow/ScrollBar.tsx b/packages/webamp/js/components/PlaylistWindow/ScrollBar.tsx deleted file mode 100644 index 7869bd19..00000000 --- a/packages/webamp/js/components/PlaylistWindow/ScrollBar.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { memo } from "react"; - -// Here we import the rc-slider class just to get it's type. -// We expect the Typescript compiler to not actually include this in the bundle. -import RcSlider from "rc-slider"; -// @ts-ignore -import SliderComponent from "rc-slider/lib/Slider"; - -import { - getAllTracksAreVisible, - getPlaylistScrollPosition, -} from "../../selectors"; -import * as Actions from "../../actionCreators"; -import { useTypedSelector, useActionCreator } from "../../hooks"; - -// Here we inform TypeScript to use the default export's type for our partial import. -const Slider = SliderComponent as typeof RcSlider; - -const Handle = () =>
; - -const ScrollBar = () => { - const playlistScrollPosition = useTypedSelector(getPlaylistScrollPosition); - const allTracksAreVisible = useTypedSelector(getAllTracksAreVisible); - const setPlaylistScrollPosition = useActionCreator((position: number) => - Actions.setPlaylistScrollPosition(100 - position) - ); - return ( - - ); -}; - -export default memo(ScrollBar); diff --git a/packages/webamp/js/components/PlaylistWindow/__snapshots__/index.test.js.snap b/packages/webamp/js/components/PlaylistWindow/__snapshots__/index.test.js.snap deleted file mode 100644 index fcf4f327..00000000 --- a/packages/webamp/js/components/PlaylistWindow/__snapshots__/index.test.js.snap +++ /dev/null @@ -1,436 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PlaylistWindow renders to snapshot 1`] = ` -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - 0 - - - : - - - 0 - - - 0 - - - / - - - 0 - - - : - - - 0 - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-`; diff --git a/packages/webamp/js/components/PlaylistWindow/index.test.js b/packages/webamp/js/components/PlaylistWindow/index.test.js deleted file mode 100644 index fae16b15..00000000 --- a/packages/webamp/js/components/PlaylistWindow/index.test.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Provider } from "react-redux"; -import renderer from "react-test-renderer"; -import getStore from "../../store"; - -import PlaylistWindow from "./index"; -const media = { - addEventListener: jest.fn(), - setVolume: jest.fn(), - setPreamp: jest.fn(), - setBalance: jest.fn(), - getAnalyser: () => null, - on: jest.fn(), -}; - -describe("PlaylistWindow", () => { - let store; - beforeEach(() => { - store = getStore(media); - }); - - it("renders to snapshot", () => { - const tree = renderer - .create( - - - - ) - .toJSON(); - expect(tree).toMatchSnapshot(); - }); -}); diff --git a/packages/webamp/js/components/PlaylistWindow/index.tsx b/packages/webamp/js/components/PlaylistWindow/index.tsx index d5af7173..49ec130b 100644 --- a/packages/webamp/js/components/PlaylistWindow/index.tsx +++ b/packages/webamp/js/components/PlaylistWindow/index.tsx @@ -17,7 +17,7 @@ import ListMenu from "./ListMenu"; import PlaylistResizeTarget from "./PlaylistResizeTarget"; import PlaylistActionArea from "./PlaylistActionArea"; import TrackList from "./TrackList"; -import ScrollBar from "./ScrollBar"; +import PlaylistScrollBar from "./PlaylistScrollBar"; import "../../../css/playlist-window.css"; import { AppState } from "../../types"; @@ -124,7 +124,7 @@ function PlaylistWindow({ analyser }: Props) {
- +
diff --git a/packages/webamp/js/components/VerticalSlider.tsx b/packages/webamp/js/components/VerticalSlider.tsx new file mode 100644 index 00000000..363f7d10 --- /dev/null +++ b/packages/webamp/js/components/VerticalSlider.tsx @@ -0,0 +1,97 @@ +import * as Utils from "../utils"; +import { ReactNode, useRef } from "react"; + +type Props = { + height: number; + width: number; + handleHeight: number; + value: number; + handle: ReactNode; + onBeforeChange?: () => void; + onChange: (value: number) => void; + onAfterChange?: () => void; + disabled?: boolean; +}; + +// `` can be rotated to become a vertical slider using +// CSS, but that makes it impossible to style the handle in a pixel perfect +// manner. Instead we reimplement it in React. +export default function VerticalSlider({ + value, + height, + width, + handle, + handleHeight, + onBeforeChange, + onChange, + onAfterChange, + disabled, +}: Props) { + const ref = useRef(null); + const handleRef = useRef(null); + const offset = (height - handleHeight) * value; + + function handleMouseDown(e: React.MouseEvent) { + const sliderNode = ref.current; + const handleNode = handleRef.current; + if (sliderNode == null || handleNode == null) { + // I don't think this could ever happen in practice + return null; + } + + const sliderRect = sliderNode.getBoundingClientRect(); + const handleRect = handleNode.getBoundingClientRect(); + + const { top: sliderTop, height: sliderHeight } = sliderRect; + const { top: handleTop, height: realHandleHeight } = handleRect; + + // If the user clicks on the handle we want them to continue to hold onto + // that point of te handle. If they click outside of the handle (in the + // slider itself) we want to center the handle at that point and have them + // move the handle from the center. + const handleOffset = handleNode.contains(e.target as HTMLElement) + ? e.clientY - handleTop + : realHandleHeight / 2; + + const baseOffset = sliderTop + handleOffset; + // Measure the actual rect height rather than use the `height` prop, becuase + // we might be in double-size mode. + const spanSize = sliderHeight - realHandleHeight; + + function moveToCursor(event: MouseEvent) { + // Ensure dragging does not cause elements/text to be selected. + // https://stackoverflow.com/a/19164149/1263117 + event.preventDefault(); + const startOffset = event.clientY - baseOffset; + onChange(Utils.clamp(startOffset / spanSize, 0, 1)); + } + + function handleMouseUp() { + if (onAfterChange != null) { + onAfterChange(); + } + document.removeEventListener("mousemove", moveToCursor); + document.removeEventListener("mouseup", handleMouseUp); + } + document.addEventListener("mousemove", moveToCursor); + document.addEventListener("mouseup", handleMouseUp); + + if (onBeforeChange != null) { + onBeforeChange(); + } + + // Move the slider to where they've started. + moveToCursor(e.nativeEvent); + } + return ( +
+
+ {handle} +
+
+ ); +} diff --git a/packages/webamp/js/skinSelectors.ts b/packages/webamp/js/skinSelectors.ts index e36c1076..a1ce1b11 100644 --- a/packages/webamp/js/skinSelectors.ts +++ b/packages/webamp/js/skinSelectors.ts @@ -155,10 +155,10 @@ export const imageSelectors: Selectors = { EQ_TITLE_BAR: [".equalizer-top"], EQ_TITLE_BAR_SELECTED: [".selected .equalizer-top"], EQ_SLIDER_BACKGROUND: [".band"], - EQ_SLIDER_THUMB: [".band .rc-slider-handle"], + EQ_SLIDER_THUMB: [".band .slider-handle"], // But the "active" pseudo selector on the parent, since clicking // anywhere on the track moves the slider. - EQ_SLIDER_THUMB_SELECTED: [".band .rc-slider:active .rc-slider-handle"], + EQ_SLIDER_THUMB_SELECTED: [".band:active .slider-handle"], EQ_ON_BUTTON: ["#on"], EQ_ON_BUTTON_DEPRESSED: ["#on:active"], EQ_ON_BUTTON_SELECTED: ["#on.selected"], @@ -349,7 +349,7 @@ export const cursorSelectors: Selectors = { CLOSE: ["#title-bar #close"], // This is not quite right. There are some areas that show this cursor // but are not clickable. - EQSLID: ["#equalizer-window .band .rc-slider"], + EQSLID: ["#equalizer-window .band"], EQNORMAL: ["#equalizer-window"], EQCLOSE: ["#equalizer-window #equalizer-close"], EQTITLE: [ diff --git a/packages/webamp/package.json b/packages/webamp/package.json index 84431396..d3a60c87 100644 --- a/packages/webamp/package.json +++ b/packages/webamp/package.json @@ -73,7 +73,6 @@ "@types/jszip": "^3.1.5", "@types/lodash": "^4.14.116", "@types/lodash-es": "^4.17.1", - "@types/rc-slider": "^8.6.3", "@types/react": "^16.8.13", "@types/react-dom": "^16.8.4", "@types/react-redux": "^7.1.1", @@ -116,7 +115,6 @@ "postcss-loader": "^3.0.0", "prettier": "^2.0.4", "puppeteer": "^1.15.0", - "rc-slider": "^8.7.1", "react": "^17.0.1", "react-dom": "^17.0.1", "react-redux": "^7.2.2",