Skip to content

Commit

Permalink
display image attachments as image instead of chip
Browse files Browse the repository at this point in the history
  • Loading branch information
rainu committed Jan 1, 2025
1 parent 78cfa62 commit 29bf64e
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 17 deletions.
47 changes: 47 additions & 0 deletions controller/asset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package controller

import (
"fmt"
"github.com/gabriel-vasile/mimetype"
"io"
"net/http"
"os"
)

type AssetMeta struct {
Path string
MimeType string
}

func (c *Controller) GetAssetMeta(path string) (AssetMeta, error) {
file, err := os.Open(path)
if err != nil {
println("error open asset file: " + err.Error())
return AssetMeta{}, fmt.Errorf("error open asset file: %w", err)
}
defer file.Close()

mime, err := mimetype.DetectReader(file)
if err != nil {
return AssetMeta{}, fmt.Errorf("error detecting mimetype: %w", err)
}

result := AssetMeta{
Path: path,
MimeType: mime.String(),
}

return result, nil
}

func (c *Controller) handleAsset(resp http.ResponseWriter, req *http.Request) {
file, err := os.Open(req.URL.Path)
if err != nil {
resp.WriteHeader(http.StatusNotFound)
return
}
defer file.Close()

resp.WriteHeader(http.StatusOK)
io.Copy(resp, file)
}
3 changes: 2 additions & 1 deletion controller/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/wailsapp/wails/v2/pkg/options/mac"
"github.com/wailsapp/wails/v2/pkg/options/windows"
"log/slog"
"net/http"
)

func BuildFromConfig(cfg *config.Config) (ctrl *Controller, err error) {
Expand Down Expand Up @@ -107,7 +108,7 @@ func GetOptions(c *Controller, icon []byte, assets embed.FS) *options.App {
WindowStartState: options.WindowStartState(ac.UI.Window.StartState),
AssetServer: &assetserver.Options{
Assets: assets,
Handler: nil,
Handler: http.HandlerFunc(c.handleAsset),
Middleware: nil,
},
Bind: []interface{}{
Expand Down
47 changes: 34 additions & 13 deletions frontend/src/components/ChatMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
<vue-markdown :source="textMessage" :options="options" />

<!-- at the moment, only user messages can have attachments -->
<v-chip
v-for="attachment of attachments"
:key="attachment"
prepend-icon="mdi-file"
color="primary"
variant="flat"
>
{{ fileName(attachment) }}
</v-chip>
<template v-for="attachmentMeta of attachmentsMeta" :key="attachmentMeta.Path">
<template v-if="isImage(attachmentMeta)">
<v-img :src="attachmentMeta.Path" :max-width="imageWidth" class="ml-auto" />
</template>
<template v-else>
<v-chip prepend-icon="mdi-file" color="primary" variant="flat">
{{ fileName(attachmentMeta) }}
</v-chip>
</template>
</template>
</v-sheet>
</v-row>
</template>
Expand All @@ -30,11 +31,13 @@
import { defineComponent, PropType } from 'vue'
import VueMarkdown from 'vue-markdown-render'
import { GetAssetMeta } from '../../wailsjs/go/controller/Controller'
import { controller } from '../../wailsjs/go/models.ts'
import AssetMeta = controller.AssetMeta
import LLMMessageContentPart = controller.LLMMessageContentPart
import hljs from 'highlight.js'
import { type Options as MarkdownItOptions } from 'markdown-it'
import { UseCodeStyle } from './code-style.ts'
import { controller } from '../../wailsjs/go/models.ts'
import LLMMessageContentPart = controller.LLMMessageContentPart
export enum Role {
User = 'human',
Expand Down Expand Up @@ -72,6 +75,7 @@ export default defineComponent({
return '' // use external default escaping
},
} as MarkdownItOptions,
attachmentsMeta: [] as AssetMeta[],
}
},
computed: {
Expand All @@ -87,6 +91,9 @@ export default defineComponent({
attachments() {
return this.message.filter((part) => part.Type === ContentType.Attachment).map((part) => part.Content)
},
imageWidth() {
return this.$appConfig.UI.Window.InitialWidth.Value / 5
},
},
methods: {
enrichCopyButtons() {
Expand Down Expand Up @@ -122,14 +129,28 @@ export default defineComponent({
})
}
},
fileName(path: string) {
return path.split('/').pop() || ''
fileName(asset: AssetMeta) {
return asset.Path.split('/').pop() || ''
},
isImage(asset: AssetMeta) {
return asset.MimeType.startsWith('image/')
},
},
watch: {
textMessage() {
this.$nextTick(() => this.enrichCopyButtons())
},
attachments: {
async handler() {
const promises = this.attachments.map((path) => GetAssetMeta(path))
try {
this.attachmentsMeta = await Promise.all(promises)
} catch (e) {
console.error(e)
}
},
immediate: true,
},
},
mounted() {
UseCodeStyle(this.$appConfig.UI.CodeStyle)
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/views/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ export default {
appbarHeight: 0,
progress: false,
input: {
prompt: '',
attachments: [] as string[],
prompt: this.$appConfig.UI.Prompt.InitValue,
attachments: this.$appConfig.UI.Prompt.InitAttachments,
} as ChatInputType,
outputStream: [
{
Expand Down Expand Up @@ -148,7 +148,7 @@ export default {
},
async waitForLLM() {
this.input.prompt = this.$appConfig.UI.Prompt.InitValue
this.input.attachments = []
this.input.attachments = this.$appConfig.UI.Prompt.InitAttachments
await this.processLLM(this.input, () => LLMWait())
},
async onInterrupt() {
Expand Down
2 changes: 2 additions & 0 deletions frontend/wailsjs/go/controller/Controller.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export function AppMounted():Promise<void>;

export function GetApplicationConfig():Promise<config.Config>;

export function GetAssetMeta(arg1:string):Promise<controller.AssetMeta>;

export function LLMAsk(arg1:controller.LLMAskArgs):Promise<string>;

export function LLMInterrupt():Promise<void>;
Expand Down
4 changes: 4 additions & 0 deletions frontend/wailsjs/go/controller/Controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export function GetApplicationConfig() {
return window['go']['controller']['Controller']['GetApplicationConfig']();
}

export function GetAssetMeta(arg1) {
return window['go']['controller']['Controller']['GetAssetMeta'](arg1);
}

export function LLMAsk(arg1) {
return window['go']['controller']['Controller']['LLMAsk'](arg1);
}
Expand Down
14 changes: 14 additions & 0 deletions frontend/wailsjs/go/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,20 @@ export namespace config {

export namespace controller {

export class AssetMeta {
Path: string;
MimeType: string;

static createFrom(source: any = {}) {
return new AssetMeta(source);
}

constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Path = source["Path"];
this.MimeType = source["MimeType"];
}
}
export class LLMMessageContentPart {
Type: string;
Content: string;
Expand Down

0 comments on commit 29bf64e

Please sign in to comment.