Skip to content

Commit

Permalink
NcAppNavigation popover fix
Browse files Browse the repository at this point in the history
Signed-off-by: Anupam Kumar <[email protected]>
  • Loading branch information
kyteinsky committed Jun 18, 2024
1 parent c07eabb commit 6769997
Show file tree
Hide file tree
Showing 4 changed files with 374 additions and 37 deletions.
2 changes: 1 addition & 1 deletion lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class Application extends App implements IBootstrap {
public const TASK_CATEGORY_SPEECH_TO_TEXT = 2;

public const CHAT_USER_INSTRUCTIONS = 'This is a conversation in a specific language between {user} and you, Nextcloud Assistant. You are a kind, polite and helpful AI that helps {user} to the best of its abilities. If you do not understand something, you will ask for clarification. Detect the language that {user} is using. Make sure to use the same language in your response. Do not mention the language explicitly.';
public const CHAT_USER_INSTRUCTIONS_TITLE = 'Above is a chat session in a specific language between {user} and you, Nextcloud Assistant. Generate a suitable title summarizing the conversation in the same language and output only that.';
public const CHAT_USER_INSTRUCTIONS_TITLE = 'Above is a chat session in a specific language between {user} and you, Nextcloud Assistant. Generate a suitable title summarizing the conversation in the same language. Output only the title in plain text, nothing else.';

public function __construct(array $urlParams = []) {
parent::__construct(self::APP_ID, $urlParams);
Expand Down
107 changes: 71 additions & 36 deletions src/components/ChattyLLM/ChattyLLMInputForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,10 @@
:name="getSessionTitle(session)"
:title="getSessionTitle(session)"
:aria-description="getSessionTitle(session)"
:editable="true"
:edit-label="t('assistant', 'Edit Title')"
@click="onSessionSelect(session)"
@update:name="(newTitle) => onEditSessionTitle(session.id, newTitle)">
:editable="false"
:inline-actions="1"
@click="onSessionSelect(session)">
<template #actions>
<NcActionButton @click="onGenerateSessionTitle(session.id)">
<template #icon>
<AutoFixIcon v-if="!loading.titleGeneration" :size="20" />
<NcLoadingIcon v-else :size="20" />
</template>
{{ t('assistant', 'Generate Title') }}
</NcActionButton>
<NcActionButton @click="deleteSession(session.id)">
<template #icon>
<DeleteIcon v-if="!loading.sessionDelete" :size="20" />
Expand All @@ -49,7 +41,33 @@
</NcAppNavigation>
<NcAppContent class="session-area">
<div class="session-area__top-bar">
{{ getSessionTitle(active) }}
<div class="session-area__top-bar__title">
<EditableTextField v-if="active != null"
:initial-text="getSessionTitle(active)"
:editing.sync="editingTitle"
:placeholder="t('assistant', 'Conversation title')"
:edit-button-aria-label="t('assistant', 'Edit title')"
:loading="loading.updateTitle"
:max-length="140"
@submit-text="onEditSessionTitle" />
</div>
<div v-if="active != null" class="session-area__top-bar__actions">
<NcActions :open.sync="titleActionsOpen">
<NcActionButton :disabled="loading.titleGeneration || editingTitle" @click="onEditSessionTitleClick">
<template #icon>
<PencilIcon :size="20" />
</template>
{{ t('assistant', 'Edit Title') }}
</NcActionButton>
<NcActionButton :disabled="loading.titleGeneration || editingTitle" @click="onGenerateSessionTitle">
<template #icon>
<AutoFixIcon v-if="!loading.titleGeneration" :size="20" />
<NcLoadingIcon v-else :size="20" />
</template>
{{ t('assistant', 'Generate Title') }}
</NcActionButton>
</NcActions>
</div>
</div>
<div class="session-area__chat-area">
<NoSession v-if="loading.newSession"
Expand Down Expand Up @@ -110,11 +128,13 @@
<script>
import AutoFixIcon from 'vue-material-design-icons/AutoFix.vue'
import DeleteIcon from 'vue-material-design-icons/Delete.vue'
import PencilIcon from 'vue-material-design-icons/Pencil.vue'
import PlusIcon from 'vue-material-design-icons/Plus.vue'
import AssistantIcon from '../icons/AssistantIcon.vue'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js'
import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js'
import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js'
Expand All @@ -124,6 +144,7 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import ConversationBox from './ConversationBox.vue'
import EditableTextField from './EditableTextField.vue'
import InputArea from './InputArea.vue'
import NoSession from './NoSession.vue'
Expand All @@ -146,11 +167,13 @@ export default {
components: {
AutoFixIcon,
DeleteIcon,
PencilIcon,
PlusIcon,
AssistantIcon,
NcActionButton,
NcActions,
NcAppContent,
NcAppNavigation,
NcAppNavigationItem,
Expand All @@ -160,6 +183,7 @@ export default {
NcLoadingIcon,
ConversationBox,
EditableTextField,
InputArea,
NoSession,
},
Expand All @@ -179,13 +203,16 @@ export default {
olderMessages: false,
llmGeneration: false,
titleGeneration: false,
updateTitle: false,
newHumanMessage: false,
newSession: false,
messageDelete: false,
sessionDelete: false,
},
msgCursor: 0,
msgLimit: 20,
titleActionsOpen: false,
editingTitle: false,
}
},
Expand All @@ -195,6 +222,7 @@ export default {
this.chatContent = ''
this.msgCursor = 0
this.messages = []
this.editingTitle = false
this.$refs.inputComponent.focus()
if (this.active != null && !this.loading.newSession) {
Expand Down Expand Up @@ -233,14 +261,27 @@ export default {
this.active = session
},
onEditSessionTitle(sessionId, newTitle) {
console.debug(sessionId, newTitle)
for (const session of this.sessions) {
if (session.id === sessionId) {
session.title = newTitle
this.updateTitle(sessionId, newTitle)
break
}
onEditSessionTitleClick() {
this.editingTitle = true
this.titleActionsOpen = false
},
async onEditSessionTitle(newTitle) {
this.loading.updateTitle = true
const session = this.sessions.find((session) => session.id === this.active.id)
try {
await axios.patch(getChatURL('/update_session'), {
sessionId: this.active.id,
title: newTitle,
})
this.editingTitle = false
session.title = newTitle
} catch (error) {
console.error('updateTitle error:', error)
showError(error?.response?.data?.error ?? t('assistant', 'Error updating conversations\'s title'))
} finally {
this.loading.updateTitle = false
}
},
Expand Down Expand Up @@ -288,28 +329,16 @@ export default {
this.fetchMessages(true)
},
async updateTitle(sessionId, title) {
try {
await axios.patch(getChatURL('/update_session'), {
sessionId,
title,
})
} catch (error) {
console.error('updateTitle error:', error)
showError(error?.response?.data?.error ?? t('assistant', 'Error updating session title'))
}
},
async onGenerateSessionTitle(sessionId) {
async onGenerateSessionTitle() {
try {
this.loading.titleGeneration = true
const response = await axios.get(getChatURL('/generate_title'), { params: { sessionId } })
const response = await axios.get(getChatURL('/generate_title'), { params: { sessionId: this.active.id } })
if (response?.data?.result == null) {
throw new Error('No title generated')
throw new Error('No title generated, response:', response)
}
for (const session of this.sessions) {
if (session.id === sessionId) {
if (session.id === this.active.id) {
session.title = response?.data?.result
break
}
Expand Down Expand Up @@ -632,15 +661,21 @@ export default {
&__top-bar {
display: flex;
justify-content: space-between;
align-items: center;
position: sticky;
top: 0;
height: 60px;
box-sizing: border-box;
border-bottom: 1px solid var(--color-border);
padding-left: 4.5em;
padding-right: 0.5em;
font-weight: bold;
background-color: var(--color-main-background);
&__title {
width: 100%;
}
}
&__chat-area {
Expand Down
Loading

0 comments on commit 6769997

Please sign in to comment.