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;
}
select option.is-default {
background-color: #0842e058;
}
.is-disabled {
pointer-events: none;
cursor: default;

View File

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

View File

@ -1,7 +1,8 @@
<script context="module" lang="ts">
import { applyProfile } from './Profiles.svelte'
import { getChatSettings } from './Storage.svelte'
import { getChatSettings, getGlobalSettings, setGlobalSettingValueByKey } from './Storage.svelte'
import { encode } from 'gpt-tokenizer'
import { faCheck, faThumbTack } from '@fortawesome/free-solid-svg-icons/index'
// Setting definitions
import {
@ -11,7 +12,10 @@ import {
type GlobalSetting,
type GlobalSettings,
type Request,
type Model
type Model,
type ControlAction
} from './Types.svelte'
export const defaultModel:Model = 'gpt-3.5-turbo-0301'
@ -103,7 +107,25 @@ const profileSetting: ChatSetting & SettingSelect = {
applyProfile(chatId)
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

View File

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

View File

@ -144,6 +144,19 @@ type SettingBoolean = {
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 = {
key: keyof ChatSettings;
name: string;
@ -155,7 +168,7 @@ type SettingBoolean = {
placeholder?: string;
hide?: (chatId:number) => boolean;
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;
afterChange?: (chatId:number, setting:ChatSetting, value:any) => boolean;
} & (SettingNumber | SettingSelect | SettingBoolean | SettingText | SettingTextArea | SettingOther);