Compare commits

..

2 Commits

Author SHA1 Message Date
Gregory Schier
65e7c804d7 Parse window title and theme better 2024-06-12 10:15:14 -07:00
Gregory Schier
23ec8bee8f Move binary detection to TextViewer 2024-06-12 09:47:34 -07:00
6 changed files with 35 additions and 39 deletions

2
src-tauri/Cargo.lock generated
View File

@@ -8136,7 +8136,7 @@ dependencies = [
]
[[package]]
name = "yaak"
name = "yaak-app"
version = "0.0.0"
dependencies = [
"anyhow",

View File

@@ -1,4 +1,5 @@
use hex_color::HexColor;
use log::warn;
use objc::{msg_send, sel, sel_impl};
use rand::{distributions::Alphanumeric, Rng};
use tauri::{
@@ -25,15 +26,35 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
let window_for_theme = window.clone();
let id1 = h.listen("yaak_bg_changed", move |ev| {
let payload = serde_json::from_str::<&str>(ev.payload()).unwrap().trim();
let color = HexColor::parse_rgb(payload).unwrap();
update_window_theme(window_for_theme.clone(), color);
let color_str: String = match serde_json::from_str(ev.payload()) {
Ok(color) => color,
Err(err) => {
warn!("Failed to JSON parse color '{}': {}", ev.payload(), err);
return;
}
};
match HexColor::parse_rgb(color_str.trim()) {
Ok(color) => {
update_window_theme(window_for_theme.clone(), color);
}
Err(err) => {
warn!("Failed to parse background color '{}': {}", color_str, err)
}
}
});
let window_for_title = window.clone();
let id2 = h.listen("yaak_title_changed", move |ev| {
let payload = serde_json::from_str::<&str>(ev.payload()).unwrap().trim();
update_window_title(window_for_title.clone(), payload.to_string());
let title: String = match serde_json::from_str(ev.payload()) {
Ok(title) => title,
Err(err) => {
warn!("Failed to parse window title \"{}\": {}", ev.payload(), err);
return;
}
};
update_window_title(window_for_title.clone(), title);
});
let h = h.clone();

View File

@@ -1,6 +1,6 @@
{
"productName": "yaak",
"version": "2024.6.2",
"version": "2024.6.3",
"identifier": "app.yaak.desktop",
"build": {
"beforeBuildCommand": "npm run build",

View File

@@ -5,7 +5,6 @@ import { createGlobalState } from 'react-use';
import { useContentTypeFromHeaders } from '../hooks/useContentTypeFromHeaders';
import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse';
import { useResponseViewMode } from '../hooks/useResponseViewMode';
import { isBinaryContentType } from '../lib/data/mimetypes';
import type { HttpRequest } from '../lib/models';
import { isResponseLoading } from '../lib/models';
import { Banner } from './core/Banner';
@@ -22,7 +21,6 @@ import { EmptyStateText } from './EmptyStateText';
import { RecentResponsesDropdown } from './RecentResponsesDropdown';
import { ResponseHeaders } from './ResponseHeaders';
import { AudioViewer } from './responseViewers/AudioViewer';
import { BinaryViewer } from './responseViewers/BinaryViewer';
import { CsvViewer } from './responseViewers/CsvViewer';
import { ImageViewer } from './responseViewers/ImageViewer';
import { PdfViewer } from './responseViewers/PdfViewer';
@@ -163,12 +161,8 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ
<VideoViewer response={activeResponse} />
) : contentType?.match(/pdf/) ? (
<PdfViewer response={activeResponse} />
) : isBinaryContentType(contentType) ? (
<BinaryViewer response={activeResponse} />
) : contentType?.match(/csv|tab-separated/) ? (
<CsvViewer className="pb-2" response={activeResponse} />
) : activeResponse.contentLength > 2 * 1000 * 1000 ? (
<EmptyStateText>Cannot preview text responses larger than 2MB</EmptyStateText>
) : viewMode === 'pretty' && contentType?.includes('html') ? (
<WebPageViewer response={activeResponse} />
) : (

View File

@@ -12,6 +12,8 @@ import { Editor } from '../core/Editor';
import { hyperlink } from '../core/Editor/hyperlink/extension';
import { IconButton } from '../core/IconButton';
import { Input } from '../core/Input';
import { EmptyStateText } from '../EmptyStateText';
import { BinaryViewer } from './BinaryViewer';
const extraExtensions = [hyperlink];
@@ -98,7 +100,11 @@ export function TextViewer({ response, pretty, className }: Props) {
}, [canFilter, filterText, isJson, isSearching, response.id, setFilterText, toggleSearch]);
if (rawBody == null) {
return 'bad';
return <BinaryViewer response={response} />;
}
if ((response.contentLength ?? 0) > 2 * 1000 * 1000) {
return <EmptyStateText>Cannot preview text responses larger than 2MB</EmptyStateText>;
}
const formattedBody =

View File

@@ -206,28 +206,3 @@ export const mimeTypes = [
'video/x-flv',
'video/x-m4v',
];
export function isBinaryContentType(contentType: string | null) {
const mimeType = contentType?.split(';')[0];
if (mimeType == null) return false;
const [first, second] = mimeType.split('/').map((s) => s.trim().toLowerCase());
if (first == 'text' || second == null) {
return false;
}
if (first != 'application') {
return true;
}
const isTextSubtype =
second === 'json' ||
second === 'ld+json' ||
second === 'x-httpd-php' ||
second === 'x-sh' ||
second === 'x-csh' ||
second === 'xhtml+xml' ||
second === 'xml';
return !isTextSubtype;
}