Add markdown editor with image support
This commit is contained in:
@@ -6,6 +6,7 @@ import styled from "@emotion/styled"
|
||||
import { jsx, css, keyframes } from "@emotion/core"
|
||||
import { compose } from "recompose"
|
||||
import { withTheme } from "@emotion/react"
|
||||
import Editor from "rich-markdown-editor";
|
||||
|
||||
import { withFirebase } from "components/firebase"
|
||||
import { withAuthentication } from "components/session"
|
||||
@@ -15,6 +16,7 @@ import { SIZES } from "styles/constants"
|
||||
|
||||
import Seek from "components/Seek"
|
||||
import Icon from "components/Icon"
|
||||
import { resizeImage } from "../utils/file"
|
||||
|
||||
const EntryHeading = styled.div`
|
||||
display: flex;
|
||||
@@ -50,33 +52,36 @@ const OfflineNotice = styled.div`
|
||||
font-size: ${SIZES.tiny};
|
||||
border-radius: 3px;
|
||||
`
|
||||
const JournalEntryArea = styled.textarea`
|
||||
font-family: sans-serif;
|
||||
const JournalEntryArea = styled(Editor)`
|
||||
flex-grow: 0.85;
|
||||
color: ${(props) => props.theme.colors.primary};
|
||||
caret-color: ${(props) => props.theme.colors.secondary};
|
||||
color: ${props => props.theme.colors.primary};
|
||||
caret-color: ${props => props.theme.colors.secondary};
|
||||
background-color: transparent;
|
||||
line-height: 1.5;
|
||||
letter-spacing: 0.5px;
|
||||
height: calc(100vh - 300px);
|
||||
width: 100%;
|
||||
border: none;
|
||||
resize: none;
|
||||
outline: none;
|
||||
font-size: ${SIZES.small};
|
||||
border-radius: 1px;
|
||||
margin-top: ${SIZES.tiny};
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
padding-left: ${SIZES.medium};
|
||||
padding-right: ${SIZES.medium};
|
||||
overflow: scroll;
|
||||
justify-content: unset !important;
|
||||
& > div {
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
}
|
||||
&::placeholder {
|
||||
color: ${(props) => props.theme.colors.tertiary};
|
||||
color: ${props => {
|
||||
return props.theme.colors.tertiary}};
|
||||
}
|
||||
&::selection {
|
||||
background: ${(props) => props.theme.colors.hover};
|
||||
}
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 8px ${(props) => props.theme.colors.bodyBackground},
|
||||
0 0 0 10px ${(props) => props.theme.colors.hover};
|
||||
&:focus-within {
|
||||
box-shadow: 0 0 0 8px ${props => props.theme.colors.bodyBackground},
|
||||
0 0 0 10px ${props => props.theme.colors.hover};
|
||||
}
|
||||
`
|
||||
const Buttons = styled.div`
|
||||
@@ -153,8 +158,10 @@ class Day extends React.Component {
|
||||
.get(options)
|
||||
.then((doc) => {
|
||||
if (doc.data()) {
|
||||
console.log("I have data!", doc.data().text)
|
||||
this.setState({ text: doc.data().text, loading: false })
|
||||
} else {
|
||||
console.log("I don't have data!")
|
||||
this.setState({ text: "", loading: false })
|
||||
}
|
||||
})
|
||||
@@ -173,9 +180,9 @@ class Day extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
onChangeText = (e) => {
|
||||
handleChange = value => {
|
||||
if (this.timeout) clearTimeout(this.timeout)
|
||||
const text = e.target.value
|
||||
const text = value()
|
||||
const { year, month, day } = this.props
|
||||
|
||||
this.setState({ text, lastEditedAt: new Date() })
|
||||
@@ -202,6 +209,7 @@ class Day extends React.Component {
|
||||
saveText = (text, year, month, day) => {
|
||||
this.setState({ saving: true })
|
||||
const { firebase, authUser } = this.props
|
||||
console.log("I am saving data!", text);
|
||||
firebase.db
|
||||
.collection("entries")
|
||||
.doc(`${year}${month}${day}-${authUser.uid}`)
|
||||
@@ -226,6 +234,16 @@ class Day extends React.Component {
|
||||
})
|
||||
}
|
||||
|
||||
handleFileUpload = (file) => {
|
||||
return resizeImage(file).then(optimizedFile => {
|
||||
const { firebase, authUser } = this.props;
|
||||
const storageRef = firebase.storage.ref()
|
||||
const imagesRef = storageRef.child(`IMAGES/${authUser.uid}/${Date.now()}`);
|
||||
return imagesRef.put(optimizedFile)
|
||||
.then(snapshot => snapshot.ref.getDownloadURL());
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { year, month, day, theme } = this.props
|
||||
const online = this.context
|
||||
@@ -282,14 +300,10 @@ class Day extends React.Component {
|
||||
) : (
|
||||
<>
|
||||
<JournalEntryArea
|
||||
id="entry-text-area"
|
||||
autoFocus={true}
|
||||
placeholder="Start writing..."
|
||||
onChange={(e) => this.onChangeText(e)}
|
||||
value={text}
|
||||
css={css`
|
||||
animation: ${fadeKeyFrames} 0.2s ease-in;
|
||||
`}
|
||||
defaultValue={text}
|
||||
onChange={this.handleChange}
|
||||
dark={theme.name === "DARK"}
|
||||
uploadImage={async file => this.handleFileUpload(file)}
|
||||
/>
|
||||
<Buttons>
|
||||
<Icon
|
||||
|
||||
Reference in New Issue
Block a user