Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
5 changes: 5 additions & 0 deletions .changeset/wise-hornets-post.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'quickmock': minor
---

Toolbar's **New** button now creates a real `.qm` file when running inside the VS Code extension instead of just clearing the canvas.
11 changes: 9 additions & 2 deletions apps/web/src/pods/toolbar/components/new-button/new-button.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { NewIcon } from '#common/components/icons/new-button.components';
import classes from '#pods/toolbar/toolbar.pod.module.css';
import { isVSCodeEnv } from '#common/utils/env.utils';
import { sendToExtension } from '#common/utils/vscode-bridge.utils';
import { useCanvasContext } from '#core/providers';
import { ToolbarButton } from '../toolbar-button';
import classes from '#pods/toolbar/toolbar.pod.module.css';
import { APP_MESSAGE_TYPE } from '@lemoncode/quickmock-bridge-protocol';
import { SHORTCUTS } from '../../shortcut/shortcut.const';
import { ToolbarButton } from '../toolbar-button';

export const NewButton = () => {
const { createNewFullDocument: clearCanvas } = useCanvasContext();

const handleClick = () => {
if (isVSCodeEnv()) {
sendToExtension({ type: APP_MESSAGE_TYPE.NEW_FILE });
return;
}
clearCanvas();
};

Expand Down
1 change: 1 addition & 0 deletions packages/bridge-protocol/src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export const APP_MESSAGE_TYPE = {
SAVE: 'qm:save',
RENDER_COMPLETE: 'qm:render-complete',
WEBVIEW_READY: 'WEBVIEW_READY',
NEW_FILE: 'qm:new-file',
} as const;
3 changes: 2 additions & 1 deletion packages/bridge-protocol/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export type AppMessage =
| {
type: typeof APP_MESSAGE_TYPE.RENDER_COMPLETE;
payload?: ContentBbox;
};
}
| { type: typeof APP_MESSAGE_TYPE.NEW_FILE };

export type PayloadOf<U extends { type: string }, T extends U['type']> =
Extract<U, { type: T }> extends { payload: infer P } ? P : undefined;
11 changes: 0 additions & 11 deletions packages/vscode-extension/src/commands/new-wireframe.ts

This file was deleted.

2 changes: 2 additions & 0 deletions packages/vscode-extension/src/commands/new-wireframe/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './new-wireframe.id';
export * from './new-wireframe.command';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as vscode from 'vscode';
import { QUICKMOCK_NEW_WIREFRAME_COMMAND_ID } from './new-wireframe.id';
import { handleNewWireframe } from './new-wireframe.handler';

export const registerNewWireframeCommand = (
context: vscode.ExtensionContext
): void => {
context.subscriptions.push(
vscode.commands.registerCommand(
QUICKMOCK_NEW_WIREFRAME_COMMAND_ID,
handleNewWireframe
)
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { getPrimaryWorkspaceFolder } from '#core';
import { writeFile } from '#editor/document';
import {
createEmptyQuickMockContent,
DEFAULT_QUICKMOCK_FILE_NAME,
QUICKMOCK_FILE_EXTENSION,
} from '#editor/template';
import * as vscode from 'vscode';

const CUSTOM_EDITOR_VIEW_TYPE = 'quickmock.editor';

const pickSaveTarget = async (): Promise<vscode.Uri | undefined> => {
const folder = getPrimaryWorkspaceFolder();
const defaultUri = folder
? vscode.Uri.joinPath(folder.uri, DEFAULT_QUICKMOCK_FILE_NAME)
: undefined;

return vscode.window.showSaveDialog({
defaultUri,
filters: { 'QuickMock Wireframe': [QUICKMOCK_FILE_EXTENSION] },
saveLabel: 'Create',
title: 'Create QuickMock File',
});
};

export const handleNewWireframe = async (): Promise<void> => {
const target = await pickSaveTarget();
if (!target) return;

try {
await writeFile(target, createEmptyQuickMockContent());
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
Comment on lines +26 to +33
vscode.window.showErrorMessage(
`Failed to create QuickMock file: ${message}`
);
return;
}

await vscode.commands.executeCommand(
'vscode.openWith',
target,
CUSTOM_EDITOR_VIEW_TYPE
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const QUICKMOCK_NEW_WIREFRAME_COMMAND_ID = 'quickmock.newWireframe';
6 changes: 6 additions & 0 deletions packages/vscode-extension/src/editor/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
HOST_MESSAGE_TYPE,
type HostMessage,
} from '@lemoncode/quickmock-bridge-protocol';
import * as vscode from 'vscode';
import { QUICKMOCK_NEW_WIREFRAME_COMMAND_ID } from '#commands';
import { type QuickMockDocument, writeFile } from './document';

type PostMessageFn = (msg: HostMessage) => void;
Expand Down Expand Up @@ -41,5 +43,9 @@ export const handleWebviewMessage = async (
await writeFile(doc.uri, doc.content);
postMessage({ type: HOST_MESSAGE_TYPE.SAVED });
break;

case APP_MESSAGE_TYPE.NEW_FILE:
await vscode.commands.executeCommand(QUICKMOCK_NEW_WIREFRAME_COMMAND_ID);
break;
}
};
1 change: 1 addition & 0 deletions packages/vscode-extension/src/editor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './document';
export * from './handlers';
export * from './panel';
export * from './provider';
export * from './template';
17 changes: 17 additions & 0 deletions packages/vscode-extension/src/editor/template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const TEMPLATE_VERSION = '0.1';
const DEFAULT_CANVAS_SIZE = { width: 1920, height: 1080 };

export const QUICKMOCK_FILE_EXTENSION = 'qm';
export const DEFAULT_QUICKMOCK_FILE_NAME = `untitled.${QUICKMOCK_FILE_EXTENSION}`;

export const createEmptyQuickMockContent = (): string =>
JSON.stringify(
{
version: TEMPLATE_VERSION,
pages: [{ id: 'page-1', name: 'Page 1', shapes: [] }],
customColors: [],
size: DEFAULT_CANVAS_SIZE,
},
null,
2
);
Loading