Skip to content

Commit

Permalink
Merge pull request #229 from abhinavkrin/new/html-embedd
Browse files Browse the repository at this point in the history
New/html embed
  • Loading branch information
sidmohanty11 authored Sep 25, 2023
2 parents dc00fea + a2e042d commit b196e3a
Show file tree
Hide file tree
Showing 36 changed files with 2,676 additions and 4,756 deletions.
3 changes: 3 additions & 0 deletions packages/htmlembed/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["@babel/preset-react"]
}
2 changes: 2 additions & 0 deletions packages/htmlembed/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
22 changes: 22 additions & 0 deletions packages/htmlembed/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@embeddedchat/htmlembed",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"type": "module",
"scripts": {
"build": "vite build && node postbuild.cjs",
"preview": "npm run build && vite preview --port=4001"
},
"dependencies": {
"@embeddedchat/react": "./packages/react",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^3.1.0",
"live-server": "^1.2.2",
"vite": "^4.2.0",
"vite-plugin-css-injected-by-js": "^3.1.0"
}
}
20 changes: 20 additions & 0 deletions packages/htmlembed/postbuild.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const fs = require('fs');
const path = require('path');

const files = fs.readdirSync(path.join(__dirname, 'public'), { recursive: true });

files.forEach((file) => {
const inPath = path.join(__dirname, 'public', file);
const outPath = path.join(__dirname, 'dist', file);
console.log("Copy: ",inPath);
if (fs.statSync(inPath).isDirectory()) {
if (!fs.existsSync(outPath)) {
fs.mkdirSync(outPath, {recursive: true});
}
} else {
fs.writeFileSync(
outPath,
fs.readFileSync(inPath)
);
}
});
39 changes: 39 additions & 0 deletions packages/htmlembed/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div>
<div id="embeddedchat"></div>
<link rel="stylesheet" href="http://127.0.0.1:4001/rocketchat-icon.css">
<script src="http://127.0.0.1:4001/embeddedchat.js"></script>
<script>
// all props for the EmbeddedChat of @embeddedchat/react will go here
// the config will be directly applied as props for the EmbeddedChat Component
const config = {
host: 'http://localhost:3000',
roomId: 'GENERAL',
GOOGLE_CLIENT_ID: '',
isClosable: true,
setClosableState: true,
moreOpts: true,
channelName: 'general',
anonymousMode: true,
headerColor: 'white',
toastBarPosition: 'bottom-end',
showRoles: true,
showAvatar: false,
enableThreads: true,
auth: {
flow: 'MANAGED',
},
}
EmbeddedChat.renderInElementWithId(config, 'embeddedchat')
</script>
</div>
</body>
</html>
13 changes: 13 additions & 0 deletions packages/htmlembed/public/rocketchat-icons.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@font-face {
font-family: 'RocketChat';
font-weight: 400;
font-style: normal;
font-display: auto;

src: url('./rocketchat.eot');
src: url('./rocketchat.eot?#iefix') format('embedded-opentype'),
url('./rocketchat.woff2') format('woff2'),
url('./rocketchat.woff') format('woff'),
url('./rocketchat.ttf') format('truetype'),
url('./rocketchat.svg#RocketChat') format('svg');
}
Binary file added packages/htmlembed/public/rocketchat.eot
Binary file not shown.
951 changes: 951 additions & 0 deletions packages/htmlembed/public/rocketchat.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/htmlembed/public/rocketchat.ttf
Binary file not shown.
Binary file added packages/htmlembed/public/rocketchat.woff
Binary file not shown.
Binary file added packages/htmlembed/public/rocketchat.woff2
Binary file not shown.
22 changes: 22 additions & 0 deletions packages/htmlembed/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import babel from '@rollup/plugin-babel';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { terser } from 'rollup-plugin-terser';

