Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
fix: reenable default edit operations on input and textarea
Browse files Browse the repository at this point in the history
  • Loading branch information
marionebl committed Sep 10, 2018
1 parent bdfef35 commit 308a128
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 61 deletions.
2 changes: 1 addition & 1 deletion src/container/page-list/page-tile-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class PageTileContainer extends React.Component<PageTileContainerProps> {

if (rootElement) {
store.setSelectedElement(rootElement);
store.getProject().setFocusedItem(Types.ItemType.Page, this.props.page);
store.getProject().setFocusedItem(this.props.page);
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/electron/create-edit-message-handler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as Clipboard from './clipboard';
import * as Message from '../message';
import { requestApp } from './request-app';
import { requestProject } from './request-project';
import * as Types from '../types';
import * as uuid from 'uuid';
Expand All @@ -17,11 +18,17 @@ export async function createEditMessageHandler(
switch (message.type) {
case Message.MessageType.Cut:
case Message.MessageType.Copy: {
const app = await requestApp(injection.sender);

if (app.getHasFocusedInput()) {
return;
}

const project = await requestProject(injection.sender);
const focusedItemType = project.getFocusedItemType();
const focusedItem = project.getFocusedItem();

if (!focusedItem || focusedItemType === Types.ItemType.None) {
if (!focusedItem) {
return;
}

Expand Down
38 changes: 29 additions & 9 deletions src/electron/create-main-menu/create-edit-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,33 @@ export function createEditMenu(
label: '&Undo',
accelerator: 'CmdOrCtrl+Z',
enabled: typeof ctx.project !== 'undefined',
click: () =>
click: () => {
if (ctx.app.hasFocusedInput) {
return Electron.Menu.sendActionToFirstResponder('redo:');
}

injection.sender.send({
id: uuid.v4(),
type: MessageType.Undo,
payload: undefined
})
});
}
},
{
label: '&Redo',
accelerator: 'Shift+CmdOrCtrl+Z',
enabled: typeof ctx.project !== 'undefined',
click: () =>
click: () => {
if (ctx.app.hasFocusedInput) {
return Electron.Menu.sendActionToFirstResponder('redo:');
}

injection.sender.send({
id: uuid.v4(),
payload: undefined,
type: MessageType.Redo
})
});
}
},
{
type: 'separator'
Expand All @@ -50,38 +60,47 @@ export function createEditMenu(
enabled: typeof ctx.project !== 'undefined',
accelerator: 'CmdOrCtrl+X',
click: () => {
if (ctx.app.hasFocusedInput) {
return Electron.Menu.sendActionToFirstResponder('cut:');
}

injection.sender.send({
id: uuid.v4(),
payload: undefined,
type: MessageType.Cut
});
Electron.Menu.sendActionToFirstResponder('cut:');
}
},
{
label: 'C&opy',
enabled: typeof ctx.project !== 'undefined',
accelerator: 'CmdOrCtrl+C',
click: () => {
if (ctx.app.hasFocusedInput) {
return Electron.Menu.sendActionToFirstResponder('copy:');
}

injection.sender.send({
id: uuid.v4(),
payload: undefined,
type: MessageType.Copy
});
Electron.Menu.sendActionToFirstResponder('copy:');
}
},
{
label: '&Paste',
enabled: typeof ctx.project !== 'undefined',
accelerator: 'CmdOrCtrl+V',
click: () => {
if (ctx.app.hasFocusedInput) {
return Electron.Menu.sendActionToFirstResponder('paste:');
}

injection.sender.send({
id: uuid.v4(),
payload: undefined,
type: MessageType.Paste
});
Electron.Menu.sendActionToFirstResponder('paste:');
}
},
{
Expand All @@ -104,7 +123,6 @@ export function createEditMenu(
},
type: MessageType.Paste
});
Electron.Menu.sendActionToFirstResponder('paste:');
}
},
{
Expand Down Expand Up @@ -138,12 +156,14 @@ export function createEditMenu(
enabled: typeof ctx.project !== 'undefined',
accelerator: process.platform === 'darwin' ? 'Backspace' : 'Delete',
click: () => {
if (ctx.app.hasFocusedInput) {
return Electron.Menu.sendActionToFirstResponder('delete:');
}
injection.sender.send({
id: uuid.v4(),
payload: undefined,
type: MessageType.Delete
});
Electron.Menu.sendActionToFirstResponder('delete:');
}
}
]
Expand Down
14 changes: 14 additions & 0 deletions src/model/alva-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as Types from '../types';

