/ src / renderer / screens / chat / ChatHistoryScreen.vue
ChatHistoryScreen.vue
 1  <script setup lang="ts">
 2  import { computed } from 'vue'
 3  import { useHistoryStore } from '@/renderer/store/history'
 4  import { useMessageStore } from '@/renderer/store/message'
 5  import { ChatConversationMessage } from '@/renderer/types/message'
 6  const historyStore = useHistoryStore()
 7  const messageStore = useMessageStore()
 8  
 9  function parseContent(content: undefined | string | ChatConversationMessage['content']) {
10    if (typeof content === 'string') {
11      return content
12    } else if (Array.isArray(content)) {
13      for (const item of content) {
14        if (item.type === 'text') {
15          return item.text
16        }
17      }
18      return 'NA'
19    } else {
20      return content
21    }
22  }
23  
24  const selectedConversation = computed({
25    get: () => [messageStore.conversation.id],
26    set: ([value]) => {
27      historyStore.select(value)
28    }
29  })
30  </script>
31  <template>
32    <v-list v-model:selected="selectedConversation" nav>
33      <v-list-item
34        v-for="(item, index) in historyStore.conversations"
35        :key="item.id"
36        :ripple="false"
37        two-line
38        :value="item.id"
39        link
40        :title="parseContent(item.messages[0]?.content)"
41        :subtitle="parseContent(item.messages.at(-1)?.content)"
42      >
43        <template #append>
44          <v-list-item-action>
45            <v-icon-btn
46              class="mr-1"
47              color="error"
48              variant="plain"
49              icon="mdi-delete-outline"
50              rounded="lg"
51              size="small"
52              :loading="item.id in messageStore.generating"
53              @click="historyStore.deleteById(index)"
54            >
55            </v-icon-btn>
56          </v-list-item-action>
57        </template>
58      </v-list-item>
59    </v-list>
60  </template>