1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-16 16:21:48 +00:00

Improvement - dirent grid view mode interactive experience (#6362)

* Improvement - dirent grid view mode interactive experience

* Fix - code formatting
This commit is contained in:
Aries 2024-07-18 11:17:19 +08:00 committed by GitHub
parent bc02e2f47d
commit 77def3b1f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 66 additions and 40 deletions

View File

@ -48,6 +48,17 @@
"no-useless-concat": "off", "no-useless-concat": "off",
"jsx-a11y/anchor-has-content": "off", "jsx-a11y/anchor-has-content": "off",
"jsx-a11y/href-no-hash": "off", "jsx-a11y/href-no-hash": "off",
"jsx-a11y/anchor-is-valid": "off" "jsx-a11y/anchor-is-valid": "off",
"space-before-blocks": ["warn", "always"],
"space-in-parens": ["warn", "never"],
"keyword-spacing": ["warn", {
"before": true,
"after": true,
"overrides": {
"if" : {
"after": true
}
}
}]
} }
} }

View File

@ -40,14 +40,20 @@ class DirentGridItem extends React.Component {
this.canDrag = modify; this.canDrag = modify;
} }
this.clickTimeout = null;
} }
UNSAFE_componentWillReceiveProps(nextProps) { componentWillUnmount() {
this.setState({isGridSelected: false}, () => { if (this.clickTimeout) {
if (nextProps.activeDirent && nextProps.activeDirent.name === nextProps.dirent.name) { clearTimeout(this.clickTimeout);
this.setState({isGridSelected: true}); }
} }
});
componentDidUpdate(prevProps) {
if (prevProps.activeDirent !== this.props.activeDirent) {
const isSelected = this.props.activeDirent && this.props.activeDirent.name === this.props.dirent.name;
this.setState({ isGridSelected: isSelected });
}
} }
onItemMove = (destRepo, dirent, selectedPath, currentPath) => { onItemMove = (destRepo, dirent, selectedPath, currentPath) => {
@ -57,31 +63,43 @@ class DirentGridItem extends React.Component {
onItemClick = (e) => { onItemClick = (e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
this.setState({isGridSelected: false});
const { dirent, activeDirent } = this.props; const { dirent, activeDirent } = this.props;
if (dirent.isDir()) {
this.props.onItemClick(dirent); if (this.clickTimeout) {
clearTimeout(this.clickTimeout);
this.clickTimeout = null;
this.handleSingleClick(dirent, activeDirent);
return; return;
} }
// is have preview permission this.clickTimeout = setTimeout(() => {
this.clickTimeout = null;
this.handleSingleClick(dirent, activeDirent);
}, 250); //A click within 250 milliseconds is considered a single click.
};
handleSingleClick = (dirent, activeDirent) => {
if (!this.canPreview) { if (!this.canPreview) {
return; return;
} }
if (dirent === activeDirent) { if (dirent === activeDirent) {
this.setState({isGridSelected: false}); this.handleDoubleClick(dirent);
if (Utils.imageCheck(dirent.name)) {
this.props.showImagePopup(dirent);
} else {
this.props.onItemClick(dirent);
}
} else { } else {
this.setState({isGridSelected: false});
this.props.onGridItemClick(this.props.dirent); this.props.onGridItemClick(this.props.dirent);
} }
}; };
handleDoubleClick = (dirent) => {
if (Utils.imageCheck(dirent.name)) {
this.props.showImagePopup(dirent);
} else {
this.props.onItemClick(dirent);
}
};
onItemLinkClick = (e) => { onItemLinkClick = (e) => {
e.preventDefault(); e.preventDefault();
const dirent = this.props.dirent; const dirent = this.props.dirent;
@ -96,11 +114,7 @@ class DirentGridItem extends React.Component {
return; return;
} }
if (Utils.imageCheck(dirent.name)) { this.handleDoubleClick(dirent);
this.props.showImagePopup(dirent);
} else {
this.props.onItemClick(dirent);
}
}; };
onGridItemDragStart = (e) => { onGridItemDragStart = (e) => {
@ -211,7 +225,7 @@ class DirentGridItem extends React.Component {
for (let i = 0; i < frontName.length; i++) { for (let i = 0; i < frontName.length; i++) {
// Use charCodeAt(i) > 127 to check Chinese and English. // Use charCodeAt(i) > 127 to check Chinese and English.
// English and symbols occupy 1 position, Chinese and others occupy 2 positions. // English and symbols occupy 1 position, Chinese and others occupy 2 positions.
frontName.charCodeAt(i) > 127 ? (sum = sum + 2 ) : (sum = sum + 1); frontName.charCodeAt(i) > 127 ? (sum = sum + 2) : (sum = sum + 1);
// When sum position exceeds 20, back string will not be displayed. // When sum position exceeds 20, back string will not be displayed.
if (sum > 20) { if (sum > 20) {
frontName = frontName.slice(0, i) + '...'; frontName = frontName.slice(0, i) + '...';
@ -248,7 +262,6 @@ class DirentGridItem extends React.Component {
} }
let gridClass = 'grid-file-img-link cursor-pointer'; let gridClass = 'grid-file-img-link cursor-pointer';
gridClass += this.state.isGridSelected ? ' grid-selected-active' : ' ';
gridClass += this.state.isGridDropTipShow ? ' grid-drop-show' : ' '; gridClass += this.state.isGridDropTipShow ? ' grid-drop-show' : ' ';
let lockedInfo = dirent.is_freezed ? gettext('Frozen by {name}') : gettext('locked by {name}'); let lockedInfo = dirent.is_freezed ? gettext('Frozen by {name}') : gettext('locked by {name}');
@ -259,7 +272,10 @@ class DirentGridItem extends React.Component {
const showName = this.getRenderedText(dirent); const showName = this.getRenderedText(dirent);
return ( return (
<Fragment> <Fragment>
<li className="grid-item" onContextMenu={this.onGridItemContextMenu} onMouseDown={this.onGridItemMouseDown}> <li
className={`grid-item ${this.state.isGridSelected ? 'grid-selected-active' : ''}`}
onContextMenu={this.onGridItemContextMenu}
onMouseDown={this.onGridItemMouseDown}>
<div <div
className={gridClass} className={gridClass}
draggable={this.canDrag} draggable={this.canDrag}
@ -294,14 +310,14 @@ class DirentGridItem extends React.Component {
)} )}
{(!dirent.isDir() && !this.canPreview) ? {(!dirent.isDir() && !this.canPreview) ?
<a <a
className={`sf-link grid-file-name-link ${this.state.isGridSelected ? 'grid-link-selected-active' : ''}`} className="sf-link grid-file-name-link"
onClick={this.onItemLinkClick} onClick={this.onItemClick}
title={dirent.name} title={dirent.name}
>{showName}</a> : >{showName}</a> :
<a <a
className={`grid-file-name-link ${this.state.isGridSelected ? 'grid-link-selected-active' : ''}`} className="grid-file-name-link"
href={dirent.type === 'dir' ? dirHref : fileHref} href={dirent.type === 'dir' ? dirHref : fileHref}
onClick={this.onItemLinkClick} onClick={this.onItemClick}
title={dirent.name} title={dirent.name}
>{showName}</a> >{showName}</a>
} }

View File

@ -15,12 +15,9 @@
line-height: 0; line-height: 0;
} }
.grid-item:hover .grid-file-img-link { .grid-item:hover {
background: #f8f8f8; background: #f5f5f5;
} border-radius: 5px;
.grid-item:hover a {
color: #eb8205;
} }
.grid-file-img-link { .grid-file-img-link {
@ -67,6 +64,11 @@
word-break: break-all; word-break: break-all;
} }
.grid-file-name-link:hover {
color: #212529;
text-decoration: none;
}
.grid-file-locked-icon { .grid-file-locked-icon {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
@ -75,11 +77,8 @@
} }
.grid-selected-active { .grid-selected-active {
background-color: #f8f8f8; background-color: #f2f4f6;
} border-radius: 5px;
.grid-link-selected-active {
color: #eb8205;
} }
.grid-drop-show { .grid-drop-show {