Created
June 21, 2021 13:50
-
-
Save asSqr/12ab42ce88402d1439f3931304b867b6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Link from 'next/link'; | |
import Head from 'next/head'; | |
import Router from 'next/router'; | |
import { useRef, useEffect, useState } from 'react'; | |
import { Editor, EditorState, RichUtils } from 'draft-js'; | |
import 'draft-js/dist/Draft.css'; | |
import { stateToHTML } from 'draft-js-export-html'; | |
import Immutable from 'immutable'; | |
import Header from '../components/Header'; | |
import Footer from '../components/Footer'; | |
import firebase, { db } from '../firebase/firebase'; | |
import { useSelector } from 'react-redux'; | |
import { persistStore } from 'redux-persist'; | |
import { PersistGate } from 'redux-persist/integration/react'; | |
import { useStore } from '../store'; | |
const EditPage = ({ store }) => { | |
const persistor = persistStore(store) | |
return ( | |
<PersistGate persistor={persistor}> | |
<RichEditor /> | |
</PersistGate> | |
) | |
} | |
const RichEditor = () => { | |
const [editorEnable, setEditorEnable] = useState(false); | |
const [titleState, setTitleState] = useState(() => EditorState.createEmpty()); | |
const [editorState, setEditorState] = useState(() => EditorState.createEmpty()); | |
const [isPostDone, setPostDone] = useState(false); | |
const user = useSelector(state => state.user).user; | |
useEffect(() => { | |
setEditorEnable(true) | |
}, []); | |
const handleKeyCommand = (command, editorState) => { | |
const newState = RichUtils.handleKeyCommand(editorState, command); | |
if( newState ) { | |
setEditorState(newState); | |
return 'handled'; | |
} | |
return 'not-handled'; | |
}; | |
const handleReturn = e => { | |
if( e.shiftKey ) { | |
setEditorState( RichUtils.insertSoftNewline(editorState) ); | |
return 'handled'; | |
} | |
return 'not-handled'; | |
} | |
const onPost = async () => { | |
if( isPostDone ) | |
return; | |
setPostDone( true ); | |
const titleContentState = titleState.getCurrentContent(); | |
const contentState = editorState.getCurrentContent(); | |
const options = { | |
defaultBlockTag: null, | |
}; | |
await db | |
.collection('posts') | |
.add({ | |
title: titleContentState.getPlainText(), | |
body: stateToHTML(contentState), | |
author: user.user_name, | |
author_id: user.id, | |
created_at: firebase.firestore.FieldValue.serverTimestamp(), | |
updated_at: firebase.firestore.FieldValue.serverTimestamp(), | |
}) | |
Router.push('../'); | |
} | |
const inlineStyleList = [ | |
{ label: '太字', style: 'BOLD' }, | |
{ label: '斜体', style: 'ITALIC' }, | |
{ label: '下線', style: 'UNDERLINE' }, | |
{ label: '等幅', style: 'CODE' }, | |
] | |
const blockTypeList = [ | |
{ label: '段落', style: 'paragraph' }, | |
{ label: '見出し1', style: 'header-one' }, | |
{ label: '見出し2', style: 'header-two' }, | |
{ label: '見出し3', style: 'header-three' }, | |
{ label: '見出し4', style: 'header-four' }, | |
{ label: '見出し5', style: 'header-five' }, | |
{ label: '見出し6', style: 'header-six' }, | |
{ label: '引用', style: 'blockquote' }, | |
{ label: '箇条書き', style: 'unordered-list-item' }, | |
{ label: '番号リスト', style: 'ordered-list-item' }, | |
{ label: 'コード', style: 'code-block' }, | |
]; | |
return ( | |
<div> | |
<Head> | |
<title>テスト</title> | |
</Head> | |
<Header /> | |
<main className="markdown-body container"> | |
<Head> | |
<title>テスト</title> | |
</Head> | |
{editorEnable && ( | |
<div className="container"> | |
タイトル | |
<Editor | |
placeholder="ここにタイトルを書いてください!" | |
editorState={titleState} | |
onChange={setTitleState} | |
/> | |
<br /> | |
本文 | |
<div className="button-list"> | |
{inlineStyleList.map((inlineStyle, index) => { | |
return ( | |
<button | |
className="mono-button" | |
onMouseDown={(e) => { | |
setEditorState( | |
RichUtils.toggleInlineStyle(editorState, inlineStyle.style) | |
) | |
e.preventDefault() | |
}} | |
key={'inline-style-'+index} | |
>{inlineStyle.label}</button> | |
) | |
})} | |
{blockTypeList.map((blockType, index) => { | |
return ( | |
<button | |
className="mono-button" | |
onMouseDown={(e) => { | |
setEditorState( | |
RichUtils.toggleBlockType(editorState, blockType.style) | |
) | |
e.preventDefault() | |
}} | |
key={'block-type-'+index} | |
>{blockType.label}</button> | |
) | |
})} | |
</div> | |
<Editor | |
placeholder="ここに文章を書いてください!" | |
editorKey="test-key" | |
handleKeyCommand={handleKeyCommand} | |
editorState={editorState} | |
onChange={setEditorState} | |
handleReturn={handleReturn} | |
/> | |
</div> | |
)} | |
<button className="btn btn-primary" onClick={onPost}>{isPostDone ? "投稿中です・・・" : "投稿する"}</button> <br/> <br/> | |
<Link href="../"> | |
<button className="footer btn btn-primary">トップに戻る</button> | |
</Link> | |
</main> | |
<Footer /> | |
</div> | |
) | |
} | |
export default EditPage; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment