mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-01-11 20:00:29 +01:00
Change curl import to post-toast
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import classNames from 'classnames';
|
||||
import type { CSSProperties } from 'react';
|
||||
import { memo, useCallback, useMemo, useState } from 'react';
|
||||
import React, { memo, useCallback, useMemo, useState } from 'react';
|
||||
import { createGlobalState } from 'react-use';
|
||||
import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse';
|
||||
import { useIsResponseLoading } from '../hooks/useIsResponseLoading';
|
||||
@@ -39,7 +39,8 @@ import { HeadersEditor } from './HeadersEditor';
|
||||
import { UrlBar } from './UrlBar';
|
||||
import { UrlParametersEditor } from './UrlParameterEditor';
|
||||
import { useCurlToRequest } from '../hooks/useCurlToRequest';
|
||||
import { useConfirm } from '../hooks/useConfirm';
|
||||
import { useToast } from './ToastContext';
|
||||
import { Icon } from './core/Icon';
|
||||
|
||||
interface Props {
|
||||
style: CSSProperties;
|
||||
@@ -230,7 +231,7 @@ export const RequestPane = memo(function RequestPane({
|
||||
);
|
||||
|
||||
const importCurl = useCurlToRequest();
|
||||
const confirm = useConfirm();
|
||||
const toast = useToast();
|
||||
|
||||
const isLoading = useIsResponseLoading(activeRequestId ?? null);
|
||||
const { updateKey } = useRequestUpdateKey(activeRequestId ?? null);
|
||||
@@ -250,15 +251,15 @@ export const RequestPane = memo(function RequestPane({
|
||||
if (!command.startsWith('curl ')) {
|
||||
return;
|
||||
}
|
||||
const confirmed = await confirm({
|
||||
id: 'paste-curl',
|
||||
title: 'Import from Curl?',
|
||||
description: 'Do you want to overwrite the current request with the Curl command?',
|
||||
confirmText: 'Overwrite',
|
||||
importCurl.mutate({ requestId: activeRequestId, command });
|
||||
toast.show({
|
||||
render: () => [
|
||||
<>
|
||||
<Icon icon="info" />
|
||||
<span>Curl command imported</span>
|
||||
</>,
|
||||
],
|
||||
});
|
||||
if (confirmed) {
|
||||
importCurl.mutate({ requestId: activeRequestId, command });
|
||||
}
|
||||
}}
|
||||
onSend={handleSend}
|
||||
onCancel={handleCancel}
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
MouseEvent as ReactMouseEvent,
|
||||
ReactNode,
|
||||
} from 'react';
|
||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useWindowSize } from 'react-use';
|
||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
||||
@@ -34,7 +34,7 @@ import { Sidebar } from './Sidebar';
|
||||
import { SidebarActions } from './SidebarActions';
|
||||
import { WorkspaceHeader } from './WorkspaceHeader';
|
||||
import { useClipboardText } from '../hooks/useClipboardText';
|
||||
import { Portal } from './Portal';
|
||||
import { useToast } from './ToastContext';
|
||||
|
||||
const side = { gridArea: 'side' };
|
||||
const head = { gridArea: 'head' };
|
||||
@@ -56,7 +56,24 @@ export default function Workspace() {
|
||||
const moveState = useRef<{ move: (e: MouseEvent) => void; up: (e: MouseEvent) => void } | null>(
|
||||
null,
|
||||
);
|
||||
const isCurlInClipboard = !!useClipboardText()?.startsWith('curl ');
|
||||
const clipboardText = useClipboardText();
|
||||
const toast = useToast();
|
||||
|
||||
useEffect(() => {
|
||||
const isCurlInClipboard = clipboardText?.startsWith('curl ');
|
||||
if (!isCurlInClipboard) {
|
||||
return;
|
||||
}
|
||||
|
||||
toast.show({
|
||||
render: () => (
|
||||
<div>
|
||||
<p>Curl command detected?</p>
|
||||
<Button color="primary">Import</Button>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
}, [clipboardText, toast]);
|
||||
|
||||
const unsub = () => {
|
||||
if (moveState.current !== null) {
|
||||
@@ -127,88 +144,83 @@ export default function Workspace() {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Portal name="toast">
|
||||
{isCurlInClipboard && <div className="static right-0 left-0 w-32 h-10">Import</div>}
|
||||
</Portal>
|
||||
<div
|
||||
style={styles}
|
||||
className={classNames(
|
||||
'grid w-full h-full',
|
||||
// Animate sidebar width changes but only when not resizing
|
||||
// because it's too slow to animate on mouse move
|
||||
!isResizing && 'transition-all',
|
||||
)}
|
||||
>
|
||||
{floating ? (
|
||||
<Overlay
|
||||
open={!floatingSidebarHidden}
|
||||
portalName="sidebar"
|
||||
onClose={() => setFloatingSidebarHidden(true)}
|
||||
<div
|
||||
style={styles}
|
||||
className={classNames(
|
||||
'grid w-full h-full',
|
||||
// Animate sidebar width changes but only when not resizing
|
||||
// because it's too slow to animate on mouse move
|
||||
!isResizing && 'transition-all',
|
||||
)}
|
||||
>
|
||||
{floating ? (
|
||||
<Overlay
|
||||
open={!floatingSidebarHidden}
|
||||
portalName="sidebar"
|
||||
onClose={() => setFloatingSidebarHidden(true)}
|
||||
>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
className={classNames(
|
||||
'absolute top-0 left-0 bottom-0 bg-gray-100 border-r border-highlight w-[14rem]',
|
||||
'grid grid-rows-[auto_1fr]',
|
||||
)}
|
||||
>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
className={classNames(
|
||||
'absolute top-0 left-0 bottom-0 bg-gray-100 border-r border-highlight w-[14rem]',
|
||||
'grid grid-rows-[auto_1fr]',
|
||||
)}
|
||||
>
|
||||
<HeaderSize className="border-transparent">
|
||||
<SidebarActions />
|
||||
</HeaderSize>
|
||||
<Sidebar />
|
||||
</motion.div>
|
||||
</Overlay>
|
||||
) : (
|
||||
<>
|
||||
<div style={side} className={classNames('overflow-hidden bg-gray-100')}>
|
||||
<Sidebar className="border-r border-highlight" />
|
||||
</div>
|
||||
<ResizeHandle
|
||||
className="-translate-x-3"
|
||||
justify="end"
|
||||
side="right"
|
||||
isResizing={isResizing}
|
||||
onResizeStart={handleResizeStart}
|
||||
onReset={resetWidth}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<HeaderSize data-tauri-drag-region style={head}>
|
||||
<WorkspaceHeader className="pointer-events-none" />
|
||||
</HeaderSize>
|
||||
{activeWorkspace == null ? (
|
||||
<div className="m-auto">
|
||||
<Banner color="warning" className="max-w-[30rem]">
|
||||
The active workspace{' '}
|
||||
<InlineCode className="text-orange-800">{activeWorkspaceId}</InlineCode> was not
|
||||
found. Select a workspace from the header menu or report this bug to <FeedbackLink />
|
||||
</Banner>
|
||||
<HeaderSize className="border-transparent">
|
||||
<SidebarActions />
|
||||
</HeaderSize>
|
||||
<Sidebar />
|
||||
</motion.div>
|
||||
</Overlay>
|
||||
) : (
|
||||
<>
|
||||
<div style={side} className={classNames('overflow-hidden bg-gray-100')}>
|
||||
<Sidebar className="border-r border-highlight" />
|
||||
</div>
|
||||
) : activeRequest == null ? (
|
||||
<HotKeyList
|
||||
hotkeys={['http_request.create', 'sidebar.toggle', 'settings.show']}
|
||||
bottomSlot={
|
||||
<HStack space={1} justifyContent="center" className="mt-3">
|
||||
<Button variant="border" size="sm" onClick={() => importData.mutate()}>
|
||||
Import
|
||||
</Button>
|
||||
<CreateDropdown hideFolder>
|
||||
<Button variant="border" forDropdown size="sm">
|
||||
New Request
|
||||
</Button>
|
||||
</CreateDropdown>
|
||||
</HStack>
|
||||
}
|
||||
<ResizeHandle
|
||||
className="-translate-x-3"
|
||||
justify="end"
|
||||
side="right"
|
||||
isResizing={isResizing}
|
||||
onResizeStart={handleResizeStart}
|
||||
onReset={resetWidth}
|
||||
/>
|
||||
) : activeRequest.model === 'grpc_request' ? (
|
||||
<GrpcConnectionLayout style={body} />
|
||||
) : (
|
||||
<HttpRequestLayout activeRequest={activeRequest} style={body} />
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
</>
|
||||
)}
|
||||
<HeaderSize data-tauri-drag-region style={head}>
|
||||
<WorkspaceHeader className="pointer-events-none" />
|
||||
</HeaderSize>
|
||||
{activeWorkspace == null ? (
|
||||
<div className="m-auto">
|
||||
<Banner color="warning" className="max-w-[30rem]">
|
||||
The active workspace{' '}
|
||||
<InlineCode className="text-orange-800">{activeWorkspaceId}</InlineCode> was not found.
|
||||
Select a workspace from the header menu or report this bug to <FeedbackLink />
|
||||
</Banner>
|
||||
</div>
|
||||
) : activeRequest == null ? (
|
||||
<HotKeyList
|
||||
hotkeys={['http_request.create', 'sidebar.toggle', 'settings.show']}
|
||||
bottomSlot={
|
||||
<HStack space={1} justifyContent="center" className="mt-3">
|
||||
<Button variant="border" size="sm" onClick={() => importData.mutate()}>
|
||||
Import
|
||||
</Button>
|
||||
<CreateDropdown hideFolder>
|
||||
<Button variant="border" forDropdown size="sm">
|
||||
New Request
|
||||
</Button>
|
||||
</CreateDropdown>
|
||||
</HStack>
|
||||
}
|
||||
/>
|
||||
) : activeRequest.model === 'grpc_request' ? (
|
||||
<GrpcConnectionLayout style={body} />
|
||||
) : (
|
||||
<HttpRequestLayout activeRequest={activeRequest} style={body} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,6 @@ import { readText } from '@tauri-apps/plugin-clipboard-manager';
|
||||
export function useClipboardText() {
|
||||
return useQuery({
|
||||
queryKey: [],
|
||||
queryFn: async () => {
|
||||
const text = await readText();
|
||||
console.log('READ CLIPBOARD', text);
|
||||
return text;
|
||||
},
|
||||
queryFn: () => readText(),
|
||||
}).data;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user