Skip to content

Commit

Permalink
feat(#18): add (Cmd/Ctrl)+Enter shortcut
Browse files Browse the repository at this point in the history
  • Loading branch information
notmedia committed Dec 3, 2022
1 parent dbe09fd commit 7da0710
Show file tree
Hide file tree
Showing 14 changed files with 369 additions and 206 deletions.
57 changes: 52 additions & 5 deletions src/app/pages/shortcuts/hooks/use-grpc-method-actions.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,63 @@
import { faSquarePlus } from '@fortawesome/free-solid-svg-icons';
import { faPaperPlane, faSquarePlus } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Action, Priority, useRegisterActions } from '@getezy/kbar';
import { Container } from '@nextui-org/react';
import React from 'react';

import { GrpcMethodType } from '@core/types';
import { CollectionType, useCollectionsStore, useTabsStore } from '@storage';
import {
CollectionType,
isGrpcTab,
isGrpcTabBidirectionalStreaming,
isGrpcTabClientStreaming,
isGrpcTabServerStreaming,
isGrpcTabUnaryCall,
useCollectionsStore,
useTabsStore,
} from '@storage';

import { StreamBadge, UnaryBadge } from '../../collections/badge-types';
import {
useBidirectionalStreaming,
useClientStreaming,
useServerStreaming,
useUnaryCall,
} from '../../tabs-container/collection-types/grpc/hooks';

function useGrpcInvokeAction(): Action {
const { tabs, activeTabId } = useTabsStore((store) => store);
const { invoke: invokeUnaryCall } = useUnaryCall();
const { invoke: invokeServerStreaming } = useServerStreaming();
const { invoke: invokeClientStreaming } = useClientStreaming();
const { invoke: invokeBidirectionalStreaming } = useBidirectionalStreaming();

return {
id: 'grpc:invoke',
section: 'grpc',
name: 'Invoke',
icon: <FontAwesomeIcon icon={faPaperPlane} />,
shortcut: ['$mod+Enter'],
perform: () => {
const tab = tabs.find((item) => item.id === activeTabId);
if (tab && isGrpcTab(tab)) {
if (isGrpcTabUnaryCall(tab)) {
invokeUnaryCall(tab);
} else if (isGrpcTabServerStreaming(tab)) {
invokeServerStreaming(tab);
} else if (isGrpcTabClientStreaming(tab)) {
invokeClientStreaming(tab);
} else if (isGrpcTabBidirectionalStreaming(tab)) {
invokeBidirectionalStreaming(tab);
}
}
},
};
}

