feature: feedback via twitter

bugfix: can not save when there is no file edited
optimization: Don't show welcome page when init App
This commit is contained in:
Jocs 2018-06-12 19:42:31 +08:00
parent fe6645e684
commit 8c392a7a5c
19 changed files with 3252 additions and 2929 deletions

5786
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -247,6 +247,10 @@ export const newTab = win => {
win.webContents.send('AGANI::new-tab') win.webContents.send('AGANI::new-tab')
} }
export const closeTab = win => {
win.webContents.send('AGANI::close-tab')
}
export const save = win => { export const save = win => {
win.webContents.send('AGANI::ask-file-save') win.webContents.send('AGANI::ask-file-save')
} }

View File

@ -1,3 +1,7 @@
export const showAboutDialog = win => { export const showAboutDialog = win => {
win.webContents.send('AGANI::about-dialog') win.webContents.send('AGANI::about-dialog')
} }
export const showTweetDialog = (win, type) => {
win.webContents.send('AGANI::tweet', type)
}

View File

@ -76,6 +76,14 @@ export default function (recentlyUsedFiles) {
fileMenu.submenu.push({ fileMenu.submenu.push({
type: 'separator' type: 'separator'
}, {
label: 'Close Tab',
accelerator: 'CmdOrCtrl+W',
click (menuItem, browserWindow) {
actions.closeTab(browserWindow)
}
}, {
type: 'separator'
}, { }, {
label: 'Save', label: 'Save',
accelerator: 'CmdOrCtrl+S', accelerator: 'CmdOrCtrl+S',

View File

@ -10,34 +10,41 @@ export default {
role: 'help', role: 'help',
submenu: [{ submenu: [{
label: 'Learn More', label: 'Learn More',
click: function () { click () {
shell.openExternal('https://github.com/marktext/marktext') shell.openExternal('https://github.com/marktext/marktext')
} }
}, {
label: 'Report Issue',
click: function () {
shell.openExternal('https://github.com/marktext/marktext/issues')
}
}, { }, {
label: 'Source Code on GitHub', label: 'Source Code on GitHub',
click: function () { click () {
shell.openExternal('https://github.com/marktext/marktext') shell.openExternal('https://github.com/marktext/marktext')
} }
}, { }, {
label: 'Changelog', label: 'Changelog',
click: function () { click () {
shell.openExternal('https://github.com/marktext/marktext/blob/master/.github/CHANGELOG.md') shell.openExternal('https://github.com/marktext/marktext/blob/master/.github/CHANGELOG.md')
} }
}, { }, {
label: 'Markdown syntax', label: 'Markdown syntax',
click: function () { click () {
shell.openExternal('https://spec.commonmark.org/0.28/') shell.openExternal('https://spec.commonmark.org/0.28/')
} }
}, { }, {
type: 'separator' type: 'separator'
}, {
label: 'Feedback via Twitter',
click (item, win) {
actions.showTweetDialog(win, 'twitter')
}
}, {
label: 'Report Issue or Feature request',
click () {
shell.openExternal('https://github.com/marktext/marktext/issues')
}
}, {
type: 'separator'
}, { }, {
label: 'Follow @Jocs on Github', label: 'Follow @Jocs on Github',
click: function () { click () {
shell.openExternal('https://github.com/Jocs') shell.openExternal('https://github.com/Jocs')
} }
}, { }, {

View File

@ -42,7 +42,7 @@ export default {
}, { }, {
type: 'separator' type: 'separator'
}, { }, {
label: 'Quit', label: 'Quit Mark Text',
accelerator: 'Command+Q', accelerator: 'Command+Q',
click: app.quit click: app.quit
}] }]

View File

@ -38,7 +38,7 @@ let viewMenu = {
}, { }, {
id: 'typewriterModeMenuItem', id: 'typewriterModeMenuItem',
label: 'Typewriter Mode', label: 'Typewriter Mode',
accelerator: 'Option+CmdOrCtrl+T', accelerator: 'Alt+CmdOrCtrl+T',
type: 'checkbox', type: 'checkbox',
checked: false, checked: false,
click (item, browserWindow) { click (item, browserWindow) {

View File

@ -6,8 +6,8 @@ export default {
accelerator: 'CmdOrCtrl+M', accelerator: 'CmdOrCtrl+M',
role: 'minimize' role: 'minimize'
}, { }, {
label: 'Close', label: 'Close Window',
accelerator: 'CmdOrCtrl+W', accelerator: 'Shift+CmdOrCtrl+W',
role: 'close' role: 'close'
}] }]
} }

View File

@ -12,10 +12,10 @@
<div class="editor-middle"> <div class="editor-middle">
<side-bar></side-bar> <side-bar></side-bar>
<recent <recent
v-if="!hasCurrentFile" v-if="!hasCurrentFile && init"
></recent> ></recent>
<editor-with-tabs <editor-with-tabs
v-else v-if="hasCurrentFile && init"
:markdown="markdown" :markdown="markdown"
:cursor="cursor" :cursor="cursor"
:theme="theme" :theme="theme"
@ -32,6 +32,7 @@
<about-dialog></about-dialog> <about-dialog></about-dialog>
<font></font> <font></font>
<rename></rename> <rename></rename>
<tweet></tweet>
</div> </div>
</template> </template>
@ -46,6 +47,7 @@
import AboutDialog from '@/components/about' import AboutDialog from '@/components/about'
import Font from '@/components/font' import Font from '@/components/font'
import Rename from '@/components/rename' import Rename from '@/components/rename'
import Tweet from '@/components/tweet'
import { mapState } from 'vuex' import { mapState } from 'vuex'
export default { export default {
@ -60,7 +62,8 @@
UploadImage, UploadImage,
AboutDialog, AboutDialog,
Font, Font,
Rename Rename,
Tweet
}, },
data () { data () {
return {} return {}
@ -80,7 +83,7 @@
'wordCount': state => state.editor.currentFile.wordCount 'wordCount': state => state.editor.currentFile.wordCount
}), }),
...mapState([ ...mapState([
'windowActive', 'platform' 'windowActive', 'platform', 'init'
]), ]),
hasCurrentFile () { hasCurrentFile () {
return this.markdown !== undefined return this.markdown !== undefined
@ -90,6 +93,8 @@
const { dispatch } = this.$store const { dispatch } = this.$store
// store/index.js // store/index.js
dispatch('LINTEN_WIN_STATUS') dispatch('LINTEN_WIN_STATUS')
// module: tweet
dispatch('LISTEN_FOR_TWEET')
// module: layout // module: layout
dispatch('LISTEN_FOR_LAYOUT') dispatch('LISTEN_FOR_LAYOUT')
dispatch('LISTEN_FOR_REQUEST_LAYOUT') dispatch('LISTEN_FOR_REQUEST_LAYOUT')
@ -121,6 +126,7 @@
dispatch('LISTEN_FOR_RENAME') dispatch('LISTEN_FOR_RENAME')
dispatch('LINTEN_FOR_SET_LINE_ENDING') dispatch('LINTEN_FOR_SET_LINE_ENDING')
dispatch('LISTEN_FOR_NEW_TAB') dispatch('LISTEN_FOR_NEW_TAB')
dispatch('LISTEN_FOR_CLOSE_TAB')
// module: notification // module: notification
dispatch('LISTEN_FOR_NOTIFICATION') dispatch('LISTEN_FOR_NOTIFICATION')
} }

File diff suppressed because one or more lines are too long

View File

@ -236,6 +236,7 @@
margin-bottom: 20px; margin-bottom: 20px;
} }
.search-wrapper { .search-wrapper {
margin: 0 auto;
margin-top: 8px; margin-top: 8px;
z-index: 10000; z-index: 10000;
position: absolute; position: absolute;
@ -243,7 +244,6 @@
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
width: 410px; width: 410px;
margin: 0 auto;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -22,6 +22,7 @@
<li <li
v-for="(icon, index) of sideBarBottomIcons" v-for="(icon, index) of sideBarBottomIcons"
:key="index" :key="index"
@click="handleLeftBottomClick(icon.name)"
> >
<svg class="icon" aria-hidden="true"> <svg class="icon" aria-hidden="true">
<use :xlink:href="'#' + icon.icon"></use> <use :xlink:href="'#' + icon.icon"></use>
@ -50,6 +51,7 @@
<script> <script>
import { sideBarIcons, sideBarBottomIcons } from './help' import { sideBarIcons, sideBarBottomIcons } from './help'
import bus from '../../bus'
import Tree from './tree.vue' import Tree from './tree.vue'
import SideBarSearch from './search.vue' import SideBarSearch from './search.vue'
import Toc from './toc.vue' import Toc from './toc.vue'
@ -126,6 +128,11 @@
this.$store.commit('SET_LAYOUT', { rightColumn: name }) this.$store.commit('SET_LAYOUT', { rightColumn: name })
this.sideBarViewWidth = +this.sideBarWidth this.sideBarViewWidth = +this.sideBarWidth
} }
},
handleLeftBottomClick (name) {
if (name === 'twitter') {
bus.$emit('tweetDialog')
}
} }
} }
} }
@ -135,7 +142,6 @@
.side-bar { .side-bar {
display: flex; display: flex;
height: calc(100vh - 22px); height: calc(100vh - 22px);
overflow: hidden;
position: relative; position: relative;
color: var(--secondaryColor); color: var(--secondaryColor);
} }
@ -175,11 +181,20 @@
& > svg { & > svg {
width: 1em; width: 1em;
height: 1em; height: 1em;
opacity: 0; opacity: 1;
color: var(--secondaryColor); color: var(--secondaryColor);
} }
} }
} }
.left-column ul.bottom li {
& > svg {
transition: transform .25s ease-in-out;
}
&:hover > svg {
color: #1da1f2;
transform: scale(1.2);
}
}
.side-bar:hover .left-column ul li svg { .side-bar:hover .left-column ul li svg {
opacity: 1; opacity: 1;
} }

