mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-02 07:27:04 +00:00
star repo (#2980)
* star repo * file_icon_url -> item_icon_url * add UserStarredFiles.objects.get_starred_repos_by_user()
This commit is contained in:
@@ -8,6 +8,7 @@ import { gettext, siteRoot, isPro, username, folderPermEnabled, isSystemStaff }
|
|||||||
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 Rename from '../rename';
|
import Rename from '../rename';
|
||||||
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentGroup: PropTypes.object,
|
currentGroup: PropTypes.object,
|
||||||
@@ -31,6 +32,7 @@ class SharedRepoListItem extends React.Component {
|
|||||||
isItemMenuShow: false,
|
isItemMenuShow: false,
|
||||||
isShowSharedDialog: false,
|
isShowSharedDialog: false,
|
||||||
isRenaming: false,
|
isRenaming: false,
|
||||||
|
isStarred: this.props.repo.starred,
|
||||||
};
|
};
|
||||||
this.isDeparementOnwerGroupMember = false;
|
this.isDeparementOnwerGroupMember = false;
|
||||||
}
|
}
|
||||||
@@ -323,6 +325,18 @@ class SharedRepoListItem extends React.Component {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onStarRepo = () => {
|
||||||
|
if (this.state.isStarred) {
|
||||||
|
seafileAPI.unStarItem(this.props.repo.repo_id, '/').then(() => {
|
||||||
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
seafileAPI.starItem(this.props.repo.repo_id, '/').then(() => {
|
||||||
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderPCUI = () => {
|
renderPCUI = () => {
|
||||||
let { iconUrl, iconTitle, libPath } = this.getRepoComputeParams();
|
let { iconUrl, iconTitle, libPath } = this.getRepoComputeParams();
|
||||||
let { repo } = this.props;
|
let { repo } = this.props;
|
||||||
@@ -332,6 +346,10 @@ class SharedRepoListItem extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.onMouseEnter} onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave}>
|
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.onMouseEnter} onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave}>
|
||||||
|
<td className="text-center">
|
||||||
|
{!this.state.isStarred && <i className="far fa-star star-empty cursor-pointer" onClick={this.onStarRepo}></i>}
|
||||||
|
{this.state.isStarred && <i className="fas fa-star cursor-pointer" onClick={this.onStarRepo}></i>}
|
||||||
|
</td>
|
||||||
<td><img src={iconUrl} title={repo.iconTitle} alt={iconTitle} width="24" /></td>
|
<td><img src={iconUrl} title={repo.iconTitle} alt={iconTitle} width="24" /></td>
|
||||||
<td>
|
<td>
|
||||||
{this.state.isRenaming ?
|
{this.state.isRenaming ?
|
||||||
|
@@ -104,8 +104,9 @@ class SharedRepoListView extends React.Component {
|
|||||||
<table className={isShowTableThread ? '' : 'table-thead-hidden'}>
|
<table className={isShowTableThread ? '' : 'table-thead-hidden'}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th width="4%"></th>
|
||||||
<th width="4%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
<th width="4%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
||||||
<th width="40%"><a className="d-block table-sort-op" href="#" onClick={this.sortByName}>{gettext('Name')} {sortByName && sortIcon}</a></th>
|
<th width="36%"><a className="d-block table-sort-op" href="#" onClick={this.sortByName}>{gettext('Name')} {sortByName && sortIcon}</a></th>
|
||||||
<th width="12%"><span className="sr-only">{gettext('Actions')}</span></th>
|
<th width="12%"><span className="sr-only">{gettext('Actions')}</span></th>
|
||||||
<th width={'14%'}>{gettext('Size')}</th>
|
<th width={'14%'}>{gettext('Size')}</th>
|
||||||
<th width={'14%'}><a className="d-block table-sort-op" href="#" onClick={this.sortByTime}>{gettext('Last Update')} {sortByTime && sortIcon}</a></th>
|
<th width={'14%'}><a className="d-block table-sort-op" href="#" onClick={this.sortByTime}>{gettext('Last Update')} {sortByTime && sortIcon}</a></th>
|
||||||
|
@@ -15,6 +15,7 @@ class Repo {
|
|||||||
this.modifier_email = object.modifier_email;
|
this.modifier_email = object.modifier_email;
|
||||||
this.modifier_name = object.modifier_name;
|
this.modifier_name = object.modifier_name;
|
||||||
this.type = object.type;
|
this.type = object.type;
|
||||||
|
this.starred = object.starred;
|
||||||
if (object.is_admin != undefined) {
|
if (object.is_admin != undefined) {
|
||||||
this.is_admin = object.is_admin;
|
this.is_admin = object.is_admin;
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ class MylibRepoListItem extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isOpIconShow: false,
|
isOpIconShow: false,
|
||||||
|
isStarred: this.props.repo.starred,
|
||||||
isRenaming: false,
|
isRenaming: false,
|
||||||
isShareDialogShow: false,
|
isShareDialogShow: false,
|
||||||
isDeleteDialogShow: false,
|
isDeleteDialogShow: false,
|
||||||
@@ -103,6 +104,18 @@ class MylibRepoListItem extends React.Component {
|
|||||||
this.props.onRepoClick(this.props.repo);
|
this.props.onRepoClick(this.props.repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onStarRepo = () => {
|
||||||
|
if (this.state.isStarred) {
|
||||||
|
seafileAPI.unStarItem(this.props.repo.repo_id, '/').then(() => {
|
||||||
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
seafileAPI.starItem(this.props.repo.repo_id, '/').then(() => {
|
||||||
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onShareToggle = () => {
|
onShareToggle = () => {
|
||||||
this.setState({isShareDialogShow: !this.state.isShareDialogShow});
|
this.setState({isShareDialogShow: !this.state.isShareDialogShow});
|
||||||
}
|
}
|
||||||
@@ -180,24 +193,28 @@ class MylibRepoListItem extends React.Component {
|
|||||||
|
|
||||||
renderPCUI = () => {
|
renderPCUI = () => {
|
||||||
let repo = this.props.repo;
|
let repo = this.props.repo;
|
||||||
let iconUrl = Utils.getLibIconUrl(repo);
|
let iconUrl = Utils.getLibIconUrl(repo);
|
||||||
let iconTitle = Utils.getLibIconTitle(repo);
|
let iconTitle = Utils.getLibIconTitle(repo);
|
||||||
let repoURL = `${siteRoot}library/${repo.repo_id}/${Utils.encodePath(repo.repo_name)}/`;
|
let repoURL = `${siteRoot}library/${repo.repo_id}/${Utils.encodePath(repo.repo_name)}/`;
|
||||||
return (
|
return (
|
||||||
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onClick={this.onRepoClick}>
|
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onClick={this.onRepoClick}>
|
||||||
|
<td className="text-center">
|
||||||
|
{!this.state.isStarred && <i className="far fa-star star-empty cursor-pointer" onClick={this.onStarRepo}></i>}
|
||||||
|
{this.state.isStarred && <i className="fas fa-star cursor-pointer" onClick={this.onStarRepo}></i>}
|
||||||
|
</td>
|
||||||
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
||||||
<td>
|
<td>
|
||||||
{this.state.isRenaming && (
|
{this.state.isRenaming && (
|
||||||
<Rename
|
<Rename
|
||||||
name={repo.repo_name}
|
name={repo.repo_name}
|
||||||
onRenameConfirm={this.onRenameConfirm}
|
onRenameConfirm={this.onRenameConfirm}
|
||||||
onRenameCancel={this.onRenameCancel}
|
onRenameCancel={this.onRenameCancel}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!this.state.isRenaming && repo.repo_name && (
|
{!this.state.isRenaming && repo.repo_name && (
|
||||||
<Link to={repoURL}>{repo.repo_name}</Link>
|
<Link to={repoURL}>{repo.repo_name}</Link>
|
||||||
)}
|
)}
|
||||||
{!this.state.isRenaming && !repo.repo_name &&
|
{!this.state.isRenaming && !repo.repo_name &&
|
||||||
(gettext('Broken (please contact your administrator to fix this library)'))
|
(gettext('Broken (please contact your administrator to fix this library)'))
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
@@ -206,9 +223,9 @@ class MylibRepoListItem extends React.Component {
|
|||||||
<div>
|
<div>
|
||||||
<a href="#" className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onShareToggle}></a>
|
<a href="#" className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onShareToggle}></a>
|
||||||
<a href="#" className="op-icon sf2-icon-delete" title={gettext('Delete')} onClick={this.onDeleteToggle}></a>
|
<a href="#" className="op-icon sf2-icon-delete" title={gettext('Delete')} onClick={this.onDeleteToggle}></a>
|
||||||
<MylibRepoMenu
|
<MylibRepoMenu
|
||||||
isPC={true}
|
isPC={true}
|
||||||
repo={this.props.repo}
|
repo={this.props.repo}
|
||||||
onMenuItemClick={this.onMenuItemClick}
|
onMenuItemClick={this.onMenuItemClick}
|
||||||
onFreezedItem={this.props.onFreezedItem}
|
onFreezedItem={this.props.onFreezedItem}
|
||||||
onUnfreezedItem={this.onUnfreezedItem}
|
onUnfreezedItem={this.onUnfreezedItem}
|
||||||
@@ -225,7 +242,7 @@ class MylibRepoListItem extends React.Component {
|
|||||||
|
|
||||||
renderMobileUI = () => {
|
renderMobileUI = () => {
|
||||||
let repo = this.props.repo;
|
let repo = this.props.repo;
|
||||||
let iconUrl = Utils.getLibIconUrl(repo);
|
let iconUrl = Utils.getLibIconUrl(repo);
|
||||||
let iconTitle = Utils.getLibIconTitle(repo);
|
let iconTitle = Utils.getLibIconTitle(repo);
|
||||||
let repoURL = `${siteRoot}library/${repo.repo_id}/${Utils.encodePath(repo.repo_name)}/`;
|
let repoURL = `${siteRoot}library/${repo.repo_id}/${Utils.encodePath(repo.repo_name)}/`;
|
||||||
|
|
||||||
@@ -234,16 +251,16 @@ class MylibRepoListItem extends React.Component {
|
|||||||
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
<td><img src={iconUrl} title={iconTitle} alt={iconTitle} width="24" /></td>
|
||||||
<td>
|
<td>
|
||||||
{this.state.isRenaming && (
|
{this.state.isRenaming && (
|
||||||
<Rename
|
<Rename
|
||||||
name={repo.repo_name}
|
name={repo.repo_name}
|
||||||
onRenameConfirm={this.onRenameConfirm}
|
onRenameConfirm={this.onRenameConfirm}
|
||||||
onRenameCancel={this.onRenameCancel}
|
onRenameCancel={this.onRenameCancel}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!this.state.isRenaming && repo.repo_name && (
|
{!this.state.isRenaming && repo.repo_name && (
|
||||||
<div><Link to={repoURL}>{repo.repo_name}</Link></div>
|
<div><Link to={repoURL}>{repo.repo_name}</Link></div>
|
||||||
)}
|
)}
|
||||||
{!this.state.isRenaming && !repo.repo_name &&
|
{!this.state.isRenaming && !repo.repo_name &&
|
||||||
<div>(gettext('Broken (please contact your administrator to fix this library)'))</div>
|
<div>(gettext('Broken (please contact your administrator to fix this library)'))</div>
|
||||||
}
|
}
|
||||||
<span className="item-meta-info">{repo.size}</span>
|
<span className="item-meta-info">{repo.size}</span>
|
||||||
@@ -251,8 +268,8 @@ class MylibRepoListItem extends React.Component {
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{repo.repo_name && (
|
{repo.repo_name && (
|
||||||
<MylibRepoMenu
|
<MylibRepoMenu
|
||||||
repo={this.props.repo}
|
repo={this.props.repo}
|
||||||
onMenuItemClick={this.onMenuItemClick}
|
onMenuItemClick={this.onMenuItemClick}
|
||||||
onFreezedItem={this.props.onFreezedItem}
|
onFreezedItem={this.props.onFreezedItem}
|
||||||
onUnfreezedItem={this.onUnfreezedItem}
|
onUnfreezedItem={this.onUnfreezedItem}
|
||||||
@@ -275,7 +292,7 @@ class MylibRepoListItem extends React.Component {
|
|||||||
</MediaQuery>
|
</MediaQuery>
|
||||||
{this.state.isShareDialogShow && (
|
{this.state.isShareDialogShow && (
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<ShareDialog
|
<ShareDialog
|
||||||
itemType={'library'}
|
itemType={'library'}
|
||||||
itemName={repo.repo_name}
|
itemName={repo.repo_name}
|
||||||
itemPath={'/'}
|
itemPath={'/'}
|
||||||
@@ -289,26 +306,26 @@ class MylibRepoListItem extends React.Component {
|
|||||||
)}
|
)}
|
||||||
{this.state.isDeleteDialogShow && (
|
{this.state.isDeleteDialogShow && (
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<DeleteRepoDialog
|
<DeleteRepoDialog
|
||||||
repo={repo}
|
repo={repo}
|
||||||
onDeleteRepo={this.onDeleteRepo}
|
onDeleteRepo={this.onDeleteRepo}
|
||||||
toggle={this.onDeleteToggle}
|
toggle={this.onDeleteToggle}
|
||||||
/>
|
/>
|
||||||
</ModalPortal>
|
</ModalPortal>
|
||||||
)}
|
)}
|
||||||
{this.state.isTransferDialogShow && (
|
{this.state.isTransferDialogShow && (
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<TransferDialog
|
<TransferDialog
|
||||||
repoID={repo.repo_id}
|
repoID={repo.repo_id}
|
||||||
itemName={repo.repo_name}
|
itemName={repo.repo_name}
|
||||||
submit={this.onTransferRepo}
|
submit={this.onTransferRepo}
|
||||||
toggleDialog={this.onTransferToggle}
|
toggleDialog={this.onTransferToggle}
|
||||||
/>
|
/>
|
||||||
</ModalPortal>
|
</ModalPortal>
|
||||||
)}
|
)}
|
||||||
{this.state.isHistorySettingDialogShow && (
|
{this.state.isHistorySettingDialogShow && (
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<LibHistorySettingDialog
|
<LibHistorySettingDialog
|
||||||
repoID={repo.repo_id}
|
repoID={repo.repo_id}
|
||||||
itemName={repo.repo_name}
|
itemName={repo.repo_name}
|
||||||
toggleDialog={this.onHistorySettingToggle}
|
toggleDialog={this.onHistorySettingToggle}
|
||||||
@@ -317,7 +334,7 @@ class MylibRepoListItem extends React.Component {
|
|||||||
)}
|
)}
|
||||||
{this.state.isChangePasswordDialogShow && (
|
{this.state.isChangePasswordDialogShow && (
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<ChangeRepoPasswordDialog
|
<ChangeRepoPasswordDialog
|
||||||
repoID={repo.repo_id}
|
repoID={repo.repo_id}
|
||||||
repoName={repo.repo_name}
|
repoName={repo.repo_name}
|
||||||
toggleDialog={this.onChangePasswordToggle}
|
toggleDialog={this.onChangePasswordToggle}
|
||||||
@@ -326,7 +343,7 @@ class MylibRepoListItem extends React.Component {
|
|||||||
)}
|
)}
|
||||||
{this.state.isResetPasswordDialogShow && (
|
{this.state.isResetPasswordDialogShow && (
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<ResetEncryptedRepoPasswordDialog
|
<ResetEncryptedRepoPasswordDialog
|
||||||
repoID={repo.repo_id}
|
repoID={repo.repo_id}
|
||||||
toggleDialog={this.onResetPasswordToggle}
|
toggleDialog={this.onResetPasswordToggle}
|
||||||
/>
|
/>
|
||||||
|
@@ -77,8 +77,9 @@ class MylibRepoListView extends React.Component {
|
|||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th width="4%"></th>
|
||||||
<th width="4%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
<th width="4%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
||||||
<th width="42%"><a className="d-block table-sort-op" href="#" onClick={this.sortByName}>{gettext('Name')} {this.props.sortBy === 'name' && sortIcon}</a></th>
|
<th width="38%"><a className="d-block table-sort-op" href="#" onClick={this.sortByName}>{gettext('Name')} {this.props.sortBy === 'name' && sortIcon}</a></th>
|
||||||
<th width="14%"><span className="sr-only">{gettext('Actions')}</span></th>
|
<th width="14%"><span className="sr-only">{gettext('Actions')}</span></th>
|
||||||
<th width={showStorageBackend ? '15%' : '20%'}>{gettext('Size')}</th>
|
<th width={showStorageBackend ? '15%' : '20%'}>{gettext('Size')}</th>
|
||||||
{showStorageBackend ? <th width="10%">{gettext('Storage backend')}</th> : null}
|
{showStorageBackend ? <th width="10%">{gettext('Storage backend')}</th> : null}
|
||||||
|
@@ -49,8 +49,9 @@ class Content extends Component {
|
|||||||
const desktopThead = (
|
const desktopThead = (
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th width="4%"></th>
|
||||||
<th width="4%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
<th width="4%"><span className="sr-only">{gettext('Library Type')}</span></th>
|
||||||
<th width="38%"><a className="d-block table-sort-op" href="#" onClick={this.sortByName}>{gettext('Name')} {sortByName && sortIcon}</a></th>
|
<th width="34%"><a className="d-block table-sort-op" href="#" onClick={this.sortByName}>{gettext('Name')} {sortByName && sortIcon}</a></th>
|
||||||
<th width="10%"><span className="sr-only">{gettext('Actions')}</span></th>
|
<th width="10%"><span className="sr-only">{gettext('Actions')}</span></th>
|
||||||
<th width="14%">{gettext('Size')}</th>
|
<th width="14%">{gettext('Size')}</th>
|
||||||
<th width="18%"><a className="d-block table-sort-op" href="#" onClick={this.sortByTime}>{gettext('Last Update')} {sortByTime && sortIcon}</a></th>
|
<th width="18%"><a className="d-block table-sort-op" href="#" onClick={this.sortByTime}>{gettext('Last Update')} {sortByTime && sortIcon}</a></th>
|
||||||
@@ -120,6 +121,7 @@ class Item extends Component {
|
|||||||
showOpIcon: false,
|
showOpIcon: false,
|
||||||
unshared: false,
|
unshared: false,
|
||||||
isShowSharedDialog: false,
|
isShowSharedDialog: false,
|
||||||
|
isStarred: this.props.data.starred,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.handleMouseOver = this.handleMouseOver.bind(this);
|
this.handleMouseOver = this.handleMouseOver.bind(this);
|
||||||
@@ -176,6 +178,18 @@ class Item extends Component {
|
|||||||
this.setState({isShowSharedDialog: false});
|
this.setState({isShowSharedDialog: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onStarRepo = () => {
|
||||||
|
if (this.state.isStarred) {
|
||||||
|
seafileAPI.unStarItem(this.props.data.repo_id, '/').then(() => {
|
||||||
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
seafileAPI.starItem(this.props.data.repo_id, '/').then(() => {
|
||||||
|
this.setState({isStarred: !this.state.isStarred});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.unshared) {
|
if (this.state.unshared) {
|
||||||
return null;
|
return null;
|
||||||
@@ -194,6 +208,10 @@ class Item extends Component {
|
|||||||
const desktopItem = (
|
const desktopItem = (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}>
|
<tr onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}>
|
||||||
|
<td className="text-center">
|
||||||
|
{!this.state.isStarred && <i className="far fa-star star-empty cursor-pointer" onClick={this.onStarRepo}></i>}
|
||||||
|
{this.state.isStarred && <i className="fas fa-star cursor-pointer" onClick={this.onStarRepo}></i>}
|
||||||
|
</td>
|
||||||
<td><img src={data.icon_url} title={data.icon_title} alt={data.icon_title} width="24" /></td>
|
<td><img src={data.icon_url} title={data.icon_title} alt={data.icon_title} width="24" /></td>
|
||||||
<td><Link to={`${siteRoot}library/${data.repo_id}/${data.repo_name}/`}>{data.repo_name}</Link></td>
|
<td><Link to={`${siteRoot}library/${data.repo_id}/${data.repo_name}/`}>{data.repo_name}</Link></td>
|
||||||
<td>
|
<td>
|
||||||
|
@@ -94,7 +94,12 @@ class TableBody extends Component {
|
|||||||
|
|
||||||
let listFilesActivities = this.state.items.map(function(item, index) {
|
let listFilesActivities = this.state.items.map(function(item, index) {
|
||||||
|
|
||||||
item.file_icon_url = item.is_dir ? Utils.getFolderIconUrl(false) : Utils.getFileIconUrl(item.obj_name);
|
if (item.path === '/') {
|
||||||
|
item.item_icon_url = Utils.getDefaultLibIconUrl(false);
|
||||||
|
} else {
|
||||||
|
item.item_icon_url = item.is_dir ? Utils.getFolderIconUrl(false) : Utils.getFileIconUrl(item.obj_name);
|
||||||
|
}
|
||||||
|
|
||||||
item.encoded_path = Utils.encodePath(item.path);
|
item.encoded_path = Utils.encodePath(item.path);
|
||||||
|
|
||||||
item.thumbnail_url = item.encoded_thumbnail_src ? `${siteRoot}${item.encoded_thumbnail_src}` : '';
|
item.thumbnail_url = item.encoded_thumbnail_src ? `${siteRoot}${item.encoded_thumbnail_src}` : '';
|
||||||
@@ -165,7 +170,7 @@ class Item extends Component {
|
|||||||
{
|
{
|
||||||
data.thumbnail_url ?
|
data.thumbnail_url ?
|
||||||
<img className="thumbnail" src={data.thumbnail_url} alt="" /> :
|
<img className="thumbnail" src={data.thumbnail_url} alt="" /> :
|
||||||
<img src={data.file_icon_url} alt={gettext('icon')} width="24" />
|
<img src={data.item_icon_url} alt={gettext('icon')} width="24" />
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -188,7 +193,7 @@ class Item extends Component {
|
|||||||
{
|
{
|
||||||
data.thumbnail_url ?
|
data.thumbnail_url ?
|
||||||
<img className="thumbnail" src={data.thumbnail_url} alt="" /> :
|
<img className="thumbnail" src={data.thumbnail_url} alt="" /> :
|
||||||
<img src={data.file_icon_url} alt={gettext('icon')} width="24" />
|
<img src={data.item_icon_url} alt={gettext('icon')} width="24" />
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
@@ -229,6 +229,13 @@ export const Utils = {
|
|||||||
navigator.userAgent.indexOf('Chrome') > -1;
|
navigator.userAgent.indexOf('Chrome') > -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getDefaultLibIconUrl: function(isBig) {
|
||||||
|
let size = Utils.isHiDPI() ? 48 : 24;
|
||||||
|
size = isBig ? 256 : size;
|
||||||
|
let icon_name = 'lib.png';
|
||||||
|
return mediaUrl + 'img/lib/' + size + '/' + icon_name;
|
||||||
|
},
|
||||||
|
|
||||||
getLibIconUrl: function(repo, isBig) {
|
getLibIconUrl: function(repo, isBig) {
|
||||||
let permission = repo.permission || repo.share_permission; //Compatible with regular repo and repo shared
|
let permission = repo.permission || repo.share_permission; //Compatible with regular repo and repo shared
|
||||||
let size = Utils.isHiDPI() ? 48 : 24;
|
let size = Utils.isHiDPI() ? 48 : 24;
|
||||||
|
@@ -29,6 +29,7 @@ from seahub.share.signals import share_repo_to_group_successful
|
|||||||
from seahub.share.utils import is_repo_admin, check_group_share_in_permission, \
|
from seahub.share.utils import is_repo_admin, check_group_share_in_permission, \
|
||||||
share_dir_to_group
|
share_dir_to_group
|
||||||
from seahub.constants import PERMISSION_READ
|
from seahub.constants import PERMISSION_READ
|
||||||
|
from seahub.base.models import UserStarredFiles
|
||||||
from seahub.base.templatetags.seahub_tags import email2nickname, \
|
from seahub.base.templatetags.seahub_tags import email2nickname, \
|
||||||
email2contact_email
|
email2contact_email
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ class GroupLibraries(APIView):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# only group member can get group libraries
|
# only group member can get group libraries
|
||||||
|
username = request.user.username
|
||||||
if not is_group_member(group_id, request.user.username):
|
if not is_group_member(group_id, request.user.username):
|
||||||
error_msg = 'Permission denied.'
|
error_msg = 'Permission denied.'
|
||||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||||
@@ -113,6 +115,13 @@ class GroupLibraries(APIView):
|
|||||||
else:
|
else:
|
||||||
contact_email_dict[email] = email2contact_email(email)
|
contact_email_dict[email] = email2contact_email(email)
|
||||||
|
|
||||||
|
try:
|
||||||
|
starred_repos = UserStarredFiles.objects.get_starred_repos_by_user(username)
|
||||||
|
starred_repo_id_list = [item.repo_id for item in starred_repos]
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
starred_repo_id_list = []
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for group_repo in group_repos:
|
for group_repo in group_repos:
|
||||||
group_repo_info = get_group_repo_info(request, group_repo)
|
group_repo_info = get_group_repo_info(request, group_repo)
|
||||||
@@ -127,6 +136,8 @@ class GroupLibraries(APIView):
|
|||||||
group_repo_info['modifier_name'] = name_dict.get(modifier, '')
|
group_repo_info['modifier_name'] = name_dict.get(modifier, '')
|
||||||
group_repo_info['modifier_contact_email'] = contact_email_dict.get(modifier, '')
|
group_repo_info['modifier_contact_email'] = contact_email_dict.get(modifier, '')
|
||||||
|
|
||||||
|
group_repo_info['starred'] = group_repo.id in starred_repo_id_list
|
||||||
|
|
||||||
result.append(group_repo_info)
|
result.append(group_repo_info)
|
||||||
|
|
||||||
return Response(result)
|
return Response(result)
|
||||||
|
@@ -28,6 +28,7 @@ from seahub.group.utils import validate_group_name, check_group_name_conflict, \
|
|||||||
is_group_member, is_group_admin, is_group_owner, is_group_admin_or_owner, \
|
is_group_member, is_group_admin, is_group_owner, is_group_admin_or_owner, \
|
||||||
group_id_to_name
|
group_id_to_name
|
||||||
from seahub.group.views import remove_group_common
|
from seahub.group.views import remove_group_common
|
||||||
|
from seahub.base.models import UserStarredFiles
|
||||||
from seahub.base.templatetags.seahub_tags import email2nickname, \
|
from seahub.base.templatetags.seahub_tags import email2nickname, \
|
||||||
translate_seahub_time, email2contact_email
|
translate_seahub_time, email2contact_email
|
||||||
from seahub.views.modules import is_wiki_mod_enabled_for_group, \
|
from seahub.views.modules import is_wiki_mod_enabled_for_group, \
|
||||||
@@ -111,6 +112,13 @@ class Groups(APIView):
|
|||||||
gids = [g.id for g in user_groups]
|
gids = [g.id for g in user_groups]
|
||||||
admin_info = ExtraGroupsSharePermission.objects.batch_get_repos_with_admin_permission(gids)
|
admin_info = ExtraGroupsSharePermission.objects.batch_get_repos_with_admin_permission(gids)
|
||||||
|
|
||||||
|
try:
|
||||||
|
starred_repos = UserStarredFiles.objects.get_starred_repos_by_user(username)
|
||||||
|
starred_repo_id_list = [item.repo_id for item in starred_repos]
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
starred_repo_id_list = []
|
||||||
|
|
||||||
for g in user_groups:
|
for g in user_groups:
|
||||||
group_info = get_group_info(request, g.id, avatar_size)
|
group_info = get_group_info(request, g.id, avatar_size)
|
||||||
|
|
||||||
@@ -170,7 +178,8 @@ class Groups(APIView):
|
|||||||
"owner_email": repo_owner,
|
"owner_email": repo_owner,
|
||||||
"owner_name": name_dict.get(repo_owner, ''),
|
"owner_name": name_dict.get(repo_owner, ''),
|
||||||
"owner_contact_email": contact_email_dict.get(repo_owner, ''),
|
"owner_contact_email": contact_email_dict.get(repo_owner, ''),
|
||||||
"is_admin": (r.id, g.id) in admin_info
|
"is_admin": (r.id, g.id) in admin_info,
|
||||||
|
"starred": r.repo_id in starred_repo_id_list,
|
||||||
}
|
}
|
||||||
repos.append(repo)
|
repos.append(repo)
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@ from seahub.api2.utils import api_error
|
|||||||
|
|
||||||
from seahub.api2.endpoints.group_owned_libraries import get_group_id_by_repo_owner
|
from seahub.api2.endpoints.group_owned_libraries import get_group_id_by_repo_owner
|
||||||
|
|
||||||
|
from seahub.base.models import UserStarredFiles
|
||||||
from seahub.base.templatetags.seahub_tags import email2nickname, \
|
from seahub.base.templatetags.seahub_tags import email2nickname, \
|
||||||
email2contact_email
|
email2contact_email
|
||||||
from seahub.signals import repo_deleted
|
from seahub.signals import repo_deleted
|
||||||
@@ -71,8 +72,16 @@ class ReposView(APIView):
|
|||||||
if is_org_context(request):
|
if is_org_context(request):
|
||||||
org_id = request.user.org.org_id
|
org_id = request.user.org.org_id
|
||||||
|
|
||||||
|
try:
|
||||||
|
starred_repos = UserStarredFiles.objects.get_starred_repos_by_user(email)
|
||||||
|
starred_repo_id_list = [item.repo_id for item in starred_repos]
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
starred_repo_id_list = []
|
||||||
|
|
||||||
repo_info_list = []
|
repo_info_list = []
|
||||||
if filter_by['mine']:
|
if filter_by['mine']:
|
||||||
|
|
||||||
if org_id:
|
if org_id:
|
||||||
owned_repos = seafile_api.get_org_owned_repo_list(org_id,
|
owned_repos = seafile_api.get_org_owned_repo_list(org_id,
|
||||||
email, ret_corrupted=True)
|
email, ret_corrupted=True)
|
||||||
@@ -109,6 +118,7 @@ class ReposView(APIView):
|
|||||||
"size": r.size,
|
"size": r.size,
|
||||||
"encrypted": r.encrypted,
|
"encrypted": r.encrypted,
|
||||||
"permission": 'rw', # Always have read-write permission to owned repo
|
"permission": 'rw', # Always have read-write permission to owned repo
|
||||||
|
"starred": r.repo_id in starred_repo_id_list,
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_pro_version() and ENABLE_STORAGE_CLASSES:
|
if is_pro_version() and ENABLE_STORAGE_CLASSES:
|
||||||
@@ -169,6 +179,7 @@ class ReposView(APIView):
|
|||||||
"size": r.size,
|
"size": r.size,
|
||||||
"encrypted": r.encrypted,
|
"encrypted": r.encrypted,
|
||||||
"permission": r.permission,
|
"permission": r.permission,
|
||||||
|
"starred": r.repo_id in starred_repo_id_list,
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.repo_id in repos_with_admin_share_to:
|
if r.repo_id in repos_with_admin_share_to:
|
||||||
@@ -210,6 +221,7 @@ class ReposView(APIView):
|
|||||||
"size": r.size,
|
"size": r.size,
|
||||||
"encrypted": r.encrypted,
|
"encrypted": r.encrypted,
|
||||||
"permission": r.permission,
|
"permission": r.permission,
|
||||||
|
"starred": r.repo_id in starred_repo_id_list,
|
||||||
}
|
}
|
||||||
repo_info_list.append(repo_info)
|
repo_info_list.append(repo_info)
|
||||||
|
|
||||||
@@ -252,6 +264,7 @@ class ReposView(APIView):
|
|||||||
"size": r.size,
|
"size": r.size,
|
||||||
"encrypted": r.encrypted,
|
"encrypted": r.encrypted,
|
||||||
"permission": r.permission,
|
"permission": r.permission,
|
||||||
|
"starred": r.repo_id in starred_repo_id_list,
|
||||||
}
|
}
|
||||||
repo_info_list.append(repo_info)
|
repo_info_list.append(repo_info)
|
||||||
|
|
||||||
|
@@ -57,9 +57,9 @@ class FileDiscuss(models.Model):
|
|||||||
|
|
||||||
class FileCommentManager(models.Manager):
|
class FileCommentManager(models.Manager):
|
||||||
def add(self, repo_id, parent_path, item_name, author, comment, detail=''):
|
def add(self, repo_id, parent_path, item_name, author, comment, detail=''):
|
||||||
fileuuidmap = FileUUIDMap.objects.get_or_create_fileuuidmap(repo_id,
|
fileuuidmap = FileUUIDMap.objects.get_or_create_fileuuidmap(repo_id,
|
||||||
parent_path,
|
parent_path,
|
||||||
item_name,
|
item_name,
|
||||||
False)
|
False)
|
||||||
c = self.model(uuid=fileuuidmap, author=author, comment=comment, detail=detail)
|
c = self.model(uuid=fileuuidmap, author=author, comment=comment, detail=detail)
|
||||||
c.save(using=self._db)
|
c.save(using=self._db)
|
||||||
@@ -75,7 +75,7 @@ class FileCommentManager(models.Manager):
|
|||||||
def get_by_file_path(self, repo_id, file_path):
|
def get_by_file_path(self, repo_id, file_path):
|
||||||
parent_path = os.path.dirname(file_path)
|
parent_path = os.path.dirname(file_path)
|
||||||
item_name = os.path.basename(file_path)
|
item_name = os.path.basename(file_path)
|
||||||
uuid = FileUUIDMap.objects.get_fileuuidmap_by_path(repo_id, parent_path,
|
uuid = FileUUIDMap.objects.get_fileuuidmap_by_path(repo_id, parent_path,
|
||||||
item_name, False)
|
item_name, False)
|
||||||
|
|
||||||
objs = super(FileCommentManager, self).filter(
|
objs = super(FileCommentManager, self).filter(
|
||||||
@@ -84,7 +84,7 @@ class FileCommentManager(models.Manager):
|
|||||||
return objs
|
return objs
|
||||||
|
|
||||||
def get_by_parent_path(self, repo_id, parent_path):
|
def get_by_parent_path(self, repo_id, parent_path):
|
||||||
uuids = FileUUIDMap.objects.get_fileuuidmaps_by_parent_path(repo_id,
|
uuids = FileUUIDMap.objects.get_fileuuidmaps_by_parent_path(repo_id,
|
||||||
parent_path)
|
parent_path)
|
||||||
objs = super(FileCommentManager, self).filter(uuid__in=uuids)
|
objs = super(FileCommentManager, self).filter(uuid__in=uuids)
|
||||||
return objs
|
return objs
|
||||||
@@ -149,6 +149,11 @@ class StarredFile(object):
|
|||||||
|
|
||||||
class UserStarredFilesManager(models.Manager):
|
class UserStarredFilesManager(models.Manager):
|
||||||
|
|
||||||
|
def get_starred_repos_by_user(self, email):
|
||||||
|
|
||||||
|
starred_repos = UserStarredFiles.objects.filter(email=email, path='/')
|
||||||
|
return starred_repos
|
||||||
|
|
||||||
def get_starred_item(self, email, repo_id, path):
|
def get_starred_item(self, email, repo_id, path):
|
||||||
|
|
||||||
path_list = [normalize_file_path(path), normalize_dir_path(path)]
|
path_list = [normalize_file_path(path), normalize_dir_path(path)]
|
||||||
|
Reference in New Issue
Block a user