export function useGrpcMethodActions() {
const { collections } = useCollectionsStore((store) => store);
const { createGrpcTab } = useTabsStore((store) => store);
const invokeAction = useGrpcInvokeAction();

const methods = collections.reduce((acc, collection) => {
collection.children?.forEach((service) => {
Expand All @@ -21,7 +67,7 @@ export function useGrpcMethodActions() {
name: method.name,
keywords: `${collection.name} ${service.name} ${method.name}`,
subtitle: `${collection.name}${service.name}`,
parent: 'grpc',
parent: 'grpc:new-tab',
icon: (
<Container
gap={0}
Expand Down Expand Up @@ -59,13 +105,14 @@ export function useGrpcMethodActions() {
useRegisterActions(
[
{
id: 'grpc',
section: 'Grpc',
id: 'grpc:new-tab',
section: 'grpc',
name: 'New gRPC Tab',
priority: Priority.HIGH,
icon: <FontAwesomeIcon icon={faSquarePlus} />,
shortcut: ['$mod+T'],
},
invokeAction,
...methods,
],
[methods]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export interface GrpcTabContainerProps {
export const GrpcTabContainer: React.FC<GrpcTabContainerProps> = ({ tab }) => {
const alignment = useSettingsStore((store) => store.alignment);

let content;
let content: React.ReactNode;

if (isGrpcTabUnaryCall(tab)) {
content = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './use-server-streaming';
export * from './use-unary-call';
export * from './use-client-streaming';
export * from './use-bidirectional-streaming';
export * from './use-grpc-tab-context';
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,35 @@ import {
} from '@storage';

import { getOptions, getTlsOptions, parseMetadata, parseRequest } from './prepare-request';
import { useGrpcTabContextStore } from './use-grpc-tab-context';

export function useBidirectionalStreaming() {
const collections = useCollectionsStore((store) => store.collections);
const { addGrpcStreamMessage } = useTabsStore((store) => store);
const tlsPresets = useTlsPresetsStore((store) => store.presets);
const { setContext, getContext, updateContext, deleteContext } = useGrpcTabContextStore();

function isRequestLoading(tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>) {
if (
!!getContext<GrpcMethodType.BIDIRECTIONAL_STREAMING>(tab.id)?.isClientStreaming ||
!!getContext<GrpcMethodType.BIDIRECTIONAL_STREAMING>(tab.id)?.isServerStreaming
) {
throw new Error('Request already invoked');
}
}

function getCallId(tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>): string | undefined {
return getContext<GrpcMethodType>(tab.id)?.callId;
}

async function invoke(
tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>,
onEnd: () => void
): Promise<string | undefined> {
async function invoke(tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>): Promise<void> {
try {
isRequestLoading(tab);

setContext<GrpcMethodType.BIDIRECTIONAL_STREAMING>(tab.id, {
isClientStreaming: true,
isServerStreaming: true,
});
const tls = getTlsOptions(tlsPresets, tab.data.tlsId);
const [grpcOptions, requestOptions] = getOptions(collections, tab, tls);
const metadata = parseMetadata(tab);
Expand Down Expand Up @@ -51,70 +69,83 @@ export function useBidirectionalStreaming() {
value: error.message,
});

onEnd();
deleteContext(tab.id);
},
() => {
addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.SERVER_STREAMING_ENDED,
timestamp: new Date().getTime(),
});

onEnd();
updateContext<GrpcMethodType.BIDIRECTIONAL_STREAMING>(tab.id, {
isClientStreaming: !!getContext<GrpcMethodType.BIDIRECTIONAL_STREAMING>(tab.id)
?.isClientStreaming,
isServerStreaming: false,
});
}
);

return id;
updateContext<GrpcMethodType.BIDIRECTIONAL_STREAMING>(tab.id, { callId: id });
} catch (error: any) {
notification(
{ title: 'Invoke request error', description: error.message },
{ type: 'error' }
);
}

return undefined;
}

async function send(
tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>,
callId: string
): Promise<void> {
async function send(tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>): Promise<void> {
try {
const request = parseRequest(tab);
const callId = getCallId(tab);

await window.clients.grpc.bidirectionalStreaming.send(callId, request);
if (callId) {
const request = parseRequest(tab);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CLIENT_MESSAGE,
timestamp: new Date().getTime(),
value: tab.data.requestTabs.request.value,
});
await window.clients.grpc.bidirectionalStreaming.send(callId, request);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CLIENT_MESSAGE,
timestamp: new Date().getTime(),
value: tab.data.requestTabs.request.value,
});
}
} catch (error: any) {
notification({ title: `Send message error`, description: error.message }, { type: 'error' });
}
}

async function end(
tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>,
callId: string
): Promise<void> {
await window.clients.grpc.bidirectionalStreaming.end(callId);
async function end(tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>): Promise<void> {
const callId = getCallId(tab);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CLIENT_STREAMING_ENDED,
timestamp: new Date().getTime(),
});
if (callId) {
await window.clients.grpc.bidirectionalStreaming.end(callId);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CLIENT_STREAMING_ENDED,
timestamp: new Date().getTime(),
});

updateContext<GrpcMethodType.BIDIRECTIONAL_STREAMING>(tab.id, {
isClientStreaming: false,
isServerStreaming:
getContext<GrpcMethodType.BIDIRECTIONAL_STREAMING>(tab.id)?.isServerStreaming || false,
});
}
}

async function cancel(
tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>,
callId: string
): Promise<void> {
addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CANCELED,
timestamp: new Date().getTime(),
});
async function cancel(tab: GrpcTab<GrpcMethodType.BIDIRECTIONAL_STREAMING>): Promise<void> {
const callId = getCallId(tab);

await window.clients.grpc.bidirectionalStreaming.cancel(callId);
if (callId) {
addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CANCELED,
timestamp: new Date().getTime(),
});

await window.clients.grpc.bidirectionalStreaming.cancel(callId);

deleteContext(tab.id);
}
}

