Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save chats #21

Merged
merged 27 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
594dda9
Update deep-chat-dev, add save (single) chat
jackitaliano Feb 6, 2024
8752bce
Initial chat history / multiple chats (WIP)
jackitaliano Feb 7, 2024
012842b
cleanup some, add renaming of chats
jackitaliano Feb 7, 2024
8b32f31
add default thread (when none found)
jackitaliano Feb 7, 2024
b27e8bc
ui changes
jackitaliano Feb 7, 2024
080a3f2
better ui and transitions
jackitaliano Feb 8, 2024
9674db0
fix margins
jackitaliano Feb 8, 2024
66c055e
testing iOS like delete (WIP)
jackitaliano Feb 8, 2024
8afc2b2
update delete functionality with swiping
jackitaliano Feb 9, 2024
84cf1ae
change delete ui to drag more like messages
jackitaliano Feb 9, 2024
22a4df1
fix mouseup/touchup bugs
jackitaliano Feb 9, 2024
4a27964
Merge branch 'main' into save-chats
jackitaliano Feb 9, 2024
5bf4fc5
adjust height to prevent scrollbar
jackitaliano Feb 9, 2024
8504649
display none on welcome, fix flickering
jackitaliano Feb 9, 2024
348f278
fixing loading when no api key (WIP)
jackitaliano Feb 9, 2024
3af6d20
chats works fully, figuring out rerender deep-chat to update width. r…
jackitaliano Feb 10, 2024
31cb5b6
stable save chats
jackitaliano Feb 10, 2024
a1906b2
fixed initial login, updated some spacing
jackitaliano Feb 11, 2024
c1e7dab
move utils into folder
jackitaliano Feb 12, 2024
4d0c99c
update deep-chat-dev to resolve `function_handler` issue
jackitaliano Feb 12, 2024
eaee375
move bidara prompts/funcs into src/assistant/
jackitaliano Feb 12, 2024
61b28c7
added back default browser styles that tailwind removed.
bruffridge Feb 13, 2024
9fb10dc
moved stylesheet to index.html to avoid styles quickly changing from …
bruffridge Feb 13, 2024
17aa5ee
style fixes.
bruffridge Feb 14, 2024
676a478
changed the button style and height of chats in sidebar.
bruffridge Feb 14, 2024
40f3b36
minor style tweaks.
bruffridge Feb 14, 2024
ad2ad5b
Merge branch 'main' of github.com:nasa-petal/bidara-deep-chat into sa…
bruffridge Feb 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
change delete ui to drag more like messages
  • Loading branch information
jackitaliano committed Feb 9, 2024
commit 84cf1aed2ca0f040f79c0741cd377c25e66d5af8
1 change: 1 addition & 0 deletions public/grip-lines-vertical-gray.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 36 additions & 23 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
export let open = false;

let threads = getThreads();
let chat_name = "";
let selectedThreadId;
let chatName = "";

function onError(error) {
console.log(error);
Expand All @@ -37,7 +38,13 @@
onMount(async () => {
keyAsstAndThread = await getKeyAsstAndThread();
threads = getThreads();
chat_name = keyAsstAndThread[2]?.name ? keyAsstAndThread[2].name : "";
chatName = keyAsstAndThread[2]?.name ? keyAsstAndThread[2].name : "";
selectedThreadId = keyAsstAndThread[2]?.id ? keyAsstAndThread[2].id : "";

if (threads.length <= 0 && chatName) {
threads = [keyAsstAndThread[2]];
setThreads(threads);
}
});

async function onNewMessage(message) {
Expand All @@ -50,8 +57,8 @@
}

if (!openAIThreadIdSet && message.message._sessionId && message.message._sessionId != await getThread()) {
const new_thread = {name: "New Chat", id: message.message._sessionId}
setThread(new_thread);
const newThread = {name: "New Chat", id: message.message._sessionId}
setThread(newThread);
openAIThreadIdSet = true;
}
}
Expand Down Expand Up @@ -83,36 +90,41 @@
async function newThreadAndSwitch() {
const deepChatRef = document.getElementById('chat-element');
const currrent_messages = deepChatRef.getMessages();

if (currrent_messages.length <= initialMessages.length) {
return;
} else {
const new_threads = filterStoredThreads((thread) => thread.name === 'New Chat');
if (new_threads.length > 0) {
switchActiveThread(new_threads[0]);
return;
}
}
}


const new_thread = await getNewThread();
const newThread = await getNewThread();

// force new object so Siderbar rerenders
threads = [ new_thread ].concat(threads);
threads = [ newThread ].concat(threads);
switchActiveThread(newThread);

setThreads(threads);

switchActiveThread(new_thread);
}

