How I Built a Google Docs Imitation

Setup

redirect(page, options) {                               
this.setState({
currentPage: page,
options: options
})
};
"scripts: { 
“start”: “electron-forge start”,
"package”: “electron-forge package”,
“make”: “electron-forge make”,
“publish”: “electron-forge publish”,
“lint”: “eslint src — color”,
“backend-dev”: “nodemon server/index.js — exec babel-node —
presets es2015,stage-2”,
“backend-build”: “babel server -d server-dist — presets es2015,stage-2”,
“backend-serve”: “node server-dist/index.js”
}

Frontend

Rich-text Editor

toggleInlineStyle(e, inlineStyle) {
e.preventDefault()
this.onChange(RichUtils.toggleInlineStyle(
this.state.editorState, inlineStyle ))
};
toggleBlockType(e, blockType) {
e.preventDefault()
this.onChange(RichUtils.toggleBlockType(
this.state.editorState, blockType ))
};

Login, registration

Backend

User registration, login + authentication

passport.use( new LocalStrategy((username, password, done) => {                           
models.User.findOne({ username: username }, (err, user) => {
if(err) return done(err)
if(!user) return done(null, false, {message: 'Incorrect
username'})
if (user.password !== password) return done(null, false, {
message: 'Incorrect password'})
return done( null, user )
})
}));
router.post('/register', function(req, res) {                                
var u = new models.User({
username: req.body.username,
password: req.body.password,
docList: []
})
u.save(function(err, user) {
if(err) {
res.status(500).json({err: err.message})
return
}
res.status(200).json({success: true})
})
});

Document storage

app.get('/documentList', function(req, res) {                          
models.Document.find({collaborators: {$in: [req.user]}}, (err,
docs) => {
if(err) res.status.end(err.message)
else res.json(docs)
})
});
<List>                                            
{this.state.list.map(item =>
<ListItem
leftAvatar={<Avatar icon={<ActionAssignment />}
backgroundColor={blue500} />}
primaryText = {item.title}
secondaryText = {'Created at ' + item.timeOfCreation}
onMouseDown={e => this.openDocument(item)}
/>)
}
</List>
remoteStateChange(content) {                               
if(!content) return
this.setState({editorState:
EditorState.createWithContent(convertFromRaw(content))}) };

Neat tricks

Lessons

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store