|
1 | 1 | <script>
|
| 2 | + import { afterUpdate, beforeUpdate, onDestroy, onMount, tick } from 'svelte'; |
| 3 | + import { page } from '$app/stores'; |
| 4 | + import moment from 'moment'; |
| 5 | + import { v4 as uuidv4 } from 'uuid'; |
2 | 6 | import 'overlayscrollbars/overlayscrollbars.css';
|
3 | 7 | import { OverlayScrollbars } from 'overlayscrollbars';
|
4 |
| - import { afterUpdate, beforeUpdate, onDestroy, onMount } from 'svelte'; |
5 |
| - import { page } from '$app/stores'; |
6 |
| - import { GetContentLogs, GetStateLogs } from '$lib/services/logging-service'; |
| 8 | + import { getContentLogs, getStateLogs } from '$lib/services/logging-service'; |
7 | 9 | import NavBar from '$lib/common/nav-bar/NavBar.svelte';
|
8 | 10 | import NavItem from '$lib/common/nav-bar/NavItem.svelte';
|
9 | 11 | import ContentLogElement from './content-log-element.svelte';
|
10 | 12 | import ConversationStateLogElement from './conversation-state-log-element.svelte';
|
11 |
| -
|
| 13 | + |
12 | 14 | const contentLogTab = 1;
|
13 | 15 | const conversationStateLogTab = 2;
|
| 16 | + const conversationId = $page.params.conversationId; |
| 17 | + const utcNow = moment.utc().toDate(); |
| 18 | +
|
| 19 | + const scrollbarElements = [ |
| 20 | + { |
| 21 | + id: '.content-log-scrollbar', |
| 22 | + type: contentLogTab, |
| 23 | + }, |
| 24 | + { |
| 25 | + id: '.conv-state-log-scrollbar', |
| 26 | + type: conversationStateLogTab, |
| 27 | + } |
| 28 | + ]; |
14 | 29 |
|
15 | 30 | /** @type {import('$conversationTypes').ConversationContentLogModel[]} */
|
16 | 31 | export let contentLogs = [];
|
|
36 | 51 | let selectedTab = contentLogTab;
|
37 | 52 | let tabChanged = false;
|
38 | 53 |
|
| 54 | + /** @type {import('$conversationTypes').ConversationLogFilter} */ |
| 55 | + let contentLogFilter = { size: 20, startTime: utcNow }; |
| 56 | + /** @type {import('$conversationTypes').ConversationLogFilter} */ |
| 57 | + let stateLogFilter = { size: 20, startTime: utcNow }; |
| 58 | +
|
39 | 59 | const options = {
|
40 | 60 | scrollbars: {
|
41 | 61 | visibility: 'auto',
|
|
49 | 69 | };
|
50 | 70 |
|
51 | 71 | onMount(async () => {
|
52 |
| - const conversationId = $page.params.conversationId; |
53 |
| - contentLogs = await GetContentLogs(conversationId); |
54 |
| - convStateLogs = await GetStateLogs(conversationId); |
55 |
| - lastestStateLog = convStateLogs.slice(-1)[0]; |
56 |
| -
|
57 |
| - const scrollbarElements = [ |
58 |
| - document.querySelector('.content-log-scrollbar'), |
59 |
| - document.querySelector('.conv-state-log-scrollbar') |
60 |
| - ].filter(Boolean); |
61 |
| - scrollbarElements.forEach(elem => { |
62 |
| - scrollbars = [ ...scrollbars, OverlayScrollbars(elem, options) ]; |
63 |
| - }); |
| 72 | + await getChatContentLogs(); |
| 73 | + await getChatStateLogs(); |
| 74 | +
|
| 75 | + initScrollbars(); |
64 | 76 | scrollToBottom();
|
65 | 77 | });
|
66 | 78 |
|
|
95 | 107 | }, 200);
|
96 | 108 | });
|
97 | 109 | }
|
| 110 | +
|
| 111 | + function initScrollbars() { |
| 112 | + scrollbarElements.forEach(item => { |
| 113 | + const elem = document.querySelector(item.id); |
| 114 | + if (!elem) return; |
| 115 | +
|
| 116 | + const scrollbar = OverlayScrollbars(elem, options); |
| 117 | + scrollbar.on("scroll", async (e) => { |
| 118 | + const curScrollTop = e.elements().scrollOffsetElement.scrollTop; |
| 119 | + if (curScrollTop <= 1) { |
| 120 | + tabChanged = true; |
| 121 | + if (item.type === contentLogTab) { |
| 122 | + await getChatContentLogs(); |
| 123 | + } else if (item.type === conversationStateLogTab) { |
| 124 | + await getChatStateLogs(); |
| 125 | + } |
| 126 | + } |
| 127 | + }); |
| 128 | +
|
| 129 | + scrollbars = [ ...scrollbars, scrollbar]; |
| 130 | + }); |
| 131 | + } |
| 132 | +
|
| 133 | + async function getChatContentLogs() { |
| 134 | + if (!contentLogFilter.startTime) return; |
| 135 | +
|
| 136 | + const pagedContentLogs = await getContentLogs(conversationId, contentLogFilter); |
| 137 | + contentLogFilter = { |
| 138 | + ...contentLogFilter, |
| 139 | + startTime: pagedContentLogs.nextTime || null |
| 140 | + }; |
| 141 | + const newLogs = pagedContentLogs.items?.map(x => { |
| 142 | + return { uid: uuidv4(), ...x }; |
| 143 | + }) || []; |
| 144 | +
|
| 145 | + if (newLogs.length > 0) { |
| 146 | + contentLogs = [...newLogs, ...contentLogs]; |
| 147 | + } |
| 148 | + } |
| 149 | +
|
| 150 | + async function getChatStateLogs() { |
| 151 | + if (!stateLogFilter.startTime) return; |
| 152 | +
|
| 153 | + const pagedStateLogs = await getStateLogs(conversationId, stateLogFilter); |
| 154 | + stateLogFilter = { |
| 155 | + ...stateLogFilter, |
| 156 | + startTime: pagedStateLogs.nextTime || null |
| 157 | + }; |
| 158 | + const newLogs = pagedStateLogs.items?.map(x => { |
| 159 | + return { uid: uuidv4(), ...x }; |
| 160 | + }) || []; |
| 161 | +
|
| 162 | + if (newLogs.length > 0) { |
| 163 | + convStateLogs = [...newLogs, ...convStateLogs]; |
| 164 | + lastestStateLog = convStateLogs.slice(-1)[0]; |
| 165 | + } |
| 166 | + } |
98 | 167 |
|
99 | 168 | function cleanLogs() {
|
100 | 169 | contentLogs = [];
|
|
141 | 210 |
|
142 | 211 | <div class="content-log-scrollbar log-list padding-side log-body" class:hide={selectedTab !== contentLogTab}>
|
143 | 212 | <ul>
|
144 |
| - {#each contentLogs as log} |
| 213 | + {#each contentLogs as log (log.uid)} |
145 | 214 | <ContentLogElement data={log} />
|
146 | 215 | {/each}
|
147 | 216 | </ul>
|
148 | 217 | </div>
|
149 | 218 |
|
150 | 219 | <div class="conv-state-log-scrollbar log-list padding-side log-body" class:hide={selectedTab !== conversationStateLogTab}>
|
151 | 220 | <ul>
|
152 |
| - {#each convStateLogs as log} |
| 221 | + {#each convStateLogs as log (log.uid)} |
153 | 222 | <ConversationStateLogElement data={log} />
|
154 | 223 | {/each}
|
155 | 224 | </ul>
|
|
0 commit comments