Skip to content

Commit

Permalink
[web] create conversation room (#90)
Browse files Browse the repository at this point in the history
* added search bar

* room page added character component

* character layout mostly done

* editing user interface, wip interaction between left side and right side

* adding limit character number to 4; added group to the checkboxes
  • Loading branch information
PandaKunQiao authored Jun 3, 2023
1 parent d121ae5 commit fe1fd42
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 1 deletion.
56 changes: 56 additions & 0 deletions skyagi-web/src/lib/Toast.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script>
import { flip } from "svelte/animate";
import { fly } from "svelte/transition";
import { notifications } from "./notifications.js";
export let themes = {
danger: "#E26D69",
success: "#84C991",
warning: "#f0ad4e",
info: "#5bc0de",
default: "#aaaaaa",
};
</script>

<div class="notifications">
{#each $notifications as notification (notification.id)}
<div
animate:flip
class="toast"
style="background: {themes[notification.type]};"
transition:fly={{ y: 30 }}
>
<div class="content">{notification.message}</div>
{#if notification.icon}<i class={notification.icon} />{/if}
</div>
{/each}
</div>

<style>
.notifications {
position: fixed;
top: 10px;
left: 0;
right: 0;
margin: 0 auto;
padding: 0;
z-index: 9999;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
pointer-events: none;
}
.toast {
flex: 0 0 auto;
margin-bottom: 10px;
}
.content {
padding: 10px;
display: block;
color: white;
font-weight: 500;
}
</style>
47 changes: 47 additions & 0 deletions skyagi-web/src/lib/notifications.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { writable, derived } from "svelte/store"

const TIMEOUT = 3000

function createNotificationStore (timeout) {
const _notifications = writable([])

function send (message, type = "default", timeout) {
_notifications.update(state => {
return [...state, { id: id(), type, message, timeout }]
})
}

let timers = []

const notifications = derived(_notifications, ($_notifications, set) => {
set($_notifications)
if ($_notifications.length > 0) {
const timer = setTimeout(() => {
_notifications.update(state => {
state.shift()
return state
})
}, $_notifications[0].timeout)
return () => {
clearTimeout(timer)
}
}
})
const { subscribe } = notifications

return {
subscribe,
send,
default: (msg, timeout) => send(msg, "default", timeout),
danger: (msg, timeout) => send(msg, "danger", timeout),
warning: (msg, timeout) => send(msg, "warning", timeout),
info: (msg, timeout) => send(msg, "info", timeout),
success: (msg, timeout) => send(msg, "success", timeout),
}
}

function id() {
return '_' + Math.random().toString(36).substr(2, 9);
};

export const notifications = createNotificationStore()
68 changes: 68 additions & 0 deletions skyagi-web/src/lib/room-new-character.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<script lang="ts">
import type { CharacterType } from './types';
import { createEventDispatcher } from 'svelte';
import { error } from '@sveltejs/kit';
import {notifications} from '$lib/notifications.js'
import Toast from '$lib/Toast.svelte'
export let character: CharacterType;
export let value;
// export let lastClickedCharacter;
const dispatch = createEventDispatcher();
function updateLastClickedCharacter(){
dispatch("message", {
character: character
})
};
export let bindGroup = [];
function onChange({ target }) {
const { value, checked } = target;
if (bindGroup.length >= 4) {
notifications.warning("Please select no more than 4 characters", 2000)
console.log("Should pop up warnings")
}
else{
if (checked) {
bindGroup = [...bindGroup, value]
} else {
bindGroup = bindGroup.filter((item) => item !== value)
}
}
}
</script>

<div class="container">
<div class=characterCheck>
<input type=checkbox
value={value}
checked={bindGroup.includes(value)}
on:change={onChange}
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
</div>
<figure>
<img src={character.image} alt="" width=100px on:click={updateLastClickedCharacter}/>
<figcaption> {character.name} </figcaption>
</figure>
</div>
<Toast />
<style>
figure {
text-align: center;
width: 100px;
/* transform: translateX(50px); */
}
.container {
grid-template-columns: 20px 100px;
column-gap: 0px;
display: grid;
align-items: center;
}
.characterCheck {
margin: 0px;
transform: translateX(-5px);
}
</style>
135 changes: 134 additions & 1 deletion skyagi-web/src/routes/room/new/+page.svelte
Original file line number Diff line number Diff line change
@@ -1 +1,134 @@
<h1 class="text-4xl">Create new chat room</h1>
<script lang="ts">
// import Scrolly from "./Scrolly.svelte";
import Character from '$lib/room-new-character.svelte';
import { Select, Label } from 'flowbite-svelte';
export const characters = [
{name: "tan li", image: "../src/lib/assets/Avatar1.png", title:"", description:""},
{name: "yy", image: "../src/lib/assets/Avatar2.png", title:"", description:""},
{name: "Vegeta", image: "../src/lib/assets/Avatar3.png", title:"", description:""},
{name: "Goku", image:"../src/lib/assets/Avatar3.png", title:"", description:""},
{name: "Sheldon", image:"../src/lib/assets/Avatar2.png", title:"", description:""}];
let lastClickedCharacter = "..."
function handleOnClickImageMessage(event) {
console.log(event.detail.character.name);
lastClickedCharacter = event.detail.character.name;
}
function getNthPicPositionStr(inputVal) {
let startPointX = 120;
let startPointY = 150;
let widthX = 200;
let widthY = 200;
let leftVal = (inputVal%3) * widthX+startPointX
let topVal = Math.floor(inputVal/3) * widthY+startPointY
// console.log("positin:absolute;left:" + leftVal.toString() + "px;top:" + topVal.toString() + "px")
return "position:static;left:" + leftVal.toString() + "px;top:" + topVal.toString() + "px"
}
let selectedModel;
let models = [
{ value: 'openai-gpt-3.5-turbo', name: 'openai-gpt-3.5-turbo' },
{ value: 'openai-gpt-4', name: 'openai-gpt-4' }
// { value: 'chatglm-6b-modelz', name: 'chatglm-6b-modelz' },
// { value: 'moss-16b-modelz', name: 'moss-16b-modelz' },
// { value: 'vicuna-13b-modelz', name: 'vicuna-13b-modelz' },
// { value: 'mpt-7b-modelz', name: 'mpt-7b-modelz' }
];
let checkedCharacterGroup = [];
let playerCharacter;
function charactersToItems(inputCharacters){
let rst = []
for (let i=0; i<inputCharacters.length; i++){
rst.push({name: inputCharacters[i], value: inputCharacters[i]})
}
return rst
}
</script>

<div id="globalGrid">

<div>
<input id="searchBar" type="search" placeholder="Search..." />
</div>

<div class="scroller">
{#each characters as character, i}
<div class="characterInfoSet">
<Character {character}
on:message={handleOnClickImageMessage}
bind:bindGroup={checkedCharacterGroup}
value={character.name}>
</Character>
</div>
{/each}
</div>

<input id="chatNameField" placeholder="Chat name">

<div>
<h1>
Select Model for {lastClickedCharacter}
</h1>
<Label>Select an option
<Select class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" items={models} bind:value={selectedModel}
placeholder = "Select LLM" />
</Label>

<h1>
API Key
</h1>
<input id="APIKeyField" placeholder="Input key">

<h1>
You will play...
</h1>
<Label class="mb-10 w-1/2">Select an option
<Select id="playerDropDown" class="mt-5" size="lg" items={charactersToItems(checkedCharacterGroup)} bind:value={playerCharacter}
placeholder = "Select your character" />
</Label>
<button>
Create
</button>

</div>
</div>


<style>
#searchBar {
width: 200px
}
#chatNameField {
width: 200px
}
.scroller {
width: 600px;
height: 500px;
top: 20px;
position: relative;
overflow-x: scroll;
overflow-y: scroll;
display: grid;
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(auto-fill, 220px);
}
#globalGrid {
display: grid;
grid-template-rows: repeat(2, 50px);
grid-auto-flow: column;
gap: 10px;
/* grid-auto-columns: 400px 400px; */
}
</style>

1 comment on commit fe1fd42

@vercel
Copy link

@vercel vercel bot commented on fe1fd42 Jun 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

skyagi – ./

skyagi-git-main-sky-agi.vercel.app
skyagi-sky-agi.vercel.app
skyagi.vercel.app
app.skyagi.ai

Please sign in to comment.