export default {
input: 'src/index.js',
output: {
file: 'dist/embeddedchat.js',
format: 'umd',
name: 'EmbeddedChat',
},
plugins: [
resolve(),
commonjs(),
babel({
babelHelpers: 'bundled',
presets: ['@babel/preset-react'],
}),
terser(),
],
};
37 changes: 37 additions & 0 deletions packages/htmlembed/src/EmbeddedChat.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import { EmbeddedChat as EmbeddedChatComponent } from '@embeddedchat/react';

const EmbeddedChat = {
renderInElementWithId(config, id) {
if (!id) {
throw new Error("Please provide a valid id of the element to render embeddedchat");
}
ReactDOM.createRoot(document.getElementById(id)).render(
<React.StrictMode>
<EmbeddedChatComponent {...config} />
</React.StrictMode>
)
},
renderInElementWithSelector(config, selector) {
if(!selector) {
throw new Error("Please provide a valid selector to render embeddedchat");
}
ReactDOM.createRoot(document.querySelector(selector)).render(
<React.StrictMode>
<EmbeddedChatComponent {...config} />
</React.StrictMode>
)
},
renderInElement(config, element) {
if (!element) {
throw new Error("Please provide a valid element to render embeddedchat");
}
ReactDOM.createRoot(element).render(
<React.StrictMode>
<EmbeddedChatComponent {...config} />
</React.StrictMode>
)
}
}
export default EmbeddedChat;
3 changes: 3 additions & 0 deletions packages/htmlembed/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import EmbeddedChat from "./EmbeddedChat";

export default EmbeddedChat;
19 changes: 19 additions & 0 deletions packages/htmlembed/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
import path from 'path';

export default defineConfig({
plugins: [react(), cssInjectedByJsPlugin()],
build: {
minify: true,
cssCodeSplit: false,
lib: {
entry: path.resolve(__dirname, 'src/index.js'),
name: 'EmbeddedChat',
formats: ['umd'],
fileName: () => 'embeddedchat.js',
}
},
define: { 'process.env.NODE_ENV': '"production"', 'process.env': '{}' }
})
1 change: 0 additions & 1 deletion packages/react/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'normalize.css'
import '@rocket.chat/icons/dist/rocketchat.css';

/** @type { import('@storybook/react').Preview } */
const preview = {
Expand Down
77 changes: 50 additions & 27 deletions packages/react/src/components/ChatBody/ChatBody.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
/* eslint-disable no-shadow */
import React, { useCallback, useContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import styles from './ChatBody.module.css';
import { css } from '@emotion/react';
import RCContext from '../../context/RCInstance';
import { useMessageStore, useUserStore } from '../../store';
import MessageList from '../MessageList';
import TotpModal from '../TotpModal/TwoFactorTotpModal';
import { useRCAuth4Google } from '../../hooks/useRCAuth4Google';
import { Box } from '../Box';
import { useRCAuth } from '../../hooks/useRCAuth';
import LoginForm from '../auth/LoginForm';
import useAttachmentWindowStore from '../../store/attachmentwindow';
import ThreadMessageList from '../Thread/ThreadMessageList';
import ModalBlock from '../uiKit/blocks/ModalBlock';
import useComponentOverrides from '../../theme/useComponentOverrides';

const ChatBody = ({ height, anonymousMode, showRoles }) => {
const { classNames, styleOverrides } = useComponentOverrides('ChatBody');
const ChatBodyCss = css`
word-break: break-all;
overflow: scroll;
overflow: auto;
display: flex;
flex-direction: column-reverse;
width: 100%;
height: 100vh;
max-height: 600px;
position: relative;
`;
const DragComponentCss = css`
width: 100%;
height: 100%;
position: absolute;
display: flex;
z-index: 50;
background: rgba(0, 0, 0, 0.5);
color: white;
font-weight: 900;
font-size: xxx-large;
flex-direction: column;
justify-content: center;
align-items: center;
`;

const ChatBody = ({ height, anonymousMode, showRoles, GOOGLE_CLIENT_ID }) => {
const { RCInstance, ECOptions } = useContext(RCContext);
const messages = useMessageStore((state) => state.messages);
const threadMessages = useMessageStore((state) => state.threadMessages);
Expand All @@ -34,7 +61,6 @@ const ChatBody = ({ height, anonymousMode, showRoles, GOOGLE_CLIENT_ID }) => {
state.threadMainMessage,
]);

const { handleGoogleLogin } = useRCAuth4Google(GOOGLE_CLIENT_ID);
const { handleLogin } = useRCAuth();

const isUserAuthenticated = useUserStore(
Expand Down Expand Up @@ -79,7 +105,7 @@ const ChatBody = ({ height, anonymousMode, showRoles, GOOGLE_CLIENT_ID }) => {
console.error(e);
}
},
[RCInstance, ECOptions?.enableThreads]
[RCInstance, ECOptions?.enableThreads, isUserAuthenticated, anonymousMode]
);

const handleGoBack = async () => {
Expand Down Expand Up @@ -149,17 +175,19 @@ const ChatBody = ({ height, anonymousMode, showRoles, GOOGLE_CLIENT_ID }) => {
});

useEffect(() => {
if (isUserAuthenticated) {
RCInstance.connect().then(() => {
RCInstance.addMessageListener(addMessage);
RCInstance.addMessageDeleteListener(removeMessage);
RCInstance.addActionTriggeredListener(onActionTriggerResponse);
RCInstance.addUiInteractionListener(onActionTriggerResponse);
});
getMessagesAndRoles();
} else {
getMessagesAndRoles(anonymousMode);
}
RCInstance.auth.onAuthChange((user) => {
if (user) {
RCInstance.connect().then(() => {
RCInstance.addMessageListener(addMessage);
RCInstance.addMessageDeleteListener(removeMessage);
RCInstance.addActionTriggeredListener(onActionTriggerResponse);
RCInstance.addUiInteractionListener(onActionTriggerResponse);
});
getMessagesAndRoles();
} else {
getMessagesAndRoles(anonymousMode);
}
});

return () => {
RCInstance.close();
Expand All @@ -169,7 +197,7 @@ const ChatBody = ({ height, anonymousMode, showRoles, GOOGLE_CLIENT_ID }) => {
RCInstance.removeUiInteractionListener(onActionTriggerResponse);
};
}, [
isUserAuthenticated,
RCInstance,
getMessagesAndRoles,
addMessage,
removeMessage,
Expand Down Expand Up @@ -206,22 +234,21 @@ const ChatBody = ({ height, anonymousMode, showRoles, GOOGLE_CLIENT_ID }) => {

return (
<Box
css={ChatBodyCss}
style={{
borderLeft: '1px solid #b1b1b1',
borderRight: '1px solid #b1b1b1',
paddingTop: '70px',
...styleOverrides,
}}
onDragOver={(e) => handleDrag(e)}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
className={styles.container}
className={`ec-chat-body ${classNames}`}
height={height}
>
{onDrag ? (
<Box
onDrop={(e) => handleDragDrop(e)}
className={styles.drag_component}
>
<Box onDrop={(e) => handleDragDrop(e)} className={DragComponentCss}>
Drop to upload file
</Box>
) : null}
Expand All @@ -233,10 +260,7 @@ const ChatBody = ({ height, anonymousMode, showRoles, GOOGLE_CLIENT_ID }) => {
) : (
<MessageList messages={messages} handleGoBack={handleGoBack} />
)}
<TotpModal
handleGoogleLogin={handleGoogleLogin}
handleLogin={handleLogin}
/>
<TotpModal handleLogin={handleLogin} />
<LoginForm />
{isModalOpen && (
<ModalBlock
Expand All @@ -257,5 +281,4 @@ ChatBody.propTypes = {
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
anonymousMode: PropTypes.bool,
showRoles: PropTypes.bool,
GOOGLE_CLIENT_ID: PropTypes.string,
};
41 changes: 0 additions & 41 deletions packages/react/src/components/ChatBody/ChatBody.module.css

This file was deleted.

Loading

0 comments on commit b196e3a

Please sign in to comment.