-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathglobalState.ts
More file actions
113 lines (102 loc) · 4.01 KB
/
Copy pathglobalState.ts
File metadata and controls
113 lines (102 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* @author Timur Kuzhagaliyev <tim.kuzh@gmail.com>
* @copyright 2020
* @license MIT
*/
import { EventEmitter } from 'events';
import shortid from 'shortid';
import { Nullable, Undefinable } from 'tsdef';
import { ContextMenuEvent, GlobalHandlers } from './handlers';
import { warn } from './util';
export enum EventName {
RequestMenu = 'request_menu',
RequestGlobalMenu = 'request_global_menu',
CloseAllMenus = 'close_all_menus',
}
export enum HideReason {
Manual,
}
export type EventListener = (data: any) => void;
export type InternalHandler = (event: ContextMenuEvent) => void;
interface ReactContextMenuWrapperState {
emitter: EventEmitter;
localMenuHandlers: { [menuId: string]: InternalHandler };
globalMenuHandlers: InternalHandler[];
longPressTimeout: Nullable<number>;
handlerDataMap: { [randomId: string]: any };
}
interface CustomWindow {
__ReactContextMenuWrapper: ReactContextMenuWrapperState;
}
let state: ReactContextMenuWrapperState;
export const initWindowState = () => {
state = {
emitter: new EventEmitter(),
localMenuHandlers: {},
globalMenuHandlers: [],
longPressTimeout: null,
handlerDataMap: {},
};
((window as any) as CustomWindow).__ReactContextMenuWrapper = state;
document.body.addEventListener('contextmenu', GlobalHandlers.handleContextMenu);
document.body.addEventListener('touchstart', GlobalHandlers.handleTouchStart);
document.body.addEventListener('touchmove', GlobalHandlers.handleTouchMove);
document.body.addEventListener('touchend', GlobalHandlers.handleTouchEnd);
document.body.addEventListener('touchcancel', GlobalHandlers.handleTouchCancel);
};
export const hideAllMenus = () => {
state.emitter.emit(EventName.CloseAllMenus);
};
export const addGenericListener = (name: EventName, listener: EventListener) => {
state.emitter.addListener(name, listener);
};
export const removeGenericListener = (name: EventName, listener: EventListener) => {
state.emitter.removeListener(name, listener);
};
export const addLocalMenuHandler = (menuId: string, handler: InternalHandler) => {
if (state.localMenuHandlers[menuId]) {
warn(`Detected duplicate menu id: ${menuId}. Only the last one will be used.`);
}
state.localMenuHandlers[menuId] = handler;
};
export const getLocalMenuHandler = (menuId: string): Undefinable<InternalHandler> => {
return state.localMenuHandlers[menuId];
};
export const removeLocalMenuHandler = (menuId: string) => {
delete state.localMenuHandlers[menuId];
};
export const addGlobalMenuHandler = (handler: InternalHandler) => {
if (state.globalMenuHandlers.length > 0) {
warn('You have defined multiple global menus. Only the last one will be used');
}
state.globalMenuHandlers.push(handler);
};
export const getGlobalMenuHandler = (): Undefinable<InternalHandler> => {
if (state.globalMenuHandlers.length <= 0) return undefined;
return state.globalMenuHandlers[state.globalMenuHandlers.length - 1];
};
export const removeGlobalMenuHandler = (handler: InternalHandler) => {
const handlerIndex = state.globalMenuHandlers.indexOf(handler);
if (handlerIndex !== -1) state.globalMenuHandlers.splice(handlerIndex);
};
export const addLongPressTimeout = (callback: () => void, timeout: number) => {
state.longPressTimeout = setTimeout(callback, timeout);
};
export const hasLongPressTimeout = () => typeof state.longPressTimeout === 'number';
export const clearLongPressTimeout = () => {
const timeoutId = state.longPressTimeout;
if (timeoutId === null) return;
state.longPressTimeout = null;
clearTimeout(timeoutId);
};
export const generateHandlerDataId = (): string => shortid.generate();
export const saveHandlerData = (dataId: string, data: any) => {
if (data === undefined) return;
state.handlerDataMap[dataId] = data;
};
export const fetchHandlerData = (dataId: string) => {
return state.handlerDataMap[dataId];
};
export const deleteHandlerData = (dataId: string) => {
delete state.handlerDataMap[dataId];
};