async function deleteThreadAndSwitch(thread) {
threads = deleteThreadFromThreads(thread.id);
const deepChatRef = document.getElementById('chat-element');
const currrent_messages = deepChatRef.getMessages();


if (threads.length <= 1 && currrent_messages.length <= initialMessages.length) {
return;
}

console.log("deleting: " + JSON.stringify(thread));

threads = deleteThreadFromThreads(thread.id);
if (threads && threads.length > 0) {
const current_thread = getStoredActiveThread();
const candidate_thread = threads[0];
const candidateThread = threads[0];

if (candidate_thread && candidate_thread !== current_thread) {
switchActiveThread(candidate_thread);
if (candidateThread && candidateThread !== current_thread) {
switchActiveThread(candidateThread);
}

} else {
newThreadAndSwitch();
}
Expand All @@ -122,7 +134,8 @@

await setThread(thread);
keyAsstAndThread = await getKeyAsstAndThread();
chat_name = thread.name;
selectedThreadId = keyAsstAndThread[2].id;
chatName = thread.name;

// reload messages
const deepChatRef = document.getElementById('chat-element');
Expand Down Expand Up @@ -187,10 +200,10 @@
<li>After you send your first message to BIDARA, it will also be available to interact with through the <a href="https://platform.openai.com/assistants">OpenAI Assistants Playground</a>. This interface is more complex, but also provides more customizability. Just select BIDARA, then click the 'Test' button.</li>
</ul>
</div>
<Navbar bind:chat_name bind:sidebar={open} handleRename={renameActiveThread}/>
<Navbar bind:chat_name={chatName} bind:sidebar={open} handleRename={renameActiveThread}/>
<div id="content-container" class:open>
{#key threads.length}
<Sidebar handleChatSelect={switchActiveThread} handleChatDelete={deleteThreadAndSwitch} handleChatNew={newThreadAndSwitch} bind:threads bind:open/>
{#key selectedThreadId}
<Sidebar handleChatSelect={switchActiveThread} handleChatDelete={deleteThreadAndSwitch} handleChatNew={newThreadAndSwitch} bind:threads bind:open bind:selectedThreadId/>
{/key}
<div id="chat-container">
<!-- demo/textInput are examples of passing an object directly into a property -->
Expand Down
99 changes: 58 additions & 41 deletions src/Chat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
export let handleClick = null;
export let handleDelete = null;

export let selected = false;

import { draggable } from 'svelte-agnostic-draggable'

Expand All @@ -20,91 +21,115 @@

let wasDragged = false
let width;
let deleteThresh;
let maxDrag;
let position;
const chatId = "chat-"+thread.id;
const trashId = "trash-"+thread.id;

function onMouseDown () {
wasDragged = false;
}

function onDragStart (event) {
width = event.target.offsetWidth;
width = event.target.clientWidth;
deleteThresh = width * (1/2);
maxDrag = width * (3/4);
touching = true;
wasDragged = true;
}

function onDrag(event) {
if (!touching || !wasDragged) return;


position = event.detail.position.left;
deltaX = (-1) * (position - initialLeft);

if (deltaX <= 0) {
event.preventDefault();
event.detail.position.left = 0;
console.log("clicked under thresh");
event.detail.position.top = 0;
} else if ( deltaX >= maxDrag ) {
event.detail.position.left = (-1) * maxDrag;

} else if (deltaX >= deleteThresh) {
const trashImage = document.getElementById(trashId);
trashImage.style.transition = 'margin-right 0.3s ease';
trashImage.style.marginRight = deleteThresh + 'px';

} else {
const trashImage = document.getElementById(trashId);
trashImage.style.transition = 'margin-right 0.3s ease';
trashImage.style.marginRight = '1em';
}
}

function onMouseUp (event) {
function onMouseUp () {
if (! wasDragged) {
console.log("clicked");

handleClick(thread);
}

const deltaX = (-1) * (position - initialLeft);
deltaX = (-1) * (position - initialLeft);

const delete_thresh = width * (1/2);
if (deltaX >= delete_thresh) {
if (deltaX >= deleteThresh) {
handleDelete(thread);
}

const trashImage = document.getElementById(trashId);
trashImage.style.transition = 'margin-right 0.3s ease';
trashImage.style.marginRight = '1em';

touching = false;
}
</script>

<a class="container">
<div class="draggable innner-container chat-text flex justify-between items-center py-0" class:touching use:draggable={{axis:'x', revert: 'true', revertDuration:'200'}} on:mousedown={onMouseDown} on:mouseup={onMouseUp} on:drag:start={onDragStart} on:drag:move={onDrag}>
<p class="chat-button my-0 text-base font-sans block w-full focus:outline-none" class:open>{thread.name}</p>
<img class="drag-image" src="chevron-right-blue.svg" alt="drag"/>
</div>
<a class="chat-trash-container">
<a id={chatId} class="draggable chat-button flex justify-between items-center py-0" class:selected class:touching use:draggable={{axis:'x', revert: 'true', revertDuration:'200'}} on:mousedown={onMouseDown} on:mouseup={onMouseUp} on:drag:start={onDragStart} on:drag:move={onDrag}>
<p class="chat-text draggable my-0 text-base font-sans block w-full focus:outline-none" use:draggable={{disabled: 'true'}} on:mousedown={onMouseDown} on:mouseup={onMouseUp} on:drag:start={onDragStart} on:drag:move={onDrag}>{thread.name}</p>
<img class="drag-image draggable" src="grip-lines-vertical-gray.svg" alt="drag" use:draggable={{disabled: 'true'}} on:mousedown={onMouseDown} on:mouseup={onMouseUp} on:drag:start={onDragStart} on:drag:move={onDrag}/>
</a>
<div id="trash" class="trash flex justify-end items-center">
<img class="trash-image" src="trash-can-white.svg" alt="trash"/>
<img id={trashId} class="trash-image" src="trash-can-white.svg" alt="trash"/>
</div>
</a>

<style>
.chat-button {
.chat-text {
overflow: hidden;
margin-right: 1em;
text-overflow: ellipsis;
white-space: nowrap;
}

.chat-button:active,
.chat-button:hover,
.chat-button:-moz-drag-over {
background-color: rgba(0,0,0,0);
cursor: pointer;
}

.draggable {
left: 0;
cursor: grab; pointer-events: auto;
z-index: 11;
-webkit-touch-callout:none;
-ms-touch-action:none; touch-action:none;
-moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; user-select:none;
}

.container {
.chat-trash-container {
position: relative;
border-bottom: 2px solid black;
cursor: pointer;
transition: margin-right 0.3s ease;
}

.selected {
background-color: rgb(0, 122, 255) !important;
color: rgb(242, 242, 247) !important;
}

.chat-text {

.chat-button {
left: 0;
padding: 1em;
z-index: 10;
background-color: rgb(229, 229, 234);
border-bottom: 1px solid rgb(199, 199, 204);
transition: background-color 0.1s ease;
cursor: pointer;
}

.trash-image {
Expand All @@ -116,30 +141,22 @@
.drag-image {
width: 15px;
height: 15px;
color: red;
transform: rotate(180deg);
cursor: grab;
margin-right: 0.2em;
transition: margin-right 0.3s ease;
}

.trash {
z-index: 9;
position: absolute;
z-index: 9;
height: 100%;
width: 100%;
left: 0;
top: 0;
background-color: rgb(255, 59, 48);
transition: background-color 0.3s ease;
}

.inner-container {
z-index: 10;
left: 0;
top: 0;
position: absolute;
}

.inner-container:hover,
.inner-container:focus,
.touching {
background-color: rgb(0, 122, 255);
transition: margin-right 0.3s ease;
border-bottom: 1px solid rgb(174, 174, 178);
}
</style>
7 changes: 7 additions & 0 deletions src/Hamburger.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,11 @@
transform: rotate(180deg);
}

@media only screen and (max-width: 700px) {
.container {
margin-right: 0;
}
}


</style>
3 changes: 0 additions & 3 deletions src/Navbar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@
header {
z-index: 10;
border-bottom: 1px solid rgb(229, 229, 234);
}

button {
padding: 0.5em;
}

Expand Down
26 changes: 23 additions & 3 deletions src/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,32 @@
export let handleChatSelect = null;
export let handleChatDelete = null
export let handleChatNew = null;
export let selectedThreadId = true;

import Chat from './Chat.svelte'

async function handleButtonClick(event) {
event.target.style.transition = 'background-color 0.2s ease color 0.2s ease';
event.target.style.backgroundColor = 'rgb(209,209,214)';

handleChatNew();

setTimeout(() => {
event.target.style.backgroundColor = 'rgb(242, 242, 247)';
}, 200);
}

</script>

<aside class="absolute full shadow-lg flex flex-col justify-between" class:open>
<nav class="w-full">
{#if threads !== null}
{#each threads as thread}
<Chat handleClick={handleChatSelect} handleDelete={handleChatDelete} bind:thread/>
<Chat handleClick={handleChatSelect} handleDelete={handleChatDelete} bind:thread selected={thread.id === selectedThreadId}/>
{/each}
{/if}
</nav>
<button class="new-thread text-base font-sans bg-gray-400 p-2 focus:outline-none" on:click={handleChatNew}>New Thread</button>
<button class="new-thread mx-2 text-base font-sans p-2 focus:outline-none" on:click={handleButtonClick}>New Thread</button>
</aside>

<style>
Expand All @@ -29,9 +41,14 @@
left: -20%;
margin-top: -1px;
transition: ease 0.3s;
background-color: rgba(229, 229, 234);
background-color: rgb(229, 229, 234);
border-right: 1px solid rgb(209, 209, 214);
}


button {
transition: background-color 0.3s ease;
}

.open {
left: 0;
Expand Down Expand Up @@ -60,5 +77,8 @@
.open {
width: 100%;
}
aside {
border-right: none;
}
}
</style>