1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-14 14:21:23 +00:00

For mobile (#6523)

* ['notice' popover, 'all notice' dialog] fixup for mobile

* ['Files' page] fixed library icon size for mobile

* ['settings' page] fixup for 'Email notification'

* ['my libs'] fixed 'star/unstar', 'share', 'delete'

* ['deleted repos' dialog] modified column width of the table for mobile

* ['share' dialog] modified 'link details' panel for mobile

* [side panel resizer] removed it for mobile

* [group/department, shared with all] fixed the operation menu for mobile

* ['dir view'] don't offer 'repo history' page for mobile

* ['help'] fixup for page with large images, for mobile

- fixup for http://127.0.0.1:8000/help/drive_client_2.0_for_windows_10/
  (in mobile, the content of it overflowed to the right, and was cut off)

* ['file view'] removed 'history' page for mobile

* ['markdown file view'] removed 'history' page for small screen, mobile

* ['dir view'] added a gray layer to close the 'file/folder tree' panel in mobile

* ['dir view'] fixup for the 'path' bar in mobile

* ['dir view', 'shared dir view'] don't display the 'tag list' in root for mobile
This commit is contained in:
llj
2024-08-12 12:14:03 +08:00
committed by GitHub
parent 980d0922eb
commit 172ab0d2ad
24 changed files with 106 additions and 81 deletions

View File

@@ -6,12 +6,18 @@
position: absolute;
background: #fff;
width: 320px;
right: -10px;
right: -16px;
top: -1px;
border-radius: 3px;
box-shadow: 0 0 5px #ccc;
}
@media (min-width: 768px) {
.notification-container {
right: -10px;
}
}
.notification-container .notification-header {
display: flex;
align-items: center;

View File

@@ -63,10 +63,10 @@ class MyLibsDeleted extends Component {
<table>
<thead>
<tr>
<th width="8%">{/* img*/}</th>
<th width="52%">{gettext('Name')}</th>
<th width="30%">{gettext('Deleted Time')}</th>
<th width="10%"></th>
<th width="10%">{/* img*/}</th>
<th width="50%">{gettext('Name')}</th>
<th width="28%">{gettext('Deleted Time')}</th>
<th width="12%"></th>
</tr>
</thead>
<tbody>

View File

@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { gettext, siteRoot } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import TreeSection from '../tree-section';
import TrashDialog from '../dialog/trash-dialog';
@@ -26,6 +27,7 @@ const DirOthers = ({ userPerm, repoID, currentRepoInfo }) => {
</div>
</div>
}
{Utils.isDesktop() &&
<div className='tree-node-inner text-nowrap' title={gettext('History')} onClick={() => location.href = historyUrl}>
<div className="tree-node-text">{gettext('History')}</div>
<div className="left-icon">
@@ -34,6 +36,7 @@ const DirOthers = ({ userPerm, repoID, currentRepoInfo }) => {
</div>
</div>
</div>
}
{showTrashDialog && (
<TrashDialog
repoID={repoID}

View File

@@ -244,13 +244,6 @@ class FileToolbar extends React.Component {
{gettext('Share')}
</DropdownItem>
)}
{filePerm == 'rw' && (
<DropdownItem>
<a href={`${siteRoot}repo/file_revisions/${repoID}/?p=${encodeURIComponent(filePath)}&referer=${encodeURIComponent(location.href)}`} className="text-inherit">
{gettext('History')}
</a>
</DropdownItem>
)}
{canDownloadFile && (
<DropdownItem>
<a href="?dl=1" className="text-inherit">

View File

@@ -1,16 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../utils/constants';
function LibsMobileThead() {
return (
<thead>
<tr>
<th width="12%"><span className="sr-only">{gettext('Library Type')}</span></th>
<th width="80%"></th>
<th width="8%"><span className="sr-only">{gettext('Actions')}</span></th>
</tr>
</thead>
);
const propTypes = {
inAllLibs: PropTypes.bool // for 'Libraries' in 'Files' page
};
class LibsMobileThead extends React.Component {
render() {
const { inAllLibs = false } = this.props;
const widthList = inAllLibs ? ['14%', '78%', '8%'] : ['12%', '80%', '8%'];
return (
<thead>
<tr>
<th width={widthList[0]}><span className="sr-only">{gettext('Library Type')}</span></th>
<th width={widthList[1]}></th>
<th width={widthList[2]}><span className="sr-only">{gettext('Actions')}</span></th>
</tr>
</thead>
);
}
}
LibsMobileThead.propTypes = propTypes;
export default LibsMobileThead;

View File

@@ -193,7 +193,7 @@ class LinkDetails extends React.Component {
<>
<dt className="text-secondary font-weight-normal">{gettext('Password')}</dt>
<dd>
<InputGroup className="w-50">
<InputGroup className="share-link-details-item">
{this.state.storedPasswordVisible ?
<Input type="text" readOnly={true} value={sharedLinkInfo.password} /> :
<Input type="text" readOnly={true} value={'***************'} />
@@ -233,7 +233,7 @@ class LinkDetails extends React.Component {
</div>
</div>
) : (
<InputGroup className="w-50">
<InputGroup className="share-link-details-item">
<Input type="text" readOnly={true} value={moment(sharedLinkInfo.expire_date).format('YYYY-MM-DD HH:mm:ss')} />
<InputGroupAddon addonType="append">
<Button
@@ -253,7 +253,7 @@ class LinkDetails extends React.Component {
<>
<dt className="text-secondary font-weight-normal">{gettext('Permission')}</dt>
<dd>
<div className="w-50">
<div className="share-link-details-item">
<SelectEditor
isTextMode={false}
isEditIconShow={false}
@@ -268,8 +268,8 @@ class LinkDetails extends React.Component {
)}
<>
<dt className="text-secondary font-weight-normal">{gettext('Scope')}</dt>
<dd className="d-flex align-items-center">
<div className="w-50 mr-2">
<dd className="d-flex align-items-center flex-wrap">
<div className="share-link-details-item mr-2">
<ShareLinkScopeEditor
isTextMode={false}
isEditIconShow={false}

View File

@@ -249,18 +249,15 @@ class SharedRepoListItem extends React.Component {
this.setState({ isHistorySettingDialogShow: !this.state.isHistorySettingDialogShow });
};
onItemShare = (e) => {
e.preventDefault();
onItemShare = () => {
this.setState({ isShowSharedDialog: true });
};
onItemUnshare = (e) => {
e.preventDefault();
onItemUnshare = () => {
this.props.onItemUnshare(this.props.repo);
};
onItemDeleteToggle = (e) => {
e.preventDefault();
onItemDeleteToggle = () => {
this.setState({ isDeleteDialogShow: !this.state.isDeleteDialogShow });
};
@@ -454,7 +451,7 @@ class SharedRepoListItem extends React.Component {
operations.push('Unshare');
}
} else {
operations = this.generatorOperations();
operations = this.generatorOperations().filter(item => item != 'Divider');
if (this.isDeparementOnwerGroupMember) {
operations.unshift('Unshare');
operations.unshift('Share');
@@ -499,9 +496,9 @@ class SharedRepoListItem extends React.Component {
} else {
operations = this.generatorOperations();
}
const shareOperation = <a href="#" className="op-icon sf3-font-share sf3-font" title={gettext('Share')} role="button" aria-label={gettext('Share')} onClick={this.onItemShare}></a>;
const unshareOperation = <a href="#" className="op-icon sf2-icon-x3" title={gettext('Unshare')} role="button" aria-label={gettext('Unshare')} onClick={this.onItemUnshare}></a>;
const deleteOperation = <a href="#" className="op-icon sf3-font-delete1 sf3-font" title={gettext('Delete')} role="button" aria-label={gettext('Delete')} onClick={this.onItemDeleteToggle}></a>;
const shareOperation = <i className="op-icon sf3-font-share sf3-font" title={gettext('Share')} role="button" aria-label={gettext('Share')} onClick={this.onItemShare}></i>;
const unshareOperation = <i className="op-icon sf2-icon-x3" title={gettext('Unshare')} role="button" aria-label={gettext('Unshare')} onClick={this.onItemUnshare}></i>;
const deleteOperation = <i className="op-icon sf3-font-delete1 sf3-font" title={gettext('Delete')} role="button" aria-label={gettext('Delete')} onClick={this.onItemDeleteToggle}></i>;
if (this.isDeparementOnwerGroupMember) {
const advancedOperations = this.getAdvancedOperations();

View File

@@ -22,6 +22,7 @@ const propTypes = {
hasNextPage: PropTypes.bool,
onMonitorRepo: PropTypes.func,
theadHidden: PropTypes.bool,
inAllLibs: PropTypes.bool,
};
class SharedRepoListView extends React.Component {
@@ -139,9 +140,10 @@ class SharedRepoListView extends React.Component {
};
renderMobileUI = () => {
const { inAllLibs = false } = this.props;
return (
<table className="table-thead-hidden">
<LibsMobileThead />
<LibsMobileThead inAllLibs={inAllLibs} />
<tbody>
{this.renderRepoListView()}
</tbody>

View File

@@ -289,7 +289,14 @@ class DirOperationToolbar extends React.Component {
} else {
content = (
<Dropdown isOpen={this.state.isMobileOpMenuOpen} toggle={this.toggleMobileOpMenu}>
<DropdownToggle tag="span" className="sf2-icon-plus mobile-toolbar-icon" />
<DropdownToggle
tag="div"
role="button"
className="path-item"
>
{this.props.children}
<i className="sf3-font-down sf3-font ml-1 path-item-dropdown-toggle"></i>
</DropdownToggle>
<DropdownMenu>
{canUpload && (
<DropdownItem onClick={this.onUploadFile}>{gettext('Upload')}</DropdownItem>

View File

@@ -66,34 +66,30 @@ class EmailNotice extends React.Component {
return (
<div className="setting-item" id="email-notice">
<h3 className="setting-item-heading">{gettext('Email Notification')}</h3>
<h6 className="">{gettext('Notifications of file changes')}</h6>
<p className="mb-1">{gettext('The list of added, deleted and modified files will be sent to your mailbox.')}</p>
<form method="post" action="" id="set-email-notice-interval-form" onSubmit={this.formSubmit}>
<h4 className="h6">{gettext('Notifications of file changes')}</h4>
<p className="mb-1">{gettext('The list of added, deleted and modified files will be sent to your mailbox.')}</p>
{this.fileUpdatesOptions.map((item, index) => {
return (
<React.Fragment key={`file-updates-${index}`}>
<input type="radio" name="interval" value={item.interval} className="align-middle" id={`file-updates-interval-option${index + 1}`} checked={fileUpdatesEmailInterval == item.interval} onChange={this.inputFileUpdatesEmailIntervalChange} />
<label className="align-middle m-0 ml-2" htmlFor={`interval-option${index + 1}`}>{item.text}</label>
<br />
</React.Fragment>
<div className="d-flex" key={`file-updates-${index}`}>
<input type="radio" name="file-interval" value={item.interval} id={`file-updates-interval-option-${index + 1}`} checked={fileUpdatesEmailInterval == item.interval} onChange={this.inputFileUpdatesEmailIntervalChange} />
<label className="m-0 ml-2" htmlFor={`file-updates-interval-option-${index + 1}`}>{item.text}</label>
</div>
);
})}
</form>
<h6 className="mt-4">{gettext('Notifications of collaboration')}</h6>
<p className="mb-1">{gettext('Whether the notifications of collaboration such as sharing library or joining group should be sent to your mailbox.')}</p>
<form method="post" action="" id="set-email-notice-interval-form" onSubmit={this.formSubmit}>
<h4 className="mt-3 h6">{gettext('Notifications of collaboration')}</h4>
<p className="mb-1">{gettext('Whether the notifications of collaboration such as sharing library or joining group should be sent to your mailbox.')}</p>
{this.collaborateOptions.map((item, index) => {
return (
<React.Fragment key={`collaborate-${index}`}>
<input type="radio" name="interval" value={item.interval} className="align-middle" id={`collaborate-interval-option${index + 1}`} checked={collaborateEmailInterval == item.interval} onChange={this.inputCollaborateEmailIntervalChange} />
<label className="align-middle m-0 ml-2" htmlFor={`interval-option${index + 1}`}>{item.text}</label>
<br />
</React.Fragment>
<div className="d-flex align-items-start" key={`collaborate-${index}`}>
<input type="radio" name="col-interval" value={item.interval} className="mt-1" id={`collaborate-interval-option-${index + 1}`} checked={collaborateEmailInterval == item.interval} onChange={this.inputCollaborateEmailIntervalChange} />
<label className="m-0 ml-2" htmlFor={`collaborate-interval-option-${index + 1}`}>{item.text}</label>
</div>
);
})}
<button type="submit" className="btn btn-outline-primary mt-4">{gettext('Submit')}</button>
</form>
<button type="submit" className="btn btn-outline-primary mt-2" onClick={this.formSubmit}>{gettext('Submit')}</button>
</div>
);
}