Update to 1.14.0 (#78)
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"package": {
|
||||
"productName": "RisuAI",
|
||||
"version": "1.13.2"
|
||||
"version": "1.14.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
|
||||
@@ -259,5 +259,11 @@ export const languageEnglish = {
|
||||
user:"User",
|
||||
additionalAssets:"Additional Assets",
|
||||
editDisplay: "Modify Display",
|
||||
community: "Community"
|
||||
community: "Community",
|
||||
textBackgrounds: "Custom Text Screen Color",
|
||||
textBorder: "Text Outlines",
|
||||
textScreenRound: "Round Text Screen",
|
||||
textScreenBorder: "Text Screen Borders",
|
||||
ttsReadOnlyQuoted: "Read Only Quoted",
|
||||
ttsStop: "Stop TTS"
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
let openChatList = false
|
||||
|
||||
const wallPaper = `background: url(${defaultWallpaper})`
|
||||
const externalStyles =
|
||||
("background: " + ($DataBase.textScreenColor ? ($DataBase.textScreenColor + '80') : "rgba(0,0,0,0.8)") + ';\n')
|
||||
+ ($DataBase.textBorder ? "text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;" : '')
|
||||
+ ($DataBase.textScreenRounded ? "border-radius: 2rem; padding: 1rem;" : '')
|
||||
+ ($DataBase.textScreenBorder ? `border: 0.3rem solid ${$DataBase.textScreenBorder};` : '')
|
||||
let bgImg= ''
|
||||
let lastBg = ''
|
||||
|
||||
@@ -27,7 +32,7 @@
|
||||
<ResizeBox />
|
||||
{/if}
|
||||
{/if}
|
||||
<DefaultChatScreen customStyle={bgImg.length > 2 ? 'background: rgba(0,0,0,0.8)': ''} bind:openChatList/>
|
||||
<DefaultChatScreen customStyle={bgImg.length > 2 ? `${externalStyles}`: ''} bind:openChatList/>
|
||||
</div>
|
||||
{:else if $DataBase.theme === 'waifu'}
|
||||
<div class="flex-grow h-full flex justify-center" style="max-width:calc({$sideBarStore ? $SizeStore.w - 400 : $SizeStore.w}px);{bgImg.length < 4 ? wallPaper : bgImg}">
|
||||
@@ -39,13 +44,13 @@
|
||||
{/if}
|
||||
{/if}
|
||||
<div class="h-full w-2xl" style:width="{42 * ($DataBase.waifuWidth / 100)}rem" class:halfwp={$selectedCharID >= 0 && $DataBase.characters[$selectedCharID].viewScreen !== 'none'}>
|
||||
<DefaultChatScreen customStyle={'background: rgba(0,0,0,0.8);backdrop-filter: blur(4px);'} bind:openChatList/>
|
||||
<DefaultChatScreen customStyle={`${externalStyles}backdrop-filter: blur(4px);`} bind:openChatList/>
|
||||
</div>
|
||||
</div>
|
||||
{:else if $DataBase.theme === 'waifuMobile'}
|
||||
<div class="flex-grow h-full relative" style={bgImg.length < 4 ? wallPaper : bgImg}>
|
||||
<div class="w-full h-1/3 absolute z-10 bottom-0 left-0">
|
||||
<DefaultChatScreen customStyle={'background: rgba(0,0,0,0.8);backdrop-filter: blur(4px);'} bind:openChatList/>
|
||||
<DefaultChatScreen customStyle={`${externalStyles}backdrop-filter: blur(4px);`} bind:openChatList/>
|
||||
</div>
|
||||
{#if $selectedCharID >= 0}
|
||||
{#if $DataBase.characters[$selectedCharID].viewScreen !== 'none'}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { DatabaseIcon, DicesIcon, LanguagesIcon, MenuIcon, RefreshCcwIcon, Send } from "lucide-svelte";
|
||||
import { DatabaseIcon, DicesIcon, LanguagesIcon, MenuIcon, MicOffIcon, RefreshCcwIcon, Send } from "lucide-svelte";
|
||||
import { selectedCharID } from "../../ts/stores";
|
||||
import Chat from "./Chat.svelte";
|
||||
import { DataBase, appVer, type Message } from "../../ts/database";
|
||||
@@ -14,6 +14,7 @@
|
||||
import { processScript } from "src/ts/process/scripts";
|
||||
import GithubStars from "../Others/GithubStars.svelte";
|
||||
import CreatorQuote from "./CreatorQuote.svelte";
|
||||
import { stopTTS } from "src/ts/process/tts";
|
||||
|
||||
let messageInput = ''
|
||||
let openMenu = false
|
||||
@@ -333,6 +334,17 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
<!-- svelte-ignore empty-block -->
|
||||
{#if $DataBase.characters[$selectedCharID].ttsMode === 'webspeech' || $DataBase.characters[$selectedCharID].ttsMode === 'elevenlab'}
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" on:click={() => {
|
||||
stopTTS()
|
||||
}}>
|
||||
<MicOffIcon />
|
||||
<span class="ml-2">{language.ttsStop}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" on:click={() => {
|
||||
openChatList = true
|
||||
openMenu = false
|
||||
|
||||
@@ -128,3 +128,52 @@
|
||||
<Check bind:check={$DataBase.instantRemove}/>
|
||||
<span>{language.instantRemove}</span>
|
||||
</div>
|
||||
|
||||
|
||||
{#if $DataBase.textScreenColor}
|
||||
<div class="flex items-center mt-2">
|
||||
<Check check={true} onChange={() => {
|
||||
$DataBase.textScreenColor = null
|
||||
}}/>
|
||||
<input type="color" class="style2 text-sm mr-2" bind:value={$DataBase.textScreenColor} >
|
||||
<span>{language.textBackgrounds}</span>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex items-center mt-2">
|
||||
<Check check={false} onChange={() => {
|
||||
$DataBase.textScreenColor = "#121212"
|
||||
}}/>
|
||||
<span>{language.textBackgrounds}</span>
|
||||
</div>
|
||||
|
||||
|
||||
{/if}
|
||||
|
||||
<div class="flex items-center mt-2">
|
||||
<Check bind:check={$DataBase.textBorder}/>
|
||||
<span>{language.textBorder}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex items-center mt-2">
|
||||
<Check bind:check={$DataBase.textScreenRounded}/>
|
||||
<span>{language.textScreenRound}</span>
|
||||
</div>
|
||||
|
||||
{#if $DataBase.textScreenBorder}
|
||||
<div class="flex items-center mt-2">
|
||||
<Check check={true} onChange={() => {
|
||||
$DataBase.textScreenBorder = null
|
||||
}}/>
|
||||
<input type="color" class="style2 text-sm mr-2" bind:value={$DataBase.textScreenBorder} >
|
||||
<span>{language.textScreenBorder}</span>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex items-center mt-2">
|
||||
<Check check={false} onChange={() => {
|
||||
$DataBase.textScreenBorder = "#121212"
|
||||
}}/>
|
||||
<span>{language.textScreenBorder}</span>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
@@ -498,6 +498,12 @@
|
||||
</select>
|
||||
{/await}
|
||||
{/if}
|
||||
{#if currentChar.data.ttsMode === 'webspeech' || currentChar.data.ttsMode === 'elevenlab'}
|
||||
<div class="flex items-center mt-2">
|
||||
<Check bind:check={currentChar.data.ttsReadOnlyQuoted}/>
|
||||
<span>{language.ttsReadOnlyQuoted}</span>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{:else if subMenu === 2}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.advancedSettings}</h2>
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
}
|
||||
async function createImport() {
|
||||
reseter();
|
||||
const cid = await importCharacter();
|
||||
await importCharacter();
|
||||
selectedCharID.set(-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { get } from "svelte/store"
|
||||
import { alertConfirm, alertError, alertNormal, alertSelect, alertStore } from "./alert"
|
||||
import { DataBase, defaultSdDataFunc, type character, setDatabase, type customscript, type loreSettings, type loreBook } from "./database"
|
||||
import { checkNullish, selectSingleFile, sleep } from "./util"
|
||||
import { checkNullish, selectMultipleFile, selectSingleFile, sleep } from "./util"
|
||||
import { language } from "src/lang"
|
||||
import { encode as encodeMsgpack, decode as decodeMsgpack } from "@msgpack/msgpack";
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
@@ -14,10 +14,24 @@ import { cloneDeep } from "lodash"
|
||||
|
||||
export async function importCharacter() {
|
||||
try {
|
||||
const f = await selectSingleFile(['png', 'json'])
|
||||
if(!f){
|
||||
const files = await selectMultipleFile(['png', 'json'])
|
||||
if(!files){
|
||||
return
|
||||
}
|
||||
|
||||
for(const f of files){
|
||||
await importCharacterProcess(f)
|
||||
}
|
||||
} catch (error) {
|
||||
alertError(`${error}`)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function importCharacterProcess(f:{
|
||||
name: string;
|
||||
data: Uint8Array;
|
||||
}) {
|
||||
if(f.name.endsWith('json')){
|
||||
const da = JSON.parse(Buffer.from(f.data).toString('utf-8'))
|
||||
if(await importSpecv2(da)){
|
||||
@@ -105,10 +119,6 @@ export async function importCharacter() {
|
||||
alertError(language.errors.noData)
|
||||
return null
|
||||
}
|
||||
} catch (error) {
|
||||
alertError(`${error}`)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export async function characterHubImport() {
|
||||
@@ -262,10 +272,10 @@ export async function exportChar(charaID:number) {
|
||||
create_date: `${Date.now()}`,
|
||||
description: char.desc,
|
||||
first_mes: char.firstMessage,
|
||||
mes_example: "<START>",
|
||||
mes_example: char.exampleMessage ?? "<START>",
|
||||
name: char.name,
|
||||
personality: "",
|
||||
scenario: "",
|
||||
personality: char.personality ?? "",
|
||||
scenario: char.scenario ?? "",
|
||||
talkativeness: "0.5"
|
||||
}
|
||||
|
||||
@@ -580,8 +590,8 @@ interface OldTavernChar{
|
||||
first_mes: string
|
||||
mes_example: string
|
||||
name: string
|
||||
personality: ""
|
||||
scenario: ""
|
||||
personality: string
|
||||
scenario: string
|
||||
talkativeness: "0.5"
|
||||
}
|
||||
type CharacterBook = {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { cloneDeep } from 'lodash';
|
||||
|
||||
export const DataBase = writable({} as any as Database)
|
||||
export const loadedStore = writable(false)
|
||||
export let appVer = '1.13.2'
|
||||
export let appVer = '1.14.0'
|
||||
|
||||
|
||||
export function setDatabase(data:Database){
|
||||
@@ -284,6 +284,7 @@ export interface character{
|
||||
ttsSpeech?:string
|
||||
supaMemory?:boolean
|
||||
additionalAssets?:[string, string][]
|
||||
ttsReadOnlyQuoted?:boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -315,6 +316,7 @@ export interface groupChat{
|
||||
firstMsgIndex?:number,
|
||||
loreSettings?:loreSettings
|
||||
supaMemory?:boolean
|
||||
ttsMode?:string
|
||||
}
|
||||
|
||||
export interface botPreset{
|
||||
@@ -418,6 +420,10 @@ export interface Database{
|
||||
palmAPI:string,
|
||||
supaMemoryKey:string
|
||||
supaMemoryType:string
|
||||
textScreenColor?:string
|
||||
textBorder?:boolean
|
||||
textScreenRounded?:boolean
|
||||
textScreenBorder?:string
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -350,13 +350,15 @@ export async function sendChat(chatProcessIndex = -1):Promise<boolean> {
|
||||
while(true){
|
||||
const readed = (await reader.read())
|
||||
if(readed.value){
|
||||
db.characters[selectedChar].chats[selectedChat].message[msgIndex].data =readed.value
|
||||
result = readed.value
|
||||
db.characters[selectedChar].chats[selectedChat].message[msgIndex].data = result
|
||||
setDatabase(db)
|
||||
}
|
||||
if(readed.done){
|
||||
break
|
||||
}
|
||||
}
|
||||
await sayTTS(currentChar, result)
|
||||
}
|
||||
else{
|
||||
const result2 = processScriptFull(currentChar, reformatContent(req.result), 'editoutput')
|
||||
|
||||
@@ -2,11 +2,23 @@ import { get } from "svelte/store";
|
||||
import { alertError } from "../alert";
|
||||
import { DataBase, type character } from "../database";
|
||||
|
||||
let sourceNode:AudioBufferSourceNode = null
|
||||
|
||||
export async function sayTTS(character:character,text:string) {
|
||||
|
||||
let db = get(DataBase)
|
||||
text = text.replace(/\*/g,'')
|
||||
|
||||
if(character.ttsReadOnlyQuoted){
|
||||
const matches = text.match(/"(.*?)"/g)
|
||||
if(matches.length > 0){
|
||||
text = matches.map(match => match.slice(1, -1)).join("");
|
||||
}
|
||||
else{
|
||||
text = ''
|
||||
}
|
||||
}
|
||||
|
||||
switch(character.ttsMode){
|
||||
case "webspeech":{
|
||||
if(speechSynthesis && SpeechSynthesisUtterance){
|
||||
@@ -19,7 +31,7 @@ export async function sayTTS(character:character,text:string) {
|
||||
}
|
||||
}
|
||||
utterThis.voice = voices[voiceIndex]
|
||||
speechSynthesis.speak(utterThis)
|
||||
const speak = speechSynthesis.speak(utterThis)
|
||||
}
|
||||
break
|
||||
}
|
||||
@@ -37,7 +49,7 @@ export async function sayTTS(character:character,text:string) {
|
||||
})
|
||||
if(da.status >= 200 && da.status < 300){
|
||||
const audioBuffer = await audioContext.decodeAudioData(await da.arrayBuffer())
|
||||
const sourceNode = audioContext.createBufferSource();
|
||||
sourceNode = audioContext.createBufferSource();
|
||||
sourceNode.buffer = audioBuffer;
|
||||
sourceNode.connect(audioContext.destination);
|
||||
sourceNode.start();
|
||||
@@ -50,6 +62,15 @@ export async function sayTTS(character:character,text:string) {
|
||||
|
||||
}
|
||||
|
||||
export function stopTTS(){
|
||||
if(sourceNode){
|
||||
sourceNode.stop()
|
||||
}
|
||||
if(speechSynthesis && SpeechSynthesisUtterance){
|
||||
speechSynthesis.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function getWebSpeechTTSVoices() {
|
||||
return speechSynthesis.getVoices().map(v => {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":"1.13.2"}
|
||||
{"version":"1.14.0"}
|
||||
@@ -53,6 +53,7 @@ export default defineConfig(async () => {
|
||||
minify: process.env.TAURI_DEBUG ? false : 'esbuild',
|
||||
// produce sourcemaps for debug builds
|
||||
sourcemap: !!process.env.TAURI_DEBUG,
|
||||
chunkSizeWarningLimit: 2000
|
||||
},
|
||||
|
||||
resolve:{
|
||||
|
||||
Reference in New Issue
Block a user