diff --git a/.eslintignore b/.eslintignore index 226d664c8..e0caccc5e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -177,6 +177,7 @@ packages/app-desktop/gui/MainScreen/commands/openTag.js packages/app-desktop/gui/MainScreen/commands/print.js packages/app-desktop/gui/MainScreen/commands/renameFolder.js packages/app-desktop/gui/MainScreen/commands/renameTag.js +packages/app-desktop/gui/MainScreen/commands/resetLayout.js packages/app-desktop/gui/MainScreen/commands/revealResourceFile.js packages/app-desktop/gui/MainScreen/commands/search.js packages/app-desktop/gui/MainScreen/commands/setTags.js diff --git a/.gitignore b/.gitignore index 8cc1ac940..33ccc7515 100644 --- a/.gitignore +++ b/.gitignore @@ -165,6 +165,7 @@ packages/app-desktop/gui/MainScreen/commands/openTag.js packages/app-desktop/gui/MainScreen/commands/print.js packages/app-desktop/gui/MainScreen/commands/renameFolder.js packages/app-desktop/gui/MainScreen/commands/renameTag.js +packages/app-desktop/gui/MainScreen/commands/resetLayout.js packages/app-desktop/gui/MainScreen/commands/revealResourceFile.js packages/app-desktop/gui/MainScreen/commands/search.js packages/app-desktop/gui/MainScreen/commands/setTags.js diff --git a/packages/app-desktop/app.reducer.ts b/packages/app-desktop/app.reducer.ts index 45551c072..2b35e4ad3 100644 --- a/packages/app-desktop/app.reducer.ts +++ b/packages/app-desktop/app.reducer.ts @@ -38,6 +38,7 @@ export interface AppState extends State { watchedResources: any; mainLayout: LayoutItem; dialogs: AppStateDialog[]; + isResettingLayout: boolean; } export function createAppDefaultState(windowContentSize: any, resourceEditWatcherDefaultState: any): AppState { @@ -60,6 +61,7 @@ export function createAppDefaultState(windowContentSize: any, resourceEditWatche mainLayout: null, startupPluginsLoaded: false, dialogs: [], + isResettingLayout: false, ...resourceEditWatcherDefaultState, }; } @@ -308,7 +310,15 @@ export default function(state: AppState, action: any) { }; break; + + case 'RESET_LAYOUT': + newState = { + ...state, + isResettingLayout: action.value, + }; + break; } + } catch (error) { error.message = `In reducer: ${error.message} Action: ${JSON.stringify(action)}`; throw error; diff --git a/packages/app-desktop/gui/MainScreen/MainScreen.tsx b/packages/app-desktop/gui/MainScreen/MainScreen.tsx index b0c6f08ef..4c9d8a95b 100644 --- a/packages/app-desktop/gui/MainScreen/MainScreen.tsx +++ b/packages/app-desktop/gui/MainScreen/MainScreen.tsx @@ -78,6 +78,7 @@ interface Props { isSafeMode: boolean; needApiAuth: boolean; processingShareInvitationResponse: boolean; + isResettingLayout: boolean; } interface ShareFolderDialogOptions { @@ -371,6 +372,15 @@ class MainScreenComponent extends React.Component { name: 'promptDialog', }); } + + if (this.props.isResettingLayout) { + Setting.setValue('ui.layout', null); + this.updateMainLayout(this.buildLayout(this.props.plugins)); + this.props.dispatch({ + type: 'RESET_LAYOUT', + value: false, + }); + } } layoutModeListenerKeyDown(event: any) { @@ -880,6 +890,7 @@ const mapStateToProps = (state: AppState) => { isSafeMode: state.settings.isSafeMode, needApiAuth: state.needApiAuth, showInstallTemplatesPlugin: state.hasLegacyTemplates && !state.pluginService.plugins['joplin.plugin.templates'], + isResettingLayout: state.isResettingLayout, }; }; diff --git a/packages/app-desktop/gui/MainScreen/commands/index.ts b/packages/app-desktop/gui/MainScreen/commands/index.ts index 41483977c..d1b4f3808 100644 --- a/packages/app-desktop/gui/MainScreen/commands/index.ts +++ b/packages/app-desktop/gui/MainScreen/commands/index.ts @@ -20,6 +20,7 @@ import * as openTag from './openTag'; import * as print from './print'; import * as renameFolder from './renameFolder'; import * as renameTag from './renameTag'; +import * as resetLayout from './resetLayout'; import * as revealResourceFile from './revealResourceFile'; import * as search from './search'; import * as setTags from './setTags'; @@ -61,6 +62,7 @@ const index:any[] = [ print, renameFolder, renameTag, + resetLayout, revealResourceFile, search, setTags, diff --git a/packages/app-desktop/gui/MainScreen/commands/resetLayout.ts b/packages/app-desktop/gui/MainScreen/commands/resetLayout.ts new file mode 100644 index 000000000..6bb2f6002 --- /dev/null +++ b/packages/app-desktop/gui/MainScreen/commands/resetLayout.ts @@ -0,0 +1,25 @@ +import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService'; +import { _ } from '@joplin/lib/locale'; +import dialogs from '../../dialogs'; + +export const declaration: CommandDeclaration = { + name: 'resetLayout', + label: () => _('Reset application layout'), +}; + +export const runtime = (): CommandRuntime => { + return { + execute: async (context: CommandContext) => { + + const message = _('Are you sure you want to return to the default layout? The current layout configuration will be lost.'); + const isConfirmed = await dialogs.confirm(message); + + if (!isConfirmed) return; + + context.dispatch({ + type: 'RESET_LAYOUT', + value: true, + }); + }, + }; +}; diff --git a/packages/app-desktop/gui/MenuBar.tsx b/packages/app-desktop/gui/MenuBar.tsx index a197b8437..17697bf84 100644 --- a/packages/app-desktop/gui/MenuBar.tsx +++ b/packages/app-desktop/gui/MenuBar.tsx @@ -675,6 +675,7 @@ function useMenu(props: Props) { label: _('&View'), submenu: [ menuItemDic.toggleLayoutMoveMode, + menuItemDic.resetLayout, separator(), menuItemDic.toggleSideBar, menuItemDic.toggleNoteList, diff --git a/packages/app-desktop/gui/menuCommandNames.ts b/packages/app-desktop/gui/menuCommandNames.ts index 012444563..296094fbc 100644 --- a/packages/app-desktop/gui/menuCommandNames.ts +++ b/packages/app-desktop/gui/menuCommandNames.ts @@ -32,6 +32,7 @@ export default function() { 'textBulletedList', 'toggleExternalEditing', 'toggleLayoutMoveMode', + 'resetLayout', 'toggleNoteList', 'toggleNotesSortOrderField', 'toggleNotesSortOrderReverse',