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

feat: adjust diff viewer to fit mobile

This commit is contained in:
liuhongbo 2024-05-15 11:45:16 +08:00 committed by 杨顺强
parent eea00b3e03
commit 0015365473
4 changed files with 105 additions and 58 deletions

View File

@ -1,11 +1,12 @@
import moment from 'moment'; import moment from 'moment';
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem} from 'reactstrap'; import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem, Modal, ModalBody } from 'reactstrap';
import classnames from 'classnames'; import classnames from 'classnames';
import { gettext, filePath } from '../../../utils/constants'; import { gettext, filePath } from '../../../utils/constants';
import URLDecorator from '../../../utils/url-decorator'; import URLDecorator from '../../../utils/url-decorator';
import Rename from '../../../components/rename'; import Rename from '../../../components/rename';
import { isMobile } from '../../../utils/utils';
import '../../../css/history-record-item.css'; import '../../../css/history-record-item.css';
@ -20,6 +21,7 @@ class HistoryVersion extends React.Component {
isMenuShow: false, isMenuShow: false,
isRenameShow: false, isRenameShow: false,
}; };
this.isMobile = isMobile;
} }
onMouseEnter = () => { onMouseEnter = () => {
@ -61,7 +63,8 @@ class HistoryVersion extends React.Component {
}; };
toggleRename = () => { toggleRename = () => {
this.setState({isRenameShow: !this.state.isRenameShow}); this.isMobile && this.setState({ isMenuShow: false });
this.setState({ isRenameShow: !this.state.isRenameShow });
}; };
onRenameConfirm = (newName) => { onRenameConfirm = (newName) => {
@ -108,8 +111,8 @@ class HistoryVersion extends React.Component {
{path[2] > 0 && (<div className="daily-history-detail-no-more"></div>)} {path[2] > 0 && (<div className="daily-history-detail-no-more"></div>)}
<div className="history-info"> <div className="history-info">
{this.state.isRenameShow ? {this.state.isRenameShow ?
<Rename name={name} onRenameConfirm={this.onRenameConfirm} onRenameCancel={this.onRenameCancel}/> <Rename name={name} onRenameConfirm={this.onRenameConfirm} onRenameCancel={this.onRenameCancel} />
:<div className="name">{name}</div> : <div className="name">{name}</div>
} }
<div className="time">{moment(ctime).format('YYYY-MM-DD HH:mm')}</div> <div className="time">{moment(ctime).format('YYYY-MM-DD HH:mm')}</div>
<div className="owner"> <div className="owner">
@ -118,22 +121,56 @@ class HistoryVersion extends React.Component {
</div> </div>
</div> </div>
<div className="history-operation"> <div className="history-operation">
<Dropdown isOpen={this.state.isMenuShow} toggle={this.onToggleClick}> {this.isMobile
<DropdownToggle ? (
tag='a' <>
className={`fas fa-ellipsis-v ${(this.state.isShowOperationIcon || isHighlightItem) ? '' : 'invisible'}`} <a
data-toggle="dropdown" className={`fas fa-ellipsis-v ${(this.state.isShowOperationIcon || isHighlightItem) ? '' : 'invisible'}`}
aria-expanded={this.state.isMenuShow} title={gettext('More operations')}
title={gettext('More operations')} aria-label={gettext('More operations')}
aria-label={gettext('More operations')} aria-expanded={this.state.isMenuShow}
/> onClick={this.onToggleClick}
<DropdownMenu> />
{/* {(this.props.index !== 0) && <DropdownItem onClick={this.onItemRestore}>{gettext('Restore')}</DropdownItem>} */} <Modal
<DropdownItem tag='a' href={url} onClick={this.onItemDownLoad}>{gettext('Download')}</DropdownItem> className='sdoc-mobile-history-options-modal'
{(path[0] !== 0 && path[1] !== 0 && path[2] !== 0) && <DropdownItem onClick={this.onItemCopy}>{gettext('Copy')}</DropdownItem>} isOpen={this.state.isMenuShow}
<DropdownItem onClick={this.toggleRename}>{gettext('Rename')}</DropdownItem> toggle={this.onToggleClick}
</DropdownMenu> >
</Dropdown> <ModalBody className='sdoc-operation-mobile-modal-body'>
<div className='option-item'>
<i className='mr-3 sf3-font sf3-font-download'></i>
<a href={url} onClick={this.onItemDownLoad}>{gettext('Download')}</a>
</div>
{(path[0] !== 0 && path[1] !== 0 && path[2] !== 0) && (
<div className='option-item'>
<i className='mr-3 sf3-font sf3-font-copy'></i>
<span href={url} onClick={this.onItemCopy}>{gettext('Copy')}</span>
</div>
)}
<div className='option-item' onClick={this.toggleRename}>
<i className='mr-3 sf3-font sf3-font-rename'></i>
<span>{gettext('Rename')}</span>
</div>
</ModalBody>
</Modal>
</>
)
: (<Dropdown isOpen={this.state.isMenuShow} toggle={this.onToggleClick}>
<DropdownToggle
tag='a'
className={`fas fa-ellipsis-v ${(this.state.isShowOperationIcon || isHighlightItem) ? '' : 'invisible'}`}
data-toggle="dropdown"
aria-expanded={this.state.isMenuShow}
title={gettext('More operations')}
aria-label={gettext('More operations')}
/>
<DropdownMenu>
{/* {(this.props.index !== 0) && <DropdownItem onClick={this.onItemRestore}>{gettext('Restore')}</DropdownItem>} */}
<DropdownItem tag='a' href={url} onClick={this.onItemDownLoad}>{gettext('Download')}</DropdownItem>
{(path[0] !== 0 && path[1] !== 0 && path[2] !== 0) && <DropdownItem onClick={this.onItemCopy}>{gettext('Copy')}</DropdownItem>}
<DropdownItem onClick={this.toggleRename}>{gettext('Rename')}</DropdownItem>
</DropdownMenu>
</Dropdown>)}
</div> </div>
</li> </li>
); );

View File

@ -26,6 +26,7 @@
.sdoc-file-history .sdoc-file-history-header .sdoc-file-history-header-right { .sdoc-file-history .sdoc-file-history-header .sdoc-file-history-header-right {
height: 100%; height: 100%;
min-width: 100px; min-width: 100px;
align-items: center;
} }
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-container { .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-container {
@ -40,6 +41,11 @@
width: 1px; width: 1px;
} }
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-switch {
display: flex;
align-items: center;
}
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-last, .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-last,
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-next, .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-next,
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-switch { .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-switch {
@ -47,6 +53,11 @@
height: 100%; height: 100%;
} }
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-switch {
padding: 0;
margin-left: 8px;
}
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-last .fas, .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-last .fas,
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-next .fas { .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-next .fas {
color: #000; color: #000;
@ -54,20 +65,28 @@
} }
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-last:hover, .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-last:hover,
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-next:hover, .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-next:hover {
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-switch:hover {
cursor: pointer; cursor: pointer;
opacity: .75; opacity: .75;
background-color: #F5F5F5; background-color: #F5F5F5;
} }
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-last:hover .fas, .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-last:hover .fas,
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-next:hover .fas, .sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-next:hover .fas {
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-switch:hover {
opacity: .75; opacity: .75;
} }
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-switch .sf3-font-history:hover {
cursor: pointer;
color: #000;
}
.sdoc-file-history .sdoc-file-history-header .sdoc-file-changes-switch .sf3-font-history {
font-size: 18px;
color: #666;
}
.sdoc-file-history .sdoc-file-history-content { .sdoc-file-history .sdoc-file-history-content {
height: 100%; height: 100%;
width: 100%; width: 100%;
@ -209,6 +228,22 @@
color: #ff8000; color: #ff8000;
} }
/* mobile options modal */
.sdoc-mobile-history-options-modal {
margin: 0;
transition: none;
transform: translateY(calc(100vh - 100%)) !important;
}
.sdoc-mobile-history-options-modal .sdoc-operation-mobile-modal-body .option-item {
padding: 10px 5px;
}
.sdoc-mobile-history-options-modal .sdoc-operation-mobile-modal-body .option-item a,
.sdoc-mobile-history-options-modal .sdoc-operation-mobile-modal-body .option-item a:hover {
color: #212529;
}
.sdoc-file-history-versions .history-list-item .history-operation:hover { .sdoc-file-history-versions .history-list-item .history-operation:hover {
cursor: pointer; cursor: pointer;
} }

View File

@ -3,6 +3,7 @@ import ReactDom from 'react-dom';
import { UncontrolledTooltip } from 'reactstrap'; import { UncontrolledTooltip } from 'reactstrap';
import classnames from 'classnames'; import classnames from 'classnames';
import { DiffViewer } from '@seafile/sdoc-editor'; import { DiffViewer } from '@seafile/sdoc-editor';
import moment from 'moment';
import { seafileAPI } from '../../../utils/seafile-api'; import { seafileAPI } from '../../../utils/seafile-api';
import { PER_PAGE, gettext, historyRepoID } from '../../../utils/constants'; import { PER_PAGE, gettext, historyRepoID } from '../../../utils/constants';
import Loading from '../../../components/loading'; import Loading from '../../../components/loading';
@ -10,11 +11,10 @@ import GoBack from '../../../components/common/go-back';
import SidePanel from './side-panel'; import SidePanel from './side-panel';
import { Utils, isMobile } from '../../../utils/utils'; import { Utils, isMobile } from '../../../utils/utils';
import toaster from '../../../components/toast'; import toaster from '../../../components/toast';
import { getCurrentAndLastVersion } from './helper';
import '../../../css/layout.css'; import '../../../css/layout.css';
import './index.css'; import './index.css';
import moment from 'moment';
import { getCurrentAndLastVersion, getLastVersion } from './helper';
const { serviceURL, avatarURL, siteRoot } = window.app.config; const { serviceURL, avatarURL, siteRoot } = window.app.config;
const { username, name } = window.app.pageOptions; const { username, name } = window.app.pageOptions;
@ -124,7 +124,6 @@ class SdocFileHistory extends React.Component {
onSelectHistoryVersion = (currentVersion, lastVersion) => { onSelectHistoryVersion = (currentVersion, lastVersion) => {
this.setState({ isLoading: true, currentVersion }); this.setState({ isLoading: true, currentVersion });
console.log('currentVersion', currentVersion);
seafileAPI.getFileRevision(historyRepoID, currentVersion.commit_id, currentVersion.path).then(res => { seafileAPI.getFileRevision(historyRepoID, currentVersion.commit_id, currentVersion.path).then(res => {
return seafileAPI.getFileContent(res.data); return seafileAPI.getFileContent(res.data);
}).then(res => { }).then(res => {
@ -241,7 +240,7 @@ class SdocFileHistory extends React.Component {
this.setState({ showSidePanel: !this.state.showSidePanel }); this.setState({ showSidePanel: !this.state.showSidePanel });
}; };
renderChangesTip = () => { renderChangesTip = ({onChangeSidePanelDisplay}) => {
const { isShowChanges, changes, currentDiffIndex, isLoading } = this.state; const { isShowChanges, changes, currentDiffIndex, isLoading } = this.state;
if (isLoading) return null; if (isLoading) return null;
if (!isShowChanges) return null; if (!isShowChanges) return null;
@ -252,6 +251,9 @@ class SdocFileHistory extends React.Component {
<div className="sdoc-file-changes-container d-flex align-items-center pl-2 pr-2"> <div className="sdoc-file-changes-container d-flex align-items-center pl-2 pr-2">
{gettext('No changes')} {gettext('No changes')}
</div> </div>
<div className='sdoc-file-changes-switch ml-2'>
<i className="sf3-font sf3-font-history" onClick={onChangeSidePanelDisplay}></i>
</div>
</div> </div>
); );
} }
@ -357,7 +359,7 @@ class SdocFileHistory extends React.Component {
<GoBack /> <GoBack />
<div className="file-name text-truncate">{fileName}</div> <div className="file-name text-truncate">{fileName}</div>
</div> </div>
{this.renderChangesTip()} {this.renderChangesTip({onChangeSidePanelDisplay: this.changeSidePanelStatus})}
</div> </div>
<div className="sdoc-file-history-content f-flex" ref={ref => this.historyContentRef = ref}> <div className="sdoc-file-history-content f-flex" ref={ref => this.historyContentRef = ref}>
{isLoading ? ( {isLoading ? (

View File

@ -31,33 +31,6 @@ class SidePanel extends Component {
this.currentPage = 1; this.currentPage = 1;
} }
// listSdocDailyHistoryDetail
componentDidMount() {
// this.firstLoadSdocHistory();
}
// firstLoadSdocHistory() {
// this.currentPage = 1;
// seafileAPI.listSdocHistory(docUuid, this.currentPage, PER_PAGE).then(res => {
// const result = res.data;
// const resultCount = result.histories.length;
// const historyGroups = this.formatHistories(result.histories);
// this.setState({
// historyGroups: this.formatHistories(result.histories),
// hasMore: resultCount >= PER_PAGE,
// isLoading: false,
// }, () => {
// if (historyGroups.length > 0) {
// this.onSelectHistoryVersion([0, 0, 0]);
// }
// });
// }).catch((error) => {
// this.setState({isLoading: false});
// throw Error('there has an error in server');
// });
// }
formatHistories(histories) { formatHistories(histories) {
const oldHistoryGroups = this.state.historyGroups; const oldHistoryGroups = this.state.historyGroups;
if (!Array.isArray(histories) || histories.length === 0) return oldHistoryGroups; if (!Array.isArray(histories) || histories.length === 0) return oldHistoryGroups;
@ -286,7 +259,7 @@ class SidePanel extends Component {
{gettext('History Versions')} {gettext('History Versions')}
</div> </div>
<div className='sdoc-side-panel-close'> <div className='sdoc-side-panel-close'>
<i className="sdoc-close" onClick={this.props.onClose}></i> <i className="sf3-font sf3-font-close" onClick={this.props.onClose}></i>
</div> </div>
</div> </div>
<div <div