diff --git a/frontend/src/pages/wiki2/constant.js b/frontend/src/pages/wiki2/constant.js new file mode 100644 index 0000000000..73cb5508aa --- /dev/null +++ b/frontend/src/pages/wiki2/constant.js @@ -0,0 +1,15 @@ +const FOLDER = 'folder'; +const PAGE = 'page'; + +const WIKI_COVER_LIST = [ + 'wiki-cover-1.jpeg', + 'wiki-cover-2.jpeg', + 'wiki-cover-3.jpeg', + 'wiki-cover-4.jpeg', + 'wiki-cover-5.jpeg', + 'wiki-cover-6.jpeg', + 'wiki-cover-7.jpeg', + 'wiki-cover-8.jpeg', +]; + +export { FOLDER, PAGE, WIKI_COVER_LIST }; diff --git a/frontend/src/pages/wiki2/editor-component/page-header.jsx b/frontend/src/pages/wiki2/editor-component/page-header.jsx index 0258e2f7eb..8a90bc5db4 100644 --- a/frontend/src/pages/wiki2/editor-component/page-header.jsx +++ b/frontend/src/pages/wiki2/editor-component/page-header.jsx @@ -6,8 +6,10 @@ import data from '@emoji-mart/data'; import Picker from '@emoji-mart/react'; import { init } from 'emoji-mart'; import { gettext } from '../../../utils/constants'; +import { WIKI_COVER_LIST } from '../constant'; -init({ data }); // init data for emoji-mart, used in Picker and `getRandomEmoji` method +// init data for emoji-mart, used in Picker and `getRandomEmoji` method +init({ data }); const propTypes = { currentPageConfig: PropTypes.object.isRequired, @@ -19,13 +21,14 @@ const PageHeader = ({ currentPageConfig, onUpdatePage }) => { const [isShowIconPanel, setIsShowIconPanel] = useState(false); const [isShowCoverController, setIsShowCoverController] = useState(false); const [isShowCoverPanel, setIsShowCoverPanel] = useState(false); - const [coverImgUrl, setCoverImgUrl] = useState(''); const iconPanelPopoverRef = useRef(null); const coverPanelPopoverRef = useRef(null); + const headerWrapperRef = useRef(null); - // currentPageConfig.coverImgUrl = 'https://img2.baidu.com/it/u=2061573580,1495285204&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500'; - - console.log('currentPageConfig', currentPageConfig); + const getCoverImgUrl = useCallback((imageName) => { + const { serviceUrl, mediaUrl } = window.seafile; + return `${serviceUrl}${mediaUrl}img/wiki/cover/${imageName}`; + }, []); const handleRenameDocument = useCallback((e) => { const { nativeEvent: { isComposing } } = e; @@ -38,9 +41,10 @@ const PageHeader = ({ currentPageConfig, onUpdatePage }) => { onUpdatePage && onUpdatePage(id, pageConfig); }, [currentPageConfig, onUpdatePage]); - const changeControllerDisplayed = useCallback(() => { - setIsShowController(!isShowController); - }, [isShowController]); + const changeControllerDisplayed = useCallback((isShowController) => { + if(isShowCoverPanel) return; + setIsShowController(isShowController); + }, [isShowCoverPanel]); const handleSetIcon = useCallback((emoji, cb) => { onUpdatePage(currentPageConfig.id, { name: currentPageConfig.name, icon: emoji }); @@ -54,29 +58,29 @@ const PageHeader = ({ currentPageConfig, onUpdatePage }) => { handleSetIcon(emoji); }, [handleSetIcon]); - const handleIconPanelDisplayedChange = useCallback(() => { - setIsShowIconPanel(!isShowIconPanel); + const handleIconPanelDisplayedChange = useCallback((isShowIconPanel) => { + setIsShowIconPanel(isShowIconPanel); setIsShowCoverPanel(false); - }, [isShowIconPanel]); + }, []); const handleClickAddIcon = useCallback(() => { setRandomEmoji(); - handleIconPanelDisplayedChange(); + handleIconPanelDisplayedChange(false); }, [handleIconPanelDisplayedChange, setRandomEmoji]); const handleIconPanelListener = useCallback((e) => { const isClickInPopover = iconPanelPopoverRef.current.contains(e.target); - if (!isClickInPopover) handleIconPanelDisplayedChange(); + if (!isClickInPopover) handleIconPanelDisplayedChange(false); }, [handleIconPanelDisplayedChange]); - const handleCoverPanelDisplayedChange = useCallback(() => { - setIsShowCoverPanel(!isShowCoverPanel); + const handleCoverPanelDisplayedChange = useCallback((isShowCoverPanel) => { + setIsShowCoverPanel(isShowCoverPanel); setIsShowIconPanel(false); - }, [isShowCoverPanel]); + }, []); const handleCoverPanelListener = useCallback((e) => { const isClickInPopover = coverPanelPopoverRef.current.contains(e.target); - if (!isClickInPopover) handleCoverPanelDisplayedChange(); + if (!isClickInPopover) handleCoverPanelDisplayedChange(false); }, [handleCoverPanelDisplayedChange]); // Update current page favicon @@ -115,47 +119,59 @@ const PageHeader = ({ currentPageConfig, onUpdatePage }) => { const handleIconRemove = () => { handleSetIcon(''); - handleIconPanelDisplayedChange(); + handleIconPanelDisplayedChange(false); }; - const handleAddCover = useCallback(() => { }, []); + const handleAddCover = useCallback(() => { + const coverName = WIKI_COVER_LIST[Math.floor(Math.random() * WIKI_COVER_LIST.length)]; + const coverImgUrl = `${coverName}`; + onUpdatePage(currentPageConfig.id, { name: currentPageConfig.name, coverImgUrl }); + }, [currentPageConfig.id, currentPageConfig.name, onUpdatePage]); const showCoverController = useCallback(() => { setIsShowCoverController(true); }, []); - const hideCoverController = useCallback(() => { + const hideCoverController = useCallback((e) => { + if(isShowCoverPanel) return; setIsShowCoverController(false); - }, []); + }, [isShowCoverPanel]); + const handleSetCoverImage = (coverName) => { + const coverImgUrl = `${coverName}`; + onUpdatePage(currentPageConfig.id, { name: currentPageConfig.name, coverImgUrl }); + handleCoverPanelDisplayedChange(false); + }; - - const handleSetCoverImage = (e) => { - // TODO set cover image - setCoverImgUrl(e.target.src); - handleCoverPanelDisplayedChange(); + const handleCoverRemove = () => { + onUpdatePage(currentPageConfig.id, { name: currentPageConfig.name, coverImgUrl: '' }); + handleCoverPanelDisplayedChange(false); }; return (
{currentPageConfig.coverImgUrl && (
- {gettext('Cover')} + {gettext('Cover')} {isShowCoverController && (
-
{gettext('Change cover')}
+
{gettext('Change cover')}
void 0} placement="bottom" - isOpen={isShowCoverPanel && currentPageConfig.coverImgUrl} + isOpen={!!(isShowCoverPanel && currentPageConfig.coverImgUrl)} innerClassName='wiki-cover-panel' hideArrow={true} popperClassName='wiki-cover-popover' @@ -163,18 +179,14 @@ const PageHeader = ({ currentPageConfig, onUpdatePage }) => {
{gettext('Gallery')} - {gettext('Remove')} + {gettext('Remove')}
- {gettext('Cover')} - {gettext('Cover')} - {gettext('Cover')} - {gettext('Cover')} - {gettext('Cover')} - {gettext('Cover')} - {gettext('Cover')} - {gettext('Cover')} - {gettext('Cover')} + { + WIKI_COVER_LIST.map(imgName => ( + {gettext('Cover')} + )) + }
@@ -186,11 +198,9 @@ const PageHeader = ({ currentPageConfig, onUpdatePage }) => {
-
+
{currentPageConfig.icon}
@@ -199,7 +209,7 @@ const PageHeader = ({ currentPageConfig, onUpdatePage }) => { target="wiki-icon-wrapper" toggle={() => void 0} placement="bottom" - isOpen={isShowIconPanel && currentPageConfig.icon} + isOpen={!!(isShowIconPanel && !!currentPageConfig.icon)} popperClassName='wiki-icon-popover' hideArrow={true} > @@ -211,11 +221,12 @@ const PageHeader = ({ currentPageConfig, onUpdatePage }) => { handleSetIcon(emoji.native, handleIconPanelDisplayedChange)} + onEmojiSelect={(emoji) => handleSetIcon(emoji.native, handleIconPanelDisplayedChange.bind(null,false))} previewPosition="none" skinTonePosition="none" locale={window.seafile.lang.slice(0, 2)} maxFrequentRows={2} + theme="light" />
@@ -223,13 +234,13 @@ const PageHeader = ({ currentPageConfig, onUpdatePage }) => {
{!currentPageConfig.icon && (
- + {gettext('Add icon')}
)} {!currentPageConfig.coverImgUrl && ( -
- +
+ {gettext('Add cover')}
)} diff --git a/frontend/src/pages/wiki2/models/page.js b/frontend/src/pages/wiki2/models/page.js index e602394b57..3610afb916 100644 --- a/frontend/src/pages/wiki2/models/page.js +++ b/frontend/src/pages/wiki2/models/page.js @@ -5,6 +5,7 @@ class Page { this.path = object.path; this.icon = object.icon; this.docUuid = object.docUuid; + this.coverImgUrl = object.coverImgUrl; this.children = Array.isArray(object.children) ? object.children.map(item => new Page(item)) : []; } } diff --git a/frontend/src/pages/wiki2/wiki.css b/frontend/src/pages/wiki2/wiki.css index 5f90a20088..da8734e0ee 100644 --- a/frontend/src/pages/wiki2/wiki.css +++ b/frontend/src/pages/wiki2/wiki.css @@ -264,6 +264,7 @@ img[src=""] { .wiki-page-controller { display: flex; visibility: hidden; + margin-top: 10px; } .wiki-page-controller.show { @@ -273,9 +274,25 @@ img[src=""] { .wiki-page-controller-item { display: flex; align-items: center; - padding: 6px; + margin-left: 6px; + padding: 2px 8px; border-radius: 4px; cursor: pointer; + color: #949491; +} + +.wiki-page-controller-item:first-of-type { + margin-left: 0; +} + +.wiki-page-controller-item:hover { + background-color: #efefef; + border-radius: 4px; +} + +.wiki-page-controller-item .text { + margin-left: 4px; + font-size: 14px; } .wiki-icon-container { @@ -306,15 +323,6 @@ img[src=""] { display: block; } -.wiki-page-controller-item .text { - margin-left: 6px; -} - -.wiki-page-controller-item:hover { - background-color: #efefef; - border-radius: 4px; -} - /* Icon */ .wiki-icon-popover { max-width: max-content; @@ -343,6 +351,10 @@ img[src=""] { background-color: #fff; } +.wiki-icon-panel-body em-emoji-picker { + height: 337px; +} + /* Cover */ .cur-view-content .wiki-cover { position: relative; diff --git a/media/css/sf_font3/iconfont.css b/media/css/sf_font3/iconfont.css index 9a7a0fba60..fd8fee365d 100644 --- a/media/css/sf_font3/iconfont.css +++ b/media/css/sf_font3/iconfont.css @@ -1,11 +1,11 @@ @font-face { font-family: "sf3-font"; /* Project id 1230969 */ - src: url('iconfont.eot?t=1719885081769'); /* IE9 */ - src: url('iconfont.eot?t=1719885081769#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url('iconfont.woff2?t=1719885081769') format('woff2'), - url('iconfont.woff?t=1719885081769') format('woff'), - url('iconfont.ttf?t=1719885081769') format('truetype'), - url('iconfont.svg?t=1719885081769#sf3-font') format('svg'); + src: url('iconfont.eot?t=1720052264663'); /* IE9 */ + src: url('iconfont.eot?t=1720052264663#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('iconfont.woff2?t=1720052264663') format('woff2'), + url('iconfont.woff?t=1720052264663') format('woff'), + url('iconfont.ttf?t=1720052264663') format('truetype'), + url('iconfont.svg?t=1720052264663#sf3-font') format('svg'); } .sf3-font { @@ -16,6 +16,10 @@ -moz-osx-font-smoothing: grayscale; } +.sf3-font-icon:before { + content: "\e622"; +} + .sf3-font-enter:before { content: "\e845"; } diff --git a/media/css/sf_font3/iconfont.eot b/media/css/sf_font3/iconfont.eot index 9dafaedecb..37a1ac0c70 100644 Binary files a/media/css/sf_font3/iconfont.eot and b/media/css/sf_font3/iconfont.eot differ diff --git a/media/css/sf_font3/iconfont.js b/media/css/sf_font3/iconfont.js index 1222946e86..a4a2c8338d 100644 --- a/media/css/sf_font3/iconfont.js +++ b/media/css/sf_font3/iconfont.js @@ -1 +1 @@ -window._iconfont_svg_string_1230969='',function(s){var c=(c=document.getElementsByTagName("script"))[c.length-1],l=c.getAttribute("data-injectcss"),c=c.getAttribute("data-disable-injectsvg");if(!c){var h,o,t,i,v,m=function(c,l){l.parentNode.insertBefore(c,l)};if(l&&!s.__iconfont__svg__cssinject__){s.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}h=function(){var c,l=document.createElement("div");l.innerHTML=s._iconfont_svg_string_1230969,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(c=document.body).firstChild?m(l,c.firstChild):c.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),h()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(t=h,i=s.document,v=!1,z(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,f())})}function f(){v||(v=!0,t())}function z(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(z,50)}f()}}(window); \ No newline at end of file +window._iconfont_svg_string_1230969='',function(s){var c=(c=document.getElementsByTagName("script"))[c.length-1],l=c.getAttribute("data-injectcss"),c=c.getAttribute("data-disable-injectsvg");if(!c){var h,o,t,i,v,m=function(c,l){l.parentNode.insertBefore(c,l)};if(l&&!s.__iconfont__svg__cssinject__){s.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}h=function(){var c,l=document.createElement("div");l.innerHTML=s._iconfont_svg_string_1230969,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(c=document.body).firstChild?m(l,c.firstChild):c.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),h()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(t=h,i=s.document,v=!1,z(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,f())})}function f(){v||(v=!0,t())}function z(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(z,50)}f()}}(window); \ No newline at end of file diff --git a/media/css/sf_font3/iconfont.svg b/media/css/sf_font3/iconfont.svg index 1879032cce..f0f0056bc9 100644 --- a/media/css/sf_font3/iconfont.svg +++ b/media/css/sf_font3/iconfont.svg @@ -14,6 +14,8 @@ /> + + diff --git a/media/css/sf_font3/iconfont.ttf b/media/css/sf_font3/iconfont.ttf index 95856d77ba..191ff3d4bc 100644 Binary files a/media/css/sf_font3/iconfont.ttf and b/media/css/sf_font3/iconfont.ttf differ diff --git a/media/css/sf_font3/iconfont.woff b/media/css/sf_font3/iconfont.woff index 778c7eaeda..98794187bb 100644 Binary files a/media/css/sf_font3/iconfont.woff and b/media/css/sf_font3/iconfont.woff differ diff --git a/media/css/sf_font3/iconfont.woff2 b/media/css/sf_font3/iconfont.woff2 index 86fbcfd8b2..d5a0d17aa7 100644 Binary files a/media/css/sf_font3/iconfont.woff2 and b/media/css/sf_font3/iconfont.woff2 differ diff --git a/media/img/wiki/cover/wiki-cover-1.jpeg b/media/img/wiki/cover/wiki-cover-1.jpeg new file mode 100644 index 0000000000..4327be737b Binary files /dev/null and b/media/img/wiki/cover/wiki-cover-1.jpeg differ diff --git a/media/img/wiki/cover/wiki-cover-2.jpeg b/media/img/wiki/cover/wiki-cover-2.jpeg new file mode 100644 index 0000000000..fbbd354911 Binary files /dev/null and b/media/img/wiki/cover/wiki-cover-2.jpeg differ diff --git a/media/img/wiki/cover/wiki-cover-3.jpeg b/media/img/wiki/cover/wiki-cover-3.jpeg new file mode 100644 index 0000000000..7d6a74e458 Binary files /dev/null and b/media/img/wiki/cover/wiki-cover-3.jpeg differ diff --git a/media/img/wiki/cover/wiki-cover-4.jpeg b/media/img/wiki/cover/wiki-cover-4.jpeg new file mode 100644 index 0000000000..4327be737b Binary files /dev/null and b/media/img/wiki/cover/wiki-cover-4.jpeg differ diff --git a/media/img/wiki/cover/wiki-cover-5.jpeg b/media/img/wiki/cover/wiki-cover-5.jpeg new file mode 100644 index 0000000000..6b9acfb03b Binary files /dev/null and b/media/img/wiki/cover/wiki-cover-5.jpeg differ diff --git a/media/img/wiki/cover/wiki-cover-6.jpeg b/media/img/wiki/cover/wiki-cover-6.jpeg new file mode 100644 index 0000000000..959a056fd4 Binary files /dev/null and b/media/img/wiki/cover/wiki-cover-6.jpeg differ diff --git a/media/img/wiki/cover/wiki-cover-7.jpeg b/media/img/wiki/cover/wiki-cover-7.jpeg new file mode 100644 index 0000000000..0c0df77821 Binary files /dev/null and b/media/img/wiki/cover/wiki-cover-7.jpeg differ diff --git a/media/img/wiki/cover/wiki-cover-8.jpeg b/media/img/wiki/cover/wiki-cover-8.jpeg new file mode 100644 index 0000000000..a822cad68c Binary files /dev/null and b/media/img/wiki/cover/wiki-cover-8.jpeg differ