mirror of
https://github.com/Kuingsmile/PicList.git
synced 2025-03-13 00:18:13 -04:00
First beta version
This commit is contained in:
commit
d1b9e0f592
39
.babelrc
Normal file
39
.babelrc
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"comments": false,
|
||||||
|
"env": {
|
||||||
|
"test": {
|
||||||
|
"presets": [
|
||||||
|
["env", {
|
||||||
|
"targets": { "node": 7 }
|
||||||
|
}],
|
||||||
|
"stage-0"
|
||||||
|
],
|
||||||
|
"plugins": ["istanbul"]
|
||||||
|
},
|
||||||
|
"main": {
|
||||||
|
"presets": [
|
||||||
|
["env", {
|
||||||
|
"targets": { "node": 7 }
|
||||||
|
}],
|
||||||
|
"stage-0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"renderer": {
|
||||||
|
"presets": [
|
||||||
|
["env", {
|
||||||
|
"modules": false
|
||||||
|
}],
|
||||||
|
"stage-0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"presets": [
|
||||||
|
["env", {
|
||||||
|
"modules": false
|
||||||
|
}],
|
||||||
|
"stage-0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"plugins": ["transform-runtime"]
|
||||||
|
}
|
130
.electron-vue/build.js
Normal file
130
.electron-vue/build.js
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
process.env.NODE_ENV = 'production'
|
||||||
|
|
||||||
|
const { say } = require('cfonts')
|
||||||
|
const chalk = require('chalk')
|
||||||
|
const del = require('del')
|
||||||
|
const { spawn } = require('child_process')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
const Multispinner = require('multispinner')
|
||||||
|
|
||||||
|
|
||||||
|
const mainConfig = require('./webpack.main.config')
|
||||||
|
const rendererConfig = require('./webpack.renderer.config')
|
||||||
|
const webConfig = require('./webpack.web.config')
|
||||||
|
|
||||||
|
const doneLog = chalk.bgGreen.white(' DONE ') + ' '
|
||||||
|
const errorLog = chalk.bgRed.white(' ERROR ') + ' '
|
||||||
|
const okayLog = chalk.bgBlue.white(' OKAY ') + ' '
|
||||||
|
const isCI = process.env.CI || false
|
||||||
|
|
||||||
|
if (process.env.BUILD_TARGET === 'clean') clean()
|
||||||
|
else if (process.env.BUILD_TARGET === 'web') web()
|
||||||
|
else build()
|
||||||
|
|
||||||
|
function clean () {
|
||||||
|
del.sync(['build/*', '!build/icons', '!build/icons/icon.*'])
|
||||||
|
console.log(`\n${doneLog}\n`)
|
||||||
|
process.exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
function build () {
|
||||||
|
greeting()
|
||||||
|
|
||||||
|
del.sync(['dist/electron/*', '!.gitkeep'])
|
||||||
|
|
||||||
|
const tasks = ['main', 'renderer']
|
||||||
|
const m = new Multispinner(tasks, {
|
||||||
|
preText: 'building',
|
||||||
|
postText: 'process'
|
||||||
|
})
|
||||||
|
|
||||||
|
let results = ''
|
||||||
|
|
||||||
|
m.on('success', () => {
|
||||||
|
process.stdout.write('\x1B[2J\x1B[0f')
|
||||||
|
console.log(`\n\n${results}`)
|
||||||
|
console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
|
||||||
|
process.exit()
|
||||||
|
})
|
||||||
|
|
||||||
|
pack(mainConfig).then(result => {
|
||||||
|
results += result + '\n\n'
|
||||||
|
m.success('main')
|
||||||
|
}).catch(err => {
|
||||||
|
m.error('main')
|
||||||
|
console.log(`\n ${errorLog}failed to build main process`)
|
||||||
|
console.error(`\n${err}\n`)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
pack(rendererConfig).then(result => {
|
||||||
|
results += result + '\n\n'
|
||||||
|
m.success('renderer')
|
||||||
|
}).catch(err => {
|
||||||
|
m.error('renderer')
|
||||||
|
console.log(`\n ${errorLog}failed to build renderer process`)
|
||||||
|
console.error(`\n${err}\n`)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function pack (config) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
webpack(config, (err, stats) => {
|
||||||
|
if (err) reject(err.stack || err)
|
||||||
|
else if (stats.hasErrors()) {
|
||||||
|
let err = ''
|
||||||
|
|
||||||
|
stats.toString({
|
||||||
|
chunks: false,
|
||||||
|
colors: true
|
||||||
|
})
|
||||||
|
.split(/\r?\n/)
|
||||||
|
.forEach(line => {
|
||||||
|
err += ` ${line}\n`
|
||||||
|
})
|
||||||
|
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
resolve(stats.toString({
|
||||||
|
chunks: false,
|
||||||
|
colors: true
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function web () {
|
||||||
|
del.sync(['dist/web/*', '!.gitkeep'])
|
||||||
|
webpack(webConfig, (err, stats) => {
|
||||||
|
if (err || stats.hasErrors()) console.log(err)
|
||||||
|
|
||||||
|
console.log(stats.toString({
|
||||||
|
chunks: false,
|
||||||
|
colors: true
|
||||||
|
}))
|
||||||
|
|
||||||
|
process.exit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function greeting () {
|
||||||
|
const cols = process.stdout.columns
|
||||||
|
let text = ''
|
||||||
|
|
||||||
|
if (cols > 85) text = 'lets-build'
|
||||||
|
else if (cols > 60) text = 'lets-|build'
|
||||||
|
else text = false
|
||||||
|
|
||||||
|
if (text && !isCI) {
|
||||||
|
say(text, {
|
||||||
|
colors: ['yellow'],
|
||||||
|
font: 'simple3d',
|
||||||
|
space: false
|
||||||
|
})
|
||||||
|
} else console.log(chalk.yellow.bold('\n lets-build'))
|
||||||
|
console.log()
|
||||||
|
}
|
40
.electron-vue/dev-client.js
Normal file
40
.electron-vue/dev-client.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
|
||||||
|
|
||||||
|
hotClient.subscribe(event => {
|
||||||
|
/**
|
||||||
|
* Reload browser when HTMLWebpackPlugin emits a new index.html
|
||||||
|
*
|
||||||
|
* Currently disabled until jantimon/html-webpack-plugin#680 is resolved.
|
||||||
|
* https://github.com/SimulatedGREG/electron-vue/issues/437
|
||||||
|
* https://github.com/jantimon/html-webpack-plugin/issues/680
|
||||||
|
*/
|
||||||
|
// if (event.action === 'reload') {
|
||||||
|
// window.location.reload()
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify `mainWindow` when `main` process is compiling,
|
||||||
|
* giving notice for an expected reload of the `electron` process
|
||||||
|
*/
|
||||||
|
if (event.action === 'compiling') {
|
||||||
|
document.body.innerHTML += `
|
||||||
|
<style>
|
||||||
|
#dev-client {
|
||||||
|
background: #4fc08d;
|
||||||
|
border-radius: 4px;
|
||||||
|
bottom: 20px;
|
||||||
|
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
|
||||||
|
color: #fff;
|
||||||
|
font-family: 'Source Sans Pro', sans-serif;
|
||||||
|
left: 20px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="dev-client">
|
||||||
|
Compiling Main Process...
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
})
|
178
.electron-vue/dev-runner.js
Normal file
178
.electron-vue/dev-runner.js
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const chalk = require('chalk')
|
||||||
|
const electron = require('electron')
|
||||||
|
const path = require('path')
|
||||||
|
const { say } = require('cfonts')
|
||||||
|
const { spawn } = require('child_process')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
const WebpackDevServer = require('webpack-dev-server')
|
||||||
|
const webpackHotMiddleware = require('webpack-hot-middleware')
|
||||||
|
|
||||||
|
const mainConfig = require('./webpack.main.config')
|
||||||
|
const rendererConfig = require('./webpack.renderer.config')
|
||||||
|
|
||||||
|
let electronProcess = null
|
||||||
|
let manualRestart = false
|
||||||
|
let hotMiddleware
|
||||||
|
|
||||||
|
function logStats (proc, data) {
|
||||||
|
let log = ''
|
||||||
|
|
||||||
|
log += chalk.yellow.bold(`┏ ${proc} Process ${new Array((19 - proc.length) + 1).join('-')}`)
|
||||||
|
log += '\n\n'
|
||||||
|
|
||||||
|
if (typeof data === 'object') {
|
||||||
|
data.toString({
|
||||||
|
colors: true,
|
||||||
|
chunks: false
|
||||||
|
}).split(/\r?\n/).forEach(line => {
|
||||||
|
log += ' ' + line + '\n'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log += ` ${data}\n`
|
||||||
|
}
|
||||||
|
|
||||||
|
log += '\n' + chalk.yellow.bold(`┗ ${new Array(28 + 1).join('-')}`) + '\n'
|
||||||
|
|
||||||
|
console.log(log)
|
||||||
|
}
|
||||||
|
|
||||||
|
function startRenderer () {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
|
||||||
|
|
||||||
|
const compiler = webpack(rendererConfig)
|
||||||
|
hotMiddleware = webpackHotMiddleware(compiler, {
|
||||||
|
log: false,
|
||||||
|
heartbeat: 2500
|
||||||
|
})
|
||||||
|
|
||||||
|
compiler.plugin('compilation', compilation => {
|
||||||
|
compilation.plugin('html-webpack-plugin-after-emit', (data, cb) => {
|
||||||
|
hotMiddleware.publish({ action: 'reload' })
|
||||||
|
cb()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
compiler.plugin('done', stats => {
|
||||||
|
logStats('Renderer', stats)
|
||||||
|
})
|
||||||
|
|
||||||
|
const server = new WebpackDevServer(
|
||||||
|
compiler,
|
||||||
|
{
|
||||||
|
contentBase: path.join(__dirname, '../'),
|
||||||
|
quiet: true,
|
||||||
|
before (app, ctx) {
|
||||||
|
app.use(hotMiddleware)
|
||||||
|
ctx.middleware.waitUntilValid(() => {
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
server.listen(9080)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function startMain () {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
|
||||||
|
|
||||||
|
const compiler = webpack(mainConfig)
|
||||||
|
|
||||||
|
compiler.plugin('watch-run', (compilation, done) => {
|
||||||
|
logStats('Main', chalk.white.bold('compiling...'))
|
||||||
|
hotMiddleware.publish({ action: 'compiling' })
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
compiler.watch({}, (err, stats) => {
|
||||||
|
if (err) {
|
||||||
|
console.log(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logStats('Main', stats)
|
||||||
|
|
||||||
|
if (electronProcess && electronProcess.kill) {
|
||||||
|
manualRestart = true
|
||||||
|
process.kill(electronProcess.pid)
|
||||||
|
electronProcess = null
|
||||||
|
startElectron()
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
manualRestart = false
|
||||||
|
}, 5000)
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function startElectron () {
|
||||||
|
electronProcess = spawn(electron, ['--inspect=5858', path.join(__dirname, '../dist/electron/main.js')])
|
||||||
|
|
||||||
|
electronProcess.stdout.on('data', data => {
|
||||||
|
electronLog(data, 'blue')
|
||||||
|
})
|
||||||
|
electronProcess.stderr.on('data', data => {
|
||||||
|
electronLog(data, 'red')
|
||||||
|
})
|
||||||
|
|
||||||
|
electronProcess.on('close', () => {
|
||||||
|
if (!manualRestart) process.exit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function electronLog (data, color) {
|
||||||
|
let log = ''
|
||||||
|
data = data.toString().split(/\r?\n/)
|
||||||
|
data.forEach(line => {
|
||||||
|
log += ` ${line}\n`
|
||||||
|
})
|
||||||
|
if (/[0-9A-z]+/.test(log)) {
|
||||||
|
console.log(
|
||||||
|
chalk[color].bold('┏ Electron -------------------') +
|
||||||
|
'\n\n' +
|
||||||
|
log +
|
||||||
|
chalk[color].bold('┗ ----------------------------') +
|
||||||
|
'\n'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function greeting () {
|
||||||
|
const cols = process.stdout.columns
|
||||||
|
let text = ''
|
||||||
|
|
||||||
|
if (cols > 104) text = 'electron-vue'
|
||||||
|
else if (cols > 76) text = 'electron-|vue'
|
||||||
|
else text = false
|
||||||
|
|
||||||
|
if (text) {
|
||||||
|
say(text, {
|
||||||
|
colors: ['yellow'],
|
||||||
|
font: 'simple3d',
|
||||||
|
space: false
|
||||||
|
})
|
||||||
|
} else console.log(chalk.yellow.bold('\n electron-vue'))
|
||||||
|
console.log(chalk.blue(' getting ready...') + '\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
function init () {
|
||||||
|
greeting()
|
||||||
|
|
||||||
|
Promise.all([startRenderer(), startMain()])
|
||||||
|
.then(() => {
|
||||||
|
startElectron()
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
init()
|
83
.electron-vue/webpack.main.config.js
Normal file
83
.electron-vue/webpack.main.config.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
process.env.BABEL_ENV = 'main'
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
const { dependencies } = require('../package.json')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
|
const babelMinifyWebpackPlugin = require('babel-minify-webpack-plugin')
|
||||||
|
|
||||||
|
let mainConfig = {
|
||||||
|
entry: {
|
||||||
|
main: path.join(__dirname, '../src/main/index.js')
|
||||||
|
},
|
||||||
|
externals: [
|
||||||
|
// ...Object.keys(dependencies || {})
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(js)$/,
|
||||||
|
enforce: 'pre',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: {
|
||||||
|
loader: 'eslint-loader',
|
||||||
|
options: {
|
||||||
|
formatter: require('eslint-friendly-formatter')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
use: 'babel-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.node$/,
|
||||||
|
use: 'node-loader'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
__dirname: process.env.NODE_ENV !== 'production',
|
||||||
|
__filename: process.env.NODE_ENV !== 'production'
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
libraryTarget: 'commonjs2',
|
||||||
|
path: path.join(__dirname, '../dist/electron')
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.NoEmitOnErrorsPlugin()
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.js', '.json', '.node']
|
||||||
|
},
|
||||||
|
target: 'electron-main'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust mainConfig for development settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
mainConfig.plugins.push(
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust mainConfig for production settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
mainConfig.plugins.push(
|
||||||
|
new babelMinifyWebpackPlugin(),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': '"production"'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = mainConfig
|
178
.electron-vue/webpack.renderer.config.js
Normal file
178
.electron-vue/webpack.renderer.config.js
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
process.env.BABEL_ENV = 'renderer'
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
const { dependencies } = require('../package.json')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
|
const BabiliWebpackPlugin = require('babili-webpack-plugin')
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||||
|
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of node_modules to include in webpack bundle
|
||||||
|
*
|
||||||
|
* Required for specific packages like Vue UI libraries
|
||||||
|
* that provide pure *.vue files that need compiling
|
||||||
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
|
||||||
|
*/
|
||||||
|
let whiteListedModules = ['vue']
|
||||||
|
|
||||||
|
let rendererConfig = {
|
||||||
|
devtool: '#cheap-module-eval-source-map',
|
||||||
|
entry: {
|
||||||
|
renderer: path.join(__dirname, '../src/renderer/main.js')
|
||||||
|
},
|
||||||
|
externals: [
|
||||||
|
// ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d))
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(js|vue)$/,
|
||||||
|
enforce: 'pre',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: {
|
||||||
|
loader: 'eslint-loader',
|
||||||
|
options: {
|
||||||
|
formatter: require('eslint-friendly-formatter')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ExtractTextPlugin.extract({
|
||||||
|
fallback: 'style-loader',
|
||||||
|
use: 'css-loader'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.html$/,
|
||||||
|
use: 'vue-html-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
use: 'babel-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.node$/,
|
||||||
|
use: 'node-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
use: {
|
||||||
|
loader: 'vue-loader',
|
||||||
|
options: {
|
||||||
|
extractCSS: process.env.NODE_ENV === 'production',
|
||||||
|
loaders: {
|
||||||
|
sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
|
||||||
|
scss: 'vue-style-loader!css-loader!sass-loader'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'url-loader',
|
||||||
|
query: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'imgs/[name]--[folder].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||||
|
loader: 'url-loader',
|
||||||
|
options: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'media/[name]--[folder].[ext]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'url-loader',
|
||||||
|
query: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'fonts/[name]--[folder].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
__dirname: process.env.NODE_ENV !== 'production',
|
||||||
|
__filename: process.env.NODE_ENV !== 'production'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new ExtractTextPlugin('styles.css'),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
filename: 'index.html',
|
||||||
|
template: path.resolve(__dirname, '../src/index.ejs'),
|
||||||
|
minify: {
|
||||||
|
collapseWhitespace: true,
|
||||||
|
removeAttributeQuotes: true,
|
||||||
|
removeComments: true
|
||||||
|
},
|
||||||
|
nodeModules: process.env.NODE_ENV !== 'production'
|
||||||
|
? path.resolve(__dirname, '../node_modules')
|
||||||
|
: false
|
||||||
|
}),
|
||||||
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
|
new webpack.NoEmitOnErrorsPlugin()
|
||||||
|
],
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
libraryTarget: 'commonjs2',
|
||||||
|
path: path.join(__dirname, '../dist/electron')
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.join(__dirname, '../src/renderer'),
|
||||||
|
'vue$': 'vue/dist/vue.esm.js'
|
||||||
|
},
|
||||||
|
extensions: ['.js', '.vue', '.json', '.css', '.node']
|
||||||
|
},
|
||||||
|
target: 'electron-renderer'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust rendererConfig for development settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
rendererConfig.plugins.push(
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust rendererConfig for production settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
rendererConfig.devtool = ''
|
||||||
|
|
||||||
|
rendererConfig.plugins.push(
|
||||||
|
new BabiliWebpackPlugin(),
|
||||||
|
new CopyWebpackPlugin([
|
||||||
|
{
|
||||||
|
from: path.join(__dirname, '../static'),
|
||||||
|
to: path.join(__dirname, '../dist/electron/static'),
|
||||||
|
ignore: ['.*']
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': '"production"'
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
minimize: true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = rendererConfig
|
139
.electron-vue/webpack.web.config.js
Normal file
139
.electron-vue/webpack.web.config.js
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
process.env.BABEL_ENV = 'web'
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
|
const BabiliWebpackPlugin = require('babili-webpack-plugin')
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||||
|
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||||
|
|
||||||
|
let webConfig = {
|
||||||
|
devtool: '#cheap-module-eval-source-map',
|
||||||
|
entry: {
|
||||||
|
web: path.join(__dirname, '../src/renderer/main.js')
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(js|vue)$/,
|
||||||
|
enforce: 'pre',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: {
|
||||||
|
loader: 'eslint-loader',
|
||||||
|
options: {
|
||||||
|
formatter: require('eslint-friendly-formatter')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ExtractTextPlugin.extract({
|
||||||
|
fallback: 'style-loader',
|
||||||
|
use: 'css-loader'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.html$/,
|
||||||
|
use: 'vue-html-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
use: 'babel-loader',
|
||||||
|
include: [ path.resolve(__dirname, '../src/renderer') ],
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
use: {
|
||||||
|
loader: 'vue-loader',
|
||||||
|
options: {
|
||||||
|
extractCSS: true,
|
||||||
|
loaders: {
|
||||||
|
sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
|
||||||
|
scss: 'vue-style-loader!css-loader!sass-loader'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'url-loader',
|
||||||
|
query: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'imgs/[name].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'url-loader',
|
||||||
|
query: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'fonts/[name].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new ExtractTextPlugin('styles.css'),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
filename: 'index.html',
|
||||||
|
template: path.resolve(__dirname, '../src/index.ejs'),
|
||||||
|
minify: {
|
||||||
|
collapseWhitespace: true,
|
||||||
|
removeAttributeQuotes: true,
|
||||||
|
removeComments: true
|
||||||
|
},
|
||||||
|
nodeModules: false
|
||||||
|
}),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.IS_WEB': 'true'
|
||||||
|
}),
|
||||||
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
|
new webpack.NoEmitOnErrorsPlugin()
|
||||||
|
],
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
path: path.join(__dirname, '../dist/web')
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.join(__dirname, '../src/renderer'),
|
||||||
|
'vue$': 'vue/dist/vue.esm.js'
|
||||||
|
},
|
||||||
|
extensions: ['.js', '.vue', '.json', '.css']
|
||||||
|
},
|
||||||
|
target: 'web'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust webConfig for production settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
webConfig.devtool = ''
|
||||||
|
|
||||||
|
webConfig.plugins.push(
|
||||||
|
new BabiliWebpackPlugin(),
|
||||||
|
new CopyWebpackPlugin([
|
||||||
|
{
|
||||||
|
from: path.join(__dirname, '../static'),
|
||||||
|
to: path.join(__dirname, '../dist/web/static'),
|
||||||
|
ignore: ['.*']
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': '"production"'
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
minimize: true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = webConfig
|
3
.eslintignore
Normal file
3
.eslintignore
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
test/unit/coverage/**
|
||||||
|
test/unit/*.js
|
||||||
|
test/e2e/*.js
|
26
.eslintrc.js
Normal file
26
.eslintrc.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parser: 'babel-eslint',
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'module'
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
extends: 'standard',
|
||||||
|
globals: {
|
||||||
|
__static: true
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
'html'
|
||||||
|
],
|
||||||
|
'rules': {
|
||||||
|
// allow paren-less arrow functions
|
||||||
|
'arrow-parens': 0,
|
||||||
|
// allow async-await
|
||||||
|
'generator-star-spacing': 0,
|
||||||
|
// allow debugger during development
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
|
||||||
|
}
|
||||||
|
}
|
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.DS_Store
|
||||||
|
dist/electron/*
|
||||||
|
dist/web/*
|
||||||
|
build/*
|
||||||
|
!build/icons
|
||||||
|
coverage
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log
|
||||||
|
npm-debug.log.*
|
||||||
|
thumbs.db
|
||||||
|
!.gitkeep
|
43
.travis.yml
Normal file
43
.travis.yml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# Commented sections below can be used to run tests on the CI server
|
||||||
|
# https://simulatedgreg.gitbooks.io/electron-vue/content/en/testing.html#on-the-subject-of-ci-testing
|
||||||
|
osx_image: xcode8.3
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
language: c
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: osx
|
||||||
|
- os: linux
|
||||||
|
env: CC=clang CXX=clang++ npm_config_clang=1
|
||||||
|
compiler: clang
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- node_modules
|
||||||
|
- "$HOME/.electron"
|
||||||
|
- "$HOME/.cache"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libgnome-keyring-dev
|
||||||
|
- icnsutils
|
||||||
|
#- xvfb
|
||||||
|
before_install:
|
||||||
|
- mkdir -p /tmp/git-lfs && curl -L https://github.com/github/git-lfs/releases/download/v1.2.1/git-lfs-$([
|
||||||
|
"$TRAVIS_OS_NAME" == "linux" ] && echo "linux" || echo "darwin")-amd64-1.2.1.tar.gz
|
||||||
|
| tar -xz -C /tmp/git-lfs --strip-components 1 && /tmp/git-lfs/git-lfs pull
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install --no-install-recommends -y icnsutils graphicsmagick xz-utils; fi
|
||||||
|
install:
|
||||||
|
#- export DISPLAY=':99.0'
|
||||||
|
#- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
|
||||||
|
- nvm install 7
|
||||||
|
- curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||||
|
- source ~/.bashrc
|
||||||
|
- npm install -g xvfb-maybe
|
||||||
|
- yarn
|
||||||
|
script:
|
||||||
|
#- xvfb-maybe node_modules/.bin/karma start test/unit/karma.conf.js
|
||||||
|
#- yarn run pack && xvfb-maybe node_modules/.bin/mocha test/e2e
|
||||||
|
- yarn run build
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
18
.vscode/launch.json
vendored
Normal file
18
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Attach",
|
||||||
|
"type": "node",
|
||||||
|
"request": "attach",
|
||||||
|
"port": 5858,
|
||||||
|
"sourceMaps": false,
|
||||||
|
"outFiles": [],
|
||||||
|
"localRoot": "${workspaceRoot}",
|
||||||
|
"remoteRoot": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"eslint.enable": true,
|
||||||
|
"eslint.autoFixOnSave": true
|
||||||
|
}
|
8
LICENSE
Normal file
8
LICENSE
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
MIT License
|
||||||
|
Copyright (c) <year> <copyright holders>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
28
README.md
Normal file
28
README.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# picgo
|
||||||
|
|
||||||
|
> Easy to upload your pic & copy to write
|
||||||
|
|
||||||
|
#### Build Setup
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
# install dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# serve with hot reload at localhost:9080
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# build electron application for production
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# run unit & end-to-end tests
|
||||||
|
npm test
|
||||||
|
|
||||||
|
|
||||||
|
# lint all JS/Vue component files in `src/`
|
||||||
|
npm run lint
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This project was generated with [electron-vue](https://github.com/SimulatedGREG/electron-vue) using [vue-cli](https://github.com/vuejs/vue-cli). Documentation about the original structure can be found [here](https://simulatedgreg.gitbooks.io/electron-vue/content/index.html).
|
33
appveyor.yml
Normal file
33
appveyor.yml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Commented sections below can be used to run tests on the CI server
|
||||||
|
# https://simulatedgreg.gitbooks.io/electron-vue/content/en/testing.html#on-the-subject-of-ci-testing
|
||||||
|
version: 0.1.{build}
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
image: Visual Studio 2017
|
||||||
|
platform:
|
||||||
|
- x64
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- node_modules
|
||||||
|
- '%APPDATA%\npm-cache'
|
||||||
|
- '%USERPROFILE%\.electron'
|
||||||
|
- '%USERPROFILE%\AppData\Local\Yarn\cache'
|
||||||
|
|
||||||
|
init:
|
||||||
|
- git config --global core.autocrlf input
|
||||||
|
|
||||||
|
install:
|
||||||
|
- ps: Install-Product node 8 x64
|
||||||
|
- choco install yarn --ignore-dependencies
|
||||||
|
- git reset --hard HEAD
|
||||||
|
- yarn
|
||||||
|
- node --version
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
#- yarn test
|
||||||
|
- yarn build
|
||||||
|
|
||||||
|
test: off
|
BIN
build/icons/256x256.png
Normal file
BIN
build/icons/256x256.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
BIN
build/icons/icon.icns
Normal file
BIN
build/icons/icon.icns
Normal file
Binary file not shown.
BIN
build/icons/icon.ico
Normal file
BIN
build/icons/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 257 KiB |
0
dist/electron/.gitkeep
vendored
Normal file
0
dist/electron/.gitkeep
vendored
Normal file
0
dist/web/.gitkeep
vendored
Normal file
0
dist/web/.gitkeep
vendored
Normal file
133
package.json
Normal file
133
package.json
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
{
|
||||||
|
"name": "picgo",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"author": "Molunerfinn <marksz@teamsz.xyz>",
|
||||||
|
"description": "Easy to upload your pic & copy to write",
|
||||||
|
"license": "MIT",
|
||||||
|
"main": "./dist/electron/main.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node .electron-vue/build.js && electron-builder",
|
||||||
|
"build:dir": "node .electron-vue/build.js && electron-builder --dir",
|
||||||
|
"build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js",
|
||||||
|
"build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
|
||||||
|
"dev": "node .electron-vue/dev-runner.js",
|
||||||
|
"e2e": "npm run pack && mocha test/e2e",
|
||||||
|
"lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src test",
|
||||||
|
"lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix src test",
|
||||||
|
"pack": "npm run pack:main && npm run pack:renderer",
|
||||||
|
"pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
|
||||||
|
"pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
|
||||||
|
"test": "npm run unit && npm run e2e",
|
||||||
|
"unit": "karma start test/unit/karma.conf.js",
|
||||||
|
"postinstall": "npm run lint:fix"
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"productName": "picgo",
|
||||||
|
"appId": "org.simulatedgreg.electron-vue",
|
||||||
|
"directories": {
|
||||||
|
"output": "build"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/electron/**/*"
|
||||||
|
],
|
||||||
|
"dmg": {
|
||||||
|
"contents": [
|
||||||
|
{
|
||||||
|
"x": 410,
|
||||||
|
"y": 150,
|
||||||
|
"type": "link",
|
||||||
|
"path": "/Applications"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 130,
|
||||||
|
"y": 150,
|
||||||
|
"type": "file"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mac": {
|
||||||
|
"icon": "build/icons/icon.icns"
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"icon": "build/icons/icon.ico"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"icon": "build/icons"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.16.1",
|
||||||
|
"element-ui": "^2.0.5",
|
||||||
|
"fs-extra": "^4.0.2",
|
||||||
|
"image-size": "^0.6.1",
|
||||||
|
"lowdb": "^1.0.0",
|
||||||
|
"request": "^2.83.0",
|
||||||
|
"request-promise": "^4.2.2",
|
||||||
|
"vue": "^2.3.3",
|
||||||
|
"vue-electron": "^1.0.6",
|
||||||
|
"vue-router": "^2.5.3",
|
||||||
|
"vuex": "^2.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.25.0",
|
||||||
|
"babel-eslint": "^7.2.3",
|
||||||
|
"babel-loader": "^7.1.1",
|
||||||
|
"babel-minify-webpack-plugin": "^0.2.0",
|
||||||
|
"babel-plugin-istanbul": "^4.1.1",
|
||||||
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
|
"babel-preset-env": "^1.6.0",
|
||||||
|
"babel-preset-stage-0": "^6.24.1",
|
||||||
|
"babel-register": "^6.24.1",
|
||||||
|
"babili-webpack-plugin": "^0.1.2",
|
||||||
|
"cfonts": "^1.1.3",
|
||||||
|
"chai": "^4.0.0",
|
||||||
|
"chalk": "^2.1.0",
|
||||||
|
"copy-webpack-plugin": "^4.0.1",
|
||||||
|
"cross-env": "^5.0.5",
|
||||||
|
"css-loader": "^0.28.4",
|
||||||
|
"del": "^3.0.0",
|
||||||
|
"devtron": "^1.4.0",
|
||||||
|
"electron": "^1.7.5",
|
||||||
|
"electron-builder": "^19.19.1",
|
||||||
|
"electron-debug": "^1.4.0",
|
||||||
|
"electron-devtools-installer": "^2.2.0",
|
||||||
|
"eslint": "^4.4.1",
|
||||||
|
"eslint-config-standard": "^10.2.1",
|
||||||
|
"eslint-friendly-formatter": "^3.0.0",
|
||||||
|
"eslint-loader": "^1.9.0",
|
||||||
|
"eslint-plugin-html": "^3.1.1",
|
||||||
|
"eslint-plugin-import": "^2.7.0",
|
||||||
|
"eslint-plugin-node": "^5.1.1",
|
||||||
|
"eslint-plugin-promise": "^3.5.0",
|
||||||
|
"eslint-plugin-standard": "^3.0.1",
|
||||||
|
"extract-text-webpack-plugin": "^3.0.0",
|
||||||
|
"file-loader": "^0.11.2",
|
||||||
|
"html-webpack-plugin": "^2.30.1",
|
||||||
|
"inject-loader": "^3.0.0",
|
||||||
|
"karma": "^1.3.0",
|
||||||
|
"karma-chai": "^0.1.0",
|
||||||
|
"karma-coverage": "^1.1.1",
|
||||||
|
"karma-electron": "^5.1.1",
|
||||||
|
"karma-mocha": "^1.2.0",
|
||||||
|
"karma-sourcemap-loader": "^0.3.7",
|
||||||
|
"karma-spec-reporter": "^0.0.31",
|
||||||
|
"karma-webpack": "^2.0.1",
|
||||||
|
"mocha": "^3.0.2",
|
||||||
|
"multispinner": "^0.2.1",
|
||||||
|
"node-loader": "^0.6.0",
|
||||||
|
"require-dir": "^0.3.0",
|
||||||
|
"spectron": "^3.7.1",
|
||||||
|
"style-loader": "^0.18.2",
|
||||||
|
"stylus": "^0.54.5",
|
||||||
|
"stylus-loader": "^3.0.1",
|
||||||
|
"url-loader": "^0.5.9",
|
||||||
|
"vue-html-loader": "^1.2.4",
|
||||||
|
"vue-loader": "^13.0.5",
|
||||||
|
"vue-style-loader": "^3.0.1",
|
||||||
|
"vue-template-compiler": "^2.4.2",
|
||||||
|
"webpack": "^3.5.2",
|
||||||
|
"webpack-dev-server": "^2.7.1",
|
||||||
|
"webpack-hot-middleware": "^2.18.2",
|
||||||
|
"webpack-merge": "^4.1.0"
|
||||||
|
}
|
||||||
|
}
|
23
src/datastore/index.js
Normal file
23
src/datastore/index.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import Datastore from 'lowdb'
|
||||||
|
import FileSync from 'lowdb/adapters/FileSync'
|
||||||
|
import path from 'path'
|
||||||
|
import { remote, app } from 'electron'
|
||||||
|
|
||||||
|
const APP = process.type === 'renderer' ? remote.app : app
|
||||||
|
const STORE_PATH = APP.getPath('userData')
|
||||||
|
|
||||||
|
const adapter = new FileSync(path.join(STORE_PATH, '/data.json'))
|
||||||
|
|
||||||
|
const db = Datastore(adapter)
|
||||||
|
|
||||||
|
if (!db.has('uploaded').value()) {
|
||||||
|
db.set('uploaded', []).write()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!db.has('picBed').value()) {
|
||||||
|
db.set('picBed', {
|
||||||
|
current: 'weibo'
|
||||||
|
}).write()
|
||||||
|
}
|
||||||
|
|
||||||
|
export default db
|
22
src/index.ejs
Normal file
22
src/index.ejs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>PicGo</title>
|
||||||
|
<% if (htmlWebpackPlugin.options.nodeModules) { %>
|
||||||
|
<!-- Add `node_modules/` to global paths so `require` works properly in development -->
|
||||||
|
<script>
|
||||||
|
require('module').globalPaths.push("<%= htmlWebpackPlugin.options.nodeModules.replace(/\\/g, '\\\\') %>")
|
||||||
|
</script>
|
||||||
|
<% } %>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- Set `__static` path to static files in production -->
|
||||||
|
<script>
|
||||||
|
if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- webpack builds are automatically injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
27
src/main/index.dev.js
Normal file
27
src/main/index.dev.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* This file is used specifically and only for development. It installs
|
||||||
|
* `electron-debug` & `vue-devtools`. There shouldn't be any need to
|
||||||
|
* modify this file, but it can be used to extend your development
|
||||||
|
* environment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
// Set environment for development
|
||||||
|
process.env.NODE_ENV = 'development'
|
||||||
|
|
||||||
|
// Install `electron-debug` with `devtron`
|
||||||
|
require('electron-debug')({ showDevTools: false })
|
||||||
|
|
||||||
|
// Install `vue-devtools`
|
||||||
|
require('electron').app.on('ready', () => {
|
||||||
|
let installExtension = require('electron-devtools-installer')
|
||||||
|
installExtension.default(installExtension.VUEJS_DEVTOOLS)
|
||||||
|
.then(() => {})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('Unable to install `vue-devtools`: \n', err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Require `main` process to boot app
|
||||||
|
require('./index')
|
230
src/main/index.js
Normal file
230
src/main/index.js
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
import { weiboUpload } from './utils/weiboUpload.js'
|
||||||
|
import { app, BrowserWindow, Tray, Menu, Notification, clipboard, ipcMain } from 'electron'
|
||||||
|
import db from '../datastore/index'
|
||||||
|
/**
|
||||||
|
* Set `__static` path to static files in production
|
||||||
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV !== 'development') {
|
||||||
|
global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
|
||||||
|
}
|
||||||
|
|
||||||
|
let window
|
||||||
|
let settingWindow
|
||||||
|
let tray
|
||||||
|
const winURL = process.env.NODE_ENV === 'development'
|
||||||
|
? `http://localhost:9080`
|
||||||
|
: `file://${__dirname}/index.html`
|
||||||
|
const settingWinURL = process.env.NODE_ENV === 'development'
|
||||||
|
? `http://localhost:9080/#setting/upload`
|
||||||
|
: `file://${__dirname}/index.html#setting/upload`
|
||||||
|
|
||||||
|
function createTray () {
|
||||||
|
tray = new Tray(`${__static}/menubarDefaultTemplate.png`)
|
||||||
|
const contextMenu = Menu.buildFromTemplate([
|
||||||
|
{
|
||||||
|
role: 'quit',
|
||||||
|
label: 'Quit'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Open setting Window',
|
||||||
|
click () {
|
||||||
|
if (settingWindow === null) {
|
||||||
|
createSettingWindow()
|
||||||
|
} else {
|
||||||
|
settingWindow.show()
|
||||||
|
settingWindow.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
tray.on('right-click', () => {
|
||||||
|
window.hide()
|
||||||
|
tray.popUpContextMenu(contextMenu)
|
||||||
|
})
|
||||||
|
tray.on('click', () => {
|
||||||
|
let img = clipboard.readImage()
|
||||||
|
let obj = []
|
||||||
|
if (!img.isEmpty()) {
|
||||||
|
obj.push({
|
||||||
|
width: img.getSize().width,
|
||||||
|
height: img.getSize().height,
|
||||||
|
imgUrl: img.toDataURL()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
toggleWindow()
|
||||||
|
setTimeout(() => {
|
||||||
|
window.webContents.send('clipboardFiles', obj)
|
||||||
|
}, 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
tray.on('drag-enter', () => {
|
||||||
|
tray.setImage(`${__static}/upload.png`)
|
||||||
|
})
|
||||||
|
|
||||||
|
tray.on('drag-end', () => {
|
||||||
|
tray.setImage(`${__static}/menubarDefaultTemplate.png`)
|
||||||
|
})
|
||||||
|
|
||||||
|
tray.on('drop-files', async (event, files) => {
|
||||||
|
const imgs = await weiboUpload(files, 'imgFromPath')
|
||||||
|
for (let i in imgs) {
|
||||||
|
clipboard.writeText(imgs[i].imgUrl)
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '上传成功',
|
||||||
|
body: imgs[i].imgUrl,
|
||||||
|
icon: files[i]
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.show()
|
||||||
|
}, i * 100)
|
||||||
|
}
|
||||||
|
console.log('drag-files')
|
||||||
|
window.webContents.send('dragFiles', imgs)
|
||||||
|
})
|
||||||
|
toggleWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
const createWindow = () => {
|
||||||
|
window = new BrowserWindow({
|
||||||
|
height: 350,
|
||||||
|
width: 196, // 196
|
||||||
|
show: false,
|
||||||
|
frame: false,
|
||||||
|
fullscreenable: false,
|
||||||
|
resizable: false,
|
||||||
|
transparent: true,
|
||||||
|
vibrancy: 'ultra-dark',
|
||||||
|
webPreferences: {
|
||||||
|
backgroundThrottling: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.loadURL(winURL)
|
||||||
|
|
||||||
|
window.on('closed', () => {
|
||||||
|
window = null
|
||||||
|
})
|
||||||
|
|
||||||
|
window.on('blur', () => {
|
||||||
|
window.hide()
|
||||||
|
})
|
||||||
|
|
||||||
|
createSettingWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
const createSettingWindow = () => {
|
||||||
|
settingWindow = new BrowserWindow({
|
||||||
|
height: 450,
|
||||||
|
width: 800,
|
||||||
|
show: true,
|
||||||
|
frame: true,
|
||||||
|
center: true,
|
||||||
|
fullscreenable: false,
|
||||||
|
resizable: false,
|
||||||
|
title: 'Pic',
|
||||||
|
vibrancy: 'ultra-dark',
|
||||||
|
transparent: true,
|
||||||
|
titleBarStyle: 'hidden',
|
||||||
|
webPreferences: {
|
||||||
|
backgroundThrottling: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
settingWindow.loadURL(settingWinURL)
|
||||||
|
|
||||||
|
settingWindow.on('closed', () => {
|
||||||
|
settingWindow = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getWindowPosition = () => {
|
||||||
|
const windowBounds = window.getBounds()
|
||||||
|
const trayBounds = tray.getBounds()
|
||||||
|
const x = Math.round(trayBounds.x + (trayBounds.width / 2) - (windowBounds.width / 2))
|
||||||
|
const y = Math.round(trayBounds.y + trayBounds.height - 10)
|
||||||
|
|
||||||
|
return {
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleWindow = () => {
|
||||||
|
if (window.isVisible()) {
|
||||||
|
window.hide()
|
||||||
|
} else {
|
||||||
|
showWindow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// const toggleSettingWindow = () => {
|
||||||
|
// if (settingWindow.isVisible()) {
|
||||||
|
// settingWindow.hide()
|
||||||
|
// } else {
|
||||||
|
// settingWindow.show()
|
||||||
|
// settingWindow.focus()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const showWindow = () => {
|
||||||
|
const position = getWindowPosition()
|
||||||
|
window.setPosition(position.x, position.y, false)
|
||||||
|
window.show()
|
||||||
|
window.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcMain.on('uploadClipboardFiles', async (evt, file) => {
|
||||||
|
const img = await weiboUpload(file, 'imgFromClipboard')
|
||||||
|
clipboard.writeText(img[0].imgUrl)
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '上传成功',
|
||||||
|
body: img[0].imgUrl,
|
||||||
|
icon: file[0]
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
clipboard.clear()
|
||||||
|
window.webContents.send('clipboardFiles', [])
|
||||||
|
window.webContents.send('uploadClipboardFiles', img)
|
||||||
|
console.log('clipboard-upload')
|
||||||
|
})
|
||||||
|
|
||||||
|
app.on('ready', () => {
|
||||||
|
createWindow()
|
||||||
|
createTray()
|
||||||
|
})
|
||||||
|
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.on('activate', () => {
|
||||||
|
if (window === null || settingWindow === null) {
|
||||||
|
createWindow()
|
||||||
|
createTray()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto Updater
|
||||||
|
*
|
||||||
|
* Uncomment the following code below and install `electron-updater` to
|
||||||
|
* support auto updating. Code Signing with a valid certificate is required.
|
||||||
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
|
||||||
|
*/
|
||||||
|
|
||||||
|
// import { autoUpdater } from 'electron-updater'
|
||||||
|
|
||||||
|
// autoUpdater.on('update-downloaded', () => {
|
||||||
|
// autoUpdater.quitAndInstall()
|
||||||
|
// })
|
||||||
|
|
||||||
|
// app.on('ready', () => {
|
||||||
|
// if (process.env.NODE_ENV === 'production') {
|
||||||
|
// autoUpdater.checkForUpdates()
|
||||||
|
// }
|
||||||
|
// })
|
35
src/main/utils/img2base64.js
Normal file
35
src/main/utils/img2base64.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import fs from 'fs-extra'
|
||||||
|
import path from 'path'
|
||||||
|
import sizeOf from 'image-size'
|
||||||
|
|
||||||
|
const imgFromPath = async (imgPath) => {
|
||||||
|
let results = []
|
||||||
|
await Promise.all(imgPath.map(async item => {
|
||||||
|
let buffer = await fs.readFile(item)
|
||||||
|
let base64Image = Buffer.from(buffer, 'binary').toString('base64')
|
||||||
|
let fileName = path.basename(item)
|
||||||
|
let imgSize = sizeOf(item)
|
||||||
|
results.push({
|
||||||
|
base64Image,
|
||||||
|
fileName,
|
||||||
|
width: imgSize.width,
|
||||||
|
height: imgSize.height
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
const imgFromClipboard = (file) => {
|
||||||
|
let result = []
|
||||||
|
result.push({
|
||||||
|
base64Image: file.imgUrl.replace(/^data\S+,/, ''),
|
||||||
|
width: file.width,
|
||||||
|
height: file.height
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
imgFromPath,
|
||||||
|
imgFromClipboard
|
||||||
|
}
|
66
src/main/utils/weiboUpload.js
Normal file
66
src/main/utils/weiboUpload.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import request from 'request-promise'
|
||||||
|
import * as img2Base64 from './img2base64'
|
||||||
|
import db from '../../datastore/index'
|
||||||
|
import { Notification } from 'electron'
|
||||||
|
const j = request.jar()
|
||||||
|
const rp = request.defaults({jar: j})
|
||||||
|
const UPLOAD_URL = 'http://picupload.service.weibo.com/interface/pic_upload.php?ori=1&mime=image%2Fjpeg&data=base64&url=0&markpos=1&logo=&nick=0&marks=1&app=miniblog'
|
||||||
|
|
||||||
|
function postOptions (formData) {
|
||||||
|
return {
|
||||||
|
method: 'POST',
|
||||||
|
url: 'https://passport.weibo.cn/sso/login',
|
||||||
|
headers: {
|
||||||
|
Referer: 'https://passport.weibo.cn/signin/login',
|
||||||
|
contentType: 'application/x-www-form-urlencoded'
|
||||||
|
},
|
||||||
|
formData,
|
||||||
|
json: true,
|
||||||
|
resolveWithFullResponse: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const weiboUpload = async function (img, type) {
|
||||||
|
try {
|
||||||
|
const formData = {
|
||||||
|
username: db.read().get('picBed.weibo.username').value(),
|
||||||
|
password: db.read().get('picBed.weibo.password').value()
|
||||||
|
}
|
||||||
|
const options = postOptions(formData)
|
||||||
|
const res = await rp(options)
|
||||||
|
if (res.body.retcode === 20000000) {
|
||||||
|
for (let i in res.body.data.crossdomainlist) {
|
||||||
|
await rp.get(res.body.data.crossdomainlist[i])
|
||||||
|
}
|
||||||
|
const imgList = await img2Base64[type](img)
|
||||||
|
let resText = []
|
||||||
|
for (let i in imgList) {
|
||||||
|
let result = await rp.post(UPLOAD_URL, {
|
||||||
|
formData: {
|
||||||
|
b64_data: imgList[i].base64Image
|
||||||
|
}
|
||||||
|
})
|
||||||
|
resText.push(result.replace(/<.*?\/>/, '').replace(/<(\w+).*?>.*?<\/\1>/, ''))
|
||||||
|
}
|
||||||
|
for (let i in imgList) {
|
||||||
|
const resTextJson = JSON.parse(resText[i])
|
||||||
|
imgList[i]['imgUrl'] = `https://ws1.sinaimg.cn/large/${resTextJson.data.pics.pic_1.pid}`
|
||||||
|
delete imgList[i].base64Image
|
||||||
|
}
|
||||||
|
return imgList
|
||||||
|
} else {
|
||||||
|
const notification = new Notification({
|
||||||
|
title: '上传失败!',
|
||||||
|
body: res.body.msg
|
||||||
|
})
|
||||||
|
notification.show()
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('This is error', err, err.name === 'RequestError')
|
||||||
|
throw new Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
weiboUpload
|
||||||
|
}
|
20
src/renderer/App.vue
Normal file
20
src/renderer/App.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<router-view></router-view>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'picgo'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus">
|
||||||
|
body,
|
||||||
|
html
|
||||||
|
padding 0
|
||||||
|
margin 0
|
||||||
|
height 100%
|
||||||
|
font-family "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif
|
||||||
|
</style>
|
0
src/renderer/assets/.gitkeep
Normal file
0
src/renderer/assets/.gitkeep
Normal file
BIN
src/renderer/assets/logo.png
Normal file
BIN
src/renderer/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
83
src/renderer/components/SettingPage.vue
Normal file
83
src/renderer/components/SettingPage.vue
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<div id="setting-page">
|
||||||
|
<div class="fake-title-bar">
|
||||||
|
PicGo
|
||||||
|
</div>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="5">
|
||||||
|
<el-menu
|
||||||
|
class="picgo-sidebar"
|
||||||
|
:default-active="defaultActive"
|
||||||
|
@select="handleSelect"
|
||||||
|
>
|
||||||
|
<el-menu-item index="upload">
|
||||||
|
<i class="el-icon-upload"></i>
|
||||||
|
<span slot="title">上传区</span>
|
||||||
|
</el-menu-item>
|
||||||
|
<el-menu-item index="weibo">
|
||||||
|
<i class="el-icon-setting"></i>
|
||||||
|
<span slot="title">微博设置</span>
|
||||||
|
</el-menu-item>
|
||||||
|
</el-menu>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="19">
|
||||||
|
<router-view></router-view>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'setting-page',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
defaultActive: 'upload'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSelect (index) {
|
||||||
|
this.$router.push({
|
||||||
|
name: index
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeRouteEnter: (to, from, next) => {
|
||||||
|
next(vm => {
|
||||||
|
vm.defaultActive = to.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang='stylus'>
|
||||||
|
#setting-page
|
||||||
|
.fake-title-bar
|
||||||
|
-webkit-app-region drag
|
||||||
|
height h = 22px
|
||||||
|
width 100%
|
||||||
|
text-align center
|
||||||
|
color #eee
|
||||||
|
font-size 12px
|
||||||
|
line-height h
|
||||||
|
.picgo-sidebar
|
||||||
|
height calc(100vh - 22px)
|
||||||
|
.el-menu
|
||||||
|
border-right none
|
||||||
|
background transparent
|
||||||
|
&-item
|
||||||
|
color #eee
|
||||||
|
position relative
|
||||||
|
&:focus,
|
||||||
|
&:hover
|
||||||
|
color #fff
|
||||||
|
background transparent
|
||||||
|
&.is-active
|
||||||
|
color active-color = #409EFF
|
||||||
|
&:before
|
||||||
|
content ''
|
||||||
|
position absolute
|
||||||
|
width 3px
|
||||||
|
height 20px
|
||||||
|
right 0
|
||||||
|
top 18px
|
||||||
|
background active-color
|
||||||
|
</style>
|
37
src/renderer/components/SettingView/ChoosePicBed.vue
Normal file
37
src/renderer/components/SettingView/ChoosePicBed.vue
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<div id="choose-pic-bed">
|
||||||
|
<span>选择 {{ label }} 作为你默认图床:</span>
|
||||||
|
<el-switch
|
||||||
|
v-model="value"
|
||||||
|
@change="choosePicBed"
|
||||||
|
>
|
||||||
|
</el-switch>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'choose-pic-bed',
|
||||||
|
props: {
|
||||||
|
type: String,
|
||||||
|
label: String
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
if (this.type === this.$db.get('picBed.current').value()) {
|
||||||
|
this.value = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
choosePicBed (val) {
|
||||||
|
this.$db.set('picBed.current', this.type)
|
||||||
|
this.$emit('update:choosed', this.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang='stylus'>
|
||||||
|
</style>
|
17
src/renderer/components/SettingView/Upload.vue
Normal file
17
src/renderer/components/SettingView/Upload.vue
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<div id="upload-view">
|
||||||
|
upload
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'upload',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
msg: '123'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang='stylus'>
|
||||||
|
</style>
|
94
src/renderer/components/SettingView/Weibo.vue
Normal file
94
src/renderer/components/SettingView/Weibo.vue
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<div id="weibo-view">
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12" :offset="6">
|
||||||
|
<div class="view-title">
|
||||||
|
微博图床设置
|
||||||
|
</div>
|
||||||
|
<el-form
|
||||||
|
ref="weiboForm"
|
||||||
|
label-position="top"
|
||||||
|
label-width="80px"
|
||||||
|
:model="form">
|
||||||
|
<el-form-item
|
||||||
|
label="设定用户名"
|
||||||
|
prop="username"
|
||||||
|
:rules="{
|
||||||
|
required: true, message: '用户名不能为空', trigger: 'blur'
|
||||||
|
}">
|
||||||
|
<el-input v-model="form.username" placeholder="用户名"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
label="设定密码"
|
||||||
|
prop="password"
|
||||||
|
:rules="{
|
||||||
|
required: true, message: '密码不能为空', trigger: 'blur'
|
||||||
|
}">
|
||||||
|
<el-input v-model="form.password" type="password" placeholder="密码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="confirm('weiboForm')">确定</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'weibo',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
username: '',
|
||||||
|
password: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
const account = this.$db.get('picBed.weibo').value()
|
||||||
|
console.log(account)
|
||||||
|
if (account) {
|
||||||
|
this.form.username = account.username
|
||||||
|
this.form.password = account.password
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
confirm (formName) {
|
||||||
|
this.$refs[formName].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.$db.set('picBed.weibo', {
|
||||||
|
username: this.form.username,
|
||||||
|
password: this.form.password
|
||||||
|
}).write()
|
||||||
|
console.log(this.$db.get('picBed.weibo').value())
|
||||||
|
this.$message({
|
||||||
|
type: 'success',
|
||||||
|
message: '设置成功'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang='stylus'>
|
||||||
|
.el-message
|
||||||
|
left 60%
|
||||||
|
#weibo-view
|
||||||
|
.view-title
|
||||||
|
color #eee
|
||||||
|
font-size 20px
|
||||||
|
text-align center
|
||||||
|
margin 20px auto
|
||||||
|
.el-form
|
||||||
|
label
|
||||||
|
line-height 22px
|
||||||
|
padding-bottom 0
|
||||||
|
color #eee
|
||||||
|
.el-button
|
||||||
|
width 100%
|
||||||
|
margin-top 10px
|
||||||
|
</style>
|
142
src/renderer/components/TrayPage.vue
Normal file
142
src/renderer/components/TrayPage.vue
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<div id="tray-page">
|
||||||
|
<div class="content">
|
||||||
|
<div class="wait-upload-img" v-if="clipboardFiles.length > 0">
|
||||||
|
<div class="list-title">等待上传</div>
|
||||||
|
<div v-for="(item, index) in clipboardFiles" :key="index" class="img-list" :style="{height: calcHeight(item.width, item.height) + 'px'}">
|
||||||
|
<div class="upload-img__container" @click="uploadClipboardFiles">
|
||||||
|
<img :src="item.imgUrl" class="upload-img">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="uploaded-img">
|
||||||
|
<div class="list-title">已上传</div>
|
||||||
|
<div v-for="(item, index) in files" :key="index" class="img-list" :style="{height: calcHeight(item.width, item.height) + 'px'}">
|
||||||
|
<div class="upload-img__container" @click="copyTheLink(item)">
|
||||||
|
<img :src="item.imgUrl" class="upload-img">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'tray-page',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
files: [],
|
||||||
|
notification: {
|
||||||
|
title: '复制链接成功',
|
||||||
|
body: '',
|
||||||
|
icon: ''
|
||||||
|
},
|
||||||
|
clipboardFiles: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
reverseList () {
|
||||||
|
return this.files.slice().reverse()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.disableDragFile()
|
||||||
|
this.getData()
|
||||||
|
this.$electron.ipcRenderer.on('dragFiles', (event, files) => {
|
||||||
|
this.$db.get('uploaded').push(...files).write()
|
||||||
|
this.files = this.$db.get('uploaded').slice().reverse().slice(0, 5).value()
|
||||||
|
})
|
||||||
|
this.$electron.ipcRenderer.on('clipboardFiles', (event, files) => {
|
||||||
|
this.clipboardFiles = files
|
||||||
|
})
|
||||||
|
this.$electron.ipcRenderer.on('uploadClipboardFiles', (event, files) => {
|
||||||
|
this.$db.get('uploaded').push(...files).write()
|
||||||
|
this.files = this.$db.get('uploaded').slice().reverse().slice(0, 5).value()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getData () {
|
||||||
|
this.files = this.$db.get('uploaded').slice().reverse().slice(0, 5).value()
|
||||||
|
},
|
||||||
|
copyTheLink (item) {
|
||||||
|
this.notification.body = item.imgUrl
|
||||||
|
this.notification.icon = item.imgUrl
|
||||||
|
const myNotification = new window.Notification(this.notification.title, this.notification)
|
||||||
|
myNotification.onclick = () => {
|
||||||
|
this.$electron.clipboard.writeText(item.imgUrl)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
calcHeight (width, height) {
|
||||||
|
return height * 160 / width
|
||||||
|
},
|
||||||
|
disableDragFile () {
|
||||||
|
window.addEventListener('dragover', (e) => {
|
||||||
|
e = e || event
|
||||||
|
e.preventDefault()
|
||||||
|
}, false)
|
||||||
|
window.addEventListener('drop', (e) => {
|
||||||
|
e = e || event
|
||||||
|
e.preventDefault()
|
||||||
|
}, false)
|
||||||
|
},
|
||||||
|
uploadClipboardFiles () {
|
||||||
|
this.$electron.ipcRenderer.send('uploadClipboardFiles', this.clipboardFiles[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus">
|
||||||
|
#tray-page
|
||||||
|
.list-title
|
||||||
|
text-align center
|
||||||
|
color #858585
|
||||||
|
font-size 12px
|
||||||
|
padding 6px 0
|
||||||
|
position relative
|
||||||
|
&:before
|
||||||
|
content ''
|
||||||
|
position absolute
|
||||||
|
height 1px
|
||||||
|
width calc(100% - 36px)
|
||||||
|
bottom 0
|
||||||
|
left 18px
|
||||||
|
background #858585
|
||||||
|
.header-arrow
|
||||||
|
position absolute
|
||||||
|
top 12px
|
||||||
|
left 50%
|
||||||
|
margin-left -10px
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 10px solid transparent
|
||||||
|
border-right: 10px solid transparent
|
||||||
|
border-bottom: 10px solid rgba(255,255,255, 1)
|
||||||
|
.content
|
||||||
|
position absolute
|
||||||
|
top 0px
|
||||||
|
width 100%
|
||||||
|
// padding-top 10px
|
||||||
|
// background-color rgba(255,255,255, 1)
|
||||||
|
.img-list
|
||||||
|
padding 16px 8px
|
||||||
|
display flex
|
||||||
|
justify-content space-between
|
||||||
|
align-items center
|
||||||
|
height 45px
|
||||||
|
cursor pointer
|
||||||
|
transition all .2s ease-in-out
|
||||||
|
&:hover
|
||||||
|
background #49B1F5
|
||||||
|
.upload-img__index
|
||||||
|
color #fff
|
||||||
|
.upload-img
|
||||||
|
height 100%
|
||||||
|
width 100%
|
||||||
|
margin 0 auto
|
||||||
|
&__container
|
||||||
|
width 100%
|
||||||
|
padding 8px 10px
|
||||||
|
height 100%
|
||||||
|
</style>
|
22
src/renderer/main.js
Normal file
22
src/renderer/main.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import axios from 'axios'
|
||||||
|
import ElementUI from 'element-ui'
|
||||||
|
import 'element-ui/lib/theme-chalk/index.css'
|
||||||
|
import App from './App'
|
||||||
|
import router from './router'
|
||||||
|
import store from './store'
|
||||||
|
import db from '../datastore/index'
|
||||||
|
Vue.use(ElementUI)
|
||||||
|
|
||||||
|
if (!process.env.IS_WEB) Vue.use(require('vue-electron'))
|
||||||
|
Vue.http = Vue.prototype.$http = axios
|
||||||
|
Vue.prototype.$db = db
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
/* eslint-disable no-new */
|
||||||
|
new Vue({
|
||||||
|
components: { App },
|
||||||
|
router,
|
||||||
|
store,
|
||||||
|
template: '<App/>'
|
||||||
|
}).$mount('#app')
|
35
src/renderer/router/index.js
Normal file
35
src/renderer/router/index.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Router from 'vue-router'
|
||||||
|
|
||||||
|
Vue.use(Router)
|
||||||
|
|
||||||
|
export default new Router({
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'tray-page',
|
||||||
|
component: require('@/components/TrayPage').default
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/setting',
|
||||||
|
name: 'setting-page',
|
||||||
|
component: require('@/components/SettingPage').default,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'upload',
|
||||||
|
component: require('@/components/SettingView/Upload').default,
|
||||||
|
name: 'upload'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'weibo',
|
||||||
|
component: require('@/components/SettingView/Weibo').default,
|
||||||
|
name: 'weibo'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '*',
|
||||||
|
redirect: '/'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
11
src/renderer/store/index.js
Normal file
11
src/renderer/store/index.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
import modules from './modules'
|
||||||
|
|
||||||
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
export default new Vuex.Store({
|
||||||
|
modules,
|
||||||
|
strict: process.env.NODE_ENV !== 'production'
|
||||||
|
})
|
25
src/renderer/store/modules/Counter.js
Normal file
25
src/renderer/store/modules/Counter.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const state = {
|
||||||
|
main: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
DECREMENT_MAIN_COUNTER (state) {
|
||||||
|
state.main--
|
||||||
|
},
|
||||||
|
INCREMENT_MAIN_COUNTER (state) {
|
||||||
|
state.main++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
someAsyncTask ({ commit }) {
|
||||||
|
// do something async
|
||||||
|
commit('INCREMENT_MAIN_COUNTER')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state,
|
||||||
|
mutations,
|
||||||
|
actions
|
||||||
|
}
|
14
src/renderer/store/modules/index.js
Normal file
14
src/renderer/store/modules/index.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* The file enables `@/store/index.js` to import all vuex modules
|
||||||
|
* in a one-shot manner. There should not be any reason to edit this file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const files = require.context('.', false, /\.js$/)
|
||||||
|
const modules = {}
|
||||||
|
|
||||||
|
files.keys().forEach(key => {
|
||||||
|
if (key === './index.js') return
|
||||||
|
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
|
||||||
|
})
|
||||||
|
|
||||||
|
export default modules
|
0
static/.gitkeep
Normal file
0
static/.gitkeep
Normal file
BIN
static/hexo-theme-melody-logo.png
Normal file
BIN
static/hexo-theme-melody-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
BIN
static/menubarDefaultTemplate.png
Normal file
BIN
static/menubarDefaultTemplate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 438 B |
BIN
static/upload.png
Normal file
BIN
static/upload.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 337 B |
11
test/.eslintrc
Normal file
11
test/.eslintrc
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"mocha": true
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"assert": true,
|
||||||
|
"expect": true,
|
||||||
|
"should": true,
|
||||||
|
"__static": true
|
||||||
|
}
|
||||||
|
}
|
18
test/e2e/index.js
Normal file
18
test/e2e/index.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
// Set BABEL_ENV to use proper env config
|
||||||
|
process.env.BABEL_ENV = 'test'
|
||||||
|
|
||||||
|
// Enable use of ES6+ on required files
|
||||||
|
require('babel-register')({
|
||||||
|
ignore: /node_modules/
|
||||||
|
})
|
||||||
|
|
||||||
|
// Attach Chai APIs to global scope
|
||||||
|
const { expect, should, assert } = require('chai')
|
||||||
|
global.expect = expect
|
||||||
|
global.should = should
|
||||||
|
global.assert = assert
|
||||||
|
|
||||||
|
// Require all JS files in `./specs` for Mocha to consume
|
||||||
|
require('require-dir')('./specs')
|
13
test/e2e/specs/Launch.spec.js
Normal file
13
test/e2e/specs/Launch.spec.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import utils from '../utils'
|
||||||
|
|
||||||
|
describe('Launch', function () {
|
||||||
|
beforeEach(utils.beforeEach)
|
||||||
|
afterEach(utils.afterEach)
|
||||||
|
|
||||||
|
it('shows the proper application title', function () {
|
||||||
|
return this.app.client.getTitle()
|
||||||
|
.then(title => {
|
||||||
|
expect(title).to.equal('picgo')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
23
test/e2e/utils.js
Normal file
23
test/e2e/utils.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import electron from 'electron'
|
||||||
|
import { Application } from 'spectron'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
afterEach () {
|
||||||
|
this.timeout(10000)
|
||||||
|
|
||||||
|
if (this.app && this.app.isRunning()) {
|
||||||
|
return this.app.stop()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeEach () {
|
||||||
|
this.timeout(10000)
|
||||||
|
this.app = new Application({
|
||||||
|
path: electron,
|
||||||
|
args: ['dist/electron/main.js'],
|
||||||
|
startTimeout: 10000,
|
||||||
|
waitTimeout: 10000
|
||||||
|
})
|
||||||
|
|
||||||
|
return this.app.start()
|
||||||
|
}
|
||||||
|
}
|
13
test/unit/index.js
Normal file
13
test/unit/index.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
Vue.config.devtools = false
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
// require all test files (files that ends with .spec.js)
|
||||||
|
const testsContext = require.context('./specs', true, /\.spec$/)
|
||||||
|
testsContext.keys().forEach(testsContext)
|
||||||
|
|
||||||
|
// require all src files except main.js for coverage.
|
||||||
|
// you can also change this to match only the subset of files that
|
||||||
|
// you want coverage for.
|
||||||
|
const srcContext = require.context('../../src/renderer', true, /^\.\/(?!main(\.js)?$)/)
|
||||||
|
srcContext.keys().forEach(srcContext)
|
62
test/unit/karma.conf.js
Normal file
62
test/unit/karma.conf.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
const merge = require('webpack-merge')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
|
const baseConfig = require('../../.electron-vue/webpack.renderer.config')
|
||||||
|
const projectRoot = path.resolve(__dirname, '../../src/renderer')
|
||||||
|
|
||||||
|
// Set BABEL_ENV to use proper preset config
|
||||||
|
process.env.BABEL_ENV = 'test'
|
||||||
|
|
||||||
|
let webpackConfig = merge(baseConfig, {
|
||||||
|
devtool: '#inline-source-map',
|
||||||
|
plugins: [
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': '"testing"'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// don't treat dependencies as externals
|
||||||
|
delete webpackConfig.entry
|
||||||
|
delete webpackConfig.externals
|
||||||
|
delete webpackConfig.output.libraryTarget
|
||||||
|
|
||||||
|
// apply vue option to apply isparta-loader on js
|
||||||
|
webpackConfig.module.rules
|
||||||
|
.find(rule => rule.use.loader === 'vue-loader').use.options.loaders.js = 'babel-loader'
|
||||||
|
|
||||||
|
module.exports = config => {
|
||||||
|
config.set({
|
||||||
|
browsers: ['visibleElectron'],
|
||||||
|
client: {
|
||||||
|
useIframe: false
|
||||||
|
},
|
||||||
|
coverageReporter: {
|
||||||
|
dir: './coverage',
|
||||||
|
reporters: [
|
||||||
|
{ type: 'lcov', subdir: '.' },
|
||||||
|
{ type: 'text-summary' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
customLaunchers: {
|
||||||
|
'visibleElectron': {
|
||||||
|
base: 'Electron',
|
||||||
|
flags: ['--show']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
frameworks: ['mocha', 'chai'],
|
||||||
|
files: ['./index.js'],
|
||||||
|
preprocessors: {
|
||||||
|
'./index.js': ['webpack', 'sourcemap']
|
||||||
|
},
|
||||||
|
reporters: ['spec', 'coverage'],
|
||||||
|
singleRun: true,
|
||||||
|
webpack: webpackConfig,
|
||||||
|
webpackMiddleware: {
|
||||||
|
noInfo: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
13
test/unit/specs/LandingPage.spec.js
Normal file
13
test/unit/specs/LandingPage.spec.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import LandingPage from '@/components/LandingPage'
|
||||||
|
|
||||||
|
describe('LandingPage.vue', () => {
|
||||||
|
it('should render correct contents', () => {
|
||||||
|
const vm = new Vue({
|
||||||
|
el: document.createElement('div'),
|
||||||
|
render: h => h(LandingPage)
|
||||||
|
}).$mount()
|
||||||
|
|
||||||
|
expect(vm.$el.querySelector('.title').textContent).to.contain('Welcome to your new project!')
|
||||||
|
})
|
||||||
|
})
|
150
yarn-error.log
Normal file
150
yarn-error.log
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
Arguments:
|
||||||
|
/usr/local/bin/node /usr/local/Cellar/yarn/1.2.1/libexec/bin/yarn.js
|
||||||
|
|
||||||
|
PATH:
|
||||||
|
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/aria2/bin
|
||||||
|
|
||||||
|
Yarn version:
|
||||||
|
1.2.1
|
||||||
|
|
||||||
|
Node version:
|
||||||
|
8.9.0
|
||||||
|
|
||||||
|
Platform:
|
||||||
|
darwin x64
|
||||||
|
|
||||||
|
npm manifest:
|
||||||
|
{
|
||||||
|
"name": "picgo",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"author": "Molunerfinn <marksz@teamsz.xyz>",
|
||||||
|
"description": "Easy to upload your pic & copy to write",
|
||||||
|
"license": null,
|
||||||
|
"main": "./dist/electron/main.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node .electron-vue/build.js && electron-builder",
|
||||||
|
"build:dir": "node .electron-vue/build.js && electron-builder --dir",
|
||||||
|
"build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js",
|
||||||
|
"build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
|
||||||
|
"dev": "node .electron-vue/dev-runner.js",
|
||||||
|
"e2e": "npm run pack && mocha test/e2e",
|
||||||
|
"lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src test",
|
||||||
|
"lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix src test",
|
||||||
|
"pack": "npm run pack:main && npm run pack:renderer",
|
||||||
|
"pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
|
||||||
|
"pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
|
||||||
|
"test": "npm run unit && npm run e2e",
|
||||||
|
"unit": "karma start test/unit/karma.conf.js",
|
||||||
|
"postinstall": "npm run lint:fix"
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"productName": "picgo",
|
||||||
|
"appId": "org.simulatedgreg.electron-vue",
|
||||||
|
"directories": {
|
||||||
|
"output": "build"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/electron/**/*"
|
||||||
|
],
|
||||||
|
"dmg": {
|
||||||
|
"contents": [
|
||||||
|
{
|
||||||
|
"x": 410,
|
||||||
|
"y": 150,
|
||||||
|
"type": "link",
|
||||||
|
"path": "/Applications"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 130,
|
||||||
|
"y": 150,
|
||||||
|
"type": "file"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mac": {
|
||||||
|
"icon": "build/icons/icon.icns"
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"icon": "build/icons/icon.ico"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"icon": "build/icons"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vue": "^2.3.3",
|
||||||
|
"axios": "^0.16.1",
|
||||||
|
"vue-electron": "^1.0.6",
|
||||||
|
"vue-router": "^2.5.3",
|
||||||
|
"vuex": "^2.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.25.0",
|
||||||
|
"babel-loader": "^7.1.1",
|
||||||
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
|
"babel-preset-env": "^1.6.0",
|
||||||
|
"babel-preset-stage-0": "^6.24.1",
|
||||||
|
"babel-register": "^6.24.1",
|
||||||
|
"babili-webpack-plugin": "^0.1.2",
|
||||||
|
"cfonts": "^1.1.3",
|
||||||
|
"chalk": "^2.1.0",
|
||||||
|
"copy-webpack-plugin": "^4.0.1",
|
||||||
|
"cross-env": "^5.0.5",
|
||||||
|
"css-loader": "^0.28.4",
|
||||||
|
"del": "^3.0.0",
|
||||||
|
"devtron": "^1.4.0",
|
||||||
|
"electron": "^1.7.5",
|
||||||
|
"electron-debug": "^1.4.0",
|
||||||
|
"electron-devtools-installer": "^2.2.0",
|
||||||
|
"electron-builder": "^19.19.1",
|
||||||
|
"babel-eslint": "^7.2.3",
|
||||||
|
"eslint": "^4.4.1",
|
||||||
|
"eslint-friendly-formatter": "^3.0.0",
|
||||||
|
"eslint-loader": "^1.9.0",
|
||||||
|
"eslint-plugin-html": "^3.1.1",
|
||||||
|
"eslint-config-standard": "^10.2.1",
|
||||||
|
"eslint-plugin-import": "^2.7.0",
|
||||||
|
"eslint-plugin-node": "^5.1.1",
|
||||||
|
"eslint-plugin-promise": "^3.5.0",
|
||||||
|
"eslint-plugin-standard": "^3.0.1",
|
||||||
|
"extract-text-webpack-plugin": "^3.0.0",
|
||||||
|
"file-loader": "^0.11.2",
|
||||||
|
"html-webpack-plugin": "^2.30.1",
|
||||||
|
"inject-loader": "^3.0.0",
|
||||||
|
"karma": "^1.3.0",
|
||||||
|
"karma-chai": "^0.1.0",
|
||||||
|
"karma-coverage": "^1.1.1",
|
||||||
|
"karma-electron": "^5.1.1",
|
||||||
|
"karma-mocha": "^1.2.0",
|
||||||
|
"karma-sourcemap-loader": "^0.3.7",
|
||||||
|
"karma-spec-reporter": "^0.0.31",
|
||||||
|
"karma-webpack": "^2.0.1",
|
||||||
|
"webpack-merge": "^4.1.0",
|
||||||
|
"require-dir": "^0.3.0",
|
||||||
|
"spectron": "^3.7.1",
|
||||||
|
"babel-plugin-istanbul": "^4.1.1",
|
||||||
|
"chai": "^4.0.0",
|
||||||
|
"mocha": "^3.0.2",
|
||||||
|
"multispinner": "^0.2.1",
|
||||||
|
"node-loader": "^0.6.0",
|
||||||
|
"style-loader": "^0.18.2",
|
||||||
|
"url-loader": "^0.5.9",
|
||||||
|
"vue-html-loader": "^1.2.4",
|
||||||
|
"vue-loader": "^13.0.5",
|
||||||
|
"vue-style-loader": "^3.0.1",
|
||||||
|
"vue-template-compiler": "^2.4.2",
|
||||||
|
"webpack": "^3.5.2",
|
||||||
|
"webpack-dev-server": "^2.7.1",
|
||||||
|
"webpack-hot-middleware": "^2.18.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yarn manifest:
|
||||||
|
No manifest
|
||||||
|
|
||||||
|
Lockfile:
|
||||||
|
No lockfile
|
||||||
|
|
||||||
|
Trace:
|
||||||
|
Error: http://registry.npm.taobao.org/caniuse-db/download/caniuse-db-1.0.30000766.tgz: unexpected end of file
|
||||||
|
at Gunzip.zlibOnError (zlib.js:153:15)
|
Loading…
Reference in New Issue
Block a user