Refactor debounce and tauri event listeners

This commit is contained in:
Gregory Schier
2023-04-01 21:39:46 -07:00
parent 5b563b8a16
commit bc35429670
11 changed files with 154 additions and 137 deletions

View File

@@ -1,9 +1,12 @@
import { invoke } from '@tauri-apps/api';
import { appWindow } from '@tauri-apps/api/window';
import classnames from 'classnames';
import type { CSSProperties } from 'react';
import { memo, useCallback, useMemo, useState } from 'react';
import { createGlobalState } from 'react-use';
import { useActiveRequest } from '../hooks/useActiveRequest';
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { useTauriEvent } from '../hooks/useTauriEvent';
import { useUpdateRequest } from '../hooks/useUpdateRequest';
import { tryFormatJson } from '../lib/formatters';
import type { HttpHeader, HttpRequest } from '../lib/models';
@@ -128,6 +131,16 @@ export const RequestPane = memo(function RequestPane({ style, fullHeight, classN
[updateRequest],
);
useTauriEvent(
'send_request',
async ({ windowLabel }) => {
if (windowLabel !== appWindow.label) return;
console.log('SEND REQUEST', activeRequest?.url);
await invoke('send_request', { requestId: activeRequestId });
},
[activeRequestId],
);
return (
<div
style={style}

View File

@@ -122,7 +122,7 @@ export const ResponsePane = memo(function ResponsePane({ style, className }: Pro
) : viewMode === 'pretty' && contentType.includes('json') ? (
<Editor
readOnly
forceUpdateKey={activeResponse.updatedAt}
forceUpdateKey={`pretty::${activeResponse.updatedAt}`}
className="bg-gray-50 dark:!bg-gray-100"
defaultValue={tryFormatJson(activeResponse?.body)}
contentType={contentType}

View File

@@ -1,9 +1,11 @@
import classnames from 'classnames';
import type { EditorView } from 'codemirror';
import type { FormEvent } from 'react';
import { memo, useCallback } from 'react';
import { memo, useCallback, useRef } from 'react';
import { useIsResponseLoading } from '../hooks/useIsResponseLoading';
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { useSendRequest } from '../hooks/useSendRequest';
import { useTauriEvent } from '../hooks/useTauriEvent';
import { useUpdateRequest } from '../hooks/useUpdateRequest';
import type { HttpRequest } from '../lib/models';
import { IconButton } from './core/IconButton';
@@ -15,6 +17,7 @@ type Props = Pick<HttpRequest, 'id' | 'url' | 'method'> & {
};
export const UrlBar = memo(function UrlBar({ id: requestId, url, method, className }: Props) {
const inputRef = useRef<EditorView>(null);
const sendRequest = useSendRequest(requestId);
const updateRequest = useUpdateRequest(requestId);
const handleMethodChange = useCallback(
@@ -36,9 +39,14 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
[sendRequest],
);
useTauriEvent('focus_url', () => {
inputRef.current?.focus();
});
return (
<form onSubmit={handleSubmit} className={classnames('url-bar', className)}>
<Input
ref={inputRef}
size="sm"
hideLabel
useTemplating

View File

@@ -10,6 +10,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useWindowSize } from 'react-use';
import { useSidebarHidden } from '../hooks/useSidebarHidden';
import { useSidebarWidth } from '../hooks/useSidebarWidth';
import { useTauriEvent } from '../hooks/useTauriEvent';
import { WINDOW_FLOATING_SIDEBAR_WIDTH } from '../lib/constants';
import { Button } from './core/Button';
import { HStack } from './core/Stacks';
@@ -27,7 +28,7 @@ const drag = { gridArea: 'drag' };
export default function Workspace() {
const { set: setWidth, value: width, reset: resetWidth } = useSidebarWidth();
const { show, hide, hidden } = useSidebarHidden();
const { show, hide, hidden, toggle } = useSidebarHidden();
const windowSize = useWindowSize();
const [floating, setFloating] = useState<boolean>(false);
@@ -36,6 +37,8 @@ export default function Workspace() {
null,
);
useTauriEvent('toggle_sidebar', toggle);
// float/un-float sidebar on window resize
useEffect(() => {
const shouldHide = windowSize.width <= WINDOW_FLOATING_SIDEBAR_WIDTH;

View File

@@ -1,6 +1,7 @@
import classnames from 'classnames';
import type { EditorView } from 'codemirror';
import type { HTMLAttributes, ReactNode } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { forwardRef, useCallback, useMemo, useState } from 'react';
import type { EditorProps } from './Editor';
import { Editor } from './Editor';
import { IconButton } from './IconButton';
@@ -27,25 +28,28 @@ export type InputProps = Omit<HTMLAttributes<HTMLInputElement>, 'onChange' | 'on
require?: boolean;
};
export function Input({
label,
type = 'text',
hideLabel,
className,
containerClassName,
labelClassName,
onChange,
placeholder,
size = 'md',
name,
leftSlot,
rightSlot,
defaultValue,
validate,
require,
forceUpdateKey,
...props
}: InputProps) {
export const Input = forwardRef<EditorView | undefined, InputProps>(function Input(
{
label,
type = 'text',
hideLabel,
className,
containerClassName,
labelClassName,
onChange,
placeholder,
size = 'md',
name,
leftSlot,
rightSlot,
defaultValue,
validate,
require,
forceUpdateKey,
...props
}: InputProps,
ref,
) {
const [obscured, setObscured] = useState(type === 'password');
const [currentValue, setCurrentValue] = useState(defaultValue ?? '');
const id = `input-${name}`;
@@ -96,6 +100,7 @@ export function Input({
>
{leftSlot}
<Editor
ref={ref}
id={id}
singleLine
type={type === 'password' && !obscured ? 'text' : type}
@@ -120,7 +125,7 @@ export function Input({
</HStack>
</VStack>
);
}
});
function validateRequire(v: string) {
return v.length > 0;