mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-03 16:10:26 +00:00
[shared with me] mobile: improvement (#3861)
This commit is contained in:
@@ -7,7 +7,7 @@ const propTypes = {
|
|||||||
toggleDialog: PropTypes.func.isRequired,
|
toggleDialog: PropTypes.func.isRequired,
|
||||||
sortBy: PropTypes.string.isRequired,
|
sortBy: PropTypes.string.isRequired,
|
||||||
sortOrder: PropTypes.string.isRequired,
|
sortOrder: PropTypes.string.isRequired,
|
||||||
sortList: PropTypes.func.isRequired
|
sortItems: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
class SortOptions extends React.Component {
|
class SortOptions extends React.Component {
|
||||||
@@ -38,7 +38,7 @@ class SortOptions extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const [sortBy, sortOrder] = e.target.value.split('-');
|
const [sortBy, sortOrder] = e.target.value.split('-');
|
||||||
this.props.sortList(sortBy, sortOrder);
|
this.props.sortItems(sortBy, sortOrder);
|
||||||
this.props.toggleDialog();
|
this.props.toggleDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -186,7 +186,7 @@ class MyLibraries extends Component {
|
|||||||
toggleDialog={this.toggleSortOptionsDialog}
|
toggleDialog={this.toggleSortOptionsDialog}
|
||||||
sortBy={this.state.sortBy}
|
sortBy={this.state.sortBy}
|
||||||
sortOrder={this.state.sortOrder}
|
sortOrder={this.state.sortOrder}
|
||||||
sortList={this.sortRepoList}
|
sortItems={this.sortRepoList}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{this.state.isShowDetails && (
|
{this.state.isShowDetails && (
|
||||||
|
@@ -110,11 +110,14 @@ class MylibRepoListItem extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onStarRepo = () => {
|
onStarRepo = () => {
|
||||||
|
const repoName = this.props.repo.repo_name;
|
||||||
if (this.state.isStarred) {
|
if (this.state.isStarred) {
|
||||||
seafileAPI.unstarItem(this.props.repo.repo_id, '/').then(() => {
|
seafileAPI.unstarItem(this.props.repo.repo_id, '/').then(() => {
|
||||||
this.setState({isStarred: !this.state.isStarred});
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
if (window.innerWidth < 728) {
|
if (window.innerWidth < 768) {
|
||||||
toaster.success(gettext('Successfully unstarred the library.'));
|
const msg = gettext('Successfully unstarred {library_name_placeholder}.')
|
||||||
|
.replace('{library_name_placeholder}', repoName);
|
||||||
|
toaster.success(msg);
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
@@ -123,8 +126,10 @@ class MylibRepoListItem extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
seafileAPI.starItem(this.props.repo.repo_id, '/').then(() => {
|
seafileAPI.starItem(this.props.repo.repo_id, '/').then(() => {
|
||||||
this.setState({isStarred: !this.state.isStarred});
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
if (window.innerWidth < 728) {
|
if (window.innerWidth < 768) {
|
||||||
toaster.success(gettext('Successfully starred the library.'));
|
const msg = gettext('Successfully starred {library_name_placeholder}.')
|
||||||
|
.replace('{library_name_placeholder}', repoName);
|
||||||
|
toaster.success(msg);
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
|
@@ -103,9 +103,9 @@ class MylibRepoListView extends React.Component {
|
|||||||
<table className="table-thead-hidden">
|
<table className="table-thead-hidden">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="10%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
<th width="12%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
||||||
<th width="84%"></th>
|
<th width="80%"></th>
|
||||||
<th width="6%"><span className="sr-only">{gettext('Actions')}</span></th>
|
<th width="8%"><span className="sr-only">{gettext('Actions')}</span></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
|
import { Dropdown, DropdownToggle, DropdownItem } from 'reactstrap';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import cookie from 'react-cookies';
|
import cookie from 'react-cookies';
|
||||||
@@ -12,6 +13,7 @@ import Loading from '../../components/loading';
|
|||||||
import EmptyTip from '../../components/empty-tip';
|
import EmptyTip from '../../components/empty-tip';
|
||||||
import ModalPotal from '../../components/modal-portal';
|
import ModalPotal from '../../components/modal-portal';
|
||||||
import ShareDialog from '../../components/dialog/share-dialog';
|
import ShareDialog from '../../components/dialog/share-dialog';
|
||||||
|
import SortOptionsDialog from '../../components/dialog/sort-options';
|
||||||
|
|
||||||
class Content extends Component {
|
class Content extends Component {
|
||||||
|
|
||||||
@@ -74,19 +76,15 @@ class Content extends Component {
|
|||||||
const mobileThead = (
|
const mobileThead = (
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="18%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
<th width="12%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
||||||
<th width="76%">
|
<th width="80%"></th>
|
||||||
{gettext('Sort:')}
|
<th width="8%"><span className="sr-only">{gettext('Actions')}</span></th>
|
||||||
<a className="table-sort-op" href="#" onClick={this.sortByName}>{gettext('name')} {sortByName && sortIcon}</a>
|
|
||||||
<a className="table-sort-op" href="#" onClick={this.sortByTime}>{gettext('last update')} {sortByTime && sortIcon}</a>
|
|
||||||
</th>
|
|
||||||
<th width="6%"><span className="sr-only">{gettext('Actions')}</span></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
);
|
);
|
||||||
|
|
||||||
const table = (
|
const table = (
|
||||||
<table>
|
<table className={window.innerWidth >= 768 ? '' : 'table-thead-hidden'}>
|
||||||
{window.innerWidth >= 768 ? desktopThead : mobileThead}
|
{window.innerWidth >= 768 ? desktopThead : mobileThead}
|
||||||
<TableBody items={items} />
|
<TableBody items={items} />
|
||||||
</table>
|
</table>
|
||||||
@@ -133,33 +131,34 @@ class Item extends Component {
|
|||||||
unshared: false,
|
unshared: false,
|
||||||
isShowSharedDialog: false,
|
isShowSharedDialog: false,
|
||||||
isStarred: this.props.data.starred,
|
isStarred: this.props.data.starred,
|
||||||
|
isOpMenuOpen: false // for mobile
|
||||||
};
|
};
|
||||||
|
|
||||||
this.handleMouseOver = this.handleMouseOver.bind(this);
|
|
||||||
this.handleMouseOut = this.handleMouseOut.bind(this);
|
|
||||||
|
|
||||||
this.share = this.share.bind(this);
|
|
||||||
this.leaveShare = this.leaveShare.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMouseOver() {
|
toggleOpMenu = () => {
|
||||||
|
this.setState({
|
||||||
|
isOpMenuOpen: !this.state.isOpMenuOpen
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMouseOver = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showOpIcon: true
|
showOpIcon: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMouseOut() {
|
handleMouseOut = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showOpIcon: false
|
showOpIcon: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
share(e) {
|
share = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.setState({isShowSharedDialog: true});
|
this.setState({isShowSharedDialog: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
leaveShare(e) {
|
leaveShare = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const data = this.props.data;
|
const data = this.props.data;
|
||||||
@@ -193,9 +192,15 @@ class Item extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onStarRepo = () => {
|
onStarRepo = () => {
|
||||||
|
const repoName = this.props.data.repo_name;
|
||||||
if (this.state.isStarred) {
|
if (this.state.isStarred) {
|
||||||
seafileAPI.unstarItem(this.props.data.repo_id, '/').then(() => {
|
seafileAPI.unstarItem(this.props.data.repo_id, '/').then(() => {
|
||||||
this.setState({isStarred: !this.state.isStarred});
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
const msg = gettext('Successfully unstarred {library_name_placeholder}.')
|
||||||
|
.replace('{library_name_placeholder}', repoName);
|
||||||
|
toaster.success(msg);
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
toaster.danger(errMessage);
|
toaster.danger(errMessage);
|
||||||
@@ -203,6 +208,11 @@ class Item extends Component {
|
|||||||
} else {
|
} else {
|
||||||
seafileAPI.starItem(this.props.data.repo_id, '/').then(() => {
|
seafileAPI.starItem(this.props.data.repo_id, '/').then(() => {
|
||||||
this.setState({isStarred: !this.state.isStarred});
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
const msg = gettext('Successfully starred {library_name_placeholder}.')
|
||||||
|
.replace('{library_name_placeholder}', repoName);
|
||||||
|
toaster.success(msg);
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
toaster.danger(errMessage);
|
toaster.danger(errMessage);
|
||||||
@@ -273,10 +283,25 @@ class Item extends Component {
|
|||||||
<span className="item-meta-info" title={moment(data.last_modified).format('llll')}>{moment(data.last_modified).fromNow()}</span>
|
<span className="item-meta-info" title={moment(data.last_modified).format('llll')}>{moment(data.last_modified).fromNow()}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{(isPro && data.is_admin) &&
|
<Dropdown isOpen={this.state.isOpMenuOpen} toggle={this.toggleOpMenu}>
|
||||||
<a href="#" className={shareIconClassName} title={gettext('Share')} onClick={this.share}></a>
|
<DropdownToggle
|
||||||
}
|
tag="i"
|
||||||
<a href="#" className={leaveShareIconClassName} title={gettext('Leave Share')} onClick={this.leaveShare}></a>
|
className="sf-dropdown-toggle fa fa-ellipsis-v 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.onStarRepo}>{this.state.isStarred ? gettext('Unstar') : gettext('Star')}</DropdownItem>
|
||||||
|
{(isPro && data.is_admin) &&
|
||||||
|
<DropdownItem className="mobile-menu-item" onClick={this.share}>{gettext('Share')}</DropdownItem>
|
||||||
|
}
|
||||||
|
<DropdownItem className="mobile-menu-item" onClick={this.leaveShare}>{gettext('Leave Share')}</DropdownItem>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dropdown>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{this.state.isShowSharedDialog && (
|
{this.state.isShowSharedDialog && (
|
||||||
@@ -314,12 +339,12 @@ class SharedLibraries extends Component {
|
|||||||
items: [],
|
items: [],
|
||||||
sortBy: cookie.load('seafile-repo-dir-sort-by') || 'name', // 'name' or 'time' or 'size'
|
sortBy: cookie.load('seafile-repo-dir-sort-by') || 'name', // 'name' or 'time' or 'size'
|
||||||
sortOrder: cookie.load('seafile-repo-dir-sort-order') || 'asc', // 'asc' or 'desc'
|
sortOrder: cookie.load('seafile-repo-dir-sort-order') || 'asc', // 'asc' or 'desc'
|
||||||
|
isSortOptionsDialogOpen: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
seafileAPI.listRepos({type:'shared'}).then((res) => {
|
seafileAPI.listRepos({type:'shared'}).then((res) => {
|
||||||
// res: {data: {...}, status: 200, statusText: "OK", headers: {…}, config: {…}, …}
|
|
||||||
let repoList = res.data.repos.map((item) => {
|
let repoList = res.data.repos.map((item) => {
|
||||||
return new Repo(item);
|
return new Repo(item);
|
||||||
});
|
});
|
||||||
@@ -361,25 +386,42 @@ class SharedLibraries extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleSortOptionsDialog = () => {
|
||||||
|
this.setState({
|
||||||
|
isSortOptionsDialogOpen: !this.state.isSortOptionsDialogOpen
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="main-panel-center">
|
<Fragment>
|
||||||
<div className="cur-view-container">
|
<div className="main-panel-center">
|
||||||
<div className="cur-view-path">
|
<div className="cur-view-container">
|
||||||
<h3 className="sf-heading">{gettext('Shared with me')}</h3>
|
<div className="cur-view-path align-items-center">
|
||||||
</div>
|
<h3 className="sf-heading m-0">{gettext('Shared with me')}</h3>
|
||||||
<div className="cur-view-content">
|
{(window.innerWidth < 768) && <span className="sf3-font sf3-font-sort action-icon" onClick={this.toggleSortOptionsDialog}></span>}
|
||||||
<Content
|
</div>
|
||||||
loading={this.state.loading}
|
<div className="cur-view-content">
|
||||||
errorMsg={this.state.errorMsg}
|
<Content
|
||||||
items={this.state.items}
|
loading={this.state.loading}
|
||||||
sortBy={this.state.sortBy}
|
errorMsg={this.state.errorMsg}
|
||||||
sortOrder={this.state.sortOrder}
|
items={this.state.items}
|
||||||
sortItems={this.sortItems}
|
sortBy={this.state.sortBy}
|
||||||
/>
|
sortOrder={this.state.sortOrder}
|
||||||
|
sortItems={this.sortItems}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{this.state.isSortOptionsDialogOpen &&
|
||||||
|
<SortOptionsDialog
|
||||||
|
toggleDialog={this.toggleSortOptionsDialog}
|
||||||
|
sortBy={this.state.sortBy}
|
||||||
|
sortOrder={this.state.sortOrder}
|
||||||
|
sortItems={this.sortItems}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user