mirror of
https://github.com/zoriya/flood.git
synced 2025-12-05 23:06:20 +00:00
client: TorrentListRow: switch to use-long-press
This commit is contained in:
6
.babelrc
6
.babelrc
@@ -1,4 +1,8 @@
|
||||
{
|
||||
"presets": ["@babel/env", "@babel/typescript", "@babel/react"],
|
||||
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/proposal-object-rest-spread"]
|
||||
"plugins": [
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/proposal-object-rest-spread",
|
||||
"@babel/plugin-proposal-optional-chaining"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<script>/* long-press-event - v2.2.2 @author John Doherty <www.johndoherty.info> @license MIT */!function(e,t){"use strict";var n=null,a="ontouchstart"in e||navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints>0,i=a?"touchstart":"mousedown",o=a?"touchend":"mouseup",s=a?"touchmove":"mousemove",c="click",u=0,r=0,m=10,l=10;function v(i){f(i);var s=i.target,u=parseInt(s.getAttribute("data-long-press-delay")||"500",10);n=function(t,n){if(!(e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame&&e.mozCancelRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame))return e.setTimeout(t,n);var a=(new Date).getTime(),i={},o=function(){(new Date).getTime()-a>=n?t.call():i.value=requestAnimFrame(o)};return i.value=requestAnimFrame(o),i}(function(n){f();var i=a?n.touches[0].clientX:n.clientX,s=a?n.touches[0].clientY:n.clientY;this.dispatchEvent(new MouseEvent("long-press",{bubbles:!0,cancelable:!0,detail:{clientX:i,clientY:s,offsetX:a?n.touches[0].offsetX:n.offsetX,offsetY:a?n.touches[0].offsetY:n.offsetY,pageX:a?n.touches[0].pageX:n.pageX,pageY:a?n.touches[0].pageY:n.pageY,screenX:a?n.touches[0].screenX:n.screenX,screenY:a?n.touches[0].screenY:n.screenY},clientX:a?n.touches[0].clientX:n.clientX,clientY:a?n.touches[0].clientY:n.clientY,offsetX:a?n.touches[0].offsetX:n.offsetX,offsetY:a?n.touches[0].offsetY:n.offsetY,pageX:a?n.touches[0].pageX:n.pageX,pageY:a?n.touches[0].pageY:n.pageY,screenX:a?n.touches[0].screenX:n.screenX,screenY:a?n.touches[0].screenY:n.screenY})),e.longPressSuppressClickEvent&&(t.addEventListener(o,function e(n){t.removeEventListener(o,e,!0),p(n)},!0),t.addEventListener(c,function e(n){t.removeEventListener(c,e,!0),p(n)},!0))}.bind(s,i),u)}function f(t){var a;(a=n)&&(e.cancelAnimationFrame?e.cancelAnimationFrame(a.value):e.webkitCancelAnimationFrame?e.webkitCancelAnimationFrame(a.value):e.webkitCancelRequestAnimationFrame?e.webkitCancelRequestAnimationFrame(a.value):e.mozCancelRequestAnimationFrame?e.mozCancelRequestAnimationFrame(a.value):e.oCancelRequestAnimationFrame?e.oCancelRequestAnimationFrame(a.value):e.msCancelRequestAnimationFrame?e.msCancelRequestAnimationFrame(a.value):clearTimeout(a)),n=null}function p(e){e.stopImmediatePropagation(),e.preventDefault(),e.stopPropagation()}"function"!=typeof e.CustomEvent&&(e.CustomEvent=function(e,n){n=n||{bubbles:!1,cancelable:!1,detail:void 0};var a=t.createEvent("CustomEvent");return a.initCustomEvent(e,n.bubbles,n.cancelable,n.detail),a},e.CustomEvent.prototype=e.Event.prototype),e.requestAnimFrame=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t){e.setTimeout(t,1e3/60)},t.addEventListener(o,f,!0),t.addEventListener(s,function(e){var t=Math.abs(u-e.clientX),n=Math.abs(r-e.clientY);(t>=m||n>=l)&&f()},!0),t.addEventListener("wheel",f,!0),t.addEventListener("scroll",f,!0),t.addEventListener(i,function(e){u=e.clientX,r=e.clientY,v(e)},!0)}(window,document);</script>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -10,7 +10,7 @@ import type {ContextMenu, Modal} from '../stores/UIStore';
|
||||
|
||||
export interface UIClickTorrentAction {
|
||||
type: 'UI_CLICK_TORRENT';
|
||||
data: {event: React.MouseEvent; hash: string};
|
||||
data: {event: React.MouseEvent | React.TouchEvent; hash: string};
|
||||
}
|
||||
|
||||
export interface UIClickTorrentDetailsAction {
|
||||
|
||||
@@ -159,8 +159,15 @@ class TorrentList extends React.Component<TorrentListProps, TorrentListStates> {
|
||||
}, 0);
|
||||
}
|
||||
|
||||
handleContextMenuClick = (torrent: TorrentProperties, event: React.MouseEvent) => {
|
||||
event.preventDefault();
|
||||
handleContextMenuClick = (torrent: TorrentProperties, event: React.MouseEvent | React.TouchEvent) => {
|
||||
if (event.cancelable === true) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
const mouseClientX = ((event as unknown) as MouseEvent).clientX;
|
||||
const mouseClientY = ((event as unknown) as MouseEvent).clientY;
|
||||
const touchClientX = ((event as unknown) as TouchEvent).touches?.[0].clientX;
|
||||
const touchClientY = ((event as unknown) as TouchEvent).touches?.[0].clientY;
|
||||
|
||||
if (!TorrentStore.getSelectedTorrents().includes(torrent.hash)) {
|
||||
UIActions.handleTorrentClick({hash: torrent.hash, event});
|
||||
@@ -169,8 +176,8 @@ class TorrentList extends React.Component<TorrentListProps, TorrentListStates> {
|
||||
UIActions.displayContextMenu({
|
||||
id: 'torrent-list-item',
|
||||
clickPosition: {
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
x: mouseClientX || touchClientX || 0,
|
||||
y: mouseClientY || touchClientY || 0,
|
||||
},
|
||||
items: TorrentListContextMenu.getContextMenuItems(this.props.intl, torrent).filter((item) => {
|
||||
if (item.type === 'separator') {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import classnames from 'classnames';
|
||||
import {LongPressDetectEvents, useLongPress} from 'use-long-press';
|
||||
import React from 'react';
|
||||
|
||||
import type {TorrentProperties} from '@shared/types/Torrent';
|
||||
@@ -17,85 +18,72 @@ interface TorrentListRowProps {
|
||||
isCondensed: boolean;
|
||||
handleClick: (torrent: TorrentProperties, event: React.MouseEvent) => void;
|
||||
handleDoubleClick: (torrent: TorrentProperties, event: React.MouseEvent) => void;
|
||||
handleRightClick: (torrent: TorrentProperties, event: React.MouseEvent) => void;
|
||||
handleRightClick: (torrent: TorrentProperties, event: React.MouseEvent | React.TouchEvent) => void;
|
||||
}
|
||||
|
||||
class TorrentListRow extends React.PureComponent<TorrentListRowProps> {
|
||||
torrentRef: HTMLLIElement | null = null;
|
||||
handleRightClick: (event: React.MouseEvent) => void;
|
||||
const TorrentListRow: React.FC<TorrentListRowProps> = (props: TorrentListRowProps) => {
|
||||
const {
|
||||
isCondensed,
|
||||
isSelected,
|
||||
columns,
|
||||
columnWidths,
|
||||
torrent,
|
||||
handleClick,
|
||||
handleDoubleClick,
|
||||
handleRightClick,
|
||||
} = props;
|
||||
|
||||
static defaultProps = {
|
||||
isCondensed: false,
|
||||
};
|
||||
const torrentClasses = torrentStatusClasses(
|
||||
torrent,
|
||||
classnames({
|
||||
'torrent--is-selected': isSelected,
|
||||
'torrent--is-condensed': isCondensed,
|
||||
'torrent--is-expanded': !isCondensed,
|
||||
}),
|
||||
'torrent',
|
||||
);
|
||||
|
||||
constructor(props: TorrentListRowProps) {
|
||||
super(props);
|
||||
|
||||
const {handleRightClick, torrent} = props;
|
||||
|
||||
this.handleRightClick = handleRightClick.bind(this, torrent);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
if (this.torrentRef != null) {
|
||||
this.torrentRef.addEventListener('long-press', (e) => this.handleRightClick((e as unknown) as React.MouseEvent));
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
if (this.torrentRef != null) {
|
||||
this.torrentRef.removeEventListener('long-press', (e) =>
|
||||
this.handleRightClick((e as unknown) as React.MouseEvent),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
const {
|
||||
isCondensed,
|
||||
isSelected,
|
||||
columns,
|
||||
columnWidths,
|
||||
torrent,
|
||||
handleClick,
|
||||
handleDoubleClick,
|
||||
handleRightClick,
|
||||
} = this.props;
|
||||
const torrentClasses = torrentStatusClasses(
|
||||
torrent,
|
||||
classnames({
|
||||
'torrent--is-selected': isSelected,
|
||||
'torrent--is-condensed': isCondensed,
|
||||
'torrent--is-expanded': !isCondensed,
|
||||
}),
|
||||
'torrent',
|
||||
);
|
||||
|
||||
if (isCondensed) {
|
||||
return (
|
||||
<TorrentListRowCondensed
|
||||
className={torrentClasses}
|
||||
columns={columns}
|
||||
columnWidths={columnWidths}
|
||||
torrent={torrent}
|
||||
handleClick={handleClick}
|
||||
handleDoubleClick={handleDoubleClick}
|
||||
handleRightClick={handleRightClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
const longPressBind = useLongPress(
|
||||
(e) => {
|
||||
if (e != null) {
|
||||
handleRightClick(torrent, e);
|
||||
}
|
||||
},
|
||||
{
|
||||
captureEvent: true,
|
||||
detect: LongPressDetectEvents.TOUCH,
|
||||
onFinish: (e) => ((e as unknown) as TouchEvent)?.preventDefault(),
|
||||
},
|
||||
);
|
||||
|
||||
if (isCondensed) {
|
||||
return (
|
||||
<TorrentListRowExpanded
|
||||
<TorrentListRowCondensed
|
||||
className={torrentClasses}
|
||||
columns={columns}
|
||||
columnWidths={columnWidths}
|
||||
torrent={torrent}
|
||||
handleClick={handleClick}
|
||||
handleDoubleClick={handleDoubleClick}
|
||||
handleRightClick={handleRightClick}
|
||||
handleTouchStart={longPressBind.onTouchStart}
|
||||
handleTouchEnd={longPressBind.onTouchEnd}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TorrentListRow;
|
||||
return (
|
||||
<TorrentListRowExpanded
|
||||
className={torrentClasses}
|
||||
columns={columns}
|
||||
torrent={torrent}
|
||||
handleClick={handleClick}
|
||||
handleDoubleClick={handleDoubleClick}
|
||||
handleRightClick={handleRightClick}
|
||||
handleTouchStart={longPressBind.onTouchStart}
|
||||
handleTouchEnd={longPressBind.onTouchEnd}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(TorrentListRow);
|
||||
|
||||
@@ -16,6 +16,8 @@ interface TorrentListRowCondensedProps {
|
||||
handleClick: (torrent: TorrentProperties, event: React.MouseEvent) => void;
|
||||
handleDoubleClick: (torrent: TorrentProperties, event: React.MouseEvent) => void;
|
||||
handleRightClick: (torrent: TorrentProperties, event: React.MouseEvent) => void;
|
||||
handleTouchStart: (event: React.TouchEvent) => void;
|
||||
handleTouchEnd: (event: React.TouchEvent) => void;
|
||||
}
|
||||
|
||||
const TorrentListRowCondensed = React.forwardRef<HTMLLIElement, TorrentListRowCondensedProps>(
|
||||
@@ -28,6 +30,8 @@ const TorrentListRowCondensed = React.forwardRef<HTMLLIElement, TorrentListRowCo
|
||||
handleClick,
|
||||
handleDoubleClick,
|
||||
handleRightClick,
|
||||
handleTouchStart,
|
||||
handleTouchEnd,
|
||||
}: TorrentListRowCondensedProps,
|
||||
ref,
|
||||
) => {
|
||||
@@ -56,6 +60,8 @@ const TorrentListRowCondensed = React.forwardRef<HTMLLIElement, TorrentListRowCo
|
||||
onClick={handleClick.bind(this, torrent)}
|
||||
onContextMenu={handleRightClick.bind(this, torrent)}
|
||||
onDoubleClick={handleDoubleClick.bind(this, torrent)}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
ref={ref}>
|
||||
{torrentListColumns}
|
||||
</li>
|
||||
|
||||
@@ -17,11 +17,22 @@ interface TorrentListRowExpandedProps {
|
||||
handleClick: (torrent: TorrentProperties, event: React.MouseEvent) => void;
|
||||
handleDoubleClick: (torrent: TorrentProperties, event: React.MouseEvent) => void;
|
||||
handleRightClick: (torrent: TorrentProperties, event: React.MouseEvent) => void;
|
||||
handleTouchStart: (event: React.TouchEvent) => void;
|
||||
handleTouchEnd: (event: React.TouchEvent) => void;
|
||||
}
|
||||
|
||||
const TorrentListRowExpanded = React.forwardRef<HTMLLIElement, TorrentListRowExpandedProps>(
|
||||
(
|
||||
{className, columns, torrent, handleClick, handleDoubleClick, handleRightClick}: TorrentListRowExpandedProps,
|
||||
{
|
||||
className,
|
||||
columns,
|
||||
torrent,
|
||||
handleClick,
|
||||
handleDoubleClick,
|
||||
handleRightClick,
|
||||
handleTouchStart,
|
||||
handleTouchEnd,
|
||||
}: TorrentListRowExpandedProps,
|
||||
ref,
|
||||
) => {
|
||||
const primarySection: React.ReactNodeArray = [];
|
||||
@@ -85,6 +96,8 @@ const TorrentListRowExpanded = React.forwardRef<HTMLLIElement, TorrentListRowExp
|
||||
onClick={handleClick.bind(this, torrent)}
|
||||
onContextMenu={handleRightClick.bind(this, torrent)}
|
||||
onDoubleClick={handleDoubleClick.bind(this, torrent)}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
ref={ref}>
|
||||
<div className="torrent__details__section__wrapper">
|
||||
{primarySection}
|
||||
|
||||
@@ -190,7 +190,7 @@ class TorrentStoreClass extends BaseStore {
|
||||
});
|
||||
}
|
||||
|
||||
setSelectedTorrents({event, hash}: {event: React.MouseEvent; hash: string}) {
|
||||
setSelectedTorrents({event, hash}: {event: React.MouseEvent | React.TouchEvent; hash: string}) {
|
||||
this.selectedTorrents = selectTorrents({
|
||||
event,
|
||||
hash,
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from 'react';
|
||||
import type {TorrentProperties} from '@shared/types/Torrent';
|
||||
|
||||
interface SelectTorrentOptions {
|
||||
event: React.MouseEvent;
|
||||
event: React.MouseEvent | React.TouchEvent;
|
||||
hash: string;
|
||||
selectedTorrents: Array<string>;
|
||||
torrentList: Array<TorrentProperties>;
|
||||
|
||||
1276
package-lock.json
generated
1276
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -55,7 +55,8 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
||||
"@babel/preset-env": "^7.12.0",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
|
||||
"@babel/preset-env": "^7.12.1",
|
||||
"@babel/preset-react": "^7.10.4",
|
||||
"@babel/preset-typescript": "^7.12.0",
|
||||
"@formatjs/cli": "^2.13.2",
|
||||
@@ -191,6 +192,7 @@
|
||||
"typed-emitter": "^1.3.1",
|
||||
"typescript": "^4.0.3",
|
||||
"url-loader": "^4.1.1",
|
||||
"use-long-press": "^1.0.4",
|
||||
"webpack": "^4.44.2",
|
||||
"webpack-dev-server": "^3.11.0",
|
||||
"webpack-manifest-plugin": "^2.2.0",
|
||||
|
||||
Reference in New Issue
Block a user