summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-15 12:01:11 -0600
committerAdam <[email protected]>2025-12-15 12:01:11 -0600
commit4236744fb5787010d8f930e0599db78d2b58a57f (patch)
tree653342cb3facfa2ddc69e3e58061f1157b0e722b
parent284c045795b531b3ed3aa7b31c4dffa8c46aa122 (diff)
downloadopencode-4236744fb5787010d8f930e0599db78d2b58a57f.tar.gz
opencode-4236744fb5787010d8f930e0599db78d2b58a57f.zip
fix: image attachments in desktop
-rw-r--r--packages/desktop/src/components/prompt-input.tsx79
-rw-r--r--packages/tauri/src-tauri/src/lib.rs1
-rw-r--r--packages/ui/src/components/icon.tsx1
3 files changed, 53 insertions, 28 deletions
diff --git a/packages/desktop/src/components/prompt-input.tsx b/packages/desktop/src/components/prompt-input.tsx
index 595f07972..840710152 100644
--- a/packages/desktop/src/components/prompt-input.tsx
+++ b/packages/desktop/src/components/prompt-input.tsx
@@ -79,6 +79,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
const providers = useProviders()
const command = useCommand()
let editorRef!: HTMLDivElement
+ let fileInputRef!: HTMLInputElement
const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`)
const tabs = createMemo(() => layout.tabs(sessionKey()))
@@ -791,7 +792,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
<Show when={store.dragging}>
<div class="absolute inset-0 z-10 flex items-center justify-center bg-surface-raised-stronger-non-alpha/90 pointer-events-none">
<div class="flex flex-col items-center gap-2 text-text-weak">
- <Icon name="plus" class="size-8" />
+ <Icon name="photo" class="size-8" />
<span class="text-14-regular">Drop images or PDFs here</span>
</div>
</div>
@@ -871,34 +872,56 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
<Icon name="chevron-down" size="small" />
</Button>
</div>
- <Tooltip
- placement="top"
- inactive={!prompt.dirty() && !working()}
- value={
- <Switch>
- <Match when={working()}>
- <div class="flex items-center gap-2">
- <span>Stop</span>
- <span class="text-icon-base text-12-medium text-[10px]!">ESC</span>
- </div>
- </Match>
- <Match when={true}>
- <div class="flex items-center gap-2">
- <span>Send</span>
- <Icon name="enter" size="small" class="text-icon-base" />
- </div>
- </Match>
- </Switch>
- }
- >
- <IconButton
- type="submit"
- disabled={!prompt.dirty() && store.imageAttachments.length === 0 && !working()}
- icon={working() ? "stop" : "arrow-up"}
- variant="primary"
- class="h-10 w-8 absolute right-2 bottom-2"
+ <div class="flex items-center gap-1 absolute right-2 bottom-2">
+ <input
+ ref={fileInputRef}
+ type="file"
+ accept={ACCEPTED_IMAGE_TYPES.join(",")}
+ class="hidden"
+ onChange={(e) => {
+ const file = e.currentTarget.files?.[0]
+ if (file) addImageAttachment(file)
+ e.currentTarget.value = ""
+ }}
/>
- </Tooltip>
+ <Tooltip placement="top" value="Attach image">
+ <IconButton
+ type="button"
+ icon="photo"
+ variant="ghost"
+ class="h-10 w-8"
+ onClick={() => fileInputRef.click()}
+ />
+ </Tooltip>
+ <Tooltip
+ placement="top"
+ inactive={!prompt.dirty() && !working()}
+ value={
+ <Switch>
+ <Match when={working()}>
+ <div class="flex items-center gap-2">
+ <span>Stop</span>
+ <span class="text-icon-base text-12-medium text-[10px]!">ESC</span>
+ </div>
+ </Match>
+ <Match when={true}>
+ <div class="flex items-center gap-2">
+ <span>Send</span>
+ <Icon name="enter" size="small" class="text-icon-base" />
+ </div>
+ </Match>
+ </Switch>
+ }
+ >
+ <IconButton
+ type="submit"
+ disabled={!prompt.dirty() && store.imageAttachments.length === 0 && !working()}
+ icon={working() ? "stop" : "arrow-up"}
+ variant="primary"
+ class="h-10 w-8"
+ />
+ </Tooltip>
+ </div>
</div>
</form>
</div>
diff --git a/packages/tauri/src-tauri/src/lib.rs b/packages/tauri/src-tauri/src/lib.rs
index b06ccd06c..aab2ce5f3 100644
--- a/packages/tauri/src-tauri/src/lib.rs
+++ b/packages/tauri/src-tauri/src/lib.rs
@@ -183,6 +183,7 @@ pub fn run() {
.inner_size(size.width as f64, size.height as f64)
.decorations(true)
.zoom_hotkeys_enabled(true)
+ .disable_drag_drop_handler()
.initialization_script(format!(
r#"
window.__OPENCODE__ ??= {{}};
diff --git a/packages/ui/src/components/icon.tsx b/packages/ui/src/components/icon.tsx
index 0dbd7a650..b8e8106e8 100644
--- a/packages/ui/src/components/icon.tsx
+++ b/packages/ui/src/components/icon.tsx
@@ -51,6 +51,7 @@ const icons = {
"circle-check": `<path d="M12.4987 7.91732L8.7487 12.5007L7.08203 10.834M17.9154 10.0007C17.9154 14.3729 14.371 17.9173 9.9987 17.9173C5.62644 17.9173 2.08203 14.3729 2.08203 10.0007C2.08203 5.6284 5.62644 2.08398 9.9987 2.08398C14.371 2.08398 17.9154 5.6284 17.9154 10.0007Z" stroke="currentColor" stroke-linecap="square"/>`,
copy: `<path d="M6.2513 6.24935V2.91602H17.0846V13.7493H13.7513M13.7513 6.24935V17.0827H2.91797V6.24935H13.7513Z" stroke="currentColor" stroke-linecap="round"/>`,
check: `<path d="M5 11.9657L8.37838 14.7529L15 5.83398" stroke="currentColor" stroke-linecap="square"/>`,
+ photo: `<path d="M16.6665 16.6666L11.6665 11.6666L9.99984 13.3333L6.6665 9.99996L3.08317 13.5833M2.9165 2.91663H17.0832V17.0833H2.9165V2.91663ZM13.3332 7.49996C13.3332 8.30537 12.6803 8.95829 11.8748 8.95829C11.0694 8.95829 10.4165 8.30537 10.4165 7.49996C10.4165 6.69454 11.0694 6.04163 11.8748 6.04163C12.6803 6.04163 13.3332 6.69454 13.3332 7.49996Z" stroke="currentColor" stroke-linecap="square"/>`,
}
export interface IconProps extends ComponentProps<"svg"> {