export interface AlvaAppInit {
activeView: Types.AlvaView;
hasFocusedInput: boolean;
panes: Set<Types.AppPane>;
paneSizes: Types.PaneSize[];
rightSidebarTab: Types.RightSidebarTab;
Expand Down Expand Up @@ -30,6 +31,8 @@ export class AlvaApp {

@Mobx.observable private paneSizes: Map<Types.AppPane, Types.PaneSize> = new Map();

@Mobx.observable private hasFocusedInput: boolean = false;

public constructor(init?: AlvaAppInit) {
if (init) {
this.activeView = init.activeView;
Expand All @@ -43,6 +46,7 @@ export class AlvaApp {
public static from(serialized: Types.SerializedAlvaApp): AlvaApp {
return new AlvaApp({
activeView: deserializeView(serialized.activeView),
hasFocusedInput: serialized.hasFocusedInput,
panes: new Set(serialized.panes.map(deserializePane)),
paneSizes: serialized.paneSizes.map(p => ({
width: p.width,
Expand All @@ -59,6 +63,10 @@ export class AlvaApp {
return this.activeView;
}

public getHasFocusedInput(): boolean {
return this.hasFocusedInput;
}

public getHoverArea(): Types.HoverArea {
return this.hoverArea;
}
Expand Down Expand Up @@ -96,6 +104,11 @@ export class AlvaApp {
this.activeView = view;
}

@Mobx.action
public setHasFocusedInput(hasFocusedInput: boolean): void {
this.hasFocusedInput = hasFocusedInput;
}

@Mobx.action
public setPaneSelectOpen(paneSelectOpen: boolean): void {
this.paneSelectOpen = paneSelectOpen;
Expand Down Expand Up @@ -146,6 +159,7 @@ export class AlvaApp {
public toJSON(): Types.SerializedAlvaApp {
return {
activeView: serializeView(this.activeView),
hasFocusedInput: this.hasFocusedInput,
panes: [...this.panes.values()].map(serializePane),
paneSizes: [...this.paneSizes.values()].map(paneSize => ({
width: paneSize.width,
Expand Down
80 changes: 35 additions & 45 deletions src/model/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@ import * as uuid from 'uuid';

export interface ProjectProperties {
id?: string;
lastChangedAuthor?: string;
lastChangedDate?: Date;
name: string;
pages: Page[];
path: string;
patternLibraries: PatternLibrary[];
userStore: UserStore;
focusedItemType?: Types.ItemType;
}

export interface ProjectCreateInit {
Expand All @@ -37,8 +34,6 @@ export class Project {

@Mobx.observable private elementContents: Map<string, ElementContent> = new Map();

@Mobx.observable private focusedItemType: Types.ItemType = Types.ItemType.None;

@Mobx.observable private id: string;

@Mobx.observable private name: string;
Expand Down Expand Up @@ -110,17 +105,43 @@ export class Project {
return elementProperties;
}

@Mobx.computed
private get focusedItem(): Element | Page | undefined {
const element = this.getElements().find(e => e.getFocused());

if (element) {
return element;
}

const page = this.getPages().find(p => p.getFocused());

if (page) {
return page;
}

return;
}

@Mobx.computed
private get focusedItemType(): Types.ItemType {
if (this.focusedItem instanceof Page) {
return Types.ItemType.Page;
}

if (this.focusedItem instanceof Element) {
return Types.ItemType.Element;
}

return Types.ItemType.None;
}

public constructor(init: ProjectProperties) {
this.name = init.name;
this.id = init.id ? init.id : uuid.v4();
this.pages = init.pages ? init.pages : [];
this.path = init.path;
this.userStore = init.userStore;

if (typeof init.focusedItemType !== 'undefined') {
this.focusedItemType = init.focusedItemType;
}

init.patternLibraries.forEach(patternLibrary => {
if (patternLibrary.getOrigin() === Types.PatternLibraryOrigin.BuiltIn) {
const updatedLibrary = Project.createBuiltinPatternLibrary({
Expand Down Expand Up @@ -198,8 +219,7 @@ export class Project {
path: serialized.path,
pages: [],
patternLibraries: serialized.patternLibraries.map(p => PatternLibrary.from(p)),
userStore,
focusedItemType: deserializeItemType(serialized.focusedItemType)
userStore
});

serialized.pages.forEach(page => project.addPage(Page.from(page, { project })));
Expand Down Expand Up @@ -289,14 +309,7 @@ export class Project {
}

public getFocusedItem(): Element | Page | undefined {
switch (this.focusedItemType) {
case Types.ItemType.Element:
return this.getElements().find(element => element.getFocused());
case Types.ItemType.Page:
return this.getPages().find(page => page.getFocused());
default:
return;
}
return this.focusedItem;
}

public getFocusedItemType(): Types.ItemType {
Expand Down Expand Up @@ -483,7 +496,7 @@ export class Project {
this.unsetSelectedElement();

page.setActive(true);
this.setFocusedItem(Types.ItemType.Page, page);
this.setFocusedItem(page);
}

@Mobx.action
Expand Down Expand Up @@ -513,13 +526,13 @@ export class Project {
}

@Mobx.action
public setFocusedItem(type: Types.ItemType, payload: Element | Page | undefined): void {
public setFocusedItem(payload: Element | Page | undefined): void {
const previousFocusItem = this.getFocusedItem();

if (previousFocusItem) {
previousFocusItem.setFocused(false);
}
this.focusedItemType = type;

if (payload) {
payload.setFocused(true);
}
Expand Down Expand Up @@ -568,7 +581,6 @@ export class Project {
elements: this.getElements().map(e => e.toJSON()),
elementActions: this.getElementActions().map(e => e.toJSON()),
elementContents: this.getElementContents().map(e => e.toJSON()),
focusedItemType: serializeItemType(this.focusedItemType),
id: this.id,
name: this.name,
pages: this.pages.map(p => p.toJSON()),
Expand Down Expand Up @@ -622,25 +634,3 @@ export class Project {
.forEach(element => element.setPlaceholderHighlighted(false));
}
}

function serializeItemType(type: Types.ItemType): Types.SerializedItemType {
switch (type) {
case Types.ItemType.None:
return 'none';
case Types.ItemType.Element:
return 'element';
case Types.ItemType.Page:
return 'page';
}
}

function deserializeItemType(type: Types.SerializedItemType): Types.ItemType {
switch (type) {
case 'none':
return Types.ItemType.None;
case 'element':
return Types.ItemType.Element;
case 'page':
return Types.ItemType.Page;
}
}
3 changes: 1 addition & 2 deletions src/renderer/create-edit-message-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export function createEditMessageHandler({
}): EditMessageHandler {
// tslint:disable-next-line:cyclomatic-complexity
return function editMessageHandler(message: Message.Message): void {
// Do not perform custom operations when an input/textarea is selected
if (['input', 'textarea'].includes(document.activeElement.tagName.toLowerCase())) {
if (store.getApp().getHasFocusedInput()) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/create-init-message-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function createInitMessageHandler({

store.setProject(projectResult.project);
app.setActiveView(Types.AlvaView.PageDetail);
store.getProject().setFocusedItem(Types.ItemType.Page, store.getActivePage());
store.getProject().setFocusedItem(store.getActivePage());

store.commit();
break;
Expand Down
Loading

0 comments on commit 308a128

Please sign in to comment.