Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/common/base/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface MenuItemCommon<T extends MenuItemCommon<T>> {
readonly label?: string;
readonly role?: MenuItemRole;
readonly type?: MenuItemType;
readonly checked?: boolean;
readonly icon?: string;
readonly enabled?: boolean;
readonly submenu?: ReadonlyArray<T>;
Expand Down
127 changes: 109 additions & 18 deletions src/renderer/application/useCases/appMenu/initAppMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import { OpenAboutUseCase } from '@/application/useCases/about/openAbout';
import { ShellProvider } from '@/application/interfaces/shellProvider';
import { OpenProjectManagerUseCase } from '@/application/useCases/projectManager/openProjectManager';
import { OpenAppManagerUseCase } from '@/application/useCases/appManager/openAppManager';
import { EditTogglePos, ProjectSwitcherPos } from '@/base/state/ui';
import { ToggleTopBarUseCase } from '@/application/useCases/toggleTopBar';
import { SetProjectSwitcherPositionUseCase } from '@/application/useCases/projectSwitcher/setProjectSwitcherPosition';
import { SetEditTogglePositionUseCase } from '@/application/useCases/setEditTogglePosition';

const urlDownload = 'https://freeter.io/v2/download';
const urlTwitter = 'https://twitter.com/FreeterApp';
Expand All @@ -28,6 +32,9 @@ type Deps = {
shellProvider: ShellProvider;
toggleEditModeUseCase: ToggleEditModeUseCase;
toggleMenuBarUseCase: ToggleMenuBarUseCase;
toggleTopBarUseCase: ToggleTopBarUseCase;
setProjectSwitcherPositionUseCase: SetProjectSwitcherPositionUseCase;
setEditTogglePositionUseCase: SetEditTogglePositionUseCase;
openApplicationSettingsUseCase: OpenApplicationSettingsUseCase;
openAboutUseCase: OpenAboutUseCase;
openProjectManagerUseCase: OpenProjectManagerUseCase;
Expand All @@ -42,6 +49,9 @@ export function createInitAppMenuUseCase({
shellProvider,
toggleEditModeUseCase,
toggleMenuBarUseCase,
toggleTopBarUseCase,
setProjectSwitcherPositionUseCase,
setEditTogglePositionUseCase,
openApplicationSettingsUseCase,
openAboutUseCase,
openProjectManagerUseCase,
Expand Down Expand Up @@ -99,9 +109,17 @@ export function createInitAppMenuUseCase({
]
}

const menuEdit: MenuItem = {
const createMenuEdit: (
editMode: boolean,
) => MenuItem = (editMode) => ({
label: '&Edit',
submenu: [
{
accelerator: 'CmdOrCtrl+E',
label: `${editMode ? 'Disable' : 'Enable'} Edit Mode`,
doAction: async () => toggleEditModeUseCase()
},
itemSeparator,
{
role: 'undo'
}, {
Expand All @@ -116,24 +134,91 @@ export function createInitAppMenuUseCase({
role: 'selectAll'
}
]
}
})

const createMenuView: (editMode: boolean, menuBar: boolean) => MenuItem = (editMode, menuBar) => ({
const createMenuView: (
menuBar: boolean,
topBar: boolean,
prjSwitcherPos: ProjectSwitcherPos,
editTogglePos: EditTogglePos,
) => MenuItem = (menuBar, topBar, prjSwitcherPos, editTogglePos) => ({
label: '&View',
submenu: [
{ role: 'togglefullscreen' },
...(!isMac
? [{
label: menuBar ? 'Hide Menu Bar (ALT to restore)' : 'Show Menu Bar',
doAction: async () => toggleMenuBarUseCase()
}]
: []
),
itemSeparator,
{
accelerator: 'CmdOrCtrl+E',
label: `${editMode ? 'Disable' : 'Enable'} Edit Mode`,
doAction: async () => toggleEditModeUseCase()
label: 'Appearance',
submenu: [
{ role: 'togglefullscreen' },
...(!isMac
? [{
label: menuBar ? 'Hide Menu Bar (ALT to restore)' : 'Show Menu Bar',
doAction: async () => toggleMenuBarUseCase()
}]
: []
),
{
label: topBar ? 'Hide Top Bar' : 'Show Top Bar',
doAction: async () => toggleTopBarUseCase()
},
itemSeparator,
{
label: 'Project Switcher Position',
submenu: [
{
label: 'On Top Bar',
type: 'radio',
checked: prjSwitcherPos === ProjectSwitcherPos.TopBar,
doAction: async () => setProjectSwitcherPositionUseCase(ProjectSwitcherPos.TopBar)
},
{
label: 'On Tab Bar (Left)',
type: 'radio',
checked: prjSwitcherPos === ProjectSwitcherPos.TabBarLeft,
doAction: async () => setProjectSwitcherPositionUseCase(ProjectSwitcherPos.TabBarLeft)
},
{
label: 'On Tab Bar (Right)',
type: 'radio',
checked: prjSwitcherPos === ProjectSwitcherPos.TabBarRight,
doAction: async () => setProjectSwitcherPositionUseCase(ProjectSwitcherPos.TabBarRight)
},
{
label: 'Hidden',
type: 'radio',
checked: prjSwitcherPos === ProjectSwitcherPos.Hidden,
doAction: async () => setProjectSwitcherPositionUseCase(ProjectSwitcherPos.Hidden)
},
]
},
{
label: 'Edit Mode Toggle Position',
submenu: [
{
label: 'On Top Bar',
type: 'radio',
checked: editTogglePos === EditTogglePos.TopBar,
doAction: async () => setEditTogglePositionUseCase(EditTogglePos.TopBar)
},
{
label: 'On Tab Bar (Left)',
type: 'radio',
checked: editTogglePos === EditTogglePos.TabBarLeft,
doAction: async () => setEditTogglePositionUseCase(EditTogglePos.TabBarLeft)
},
{
label: 'On Tab Bar (Right)',
type: 'radio',
checked: editTogglePos === EditTogglePos.TabBarRight,
doAction: async () => setEditTogglePositionUseCase(EditTogglePos.TabBarRight)
},
{
label: 'Hidden',
type: 'radio',
checked: editTogglePos === EditTogglePos.Hidden,
doAction: async () => setEditTogglePositionUseCase(EditTogglePos.Hidden)
},
]
},
]
},
itemSeparator,
{
Expand Down Expand Up @@ -210,16 +295,22 @@ export function createInitAppMenuUseCase({
isLoading: state.isLoading,
editMode: state.ui.editMode,
menuBar: state.ui.menuBar,
topBar: state.ui.topBar,
prjSwitcherPos: state.ui.projectSwitcher.pos,
editTogglePos: state.ui.editTogglePos,
}), ({
isLoading,
editMode,
menuBar
menuBar,
topBar,
prjSwitcherPos,
editTogglePos
}) => {
if (!isLoading) {
appMenu.setMenu([
(isMac ? menuApp : menuFile),
menuEdit,
createMenuView(editMode, menuBar),
createMenuEdit(editMode),
createMenuView(menuBar, topBar, prjSwitcherPos, editTogglePos),
menuHelp,
...(isDevMode
? [menuDev]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright: (c) 2024, Alex Kaul
* GNU General Public License v3.0 or later (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
*/

import { AppStore } from '@/application/interfaces/store';
import { ProjectSwitcherPos } from '@/base/state/ui';

type Deps = {
appStore: AppStore;
}

export function createSetProjectSwitcherPositionUseCase({
appStore
}: Deps) {
const useCase = (newPos: ProjectSwitcherPos) => {
const state = appStore.get();
appStore.set({
...state,
ui: {
...state.ui,
projectSwitcher: {
...state.ui.projectSwitcher,
pos: newPos
}
}
})
}

return useCase;
}

export type SetProjectSwitcherPositionUseCase = ReturnType<typeof createSetProjectSwitcherPositionUseCase>;
30 changes: 30 additions & 0 deletions src/renderer/application/useCases/setEditTogglePosition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright: (c) 2024, Alex Kaul
* GNU General Public License v3.0 or later (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
*/

import { AppStore } from '@/application/interfaces/store';
import { EditTogglePos } from '@/base/state/ui';

type Deps = {
appStore: AppStore;
}

export function createSetEditTogglePositionUseCase({
appStore
}: Deps) {
const useCase = (newPos: EditTogglePos) => {
const state = appStore.get();
appStore.set({
...state,
ui: {
...state.ui,
editTogglePos: newPos
}
})
}

return useCase;
}

export type SetEditTogglePositionUseCase = ReturnType<typeof createSetEditTogglePositionUseCase>;
30 changes: 30 additions & 0 deletions src/renderer/application/useCases/toggleTopBar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright: (c) 2024, Alex Kaul
* GNU General Public License v3.0 or later (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
*/

import { AppStore } from '@/application/interfaces/store';

type Deps = {
appStore: AppStore;
}

export function createToggleTopBarUseCase({
appStore
}: Deps) {
const useCase = () => {
const state = appStore.get();
const { topBar } = state.ui;
appStore.set({
...state,
ui: {
...state.ui,
topBar: !topBar
}
})
}

return useCase;
}

export type ToggleTopBarUseCase = ReturnType<typeof createToggleTopBarUseCase>;
22 changes: 21 additions & 1 deletion src/renderer/base/state/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,17 @@ export interface ProjectManagerState {
duplicateProjectIds: Record<EntityId, EntityId> | null;
}

export enum ProjectSwitcherPos {
Hidden = 0,
TopBar = 1,
TabBarLeft = 2,
TabBarRight = 3,
}

export interface ProjectSwitcherState {
projectIds: EntityIdList;
currentProjectId: EntityId;
pos: ProjectSwitcherPos;
}

export interface AppManagerState {
Expand Down Expand Up @@ -190,9 +198,18 @@ export interface MemSaverState {
workflowTimeouts: Record<EntityId, NodeJS.Timeout>;
}

export enum EditTogglePos {
Hidden = 0,
TopBar = 1,
TabBarLeft = 2,
TabBarRight = 3,
}

export interface UiState {
editMode: boolean;
menuBar: boolean;
topBar: boolean;
editTogglePos: EditTogglePos;
appConfig: AppConfig;
apps: AppsState;
dragDrop: DragDropState;
Expand All @@ -210,6 +227,8 @@ export function createUiState(): UiState {
dragDrop: {},
editMode: false,
menuBar: true,
topBar: false,
editTogglePos: EditTogglePos.TabBarRight,
appConfig: {
mainHotkey: 'CmdOrCtrl+Shift+F',
memSaver: {
Expand Down Expand Up @@ -267,7 +286,8 @@ export function createUiState(): UiState {
},
projectSwitcher: {
currentProjectId: '',
projectIds: []
projectIds: [],
pos: ProjectSwitcherPos.TabBarRight,
},
shelf: {
widgetList: []
Expand Down
Loading