diff --git a/src/lang/en.ts b/src/lang/en.ts index 4b4ae98e..e3c3e488 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -164,6 +164,7 @@ export const languageEnglish = { translatorNote: "Here, you can add a unique translation prompt for each character. This option only applies when using the Ax. model for translation. To apply it, include `{{slot::tnote}}` in the language settings. It doesn't work in group chats.", groupInnerFormat: "This defines a format that is used in group chat for characters that isn't speaker. if it is not blank, it will use this format instead of the default format. if `Group Other Bot Role` is `assistant`, it will also be applied to the speaker.", groupOtherBotRole: "This defines a role that is used in group chat for characters that isn't speaker.", + chatHTML: "A HTML that would be inserted as each chat.\n\nYou can use CBS and special tags.\n- ``: a textbox that would be used to render text\n- ``: an icon for user or assistant\n- ``: icon buttons for chat edit, translations and etc.\n- ``: generation information button." }, setup: { chooseProvider: "Choose AI Provider", @@ -749,4 +750,5 @@ export const languageEnglish = { groupInnerFormat: "Non-Speaker Inner Format", groupOtherBotRole: "Non-Speaker Role in Group", defineCustomGUI: "Define Custom GUI", + chatHTML: "Chat HTML", } \ No newline at end of file diff --git a/src/lib/ChatScreens/Chat.svelte b/src/lib/ChatScreens/Chat.svelte index bfa203de..ce4d14ec 100644 --- a/src/lib/ChatScreens/Chat.svelte +++ b/src/lib/ChatScreens/Chat.svelte @@ -191,6 +191,19 @@ onDestroy(()=>{ unsubscribers.forEach(u => u()) }) + + function RenderGUIHtml(html:string){ + try { + const parser = new DOMParser() + const doc = parser.parseFromString(risuChatParser(html ?? ''), 'text/html') + console.log(doc.body) + return doc.body + } catch (error) { + const placeholder = document.createElement('div') + return placeholder + } + } + @@ -227,7 +240,7 @@ {:else} - { + { if(DBState.db.clickToEdit && idx > -1){ editMode = true } @@ -336,6 +349,148 @@ {/if} {/snippet} +{#snippet renderGuiHtmlPart(dom:HTMLElement)} + {#if dom.tagName === 'IMG'} + + {:else if dom.tagName === 'A'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'SPAN'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'DIV'} +
+ {@render renderChilds(dom)} +
+ {:else if dom.tagName === 'P'} +

+ {@render renderChilds(dom)} +

+ {:else if dom.tagName === 'H1'} +

+ {@render renderChilds(dom)} +

+ {:else if dom.tagName === 'H2'} +

+ {@render renderChilds(dom)} +

+ {:else if dom.tagName === 'H3'} +

+ {@render renderChilds(dom)} +

+ {:else if dom.tagName === 'H4'} +

+ {@render renderChilds(dom)} +

+ {:else if dom.tagName === 'H5'} +
+ {@render renderChilds(dom)} +
+ {:else if dom.tagName === 'H6'} +
+ {@render renderChilds(dom)} +
+ {:else if dom.tagName === 'UL'} +
    + {@render renderChilds(dom)} +
+ {:else if dom.tagName === 'OL'} +
    + {@render renderChilds(dom)} +
+ {:else if dom.tagName === 'LI'} +
  • + {@render renderChilds(dom)} +
  • + {:else if dom.tagName === 'TABLE'} + + {@render renderChilds(dom)} +
    + {:else if dom.tagName === 'TR'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'TD'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'TH'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'HR'} +
    + {:else if dom.tagName === 'BR'} +
    + {:else if dom.tagName === 'CODE'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'PRE'} +
    +            {@render renderChilds(dom)}
    +        
    + {:else if dom.tagName === 'BLOCKQUOTE'} +
    + {@render renderChilds(dom)} +
    + {:else if dom.tagName === 'EM'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'STRONG'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'U'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'DEL'} + + {@render renderChilds(dom)} + + {:else if dom.tagName === 'BUTTON'} + + {:else if dom.tagName === 'STYLE'} + + {:else if dom.tagName === 'RISUTEXTBOX'} + {@render textBox()} + {:else if dom.tagName === 'RISUICON'} + {@render icon()} + {:else if dom.tagName === 'RISUBUTTONS'} + {@render icons()} + {:else if dom.tagName === 'RISUGENINFO'} + {@render genInfo()} + {:else if dom.tagName === 'STYLE'} + + {dom.innerHTML} + + {:else} +
    + {@render renderChilds(dom)} +
    + {/if} + + +{/snippet} + +{#snippet renderChilds(dom:HTMLElement)} + {#each dom.children as node} + {@render renderGuiHtmlPart((node as HTMLElement))} + {/each} +{/snippet} +
    {#if DBState.db.theme === 'mobilechat' && !blankMessage} @@ -390,12 +545,14 @@ {@render icons({applyTextColors: false})}
    + {:else if DBState.db.theme === 'customHTML' && !blankMessage} + {@render renderGuiHtmlPart(RenderGUIHtml(DBState.db.guiHTML))} {:else} {@render icon({rounded: DBState.db.roundIcons})} -
    +
    {#if DBState.db.characters[$selectedCharID]?.chaId === "§playground" && !blankMessage} - + {name === 'assistant' ? 'Assistant' : 'User'} {:else if !blankMessage && !$HideIconStore} - {name} + {name} {/if} {@render icons()}
    @@ -412,21 +569,4 @@ {/if}
    - - - - \ No newline at end of file + \ No newline at end of file diff --git a/src/lib/Setting/Pages/DisplaySettings.svelte b/src/lib/Setting/Pages/DisplaySettings.svelte index c41cc439..d0923bdb 100644 --- a/src/lib/Setting/Pages/DisplaySettings.svelte +++ b/src/lib/Setting/Pages/DisplaySettings.svelte @@ -57,7 +57,7 @@ Mobile Chat CardBoard - + Custom HTML {#if DBState.db.theme === "custom"} @@ -67,6 +67,12 @@ {/if} + {#if DBState.db.theme === 'customHTML'} + {language.chatHTML} + + {/if} + + {#if DBState.db.theme === "waifu"} {language.waifuWidth} diff --git a/src/lib/UI/GUI/TextAreaResizable.svelte b/src/lib/UI/GUI/TextAreaResizable.svelte index fa152149..6b4b2d9a 100644 --- a/src/lib/UI/GUI/TextAreaResizable.svelte +++ b/src/lib/UI/GUI/TextAreaResizable.svelte @@ -35,7 +35,7 @@ oninput={handleInput} use:longpress={handleLongPress} bind:value={value} - class="rounded-md p-2 text-textcolor bg-transparent resize-none overflow-y-hidden border border-darkborderc" + class="rounded-md p-2 text-textcolor bg-transparent resize-none overflow-y-hidden border border-darkborderc w-full" style:font-size="{0.875 * (DBState.db.zoomsize / 100)}rem" style:line-height="{(DBState.db.lineHeight ?? 1.25) * (DBState.db.zoomsize / 100)}rem" > \ No newline at end of file diff --git a/src/styles.css b/src/styles.css index 4a8eaab9..a1711efe 100644 --- a/src/styles.css +++ b/src/styles.css @@ -254,4 +254,15 @@ html, body{ .z-100{ z-index: 100; +} + +.flexium{ + display: flex; + flex-direction: row; + justify-content: flex-start; +} +.chat-width{ + max-width: calc(100% - 0.5rem); + word-break: normal; + overflow-wrap: anywhere; } \ No newline at end of file diff --git a/src/ts/storage/database.svelte.ts b/src/ts/storage/database.svelte.ts index b3e00135..e6a1fb15 100644 --- a/src/ts/storage/database.svelte.ts +++ b/src/ts/storage/database.svelte.ts @@ -813,6 +813,7 @@ export interface Database{ groupTemplate?:string groupOtherBotRole?:string customGUI:string + guiHTML:string } export interface customscript{