mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #20715 from overleaf/ii-bs5-chat-pane
[web] BS5 chat pane GitOrigin-RevId: 8587aca1372b4d2087863d492e702f04a31c23e2
This commit is contained in:
parent
e05c181af4
commit
6c7ee8f778
9 changed files with 195 additions and 18 deletions
|
@ -1,6 +1,7 @@
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Button, Alert } from 'react-bootstrap'
|
import OLNotification from '@/features/ui/components/ol/ol-notification'
|
||||||
|
import OLButton from '@/features/ui/components/ol/ol-button'
|
||||||
|
|
||||||
function ChatFallbackError({ reconnect }) {
|
function ChatFallbackError({ reconnect }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
@ -8,12 +9,12 @@ function ChatFallbackError({ reconnect }) {
|
||||||
return (
|
return (
|
||||||
<aside className="chat">
|
<aside className="chat">
|
||||||
<div className="chat-error">
|
<div className="chat-error">
|
||||||
<Alert bsStyle="danger">{t('chat_error')}</Alert>
|
<OLNotification type="error" content={t('chat_error')} />
|
||||||
{reconnect && (
|
{reconnect && (
|
||||||
<p className="text-center">
|
<p className="text-center">
|
||||||
<Button bsStyle="info" type="button" onClick={reconnect}>
|
<OLButton variant="secondary" onClick={reconnect}>
|
||||||
{t('reconnect')}
|
{t('reconnect')}
|
||||||
</Button>
|
</OLButton>
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -11,6 +11,9 @@ import withErrorBoundary from '../../../infrastructure/error-boundary'
|
||||||
import { FetchError } from '../../../infrastructure/fetch-json'
|
import { FetchError } from '../../../infrastructure/fetch-json'
|
||||||
import { useChatContext } from '../context/chat-context'
|
import { useChatContext } from '../context/chat-context'
|
||||||
import LoadingSpinner from '../../../shared/components/loading-spinner'
|
import LoadingSpinner from '../../../shared/components/loading-spinner'
|
||||||
|
import { bsVersion } from '@/features/utils/bootstrap-5'
|
||||||
|
import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/bootstrap-version-switcher'
|
||||||
|
import MaterialIcon from '@/shared/components/material-icon'
|
||||||
|
|
||||||
const MessageList = lazy(() => import('./message-list'))
|
const MessageList = lazy(() => import('./message-list'))
|
||||||
|
|
||||||
|
@ -79,7 +82,9 @@ const ChatPane = React.memo(function ChatPane() {
|
||||||
itemCount={messageContentCount}
|
itemCount={messageContentCount}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<h2 className="sr-only">{t('chat')}</h2>
|
<h2 className={bsVersion({ bs3: 'sr-only', bs5: 'visually-hidden' })}>
|
||||||
|
{t('chat')}
|
||||||
|
</h2>
|
||||||
<Suspense fallback={<LoadingSpinner delay={500} />}>
|
<Suspense fallback={<LoadingSpinner delay={500} />}>
|
||||||
{status === 'pending' && <LoadingSpinner delay={500} />}
|
{status === 'pending' && <LoadingSpinner delay={500} />}
|
||||||
{shouldDisplayPlaceholder && <Placeholder />}
|
{shouldDisplayPlaceholder && <Placeholder />}
|
||||||
|
@ -107,7 +112,10 @@ function Placeholder() {
|
||||||
<div className="first-message text-center">
|
<div className="first-message text-center">
|
||||||
{t('send_first_message')}
|
{t('send_first_message')}
|
||||||
<br />
|
<br />
|
||||||
<Icon type="arrow-down" />
|
<BootstrapVersionSwitcher
|
||||||
|
bs3={<Icon type="arrow-down" />}
|
||||||
|
bs5={<MaterialIcon type="arrow_downward" />}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { bsVersion } from '@/features/utils/bootstrap-5'
|
||||||
|
|
||||||
type MessageInputProps = {
|
type MessageInputProps = {
|
||||||
resetUnreadMessages: () => void
|
resetUnreadMessages: () => void
|
||||||
|
@ -26,7 +27,10 @@ function MessageInput({ resetUnreadMessages, sendMessage }: MessageInputProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="new-message">
|
<form className="new-message">
|
||||||
<label htmlFor="chat-input" className="sr-only">
|
<label
|
||||||
|
htmlFor="chat-input"
|
||||||
|
className={bsVersion({ bs3: 'sr-only', bs5: 'visually-hidden' })}
|
||||||
|
>
|
||||||
{t('your_message_to_collaborators')}
|
{t('your_message_to_collaborators')}
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
|
|
|
@ -44,7 +44,7 @@ function LoadingSpinner({
|
||||||
animation="border"
|
animation="border"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
role="status"
|
role="status"
|
||||||
className="align-bottom"
|
className="align-middle"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{loadingText || t('loading')}…
|
{loadingText || t('loading')}…
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
@new-message-height: 80px;
|
@new-message-height: 80px;
|
||||||
|
|
||||||
#chat-wrapper {
|
|
||||||
> .ui-layout-resizer > .ui-layout-toggler {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat {
|
.chat {
|
||||||
.loading {
|
.loading {
|
||||||
font-family: @font-family-serif;
|
font-family: @font-family-serif;
|
||||||
|
@ -140,7 +134,3 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.break-word {
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
@import 'mixins';
|
@import 'mixins';
|
||||||
@import 'variables';
|
@import 'variables';
|
||||||
@import 'variable-overrides';
|
@import 'variable-overrides';
|
||||||
|
@import 'themes-common-variables';
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
:root {
|
||||||
|
--editor-border-color: var(--neutral-80);
|
||||||
|
}
|
||||||
|
|
||||||
|
@include theme('light') {
|
||||||
|
--editor-border-color: var(--neutral-20);
|
||||||
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
@import 'editor/outline';
|
@import 'editor/outline';
|
||||||
@import 'editor/file-tree';
|
@import 'editor/file-tree';
|
||||||
@import 'editor/figure-modal';
|
@import 'editor/figure-modal';
|
||||||
|
@import 'editor/chat';
|
||||||
@import 'subscription';
|
@import 'subscription';
|
||||||
@import 'editor/pdf';
|
@import 'editor/pdf';
|
||||||
@import 'editor/compile-button';
|
@import 'editor/compile-button';
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
:root {
|
||||||
|
--chat-bg: var(--neutral-80);
|
||||||
|
--chat-color: var(--white);
|
||||||
|
--chat-instructions-color: var(--neutral-20);
|
||||||
|
--chat-new-message-bg: var(--neutral-70);
|
||||||
|
--chat-new-message-textarea-color: var(--neutral-90);
|
||||||
|
--chat-new-message-textarea-bg: var(--neutral-20);
|
||||||
|
--chat-message-date-color: var(--neutral-40);
|
||||||
|
--chat-message-name-color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
@include theme('light') {
|
||||||
|
--chat-bg: var(--white);
|
||||||
|
--chat-color: var(--neutral-70);
|
||||||
|
--chat-instructions-color: var(--neutral-70);
|
||||||
|
--chat-new-message-bg: var(--neutral-10);
|
||||||
|
--chat-new-message-textarea-color: var(--neutral-90);
|
||||||
|
--chat-new-message-textarea-bg: var(--white);
|
||||||
|
--chat-message-date-color: var(--neutral-70);
|
||||||
|
--chat-message-name-color: var(--neutral-70);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat {
|
||||||
|
$new-message-height: 80px;
|
||||||
|
|
||||||
|
color: var(--chat-color);
|
||||||
|
|
||||||
|
.no-messages {
|
||||||
|
padding: calc(var(--line-height-03) / 2);
|
||||||
|
color: var(--chat-instructions-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.first-message {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: calc(var(--line-height-03) / 2);
|
||||||
|
color: var(--chat-instructions-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-error {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: var(--chat-bg);
|
||||||
|
padding: calc(var(--line-height-03) / 2);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messages {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
bottom: $new-message-height;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background-color: var(--chat-bg);
|
||||||
|
|
||||||
|
li.message {
|
||||||
|
margin: calc(var(--line-height-03) / 2);
|
||||||
|
|
||||||
|
.date {
|
||||||
|
font-size: var(--font-size-01);
|
||||||
|
color: var(--chat-message-date-color);
|
||||||
|
margin-bottom: calc(var(--line-height-03) / 2);
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-wrapper {
|
||||||
|
.name {
|
||||||
|
font-size: var(--font-size-01);
|
||||||
|
color: var(--chat-message-name-color);
|
||||||
|
margin-bottom: var(--spacing-02);
|
||||||
|
min-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
font-size: var(--font-size-02);
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: var(--border-radius-base);
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.message-content {
|
||||||
|
padding: var(--spacing-03) var(--spacing-05);
|
||||||
|
overflow-x: auto;
|
||||||
|
color: var(--white);
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
right: 90%;
|
||||||
|
top: -15px;
|
||||||
|
border: solid;
|
||||||
|
content: ' ';
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
border-top-color: transparent !important;
|
||||||
|
border-bottom-color: transparent !important;
|
||||||
|
border-width: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: calc(var(--line-height-03) / 4);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.self) {
|
||||||
|
.message {
|
||||||
|
.arrow {
|
||||||
|
border-left-color: transparent !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.self {
|
||||||
|
margin-top: var(--line-height-03);
|
||||||
|
|
||||||
|
.message-wrapper .message {
|
||||||
|
border-left: none;
|
||||||
|
border-right: 3px solid transparent;
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
left: 100%;
|
||||||
|
right: auto;
|
||||||
|
border-right-color: transparent !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-message {
|
||||||
|
@extend .full-size;
|
||||||
|
|
||||||
|
top: auto;
|
||||||
|
height: $new-message-height;
|
||||||
|
background-color: var(--chat-new-message-bg);
|
||||||
|
padding: calc(var(--line-height-03) / 4);
|
||||||
|
border-top: 1px solid var(--editor-border-color);
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
overflow: auto;
|
||||||
|
resize: none;
|
||||||
|
border-radius: var(--border-radius-base);
|
||||||
|
border: 1px solid var(--editor-border-color);
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
color: var(--chat-new-message-textarea-color);
|
||||||
|
font-size: var(--font-size-02);
|
||||||
|
padding: calc(var(--line-height-03) / 4);
|
||||||
|
background-color: var(--chat-new-message-textarea-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue