diff --git a/src/main/menu/actions/file.js b/src/main/menu/actions/file.js index 90669053..c966fbf7 100644 --- a/src/main/menu/actions/file.js +++ b/src/main/menu/actions/file.js @@ -74,11 +74,11 @@ const handleResponseForPrint = e => { // }) } -const handleResponseForSave = async (e, { id, markdown, pathname, options }) => { +const handleResponseForSave = async (e, { id, filename, markdown, pathname, options, defaultPath }) => { const win = BrowserWindow.fromWebContents(e.sender) let recommendFilename = getRecommendTitleFromMarkdownString(markdown) if (!recommendFilename) { - recommendFilename = 'Untitled' + recommendFilename = filename || 'Untitled' } // If the file doesn't exist on disk add it to the recently used documents later @@ -90,7 +90,7 @@ const handleResponseForSave = async (e, { id, markdown, pathname, options }) => if (!filePath) { const { filePath: dialogPath, canceled } = await dialog.showSaveDialog(win, { - defaultPath: path.join(getPath('documents'), `${recommendFilename}.md`) + defaultPath: path.join(defaultPath || getPath('documents'), `${recommendFilename}.md`) }) if (dialogPath && !canceled) { @@ -203,11 +203,11 @@ ipcMain.on('mt::save-and-close-tabs', async (e, unsavedFiles) => { } }) -ipcMain.on('AGANI::response-file-save-as', async (e, { id, markdown, pathname, options }) => { +ipcMain.on('AGANI::response-file-save-as', async (e, { id, filename, markdown, pathname, options, defaultPath }) => { const win = BrowserWindow.fromWebContents(e.sender) let recommendFilename = getRecommendTitleFromMarkdownString(markdown) if (!recommendFilename) { - recommendFilename = 'Untitled' + recommendFilename = filename || 'Untitled' } // If the file doesn't exist on disk add it to the recently used documents later @@ -216,7 +216,7 @@ ipcMain.on('AGANI::response-file-save-as', async (e, { id, markdown, pathname, o const alreadyExistOnDisk = !!pathname let { filePath, canceled } = await dialog.showSaveDialog(win, { - defaultPath: pathname || getPath('documents') + `/${recommendFilename}.md` + defaultPath: pathname || path.join(defaultPath || getPath('documents'), `${recommendFilename}.md`) }) if (filePath && !canceled) { diff --git a/src/renderer/store/editor.js b/src/renderer/store/editor.js index e1c8c7d7..b4e19501 100644 --- a/src/renderer/store/editor.js +++ b/src/renderer/store/editor.js @@ -323,23 +323,39 @@ const actions = { }, // need pass some data to main process when `save` menu item clicked - LISTEN_FOR_SAVE ({ commit, state, dispatch }) { + LISTEN_FOR_SAVE ({ state, rootState }) { ipcRenderer.on('AGANI::ask-file-save', () => { - const { id, pathname, markdown } = state.currentFile + const { id, filename, pathname, markdown } = state.currentFile const options = getOptionsFromState(state.currentFile) + const defaultPath = getRootFolderFromState(rootState) if (id) { - ipcRenderer.send('AGANI::response-file-save', { id, pathname, markdown, options }) + ipcRenderer.send('AGANI::response-file-save', { + id, + filename, + pathname, + markdown, + options, + defaultPath + }) } }) }, // need pass some data to main process when `save as` menu item clicked - LISTEN_FOR_SAVE_AS ({ commit, state }) { + LISTEN_FOR_SAVE_AS ({ state, rootState }) { ipcRenderer.on('AGANI::ask-file-save-as', () => { - const { id, pathname, markdown } = state.currentFile + const { id, filename, pathname, markdown } = state.currentFile const options = getOptionsFromState(state.currentFile) + const defaultPath = getRootFolderFromState(rootState) if (id) { - ipcRenderer.send('AGANI::response-file-save-as', { id, pathname, markdown, options }) + ipcRenderer.send('AGANI::response-file-save-as', { + id, + filename, + pathname, + markdown, + options, + defaultPath + }) } }) }, @@ -430,14 +446,22 @@ const actions = { } }, - LISTEN_FOR_MOVE_TO ({ commit, state }) { + LISTEN_FOR_MOVE_TO ({ state, rootState }) { ipcRenderer.on('AGANI::ask-file-move-to', () => { - const { id, pathname, markdown } = state.currentFile + const { id, filename, pathname, markdown } = state.currentFile const options = getOptionsFromState(state.currentFile) + const defaultPath = getRootFolderFromState(rootState) if (!id) return if (!pathname) { // 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, + filename, + pathname, + markdown, + options, + defaultPath + }) } else { // if not, move to a new(maybe) folder ipcRenderer.send('AGANI::response-file-move-to', { id, pathname }) @@ -451,13 +475,21 @@ const actions = { }) }, - RESPONSE_FOR_RENAME ({ commit, state }) { - const { id, pathname, markdown } = state.currentFile + RESPONSE_FOR_RENAME ({ state, rootState }) { + const { id, filename, pathname, markdown } = state.currentFile const options = getOptionsFromState(state.currentFile) + const defaultPath = getRootFolderFromState(rootState) if (!id) return if (!pathname) { // 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, + filename, + pathname, + markdown, + options, + defaultPath + }) } else { bus.$emit('rename') } @@ -695,7 +727,7 @@ const actions = { // WORKAROUND: id is "muya" if changes come from muya and not source code editor! So we don't have to apply the workaround. LISTEN_FOR_CONTENT_CHANGE ({ commit, dispatch, state, rootState }, { id, markdown, wordCount, cursor, history, toc }) { const { autoSave } = rootState.preferences - const { id: currentId, pathname, markdown: oldMarkdown } = state.currentFile + const { id: currentId, filename, pathname, markdown: oldMarkdown } = state.currentFile const { listToc } = state if (!id) { @@ -740,12 +772,18 @@ const actions = { if (markdown !== oldMarkdown) { commit('SET_SAVE_STATUS', false) if (pathname && autoSave) { - dispatch('HANDLE_AUTO_SAVE', { id: currentId, pathname, markdown, options }) + dispatch('HANDLE_AUTO_SAVE', { + id: currentId, + filename, + pathname, + markdown, + options + }) } } }, - HANDLE_AUTO_SAVE ({ commit, state, rootState }, { id, pathname, markdown, options }) { + HANDLE_AUTO_SAVE ({ commit, state, rootState }, { id, filename, pathname, markdown, options }) { if (!id || !pathname) { throw new Error('HANDLE_AUTO_SAVE: Invalid tab.') } @@ -767,8 +805,17 @@ const actions = { // gracefully closed. The automatically save event may fire meanwhile. const tab = tabs.find(t => t.id === id) if (tab && !tab.isSaved) { + const defaultPath = getRootFolderFromState(rootState) + // Tab changed status is set after the file is saved. - ipcRenderer.send('AGANI::response-file-save', { id, pathname, markdown, options }) + ipcRenderer.send('AGANI::response-file-save', { + id, + filename, + pathname, + markdown, + options, + defaultPath + }) } }, autoSaveDelay) autoSaveTimers.set(id, timer) @@ -919,4 +966,19 @@ const actions = { } } +// ---------------------------------------------------------------------------- + +/** + * Return the opened root folder or an empty string. + * + * @param {*} rootState The root state. + */ +const getRootFolderFromState = rootState => { + const openedFolder = rootState.project.projectTree + if (openedFolder) { + return openedFolder.pathname + } + return '' +} + export default { state, mutations, actions }