generated from nhcarrigan/template
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 84b6c3109f |
+1
-1
@@ -13,7 +13,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@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.5",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
"react-dom": "19.1.0"
|
"react-dom": "19.1.0"
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+5
-5
@@ -15,8 +15,8 @@ importers:
|
|||||||
specifier: 2.3.0
|
specifier: 2.3.0
|
||||||
version: 2.3.0
|
version: 2.3.0
|
||||||
'@tauri-apps/plugin-fs':
|
'@tauri-apps/plugin-fs':
|
||||||
specifier: 2.4.0
|
specifier: 2.4.5
|
||||||
version: 2.4.0
|
version: 2.4.5
|
||||||
react:
|
react:
|
||||||
specifier: 19.1.0
|
specifier: 19.1.0
|
||||||
version: 19.1.0
|
version: 19.1.0
|
||||||
@@ -652,8 +652,8 @@ packages:
|
|||||||
'@tauri-apps/plugin-dialog@2.3.0':
|
'@tauri-apps/plugin-dialog@2.3.0':
|
||||||
resolution: {integrity: sha512-ylSBvYYShpGlKKh732ZuaHyJ5Ie1JR71QCXewCtsRLqGdc8Is4xWdz6t43rzXyvkItM9syNPMvFVcvjgEy+/GA==}
|
resolution: {integrity: sha512-ylSBvYYShpGlKKh732ZuaHyJ5Ie1JR71QCXewCtsRLqGdc8Is4xWdz6t43rzXyvkItM9syNPMvFVcvjgEy+/GA==}
|
||||||
|
|
||||||
'@tauri-apps/plugin-fs@2.4.0':
|
'@tauri-apps/plugin-fs@2.4.5':
|
||||||
resolution: {integrity: sha512-Sp8AdDcbyXyk6LD6Pmdx44SH3LPeNAvxR2TFfq/8CwqzfO1yOyV+RzT8fov0NNN7d9nvW7O7MtMAptJ42YXA5g==}
|
resolution: {integrity: sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA==}
|
||||||
|
|
||||||
'@types/babel__core@7.20.5':
|
'@types/babel__core@7.20.5':
|
||||||
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
||||||
@@ -2900,7 +2900,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.10.1
|
'@tauri-apps/api': 2.10.1
|
||||||
|
|
||||||
'@tauri-apps/plugin-fs@2.4.0':
|
'@tauri-apps/plugin-fs@2.4.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.10.1
|
'@tauri-apps/api': 2.10.1
|
||||||
|
|
||||||
|
|||||||
+10
-14
@@ -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})]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user