Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image upload #18

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 13 additions & 24 deletions main/create-window.js → main/actions/create-window.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
const { app, BrowserWindow } = require('electron')
const { BrowserWindow } = require('electron')
const { resolve } = require('app-root-path')
const dev = require('electron-is-dev')

const startServer = require('./server')
const setMenu = require('./menu')
const setIPCEvents = require('./ipc-events')

async function createWindow () {
let server

try {
// when starting the window run the server
server = await startServer()
} catch (error) {
console.error(error)
app.exit(error)
}
const setMenu = require('../menu')

async function createWindow (_windows) {
// after the server starts create the electron browser window
global.win = new BrowserWindow({
let win = new BrowserWindow({
title: 'Pulse',
backgroundColor: '#058ecd',
height: 768,
Expand All @@ -32,32 +20,33 @@ async function createWindow () {
textAreasAreResizable: false
}
})
const id = win.id

// open our server URL or the build directory in production
global.win.loadURL(dev ? 'http://localhost:8000' : `file://${resolve('./build')}/index.html`)
win.loadURL(dev ? 'http://localhost:8000' : `file://${resolve('./build')}/index.html`)

// in development open devtools
if (dev) {
global.win.webContents.openDevTools()
win.webContents.openDevTools()
}

global.win.once('ready-to-show', () => {
global.win.show()
win.once('ready-to-show', () => {
win.show()
})

global.win.on('close', () => {
global.win = null
if (server) server.close()
win.on('closed', () => {
_windows.delete(id)
})

setIPCEvents()
setMenu()

// TODO: implement a way to get the Markdown data
// protocol.registerHttpProtocol('pulse', (request, callback) => {
// const url = request.url.substr(8)
// console.log(url)
// })
_windows.set(id, win)
return win
}

module.exports = createWindow
Binary file modified main/assets/icon.icns
Binary file not shown.
Binary file modified main/assets/icon.ico
Binary file not shown.
Binary file modified main/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 35 additions & 7 deletions main/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,45 @@
const WindowManager = require('./window-manager')
const { app } = require('electron')

const createWindow = require('./create-window')
const dev = require('electron-is-dev')
const startServer = require('./server')
const setIPCEvents = require('./ipc-events')

app.on('ready', createWindow)
class Main {
constructor () {
this.server = null
this._windowManager = new WindowManager()
}
get windowManager () {
return this._windowManager
}

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
async onReady () {
if (dev) {
try {
this.server = await startServer()
} catch (error) {
console.error(error)
app.exit(error)
}
}
this._windowManager.createNewWindow()
}

onWindowAllClosed () {
app.quit()
}
}
const main = new Main()

app.once('ready', () => {
main.onReady()
setIPCEvents()
})

app.on('activate', () => {
if (!global.win) {
createWindow()
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
main.onWindowAllClosed()
}
if (this.server) this.server.close()
})
12 changes: 11 additions & 1 deletion main/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ const template = [
}
}
},
{
label: 'New window',
accelerator: 'CmdOrCtrl+Alt+N',
click () {
const webContent = webContents.getFocusedWebContents()
if (webContent) {
webContent.send('shortcut-press')
}
}
},
{
label: 'Open...',
accelerator: 'CmdOrCtrl+O',
Expand All @@ -29,7 +39,7 @@ const template = [
{
label: 'Save file',
accelerator: 'CmdOrCtrl+S',
click() {
click () {
const webContent = webContents.getFocusedWebContents()
if (webContent) {
webContent.send('trying-to-save')
Expand Down
27 changes: 27 additions & 0 deletions main/window-manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const { ipcMain, BrowserWindow } = require('electron')
const createWindow = require('./actions/create-window')

class WindowManager {
constructor () {
this._windows = new Map()
ipcMain.on('create-new-window', this._onRequestCreateNewWindow.bind(this))
}

reload () {
const w = BrowserWindow.getFocusedWindow()
if (w) {
w.reload()
}
}

createNewWindow (value = '', fileName = undefined) {
createWindow(this._windows, value, fileName)
}

_onRequestCreateNewWindow (event) {
this.createNewWindow()
event.sender.send('created-new-window')
}
}

module.exports = WindowManager
48 changes: 48 additions & 0 deletions renderer/components/window-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Component } from 'react'
import { Base } from 'pulse-editor/buttons'
import { ipcRenderer } from 'electron'
import { func } from 'prop-types'
import isMac from 'pulse-editor/built/utils/is-mac'
import Icon from 'react-icons/lib/fa/plus-circle'

export default class CreateButton extends Component {
static contextTypes = {
setShortcut: func.isRequired,
removeShortcut: func.isRequired,
writeValue: func.isRequired,
setFileName: func.isRequired
}

componentDidMount () {
ipcRenderer.on('shortcut-press', this.createWindow)
this.context.setShortcut({
ctrlKey: !isMac(),
metaKey: isMac(),
altKey: true,
shiftKey: false,
keyName: 'n',
updater: selected => selected,
handler: event => {
this.createWindow()
return event.selection
}
})
}

componentWillUnmount () {
this.context.removeShortcut({ keyName: 'n' })
ipcRenderer.removeListener('shortcut-press', this.createWindow)
}

createWindow = () => ipcRenderer.send('create-new-window')

handleClick = () => this.createWindow()

render = () => (
<Base onClick={this.handleClick} name='open'>
<span title='New Window [CMD+ALT+N]'>
<Icon /> New Window
</span>
</Base>
)
}
61 changes: 58 additions & 3 deletions renderer/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Save from '../components/save-button'
import Open from '../components/open-button'
import New from '../components/new-button'
import Export from '../components/export-button'
import Create from '../components/window-button'

import BoldIcon from 'react-icons/lib/fa/bold'
import ItalicIcon from 'react-icons/lib/fa/italic'
Expand Down Expand Up @@ -50,12 +51,11 @@ export default class extends Component {
setFileName: this.setFileName
}
}

componentDidMount () {
this.$preview = document.querySelector('.PulseEditor-preview')
this.$preview.addEventListener('click', this.handlePreviewLinkClick)
}

componentWillUnmount () {
this.$preview.removeEventListener('click', this.handlePreviewLinkClick)
}
Expand All @@ -70,7 +70,61 @@ export default class extends Component {
)
}

handleDrop = event => event.preventDefault()
successMessage (fileName, successData) {
const resultMessage = {
target: {
value: `${this.editor.domField.value} ![${fileName}](${successData.data.link})`
}
}
this.editor.writeValue(resultMessage)
}

async sendImage (file, imageData) {
const response = await fetch('https://api.imgur.com/3/image',
{
method: 'POST',
headers: {
'Authorization': `Client-ID e3f6a51d5c12580`
},
body: imageData}
)
if (response.ok) {
const successData = await response.json()
return this.successMessage(file.name, successData)
}
this.errorMessage()
}

errorMessage () {
const errorMessage = {
target: {
value: `${this.editor.domField.value} ![A problem when sending the file, please try again.]()`
}
}
this.editor.writeValue(errorMessage)
}
handleDrop = event => {
event.preventDefault()
// without 'preventDefault', when you drop the image, change the whole editor view
const defaultMessage = {
target: {
value: `${this.editor.domField.value} ![Problem with the format file](url)`
}
}
const file = event.dataTransfer.files[0]
const imageFormat = ['jpeg', 'png', 'gif', 'peg', 'apng', 'tiff', 'pdf', 'xcf']
const validFile = imageFormat.filter((format) => {
const regExp = new RegExp("\\b(" + format + ")\\b")
return regExp.test(file.type)
})
if (!!validFile && validFile.length !== 0) {
const imageData = new FormData()
imageData.append('image', file)
return this.sendImage(file, imageData, defaultMessage)
}
// if file format doesn't support by imgur, advice the user
return this.editor.writeValue(defaultMessage)
}

handleChange= event => {
if (event.markdown && this.state.fileName) {
Expand Down Expand Up @@ -149,6 +203,7 @@ export default class extends Component {
</ButtonGroup>

<ButtonGroup>
<Create />
<New />
<Open />
<Save />
Expand Down