Add UI for default profile

This commit is contained in:
Webifi 2023-06-03 16:50:08 -05:00
parent 2880cf3750
commit 759eb35bc6
5 changed files with 88 additions and 15 deletions

View File

@ -117,6 +117,10 @@ html {
min-height: 100vh; min-height: 100vh;
} }
select option.is-default {
background-color: #0842e058;
}
.is-disabled { .is-disabled {
pointer-events: none; pointer-events: none;
cursor: default; cursor: default;

View File

@ -2,9 +2,10 @@
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { getProfile } from './Profiles.svelte' import { getProfile } from './Profiles.svelte'
import { addChat, cleanSettingValue, setChatSettingValue } from './Storage.svelte' import { addChat, cleanSettingValue, setChatSettingValue } from './Storage.svelte'
import type { Chat, ChatSetting, ChatSettings, SettingPrompt } from './Types.svelte' import type { Chat, ChatSetting, ChatSettings, ControlAction, FieldControl, SettingPrompt } from './Types.svelte'
import { autoGrowInputOnEvent } from './Util.svelte' import { autoGrowInputOnEvent } from './Util.svelte'
import { replace } from 'svelte-spa-router' import { replace } from 'svelte-spa-router'
import Fa from 'svelte-fa/src/fa.svelte'
export let setting:ChatSetting export let setting:ChatSetting
export let chatSettings:ChatSettings export let chatSettings:ChatSettings
@ -14,6 +15,10 @@
const chatId = chat.id const chatId = chat.id
const fieldControls:ControlAction[] = (setting.fieldControls || [] as FieldControl[]).map(fc => {
return fc.getAction(chatId, setting, chatSettings[setting.key])
})
if (originalProfile) { if (originalProfile) {
// eventually... // eventually...
} }
@ -36,7 +41,8 @@
{ {
prompt: 'Would you like to start a new chat session with this profile?', prompt: 'Would you like to start a new chat session with this profile?',
checkPrompt: (setting, newVal, oldVal) => { checkPrompt: (setting, newVal, oldVal) => {
return newVal !== oldVal return chat.sessionStarted && newVal !== originalProfile &&
(getProfile(newVal).characterName !== chatSettings.characterName)
}, },
onYes: (setting, newVal, oldVal) => { onYes: (setting, newVal, oldVal) => {
// start new char session, apply this profile, amd start it // start new char session, apply this profile, amd start it
@ -46,6 +52,7 @@
replace(`/chat/${newChatId}`) replace(`/chat/${newChatId}`)
return true return true
}, },
onNo: (setting, newVal, oldVal) => true, // Continue on no
passed: false passed: false
}, },
{ {
@ -54,6 +61,7 @@
return chat.sessionStarted && newVal !== originalProfile && return chat.sessionStarted && newVal !== originalProfile &&
(getProfile(newVal).characterName !== chatSettings.characterName) (getProfile(newVal).characterName !== chatSettings.characterName)
}, },
onYes: (setting, newVal, oldVal) => true,
passed: false passed: false
} }
] ]
@ -116,12 +124,14 @@
} }
} else { } else {
// roll-back // roll-back
setChatSettingValue(chatId, setting, val) if (!c.onNo || !c.onNo(setting, newVal, val)) {
// refresh setting modal, if open setChatSettingValue(chatId, setting, val)
c.onNo && c.onNo(setting, newVal, val) // refresh setting modal, if open
refreshSettings() c.onNo && c.onNo(setting, newVal, val)
resetSettingCheck(setting.key) refreshSettings()
return resetSettingCheck(setting.key)
return
}
} }
} else { } else {
c.passed = true c.passed = true
@ -172,7 +182,7 @@
</div> </div>
{/if} {/if}
<div class="field-body"> <div class="field-body">
<div class="field"> <div class="field" class:has-addons={fieldControls.length}>
{#if setting.type === 'number'} {#if setting.type === 'number'}
<input <input
class="input" class="input"
@ -188,13 +198,31 @@
on:change={e => queueSettingValueChange(e, setting)} on:change={e => queueSettingValueChange(e, setting)}
/> />
{:else if setting.type === 'select'} {:else if setting.type === 'select'}
<div class="select"> <!-- <div class="select"> -->
<div class="select" class:control={fieldControls.length}>
<select id="settings-{setting.key}" title="{setting.title}" on:change={e => queueSettingValueChange(e, setting) } > <select id="settings-{setting.key}" title="{setting.title}" on:change={e => queueSettingValueChange(e, setting) } >
{#each setting.options as option} {#each setting.options as option}
<option class:is-default={option.value === chatDefaults[setting.key]} value={option.value} selected={option.value === chatSettings[setting.key]}>{option.text}</option> <option class:is-default={option.value === chatDefaults[setting.key]} value={option.value} selected={option.value === chatSettings[setting.key]}>{option.text}</option>
{/each} {/each}
</select> </select>
</div> </div>
{#each fieldControls as cont}
<div class="control">
<button title={cont.text} on:click={() => { cont.action && cont.action(chatId, setting, chatSettings[setting.key]); refreshSettings() }} class="button {cont.class || ''}">
{#if cont.text}
<span class="text">
<Fa icon={cont.icon} />
</span>
{/if}
{#if cont.icon}
<span class="icon">
<Fa icon={cont.icon} />
</span>
{/if}
</button>
</div>
{/each}
{:else if setting.type === 'text'} {:else if setting.type === 'text'}
<div class="field"> <div class="field">
<input <input

View File

@ -1,7 +1,8 @@
<script context="module" lang="ts"> <script context="module" lang="ts">
import { applyProfile } from './Profiles.svelte' import { applyProfile } from './Profiles.svelte'
import { getChatSettings } from './Storage.svelte' import { getChatSettings, getGlobalSettings, setGlobalSettingValueByKey } from './Storage.svelte'
import { encode } from 'gpt-tokenizer' import { encode } from 'gpt-tokenizer'
import { faCheck, faThumbTack } from '@fortawesome/free-solid-svg-icons/index'
// Setting definitions // Setting definitions
import { import {
@ -11,7 +12,10 @@ import {
type GlobalSetting, type GlobalSetting,
type GlobalSettings, type GlobalSettings,
type Request, type Request,
type Model type Model,
type ControlAction
} from './Types.svelte' } from './Types.svelte'
export const defaultModel:Model = 'gpt-3.5-turbo-0301' export const defaultModel:Model = 'gpt-3.5-turbo-0301'
@ -103,7 +107,25 @@ const profileSetting: ChatSetting & SettingSelect = {
applyProfile(chatId) applyProfile(chatId)
return true // Signal we should refresh the setting modal return true // Signal we should refresh the setting modal
}, },
setDefault: (chatId, setting, value) => {} fieldControls: [{
getAction: (chatId, setting, value) => {
if (value === getGlobalSettings().defaultProfile) {
return {
title: 'This profile is currently your default',
icon: faCheck
} as ControlAction
} else {
return {
title: 'Set this profile as your default',
icon: faThumbTack,
class: 'is-info',
action: (chatId, setting, value) => {
setGlobalSettingValueByKey('defaultProfile', value)
}
} as ControlAction
}
}
}]
} }
// Settings that will not be part of the API request // Settings that will not be part of the API request

View File

@ -333,6 +333,12 @@
globalStorage.set(store) globalStorage.set(store)
} }
export const getGlobalSettingValue = (key:keyof GlobalSetting, value):any => {
const store = get(globalStorage)
return store[key]
}
export const getGlobalSettings = ():GlobalSettings => { export const getGlobalSettings = ():GlobalSettings => {
return get(globalStorage) return get(globalStorage)
} }

View File

@ -144,6 +144,19 @@ type SettingBoolean = {
type: 'other'; type: 'other';
}; };
export type ControlAction = {
title:string;
icon?:any,
text?:string;
class?:string;
disabled?:boolean;
action?: (chatId:number, setting:any, value:any) => any;
};
export type FieldControl = {
getAction: (chatId:number, setting:any, value:any) => ControlAction;
};
export type ChatSetting = { export type ChatSetting = {
key: keyof ChatSettings; key: keyof ChatSettings;
name: string; name: string;
@ -155,7 +168,7 @@ type SettingBoolean = {
placeholder?: string; placeholder?: string;
hide?: (chatId:number) => boolean; hide?: (chatId:number) => boolean;
apiTransform?: (chatId:number, setting:ChatSetting, value:any) => any; apiTransform?: (chatId:number, setting:ChatSetting, value:any) => any;
setDefault?: (chatId:number, setting:ChatSetting, value:any) => any; fieldControls?: FieldControl[];
beforeChange?: (chatId:number, setting:ChatSetting, value:any) => boolean; beforeChange?: (chatId:number, setting:ChatSetting, value:any) => boolean;
afterChange?: (chatId:number, setting:ChatSetting, value:any) => boolean; afterChange?: (chatId:number, setting:ChatSetting, value:any) => boolean;
} & (SettingNumber | SettingSelect | SettingBoolean | SettingText | SettingTextArea | SettingOther); } & (SettingNumber | SettingSelect | SettingBoolean | SettingText | SettingTextArea | SettingOther);