Skip to content

Commit

Permalink
implement music creation frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
juzeon committed Mar 3, 2024
1 parent 3354c92 commit 8652712
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 13 deletions.
30 changes: 30 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,36 @@ func (a *App) SaveRemoteJPEGImage(url string) error {
}
return os.WriteFile(filePath, resp.Bytes(), 0644)
}
func (a *App) SaveRemoteFile(extWithoutDot, defaultFilenameWithoutExt, url string) error {
filePath, err := runtime.SaveFileDialog(a.ctx, runtime.SaveDialogOptions{
Title: "Choose a destination to save the file",
Filters: []runtime.FileFilter{{
DisplayName: "*." + extWithoutDot,
Pattern: "*." + extWithoutDot,
}},
DefaultFilename: lo.Ternary(defaultFilenameWithoutExt != "", defaultFilenameWithoutExt, "file") +
"." + extWithoutDot,
CanCreateDirectories: true,
})
if err != nil {
return err
}
if filePath == "" { // cancelled
return nil
}
_, client, err := util.MakeHTTPClient(a.settings.config.Proxy, 60*time.Second)
if err != nil {
return err
}
resp, err := client.R().Get(url)
if err != nil {
return err
}
if !strings.HasSuffix(filePath, "."+extWithoutDot) {
filePath += "." + extWithoutDot
}
return os.WriteFile(filePath, resp.Bytes(), 0644)
}
func (a *App) ExportWorkspace(id int) error {
workspace, ok := lo.Find(a.settings.config.Workspaces, func(item Workspace) bool {
return item.ID == id
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/components/index/RichChatContext.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'katex/dist/katex.min.css'
import {v4 as uuidV4} from "uuid"
import RichImageBlock from "./rich_blocks/RichImageBlock.vue"
import {main} from "../../../wailsjs/go/models"
import RichMusicBlock from "./rich_blocks/RichMusicBlock.vue"
import DataReference = main.DataReference
let props = defineProps<{
Expand Down Expand Up @@ -175,6 +176,10 @@ onUpdated(() => {
<rich-image-block v-else-if="findDataReferenceFromUUID(message.message)!.type==='image'"
:custom-font-style="customFontStyle"
:data="findDataReferenceFromUUID(message.message)!.data"></rich-image-block>
<rich-music-block v-else-if="findDataReferenceFromUUID(message.message)!.type==='music'"
:custom-font-style="customFontStyle"
:data="findDataReferenceFromUUID(message.message)!.data"></rich-music-block>
<div v-else><i>Undefined data reference type: {{ findDataReferenceFromUUID(message.message)!.type }}</i></div>
</div>
<div v-else-if="showSystemPrompt || !(message.role==='system' && message.type==='additional_instructions')"
v-html="renderMessage(message)" class="my-1"></div>
Expand Down
76 changes: 76 additions & 0 deletions frontend/src/components/index/rich_blocks/RichMusicBlock.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<script setup lang="ts">
import {sydney} from "../../../../wailsjs/go/models"
import dayjs from "dayjs"
import duration from "dayjs/plugin/duration"
import {ref} from "vue"
import {SaveRemoteFile} from "../../../../wailsjs/go/main/App"
import {swal} from "../../../helper"
import GenerateMusicResult = sydney.GenerateMusicResult
dayjs.extend(duration)
let props = defineProps<{
data: GenerateMusicResult,
customFontStyle: any,
}>()
let previewDialog = ref(false)
let saving = ref(false)
function saveFile(type: string) {
let errHandle = (err: any) => {
swal.error(err)
}
let finalize = () => {
saving.value = false
}
saving.value = true
if (type === 'audio') {
SaveRemoteFile('mp3', props.data.title, props.data.music_url).catch(errHandle).finally(finalize)
} else {
SaveRemoteFile('mp4', props.data.title, props.data.video_url).catch(errHandle).finally(finalize)
}
}
</script>

<template>
<div :style="{'font-family':customFontStyle['font-family']}">
<div class="d-flex mt-2">
<div>
<img :src="data.cover_img_url" alt="Cover Image" class="d-block">
<div class="d-flex justify-center">
<v-btn @click="previewDialog=true" variant="tonal" color="primary" class="mt-1">Preview</v-btn>
</div>
</div>
<div class="ml-3">
<div class="d-flex align-center">
<div style="font-size: 18px" class="d-flex align-center">
<v-icon class="mr-2">mdi-music</v-icon>
<p><b>{{ data.title }}</b></p>
</div>
<p class="text-caption ml-3" style="color: #999">Musical style: {{ data.musical_style }}
(generation took {{
dayjs.duration(Math.floor(data.duration / 1000 / 1000)).asSeconds()
}} seconds)</p>
</div>
<div v-html="data.lyrics.replaceAll('\n', '<br/>')"></div>
</div>
</div>
<v-dialog max-width="400" v-model="previewDialog">
<v-card title="Music Preview">
<v-card-text class="d-flex justify-center">
<video style="max-height: 550px" controls :src="data.video_url"></video>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn variant="text" color="primary" :loading="saving" @click="saveFile('video')">Save Video File</v-btn>
<v-btn variant="text" color="primary" :loading="saving" @click="saveFile('audio')">Save Audio File</v-btn>
<v-btn variant="text" color="primary" @click="previewDialog=false">Close</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>

<style scoped>
</style>
38 changes: 25 additions & 13 deletions frontend/src/pages/IndexPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {computed, onMounted, onUnmounted, ref, watch} from "vue"
import {main, sydney} from "../../wailsjs/go/models"
import {EventsEmit, EventsOff, EventsOn} from "../../wailsjs/runtime"
import {fromChatMessages, generateRandomName, shadeColor, swal, toChatMessages} from "../helper"
import {AskAI, CountToken, GenerateImage, GetConciseAnswer} from "../../wailsjs/go/main/App"
import {AskAI, CountToken, GenerateImage, GenerateMusic, GetConciseAnswer} from "../../wailsjs/go/main/App"
import {AskTypeOpenAI, AskTypeSydney} from "../constants"
import Scaffold from "../components/Scaffold.vue"
import {useSettings} from "../composables"
Expand Down Expand Up @@ -367,12 +367,14 @@ function generateImage(req: GenerativeImage) {
}
function generateMusic(req: GenerativeMusic) {
// TODO generate music
// remove image packs from workspace; remove image window
// add a data array to workspace
// each data has a uuid
// use [assistant](#syndey_inner_data) etc to specify uuid to be replaced in rich context
// this message should not be sent to Bing and excluded from token count (?)
generativeMediaLoading.value = true
GenerateMusic(req).then(res => {
insertAsDataReference('music', res)
}).catch(err => {
swal.error(err)
}).finally(() => {
generativeMediaLoading.value = false
})
}
let workspaceNav = ref(null)
Expand All @@ -387,7 +389,7 @@ let pluginList = [
{
name: 'Suno',
description: 'Music creator. Generating audios, videos and cover images for music.'
},
}
]
function generateTitle() {
Expand Down Expand Up @@ -473,15 +475,25 @@ function generateTitle() {
color="primary"></v-switch>
</template>
</v-tooltip>
<v-btn @click="pluginDialog=true" icon variant="text" color="primary">
<v-icon>mdi-toy-brick</v-icon>
</v-btn>
<v-tooltip text="Plugins" location="bottom">
<template #activator="{props}">
<v-btn v-bind="props" @click="pluginDialog=true" icon variant="text" color="primary">
<v-icon>mdi-toy-brick</v-icon>
</v-btn>
</template>
</v-tooltip>
<v-dialog max-width="300" v-model="pluginDialog">
<v-card title="Plugins">
<v-card-text>
<div v-for="plugin in pluginList">
<v-checkbox :label="plugin.name" v-model="currentWorkspace.plugins"></v-checkbox>
<p class="text-caption">{{ plugin.description }}</p>
<v-checkbox :value="plugin.name" density="compact" :label="plugin.name"
v-model="currentWorkspace.plugins">
<template #details>
<div style="width: 100%">
<p>{{ plugin.description }}</p>
</div>
</template>
</v-checkbox>
</div>
</v-card-text>
<v-card-actions>
Expand Down
2 changes: 2 additions & 0 deletions frontend/wailsjs/go/main/App.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export function GetConciseAnswer(arg1:main.ConciseAnswerReq):Promise<string>;

export function GetUser():Promise<string>;

export function SaveRemoteFile(arg1:string,arg2:string,arg3:string):Promise<void>;

export function SaveRemoteJPEGImage(arg1:string):Promise<void>;

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

export function SaveRemoteFile(arg1, arg2, arg3) {
return window['go']['main']['App']['SaveRemoteFile'](arg1, arg2, arg3);
}

export function SaveRemoteJPEGImage(arg1) {
return window['go']['main']['App']['SaveRemoteJPEGImage'](arg1);
}
Expand Down

0 comments on commit 8652712

Please sign in to comment.