Compare commits

..

1 Commits

Author SHA1 Message Date
minori 1a6bd0f38f deps: update react to 19.2.4
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m10s
CI / Lint & Check (pull_request) Successful in 14m5s
CI / Build Windows (pull_request) Failing after 30m42s
2026-04-10 07:06:02 -07:00
5 changed files with 56 additions and 72 deletions
+1 -1
View File
@@ -14,7 +14,7 @@
"@tauri-apps/api": "2.5.0", "@tauri-apps/api": "2.5.0",
"@tauri-apps/plugin-dialog": "2.3.0", "@tauri-apps/plugin-dialog": "2.3.0",
"@tauri-apps/plugin-fs": "2.4.0", "@tauri-apps/plugin-fs": "2.4.0",
"react": "19.1.0", "react": "19.2.4",
"react-dom": "19.1.0" "react-dom": "19.1.0"
}, },
"devDependencies": { "devDependencies": {
+11 -11
View File
@@ -18,15 +18,15 @@ importers:
specifier: 2.4.0 specifier: 2.4.0
version: 2.4.0 version: 2.4.0
react: react:
specifier: 19.1.0 specifier: 19.2.4
version: 19.1.0 version: 19.2.4
react-dom: react-dom:
specifier: 19.1.0 specifier: 19.1.0
version: 19.1.0(react@19.1.0) version: 19.1.0(react@19.2.4)
devDependencies: devDependencies:
'@nhcarrigan/eslint-config': '@nhcarrigan/eslint-config':
specifier: 5.2.0 specifier: 5.2.0
version: 5.2.0(@typescript-eslint/utils@8.58.1(eslint@9.25.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.25.1(jiti@1.21.7))(playwright@1.59.1)(react@19.1.0)(typescript@5.8.3)(vitest@4.1.4(vite@6.3.2(jiti@1.21.7)(yaml@2.8.3))) version: 5.2.0(@typescript-eslint/utils@8.58.1(eslint@9.25.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.25.1(jiti@1.21.7))(playwright@1.59.1)(react@19.2.4)(typescript@5.8.3)(vitest@4.1.4(vite@6.3.2(jiti@1.21.7)(yaml@2.8.3)))
'@nhcarrigan/typescript-config': '@nhcarrigan/typescript-config':
specifier: 4.0.0 specifier: 4.0.0
version: 4.0.0(typescript@5.8.3) version: 4.0.0(typescript@5.8.3)
@@ -1960,8 +1960,8 @@ packages:
resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
react@19.1.0: react@19.2.4:
resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
read-cache@1.0.0: read-cache@1.0.0:
@@ -2707,7 +2707,7 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2 '@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/sourcemap-codec': 1.5.5
'@nhcarrigan/eslint-config@5.2.0(@typescript-eslint/utils@8.58.1(eslint@9.25.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.25.1(jiti@1.21.7))(playwright@1.59.1)(react@19.1.0)(typescript@5.8.3)(vitest@4.1.4(vite@6.3.2(jiti@1.21.7)(yaml@2.8.3)))': '@nhcarrigan/eslint-config@5.2.0(@typescript-eslint/utils@8.58.1(eslint@9.25.1(jiti@1.21.7))(typescript@5.8.3))(eslint@9.25.1(jiti@1.21.7))(playwright@1.59.1)(react@19.2.4)(typescript@5.8.3)(vitest@4.1.4(vite@6.3.2(jiti@1.21.7)(yaml@2.8.3)))':
dependencies: dependencies:
'@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.25.1(jiti@1.21.7)) '@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.25.1(jiti@1.21.7))
'@eslint/compat': 1.2.4(eslint@9.25.1(jiti@1.21.7)) '@eslint/compat': 1.2.4(eslint@9.25.1(jiti@1.21.7))
@@ -2727,7 +2727,7 @@ snapshots:
eslint-plugin-unicorn: 56.0.1(eslint@9.25.1(jiti@1.21.7)) eslint-plugin-unicorn: 56.0.1(eslint@9.25.1(jiti@1.21.7))
globals: 15.14.0 globals: 15.14.0
playwright: 1.59.1 playwright: 1.59.1
react: 19.1.0 react: 19.2.4
typescript: 5.8.3 typescript: 5.8.3
vitest: 4.1.4(vite@6.3.2(jiti@1.21.7)(yaml@2.8.3)) vitest: 4.1.4(vite@6.3.2(jiti@1.21.7)(yaml@2.8.3))
transitivePeerDependencies: transitivePeerDependencies:
@@ -4435,16 +4435,16 @@ snapshots:
queue-microtask@1.2.3: {} queue-microtask@1.2.3: {}
react-dom@19.1.0(react@19.1.0): react-dom@19.1.0(react@19.2.4):
dependencies: dependencies:
react: 19.1.0 react: 19.2.4
scheduler: 0.26.0 scheduler: 0.26.0
react-is@16.13.1: {} react-is@16.13.1: {}
react-refresh@0.17.0: {} react-refresh@0.17.0: {}
react@19.1.0: {} react@19.2.4: {}
read-cache@1.0.0: read-cache@1.0.0:
dependencies: dependencies:
Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 KiB

After

Width:  |  Height:  |  Size: 155 KiB

+10 -14
View File
@@ -83,26 +83,22 @@ fn build_user_gemini_parts(
user_image_base64: &Option<String>, user_image_base64: &Option<String>,
user_image_mime: &Option<String>, user_image_mime: &Option<String>,
) -> Vec<Value> { ) -> Vec<Value> {
if let Some(image_data) = user_image_base64.as_deref() { if mode == "replace" && user_image_base64.is_some() {
let mime = user_image_mime.as_deref().unwrap_or("image/png"); let mime = user_image_mime.as_deref().unwrap_or("image/png");
let data = user_image_base64.as_deref().unwrap_or("");
let base_text = user_text.as_deref().unwrap_or(""); let base_text = user_text.as_deref().unwrap_or("");
let final_text = if mode == "replace" { let final_text = if base_text.is_empty() {
if base_text.is_empty() { REPLACE_MODE_APPEND.to_string()
REPLACE_MODE_APPEND.to_string()
} else {
format!("{}\n{}", base_text, REPLACE_MODE_APPEND)
}
} else { } else {
base_text.to_string() format!("{}\n{}", base_text, REPLACE_MODE_APPEND)
}; };
let mut parts = vec![json!({"inlineData": {"mimeType": mime, "data": image_data}})]; vec![
if !final_text.is_empty() { json!({"inlineData": {"mimeType": mime, "data": data}}),
parts.push(json!({"text": final_text})); json!({"text": final_text}),
} ]
parts
} else { } else {
// No image: text-only message // Art/avatar mode, or replace mode follow-up correction (text only)
let text = user_text.as_deref().unwrap_or(""); let text = user_text.as_deref().unwrap_or("");
vec![json!({"text": text})] vec![json!({"text": text})]
} }
+34 -46
View File
@@ -256,8 +256,7 @@ const inputArea = ({
if (isInitialReplace && imageBase64 === undefined) { if (isInitialReplace && imageBase64 === undefined) {
return; return;
} }
const hasContent = text.trim().length > 0 || imageBase64 !== undefined; if (!isInitialReplace && text.trim().length === 0) {
if (!isInitialReplace && !hasContent) {
return; return;
} }
@@ -333,9 +332,6 @@ const inputArea = ({
: dropZoneInactiveClass, : dropZoneInactiveClass,
].join(" "); ].join(" ");
const hasNoContent = text.trim().length === 0 && imageBase64 === undefined;
const isSendDisabled = isLoading || hasNoContent;
return ( return (
<div className="border-t border-purple-900/30 p-4 bg-[#0f0a1a]"> <div className="border-t border-purple-900/30 p-4 bg-[#0f0a1a]">
<div className="flex items-center gap-2 mb-2"> <div className="flex items-center gap-2 mb-2">
@@ -401,15 +397,6 @@ const inputArea = ({
type="file" type="file"
/> />
<textarea
className={textareaClass}
disabled={isLoading}
onChange={handleTextChange}
placeholder="Add notes to include with the image (optional)..."
rows={2}
value={text}
/>
<button <button
className={replaceButtonClass} className={replaceButtonClass}
disabled={isLoading || imageBase64 === undefined} disabled={isLoading || imageBase64 === undefined}
@@ -427,40 +414,41 @@ const inputArea = ({
</div> </div>
: <div className="flex flex-col gap-3"> : <div className="flex flex-col gap-3">
<div className="flex flex-col gap-2"> {mode === "replace"
{imagePreview === undefined ? <div className="flex flex-col gap-2">
? <button {imagePreview === undefined
className={pasteButtonClass} ? <button
onClick={handlePasteButtonClick} className={pasteButtonClass}
type="button" onClick={handlePasteButtonClick}
>
{mode === "replace"
? "📋 Paste replacement image (optional)"
: "📋 Paste image (optional)"}
</button>
: <div className="relative inline-block">
<img
alt="Upload preview"
className="max-h-32 rounded-lg border border-purple-700/40"
src={imagePreview}
/>
<button
className={clearButtonClass}
onClick={clearImage}
type="button" type="button"
> >
{"×"} {"📋 Paste replacement image (optional)"}
</button> </button>
</div>}
<input : <div className="relative inline-block">
accept="image/*" <img
className="hidden" alt="Upload preview"
onChange={handleFileChange} className="max-h-32 rounded-lg border border-purple-700/40"
ref={fileInputReference} src={imagePreview}
type="file" />
/> <button
</div> className={clearButtonClass}
onClick={clearImage}
type="button"
>
{"×"}
</button>
</div>}
<input
accept="image/*"
className="hidden"
onChange={handleFileChange}
ref={fileInputReference}
type="file"
/>
</div>
: null}
<div className="flex gap-3 items-end"> <div className="flex gap-3 items-end">
<textarea <textarea
@@ -476,7 +464,7 @@ const inputArea = ({
/> />
<button <button
className={sendButtonClass} className={sendButtonClass}
disabled={isSendDisabled} disabled={isLoading || text.trim().length === 0}
onClick={handleSend} onClick={handleSend}
type="button" type="button"
> >