mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-25 11:04:00 +00:00
Log more user events
This commit is contained in:
parent
7032212002
commit
5e086ffeea
10 changed files with 112 additions and 14 deletions
|
|
@ -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",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ export {
|
|||
addFilesFromUrl,
|
||||
addFilesFromList,
|
||||
saveFilesToList,
|
||||
droppedFiles,
|
||||
} from "./files";
|
||||
export {
|
||||
cropPlaylist,
|
||||
|
|
|
|||
|
|
@ -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<HTMLDivElement> {
|
||||
handleDrop(e: React.DragEvent<HTMLDivElement>, coord: Coord): void;
|
||||
windowId: WindowId;
|
||||
}
|
||||
|
||||
function supress(e: React.DragEvent<HTMLDivElement>) {
|
||||
|
|
@ -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<HTMLDivElement>) => {
|
||||
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 (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import * as Actions from "../../actionCreators";
|
||||
import * as Selectors from "../../selectors";
|
||||
import { LOAD_STYLE } from "../../constants";
|
||||
|
|
@ -13,7 +13,7 @@ interface Props {
|
|||
filePickers: FilePicker[];
|
||||
}
|
||||
|
||||
const MainContextMenu = React.memo((props: Props) => {
|
||||
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 (
|
||||
<React.Fragment>
|
||||
|
|
@ -32,8 +38,8 @@ const MainContextMenu = React.memo((props: Props) => {
|
|||
<Hr />
|
||||
<Parent label="Play">
|
||||
<Node onClick={openMediaFileDialog} label="File..." hotkey="L" />
|
||||
{props.filePickers &&
|
||||
props.filePickers.map(
|
||||
{filePickers != null &&
|
||||
filePickers.map(
|
||||
(picker, i) =>
|
||||
(networkConnected || !picker.requiresNetwork) && (
|
||||
<Node
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ const MainWindow = React.memo(({ analyser, filePickers }: Props) => {
|
|||
return (
|
||||
<DropTarget
|
||||
id="main-window"
|
||||
windowId={WINDOWS.MAIN}
|
||||
className={className}
|
||||
handleDrop={loadMedia}
|
||||
onWheel={scrollVolume}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,10 @@ function Milkdrop({ analyser }: Props) {
|
|||
return (
|
||||
<MilkdropContextMenu>
|
||||
<Background>
|
||||
<DropTarget handleDrop={handlePresetDrop}>
|
||||
<DropTarget
|
||||
windowId={WINDOWS.MILKDROP}
|
||||
handleDrop={handlePresetDrop}
|
||||
>
|
||||
{overlay && <PresetOverlay {...size} />}
|
||||
<Fullscreen enabled={fullscreen} onChange={setFullscreen}>
|
||||
<div onDoubleClick={toggleFullscreen}>
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ function PlaylistWindow({ analyser }: Props) {
|
|||
<FocusTarget windowId={WINDOWS.PLAYLIST}>
|
||||
<DropTarget
|
||||
id="playlist-window"
|
||||
windowId={WINDOWS.PLAYLIST}
|
||||
className={classes}
|
||||
style={style}
|
||||
handleDrop={handleDrop}
|
||||
|
|
|
|||
|
|
@ -535,7 +535,20 @@ export type Action =
|
|||
index: number;
|
||||
transitionType: TransitionType;
|
||||
}
|
||||
| { type: "TOGGLE_PRESET_OVERLAY" };
|
||||
| { type: "TOGGLE_PRESET_OVERLAY" }
|
||||
| { type: "MAIN_CONTEXT_MENU_OPENED" }
|
||||
| {
|
||||
type: "DROPPED_FILES";
|
||||
count: number;
|
||||
firstFileName: string | null;
|
||||
windowId: WindowId;
|
||||
}
|
||||
| {
|
||||
type: "OPENED_FILES";
|
||||
expectedType: "SKIN" | "MEDIA" | "EQ";
|
||||
count: number;
|
||||
firstFileName: string | null;
|
||||
};
|
||||
|
||||
export type MediaTagRequestStatus =
|
||||
| "INITIALIZED"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue