add an option to remove chat from server pro (#20445)

* add option to remove chat from backend

* make chat default to enabled

* Check chat is enabled in chat context

---------

Co-authored-by: mserranom <mserranom@gmail.com>
GitOrigin-RevId: 7dda09df4bb74007eb4b1272d4918155b5cddaf6
This commit is contained in:
Brian Gough 2024-10-09 10:17:12 +01:00 committed by Copybot
parent ce130a8bc5
commit 4a32f49b3d
12 changed files with 92 additions and 39 deletions

View file

@ -719,6 +719,7 @@ const _ProjectController = {
isTokenMember,
isInvitedMember
),
chatEnabled: Features.hasFeature('chat'),
roMirrorOnClientNoLocalStorage:
Settings.adminOnlyLogin || project.name.startsWith('Debug: '),
languages: Settings.languages,

View file

@ -58,6 +58,8 @@ const Features = {
)
case 'registration':
return Boolean(Settings.overleaf)
case 'chat':
return Boolean(Settings.disableChat) === false
case 'github-sync':
return Boolean(Settings.enableGithubSync)
case 'git-bridge':

View file

@ -1139,19 +1139,21 @@ async function initialize(webRouter, privateApiRouter, publicApiRouter) {
SpellingController.unlearn
)
webRouter.get(
'/project/:project_id/messages',
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
ChatController.getMessages
)
webRouter.post(
'/project/:project_id/messages',
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
RateLimiterMiddleware.rateLimit(rateLimiters.sendChatMessage),
ChatController.sendMessage
)
if (Features.hasFeature('chat')) {
webRouter.get(
'/project/:project_id/messages',
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
ChatController.getMessages
)
webRouter.post(
'/project/:project_id/messages',
AuthorizationMiddleware.blockRestrictedUserFromProject,
AuthorizationMiddleware.ensureUserCanReadProject,
RateLimiterMiddleware.rateLimit(rateLimiters.sendChatMessage),
ChatController.sendMessage
)
}
webRouter.post(
'/project/:Project_id/references/indexAll',

View file

@ -9,6 +9,7 @@ meta(name="ol-isTokenMember" data-type="boolean" content=isTokenMember)
meta(name="ol-isRestrictedTokenMember" data-type="boolean" content=isRestrictedTokenMember)
meta(name="ol-maxDocLength" data-type="json" content=maxDocLength)
meta(name="ol-wikiEnabled" data-type="boolean" content=settings.proxyLearn)
meta(name="ol-chatEnabled" data-type="boolean" content=chatEnabled)
meta(name="ol-gitBridgePublicBaseUrl" content=gitBridgePublicBaseUrl)
meta(name="ol-gitBridgeEnabled" data-type="boolean" content=gitBridgeEnabled)
meta(name="ol-compilesUserContentDomain" content=settings.compilesUserContentDomain)

View file

@ -407,6 +407,7 @@ module.exports = {
},
],
disableChat: process.env.OVERLEAF_DISABLE_CHAT === 'true',
enableSubscriptions: false,
restrictedCountries: [],
enableOnboardingEmails: process.env.ENABLE_ONBOARDING_EMAILS === 'true',

View file

@ -17,6 +17,8 @@ import { appendMessage, prependMessages } from '../utils/message-list-appender'
import useBrowserWindow from '../../../shared/hooks/use-browser-window'
import { useLayoutContext } from '../../../shared/context/layout-context'
import { useIdeContext } from '@/shared/context/ide-context'
import getMeta from '@/utils/meta'
import { debugConsole } from '@/utils/debugging'
const PAGE_SIZE = 50
@ -187,6 +189,8 @@ export const ChatContext = createContext<
>(undefined)
export const ChatProvider: FC = ({ children }) => {
const chatEnabled = getMeta('ol-chatEnabled')
const clientId = useRef<string>()
if (clientId.current === undefined) {
clientId.current = chatClientIdGenerator.generate()
@ -235,6 +239,10 @@ export const ChatProvider: FC = ({ children }) => {
}
function loadInitialMessages() {
if (!chatEnabled) {
debugConsole.warn(`chat is disabled, won't load initial messages`)
return
}
if (state.initialMessagesLoaded) return
dispatch({ type: 'INITIAL_FETCH_MESSAGES' })
@ -242,11 +250,19 @@ export const ChatProvider: FC = ({ children }) => {
}
function loadMoreMessages() {
if (!chatEnabled) {
debugConsole.warn(`chat is disabled, won't load messages`)
return
}
dispatch({ type: 'FETCH_MESSAGES' })
fetchMessages()
}
function reset() {
if (!chatEnabled) {
debugConsole.warn(`chat is disabled, won't reset chat`)
return
}
dispatch({ type: 'CLEAR' })
fetchMessages()
}
@ -256,10 +272,20 @@ export const ChatProvider: FC = ({ children }) => {
loadMoreMessages,
reset,
}
}, [projectId, state.atEnd, state.initialMessagesLoaded, state.lastTimestamp])
}, [
chatEnabled,
projectId,
state.atEnd,
state.initialMessagesLoaded,
state.lastTimestamp,
])
const sendMessage = useCallback(
content => {
if (!chatEnabled) {
debugConsole.warn(`chat is disabled, won't send message`)
return
}
if (!content) return
dispatch({
@ -278,17 +304,21 @@ export const ChatProvider: FC = ({ children }) => {
})
})
},
[projectId, user]
[chatEnabled, projectId, user]
)
const markMessagesAsRead = useCallback(() => {
if (!chatEnabled) {
debugConsole.warn(`chat is disabled, won't mark messages as read`)
return
}
dispatch({ type: 'MARK_MESSAGES_AS_READ' })
}, [])
}, [chatEnabled])
// Handling receiving messages over the socket
const { socket } = useIdeContext()
useEffect(() => {
if (!socket) return
if (!chatEnabled || !socket) return
function receivedMessage(message: any) {
// If the message is from the current client id, then we are receiving the sent message back from the socket.
@ -304,7 +334,7 @@ export const ChatProvider: FC = ({ children }) => {
socket.removeListener('new-chat-message', receivedMessage)
}
}, [socket])
}, [chatEnabled, socket])
// Handle unread messages
useEffect(() => {

View file

@ -51,6 +51,8 @@ const ToolbarHeader = React.memo(function ToolbarHeader({
openShareModal,
trackChangesVisible,
}) {
const chatEnabled = getMeta('ol-chatEnabled')
const { t } = useTranslation()
const shouldDisplayPublishButton = hasPublishPermissions && PublishButton
@ -123,7 +125,7 @@ const ToolbarHeader = React.memo(function ToolbarHeader({
<LayoutDropdownButton />
{chatVisible && (
{chatEnabled && chatVisible && (
<ChatToggleButton
chatIsOpen={chatIsOpen}
onClick={toggleChatOpen}

View file

@ -13,6 +13,7 @@ import { useSidebarPane } from '@/features/ide-react/hooks/use-sidebar-pane'
import { useChatPane } from '@/features/ide-react/hooks/use-chat-pane'
import { EditorAndPdf } from '@/features/ide-react/components/editor-and-pdf'
import HistoryContainer from '@/features/ide-react/components/history-container'
import getMeta from '@/utils/meta'
export const MainLayout: FC = () => {
const { view } = useLayoutContext()
@ -38,6 +39,8 @@ export const MainLayout: FC = () => {
handlePaneExpand: handleChatExpand,
} = useChatPane()
const chatEnabled = getMeta('ol-chatEnabled')
const { t } = useTranslation()
return (
@ -90,27 +93,31 @@ export const MainLayout: FC = () => {
<EditorAndPdf />
</Panel>
<HorizontalResizeHandle
onDoubleClick={toggleChat}
resizable={chatIsOpen}
onDragging={setChatResizing}
hitAreaMargins={{ coarse: 0, fine: 0 }}
/>
{chatEnabled && (
<>
<HorizontalResizeHandle
onDoubleClick={toggleChat}
resizable={chatIsOpen}
onDragging={setChatResizing}
hitAreaMargins={{ coarse: 0, fine: 0 }}
/>
{/* chat */}
<Panel
ref={chatPanelRef}
id="panel-chat"
order={2}
defaultSize={20}
minSize={5}
maxSize={30}
collapsible
onCollapse={handleChatCollapse}
onExpand={handleChatExpand}
>
<ChatPane />
</Panel>
{/* chat */}
<Panel
ref={chatPanelRef}
id="panel-chat"
order={2}
defaultSize={20}
minSize={5}
maxSize={30}
collapsible
onCollapse={handleChatCollapse}
onExpand={handleChatExpand}
>
<ChatPane />
</Panel>
</>
)}
</PanelGroup>
</Panel>
</PanelGroup>

View file

@ -69,6 +69,7 @@ export interface Meta {
'ol-cannot-link-other-third-party-sso': boolean
'ol-cannot-reactivate-subscription': boolean
'ol-cannot-use-ai': boolean
'ol-chatEnabled': boolean
'ol-countryCode': PricingFormState['country']
'ol-couponCode': PricingFormState['coupon']
'ol-createdAt': Date

View file

@ -22,6 +22,7 @@ describe('<ChatPane />', function () {
beforeEach(function () {
window.metaAttributesCache.set('ol-user', user)
window.metaAttributesCache.set('ol-chatEnabled', true)
})
afterEach(function () {

View file

@ -29,6 +29,7 @@ describe('ChatContext', function () {
stubMathJax()
window.metaAttributesCache.set('ol-user', user)
window.metaAttributesCache.set('ol-chatEnabled', true)
this.stub = sinon.stub(chatClientIdGenerator, 'generate').returns(uuidValue)
})

View file

@ -26,6 +26,10 @@ describe('<ToolbarHeader />', function () {
detach: () => {},
}
beforeEach(function () {
window.metaAttributesCache.set('ol-chatEnabled', true)
})
describe('cobranding logo', function () {
it('is not displayed by default', function () {
renderWithEditorContext(<ToolbarHeader {...defaultProps} />)