Migrate to svelte 5
This commit is contained in:
@@ -1,18 +1,21 @@
|
||||
<script>
|
||||
import { run } from 'svelte/legacy';
|
||||
|
||||
import { onMount, createEventDispatcher } from 'svelte';
|
||||
import { EditIcon, LanguagesIcon } from "lucide-svelte";
|
||||
import { DataBase } from "../../ts/storage/database";
|
||||
import CodeMirror from 'codemirror';
|
||||
import 'codemirror/lib/codemirror.css';
|
||||
|
||||
export let value, translate;
|
||||
/** @type {{value: any, translate: any}} */
|
||||
let { value = $bindable(), translate = $bindable() } = $props();
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
let toggleTranslate = !$DataBase.useAutoTranslateInput;
|
||||
let velement, veditor;
|
||||
let telement, teditor;
|
||||
let _value = value;
|
||||
let _translate = translate;
|
||||
let toggleTranslate = $state(!$DataBase.useAutoTranslateInput);
|
||||
let velement = $state(), veditor = $state();
|
||||
let telement = $state(), teditor = $state();
|
||||
let _value = $state(value);
|
||||
let _translate = $state(translate);
|
||||
|
||||
const markdowns = [
|
||||
{
|
||||
@@ -61,12 +64,16 @@ onMount(() => {
|
||||
toggleTranslateText();
|
||||
});
|
||||
|
||||
$: if(value != _value) {
|
||||
veditor.setValue(_value = value);
|
||||
}
|
||||
$: if(translate != _translate) {
|
||||
teditor.setValue(_translate = translate);
|
||||
}
|
||||
run(() => {
|
||||
if(value != _value) {
|
||||
veditor.setValue(_value = value);
|
||||
}
|
||||
});
|
||||
run(() => {
|
||||
if(translate != _translate) {
|
||||
teditor.setValue(_translate = translate);
|
||||
}
|
||||
});
|
||||
|
||||
function toggleTranslateText() {
|
||||
toggleTranslate = !toggleTranslate;
|
||||
@@ -108,7 +115,7 @@ function updateMarks(doc) {
|
||||
<div class="flex flex-1 items-end ml-2 mr-2">
|
||||
{#if $DataBase.useAutoTranslateInput}
|
||||
<button
|
||||
on:click={toggleTranslateText}
|
||||
onclick={toggleTranslateText}
|
||||
class="mr-2 bg-textcolor2 flex justify-center items-center text-gray-100 w-12 h-12 rounded-md hover:bg-green-500 transition-colors">
|
||||
{#if toggleTranslate}
|
||||
<LanguagesIcon />
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
<script lang="ts">
|
||||
import { run } from 'svelte/legacy';
|
||||
|
||||
import { get } from 'svelte/store';
|
||||
import { FileAudioIcon, PlusIcon } from "lucide-svelte";
|
||||
import { DataBase, setDatabase, type character, type groupChat } from "src/ts/storage/database";
|
||||
import { getFileSrc, saveAsset } from "src/ts/storage/globalApi";
|
||||
import { selectMultipleFile } from "src/ts/util";
|
||||
export let currentCharacter:character|groupChat;
|
||||
export let onSelect:(additionalAsset:[string,string,string])=>void;
|
||||
let assetFileExtensions:string[] = []
|
||||
let assetFilePath:string[] = []
|
||||
interface Props {
|
||||
currentCharacter: character|groupChat;
|
||||
onSelect: (additionalAsset:[string,string,string])=>void;
|
||||
}
|
||||
|
||||
$:{
|
||||
let { currentCharacter = $bindable(), onSelect }: Props = $props();
|
||||
let assetFileExtensions:string[] = $state([])
|
||||
let assetFilePath:string[] = $state([])
|
||||
|
||||
run(() => {
|
||||
if(currentCharacter.type ==='character'){
|
||||
if(currentCharacter.additionalAssets){
|
||||
for(let i = 0; i < currentCharacter.additionalAssets.length; i++){
|
||||
@@ -25,10 +31,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{#if currentCharacter.type ==='character'}
|
||||
<button class="hover:text-green-500 bg-textcolor2 flex justify-center items-center w-16 h-16 m-1 rounded-md" on:click={async () => {
|
||||
<button class="hover:text-green-500 bg-textcolor2 flex justify-center items-center w-16 h-16 m-1 rounded-md" onclick={async () => {
|
||||
if(currentCharacter.type === 'character'){
|
||||
const da = await selectMultipleFile(['png', 'webp', 'mp4', 'mp3', 'gif'])
|
||||
currentCharacter.additionalAssets = currentCharacter.additionalAssets ?? []
|
||||
@@ -52,12 +58,12 @@
|
||||
</button>
|
||||
{#if currentCharacter.additionalAssets}
|
||||
{#each currentCharacter.additionalAssets as additionalAsset, i}
|
||||
<button on:click={()=>{
|
||||
<button onclick={()=>{
|
||||
onSelect(additionalAsset)
|
||||
}}>
|
||||
{#if assetFilePath[i]}
|
||||
{#if assetFileExtensions[i] === 'mp4'}
|
||||
<!-- svelte-ignore a11y-media-has-caption -->
|
||||
<!-- svelte-ignore a11y_media_has_caption -->
|
||||
<video class="w-16 h-16 m-1 rounded-md"><source src={assetFilePath[i]} type="video/mp4"></video>
|
||||
{:else if assetFileExtensions[i] === 'mp3'}
|
||||
<div class='w-16 h-16 m-1 rounded-md bg-slate-500 flex flex-col justify-center items-center'>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
import { moduleBackgroundEmbedding, ReloadGUIPointer, selectedCharID } from "src/ts/stores";
|
||||
import { onDestroy } from "svelte";
|
||||
|
||||
let backgroundHTML = ''
|
||||
let backgroundHTML = $state('')
|
||||
let lastdb:Database
|
||||
let currentChar:character|groupChat
|
||||
let currentChar:character|groupChat = $state()
|
||||
let selectedId = 0
|
||||
|
||||
function checkUpdate(){
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { run } from 'svelte/legacy';
|
||||
|
||||
import { ArrowLeft, ArrowRight, PencilIcon, LanguagesIcon, RefreshCcwIcon, TrashIcon, CopyIcon, Volume2Icon, BotIcon, ArrowLeftRightIcon, UserIcon } from "lucide-svelte";
|
||||
import { type CbsConditions, ParseMarkdown, postTranslationParse, type simpleCharacterArgument } from "../../ts/parser";
|
||||
import AutoresizeArea from "../UI/GUI/TextAreaResizable.svelte";
|
||||
import { alertConfirm, alertError, alertRequestData } from "../../ts/alert";
|
||||
import { language } from "../../lang";
|
||||
import { DataBase, type MessageGenerationInfo } from "../../ts/storage/database";
|
||||
import { CurrentCharacter, CurrentChat, HideIconStore, ReloadGUIPointer } from "../../ts/stores";
|
||||
import { HideIconStore, ReloadGUIPointer, selectedCharID } from "../../ts/stores";
|
||||
import { translateHTML } from "../../ts/translator/translator";
|
||||
import { risuChatParser } from "src/ts/process/scripts";
|
||||
import { get, type Unsubscriber } from "svelte/store";
|
||||
@@ -17,33 +19,51 @@
|
||||
import { ColorSchemeTypeStore } from "src/ts/gui/colorscheme";
|
||||
import { ConnectionOpenStore } from "src/ts/sync/multiuser";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
export let message = ''
|
||||
export let name = ''
|
||||
export let largePortrait = false
|
||||
export let isLastMemory:boolean
|
||||
export let img:string|Promise<string> = ''
|
||||
export let idx = -1
|
||||
export let rerollIcon = false
|
||||
export let messageGenerationInfo:MessageGenerationInfo|null = null
|
||||
export let onReroll = () => {}
|
||||
export let unReroll = () => {}
|
||||
export let character:simpleCharacterArgument|string|null = null
|
||||
export let firstMessage = false
|
||||
let translating = false
|
||||
let translating = $state(false)
|
||||
try {
|
||||
translating = get(DataBase).autoTranslate
|
||||
} catch (error) {}
|
||||
let editMode = false
|
||||
let statusMessage:string = ''
|
||||
export let altGreeting = false
|
||||
let editMode = $state(false)
|
||||
let statusMessage:string = $state('')
|
||||
interface Props {
|
||||
message?: string;
|
||||
name?: string;
|
||||
largePortrait?: boolean;
|
||||
isLastMemory: boolean;
|
||||
img?: string|Promise<string>;
|
||||
idx?: any;
|
||||
rerollIcon?: boolean;
|
||||
messageGenerationInfo?: MessageGenerationInfo|null;
|
||||
onReroll?: any;
|
||||
unReroll?: any;
|
||||
character?: simpleCharacterArgument|string|null;
|
||||
firstMessage?: boolean;
|
||||
altGreeting?: boolean;
|
||||
}
|
||||
|
||||
let msgDisplay = ''
|
||||
let translated = get(DataBase).autoTranslate
|
||||
let {
|
||||
message = $bindable(''),
|
||||
name = '',
|
||||
largePortrait = false,
|
||||
isLastMemory,
|
||||
img = '',
|
||||
idx = -1,
|
||||
rerollIcon = false,
|
||||
messageGenerationInfo = null,
|
||||
onReroll = () => {},
|
||||
unReroll = () => {},
|
||||
character = null,
|
||||
firstMessage = false,
|
||||
altGreeting = false
|
||||
}: Props = $props();
|
||||
|
||||
let msgDisplay = $state('')
|
||||
let translated = $state(get(DataBase).autoTranslate)
|
||||
async function rm(e:MouseEvent, rec?:boolean){
|
||||
if(e.shiftKey){
|
||||
let msg = $CurrentChat.message
|
||||
let msg = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message
|
||||
msg = msg.slice(0, idx)
|
||||
$CurrentChat.message = msg
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message = msg
|
||||
return
|
||||
}
|
||||
|
||||
@@ -51,33 +71,33 @@
|
||||
if(rm){
|
||||
if($DataBase.instantRemove || rec){
|
||||
const r = await alertConfirm(language.instantRemoveConfirm)
|
||||
let msg = $CurrentChat.message
|
||||
let msg = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message
|
||||
if(!r){
|
||||
msg = msg.slice(0, idx)
|
||||
}
|
||||
else{
|
||||
msg.splice(idx, 1)
|
||||
}
|
||||
$CurrentChat.message = msg
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message = msg
|
||||
}
|
||||
else{
|
||||
let msg = $CurrentChat.message
|
||||
let msg = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message
|
||||
msg.splice(idx, 1)
|
||||
$CurrentChat.message = msg
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message = msg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function edit(){
|
||||
let msg = $CurrentChat.message
|
||||
let msg = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message
|
||||
msg[idx].data = message
|
||||
$CurrentChat.message = msg
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message = msg
|
||||
}
|
||||
|
||||
function getCbsCondition(){
|
||||
const cbsConditions:CbsConditions = {
|
||||
firstmsg: firstMessage ?? false,
|
||||
chatRole: $CurrentChat?.message?.[idx]?.role ?? null,
|
||||
chatRole: $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage]?.message?.[idx]?.role ?? null,
|
||||
}
|
||||
return cbsConditions
|
||||
}
|
||||
@@ -94,15 +114,18 @@
|
||||
}, timeout)
|
||||
}
|
||||
|
||||
let lastParsed = ''
|
||||
let lastParsed = $state('')
|
||||
let lastCharArg:string|simpleCharacterArgument = null
|
||||
let lastChatId = -10
|
||||
let blankMessage = (message === '{{none}}' || message === '{{blank}}' || message === '') && idx === -1
|
||||
$: blankMessage = (message === '{{none}}' || message === '{{blank}}' || message === '') && idx === -1
|
||||
let blankMessage = $state((message === '{{none}}' || message === '{{blank}}' || message === '') && idx === -1)
|
||||
run(() => {
|
||||
blankMessage = (message === '{{none}}' || message === '{{blank}}' || message === '') && idx === -1
|
||||
});
|
||||
const markParsing = async (data: string, charArg?: string | simpleCharacterArgument, mode?: "normal" | "back", chatID?: number, translateText?:boolean, tries?:number) => {
|
||||
let lastParsedQueue = ''
|
||||
try {
|
||||
if((!isEqual(lastCharArg, charArg)) || (chatID !== lastChatId)){
|
||||
lastParsed = ''
|
||||
if((!isEqual(lastCharArg, charArg)) || (chatID !== lastChatId)){
|
||||
lastParsedQueue = ''
|
||||
lastCharArg = charArg
|
||||
lastChatId = chatID
|
||||
translateText = false
|
||||
@@ -119,7 +142,7 @@
|
||||
translating = true
|
||||
const translated = await postTranslationParse(await translateHTML(marked, false, charArg, chatID))
|
||||
translating = false
|
||||
lastParsed = translated
|
||||
lastParsedQueue = translated
|
||||
lastCharArg = charArg
|
||||
return translated
|
||||
}
|
||||
@@ -128,14 +151,14 @@
|
||||
translating = true
|
||||
const translated = await translateHTML(marked, false, charArg, chatID)
|
||||
translating = false
|
||||
lastParsed = translated
|
||||
lastParsedQueue = translated
|
||||
lastCharArg = charArg
|
||||
return translated
|
||||
}
|
||||
}
|
||||
else{
|
||||
const marked = await ParseMarkdown(data, charArg, mode, chatID, getCbsCondition())
|
||||
lastParsed = marked
|
||||
lastParsedQueue = marked
|
||||
lastCharArg = charArg
|
||||
return marked
|
||||
}
|
||||
@@ -148,9 +171,16 @@
|
||||
}
|
||||
return await markParsing(data, charArg, mode, chatID, translateText, (tries ?? 0) + 1)
|
||||
}
|
||||
finally{
|
||||
setTimeout(() => {
|
||||
lastParsed = lastParsedQueue
|
||||
}, 1)
|
||||
}
|
||||
}
|
||||
|
||||
$: displaya(message)
|
||||
run(() => {
|
||||
displaya(message)
|
||||
});
|
||||
|
||||
const unsubscribers:Unsubscriber[] = []
|
||||
|
||||
@@ -167,7 +197,7 @@
|
||||
<div class="flex max-w-full justify-center risu-chat" style={isLastMemory ? `border-top:${$DataBase.memoryLimitThickness}px solid rgba(98, 114, 164, 0.7);` : ''}>
|
||||
<div class="text-textcolor mt-1 ml-4 mr-4 mb-1 p-2 bg-transparent flex-grow border-t-gray-900 border-opacity-30 border-transparent flexium items-start max-w-full" >
|
||||
{#if !blankMessage && !$HideIconStore}
|
||||
{#if $CurrentCharacter?.chaId === "§playground"}
|
||||
{#if $DataBase.characters[$selectedCharID]?.chaId === "§playground"}
|
||||
<div class="shadow-lg border-textcolor2 border mt-2 flex justify-center items-center text-textcolor2" style={`height:${$DataBase.iconsize * 3.5 / 100}rem;width:${$DataBase.iconsize * 3.5 / 100}rem;min-width:${$DataBase.iconsize * 3.5 / 100}rem`}
|
||||
class:rounded-md={!$DataBase.roundIcons} class:rounded-full={$DataBase.roundIcons}>
|
||||
{#if name === 'assistant'}
|
||||
@@ -179,26 +209,26 @@
|
||||
{:else}
|
||||
{#await img}
|
||||
<div class="shadow-lg bg-textcolor2 mt-2" style={`height:${$DataBase.iconsize * 3.5 / 100}rem;width:${$DataBase.iconsize * 3.5 / 100}rem;min-width:${$DataBase.iconsize * 3.5 / 100}rem`}
|
||||
class:rounded-md={!$DataBase.roundIcons} class:rounded-full={$DataBase.roundIcons} />
|
||||
class:rounded-md={!$DataBase.roundIcons} class:rounded-full={$DataBase.roundIcons}></div>
|
||||
{:then m}
|
||||
{#if largePortrait && (!$DataBase.roundIcons)}
|
||||
<div class="shadow-lg bg-textcolor2 mt-2" style={m + `height:${$DataBase.iconsize * 3.5 / 100 / 0.75}rem;width:${$DataBase.iconsize * 3.5 / 100}rem;min-width:${$DataBase.iconsize * 3.5 / 100}rem`}
|
||||
class:rounded-md={!$DataBase.roundIcons} class:rounded-full={$DataBase.roundIcons} />
|
||||
class:rounded-md={!$DataBase.roundIcons} class:rounded-full={$DataBase.roundIcons}></div>
|
||||
{:else}
|
||||
<div class="shadow-lg bg-textcolor2 mt-2" style={m + `height:${$DataBase.iconsize * 3.5 / 100}rem;width:${$DataBase.iconsize * 3.5 / 100}rem;min-width:${$DataBase.iconsize * 3.5 / 100}rem`}
|
||||
class:rounded-md={!$DataBase.roundIcons} class:rounded-full={$DataBase.roundIcons} />
|
||||
class:rounded-md={!$DataBase.roundIcons} class:rounded-full={$DataBase.roundIcons}></div>
|
||||
{/if}
|
||||
{/await}
|
||||
{/if}
|
||||
{/if}
|
||||
<span class="flex flex-col ml-4 w-full max-w-full min-w-0">
|
||||
<div class="flexium items-center chat">
|
||||
{#if $CurrentCharacter?.chaId === "§playground" && !blankMessage}
|
||||
{#if $DataBase.characters[$selectedCharID]?.chaId === "§playground" && !blankMessage}
|
||||
<span class="chat text-xl border-darkborderc flex items-center">
|
||||
<span>{name === 'assistant' ? 'Assistant' : 'User'}</span>
|
||||
<button class="ml-2 text-textcolor2 hover:text-textcolor" on:click={() => {
|
||||
$CurrentChat.message[idx].role = $CurrentChat.message[idx].role === 'char' ? 'user' : 'char'
|
||||
$CurrentChat = $CurrentChat
|
||||
<button class="ml-2 text-textcolor2 hover:text-textcolor" onclick={() => {
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message[idx].role = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message[idx].role === 'char' ? 'user' : 'char'
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage] = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage]
|
||||
}}><ArrowLeftRightIcon size="18" /></button>
|
||||
</span>
|
||||
{:else if !blankMessage && !$HideIconStore}
|
||||
@@ -207,7 +237,7 @@
|
||||
<div class="flex-grow flex items-center justify-end text-textcolor2">
|
||||
<span class="text-xs">{statusMessage}</span>
|
||||
{#if $DataBase.useChatCopy && !blankMessage}
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" on:click={()=>{
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" onclick={()=>{
|
||||
window.navigator.clipboard.writeText(msgDisplay).then(() => {
|
||||
setStatusMessage(language.copied)
|
||||
})
|
||||
@@ -216,8 +246,8 @@
|
||||
</button>
|
||||
{/if}
|
||||
{#if idx > -1}
|
||||
{#if $CurrentCharacter.type !== 'group' && $CurrentCharacter.ttsMode !== 'none' && ($CurrentCharacter.ttsMode)}
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" on:click={()=>{
|
||||
{#if $DataBase.characters[$selectedCharID].type !== 'group' && $DataBase.characters[$selectedCharID].ttsMode !== 'none' && ($DataBase.characters[$selectedCharID].ttsMode)}
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" onclick={()=>{
|
||||
return sayTTS(null, message)
|
||||
}}>
|
||||
<Volume2Icon size={20}/>
|
||||
@@ -225,7 +255,7 @@
|
||||
{/if}
|
||||
|
||||
{#if !$ConnectionOpenStore}
|
||||
<button class={"ml-2 hover:text-green-500 transition-colors "+(editMode?'text-green-400':'')} on:click={() => {
|
||||
<button class={"ml-2 hover:text-green-500 transition-colors "+(editMode?'text-green-400':'')} onclick={() => {
|
||||
if(!editMode){
|
||||
editMode = true
|
||||
}
|
||||
@@ -236,13 +266,13 @@
|
||||
}}>
|
||||
<PencilIcon size={20}/>
|
||||
</button>
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" on:click={(e) => rm(e, false)} use:longpress={(e) => rm(e, true)}>
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" onclick={(e) => rm(e, false)} use:longpress={(e) => rm(e, true)}>
|
||||
<TrashIcon size={20}/>
|
||||
</button>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if $DataBase.translator !== '' && !blankMessage}
|
||||
<button class={"ml-2 cursor-pointer hover:text-green-500 transition-colors " + (translated ? 'text-green-400':'')} class:translating={translating} on:click={async () => {
|
||||
<button class={"ml-2 cursor-pointer hover:text-green-500 transition-colors " + (translated ? 'text-green-400':'')} class:translating={translating} onclick={async () => {
|
||||
translated = !translated
|
||||
}}>
|
||||
<LanguagesIcon />
|
||||
@@ -250,14 +280,14 @@
|
||||
{/if}
|
||||
{#if rerollIcon || altGreeting}
|
||||
{#if $DataBase.swipe || altGreeting}
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" on:click={unReroll}>
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" onclick={unReroll}>
|
||||
<ArrowLeft size={22}/>
|
||||
</button>
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" on:click={onReroll}>
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" onclick={onReroll}>
|
||||
<ArrowRight size={22}/>
|
||||
</button>
|
||||
{:else}
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" on:click={onReroll}>
|
||||
<button class="ml-2 hover:text-green-500 transition-colors" onclick={onReroll}>
|
||||
<RefreshCcwIcon size={20}/>
|
||||
</button>
|
||||
{/if}
|
||||
@@ -268,7 +298,7 @@
|
||||
<div>
|
||||
<button class="text-sm p-1 text-textcolor2 border-darkborderc float-end mr-2 my-2
|
||||
hover:ring-darkbutton hover:ring rounded-md hover:text-textcolor transition-all flex justify-center items-center"
|
||||
on:click={() => {
|
||||
onclick={() => {
|
||||
alertRequestData({
|
||||
genInfo: messageGenerationInfo,
|
||||
idx: idx,
|
||||
@@ -291,8 +321,8 @@
|
||||
{language.noMessage}
|
||||
</div>
|
||||
{:else}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<span class="text chat chattext prose minw-0" class:prose-invert={$ColorSchemeTypeStore} on:click={() => {
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<span class="text chat chattext prose minw-0" class:prose-invert={$ColorSchemeTypeStore} onclick={() => {
|
||||
if($DataBase.clickToEdit && idx > -1){
|
||||
editMode = true
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { run } from 'svelte/legacy';
|
||||
|
||||
import { getCustomBackground, getEmotion } from "../../ts/util";
|
||||
import { DataBase } from "../../ts/storage/database";
|
||||
import { CharEmotion, CurrentCharacter, ShowVN, selectedCharID } from "../../ts/stores";
|
||||
import { CharEmotion, ShowVN, selectedCharID } from "../../ts/stores";
|
||||
import ResizeBox from './ResizeBox.svelte'
|
||||
import DefaultChatScreen from "./DefaultChatScreen.svelte";
|
||||
import defaultWallpaper from '../../etc/bg.jpg'
|
||||
@@ -11,8 +13,8 @@
|
||||
import SideBarArrow from "../UI/GUI/SideBarArrow.svelte";
|
||||
import VisualNovelMain from "../VisualNovel/VisualNovelMain.svelte";
|
||||
import ModuleChatMenu from "../Setting/Pages/Module/ModuleChatMenu.svelte";
|
||||
let openChatList = false
|
||||
let openModuleList = false
|
||||
let openChatList = $state(false)
|
||||
let openModuleList = $state(false)
|
||||
|
||||
const wallPaper = `background: url(${defaultWallpaper})`
|
||||
const externalStyles =
|
||||
@@ -20,14 +22,16 @@
|
||||
+ ($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 = ''
|
||||
$: (async () =>{
|
||||
if($DataBase.customBackground !== lastBg){
|
||||
lastBg = $DataBase.customBackground
|
||||
bgImg = await getCustomBackground($DataBase.customBackground)
|
||||
}
|
||||
})()
|
||||
let bgImg= $state('')
|
||||
let lastBg = $state('')
|
||||
run(() => {
|
||||
(async () =>{
|
||||
if($DataBase.customBackground !== lastBg){
|
||||
lastBg = $DataBase.customBackground
|
||||
bgImg = await getCustomBackground($DataBase.customBackground)
|
||||
}
|
||||
})()
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if $ShowVN}
|
||||
@@ -38,7 +42,7 @@
|
||||
<BackgroundDom />
|
||||
<div style={bgImg} class="h-full w-full" class:max-w-6xl={$DataBase.classicMaxWidth}>
|
||||
{#if $selectedCharID >= 0}
|
||||
{#if $CurrentCharacter.viewScreen !== 'none' && ($CurrentCharacter.type === 'group' || (!$CurrentCharacter.inlayViewScreen))}
|
||||
{#if $DataBase.characters[$selectedCharID].viewScreen !== 'none' && ($DataBase.characters[$selectedCharID].type === 'group' || (!$DataBase.characters[$selectedCharID].inlayViewScreen))}
|
||||
<ResizeBox />
|
||||
{/if}
|
||||
{/if}
|
||||
@@ -50,13 +54,13 @@
|
||||
<SideBarArrow />
|
||||
<BackgroundDom />
|
||||
{#if $selectedCharID >= 0}
|
||||
{#if $CurrentCharacter.viewScreen !== 'none'}
|
||||
{#if $DataBase.characters[$selectedCharID].viewScreen !== 'none'}
|
||||
<div class="h-full mr-10 flex justify-end halfw" style:width="{42 * ($DataBase.waifuWidth2 / 100)}rem">
|
||||
<TransitionImage classType="waifu" src={getEmotion($DataBase, $CharEmotion, 'plain')}/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
<div class="h-full w-2xl" style:width="{42 * ($DataBase.waifuWidth / 100)}rem" class:halfwp={$selectedCharID >= 0 && $CurrentCharacter.viewScreen !== 'none'}>
|
||||
<div class="h-full w-2xl" style:width="{42 * ($DataBase.waifuWidth / 100)}rem" class:halfwp={$selectedCharID >= 0 && $DataBase.characters[$selectedCharID].viewScreen !== 'none'}>
|
||||
<DefaultChatScreen customStyle={`${externalStyles}backdrop-filter: blur(4px);`} bind:openChatList bind:openModuleList/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,13 +69,13 @@
|
||||
<SideBarArrow />
|
||||
<BackgroundDom />
|
||||
<div class="w-full absolute z-10 bottom-0 left-0"
|
||||
class:per33={$selectedCharID >= 0 && $CurrentCharacter.viewScreen !== 'none'}
|
||||
class:h-full={!($selectedCharID >= 0 && $CurrentCharacter.viewScreen !== 'none')}
|
||||
class:per33={$selectedCharID >= 0 && $DataBase.characters[$selectedCharID].viewScreen !== 'none'}
|
||||
class:h-full={!($selectedCharID >= 0 && $DataBase.characters[$selectedCharID].viewScreen !== 'none')}
|
||||
>
|
||||
<DefaultChatScreen customStyle={`${externalStyles}backdrop-filter: blur(4px);`} bind:openChatList bind:openModuleList/>
|
||||
</div>
|
||||
{#if $selectedCharID >= 0}
|
||||
{#if $CurrentCharacter.viewScreen !== 'none'}
|
||||
{#if $DataBase.characters[$selectedCharID].viewScreen !== 'none'}
|
||||
<div class="h-full w-full absolute bottom-0 left-0 max-w-full">
|
||||
<TransitionImage classType="mobile" src={getEmotion($DataBase, $CharEmotion, 'plain')}/>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="flex w-full justify-center mt-4 max-w-100vw">
|
||||
<div class="w-5/6 max-w-80vw bg-darkbg rounded-md p-3 text-textcolor text-sm">
|
||||
<h1 class="font-bold mb-2">{language.creatorNotes}
|
||||
<button class="float-right" on:click={onRemove}>
|
||||
<button class="float-right" onclick={onRemove}>
|
||||
<XIcon />
|
||||
</button>
|
||||
</h1>
|
||||
@@ -13,6 +13,10 @@
|
||||
import { language } from "src/lang";
|
||||
import MultiLangDisplay from "../UI/GUI/MultiLangDisplay.svelte";
|
||||
|
||||
export let onRemove: () => void
|
||||
export let quote:string
|
||||
interface Props {
|
||||
onRemove: () => void;
|
||||
quote: string;
|
||||
}
|
||||
|
||||
let { onRemove, quote }: Props = $props();
|
||||
</script>
|
||||
@@ -1,8 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { run } from 'svelte/legacy';
|
||||
|
||||
import Suggestion from './Suggestion.svelte';
|
||||
import AdvancedChatEditor from './AdvancedChatEditor.svelte';
|
||||
import { CameraIcon, DatabaseIcon, DicesIcon, GlobeIcon, ImagePlusIcon, LanguagesIcon, Laugh, MenuIcon, MicOffIcon, PackageIcon, Plus, RefreshCcwIcon, ReplyIcon, Send, StepForwardIcon } from "lucide-svelte";
|
||||
import { CurrentCharacter, CurrentChat, CurrentUsername, selectedCharID, CurrentUserIcon, CurrentShowMemoryLimit,CurrentSimpleCharacter, PlaygroundStore, UserIconProtrait } from "../../ts/stores";
|
||||
import { selectedCharID, CurrentShowMemoryLimit, PlaygroundStore, UserIconProtrait, createSimpleCharacter } from "../../ts/stores";
|
||||
import Chat from "./Chat.svelte";
|
||||
import { DataBase, type Message, type character, type groupChat } from "../../ts/storage/database";
|
||||
import { getCharImage } from "../../ts/characters";
|
||||
@@ -27,20 +29,18 @@
|
||||
import PlaygroundMenu from '../Playground/PlaygroundMenu.svelte';
|
||||
import { ConnectionOpenStore } from 'src/ts/sync/multiuser';
|
||||
|
||||
let messageInput:string = ''
|
||||
let messageInputTranslate:string = ''
|
||||
let openMenu = false
|
||||
let loadPages = 30
|
||||
let autoMode = false
|
||||
let messageInput:string = $state('')
|
||||
let messageInputTranslate:string = $state('')
|
||||
let openMenu = $state(false)
|
||||
let loadPages = $state(30)
|
||||
let autoMode = $state(false)
|
||||
let rerolls:Message[][] = []
|
||||
let rerollid = -1
|
||||
let lastCharId = -1
|
||||
let doingChatInputTranslate = false
|
||||
let currentCharacter:character|groupChat = $CurrentCharacter
|
||||
let toggleStickers:boolean = false
|
||||
let fileInput:string[] = []
|
||||
export let openModuleList = false
|
||||
export let openChatList:boolean = false
|
||||
let currentCharacter:character|groupChat = $state($DataBase.characters[$selectedCharID])
|
||||
let toggleStickers:boolean = $state(false)
|
||||
let fileInput:string[] = $state([])
|
||||
|
||||
async function send(){
|
||||
return sendMain(false)
|
||||
@@ -83,7 +83,7 @@
|
||||
cha.push({
|
||||
role: 'user',
|
||||
data: '*says nothing*',
|
||||
name: $ConnectionOpenStore ? $CurrentUsername : null
|
||||
name: $ConnectionOpenStore ? $DataBase.username : null
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,7 @@
|
||||
role: 'user',
|
||||
data: await processScript(char,messageInput,'editinput'),
|
||||
time: Date.now(),
|
||||
name: $ConnectionOpenStore ? $CurrentUsername : null
|
||||
name: $ConnectionOpenStore ? $DataBase.username : null
|
||||
})
|
||||
}
|
||||
else{
|
||||
@@ -109,7 +109,7 @@
|
||||
role: 'user',
|
||||
data: messageInput,
|
||||
time: Date.now(),
|
||||
name: $ConnectionOpenStore ? $CurrentUsername : null
|
||||
name: $ConnectionOpenStore ? $DataBase.username : null
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -131,11 +131,11 @@
|
||||
rerolls = []
|
||||
rerollid = -1
|
||||
}
|
||||
const genId = $CurrentChat.message.at(-1)?.generationInfo?.generationId
|
||||
const genId = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.at(-1)?.generationInfo?.generationId
|
||||
if(genId){
|
||||
const r = Prereroll(genId)
|
||||
if(r){
|
||||
$CurrentChat.message[$CurrentChat.message.length - 1].data = r
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message[$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length - 1].data = r
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -144,20 +144,20 @@
|
||||
let db = $DataBase
|
||||
rerollid += 1
|
||||
let rerollData = structuredClone(rerolls[rerollid])
|
||||
let msgs = db.characters[$selectedCharID].chats[$CurrentCharacter.chatPage].message
|
||||
let msgs = db.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message
|
||||
for(let i = 0; i < rerollData.length; i++){
|
||||
msgs[msgs.length - rerollData.length + i] = rerollData[i]
|
||||
}
|
||||
db.characters[$selectedCharID].chats[$CurrentCharacter.chatPage].message = msgs
|
||||
db.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message = msgs
|
||||
$DataBase = db
|
||||
}
|
||||
return
|
||||
}
|
||||
if(rerolls.length === 0){
|
||||
rerolls.push(structuredClone([$CurrentChat.message.at(-1)]))
|
||||
rerolls.push(structuredClone([$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.at(-1)]))
|
||||
rerollid = rerolls.length - 1
|
||||
}
|
||||
let cha = structuredClone($CurrentChat.message)
|
||||
let cha = structuredClone($DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message)
|
||||
if(cha.length === 0 ){
|
||||
return
|
||||
}
|
||||
@@ -176,7 +176,7 @@
|
||||
return
|
||||
}
|
||||
}
|
||||
$CurrentChat.message = cha
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message = cha
|
||||
await sendChatMain()
|
||||
}
|
||||
|
||||
@@ -188,11 +188,11 @@
|
||||
rerolls = []
|
||||
rerollid = -1
|
||||
}
|
||||
const genId = $CurrentChat.message.at(-1)?.generationInfo?.generationId
|
||||
const genId = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.at(-1)?.generationInfo?.generationId
|
||||
if(genId){
|
||||
const r = PreUnreroll(genId)
|
||||
if(r){
|
||||
$CurrentChat.message[$CurrentChat.message.length - 1].data = r
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message[$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length - 1].data = r
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -203,11 +203,11 @@
|
||||
let db = $DataBase
|
||||
rerollid -= 1
|
||||
let rerollData = structuredClone(rerolls[rerollid])
|
||||
let msgs = db.characters[$selectedCharID].chats[$CurrentCharacter.chatPage].message
|
||||
let msgs = db.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message
|
||||
for(let i = 0; i < rerollData.length; i++){
|
||||
msgs[msgs.length - rerollData.length + i] = rerollData[i]
|
||||
}
|
||||
db.characters[$selectedCharID].chats[$CurrentCharacter.chatPage].message = msgs
|
||||
db.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message = msgs
|
||||
$DataBase = db
|
||||
}
|
||||
}
|
||||
@@ -216,7 +216,7 @@
|
||||
|
||||
async function sendChatMain(continued:boolean = false) {
|
||||
|
||||
let previousLength = $CurrentChat.message.length
|
||||
let previousLength = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length
|
||||
messageInput = ''
|
||||
abortController = new AbortController()
|
||||
try {
|
||||
@@ -224,8 +224,8 @@
|
||||
signal:abortController.signal,
|
||||
continue:continued
|
||||
})
|
||||
if(previousLength < $CurrentChat.message.length){
|
||||
rerolls.push(structuredClone($CurrentChat.message).slice(previousLength))
|
||||
if(previousLength < $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length){
|
||||
rerolls.push(structuredClone($DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message).slice(previousLength))
|
||||
rerollid = rerolls.length - 1
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -261,11 +261,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
export let customStyle = ''
|
||||
let inputHeight = "44px"
|
||||
let inputEle:HTMLTextAreaElement
|
||||
let inputTranslateHeight = "44px"
|
||||
let inputTranslateEle:HTMLTextAreaElement
|
||||
interface Props {
|
||||
openModuleList?: boolean;
|
||||
openChatList?: boolean;
|
||||
customStyle?: string;
|
||||
}
|
||||
|
||||
let { openModuleList = $bindable(false), openChatList = $bindable(false), customStyle = '' }: Props = $props();
|
||||
let inputHeight = $state("44px")
|
||||
let inputEle:HTMLTextAreaElement = $state()
|
||||
let inputTranslateHeight = $state("44px")
|
||||
let inputTranslateEle:HTMLTextAreaElement = $state()
|
||||
|
||||
function updateInputSizeAll() {
|
||||
updateInputSize()
|
||||
@@ -287,7 +293,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: updateInputSizeAll()
|
||||
run(() => {
|
||||
updateInputSizeAll()
|
||||
});
|
||||
|
||||
async function updateInputTransateMessage(reverse: boolean) {
|
||||
if(isExpTranslator()){
|
||||
@@ -388,13 +396,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
currentCharacter = $CurrentCharacter
|
||||
}
|
||||
run(() => {
|
||||
currentCharacter = $DataBase.characters[$selectedCharID]
|
||||
});
|
||||
</script>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div class="w-full h-full" style={customStyle} on:click={() => {
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div class="w-full h-full" style={customStyle} onclick={() => {
|
||||
openMenu = false
|
||||
}}>
|
||||
{#if $selectedCharID < 0}
|
||||
@@ -404,16 +412,16 @@
|
||||
<PlaygroundMenu />
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="h-full w-full flex flex-col-reverse overflow-y-auto relative default-chat-screen" on:scroll={(e) => {
|
||||
<div class="h-full w-full flex flex-col-reverse overflow-y-auto relative default-chat-screen" onscroll={(e) => {
|
||||
//@ts-ignore
|
||||
const scrolled = (e.target.scrollHeight - e.target.clientHeight + e.target.scrollTop)
|
||||
if(scrolled < 100 && $CurrentChat.message.length > loadPages){
|
||||
if(scrolled < 100 && $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length > loadPages){
|
||||
loadPages += 15
|
||||
}
|
||||
}}>
|
||||
<div class="flex items-stretch mt-2 mb-2 w-full">
|
||||
{#if $DataBase.useChatSticker && currentCharacter.type !== 'group'}
|
||||
<div on:click={()=>{toggleStickers = !toggleStickers}}
|
||||
<div onclick={()=>{toggleStickers = !toggleStickers}}
|
||||
class={"ml-4 bg-textcolor2 flex justify-center items-center w-12 h-12 rounded-md hover:bg-green-500 transition-colors "+(toggleStickers ? 'text-green-500':'text-textcolor')}>
|
||||
<Laugh/>
|
||||
</div>
|
||||
@@ -423,7 +431,7 @@
|
||||
<textarea class="peer focus:border-textcolor transition-colors outline-none text-textcolor p-2 min-w-0 border border-r-0 bg-transparent rounded-md rounded-r-none input-text text-xl flex-grow ml-4 border-darkborderc resize-none overflow-y-hidden overflow-x-hidden max-w-full"
|
||||
bind:value={messageInput}
|
||||
bind:this={inputEle}
|
||||
on:keydown={(e) => {
|
||||
onkeydown={(e) => {
|
||||
if(e.key.toLocaleLowerCase() === "enter" && (!e.shiftKey) && !e.isComposing){
|
||||
if($DataBase.sendWithEnter){
|
||||
send()
|
||||
@@ -435,37 +443,36 @@
|
||||
e.preventDefault()
|
||||
}
|
||||
}}
|
||||
on:input={()=>{updateInputSizeAll();updateInputTransateMessage(false)}}
|
||||
oninput={()=>{updateInputSizeAll();updateInputTransateMessage(false)}}
|
||||
style:height={inputHeight}
|
||||
/>
|
||||
></textarea>
|
||||
{:else}
|
||||
<AdvancedChatEditor
|
||||
bind:value={messageInput}
|
||||
bind:translate={messageInputTranslate}
|
||||
on:change={(e) => { updateInputTransateMessage(e.detail.translate);}}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
||||
{#if $doingChat || doingChatInputTranslate}
|
||||
<button
|
||||
class="peer-focus:border-textcolor flex justify-center border-y border-darkborderc items-center text-gray-100 p-3 hover:bg-blue-500 transition-colors" on:click={abortChat}
|
||||
class="peer-focus:border-textcolor flex justify-center border-y border-darkborderc items-center text-gray-100 p-3 hover:bg-blue-500 transition-colors" onclick={abortChat}
|
||||
style:height={inputHeight}
|
||||
>
|
||||
<div class="loadmove chat-process-stage-{$chatProcessStage}" class:autoload={autoMode} />
|
||||
<div class="loadmove chat-process-stage-{$chatProcessStage}" class:autoload={autoMode}></div>
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
on:click={send}
|
||||
onclick={send}
|
||||
class="flex justify-center border-y border-darkborderc items-center text-gray-100 p-3 peer-focus:border-textcolor hover:bg-blue-500 transition-colors"
|
||||
style:height={inputHeight}
|
||||
>
|
||||
<Send />
|
||||
</button>
|
||||
{/if}
|
||||
{#if $CurrentCharacter?.chaId !== '§playground'}
|
||||
{#if $DataBase.characters[$selectedCharID]?.chaId !== '§playground'}
|
||||
<button
|
||||
on:click={(e) => {
|
||||
onclick={(e) => {
|
||||
openMenu = !openMenu
|
||||
e.stopPropagation()
|
||||
}}
|
||||
@@ -475,12 +482,12 @@
|
||||
<MenuIcon />
|
||||
</button>
|
||||
{:else}
|
||||
<div on:click={(e) => {
|
||||
$CurrentChat.message.push({
|
||||
<div onclick={(e) => {
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.push({
|
||||
role: 'char',
|
||||
data: ''
|
||||
})
|
||||
$CurrentChat = $CurrentChat
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage] = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage]
|
||||
}}
|
||||
class="peer-focus:border-textcolor mr-2 flex border-y border-r border-darkborderc justify-center items-center text-gray-100 p-3 rounded-r-md hover:bg-blue-500 transition-colors"
|
||||
style:height={inputHeight}
|
||||
@@ -489,7 +496,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if $DataBase.useAutoTranslateInput && !$DataBase.useAdvancedEditor && $CurrentCharacter?.chaId !== '§playground'}
|
||||
{#if $DataBase.useAutoTranslateInput && !$DataBase.useAdvancedEditor && $DataBase.characters[$selectedCharID]?.chaId !== '§playground'}
|
||||
<div class="flex items-center mt-2 mb-2">
|
||||
<label for='messageInputTranslate' class="text-textcolor ml-4">
|
||||
<LanguagesIcon />
|
||||
@@ -497,7 +504,7 @@
|
||||
<textarea id = 'messageInputTranslate' class="text-textcolor rounded-md p-2 min-w-0 bg-transparent input-text text-xl flex-grow ml-4 mr-2 border-darkbutton resize-none focus:bg-selected overflow-y-hidden overflow-x-hidden max-w-full"
|
||||
bind:value={messageInputTranslate}
|
||||
bind:this={inputTranslateEle}
|
||||
on:keydown={(e) => {
|
||||
onkeydown={(e) => {
|
||||
if(e.key.toLocaleLowerCase() === "enter" && (!e.shiftKey)){
|
||||
if($DataBase.sendWithEnter){
|
||||
send()
|
||||
@@ -509,10 +516,10 @@
|
||||
e.preventDefault()
|
||||
}
|
||||
}}
|
||||
on:input={()=>{updateInputSizeAll();updateInputTransateMessage(true)}}
|
||||
oninput={()=>{updateInputSizeAll();updateInputTransateMessage(true)}}
|
||||
placeholder={language.enterMessageForTranslateToEnglish}
|
||||
style:height={inputTranslateHeight}
|
||||
/>
|
||||
></textarea>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -552,20 +559,20 @@
|
||||
)} {send}/>
|
||||
{/if}
|
||||
|
||||
{#each messageForm($CurrentChat.message, loadPages) as chat, i}
|
||||
{#each messageForm($DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message, loadPages) as chat, i}
|
||||
{#if chat.role === 'char'}
|
||||
{#if $CurrentCharacter.type !== 'group'}
|
||||
{#if $DataBase.characters[$selectedCharID].type !== 'group'}
|
||||
<Chat
|
||||
idx={chat.index}
|
||||
name={$CurrentCharacter.name}
|
||||
name={$DataBase.characters[$selectedCharID].name}
|
||||
message={chat.data}
|
||||
img={getCharImage($CurrentCharacter.image, 'css')}
|
||||
img={getCharImage($DataBase.characters[$selectedCharID].image, 'css')}
|
||||
rerollIcon={i === 0}
|
||||
onReroll={reroll}
|
||||
unReroll={unReroll}
|
||||
isLastMemory={$CurrentChat.lastMemory === (chat.chatId ?? 'none') && $CurrentShowMemoryLimit}
|
||||
character={$CurrentSimpleCharacter}
|
||||
largePortrait={$CurrentCharacter.largePortrait}
|
||||
isLastMemory={$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].lastMemory === (chat.chatId ?? 'none') && $CurrentShowMemoryLimit}
|
||||
character={createSimpleCharacter($DataBase.characters[$selectedCharID])}
|
||||
largePortrait={$DataBase.characters[$selectedCharID].largePortrait}
|
||||
messageGenerationInfo={chat.generationInfo}
|
||||
/>
|
||||
{:else}
|
||||
@@ -577,7 +584,7 @@
|
||||
onReroll={reroll}
|
||||
unReroll={unReroll}
|
||||
img={getCharImage(findCharacterbyId(chat.saying).image, 'css')}
|
||||
isLastMemory={$CurrentChat.lastMemory === (chat.chatId ?? 'none') && $CurrentShowMemoryLimit}
|
||||
isLastMemory={$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].lastMemory === (chat.chatId ?? 'none') && $CurrentShowMemoryLimit}
|
||||
character={chat.saying}
|
||||
largePortrait={findCharacterbyId(chat.saying).largePortrait}
|
||||
messageGenerationInfo={chat.generationInfo}
|
||||
@@ -585,32 +592,32 @@
|
||||
{/if}
|
||||
{:else}
|
||||
<Chat
|
||||
character={$CurrentSimpleCharacter}
|
||||
character={createSimpleCharacter($DataBase.characters[$selectedCharID])}
|
||||
idx={chat.index}
|
||||
name={chat.name ?? $CurrentUsername}
|
||||
name={chat.name ?? $DataBase.username}
|
||||
message={chat.data}
|
||||
img={$ConnectionOpenStore ? '' : getCharImage($CurrentUserIcon, 'css')}
|
||||
isLastMemory={$CurrentChat.lastMemory === (chat.chatId ?? 'none') && $CurrentShowMemoryLimit}
|
||||
img={$ConnectionOpenStore ? '' : getCharImage($DataBase.userIcon, 'css')}
|
||||
isLastMemory={$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].lastMemory === (chat.chatId ?? 'none') && $CurrentShowMemoryLimit}
|
||||
largePortrait={$UserIconProtrait}
|
||||
messageGenerationInfo={chat.generationInfo}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
{#if $CurrentChat.message.length <= loadPages}
|
||||
{#if $CurrentCharacter.type !== 'group' }
|
||||
{#if $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length <= loadPages}
|
||||
{#if $DataBase.characters[$selectedCharID].type !== 'group' }
|
||||
<Chat
|
||||
character={$CurrentSimpleCharacter}
|
||||
name={$CurrentCharacter.name}
|
||||
message={$CurrentChat.fmIndex === -1 ? $CurrentCharacter.firstMessage :
|
||||
$CurrentCharacter.alternateGreetings[$CurrentChat.fmIndex]}
|
||||
img={getCharImage($CurrentCharacter.image, 'css')}
|
||||
character={createSimpleCharacter($DataBase.characters[$selectedCharID])}
|
||||
name={$DataBase.characters[$selectedCharID].name}
|
||||
message={$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].fmIndex === -1 ? $DataBase.characters[$selectedCharID].firstMessage :
|
||||
$DataBase.characters[$selectedCharID].alternateGreetings[$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].fmIndex]}
|
||||
img={getCharImage($DataBase.characters[$selectedCharID].image, 'css')}
|
||||
idx={-1}
|
||||
altGreeting={$CurrentCharacter.alternateGreetings.length > 0}
|
||||
largePortrait={$CurrentCharacter.largePortrait}
|
||||
altGreeting={$DataBase.characters[$selectedCharID].alternateGreetings.length > 0}
|
||||
largePortrait={$DataBase.characters[$selectedCharID].largePortrait}
|
||||
firstMessage={true}
|
||||
onReroll={() => {
|
||||
const cha = $CurrentCharacter
|
||||
const chat = $CurrentChat
|
||||
const cha = $DataBase.characters[$selectedCharID]
|
||||
const chat = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage]
|
||||
if(cha.type !== 'group'){
|
||||
if (chat.fmIndex >= (cha.alternateGreetings.length - 1)){
|
||||
chat.fmIndex = -1
|
||||
@@ -619,11 +626,11 @@
|
||||
chat.fmIndex += 1
|
||||
}
|
||||
}
|
||||
$CurrentChat = chat
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage] = chat
|
||||
}}
|
||||
unReroll={() => {
|
||||
const cha = $CurrentCharacter
|
||||
const chat = $CurrentChat
|
||||
const cha = $DataBase.characters[$selectedCharID]
|
||||
const chat = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage]
|
||||
if(cha.type !== 'group'){
|
||||
if (chat.fmIndex === -1){
|
||||
chat.fmIndex = (cha.alternateGreetings.length - 1)
|
||||
@@ -632,38 +639,38 @@
|
||||
chat.fmIndex -= 1
|
||||
}
|
||||
}
|
||||
$CurrentChat = chat
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage] = chat
|
||||
}}
|
||||
isLastMemory={false}
|
||||
|
||||
/>
|
||||
{#if !$CurrentCharacter.removedQuotes && $CurrentCharacter.creatorNotes.length >= 2}
|
||||
<CreatorQuote quote={$CurrentCharacter.creatorNotes} onRemove={() => {
|
||||
const cha = $CurrentCharacter
|
||||
{#if !$DataBase.characters[$selectedCharID].removedQuotes && $DataBase.characters[$selectedCharID].creatorNotes.length >= 2}
|
||||
<CreatorQuote quote={$DataBase.characters[$selectedCharID].creatorNotes} onRemove={() => {
|
||||
const cha = $DataBase.characters[$selectedCharID]
|
||||
if(cha.type !== 'group'){
|
||||
cha.removedQuotes = true
|
||||
}
|
||||
$CurrentCharacter = cha
|
||||
$DataBase.characters[$selectedCharID] = cha
|
||||
}} />
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{#if openMenu}
|
||||
<div class="absolute right-2 bottom-16 p-5 bg-darkbg flex flex-col gap-3 text-textcolor rounded-md" on:click={(e) => {
|
||||
<div class="absolute right-2 bottom-16 p-5 bg-darkbg flex flex-col gap-3 text-textcolor rounded-md" onclick={(e) => {
|
||||
e.stopPropagation()
|
||||
}}>
|
||||
{#if $CurrentCharacter.type === 'group'}
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" on:click={runAutoMode}>
|
||||
{#if $DataBase.characters[$selectedCharID].type === 'group'}
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" onclick={runAutoMode}>
|
||||
<DicesIcon />
|
||||
<span class="ml-2">{language.autoMode}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
<!-- svelte-ignore empty-block -->
|
||||
{#if $CurrentCharacter.ttsMode === 'webspeech' || $CurrentCharacter.ttsMode === 'elevenlab'}
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" on:click={() => {
|
||||
<!-- svelte-ignore block_empty -->
|
||||
{#if $DataBase.characters[$selectedCharID].ttsMode === 'webspeech' || $DataBase.characters[$selectedCharID].ttsMode === 'elevenlab'}
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" onclick={() => {
|
||||
stopTTS()
|
||||
}}>
|
||||
<MicOffIcon />
|
||||
@@ -672,9 +679,9 @@
|
||||
{/if}
|
||||
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors"
|
||||
class:text-textcolor2={($CurrentChat.message.length < 2) || ($CurrentChat.message[$CurrentChat.message.length - 1].role !== 'char')}
|
||||
on:click={() => {
|
||||
if(($CurrentChat.message.length < 2) || ($CurrentChat.message[$CurrentChat.message.length - 1].role !== 'char')){
|
||||
class:text-textcolor2={($DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length < 2) || ($DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message[$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length - 1].role !== 'char')}
|
||||
onclick={() => {
|
||||
if(($DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length < 2) || ($DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message[$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message.length - 1].role !== 'char')){
|
||||
return
|
||||
}
|
||||
sendContinue();
|
||||
@@ -686,7 +693,7 @@
|
||||
|
||||
|
||||
{#if $DataBase.showMenuChatList}
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" on:click={() => {
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" onclick={() => {
|
||||
openChatList = true
|
||||
openMenu = false
|
||||
}}>
|
||||
@@ -696,7 +703,7 @@
|
||||
{/if}
|
||||
|
||||
{#if $DataBase.translator !== ''}
|
||||
<div class={"flex items-center cursor-pointer "+ ($DataBase.useAutoTranslateInput ? 'text-green-500':'lg:hover:text-green-500')} on:click={() => {
|
||||
<div class={"flex items-center cursor-pointer "+ ($DataBase.useAutoTranslateInput ? 'text-green-500':'lg:hover:text-green-500')} onclick={() => {
|
||||
$DataBase.useAutoTranslateInput = !$DataBase.useAutoTranslateInput
|
||||
}}>
|
||||
<GlobeIcon />
|
||||
@@ -705,14 +712,14 @@
|
||||
|
||||
{/if}
|
||||
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" on:click={() => {
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" onclick={() => {
|
||||
screenShot()
|
||||
}}>
|
||||
<CameraIcon />
|
||||
<span class="ml-2">{language.screenshot}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" on:click={async () => {
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" onclick={async () => {
|
||||
const res = await postChatFile(messageInput)
|
||||
if(res?.type === 'image'){
|
||||
fileInput.push(res.data)
|
||||
@@ -728,7 +735,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class={"flex items-center cursor-pointer "+ ($DataBase.useAutoSuggestions ? 'text-green-500':'lg:hover:text-green-500')} on:click={async () => {
|
||||
<div class={"flex items-center cursor-pointer "+ ($DataBase.useAutoSuggestions ? 'text-green-500':'lg:hover:text-green-500')} onclick={async () => {
|
||||
$DataBase.useAutoSuggestions = !$DataBase.useAutoSuggestions
|
||||
}}>
|
||||
<ReplyIcon />
|
||||
@@ -736,8 +743,8 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" on:click={() => {
|
||||
$CurrentChat.modules ??= []
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" onclick={() => {
|
||||
$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].modules ??= []
|
||||
openModuleList = true
|
||||
openMenu = false
|
||||
}}>
|
||||
@@ -746,7 +753,7 @@
|
||||
</div>
|
||||
|
||||
{#if $DataBase.sideMenuRerollButton}
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" on:click={reroll}>
|
||||
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" onclick={reroll}>
|
||||
<RefreshCcwIcon />
|
||||
<span class="ml-2">{language.reroll}</span>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
{#await getEmotion($DataBase,$CharEmotion, 'contain') then images}
|
||||
{#each images as image, i}
|
||||
<div style={image + `width:${(100 / images.length)}%;bottom:0;left:${100 / images.length * i}%`} class="h-full bg-center absolute" />
|
||||
<div style={image + `width:${(100 / images.length)}%;bottom:0;left:${100 / images.length * i}%`} class="h-full bg-center absolute"></div>
|
||||
|
||||
{/each}
|
||||
{/await}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { getEmotion } from '../../ts/util';
|
||||
import { DataBase } from '../../ts/storage/database';
|
||||
|
||||
let box;
|
||||
let box = $state();
|
||||
let isResizing = false;
|
||||
let initialWidth;
|
||||
let initialHeight;
|
||||
@@ -88,9 +88,9 @@
|
||||
<TransitionImage classType='risu' src={getEmotion($DataBase, $CharEmotion, 'plain')}/>
|
||||
<div
|
||||
class="resize-handle"
|
||||
on:mousedown="{handleStart}"
|
||||
on:mouseup="{handleEnd}"
|
||||
on:touchstart="{handleStart}"
|
||||
on:touchend="{handleEnd}"
|
||||
onmousedown={handleStart}
|
||||
onmouseup={handleEnd}
|
||||
ontouchstart={handleStart}
|
||||
ontouchend={handleEnd}
|
||||
></div>
|
||||
</div>
|
||||
@@ -1,8 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { run } from 'svelte/legacy';
|
||||
|
||||
import { requestChatData } from "src/ts/process/request";
|
||||
import { doingChat, type OpenAIChat } from "../../ts/process/index";
|
||||
import { DataBase, setDatabase, type character, type Message, type groupChat, type Database } from "../../ts/storage/database";
|
||||
import { CurrentCharacter, selectedCharID } from "../../ts/stores";
|
||||
import { selectedCharID } from "../../ts/stores";
|
||||
import { translate } from "src/ts/translator/translator";
|
||||
import { CopyIcon, LanguagesIcon, RefreshCcwIcon } from "lucide-svelte";
|
||||
import { alertConfirm } from "src/ts/alert";
|
||||
@@ -13,21 +15,19 @@
|
||||
import { get } from "svelte/store";
|
||||
import { ParseMarkdown } from "src/ts/parser";
|
||||
|
||||
export let send: () => any;
|
||||
export let messageInput:(string:string) => any;
|
||||
let suggestMessages:string[] = $CurrentCharacter?.chats[$CurrentCharacter.chatPage]?.suggestMessages
|
||||
let suggestMessagesTranslated:string[]
|
||||
let toggleTranslate:boolean = $DataBase.autoTranslate
|
||||
let progress:boolean;
|
||||
interface Props {
|
||||
send: () => any;
|
||||
messageInput: (string:string) => any;
|
||||
}
|
||||
|
||||
let { send, messageInput }: Props = $props();
|
||||
let suggestMessages:string[] = $state($DataBase.characters[$selectedCharID]?.chats[$DataBase.characters[$selectedCharID].chatPage]?.suggestMessages)
|
||||
let suggestMessagesTranslated:string[] = $state()
|
||||
let toggleTranslate:boolean = $state($DataBase.autoTranslate)
|
||||
let progress:boolean = $state();
|
||||
let progressChatPage=-1;
|
||||
let abortController:AbortController;
|
||||
let chatPage:number
|
||||
$: {
|
||||
$selectedCharID
|
||||
//FIXME add selectedChatPage for optimize render
|
||||
chatPage = $CurrentCharacter.chatPage
|
||||
updateSuggestions()
|
||||
}
|
||||
let chatPage:number = $state()
|
||||
|
||||
const updateSuggestions = () => {
|
||||
if($selectedCharID > -1 && !$doingChat) {
|
||||
@@ -35,7 +35,7 @@
|
||||
progress=false
|
||||
abortController?.abort()
|
||||
}
|
||||
let currentChar = $CurrentCharacter;
|
||||
let currentChar = $DataBase.characters[$selectedCharID];
|
||||
suggestMessages = currentChar?.chats[currentChar.chatPage].suggestMessages
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@
|
||||
suggestMessages = []
|
||||
}
|
||||
if(!v && $selectedCharID > -1 && (!suggestMessages || suggestMessages.length === 0) && !progress){
|
||||
let currentChar:character|groupChat = $CurrentCharacter;
|
||||
let currentChar:character|groupChat = $DataBase.characters[$selectedCharID];
|
||||
let messages:Message[] = []
|
||||
|
||||
messages = [...messages, ...currentChar.chats[currentChar.chatPage].message];
|
||||
@@ -112,20 +112,26 @@
|
||||
|
||||
onDestroy(unsub)
|
||||
|
||||
$: {translateSuggest(toggleTranslate, suggestMessages)}
|
||||
run(() => {
|
||||
$selectedCharID
|
||||
//FIXME add selectedChatPage for optimize render
|
||||
chatPage = $DataBase.characters[$selectedCharID].chatPage
|
||||
updateSuggestions()
|
||||
});
|
||||
run(() => {translateSuggest(toggleTranslate, suggestMessages)});
|
||||
</script>
|
||||
|
||||
<div class="ml-4 flex flex-wrap">
|
||||
{#if progress}
|
||||
<div class="flex bg-textcolor2 p-2 rounded-lg items-center">
|
||||
<div class="loadmove mx-2"/>
|
||||
<div class="loadmove mx-2"></div>
|
||||
<div>{language.creatingSuggestions}</div>
|
||||
</div>
|
||||
{:else if !$doingChat}
|
||||
{#if $DataBase.translator !== ''}
|
||||
<div class="flex mr-2 mb-2">
|
||||
<button class={"bg-textcolor2 hover:bg-darkbutton font-bold py-2 px-4 rounded " + (toggleTranslate ? 'text-green-500' : 'text-textcolor')}
|
||||
on:click={() => {
|
||||
onclick={() => {
|
||||
toggleTranslate = !toggleTranslate
|
||||
}}
|
||||
>
|
||||
@@ -137,7 +143,7 @@
|
||||
|
||||
<div class="flex mr-2 mb-2">
|
||||
<button class="bg-textcolor2 hover:bg-darkbutton font-bold py-2 px-4 rounded text-textcolor"
|
||||
on:click={() => {
|
||||
onclick={() => {
|
||||
alertConfirm(language.askReRollAutoSuggestions).then((result) => {
|
||||
if(result) {
|
||||
suggestMessages = []
|
||||
@@ -152,7 +158,7 @@
|
||||
</div>
|
||||
{#each suggestMessages??[] as suggest, i}
|
||||
<div class="flex mr-2 mb-2">
|
||||
<button class="bg-textcolor2 hover:bg-darkbutton text-textcolor font-bold py-2 px-4 rounded" on:click={() => {
|
||||
<button class="bg-textcolor2 hover:bg-darkbutton text-textcolor font-bold py-2 px-4 rounded" onclick={() => {
|
||||
suggestMessages = []
|
||||
messageInput(suggest)
|
||||
send()
|
||||
@@ -161,7 +167,7 @@
|
||||
{@html md}
|
||||
{/await}
|
||||
</button>
|
||||
<button class="bg-textcolor2 hover:bg-darkbutton text-textcolor font-bold py-2 px-4 rounded ml-1" on:click={() => {
|
||||
<button class="bg-textcolor2 hover:bg-darkbutton text-textcolor font-bold py-2 px-4 rounded ml-1" onclick={() => {
|
||||
messageInput(suggest)
|
||||
}}>
|
||||
<CopyIcon/>
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
<script lang="ts">
|
||||
let currentSrc:string[] = []
|
||||
let oldSrc:string[] = [];
|
||||
let showOldImage = false;
|
||||
let styleType:string = 'normal'
|
||||
let oldStyleType:string = 'normal'
|
||||
import { run } from 'svelte/legacy';
|
||||
|
||||
export let src:string[]|Promise<string[]> = [];
|
||||
export let classType: 'waifu'|'risu'|'mobile'
|
||||
let currentSrc:string[] = $state([])
|
||||
let oldSrc:string[] = $state([]);
|
||||
let showOldImage = $state(false);
|
||||
let styleType:string = $state('normal')
|
||||
let oldStyleType:string = $state('normal')
|
||||
|
||||
interface Props {
|
||||
src?: string[]|Promise<string[]>;
|
||||
classType: 'waifu'|'risu'|'mobile';
|
||||
}
|
||||
|
||||
let { src = [], classType }: Props = $props();
|
||||
|
||||
async function processSrc(src:string[]|Promise<string[]>) {
|
||||
const resultSrc = await src
|
||||
@@ -38,7 +44,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: processSrc(src)
|
||||
run(() => {
|
||||
processSrc(src)
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -137,7 +145,7 @@
|
||||
src={oldSrc[i]}
|
||||
alt="img"
|
||||
class="old-image"
|
||||
on:animationend={handleTransitionEnd}
|
||||
onanimationend={handleTransitionEnd}
|
||||
style:width={`${100 / oldSrc.length}%`}
|
||||
style:left={`${100 / oldSrc.length * i}%`}
|
||||
/>
|
||||
@@ -150,7 +158,7 @@
|
||||
src={oldSrc[i]}
|
||||
alt="img"
|
||||
class="old-image"
|
||||
on:animationend={handleTransitionEnd}
|
||||
onanimationend={handleTransitionEnd}
|
||||
style:width={`${80 - (i*10)}%`}
|
||||
style:left={`${30-(i*30)}%`}
|
||||
style:z-index={9 - i}
|
||||
|
||||
Reference in New Issue
Block a user