From 5e086ffeea53289a5f2105ebb08517d23ddeb87a Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Wed, 26 Aug 2020 21:19:04 -0700 Subject: [PATCH] Log more user events --- packages/webamp/demo/js/eventLogger.ts | 36 +++++++++++++++++++ packages/webamp/demo/js/logger.ts | 7 ++-- packages/webamp/js/actionCreators/files.ts | 36 ++++++++++++++++--- packages/webamp/js/actionCreators/index.ts | 1 + packages/webamp/js/components/DropTarget.tsx | 10 +++++- .../components/MainWindow/MainContextMenu.tsx | 14 +++++--- .../webamp/js/components/MainWindow/index.tsx | 1 + .../js/components/MilkdropWindow/index.tsx | 5 ++- .../js/components/PlaylistWindow/index.tsx | 1 + packages/webamp/js/types.ts | 15 +++++++- 10 files changed, 112 insertions(+), 14 deletions(-) diff --git a/packages/webamp/demo/js/eventLogger.ts b/packages/webamp/demo/js/eventLogger.ts index 85359da4..bbcf6a2d 100644 --- a/packages/webamp/demo/js/eventLogger.ts +++ b/packages/webamp/demo/js/eventLogger.ts @@ -46,6 +46,12 @@ export function attachLogger(webamp: WebmapLazy) { action: "ToggleDoublesizeMode", }); }); + webamp._actionEmitter.on("TOGGLE_VISUALIZER_STYLE", () => { + log({ + category: "Display", + action: "ToggleVisualizerStyle", + }); + }); webamp._actionEmitter.on("SET_SKIN_DATA", () => { log({ category: "Display", @@ -131,12 +137,14 @@ export function attachLogger(webamp: WebmapLazy) { action: "InvertSelection", }); }); + /* This is triggered programatically when you load a new track webamp._actionEmitter.on("REMOVE_ALL_TRACKS", () => { log({ category: "Playlist", action: "RemoveAllTracks", }); }); + */ webamp._actionEmitter.on("REVERSE_LIST", () => { log({ category: "Playlist", @@ -183,4 +191,32 @@ export function attachLogger(webamp: WebmapLazy) { label: `${action.windowId}:${action.hidden ? "hidden" : "visibile"}`, }); }); + webamp._actionEmitter.on("MAIN_CONTEXT_MENU_OPENED", () => { + log({ + category: "ContextMenu", + action: "MainContextMenuOpened", + }); + }); + webamp._actionEmitter.on("DROPPED_FILES", (action) => { + log({ + category: "DroppedFiles", + action: action.windowId, + label: action.firstFileName ?? "[UNKNOWN]", + value: action.count, + }); + }); + webamp._actionEmitter.on("OPENED_FILES", (action) => { + log({ + category: "OpenedFiles", + action: action.expectedType, + label: action.firstFileName ?? "[UNKNOWN]", + value: action.count, + }); + }); + webamp._actionEmitter.on("TOGGLE_LLAMA_MODE", () => { + log({ + category: "Hotkeys", + action: "ToggledLlamaMode", + }); + }); } diff --git a/packages/webamp/demo/js/logger.ts b/packages/webamp/demo/js/logger.ts index 1f6ffeb1..6c36f2cd 100644 --- a/packages/webamp/demo/js/logger.ts +++ b/packages/webamp/demo/js/logger.ts @@ -2,15 +2,18 @@ export function log({ category, action, label, + value, }: { category: string; action: string; label?: string; + value?: number; }) { // @ts-ignore if (window.ga != null) { - window.ga("send", "event", category, action, label); + // @ts-ignore + window.ga("send", "event", category, action, label, value); } else { - // console.log({ category, action, label }); + // console.log({ category, action, label, value }); } } diff --git a/packages/webamp/js/actionCreators/files.ts b/packages/webamp/js/actionCreators/files.ts index 4b93eff1..141b9f4a 100644 --- a/packages/webamp/js/actionCreators/files.ts +++ b/packages/webamp/js/actionCreators/files.ts @@ -34,7 +34,14 @@ import LoadQueue from "../loadQueue"; import { removeAllTracks } from "./playlist"; import { setPreamp, setEqBand } from "./equalizer"; -import { LoadStyle, Thunk, Track, EqfPreset, SkinData } from "../types"; +import { + LoadStyle, + Thunk, + Track, + EqfPreset, + SkinData, + WindowId, +} from "../types"; // Lower is better const DURATION_VISIBLE_PRIORITY = 5; @@ -138,23 +145,32 @@ export function setSkinFromUrl(url: string): Thunk { // This function is private, since Winamp consumers can provide means for // opening files via other methods. Only use the file type specific // versions below, since they can defer to the user-defined behavior. -function _openFileDialog(accept: string | null): Thunk { +function _openFileDialog( + accept: string | null, + expectedType: "SKIN" | "MEDIA" | "EQ" +): Thunk { return async (dispatch) => { const fileReferences = await promptForFileReferences({ accept }); + dispatch({ + type: "OPENED_FILES", + expectedType, + count: fileReferences.length, + firstFileName: fileReferences[0]?.name, + }); dispatch(loadFilesFromReferences(fileReferences)); }; } export function openEqfFileDialog(): Thunk { - return _openFileDialog(".eqf"); + return _openFileDialog(".eqf", "EQ"); } export function openMediaFileDialog(): Thunk { - return _openFileDialog(null); + return _openFileDialog(null, "MEDIA"); } export function openSkinFileDialog() { - return _openFileDialog(".zip, .wsz"); + return _openFileDialog(".zip, .wsz", "SKIN"); } export function fetchMediaDuration(url: string, id: number): Thunk { @@ -443,3 +459,13 @@ export function saveFilesToList(): Thunk { } }; } + +export function droppedFiles(e: React.DragEvent, windowId: WindowId): Thunk { + return (dispatch) => + dispatch({ + type: "DROPPED_FILES", + count: e.dataTransfer.files.length, + firstFileName: e.dataTransfer.files[0]?.name, + windowId, + }); +} diff --git a/packages/webamp/js/actionCreators/index.ts b/packages/webamp/js/actionCreators/index.ts index e9ccf6ca..f8595e7c 100644 --- a/packages/webamp/js/actionCreators/index.ts +++ b/packages/webamp/js/actionCreators/index.ts @@ -96,6 +96,7 @@ export { addFilesFromUrl, addFilesFromList, saveFilesToList, + droppedFiles, } from "./files"; export { cropPlaylist, diff --git a/packages/webamp/js/components/DropTarget.tsx b/packages/webamp/js/components/DropTarget.tsx index 9e7e9f5f..80a321fd 100644 --- a/packages/webamp/js/components/DropTarget.tsx +++ b/packages/webamp/js/components/DropTarget.tsx @@ -1,4 +1,7 @@ import React, { useCallback } from "react"; +import { useActionCreator } from "../hooks"; +import * as Actions from "../actionCreators"; +import { WindowId } from "../types"; interface Coord { x: number; @@ -7,6 +10,7 @@ interface Coord { interface Props extends React.HTMLAttributes { handleDrop(e: React.DragEvent, coord: Coord): void; + windowId: WindowId; } function supress(e: React.DragEvent) { @@ -20,12 +24,16 @@ const DropTarget = (props: Props) => { const { // eslint-disable-next-line no-shadow, no-unused-vars handleDrop, + windowId, ...passThroughProps } = props; + const droppedFiles = useActionCreator(Actions.droppedFiles); + const onDrop = useCallback( (e: React.DragEvent) => { supress(e); + droppedFiles(e, windowId); // TODO: We could probably move this coordinate logic into the playlist. // I think that's the only place it gets used. const { currentTarget } = e; @@ -36,7 +44,7 @@ const DropTarget = (props: Props) => { const { left: x, top: y } = currentTarget.getBoundingClientRect(); handleDrop(e, { x, y }); }, - [handleDrop] + [handleDrop, droppedFiles, windowId] ); return (
{ +const MainContextMenu = React.memo(({ filePickers }: Props) => { const networkConnected = useTypedSelector(Selectors.getNetworkConnected); const genWindows = useTypedSelector(Selectors.getGenWindows); @@ -21,6 +21,12 @@ const MainContextMenu = React.memo((props: Props) => { const openMediaFileDialog = useActionCreator(Actions.openMediaFileDialog); const loadMediaFiles = useActionCreator(Actions.loadMediaFiles); const toggleWindow = useActionCreator(Actions.toggleWindow); + const menuOpened = useActionCreator(() => ({ + type: "MAIN_CONTEXT_MENU_OPENED", + })); + useEffect(() => { + menuOpened(); + }, [menuOpened]); return ( @@ -32,8 +38,8 @@ const MainContextMenu = React.memo((props: Props) => {
- {props.filePickers && - props.filePickers.map( + {filePickers != null && + filePickers.map( (picker, i) => (networkConnected || !picker.requiresNetwork) && ( { return ( - + {overlay && }
diff --git a/packages/webamp/js/components/PlaylistWindow/index.tsx b/packages/webamp/js/components/PlaylistWindow/index.tsx index 4eb45459..e78a426a 100644 --- a/packages/webamp/js/components/PlaylistWindow/index.tsx +++ b/packages/webamp/js/components/PlaylistWindow/index.tsx @@ -93,6 +93,7 @@ function PlaylistWindow({ analyser }: Props) {