diff --git a/frontend/src/pages/markdown-editor/header-toolbar/button-group.js b/frontend/src/pages/markdown-editor/header-toolbar/button-group.js new file mode 100644 index 0000000000..d88337f6ed --- /dev/null +++ b/frontend/src/pages/markdown-editor/header-toolbar/button-group.js @@ -0,0 +1,13 @@ +import React from 'react'; + +class ButtonGroup extends React.PureComponent { + render() { + return ( +
+ {this.props.children} +
+ ); + } +} + +export default ButtonGroup; diff --git a/frontend/src/pages/markdown-editor/header-toolbar/button-item.js b/frontend/src/pages/markdown-editor/header-toolbar/button-item.js new file mode 100644 index 0000000000..cbe8b5aea5 --- /dev/null +++ b/frontend/src/pages/markdown-editor/header-toolbar/button-item.js @@ -0,0 +1,108 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Tooltip } from 'reactstrap'; + +const propTypes = { + id: PropTypes.string.isRequired, + isActive: PropTypes.bool, + disabled: PropTypes.bool, + isRichEditor: PropTypes.bool, + className: PropTypes.string, + icon: PropTypes.string, + text: PropTypes.string, +}; + +class ButtonItem extends React.Component { + + static defaultProps = { + className: '', + isActive: false, + } + + constructor(props) { + super(props); + + this.state = { + tooltipOpen: false, + isFreezed: false, + }; + } + + toggle = () => { + const { disabled } = this.props; + if (disabled) return; + + const { isFreezed, tooltipOpen } = this.state; + if (isFreezed && !tooltipOpen) return; + this.setState({tooltipOpen: !tooltipOpen, isFreezed: true}); + + setTimeout(() => { + this.setState({ isFreezed: false }); + }, 100); + } + + shouldComponentUpdate (nextProps, nextState) { + const { disabled, isActive } = nextProps; + const { disabled: oldDisabled, isActive: oldIsActive } = this.props; + if (disabled !== oldDisabled) { + this.setState({tooltipOpen: false}); + return true; + } + // only render iconButton when the button is active or show show tooltip + const { tooltipOpen } = nextState; + const { tooltipOpen: oldTooltipOpen } = this.state; + if (tooltipOpen === oldTooltipOpen && isActive === oldIsActive) { + return false; + } + + return true; + } + + onClick = (event) => { + if (!this.props.disabled) { + this.props.onClick && this.props.onClick(event); + } + } + + onMouseDown = (event) => { + if (!this.props.disabled) { + this.props.onMouseDown(event); + } + } + + getClassName = () => { + const { isRichEditor, className, disabled } = this.props; + let itemClass = 'btn btn-icon btn-secondary btn-active'; + if (!isRichEditor) return itemClass + ' ' + className; + + itemClass = `rich-icon-btn ${disabled ? 'rich-icon-btn-disabled' : 'rich-icon-btn-hover'}`; + return itemClass + ' ' + className; + } + + render() { + const { tooltipOpen } = this.state; + const { id, isActive, disabled, icon, text } = this.props; + const className = this.getClassName(); + const delay = {show: 0, hide: 0}; + return ( + + ); + } +} + +ButtonItem.propTypes = propTypes; + +export default ButtonItem; diff --git a/frontend/src/pages/markdown-editor/header-toolbar/collab-users-button.js b/frontend/src/pages/markdown-editor/header-toolbar/collab-users-button.js new file mode 100644 index 0000000000..d508ef218d --- /dev/null +++ b/frontend/src/pages/markdown-editor/header-toolbar/collab-users-button.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap'; + +class CollabUsersButton extends React.PureComponent { + + constructor(props) { + super(props); + this.state = { + dropdownOpen: false, + }; + } + + dropdownToggle = () => { + this.setState({dropdownOpen: !this.state.dropdownOpen}); + } + + render() { + return ( + + + {this.props.users.length} + + + {this.props.users.map((ele, idx) => ( + + {ele.user.name} {ele.myself ? '(you)' : ''} + + ))} + + + ); + } + +} + +export default CollabUsersButton; diff --git a/frontend/src/components/toolbar/markdown-viewer-toolbar.js b/frontend/src/pages/markdown-editor/header-toolbar/header-toolbar.js similarity index 72% rename from frontend/src/components/toolbar/markdown-viewer-toolbar.js rename to frontend/src/pages/markdown-editor/header-toolbar/header-toolbar.js index ac4a17f6a8..e8c2835b8a 100644 --- a/frontend/src/components/toolbar/markdown-viewer-toolbar.js +++ b/frontend/src/pages/markdown-editor/header-toolbar/header-toolbar.js @@ -1,9 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { gettext, canGenerateShareLink, isPro, mediaUrl, canLockUnlockFile } from '../../utils/constants'; -import { IconButton, ButtonGroup, CollabUsersButton } from '@seafile/seafile-editor/dist/components/topbar-component/editor-toolbar'; -import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem, Tooltip } from 'reactstrap'; import FileInfo from '@seafile/seafile-editor/dist/components/topbar-component/file-info'; +import { gettext, canGenerateShareLink, isPro, mediaUrl, canLockUnlockFile } from '../../../utils/constants'; +import ButtonGroup from './button-group'; +import ButtonItem from './button-item'; +import CollabUsersButton from './collab-users-button'; +import MoreMenu from './more-menu'; const { seafileCollabServer } = window.app.config; const { canDownloadFile } = window.app.pageOptions; @@ -33,78 +35,7 @@ const propTypes = { toggleLockFile: PropTypes.func.isRequired, }; -const MoreMenuPropTypes = { - readOnly: PropTypes.bool.isRequired, - openDialogs: PropTypes.func.isRequired, - onEdit: PropTypes.func.isRequired, - editorMode: PropTypes.string.isRequired, - isSmallScreen: PropTypes.bool, - toggleShareLinkDialog: PropTypes.func, - openParentDirectory: PropTypes.func, - showFileHistory: PropTypes.bool, - toggleHistory: PropTypes.func, -}; - -class MoreMenu extends React.PureComponent { - - constructor(props) { - super(props); - this.state = { - tooltipOpen: false, - dropdownOpen:false - }; - } - - tooltipToggle = () => { - this.setState({ tooltipOpen: !this.state.tooltipOpen }); - } - - dropdownToggle = () => { - this.setState({ dropdownOpen:!this.state.dropdownOpen }); - } - - downloadFile = () => { - location.href = '?dl=1'; - } - - render() { - const editorMode = this.props.editorMode; - const isSmall = this.props.isSmallScreen; - return ( - - - - {gettext('More')} - - - - {(!this.props.readOnly && editorMode === 'rich') && - {gettext('Switch to plain text editor')}} - {(!this.props.readOnly && editorMode === 'plain') && - {gettext('Switch to rich text editor')}} - {!isSmall && this.props.showFileHistory && - {gettext('History')}} - {(this.props.openDialogs && editorMode === 'rich') && - {gettext('Help')} - } - {isSmall && {gettext('Open parent directory')}} - {isSmall && canGenerateShareLink && {gettext('Share')}} - {(isSmall && this.props.showFileHistory) && - {gettext('History')} - } - {isSmall && canDownloadFile && - {gettext('Download')} - } - - - ); - } -} - -MoreMenu.propTypes = MoreMenuPropTypes; - - -class MarkdownViewerToolbar extends React.Component { +class HeaderToolbar extends React.Component { constructor(props) { super(props); @@ -120,6 +51,7 @@ class MarkdownViewerToolbar extends React.Component { } render() { + console.log('aaa'); let { contentChanged, saving, isLocked, lockedByMe } = this.props; let canPublishDraft = this.props.fileInfo.permission == 'rw'; let canCreateDraft = canPublishDraft && (!this.props.hasDraft && !this.props.isDraft && this.props.isDocs); @@ -167,27 +99,27 @@ class MarkdownViewerToolbar extends React.Component { /> } - {(canLockUnlockFile && !isLocked) && - + } {(canLockUnlockFile && lockedByMe) && - + } {canGenerateShareLink && - } {saving ? : - } {canDownloadFile && ( - )} {this.props.fileInfo.permission == 'rw' && - : - } @@ -265,7 +197,7 @@ class MarkdownViewerToolbar extends React.Component { : - + } : - { + this.setState({ tooltipOpen: !this.state.tooltipOpen }); + } + + dropdownToggle = () => { + this.setState({ dropdownOpen:!this.state.dropdownOpen }); + } + + downloadFile = () => { + location.href = '?dl=1'; + } + + render() { + const editorMode = this.props.editorMode; + const isSmall = this.props.isSmallScreen; + return ( + + + + {gettext('More')} + + + + {(!this.props.readOnly && editorMode === 'rich') && + {gettext('Switch to plain text editor')}} + {(!this.props.readOnly && editorMode === 'plain') && + {gettext('Switch to rich text editor')}} + {!isSmall && this.props.showFileHistory && + {gettext('History')}} + {(this.props.openDialogs && editorMode === 'rich') && + {gettext('Help')} + } + {isSmall && {gettext('Open parent directory')}} + {isSmall && canGenerateShareLink && {gettext('Share')}} + {(isSmall && this.props.showFileHistory) && + {gettext('History')} + } + {isSmall && canDownloadFile && + {gettext('Download')} + } + + + ); + } +} + +MoreMenu.propTypes = MoreMenuPropTypes; + +export default MoreMenu; \ No newline at end of file diff --git a/frontend/src/pages/markdown-editor/index.js b/frontend/src/pages/markdown-editor/index.js index 903eba46ac..c80f29bdcd 100644 --- a/frontend/src/pages/markdown-editor/index.js +++ b/frontend/src/pages/markdown-editor/index.js @@ -14,7 +14,7 @@ import LocalDraftDialog from '../../components/dialog/local-draft-dialog'; import EditFileTagDialog from '../../components/dialog/edit-filetag-dialog'; import InsertRepoImageDialog from '../../components/dialog/insert-repo-image-dialog'; import FileParticipantDialog from '../../components/dialog/file-participant-dialog'; -import MarkdownViewerToolbar from '../../components/toolbar/markdown-viewer-toolbar'; +import HeaderToolbar from './header-toolbar'; import editorApi from './editor-api'; import '../../css/markdown-viewer/markdown-editor.css'; @@ -509,7 +509,7 @@ class MarkdownEditor extends React.Component { } else if (this.state.mode === 'editor') { component = ( -