1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-13 05:39:59 +00:00

[Refactor] Do not run mobile functions on PC devices (#6408)

* 01 refactor dirent-list-item

* 02 refactor upload links

* 03 refactor linked devices

* 04 refactor user-settings linked-devices

* 05 refactor invitation view

* 06 refactor share-links

* 07 refactor starred page

* 08 refactor share-admin folders

* 09 refactor share-admin libraries

* 10 refactor shared-libs
This commit is contained in:
Michael An
2024-07-25 11:04:36 +08:00
committed by GitHub
parent 5f99c77596
commit 113a88d850
10 changed files with 752 additions and 721 deletions

View File

@@ -708,7 +708,10 @@ class DirentListItem extends React.Component {
const { canDrag } = this.state;
const lockedImageUrl = `${mediaUrl}img/file-${dirent.is_freezed ? 'freezed-32.svg' : 'locked-32.png'}`;
const lockedMessage = dirent.is_freezed ? gettext('freezed') : gettext('locked');
const desktopItem = (
return (
<Fragment>
{isDesktop ?
<tr
className={trClass}
draggable={canDrag}
@@ -780,8 +783,7 @@ class DirentListItem extends React.Component {
<td className="file-size">{dirent.size && dirent.size}</td>
<td className="last-update" title={moment.unix(dirent.mtime).format('llll')}>{dirent.mtime_relative}</td>
</tr>
);
const mobileItem = (
:
<tr>
<td onClick={this.onItemClick}>
<div className="dir-icon">
@@ -820,11 +822,21 @@ class DirentListItem extends React.Component {
<div className="mobile-operation-menu-bg-layer"></div>
<div className="mobile-operation-menu">
{dirent.starred !== undefined &&
<DropdownItem className="mobile-menu-item" onClick={this.onItemStarred}>{dirent.starred ? gettext('Unstar') : gettext('Star')}</DropdownItem>}
<DropdownItem className="mobile-menu-item" onClick={this.onItemStarred}>
{dirent.starred ? gettext('Unstar') : gettext('Star')}
</DropdownItem>
}
{this.props.getDirentItemMenuList(dirent, true).map((item, index) => {
if (item != 'Divider' && item.key != 'Open via Client') {
return (
<DropdownItem className="mobile-menu-item" key={index} data-op={item.key} onClick={this.onMobileMenuItemClick}>{item.value}</DropdownItem>
<DropdownItem
className="mobile-menu-item"
key={index}
data-op={item.key}
onClick={this.onMobileMenuItemClick}
>
{item.value}
</DropdownItem>
);
} else {
return null;
@@ -835,11 +847,7 @@ class DirentListItem extends React.Component {
</Dropdown>
</td>
</tr>
);
return (
<Fragment>
{isDesktop ? desktopItem : mobileItem}
}
{this.state.isMoveDialogShow &&
<ModalPortal>
<MoveDirentDialog

View File

@@ -126,17 +126,11 @@ class Item extends Component {
});
};
render() {
if (this.state.unlinked) {
return null;
}
renderDesktop = () => {
const data = this.props.data;
let opClasses = 'sf3-font-delete1 sf3-font unlink-device action-icon';
opClasses += this.state.isOpIconShown ? '' : ' invisible';
const desktopItem = (
return (
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onFocus={this.handleMouseOver}>
<td>{data.platform}</td>
<td>{data.device_name}</td>
@@ -147,8 +141,11 @@ class Item extends Component {
</td>
</tr>
);
};
const mobileItem = (
renderMobile = () => {
const data = this.props.data;
return (
<tr>
<td>
{data.device_name}<br />
@@ -176,10 +173,15 @@ class Item extends Component {
</td>
</tr>
);
};
render() {
if (this.state.unlinked) {
return null;
}
return (
<React.Fragment>
{this.props.isDesktop ? desktopItem : mobileItem}
{this.props.isDesktop ? this.renderDesktop() : this.renderMobile()}
{this.state.isConfirmUnlinkDialogOpen &&
<ConfirmUnlinkDeviceDialog
executeOperation={this.unlinkDevice}

View File

@@ -82,7 +82,9 @@ class Item extends React.Component {
const item = this.props.invitation;
const desktopItem = (
return (
<Fragment>
{this.props.isDesktop ?
<tr onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onFocus={this.onMouseEnter} tabIndex="0">
<td>{item.accepter}</td>
<td>{moment(item.invite_time).format('YYYY-MM-DD')}</td>
@@ -108,9 +110,7 @@ class Item extends React.Component {
)}
</td>
</tr>
);
const mobileItem = (
:
<tr>
<td>
{item.accepter}<br />
@@ -140,11 +140,7 @@ class Item extends React.Component {
</Dropdown>
</td>
</tr>
);
return (
<Fragment>
{this.props.isDesktop ? desktopItem : mobileItem}
}
{isRevokeDialogOpen &&
<InvitationRevokeDialog
accepter={item.accepter}

View File

@@ -128,17 +128,11 @@ class Item extends Component {
});
};
render() {
if (this.state.unlinked) {
return null;
}
renderDesktopItem = () => {
const data = this.props.data;
let opClasses = 'sf3-font-delete1 sf3-font unlink-device action-icon';
opClasses += this.state.isOpIconShown ? '' : ' invisible';
const desktopItem = (
return (
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onFocus={this.handleMouseOver}>
<td>{data.platform}</td>
<td>{data.device_name}</td>
@@ -149,8 +143,11 @@ class Item extends Component {
</td>
</tr>
);
};
const mobileItem = (
renderMobileItem = () => {
const data = this.props.data;
return (
<tr>
<td>
{data.device_name}<br />
@@ -178,10 +175,15 @@ class Item extends Component {
</td>
</tr>
);
};
render() {
if (this.state.unlinked) {
return null;
}
return (
<React.Fragment>
{this.props.isDesktop ? desktopItem : mobileItem}
{this.props.isDesktop ? this.renderDesktopItem() : this.renderMobileItem()}
{this.state.isConfirmUnlinkDialogOpen &&
<ConfirmUnlinkDeviceDialog
executeOperation={this.unlinkDevice}

View File

@@ -209,7 +209,9 @@ class Item extends Component {
if (share_permission.startsWith('custom-')) {
share_permission = share_permission.slice(7);
}
const desktopItem = (
if (this.props.isDesktop) {
return (
<tr onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onFocus={this.onMouseEnter}>
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
<td><Link to={folderUrl}>{item.folder_name}</Link></td>
@@ -248,8 +250,8 @@ class Item extends Component {
<td><a href="#" role="button" aria-label={gettext('Unshare')} className={`action-icon sf2-icon-x3 ${isOpIconShown ? '' : 'invisible'}`} title={gettext('Unshare')} onClick={this.unshare}></a></td>
</tr>
);
const mobileItem = (
} else {
return (
<Fragment>
<tr>
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
@@ -290,8 +292,7 @@ class Item extends Component {
)}
</Fragment>
);
return this.props.isDesktop ? desktopItem : mobileItem;
}
}
}

View File

@@ -224,7 +224,8 @@ class Item extends Component {
share_permission = share_permission.slice(7);
}
const desktopItem = (
if (this.props.isDesktop) {
return (
<tr onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onFocus={this.onMouseEnter}>
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
<td><Link to={repoUrl}>{item.repo_name}</Link></td>
@@ -262,8 +263,8 @@ class Item extends Component {
<td><a href="#" role="button" aria-label={gettext('Unshare')} className={`action-icon sf2-icon-x3 ${isOpIconShown ? '' : 'invisible'}`} title={gettext('Unshare')} onClick={this.unshare}></a></td>
</tr>
);
const mobileItem = (
} else {
return (
<Fragment>
<tr>
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
@@ -304,8 +305,7 @@ class Item extends Component {
)}
</Fragment>
);
return this.props.isDesktop ? desktopItem : mobileItem;
}
}
}

View File

@@ -267,18 +267,26 @@ class Item extends Component {
objUrl = `${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`;
}
const deletedTip = item.obj_id === '' ? <span style={{ color: 'red' }}>{gettext('(deleted)')}</span> : null;
const desktopItem = (
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} onFocus={this.handleMouseEnter}>
return (
<Fragment>
{this.props.isDesktop ?
<tr
className={this.state.highlight ? 'tr-highlight' : ''}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
onFocus={this.handleMouseEnter}
>
<td><img src={iconUrl} width="24" alt="" /></td>
<td>
{item.is_dir ?
<Link to={objUrl}>{item.obj_name}</Link> :
<a href={objUrl} target="_blank" rel="noreferrer">{item.obj_name}</a>
}
{deletedTip}
{item.obj_id === '' ? <span style={{ color: 'red' }}>{gettext('(deleted)')}</span> : null}
</td>
<td>
<Link to={`${siteRoot}library/${item.repo_id}/${encodeURIComponent(item.repo_name)}/`}>{item.repo_name}</Link>
</td>
<td><Link to={`${siteRoot}library/${item.repo_id}/${encodeURIComponent(item.repo_name)}/`}>{item.repo_name}</Link></td>
{isPro &&
<td>
<Selector
@@ -293,13 +301,29 @@ class Item extends Component {
<td>{item.view_cnt}</td>
<td>{this.renderExpiration()}</td>
<td>
{!item.is_expired && <a href="#" className={`sf2-icon-link action-icon op-icon ${isOpIconShown ? '' : 'invisible'}`} title={gettext('View')} aria-label={gettext('View')} role="button" onClick={this.viewLink}></a>}
<a href="#" className={`sf3-font-delete1 sf3-font action-icon op-icon ${isOpIconShown ? '' : 'invisible'}`} title={gettext('Remove')} aria-label={gettext('Remove')} role="button" onClick={this.removeLink}></a>
{!item.is_expired &&
<a
href="#"
className={`sf2-icon-link action-icon op-icon ${isOpIconShown ? '' : 'invisible'}`}
title={gettext('View')}
aria-label={gettext('View')}
role="button"
onClick={this.viewLink}
>
</a>
}
<a
href="#"
className={`sf3-font-delete1 sf3-font action-icon op-icon ${isOpIconShown ? '' : 'invisible'}`}
title={gettext('Remove')}
aria-label={gettext('Remove')}
role="button"
onClick={this.removeLink}
>
</a>
</td>
</tr>
);
const mobileItem = (
:
<Fragment>
<tr>
<td><img src={iconUrl} alt="" width="24" /></td>
@@ -344,11 +368,7 @@ class Item extends Component {
/>
}
</Fragment>
);
return (
<Fragment>
{this.props.isDesktop ? desktopItem : mobileItem}
}
{isLinkDialogOpen &&
<ShareAdminLink
link={item.link}

View File

@@ -140,11 +140,15 @@ class Item extends Component {
const repoUrl = `${siteRoot}library/${item.repo_id}/${encodeURIComponent(item.repo_name)}`;
const objUrl = `${repoUrl}${Utils.encodePath(item.path)}`;
const deletedTip = item.obj_id === '' ? <span style={{ color: 'red' }}>{gettext('(deleted)')}</span> : null;
const desktopItem = (
return (
<Fragment>
{this.props.isDesktop ?
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onFocus={this.handleMouseOver}>
<td><img src={iconUrl} alt="" width="24" /></td>
<td><Link to={objUrl}>{item.obj_name}</Link>{deletedTip}</td>
<td>
<Link to={objUrl}>{item.obj_name}</Link>
{item.obj_id === '' ? <span style={{ color: 'red' }}>{gettext('(deleted)')}</span> : null}
</td>
<td><Link to={repoUrl}>{item.repo_name}</Link></td>
<td>{item.view_cnt}</td>
<td>{this.renderExpiration()}</td>
@@ -153,9 +157,7 @@ class Item extends Component {
<a href="#" className={`sf3-font-delete1 sf3-font action-icon op-icon ${isOpIconShown ? '' : 'invisible'}`} title={gettext('Remove')} aria-label={gettext('Remove')} role="button" onClick={this.removeLink}></a>
</td>
</tr>
);
const mobileItem = (
:
<tr>
<td><img src={iconUrl} alt="" width="24" /></td>
<td>
@@ -185,10 +187,7 @@ class Item extends Component {
</Dropdown>
</td>
</tr>
);
return (
<Fragment>
{this.props.isDesktop ? desktopItem : mobileItem}
}
{isLinkDialogOpen &&
<ShareAdminLink
link={item.link}

View File

@@ -282,7 +282,8 @@ class Item extends Component {
// at present, only repo shared with 'r', 'rw' can be monitored.(Fri Feb 10 16:24:49 CST 2023)
const enableMonitorRepo = isPro && (data.permission == 'r' || data.permission == 'rw');
const desktopItem = (
if (this.props.isDesktop) {
return (
<Fragment>
{currentViewMode == 'list' ? (
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onFocus={this.handleMouseOver}>
@@ -395,8 +396,8 @@ class Item extends Component {
)}
</Fragment>
);
const mobileItem = (
} else {
return (
<Fragment>
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}>
<td onClick={this.visitRepo}><img src={data.icon_url} title={data.icon_title} alt={data.icon_title} width="24" /></td>
@@ -446,8 +447,7 @@ class Item extends Component {
)}
</Fragment>
);
return this.props.isDesktop ? desktopItem : mobileItem;
}
}
}

View File

@@ -19,15 +19,18 @@ class Content extends Component {
return <Loading />;
} else if (errorMsg) {
return <p className="error text-center">{errorMsg}</p>;
} else {
const emptyTip = (
} else if (items.length === 0) {
return (
<EmptyTip>
<h2>{gettext('No favorites')}</h2>
<p>{gettext('You have not added any libraries, folders or files to your favorites yet. A favorite gives you quick access to your most frequently used objects. You can add a library, folder or file to your favorites by clicking the star to the left of its name.')}</p>
</EmptyTip>
);
const desktopThead = (
} else {
const isDesktop = Utils.isDesktop();
return (
<table className={`table-hover ${isDesktop ? '' : 'table-thead-hidden'}`}>
{isDesktop ?
<thead>
<tr>
<th width="4%"></th>
@@ -37,8 +40,7 @@ class Content extends Component {
<th width="6%"></th>
</tr>
</thead>
);
const mobileThead = (
:
<thead>
<tr>
<th width="12%"></th>
@@ -46,15 +48,10 @@ class Content extends Component {
<th width="8%"></th>
</tr>
</thead>
);
const isDesktop = Utils.isDesktop();
return items.length ? (
<table className={`table-hover ${isDesktop ? '' : 'table-thead-hidden'}`}>
{isDesktop ? desktopThead : mobileThead}
<TableBody items={items} />
}
<TableBody items={items} isDesktop={isDesktop} />
</table>
) : emptyTip;
);
}
}
}
@@ -133,7 +130,7 @@ class TableBody extends Component {
item.mtime_relative = moment(item.mtime).fromNow();
return <Item key={index} data={item} />;
return <Item key={index} data={item} isDesktop={this.props.isDesktop} />;
}, this);
return (
@@ -145,6 +142,7 @@ class TableBody extends Component {
TableBody.propTypes = {
data: PropTypes.object,
items: PropTypes.array,
isDesktop: PropTypes.bool.isRequired,
};
class Item extends Component {
@@ -197,18 +195,54 @@ class Item extends Component {
}
};
render() {
if (this.state.unstarred) {
return null;
}
renderMobile = () => {
const data = this.props.data;
const linkUrl = data.dirent_view_url;
const mobileItem = (
<tr>
<td className="text-center" onClick={this.visitItem}>
{
data.thumbnail_url ?
<img className="thumbnail" src={data.thumbnail_url} alt="" /> :
<img src={data.item_icon_url} alt={gettext('icon')} width="24" />
}
</td>
<td onClick={this.visitItem}>
{data.is_dir ?
<Link to={linkUrl}>{data.obj_name}</Link> :
<a className="normal" href={data.dirent_view_url} target="_blank" rel="noreferrer">{data.obj_name}</a>
}
<br />
<span className="item-meta-info">{data.repo_name}</span>
<span className="item-meta-info" dangerouslySetInnerHTML={{ __html: data.mtime_relative }}></span>
</td>
<td>
<Dropdown isOpen={this.state.isOpMenuOpen} toggle={this.toggleOpMenu}>
<DropdownToggle
tag="i"
className="sf-dropdown-toggle sf3-font sf3-font-more-vertical ml-0"
title={gettext('More operations')}
data-toggle="dropdown"
aria-expanded={this.state.isOpMenuOpen}
/>
<div className={this.state.isOpMenuOpen ? '' : 'd-none'} onClick={this.toggleOpMenu}>
<div className="mobile-operation-menu-bg-layer"></div>
<div className="mobile-operation-menu">
<DropdownItem className="mobile-menu-item" onClick={this.unstar}>{gettext('Unstar')}</DropdownItem>
</div>
</div>
</Dropdown>
</td>
</tr>
);
return mobileItem;
};
renderDesktop = () => {
const data = this.props.data;
let opClasses = 'sf2-icon-x3 unstar action-icon';
opClasses += this.state.showOpIcon ? '' : ' invisible';
const linkUrl = data.dirent_view_url;
const desktopItem = (
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onFocus={this.handleMouseOver}>
<td className="text-center">
@@ -238,52 +272,21 @@ class Item extends Component {
</td>
</tr>
);
return desktopItem;
};
const mobileItem = (
<tr>
<td className="text-center" onClick={this.visitItem}>
{
data.thumbnail_url ?
<img className="thumbnail" src={data.thumbnail_url} alt="" /> :
<img src={data.item_icon_url} alt={gettext('icon')} width="24" />
render() {
if (this.state.unstarred) {
return null;
}
</td>
<td onClick={this.visitItem}>
{ data.is_dir ?
<Link to={linkUrl}>{data.obj_name}</Link> :
<a className="normal" href={data.dirent_view_url} target="_blank" rel="noreferrer">{data.obj_name}</a>
}
<br />
<span className="item-meta-info">{data.repo_name}</span>
<span className="item-meta-info" dangerouslySetInnerHTML={{ __html: data.mtime_relative }}></span>
</td>
<td>
<Dropdown isOpen={this.state.isOpMenuOpen} toggle={this.toggleOpMenu}>
<DropdownToggle
tag="i"
className="sf-dropdown-toggle sf3-font sf3-font-more-vertical ml-0"
title={gettext('More operations')}
data-toggle="dropdown"
aria-expanded={this.state.isOpMenuOpen}
/>
<div className={this.state.isOpMenuOpen ? '' : 'd-none'} onClick={this.toggleOpMenu}>
<div className="mobile-operation-menu-bg-layer"></div>
<div className="mobile-operation-menu">
<DropdownItem className="mobile-menu-item" onClick={this.unstar}>{gettext('Unstar')}</DropdownItem>
</div>
</div>
</Dropdown>
</td>
</tr>
);
return Utils.isDesktop() ? desktopItem : mobileItem;
return this.props.isDesktop ? this.renderDesktop() : this.renderMobile();
}
}
Item.propTypes = {
data: PropTypes.object,
items: PropTypes.array,
isDesktop: PropTypes.bool.isRequired,
};
class Starred extends Component {