blob: 6d34d0fab0d7d974ff4b834aec5b33d4b4f8c464 [file] [log] [blame] [edit]
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import '../shared/gr-date-formatter/gr-date-formatter';
import '../shared/gr-icon/gr-icon';
import {css, html, LitElement} from 'lit';
import {customElement, state} from 'lit/decorators.js';
import {Conversation} from '../../api/ai-code-review';
import {chatModelToken} from '../../models/chat/chat-model';
import {resolve} from '../../models/dependency';
import {dateToTimestamp} from '../../utils/date-util';
import {subscribe} from '../lit/subscription-controller';
@customElement('chat-history')
export class ChatHistory extends LitElement {
private readonly getChatModel = resolve(this, chatModelToken);
@state() conversations: readonly Conversation[] = [];
constructor() {
super();
subscribe(
this,
() => this.getChatModel().conversations$,
conversations => (this.conversations = conversations ?? [])
);
}
static override styles = css`
.conversation-card {
width: 85%;
margin: 0 auto;
padding: var(--spacing-m);
padding-left: 0px;
display: flex;
flex-direction: row;
border-bottom: 1px solid var(--hairline);
cursor: pointer;
user-select: none;
}
.conversation-card * {
cursor: pointer;
}
.conversation-card:hover {
background-color: var(--background-color-secondary);
}
.conversation-icon {
margin-top: var(--spacing-s);
}
.conversation-content {
margin-left: var(--spacing-xxl);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
min-width: 0;
}
.conversation-content p {
margin: 0px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
}
.conversation-content p.ts {
margin-top: var(--spacing-m);
color: var(--deemphasized-text-color);
}
`;
override render() {
if (this.conversations.length === 0) {
return html`<div>No conversations found.</div>`;
}
return html`
${this.conversations.map(
conversation => html`
<div
class="conversation-card"
@click=${() => this.loadConversation(conversation)}
>
<div class="conversation-icon">
<gr-icon icon="history"></gr-icon>
</div>
<div class="conversation-content">
<p>${conversation.title}</p>
<p class="ts">
<gr-date-formatter
withTooltip
.dateStr=${dateToTimestamp(
new Date(conversation.timestamp_millis)
)}
></gr-date-formatter>
</p>
</div>
</div>
`
)}
`;
}
// visible for testing
loadConversation(conversation: Conversation) {
this.getChatModel().loadConversation(conversation.id);
}
}
declare global {
interface HTMLElementTagNameMap {
'chat-history': ChatHistory;
}
}