View File

@ -0,0 +1,200 @@
<template>
<div class="tweet-dialog" :class="theme">
<el-dialog
:visible.sync="showTweetDialog"
:show-close="false"
:modal="true"
custom-class="ag-dialog-table"
width="450px"
>
<div slot="title" class="title">
<span>Send us feedback via tweet</span>
</div>
<div class="body">
<div class="feeling">
<div>What's your experience feelings?</div>
<ul>
<li
:class="{ 'active': selectedFace === 'smile' }"
@click="faceClick('smile')"
>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-smile"></use>
</svg>
</li>
<li
:class="{ 'active': selectedFace === 'sad' }"
@click="faceClick('sad')"
>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-sad"></use>
</svg>
</li>
</ul>
</div>
<div class="feedback">
<div>Tell us your feedback?</div>
<textarea cols="30" rows="10" v-model="value" ref="textarea"></textarea>
</div>
<div class="button">
<a
href="javascript:;"
class="github"
@click="reportViaGithub"
>
Report bug or feature request via github
</a>
<a
href="javascript:;"
class="twitter"
:class="{ 'active': value }"
@click="reportViaTwitter"
>
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-twitter"></use>
</svg>
Tweet
</a>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { shell } from 'electron'
import { mapState } from 'vuex'
import bus from '../../bus'
export default {
data () {
return {
showTweetDialog: false,
value: '',
selectedFace: 'smile'
}
},
computed: {
...mapState({
'theme': state => state.preferences.theme
})
},
created () {
bus.$on('tweetDialog', this.showDialog)
},
beforeDestroy () {
bus.$off('tweetDialog', this.showDialog)
},
methods: {
showDialog () {
this.showTweetDialog = true
this.value = ''
bus.$emit('editor-blur')
this.$nextTick(() => {
this.$refs.textarea.focus()
})
},
faceClick (name) {
this.selectedFace = name
},
reportViaGithub () {
shell.openExternal('https://github.com/marktext/marktext/issues')
},
reportViaTwitter () {
const { value, selectedFace } = this
if (!value) return
const origin = 'https://twitter.com/intent/tweet'
const params = {
via: 'marktextme',
url: encodeURI('https://github.com/marktext/marktext/'),
text: value
}
if (selectedFace === 'smile') params.hashtags = 'happyMarkText'
shell.openExternal(`${origin}?${Object.keys(params).map(key => `${key}=${params[key]}`).join('&')}`)
this.showTweetDialog = false
}
}
}
</script>
<style>
.tweet-dialog {
width: 450px;
& .title {
color: var(--regularColor);
font-size: 24px;
}
}
.feeling, .feedback {
font-size: 16px;
color: var(--secondaryColor);
}
.feeling {
& ul {
display: flex;
list-style: none;
margin: 0;
padding: 0;
height: 45px;
& li {
display: flex;
align-items: center;
margin-right: 15px;
cursor: pointer;
}
}
& li > svg {
transition: color .25s ease-in-out;
width: 25px;
height: 25px;
}
& li:hover > svg, & li.active > svg {
color: rgb(255, 204, 0);
}
}
.feedback {
& > textarea {
width: 100%;
box-sizing: border-box;
margin: 15px 0;
padding: .5rem;
resize: none;
outline: none;
border-color: var(--lightBorder);
border-radius: 5px;
font-size: 14px;
height: 80px;
}
}
.button {
display: flex;
justify-content: space-between;
align-items: center;
}
.button a.twitter {
color: var(--secondaryColor);
text-decoration: none;
width: auto;
height: 30px;
line-height: 30px;
padding: 0 8px;
border-radius: 2px;
box-sizing: border-box;
display: inline-block;
background: #eee;
}
.button a.active, .button a.twitter:hover {
background: #1da1f2;
color: #fff;
}
.button a.github {
color: var(--secondaryColor);
text-decoration: none;
&:hover {
color: #1da1f2;
}
}
</style>

