mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 05:37:32 +00:00
fix(core): text style is not centered when chat-panel is wide (#10607)
Fix issue [BS-2751](https://linear.app/affine-design/issue/BS-2751). Before:  After: 
This commit is contained in:
@@ -11,7 +11,6 @@ import type { BaseSelection } from '@blocksuite/affine/store';
|
|||||||
import { css, html, nothing } from 'lit';
|
import { css, html, nothing } from 'lit';
|
||||||
import { property, query, state } from 'lit/decorators.js';
|
import { property, query, state } from 'lit/decorators.js';
|
||||||
import { repeat } from 'lit/directives/repeat.js';
|
import { repeat } from 'lit/directives/repeat.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
|
||||||
import { debounce } from 'lodash-es';
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -50,7 +49,7 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-panel-messages-placeholder {
|
.messages-placeholder {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
@@ -63,6 +62,47 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.messages-placeholder-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--affine-text-primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.messages-placeholder-title[data-loading='true'] {
|
||||||
|
font-size: var(--affine-font-sm);
|
||||||
|
color: var(--affine-text-secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.onboarding-wrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.onboarding-item {
|
||||||
|
display: flex;
|
||||||
|
height: 28px;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: start;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.onboarding-item-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.onboarding-item-text {
|
||||||
|
font-size: var(--affine-font-xs);
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--affine-text-primary-color);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.item-wrapper {
|
.item-wrapper {
|
||||||
margin-left: 32px;
|
margin-left: 32px;
|
||||||
}
|
}
|
||||||
@@ -73,14 +113,14 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
color: var(--affine-text-primary-color);
|
color: var(--affine-text-primary-color);
|
||||||
font-size: 14px;
|
font-size: var(--affine-font-sm);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-info {
|
.message-info {
|
||||||
color: var(--affine-placeholder-color);
|
color: var(--affine-placeholder-color);
|
||||||
font-size: 12px;
|
font-size: var(--affine-font-xs);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +166,7 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
|||||||
accessor _selectionValue: BaseSelection[] = [];
|
accessor _selectionValue: BaseSelection[] = [];
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
accessor showDownIndicator = false;
|
accessor canScrollDown = false;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
accessor avatarUrl = '';
|
accessor avatarUrl = '';
|
||||||
@@ -156,46 +196,32 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
|||||||
return this.messagesContainer;
|
return this.messagesContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get showDownIndicator() {
|
||||||
|
if (!this.messagesContainer) return false;
|
||||||
|
const { clientHeight, scrollTop, scrollHeight } = this.messagesContainer;
|
||||||
|
const canScrollDown = scrollHeight - scrollTop - clientHeight > 200;
|
||||||
|
const showDownIndicator =
|
||||||
|
canScrollDown &&
|
||||||
|
this.chatContextValue.items.length > 0 &&
|
||||||
|
this.chatContextValue.status !== 'transmitting';
|
||||||
|
return showDownIndicator;
|
||||||
|
}
|
||||||
|
|
||||||
private _renderAIOnboarding() {
|
private _renderAIOnboarding() {
|
||||||
return this.isLoading ||
|
return this.isLoading ||
|
||||||
!this.host?.doc.get(FeatureFlagService).getFlag('enable_ai_onboarding')
|
!this.host?.doc.get(FeatureFlagService).getFlag('enable_ai_onboarding')
|
||||||
? nothing
|
? nothing
|
||||||
: html`<div
|
: html`<div class="onboarding-wrapper">
|
||||||
style=${styleMap({
|
|
||||||
display: 'flex',
|
|
||||||
gap: '8px',
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'center',
|
|
||||||
marginTop: '16px',
|
|
||||||
width: '100%',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
${repeat(
|
${repeat(
|
||||||
AIPreloadConfig,
|
AIPreloadConfig,
|
||||||
config => config.text,
|
config => config.text,
|
||||||
config => {
|
config => {
|
||||||
return html`<div
|
return html`<div
|
||||||
@click=${() => config.handler()}
|
@click=${() => config.handler()}
|
||||||
style=${styleMap({
|
class="onboarding-item"
|
||||||
display: 'flex',
|
|
||||||
height: '28px',
|
|
||||||
gap: '8px',
|
|
||||||
width: '88%',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'start',
|
|
||||||
cursor: 'pointer',
|
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
${config.icon}
|
<div class="onboarding-item-icon">${config.icon}</div>
|
||||||
<div
|
<div class="onboarding-item-text">${config.text}</div>
|
||||||
style=${styleMap({
|
|
||||||
fontSize: '12px',
|
|
||||||
fontWeight: '400',
|
|
||||||
color: 'var(--affine-text-primary-color)',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
${config.text}
|
|
||||||
</div>
|
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
@@ -205,7 +231,7 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
|||||||
private readonly _onScroll = () => {
|
private readonly _onScroll = () => {
|
||||||
if (!this.messagesContainer) return;
|
if (!this.messagesContainer) return;
|
||||||
const { clientHeight, scrollTop, scrollHeight } = this.messagesContainer;
|
const { clientHeight, scrollTop, scrollHeight } = this.messagesContainer;
|
||||||
this.showDownIndicator = scrollHeight - scrollTop - clientHeight > 200;
|
this.canScrollDown = scrollHeight - scrollTop - clientHeight > 200;
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly _debouncedOnScroll = debounce(
|
private readonly _debouncedOnScroll = debounce(
|
||||||
@@ -225,28 +251,19 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return html`<style>
|
return html`
|
||||||
.chat-panel-messages-placeholder div {
|
|
||||||
color: ${isLoading
|
|
||||||
? 'var(--affine-text-secondary-color)'
|
|
||||||
: 'var(--affine-text-primary-color)'};
|
|
||||||
font-size: ${isLoading ? 'var(--affine-font-sm)' : '18px'};
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="chat-panel-messages"
|
class="chat-panel-messages"
|
||||||
@scroll=${() => this._debouncedOnScroll()}
|
@scroll=${() => this._debouncedOnScroll()}
|
||||||
>
|
>
|
||||||
${items.length === 0
|
${filteredItems.length === 0
|
||||||
? html`<div class="chat-panel-messages-placeholder">
|
? html`<div class="messages-placeholder">
|
||||||
${AffineIcon(
|
${AffineIcon(
|
||||||
isLoading
|
isLoading
|
||||||
? 'var(--affine-icon-secondary)'
|
? 'var(--affine-icon-secondary)'
|
||||||
: 'var(--affine-primary-color)'
|
: 'var(--affine-primary-color)'
|
||||||
)}
|
)}
|
||||||
<div>
|
<div class="messages-placeholder-title" data-loading=${isLoading}>
|
||||||
${this.isLoading
|
${this.isLoading
|
||||||
? 'AFFiNE AI is loading history...'
|
? 'AFFiNE AI is loading history...'
|
||||||
: 'What can I help you with?'}
|
: 'What can I help you with?'}
|
||||||
@@ -267,11 +284,12 @@ export class ChatPanelMessages extends WithDisposable(ShadowlessElement) {
|
|||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
${this.showDownIndicator && filteredItems.length > 1
|
${this.showDownIndicator && filteredItems.length > 0
|
||||||
? html`<div class="down-indicator" @click=${this.scrollToEnd}>
|
? html`<div class="down-indicator" @click=${this.scrollToEnd}>
|
||||||
${DownArrowIcon}
|
${DownArrowIcon}
|
||||||
</div>`
|
</div>`
|
||||||
: nothing} `;
|
: nothing}
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
override connectedCallback() {
|
override connectedCallback() {
|
||||||
|
|||||||
@@ -133,7 +133,6 @@ export class ChatPanel extends WithDisposable(ShadowlessElement) {
|
|||||||
|
|
||||||
private readonly _updateHistory = async () => {
|
private readonly _updateHistory = async () => {
|
||||||
const { doc } = this;
|
const { doc } = this;
|
||||||
this.isLoading = true;
|
|
||||||
|
|
||||||
const currentRequest = ++this._updateHistoryCounter;
|
const currentRequest = ++this._updateHistoryCounter;
|
||||||
|
|
||||||
@@ -164,7 +163,6 @@ export class ChatPanel extends WithDisposable(ShadowlessElement) {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isLoading = false;
|
|
||||||
this._scrollToEnd();
|
this._scrollToEnd();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -253,7 +251,7 @@ export class ChatPanel extends WithDisposable(ShadowlessElement) {
|
|||||||
accessor previewSpecBuilder!: SpecBuilder;
|
accessor previewSpecBuilder!: SpecBuilder;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
accessor isLoading = false;
|
accessor isLoading = true;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
accessor chatContextValue: ChatContextValue = DEFAULT_CHAT_CONTEXT_VALUE;
|
accessor chatContextValue: ChatContextValue = DEFAULT_CHAT_CONTEXT_VALUE;
|
||||||
@@ -301,6 +299,7 @@ export class ChatPanel extends WithDisposable(ShadowlessElement) {
|
|||||||
const userId = (await AIProvider.userInfo)?.id;
|
const userId = (await AIProvider.userInfo)?.id;
|
||||||
if (!userId) return;
|
if (!userId) return;
|
||||||
|
|
||||||
|
this.isLoading = true;
|
||||||
const sessions = await AIProvider.session?.getSessions(
|
const sessions = await AIProvider.session?.getSessions(
|
||||||
this.doc.workspace.id,
|
this.doc.workspace.id,
|
||||||
this.doc.id
|
this.doc.id
|
||||||
@@ -309,6 +308,7 @@ export class ChatPanel extends WithDisposable(ShadowlessElement) {
|
|||||||
this._chatSessionId = sessions?.[0].id;
|
this._chatSessionId = sessions?.[0].id;
|
||||||
await this._updateHistory();
|
await this._updateHistory();
|
||||||
}
|
}
|
||||||
|
this.isLoading = false;
|
||||||
if (this._chatSessionId) {
|
if (this._chatSessionId) {
|
||||||
this._chatContextId = await AIProvider.context?.getContextId(
|
this._chatContextId = await AIProvider.context?.getContextId(
|
||||||
this.doc.workspace.id,
|
this.doc.workspace.id,
|
||||||
|
|||||||
@@ -313,6 +313,11 @@ export class TextRenderer extends WithDisposable(ShadowlessElement) {
|
|||||||
);
|
);
|
||||||
// Apply min-height to prevent shrinking
|
// Apply min-height to prevent shrinking
|
||||||
this._container.style.minHeight = `${this._maxContainerHeight}px`;
|
this._container.style.minHeight = `${this._maxContainerHeight}px`;
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
this._maxContainerHeight = 0;
|
||||||
|
this._container.style.minHeight = '';
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ const clearChat = async (page: Page) => {
|
|||||||
const collectChat = async (page: Page) => {
|
const collectChat = async (page: Page) => {
|
||||||
await page.waitForTimeout(ONE_SECOND);
|
await page.waitForTimeout(ONE_SECOND);
|
||||||
const chatPanel = await page.waitForSelector('.chat-panel-messages');
|
const chatPanel = await page.waitForSelector('.chat-panel-messages');
|
||||||
if (await chatPanel.$('.chat-panel-messages-placeholder')) {
|
if (await chatPanel.$('.messages-placeholder')) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
// wait ai response
|
// wait ai response
|
||||||
|
|||||||
Reference in New Issue
Block a user