Skip to content

Commit

Permalink
feat: added search, favorites, and overhauled sidebars (#42)
Browse files Browse the repository at this point in the history
* feat: added search, favorites, and overhauled sidebars

* fix: correct header on settings
  • Loading branch information
henrycunh authored Apr 26, 2023
1 parent a6d7155 commit bcb716b
Show file tree
Hide file tree
Showing 28 changed files with 528 additions and 240 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
- 💠 Cross device synchronisation
- 🍻 Share chat history

[
![](https://raw.githubusercontent.com/deta/community-content/main/Install-Button/light.svg#gh-light-mode-only)
![](https://raw.githubusercontent.com/deta/community-content/main/Install-Button/dark.svg#gh-dark-mode-only)
](https://deta.space/discovery/@henrycunh/golem)

## 🛠 Configuration
You can use **environment variables** to customize your instance.
Expand Down
5 changes: 3 additions & 2 deletions app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ useHead({

<style>
body {
@apply dark:bg-dark-4 light:bg-gray-1/40 transition;
@apply dark:bg-dark-4 light:bg-#FAFAFB transition;
margin: 0;
/* background-color: #f9fafb; */
font-family: ColfaxAI, -system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none !important;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
15 changes: 9 additions & 6 deletions components/app-chat/header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defineProps<{
const { currentConversation, updateConversation } = useConversations()
const { isDetaEnabled } = useDeta()
const { isOnSharePage } = useSession()
const conversationTitle = ref<string>(currentConversation.value?.title || '')
const isEditingTitle = ref(false)
Expand Down Expand Up @@ -46,8 +47,7 @@ function onFavoriteConversation() {

<template>
<div
v-if="!embedded"
absolute top-0 left-0 right-0 b-0 b-b-1 b-gray-1 dark:b-dark-1 b-solid py-3
absolute top-0 left-0 right-0 b="solid 0 b-1 dark:white/10 dark-1/10" py-3
z-1
backdrop-blur-4
mx-auto
Expand All @@ -60,11 +60,11 @@ function onFavoriteConversation() {
<div>
<div flex items-center gap-1>
<Transition name="appear-left">
<div v-if="isEditingTitle" i-tabler-edit text-18px text-color mr-1 />
<div v-if="isEditingTitle && !isOnSharePage" i-tabler-edit text-18px text-color mr-1 />
</Transition>
<Transition name="appear-left">
<div
v-if="!isEditingTitle"
v-if="!isEditingTitle && !isOnSharePage"
text-5 mr-1
cursor-pointer
hover:scale-120
Expand All @@ -85,10 +85,13 @@ function onFavoriteConversation() {
bg-transparent border-none outline-none p-0
transition font-bold grow mr-3 truncate
text-14px sm:text-18px h-1.75em
min-w-50dvw
:class="[
isEditingTitle
? 'text-gray-900 dark:text-gray-1 select-all'
: 'text-gray-700 dark:text-gray-3 select-none cursor-pointer',
: 'text-gray-700 dark:text-gray-3 select-none',
isEditingTitle && !isOnSharePage && 'cursor-pointer',
isOnSharePage && 'w-94dvw',
]"
@blur="isEditingTitle = false"
@input="onInput"
Expand All @@ -98,7 +101,7 @@ function onFavoriteConversation() {
</div>
<!-- TODO: implement sharing -->
<UButton
v-if="!embedded && isDetaEnabled" ml-auto icon="i-tabler-share"
v-if="!isOnSharePage && isDetaEnabled" ml-auto icon="i-tabler-share"
@click="onShare"
>
Share
Expand Down
3 changes: 1 addition & 2 deletions components/app-chat/history-container.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ function onFileDrop(event: any) {
h-full overflow-y-auto pb-50
z-0
:class="[
embedded && '!pt-2',
isOnSharePage && '!pt-6',
isOnSharePage && '!pt-16',
]"
@dragover.prevent @drop="onFileDrop"
>
Expand Down
4 changes: 1 addition & 3 deletions components/app-chat/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ const { isOnSharePage } = useSession()

<template>
<div>
<AppChatHeader
:embedded="embedded"
/>
<AppChatHeader />
<AppChatHistory
:embedded="embedded"
/>
Expand Down
22 changes: 1 addition & 21 deletions components/app-chat/prompt.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts" setup>
const { sendMessage, isTypingInCurrentConversation, stopConversationMessageGeneration, currentConversation } = useConversations()
const { sendMessage } = useConversations()
const { isMobile } = useDevice()
const { apiKey } = useSettings()
Expand Down Expand Up @@ -27,14 +27,6 @@ function onHandlePromptClick() {
}
}
}
function onStopGenerationClick() {
if (!currentConversation.value) {
return
}
stopConversationMessageGeneration(currentConversation.value.id)
}
</script>

<template>
Expand Down Expand Up @@ -65,18 +57,6 @@ function onStopGenerationClick() {
@send="onSendMessage"
@click="onHandlePromptClick"
/>
<Transition name="appear-top">
<div
v-if="isTypingInCurrentConversation"
absolute top-2
right-18 sm:right-20 lg:right-30
>
<UButton @click="onStopGenerationClick">
<div i-tabler-player-stop-filled text-3 sm:text-5 />
<span text-10px sm:text-4>Stop talking!</span>
</UButton>
</div>
</Transition>
</div>
<AppChatScrollToBottomButton />
</div>
Expand Down
39 changes: 39 additions & 0 deletions components/app-messages-sidebar/favorite-conversations.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<script lang="ts" setup>
const { conversationList } = useConversations()
const { filterConversationsBySearchTerm } = useSearch()
const conversationsSortedByUpdatedAt = computed(() => {
if (conversationList.value === null) {
return null
}
return filterConversationsBySearchTerm(conversationList.value)
.filter(conversation => conversation.metadata?.favorite)
.sort((a, b) => {
if (a.updatedAt === null) {
return 1
}
if (b.updatedAt === null) {
return -1
}
// Compare dates
return b.updatedAt.getTime() - a.updatedAt.getTime()
})
})
</script>

<template>
<div>
<div v-if="conversationsSortedByUpdatedAt?.length" uppercase font-bold font-text text-13px text-color-lighter my-2 flex items-center px-3>
Favorites
</div>
<div
max-h-100 overflow-y-auto overflow-x-hidden w-full pb-2
>
<ConversationTab
v-for="conversation in conversationsSortedByUpdatedAt"
:key="conversation.id"
:conversation="conversation"
/>
</div>
</div>
</template>
90 changes: 90 additions & 0 deletions components/app-messages-sidebar/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<script lang="ts" setup>
const {
createConversation,
switchConversation,
clearConversations,
} = useConversations()
const { apiKey } = useSettings()
const { isSidebarCompact } = useUI()
const colorMode = useColorMode()
const onCreateConversation = async () => {
const newConversation = await createConversation('Untitled Conversation')
await switchConversation(newConversation.id)
}
const isSearchBarVisible = ref(false)
function onToggleSearchBar() {
isSearchBarVisible.value = !isSearchBarVisible.value
}
</script>

<template>
<div
h-full flex-col flex
b-0 b-r-1 b-solid b="dark:white/15 dark-1/10"
>
<div text-color font-bold font-title text-5 px-3 my-4 flex items-center>
<div>
Messages
</div>

<UButton
secondary
:icon="`${isSearchBarVisible ? 'i-tabler-search-off' : 'i-tabler-message-search'} text-18px`"
ml-auto @click="onToggleSearchBar"
/>
</div>

<Transition name="fade">
<div
v-if="isSearchBarVisible"
px-3 mb-4
>
<SearchBar w-full text-16px font-text />
</div>
</Transition>

<AppMessagesSidebarFavoriteConversations />
<AppMessagesSidebarRecentConversations />
<div mt-auto>
<div flex="~ col" children:grow gap-3 mt-2 px-3>
<UButton
secondary icon="i-tabler-plus"
@click="onCreateConversation"
>
New chat
</UButton>
<GpLongPressButton
:duration="1500"
icon="i-tabler-arrow-bar-to-up"
progress-bar-style="bg-red/50"
success-style="!ring-red"
@success="clearConversations"
>
Clear all
</GpLongPressButton>
</div>
<SidebarApiKeyAlert
v-if="!apiKey"
mt-3 mx-2
@click="navigateTo('/settings/api-key')"
/>
<div
text-color-lighter my-6 text-5 tracking--1px w-full
flex justify-center items-center
>
<img
:src="
isSidebarCompact
? `/image/logo-${colorMode.value}-square-transparent.svg`
: `/image/logo-${colorMode.value}-lettered.svg`
"
:class="[isSidebarCompact ? 'w-12' : 'w-24']" op-60
>
</div>
</div>
</div>
</template>
52 changes: 52 additions & 0 deletions components/app-messages-sidebar/recent-conversations.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script lang="ts" setup>
const { conversationList } = useConversations()
const { filterConversationsBySearchTerm } = useSearch()
const conversationsSortedByUpdatedAt = computed(() => {
if (conversationList.value === null) {
return null
}
return filterConversationsBySearchTerm(conversationList.value)
.filter(conversation => !conversation.metadata?.favorite)
.sort((a, b) => {
if (a.updatedAt === null) {
return 1
}
if (b.updatedAt === null) {
return -1
}
// Compare dates
return b.updatedAt.getTime() - a.updatedAt.getTime()
})
})
</script>

<template>
<div>
<div uppercase font-bold font-text text-13px text-color-lighter my-2 flex items-center px-3>
Recent
</div>
<div
v-if="conversationsSortedByUpdatedAt?.length" max-h-100 overflow-y-auto overflow-x-hidden w-full
pb-2
>
<ConversationTab
v-for="conversation in conversationsSortedByUpdatedAt"
:key="conversation.id"
:conversation="conversation"
w-full
/>
</div>
<div v-else>
<div text-color flex="~ col" items-center justify-center gap-1 op-40>
<div i-tabler-file-off text-7 />
<div font-bold font-title>
No results
</div>
<div text-3>
Try a different search term
</div>
</div>
</div>
</div>
</template>
Loading

0 comments on commit bcb716b

Please sign in to comment.