View File

@ -1,6 +1,7 @@
import { ipcRenderer } from 'electron' import { ipcRenderer } from 'electron'
import path from 'path' import path from 'path'
import bus from '../bus' import bus from '../bus'
import { hasKeys } from '../util'
import { getOptionsFromState, getSingleFileState, getBlankFileState } from './help' import { getOptionsFromState, getSingleFileState, getBlankFileState } from './help'
const toc = require('markdown-toc') const toc = require('markdown-toc')
@ -62,7 +63,9 @@ const mutations = {
} }
}, },
SET_SAVE_STATUS (state, status) { SET_SAVE_STATUS (state, status) {
if (hasKeys(state.currentFile)) {
state.currentFile.isSaved = status state.currentFile.isSaved = status
}
}, },
SET_SAVE_STATUS_WHEN_REMOVE (state, { pathname }) { SET_SAVE_STATUS_WHEN_REMOVE (state, { pathname }) {
state.tabs.forEach(f => { state.tabs.forEach(f => {
@ -72,25 +75,39 @@ const mutations = {
}) })
}, },
SET_MARKDOWN (state, markdown) { SET_MARKDOWN (state, markdown) {
if (hasKeys(state.currentFile)) {
state.currentFile.markdown = markdown state.currentFile.markdown = markdown
}
}, },
SET_IS_UTF8_BOM_ENCODED (state, isUtf8BomEncoded) { SET_IS_UTF8_BOM_ENCODED (state, isUtf8BomEncoded) {
if (hasKeys(state.currentFile)) {
state.currentFile.isUtf8BomEncoded = isUtf8BomEncoded state.currentFile.isUtf8BomEncoded = isUtf8BomEncoded
}
}, },
SET_LINE_ENDING (state, lineEnding) { SET_LINE_ENDING (state, lineEnding) {
if (hasKeys(state.currentFile)) {
state.currentFile.lineEnding = lineEnding state.currentFile.lineEnding = lineEnding
}
}, },
SET_ADJUST_LINE_ENDING_ON_SAVE (state, adjustLineEndingOnSave) { SET_ADJUST_LINE_ENDING_ON_SAVE (state, adjustLineEndingOnSave) {
if (hasKeys(state.currentFile)) {
state.currentFile.adjustLineEndingOnSave = adjustLineEndingOnSave state.currentFile.adjustLineEndingOnSave = adjustLineEndingOnSave
}
}, },
SET_WORD_COUNT (state, wordCount) { SET_WORD_COUNT (state, wordCount) {
if (hasKeys(state.currentFile)) {
state.currentFile.wordCount = wordCount state.currentFile.wordCount = wordCount
}
}, },
SET_CURSOR (state, cursor) { SET_CURSOR (state, cursor) {
if (hasKeys(state.currentFile)) {
state.currentFile.cursor = cursor state.currentFile.cursor = cursor
}
}, },
SET_HISTORY (state, history) { SET_HISTORY (state, history) {
if (hasKeys(state.currentFile)) {
state.currentFile.history = history state.currentFile.history = history
}
}, },
CLOSE_TABS (state, arr) { CLOSE_TABS (state, arr) {
arr.forEach(id => { arr.forEach(id => {
@ -147,13 +164,15 @@ const actions = {
// need update line ending when change between tabs // need update line ending when change between tabs
UPDATE_LINEENDING_MENU ({ commit, state }) { UPDATE_LINEENDING_MENU ({ commit, state }) {
const { lineEnding } = state.currentFile const { lineEnding } = state.currentFile
if (lineEnding) {
ipcRenderer.send('AGANI::update-line-ending-menu', lineEnding) ipcRenderer.send('AGANI::update-line-ending-menu', lineEnding)
}
}, },
CLOSE_SINGLE_FILE ({ commit, state }, file) { CLOSE_SINGLE_FILE ({ commit, state }, file) {
const { id, pathname, markdown } = file const { id, pathname, filename, markdown } = file
const options = getOptionsFromState(file) const options = getOptionsFromState(file)
ipcRenderer.send('AGANI::save-close', [{ id, pathname, markdown, options }], true) ipcRenderer.send('AGANI::save-close', [{ id, pathname, filename, markdown, options }], true)
}, },
// need pass some data to main process when `save` menu item clicked // need pass some data to main process when `save` menu item clicked
@ -161,7 +180,9 @@ const actions = {
ipcRenderer.on('AGANI::ask-file-save', () => { ipcRenderer.on('AGANI::ask-file-save', () => {
const { id, pathname, markdown } = state.currentFile const { id, pathname, markdown } = state.currentFile
const options = getOptionsFromState(state.currentFile) const options = getOptionsFromState(state.currentFile)
if (id) {
ipcRenderer.send('AGANI::response-file-save', { id, pathname, markdown, options }) ipcRenderer.send('AGANI::response-file-save', { id, pathname, markdown, options })
}
}) })
}, },
@ -170,7 +191,9 @@ const actions = {
ipcRenderer.on('AGANI::ask-file-save-as', () => { ipcRenderer.on('AGANI::ask-file-save-as', () => {
const { id, pathname, markdown } = state.currentFile const { id, pathname, markdown } = state.currentFile
const options = getOptionsFromState(state.currentFile) const options = getOptionsFromState(state.currentFile)
if (id) {
ipcRenderer.send('AGANI::response-file-save-as', { id, pathname, markdown, options }) ipcRenderer.send('AGANI::response-file-save-as', { id, pathname, markdown, options })
}
}) })
}, },
@ -233,6 +256,7 @@ const actions = {
ipcRenderer.on('AGANI::ask-file-move-to', () => { ipcRenderer.on('AGANI::ask-file-move-to', () => {
const { id, pathname, markdown } = state.currentFile const { id, pathname, markdown } = state.currentFile
const options = getOptionsFromState(state.currentFile) const options = getOptionsFromState(state.currentFile)
if (!id) return
if (!pathname) { if (!pathname) {
// if current file is a newly created file, just save it! // if current file is a newly created file, just save it!
ipcRenderer.send('AGANI::response-file-save', { id, pathname, markdown, options }) ipcRenderer.send('AGANI::response-file-save', { id, pathname, markdown, options })
@ -252,6 +276,7 @@ const actions = {
RESPONSE_FOR_RENAME ({ commit, state }) { RESPONSE_FOR_RENAME ({ commit, state }) {
const { id, pathname, markdown } = state.currentFile const { id, pathname, markdown } = state.currentFile
const options = getOptionsFromState(state.currentFile) const options = getOptionsFromState(state.currentFile)
if (!id) return
if (!pathname) { if (!pathname) {
// if current file is a newly created file, just save it! // if current file is a newly created file, just save it!
ipcRenderer.send('AGANI::response-file-save', { id, pathname, markdown, options }) ipcRenderer.send('AGANI::response-file-save', { id, pathname, markdown, options })
@ -263,7 +288,7 @@ const actions = {
// ask for main process to rename this file to a new name `newFilename` // ask for main process to rename this file to a new name `newFilename`
RENAME ({ commit, state }, newFilename) { RENAME ({ commit, state }, newFilename) {
const { id, pathname, filename } = state.currentFile const { id, pathname, filename } = state.currentFile
if (filename !== newFilename) { if (typeof filename === 'string' && filename !== newFilename) {
const newPathname = path.join(path.dirname(pathname), newFilename) const newPathname = path.join(path.dirname(pathname), newFilename)
ipcRenderer.send('AGANI::rename', { id, pathname, newPathname }) ipcRenderer.send('AGANI::rename', { id, pathname, newPathname })
} }
@ -282,6 +307,7 @@ const actions = {
const fileState = getSingleFileState({ markdown, filename, pathname, options }) const fileState = getSingleFileState({ markdown, filename, pathname, options })
const { lineEnding } = options const { lineEnding } = options
commit('SET_GLOBAL_LINE_ENDING', lineEnding) commit('SET_GLOBAL_LINE_ENDING', lineEnding)
dispatch('INIT_STATUS', true)
dispatch('UPDATE_CURRENT_FILE', fileState) dispatch('UPDATE_CURRENT_FILE', fileState)
bus.$emit('file-loaded', markdown) bus.$emit('file-loaded', markdown)
commit('SET_LAYOUT', { commit('SET_LAYOUT', {
@ -299,6 +325,19 @@ const actions = {
}) })
}, },
LISTEN_FOR_CLOSE_TAB ({ commit, state, dispatch }) {
ipcRenderer.on('AGANI::close-tab', e => {
const file = state.currentFile
if (!hasKeys(file)) return
const { isSaved } = file
if (isSaved) {
dispatch('REMOVE_FILE_IN_TABS', file)
} else {
dispatch('CLOSE_SINGLE_FILE', file)
}
})
},
NEW_BLANK_FILE ({ commit, state, dispatch }) { NEW_BLANK_FILE ({ commit, state, dispatch }) {
const { tabs, lineEnding } = state const { tabs, lineEnding } = state
const fileState = getBlankFileState(tabs, lineEnding) const fileState = getBlankFileState(tabs, lineEnding)
@ -313,6 +352,7 @@ const actions = {
const fileState = getBlankFileState(tabs, lineEnding) const fileState = getBlankFileState(tabs, lineEnding)
const { markdown } = fileState const { markdown } = fileState
commit('SET_GLOBAL_LINE_ENDING', lineEnding) commit('SET_GLOBAL_LINE_ENDING', lineEnding)
dispatch('INIT_STATUS', true)
dispatch('UPDATE_CURRENT_FILE', fileState) dispatch('UPDATE_CURRENT_FILE', fileState)
bus.$emit('file-loaded', markdown) bus.$emit('file-loaded', markdown)
commit('SET_LAYOUT', { commit('SET_LAYOUT', {
@ -385,12 +425,14 @@ const actions = {
}, },
EXPORT ({ commit, state }, { type, content }) { EXPORT ({ commit, state }, { type, content }) {
if (!hasKeys(state.currentFile)) return
const { filename, pathname } = state.currentFile const { filename, pathname } = state.currentFile
ipcRenderer.send('AGANI::response-export', { type, content, filename, pathname }) ipcRenderer.send('AGANI::response-export', { type, content, filename, pathname })
}, },
LISTEN_FOR_INSERT_IMAGE ({ commit, state }) { LISTEN_FOR_INSERT_IMAGE ({ commit, state }) {
ipcRenderer.on('AGANI::INSERT_IMAGE', (e, { filename: imagePath, type }) => { ipcRenderer.on('AGANI::INSERT_IMAGE', (e, { filename: imagePath, type }) => {
if (!hasKeys(state.currentFile)) return
if (type === 'absolute' || type === 'relative') { if (type === 'absolute' || type === 'relative') {
const { pathname } = state.currentFile const { pathname } = state.currentFile
if (type === 'relative' && pathname) { if (type === 'relative' && pathname) {

View File

@ -10,6 +10,7 @@ import layout from './layout'
import preferences from './preferences' import preferences from './preferences'
import autoUpdates from './autoUpdates' import autoUpdates from './autoUpdates'
import notification from './notification' import notification from './notification'
import tweet from './tweet'
Vue.use(Vuex) Vue.use(Vuex)
@ -17,7 +18,8 @@ Vue.use(Vuex)
const state = { const state = {
platform: process.platform, // platform of system `darwin` | `win32` | `linux` platform: process.platform, // platform of system `darwin` | `win32` | `linux`
appVersion: remote.app.getVersion(), // electron version in develop and Mark Text version in production appVersion: remote.app.getVersion(), // electron version in develop and Mark Text version in production
windowActive: true // weather current window is active or focused windowActive: true, // weather current window is active or focused
init: process.env.NODE_ENV === 'development' // weather Mark Text is inited
} }
const getters = {} const getters = {}
@ -25,6 +27,9 @@ const getters = {}
const mutations = { const mutations = {
SET_WIN_STATUS (state, status) { SET_WIN_STATUS (state, status) {
state.windowActive = status state.windowActive = status
},
SET_INIT_STATUS (state, status) {
state.init = status
} }
} }
@ -33,6 +38,9 @@ const actions = {
ipcRenderer.on('AGANI::window-active-status', (e, { status }) => { ipcRenderer.on('AGANI::window-active-status', (e, { status }) => {
commit('SET_WIN_STATUS', status) commit('SET_WIN_STATUS', status)
}) })
},
INIT_STATUS ({ commit }, status) {
commit('SET_INIT_STATUS', status)
} }
} }
@ -46,6 +54,7 @@ const store = new Vuex.Store({
listenForMain, listenForMain,
autoUpdates, autoUpdates,
notification, notification,
tweet,
// have states // have states
project, project,
aidou, aidou,

View File

@ -85,6 +85,7 @@ const mutations = {
const actions = { const actions = {
LISTEN_FOR_LOAD_PROJECT ({ commit, dispatch }) { LISTEN_FOR_LOAD_PROJECT ({ commit, dispatch }) {
ipcRenderer.on('AGANI::open-project', (e, { pathname, name }) => { ipcRenderer.on('AGANI::open-project', (e, { pathname, name }) => {
dispatch('INIT_STATUS', true)
commit('SET_PROJECT_TREE', { pathname, name }) commit('SET_PROJECT_TREE', { pathname, name })
commit('SET_LAYOUT', { commit('SET_LAYOUT', {
rightColumn: 'files', rightColumn: 'files',

View File

@ -0,0 +1,20 @@
import { ipcRenderer } from 'electron'
import bus from '../bus'
const state = {}
const getters = {}
const mutations = {}
const actions = {
LISTEN_FOR_TWEET () {
ipcRenderer.on('AGANI::tweet', (e, type) => {
if (type === 'twitter') {
bus.$emit('tweetDialog')
}
})
}
}
export default { state, getters, mutations, actions }

View File

@ -174,3 +174,5 @@ export const animatedScrollTo = function (element, to, duration, callback) {
export const getUniqueId = () => { export const getUniqueId = () => {
return `${ID_PREFEX}${id++}` return `${ID_PREFEX}${id++}`
} }
export const hasKeys = obj => Object.keys(obj).length > 0

View File

@ -81,8 +81,7 @@ body {
} }
.v-modal { .v-modal {
background: #fff; background: rgba(230, 230, 230, .9);
opacity: .8;
} }
body>*:first-child { body>*:first-child {