return { invoke, cancel, send, end };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,29 @@ import {
} from '@storage';

import { getOptions, getTlsOptions, parseMetadata, parseRequest } from './prepare-request';
import { useGrpcTabContextStore } from './use-grpc-tab-context';

export function useClientStreaming() {
const collections = useCollectionsStore((store) => store.collections);
const { addGrpcStreamMessage } = useTabsStore((store) => store);
const tlsPresets = useTlsPresetsStore((store) => store.presets);
const { setContext, getContext, updateContext, deleteContext } = useGrpcTabContextStore();

async function invoke(
tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>,
onEnd: () => void
): Promise<string | undefined> {
function isRequestLoading(tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>) {
if (getContext<GrpcMethodType.CLIENT_STREAMING>(tab.id)?.isClientStreaming) {
throw new Error('Request already invoked');
}
}

function getCallId(tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>): string | undefined {
return getContext<GrpcMethodType>(tab.id)?.callId;
}

async function invoke(tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>): Promise<void> {
try {
isRequestLoading(tab);

setContext<GrpcMethodType.CLIENT_STREAMING>(tab.id, { isClientStreaming: true });
const tls = getTlsOptions(tlsPresets, tab.data.tlsId);
const [grpcOptions, requestOptions] = getOptions(collections, tab, tls);
const metadata = parseMetadata(tab);
Expand Down Expand Up @@ -51,59 +63,67 @@ export function useClientStreaming() {
value: JSON.stringify(error, null, 2),
});

onEnd();
deleteContext(tab.id);
}
);

return id;
updateContext<GrpcMethodType.CLIENT_STREAMING>(tab.id, { callId: id });
} catch (error: any) {
notification(
{ title: 'Invoke request error', description: error.message },
{ type: 'error' }
);
}

return undefined;
}

async function send(
tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>,
callId: string
): Promise<void> {
async function send(tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>): Promise<void> {
try {
const request = parseRequest(tab);
const callId = getCallId(tab);

await window.clients.grpc.clientStreaming.send(callId, request);
if (callId) {
const request = parseRequest(tab);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CLIENT_MESSAGE,
timestamp: new Date().getTime(),
value: tab.data.requestTabs.request.value,
});
await window.clients.grpc.clientStreaming.send(callId, request);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CLIENT_MESSAGE,
timestamp: new Date().getTime(),
value: tab.data.requestTabs.request.value,
});
}
} catch (error: any) {
notification({ title: `Send message error`, description: error.message }, { type: 'error' });
}
}

async function end(tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>, callId: string): Promise<void> {
await window.clients.grpc.clientStreaming.end(callId);
async function end(tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>): Promise<void> {
const callId = getCallId(tab);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CLIENT_STREAMING_ENDED,
timestamp: new Date().getTime(),
});
if (callId) {
await window.clients.grpc.clientStreaming.end(callId);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CLIENT_STREAMING_ENDED,
timestamp: new Date().getTime(),
});

deleteContext(tab.id);
}
}

async function cancel(
tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>,
callId: string
): Promise<void> {
await window.clients.grpc.clientStreaming.cancel(callId);
async function cancel(tab: GrpcTab<GrpcMethodType.CLIENT_STREAMING>): Promise<void> {
const callId = getCallId(tab);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CANCELED,
timestamp: new Date().getTime(),
});
if (callId) {
await window.clients.grpc.clientStreaming.cancel(callId);

addGrpcStreamMessage(tab.id, {
type: GrpcStreamMessageType.CANCELED,
timestamp: new Date().getTime(),
});

deleteContext(tab.id);
}
}

return { invoke, cancel, send, end };
Expand Down
Loading

0 comments on commit 7da0710

Please sign in to comment.