refactor: pointer device listener code refinement (#7311)

This commit is contained in:
Rukario
2024-12-30 08:40:42 -08:00
committed by GitHub
parent 5b53b1ec87
commit 0795e932bd

View File

@@ -49,11 +49,14 @@ export class Transmission extends EventTarget {
this.refilterSoon = debounce(() => this._refilter(false)); this.refilterSoon = debounce(() => this._refilter(false));
this.refilterAllSoon = debounce(() => this._refilter(true)); this.refilterAllSoon = debounce(() => this._refilter(true));
this.pointer_device = Object.seal({
is_touch_device: 'ontouchstart' in window,
long_press_callback: null,
x: 0,
y: 0,
});
this.popup = Array.from({ length: Transmission.max_popups }).fill(null); this.popup = Array.from({ length: Transmission.max_popups }).fill(null);
this.isTouch = 'ontouchstart' in window;
this.busyclick = false;
// listen to actions // listen to actions
// TODO: consider adding a mutator listener here to see dynamic additions // TODO: consider adding a mutator listener here to see dynamic additions
for (const element of document.querySelectorAll(`button[data-action]`)) { for (const element of document.querySelectorAll(`button[data-action]`)) {
@@ -218,8 +221,27 @@ export class Transmission extends EventTarget {
torrent_list: document.querySelector('#torrent-list'), torrent_list: document.querySelector('#torrent-list'),
}; };
const rightc = (event_) => { const context_menu = () => {
if (this.isTouch && event_.touches.length > 1) { // open context menu
const popup = new ContextMenu(this.action_manager);
this.setCurrentPopup(popup);
const boundingElement = document.querySelector('#torrent-container');
const bounds = boundingElement.getBoundingClientRect();
const x = Math.min(
this.pointer_device.x,
bounds.right + globalThis.scrollX - popup.root.clientWidth,
);
const y = Math.min(
this.pointer_device.y,
bounds.bottom + globalThis.scrollY - popup.root.clientHeight,
);
popup.root.style.left = `${Math.max(x, 0)}px`;
popup.root.style.top = `${Math.max(y, 0)}px`;
};
const right_click = (event_) => {
if (this.pointer_device.is_touch_device && event_.touches.length > 1) {
return; return;
} }
@@ -233,37 +255,30 @@ export class Transmission extends EventTarget {
this._setSelectedRow(row); this._setSelectedRow(row);
} }
// open context menu context_menu();
const popup = new ContextMenu(this.action_manager);
this.setCurrentPopup(popup);
const boundingElement = document.querySelector('#torrent-container');
const bounds = boundingElement.getBoundingClientRect();
const x = Math.min(
this.isTouch ? event_.touches[0].pageX : event_.pageX,
bounds.right + globalThis.scrollX - popup.root.clientWidth,
);
const y = Math.min(
this.isTouch ? event_.touches[0].pageY : event_.pageY,
bounds.bottom + globalThis.scrollY - popup.root.clientHeight,
);
popup.root.style.left = `${Math.max(x, 0)}px`;
popup.root.style.top = `${Math.max(y, 0)}px`;
event_.preventDefault(); event_.preventDefault();
}; };
if (this.isTouch) { if (this.pointer_device.is_touch_device) {
const touch = this.pointer_device;
this.elements.torrent_list.addEventListener('touchstart', (event_) => { this.elements.torrent_list.addEventListener('touchstart', (event_) => {
if (this.busyclick) { touch.x = event_.touches[0].pageX;
clearTimeout(this.busyclick); touch.y = event_.touches[0].pageY;
this.busyclick = false;
if (touch.long_press_callback) {
clearTimeout(touch.long_press_callback);
touch.long_press_callback = null;
} else { } else {
this.busyclick = setTimeout(rightc.bind(this), 500, event_); touch.long_press_callback = setTimeout(
right_click.bind(this),
500,
event_,
);
} }
}); });
this.elements.torrent_list.addEventListener('touchend', () => { this.elements.torrent_list.addEventListener('touchend', () => {
clearTimeout(this.busyclick); clearTimeout(touch.long_press_callback);
this.busyclick = false; touch.long_press_callback = null;
setTimeout(() => { setTimeout(() => {
const popup = this.popup[Transmission.default_popup_level]; const popup = this.popup[Transmission.default_popup_level];
if (popup) { if (popup) {
@@ -271,16 +286,23 @@ export class Transmission extends EventTarget {
} }
}, 1); }, 1);
}); });
this.elements.torrent_list.addEventListener('touchmove', () => { this.elements.torrent_list.addEventListener('touchmove', (event_) => {
clearTimeout(this.busyclick); touch.x = event_.touches[0].pageX;
this.busyclick = false; touch.y = event_.touches[0].pageY;
clearTimeout(touch.long_press_callback);
touch.long_press_callback = null;
}); });
this.elements.torrent_list.addEventListener('contextmenu', (event_) => { this.elements.torrent_list.addEventListener('contextmenu', (event_) => {
event_.preventDefault(); event_.preventDefault();
}); });
} else { } else {
this.elements.torrent_list.addEventListener('mousemove', (event_) => {
this.pointer_device.x = event_.pageX;
this.pointer_device.y = event_.pageY;
});
this.elements.torrent_list.addEventListener('contextmenu', (event_) => { this.elements.torrent_list.addEventListener('contextmenu', (event_) => {
rightc(event_); right_click(event_);
const popup = this.popup[Transmission.default_popup_level]; const popup = this.popup[Transmission.default_popup_level];
if (popup) { if (popup) {
popup.root.style.pointerEvents = 'auto'; popup.root.style.pointerEvents = 'auto';