Tweak getting content type

This commit is contained in:
Gregory Schier
2025-02-23 06:25:53 -08:00
parent dac2cec52f
commit 9d8b7a5265
8 changed files with 17 additions and 29 deletions

View File

@@ -3,7 +3,7 @@ import { useMemo, type ReactNode } from 'react';
import { useSaveResponse } from '../hooks/useSaveResponse'; import { useSaveResponse } from '../hooks/useSaveResponse';
import { useToggle } from '../hooks/useToggle'; import { useToggle } from '../hooks/useToggle';
import { isProbablyTextContentType } from '../lib/contentType'; import { isProbablyTextContentType } from '../lib/contentType';
import { getContentTypeHeader } from '../lib/model_util'; import { getContentTypeFromHeaders } from '../lib/model_util';
import { getResponseBodyText } from '../lib/responseBody'; import { getResponseBodyText } from '../lib/responseBody';
import { CopyButton } from './CopyButton'; import { CopyButton } from './CopyButton';
import { Banner } from './core/Banner'; import { Banner } from './core/Banner';
@@ -24,7 +24,7 @@ export function ConfirmLargeResponse({ children, response }: Props) {
const { mutate: saveResponse } = useSaveResponse(response); const { mutate: saveResponse } = useSaveResponse(response);
const [showLargeResponse, toggleShowLargeResponse] = useToggle(); const [showLargeResponse, toggleShowLargeResponse] = useToggle();
const isProbablyText = useMemo(() => { const isProbablyText = useMemo(() => {
const contentType = getContentTypeHeader(response.headers); const contentType = getContentTypeFromHeaders(response.headers);
return isProbablyTextContentType(contentType); return isProbablyTextContentType(contentType);
}, [response.headers]); }, [response.headers]);

View File

@@ -7,7 +7,6 @@ import type { CSSProperties } from 'react';
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { activeRequestIdAtom } from '../hooks/useActiveRequestId'; import { activeRequestIdAtom } from '../hooks/useActiveRequestId';
import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse'; import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse';
import { useContentTypeFromHeaders } from '../hooks/useContentTypeFromHeaders';
import { grpcRequestsAtom } from '../hooks/useGrpcRequests'; import { grpcRequestsAtom } from '../hooks/useGrpcRequests';
import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication'; import { useHttpAuthenticationSummaries } from '../hooks/useHttpAuthentication';
import { httpRequestsAtom } from '../hooks/useHttpRequests'; import { httpRequestsAtom } from '../hooks/useHttpRequests';
@@ -28,7 +27,7 @@ import {
BODY_TYPE_JSON, BODY_TYPE_JSON,
BODY_TYPE_NONE, BODY_TYPE_NONE,
BODY_TYPE_OTHER, BODY_TYPE_OTHER,
BODY_TYPE_XML, BODY_TYPE_XML, getContentTypeFromHeaders,
} from '../lib/model_util'; } from '../lib/model_util';
import { prepareImportQuerystring } from '../lib/prepareImportQuerystring'; import { prepareImportQuerystring } from '../lib/prepareImportQuerystring';
import { resolvedModelName } from '../lib/resolvedModelName'; import { resolvedModelName } from '../lib/resolvedModelName';
@@ -84,7 +83,7 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }:
const [forceUpdateHeaderEditorKey, setForceUpdateHeaderEditorKey] = useState<number>(0); const [forceUpdateHeaderEditorKey, setForceUpdateHeaderEditorKey] = useState<number>(0);
const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null); const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null);
const [{ urlKey }, { focusParamsTab, forceUrlRefresh, forceParamsRefresh }] = useRequestEditor(); const [{ urlKey }, { focusParamsTab, forceUrlRefresh, forceParamsRefresh }] = useRequestEditor();
const contentType = useContentTypeFromHeaders(activeRequest.headers); const contentType = getContentTypeFromHeaders(activeRequest.headers);
const authentication = useHttpAuthenticationSummaries(); const authentication = useHttpAuthenticationSummaries();
const handleContentTypeChange = useCallback( const handleContentTypeChange = useCallback(

View File

@@ -3,9 +3,9 @@ import classNames from 'classnames';
import type { CSSProperties, ReactNode } from 'react'; import type { CSSProperties, ReactNode } from 'react';
import React, { useCallback, useMemo } from 'react'; import React, { useCallback, useMemo } from 'react';
import { useLocalStorage } from 'react-use'; import { useLocalStorage } from 'react-use';
import { useContentTypeFromHeaders } from '../hooks/useContentTypeFromHeaders';
import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse'; import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse';
import { useResponseViewMode } from '../hooks/useResponseViewMode'; import { useResponseViewMode } from '../hooks/useResponseViewMode';
import { getContentTypeFromHeaders } from '../lib/model_util';
import { ConfirmLargeResponse } from './ConfirmLargeResponse'; import { ConfirmLargeResponse } from './ConfirmLargeResponse';
import { Banner } from './core/Banner'; import { Banner } from './core/Banner';
import { CountBadge } from './core/CountBadge'; import { CountBadge } from './core/CountBadge';
@@ -47,7 +47,7 @@ export function HttpResponsePane({ style, className, activeRequestId }: Props) {
'responsePaneActiveTabs', 'responsePaneActiveTabs',
{}, {},
); );
const contentType = useContentTypeFromHeaders(activeResponse?.headers ?? null); const contentType = getContentTypeFromHeaders(activeResponse?.headers ?? null);
const tabs = useMemo<TabItem[]>( const tabs = useMemo<TabItem[]>(
() => [ () => [

View File

@@ -1,6 +1,6 @@
import type { HttpResponse } from '@yaakapp-internal/models'; import type { HttpResponse } from '@yaakapp-internal/models';
import { useSaveResponse } from '../../hooks/useSaveResponse'; import { useSaveResponse } from '../../hooks/useSaveResponse';
import { getContentTypeHeader } from '../../lib/model_util'; import { getContentTypeFromHeaders } from '../../lib/model_util';
import { Banner } from '../core/Banner'; import { Banner } from '../core/Banner';
import { Button } from '../core/Button'; import { Button } from '../core/Button';
import { InlineCode } from '../core/InlineCode'; import { InlineCode } from '../core/InlineCode';
@@ -13,7 +13,7 @@ interface Props {
export function BinaryViewer({ response }: Props) { export function BinaryViewer({ response }: Props) {
const saveResponse = useSaveResponse(response); const saveResponse = useSaveResponse(response);
const contentType = getContentTypeHeader(response.headers) ?? 'unknown'; const contentType = getContentTypeFromHeaders(response.headers) ?? 'unknown';
// Wait until the response has been fully-downloaded // Wait until the response has been fully-downloaded
if (response.state === 'closed') { if (response.state === 'closed') {

View File

@@ -1,7 +1,7 @@
import type { HttpResponse } from '@yaakapp-internal/models'; import type { HttpResponse } from '@yaakapp-internal/models';
import { useContentTypeFromHeaders } from '../../hooks/useContentTypeFromHeaders';
import { useResponseBodyText } from '../../hooks/useResponseBodyText'; import { useResponseBodyText } from '../../hooks/useResponseBodyText';
import { languageFromContentType } from '../../lib/contentType'; import { languageFromContentType } from '../../lib/contentType';
import { getContentTypeFromHeaders } from '../../lib/model_util';
import { BinaryViewer } from './BinaryViewer'; import { BinaryViewer } from './BinaryViewer';
import { TextViewer } from './TextViewer'; import { TextViewer } from './TextViewer';
import { WebPageViewer } from './WebPageViewer'; import { WebPageViewer } from './WebPageViewer';
@@ -14,10 +14,8 @@ interface Props {
export function HTMLOrTextViewer({ response, pretty, textViewerClassName }: Props) { export function HTMLOrTextViewer({ response, pretty, textViewerClassName }: Props) {
const rawTextBody = useResponseBodyText(response); const rawTextBody = useResponseBodyText(response);
const language = languageFromContentType( const contentType = getContentTypeFromHeaders(response.headers);
useContentTypeFromHeaders(response.headers), const language = languageFromContentType(contentType, rawTextBody.data ?? '');
rawTextBody.data ?? '',
);
if (rawTextBody.isLoading || response.state === 'initialized') { if (rawTextBody.isLoading || response.state === 'initialized') {
return null; return null;

View File

@@ -1,9 +0,0 @@
import type { HttpResponseHeader } from '@yaakapp-internal/models';
import { useMemo } from 'react';
export function useContentTypeFromHeaders(headers: HttpResponseHeader[] | null): string | null {
return useMemo(
() => headers?.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? null,
[headers],
);
}

View File

@@ -3,7 +3,7 @@ import type { HttpResponse } from '@yaakapp-internal/models';
import mime from 'mime'; import mime from 'mime';
import slugify from 'slugify'; import slugify from 'slugify';
import { InlineCode } from '../components/core/InlineCode'; import { InlineCode } from '../components/core/InlineCode';
import { getContentTypeHeader } from '../lib/model_util'; import { getContentTypeFromHeaders } from '../lib/model_util';
import { invokeCmd } from '../lib/tauri'; import { invokeCmd } from '../lib/tauri';
import { showToast } from '../lib/toast'; import { showToast } from '../lib/toast';
import { useFastMutation } from './useFastMutation'; import { useFastMutation } from './useFastMutation';
@@ -13,10 +13,10 @@ export function useSaveResponse(response: HttpResponse) {
return useFastMutation({ return useFastMutation({
mutationKey: ['save_response', response.id], mutationKey: ['save_response', response.id],
mutationFn: async () => { mutationFn: async () => {
const request = await getHttpRequest(response.requestId); const request = getHttpRequest(response.requestId);
if (request == null) return null; if (request == null) return null;
const contentType = getContentTypeHeader(response.headers) ?? 'unknown'; const contentType = getContentTypeFromHeaders(response.headers) ?? 'unknown';
const ext = mime.getExtension(contentType); const ext = mime.getExtension(contentType);
const slug = slugify(request.name || 'response', { lower: true }); const slug = slugify(request.name || 'response', { lower: true });
const filepath = await save({ const filepath = await save({

View File

@@ -36,12 +36,12 @@ export function modelsEq(a: AnyModel, b: AnyModel) {
return false; return false;
} }
export function getContentTypeHeader(headers: HttpResponseHeader[]): string | null { export function getContentTypeFromHeaders(headers: HttpResponseHeader[] | null): string | null {
return headers.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? null; return headers?.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? null;
} }
export function getCharsetFromContentType(headers: HttpResponseHeader[]): string | null { export function getCharsetFromContentType(headers: HttpResponseHeader[]): string | null {
const contentType = getContentTypeHeader(headers); const contentType = getContentTypeFromHeaders(headers);
if (contentType == null) return null; if (contentType == null) return null;
const mimeType = getMimeTypeFromContentType(contentType); const mimeType = getMimeTypeFromContentType(contentType);