diff --git a/.github/workflows/build-and-lint.yml b/.github/workflows/build-and-lint.yml new file mode 100644 index 000000000..d92c4001a --- /dev/null +++ b/.github/workflows/build-and-lint.yml @@ -0,0 +1,46 @@ +name: Build and Lint + +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] + +jobs: + build-and-lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 16.19.0 + + - name: Set up Yarn + uses: actions/setup-node@v3 + with: + node-version: 16.19.0 + cache: 'yarn' + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.yarn + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install dependencies + run: yarn + + - name: Format check + run: yarn format:check + + - name: Lint check + run: yarn lint + + - name: Build + run: yarn build && yarn build:storybook diff --git a/package.json b/package.json index f19dbb472..086c7ff1d 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,11 @@ "scripts": { "preinstall": "node scripts/node-check.js", "postinstall": "yarn build", - "build": "lerna run build" + "build": "lerna run build", + "lint": "lerna run lint", + "build:storybook": "lerna run build-storybook", + "format": "lerna run format", + "format:check": "lerna run format:check" }, "devDependencies": { "@changesets/cli": "^2.26.2", diff --git a/packages/api/package.json b/packages/api/package.json index 1481af2e8..f6c304e94 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -9,7 +9,9 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "rollup -c", - "dev": "yarn parcel playground/index.html" + "dev": "yarn parcel playground/index.html", + "format": "prettier --write 'src/'", + "format:check": "prettier --check 'src/'" }, "author": "", "license": "ISC", diff --git a/packages/api/src/EmbeddedChatApi.ts b/packages/api/src/EmbeddedChatApi.ts index ce81a5427..2286011e0 100644 --- a/packages/api/src/EmbeddedChatApi.ts +++ b/packages/api/src/EmbeddedChatApi.ts @@ -1,6 +1,10 @@ -import { Rocketchat } from '@rocket.chat/sdk'; -import cloneArray from './cloneArray'; -import { IRocketChatAuthOptions, RocketChatAuth, ApiError } from '@embeddedchat/auth'; +import { Rocketchat } from "@rocket.chat/sdk"; +import cloneArray from "./cloneArray"; +import { + IRocketChatAuthOptions, + RocketChatAuth, + ApiError, +} from "@embeddedchat/auth"; // mutliple typing status can come at the same time they should be processed in order. let typingHandlerLock = 0; @@ -8,19 +12,23 @@ export default class EmbeddedChatApi { host: string; rid: string; rcClient: Rocketchat; - onMessageCallbacks: ((message: any) => void)[] - onMessageDeleteCallbacks: ((messageId: string) => void)[] + onMessageCallbacks: ((message: any) => void)[]; + onMessageDeleteCallbacks: ((messageId: string) => void)[]; onTypingStatusCallbacks: ((users: string[]) => void)[]; onActionTriggeredCallbacks: ((data: any) => void)[]; onUiInteractionCallbacks: ((data: any) => void)[]; typingUsers: string[]; auth: RocketChatAuth; - constructor(host: string, rid: string, { getToken, saveToken, deleteToken, autoLogin }: IRocketChatAuthOptions ) { + constructor( + host: string, + rid: string, + { getToken, saveToken, deleteToken, autoLogin }: IRocketChatAuthOptions + ) { this.host = host; this.rid = rid; this.rcClient = new Rocketchat({ - protocol: 'ddp', + protocol: "ddp", host: this.host, useSsl: !/http:\/\//.test(host), reopen: 20000, @@ -59,13 +67,13 @@ export default class EmbeddedChatApi { const tokens = await signIn(); let acsPayload = null; - if (typeof acsCode === 'string') { + if (typeof acsCode === "string") { acsPayload = acsCode; } const payload = acsCode ? JSON.stringify({ - serviceName: 'google', + serviceName: "google", accessToken: tokens.access_token, idToken: tokens.id_token, expiresIn: 3600, @@ -74,24 +82,24 @@ export default class EmbeddedChatApi { }, }) : JSON.stringify({ - serviceName: 'google', + serviceName: "google", accessToken: tokens.access_token, idToken: tokens.id_token, expiresIn: 3600, - scope: 'profile', + scope: "profile", }); try { const req = await fetch(`${this.host}/api/v1/login`, { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, body: payload, }); const response = await req.json(); - if (response.status === 'success') { + if (response.status === "success") { if (!response.data.me.username) { await this.updateUserUsername( response.data.userId, @@ -101,7 +109,7 @@ export default class EmbeddedChatApi { return { status: response.status, me: response.data.me }; } - if (response.error === 'totp-required') { + if (response.error === "totp-required") { return response; } } catch (err) { @@ -126,12 +134,9 @@ export default class EmbeddedChatApi { try { const data = await this.auth.loginWithPassword(credentials); if (!data.me.username) { - await this.updateUserUsername( - data.userId, - data.me.name - ); + await this.updateUserUsername(data.userId, data.me.name); } - return { status: 'success', me: data.me }; + return { status: "success", me: data.me }; } catch (error) { if (error instanceof ApiError && error.response?.status === 401) { const authErrorRes = await error.response.json(); @@ -165,7 +170,7 @@ export default class EmbeddedChatApi { return; } const message = JSON.parse(JSON.stringify(data)); - if( message.ts?.$date) { + if (message.ts?.$date) { console.log(message.ts?.$date); message.ts = message.ts.$date; } @@ -175,58 +180,68 @@ export default class EmbeddedChatApi { this.onMessageCallbacks.map((callback) => callback(message)); }); await this.rcClient.subscribe( - 'stream-notify-room', + "stream-notify-room", `${this.rid}/user-activity` ); - await this.rcClient.onStreamData('stream-notify-room', (ddpMessage: any) => { - const [roomId, event] = ddpMessage.fields.eventName.split('/'); + await this.rcClient.onStreamData( + "stream-notify-room", + (ddpMessage: any) => { + const [roomId, event] = ddpMessage.fields.eventName.split("/"); - if (roomId !== this.rid) { - return; - } + if (roomId !== this.rid) { + return; + } - if (event === 'user-activity') { - const typingUser = ddpMessage.fields.args[0]; - const isTyping = ddpMessage.fields.args[1]?.includes('user-typing'); - this.handleTypingEvent({ typingUser, isTyping }); - } + if (event === "user-activity") { + const typingUser = ddpMessage.fields.args[0]; + const isTyping = ddpMessage.fields.args[1]?.includes("user-typing"); + this.handleTypingEvent({ typingUser, isTyping }); + } - if (event === 'typing') { - const typingUser = ddpMessage.fields.args[0]; - const isTyping = ddpMessage.fields.args[1]; - this.handleTypingEvent({ typingUser, isTyping }); - } - if (event === 'deleteMessage') { - const messageId = ddpMessage.fields.args[0]?._id; - this.onMessageDeleteCallbacks.map((callback) => callback(messageId)); - } - }); - await this.rcClient.subscribeNotifyUser(); - await this.rcClient.onStreamData('stream-notify-user', (ddpMessage: any) => { - const [, event] = ddpMessage.fields.eventName.split('/'); - const args: any[] = ddpMessage.fields.args - ? Array.isArray(ddpMessage.fields.args) - ? ddpMessage.fields.args - : [ddpMessage.fields.args] - : []; - if (event === 'message') { - const data = args[0]; - if (!data || data?.rid !== this.rid) { - return; + if (event === "typing") { + const typingUser = ddpMessage.fields.args[0]; + const isTyping = ddpMessage.fields.args[1]; + this.handleTypingEvent({ typingUser, isTyping }); } - const message = JSON.parse(JSON.stringify(data)); - if( message.ts?.$date) { - message.ts = message.ts.$date; + if (event === "deleteMessage") { + const messageId = ddpMessage.fields.args[0]?._id; + this.onMessageDeleteCallbacks.map((callback) => + callback(messageId) + ); } - if (!message.ts) { - message.ts = new Date().toISOString(); + } + ); + await this.rcClient.subscribeNotifyUser(); + await this.rcClient.onStreamData( + "stream-notify-user", + (ddpMessage: any) => { + const [, event] = ddpMessage.fields.eventName.split("/"); + const args: any[] = ddpMessage.fields.args + ? Array.isArray(ddpMessage.fields.args) + ? ddpMessage.fields.args + : [ddpMessage.fields.args] + : []; + if (event === "message") { + const data = args[0]; + if (!data || data?.rid !== this.rid) { + return; + } + const message = JSON.parse(JSON.stringify(data)); + if (message.ts?.$date) { + message.ts = message.ts.$date; + } + if (!message.ts) { + message.ts = new Date().toISOString(); + } + message.renderType = "blocks"; + this.onMessageCallbacks.map((callback) => callback(message)); + } else if (event === "uiInteraction") { + this.onUiInteractionCallbacks.forEach((callback) => + callback(args[0]) + ); } - message.renderType = 'blocks'; - this.onMessageCallbacks.map((callback) => callback(message)); - } else if (event === 'uiInteraction') { - this.onUiInteractionCallbacks.forEach((callback) => callback(args[0])); } - }); + ); } catch (err) { await this.close(); } @@ -295,9 +310,7 @@ export default class EmbeddedChatApi { } async addUiInteractionListener(callback: (data: any) => void) { - const idx = this.onUiInteractionCallbacks.findIndex( - (c) => c === callback - ); + const idx = this.onUiInteractionCallbacks.findIndex((c) => c === callback); if (idx !== -1) { this.onUiInteractionCallbacks[idx] = callback; } else { @@ -311,7 +324,10 @@ export default class EmbeddedChatApi { ); } - handleTypingEvent({ typingUser, isTyping }: { + handleTypingEvent({ + typingUser, + isTyping, + }: { typingUser: string; isTyping: boolean; }) { @@ -339,16 +355,16 @@ export default class EmbeddedChatApi { async updateUserNameThroughSuggestion(userid: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch( `${this.host}/api/v1/users.getUsernameSuggestion`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", } ); @@ -358,11 +374,11 @@ export default class EmbeddedChatApi { const response2 = await fetch(`${this.host}/api/v1/users.update`, { body: `{"userId": "${userid}", "data": { "username": "${suggestedUsername.result}" }}`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response2.json(); @@ -373,28 +389,28 @@ export default class EmbeddedChatApi { } async updateUserUsername(userid: string, username: string) { - const newUserName = username.replace(/\s/g, '.').toLowerCase(); + const newUserName = username.replace(/\s/g, ".").toLowerCase(); const usernameRegExp = /[0-9a-zA-Z-_.]+/; if (usernameRegExp.test(newUserName)) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/users.update`, { body: `{"userId": "${userid}", "data": { "username": "${newUserName}" }}`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); const result = await response.json(); if ( !result.success && - result.errorType === 'error-could-not-save-identity' + result.errorType === "error-could-not-save-identity" ) { return await this.updateUserNameThroughSuggestion(userid); } @@ -409,16 +425,16 @@ export default class EmbeddedChatApi { async channelInfo() { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch( `${this.host}/api/v1/rooms.info?roomId=${this.rid}`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", } ); return await response.json(); @@ -439,32 +455,36 @@ export default class EmbeddedChatApi { * fields - json object with properties that have either 1 or 0 to include them or exclude them * @returns messages */ - async getMessages(anonymousMode = false, options: { - query?: object | undefined; - field?: object | undefined; + async getMessages( + anonymousMode = false, + options: { + query?: object | undefined; + field?: object | undefined; } = { query: undefined, - field: undefined - }, isChannelPrivate = false) { - const roomType = isChannelPrivate ? 'groups' : 'channels' ; - const endp = anonymousMode ? 'anonymousread' : 'messages'; + field: undefined, + }, + isChannelPrivate = false + ) { + const roomType = isChannelPrivate ? "groups" : "channels"; + const endp = anonymousMode ? "anonymousread" : "messages"; const query = options?.query ? `&query=${JSON.stringify(options.query)}` - : ''; + : ""; const field = options?.field ? `&field=${JSON.stringify(options.field)}` - : ''; + : ""; try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const messages = await fetch( `${this.host}/api/v1/${roomType}.${endp}?roomId=${this.rid}${query}${field}`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", } ); return await messages.json(); @@ -474,26 +494,30 @@ export default class EmbeddedChatApi { } async getThreadMessages(tmid: string, isChannelPrivate = false) { - return this.getMessages(false, { - query: { - tmid, + return this.getMessages( + false, + { + query: { + tmid, + }, }, - }, isChannelPrivate); + isChannelPrivate + ); } async getChannelRoles(isChannelPrivate = false) { - const roomType = isChannelPrivate ? 'groups' : 'channels'; + const roomType = isChannelPrivate ? "groups" : "channels"; try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const roles = await fetch( `${this.host}/api/v1/${roomType}.roles?roomId=${this.rid}`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", } ); return await roles.json(); @@ -505,10 +529,10 @@ export default class EmbeddedChatApi { async sendTypingStatus(username: string, typing: boolean) { try { this.rcClient.methodCall( - 'stream-notify-room', + "stream-notify-room", `${this.rid}/user-activity`, username, - typing ? ['user-typing'] : [] + typing ? ["user-typing"] : [] ); } catch (err) { console.error(err); @@ -521,7 +545,7 @@ export default class EmbeddedChatApi { */ async sendMessage(message: any, threadId: string) { const messageObj = - typeof message === 'string' + typeof message === "string" ? { rid: this.rid, msg: message, @@ -534,15 +558,15 @@ export default class EmbeddedChatApi { messageObj.tmid = threadId; } try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/chat.sendMessage`, { body: JSON.stringify({ message: messageObj }), headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response.json(); } catch (err) { @@ -552,15 +576,15 @@ export default class EmbeddedChatApi { async deleteMessage(msgId: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/chat.delete`, { body: `{"roomId": "${this.rid}", "msgId": "${msgId}","asUser" : true }`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response.json(); } catch (err) { @@ -570,15 +594,15 @@ export default class EmbeddedChatApi { async updateMessage(msgId: string, text: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/chat.update`, { body: `{"roomId": "${this.rid}", "msgId": "${msgId}","text" : "${text}" }`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response.json(); } catch (err) { @@ -588,15 +612,15 @@ export default class EmbeddedChatApi { async starMessage(mid: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/chat.starMessage`, { body: `{"messageId": "${mid}"}`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response.json(); } catch (err) { @@ -606,15 +630,15 @@ export default class EmbeddedChatApi { async unstarMessage(mid: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/chat.unStarMessage`, { body: `{"messageId": "${mid}"}`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response.json(); } catch (err) { @@ -624,16 +648,16 @@ export default class EmbeddedChatApi { async getStarredMessages() { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch( `${this.host}/api/v1/chat.getStarredMessages?roomId=${this.rid}`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", } ); return await response.json(); @@ -644,16 +668,16 @@ export default class EmbeddedChatApi { async getPinnedMessages() { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch( `${this.host}/api/v1/chat.getPinnedMessages?roomId=${this.rid}`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", } ); return await response.json(); @@ -664,15 +688,15 @@ export default class EmbeddedChatApi { async pinMessage(mid: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/chat.pinMessage`, { body: `{"messageId": "${mid}"}`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response.json(); } catch (err) { @@ -684,15 +708,15 @@ export default class EmbeddedChatApi { async unpinMessage(mid: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/chat.unPinMessage`, { body: `{"messageId": "${mid}"}`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response.json(); } catch (err) { @@ -702,15 +726,15 @@ export default class EmbeddedChatApi { async reactToMessage(emoji: string, messageId: string, shouldReact: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/chat.react`, { body: `{"messageId": "${messageId}", "emoji": "${emoji}", "shouldReact": ${shouldReact}}`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response.json(); } catch (err) { @@ -720,15 +744,15 @@ export default class EmbeddedChatApi { async reportMessage(messageId: string, description: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/chat.reportMessage`, { body: `{"messageId": "${messageId}", "description": "${description}"}`, headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", }); return await response.json(); } catch (err) { @@ -738,14 +762,14 @@ export default class EmbeddedChatApi { async findOrCreateInvite() { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/findOrCreateInvite`, { - method: 'POST', + method: "POST", body: JSON.stringify({ rid: this.rid, days: 1, maxUses: 10 }), headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, }); return await response.json(); @@ -757,26 +781,26 @@ export default class EmbeddedChatApi { async sendAttachment( file: File, fileName: string, - fileDescription = '', + fileDescription = "", threadId = undefined ) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const form = new FormData(); if (threadId) { - form.append('tmid', threadId); + form.append("tmid", threadId); } - form.append('file', file, fileName); + form.append("file", file, fileName); form.append( - 'description', - fileDescription.length !== 0 ? fileDescription : '' + "description", + fileDescription.length !== 0 ? fileDescription : "" ); const response = fetch(`${this.host}/api/v1/rooms.upload/${this.rid}`, { - method: 'POST', + method: "POST", body: form, headers: { - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "X-Auth-Token": authToken, + "X-User-Id": userId, }, }).then((r) => r.json()); return response; @@ -787,14 +811,14 @@ export default class EmbeddedChatApi { async me() { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/me`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", }); return await response.json(); } catch (err) { @@ -803,18 +827,18 @@ export default class EmbeddedChatApi { } async getChannelMembers(isChannelPrivate = false) { - const roomType = isChannelPrivate ? 'groups' : 'channels'; + const roomType = isChannelPrivate ? "groups" : "channels"; try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch( `${this.host}/api/v1/${roomType}.members?roomId=${this.rid}`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", } ); return await response.json(); @@ -825,16 +849,16 @@ export default class EmbeddedChatApi { async getSearchMessages(text: string) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch( `${this.host}/api/v1/chat.search?roomId=${this.rid}&searchText=${text}`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", } ); return await response.json(); @@ -853,7 +877,7 @@ export default class EmbeddedChatApi { ...rest }: any) { try { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const triggerId = Math.random().toString(32).slice(2, 16); @@ -863,13 +887,13 @@ export default class EmbeddedChatApi { `${this.host}/api/apps/ui.interaction/${appId}`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", body: JSON.stringify({ - type: 'blockAction', + type: "blockAction", actionId, payload, container, @@ -889,28 +913,28 @@ export default class EmbeddedChatApi { } async getCommandsList() { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/commands.list`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'GET', + method: "GET", }); const data = await response.json(); return data; } - async execCommand({ command, params }: { command: string, params: string; }) { - const { userId, authToken } = await this.auth.getCurrentUser() || {}; + async execCommand({ command, params }: { command: string; params: string }) { + const { userId, authToken } = (await this.auth.getCurrentUser()) || {}; const response = await fetch(`${this.host}/api/v1/commands.run`, { headers: { - 'Content-Type': 'application/json', - 'X-Auth-Token': authToken, - 'X-User-Id': userId, + "Content-Type": "application/json", + "X-Auth-Token": authToken, + "X-User-Id": userId, }, - method: 'POST', + method: "POST", body: JSON.stringify({ command, params, diff --git a/packages/api/src/cloneArray.ts b/packages/api/src/cloneArray.ts index cbdaa185d..ceb43ad43 100644 --- a/packages/api/src/cloneArray.ts +++ b/packages/api/src/cloneArray.ts @@ -5,7 +5,7 @@ */ const cloneArray = (array: any[]) => { const newArray = [...array].map((item) => - typeof item === 'object' ? { ...item } : item + typeof item === "object" ? { ...item } : item ); return newArray; }; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index aa9ac1d7d..b4ff83a1c 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1 +1 @@ -export { default as EmbeddedChatApi } from './EmbeddedChatApi' +export { default as EmbeddedChatApi } from "./EmbeddedChatApi"; diff --git a/packages/auth/package.json b/packages/auth/package.json index 6e49486b5..0eb2f1a77 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -9,7 +9,9 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "rollup -c", - "dev": "yarn parcel playground/index.html" + "dev": "yarn parcel playground/index.html", + "format": "prettier --write 'src/' ", + "format:check": "prettier --check 'src/' " }, "author": "", "license": "ISC", diff --git a/packages/auth/src/Api.ts b/packages/auth/src/Api.ts index 7179a4e09..78d6c82c7 100644 --- a/packages/auth/src/Api.ts +++ b/packages/auth/src/Api.ts @@ -1,58 +1,63 @@ export class ApiError extends Error { - response: Response; - constructor( - response: Response, - message?: string | undefined, - options?: ErrorOptions | undefined, - ...other: any[] - ) { - super(message, options, ...other as []); - this.response = response; - } + response: Response; + constructor( + response: Response, + message?: string | undefined, + options?: ErrorOptions | undefined, + ...other: any[] + ) { + super(message, options, ...(other as [])); + this.response = response; + } } export class Api { - baseUrl: string; - constructor(baseUrl: string) { - this.baseUrl = baseUrl; - } - getFetchConfig = (config: RequestInit) => { - const headers = { - 'Content-Type': 'application/json', - ...(config?.headers || {}) - } - const requestInit: RequestInit = { - ...config, - headers, - } - return requestInit; - } - async request(method: string = 'GET', endpoint: string, data: any, config: RequestInit) { - const url = new URL(endpoint, this.baseUrl).toString(); - const response = await fetch(url, { - body: data ? JSON.stringify(data) : undefined, - method, - headers: { - ...config.headers, - } - }); - if (!response.ok) { - throw new ApiError(response, "Failed Api Request for "+endpoint); - } - const jsonData = await response.json(); - return { data: jsonData }; - } + baseUrl: string; + constructor(baseUrl: string) { + this.baseUrl = baseUrl; + } + getFetchConfig = (config: RequestInit) => { + const headers = { + "Content-Type": "application/json", + ...(config?.headers || {}), + }; + const requestInit: RequestInit = { + ...config, + headers, + }; + return requestInit; + }; + async request( + method: string = "GET", + endpoint: string, + data: any, + config: RequestInit + ) { + const url = new URL(endpoint, this.baseUrl).toString(); + const response = await fetch(url, { + body: data ? JSON.stringify(data) : undefined, + method, + headers: { + ...config.headers, + }, + }); + if (!response.ok) { + throw new ApiError(response, "Failed Api Request for " + endpoint); + } + const jsonData = await response.json(); + return { data: jsonData }; + } - async post(endpoint: string, data: any, config: RequestInit = {}) { - return this.request('POST', endpoint, data, this.getFetchConfig(config)); - } - async get(endpoint: string, config: RequestInit = {}) { - return this.request('GET', endpoint, null, this.getFetchConfig(config)); - } - async put(endpoint: string, data: any, config: RequestInit = {}) { - return this.request('PUT', endpoint, data, this.getFetchConfig(config)); - } - async delete(endpoint: string, config: RequestInit = {}) { - return this.request('DELETE', endpoint, null, this.getFetchConfig(config)); - } + async post(endpoint: string, data: any, config: RequestInit = {}) { + return this.request("POST", endpoint, data, this.getFetchConfig(config)); + } + async get(endpoint: string, config: RequestInit = {}) { + return this.request("GET", endpoint, null, this.getFetchConfig(config)); + } + async put(endpoint: string, data: any, config: RequestInit = {}) { + return this.request("PUT", endpoint, data, this.getFetchConfig(config)); + } + async delete(endpoint: string, config: RequestInit = {}) { + return this.request("DELETE", endpoint, null, this.getFetchConfig(config)); + } } diff --git a/packages/auth/src/IRocketChatAuthOptions.ts b/packages/auth/src/IRocketChatAuthOptions.ts index 06181cdb2..1c452fa4a 100644 --- a/packages/auth/src/IRocketChatAuthOptions.ts +++ b/packages/auth/src/IRocketChatAuthOptions.ts @@ -1,7 +1,7 @@ export interface IRocketChatAuthOptions { - host: string; - saveToken: (token: string) => Promise; - getToken: () => Promise; - deleteToken: () => Promise; - autoLogin?: boolean; + host: string; + saveToken: (token: string) => Promise; + getToken: () => Promise; + deleteToken: () => Promise; + autoLogin?: boolean; } diff --git a/packages/auth/src/auth.ts b/packages/auth/src/auth.ts index e8b8620a6..5d06758da 100644 --- a/packages/auth/src/auth.ts +++ b/packages/auth/src/auth.ts @@ -1,22 +1,20 @@ -import { IRocketChatAuthOptions } from './IRocketChatAuthOptions'; -import RocketChatAuth from './RocketChatAuth'; +import { IRocketChatAuthOptions } from "./IRocketChatAuthOptions"; +import RocketChatAuth from "./RocketChatAuth"; const rocketChatAuth = ({ - host, - saveToken, - getToken, - deleteToken, - autoLogin, + host, + saveToken, + getToken, + deleteToken, + autoLogin, }: IRocketChatAuthOptions) => { - return new RocketChatAuth({ - host, - saveToken, - getToken, - deleteToken, - autoLogin, - }); -} + return new RocketChatAuth({ + host, + saveToken, + getToken, + deleteToken, + autoLogin, + }); +}; -export { - rocketChatAuth -} +export { rocketChatAuth }; diff --git a/packages/auth/src/getAuthorizationUrl.ts b/packages/auth/src/getAuthorizationUrl.ts index 1c9346706..32e9a5e15 100644 --- a/packages/auth/src/getAuthorizationUrl.ts +++ b/packages/auth/src/getAuthorizationUrl.ts @@ -1,12 +1,15 @@ const getAuthorizationUrl = (oauthService: any) => { - if (oauthService.authorizePath?.startsWith('http')){ - return oauthService.authorizePath; - } - if (oauthService.serverURL) { - return new URL(oauthService.authorizePath, oauthService.serverURL).toString(); - } else { - return oauthService.authorizePath; - } -} + if (oauthService.authorizePath?.startsWith("http")) { + return oauthService.authorizePath; + } + if (oauthService.serverURL) { + return new URL( + oauthService.authorizePath, + oauthService.serverURL + ).toString(); + } else { + return oauthService.authorizePath; + } +}; export default getAuthorizationUrl; diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts index 91b9edfc0..ff36dfb6a 100644 --- a/packages/auth/src/index.ts +++ b/packages/auth/src/index.ts @@ -1,4 +1,4 @@ -export * from './auth'; -export { default as RocketChatAuth } from './RocketChatAuth'; -export * from './IRocketChatAuthOptions'; -export {ApiError} from './Api'; \ No newline at end of file +export * from "./auth"; +export { default as RocketChatAuth } from "./RocketChatAuth"; +export * from "./IRocketChatAuthOptions"; +export { ApiError } from "./Api"; diff --git a/packages/auth/src/loginWithOAuthServiceToken.ts b/packages/auth/src/loginWithOAuthServiceToken.ts index bd823505b..64518ee44 100644 --- a/packages/auth/src/loginWithOAuthServiceToken.ts +++ b/packages/auth/src/loginWithOAuthServiceToken.ts @@ -1,17 +1,17 @@ import { Api } from "./Api"; const loginWithOAuthServiceToken = async ( - config: { - api: Api - }, - credentials: { - service: string; - access_token: string; - [key:string]: string; - } + config: { + api: Api; + }, + credentials: { + service: string; + access_token: string; + [key: string]: string; + } ) => { - const response = await config.api.post('/api/v1/login', credentials) - return response.data; -} + const response = await config.api.post("/api/v1/login", credentials); + return response.data; +}; export default loginWithOAuthServiceToken; diff --git a/packages/auth/src/loginWithPassword.ts b/packages/auth/src/loginWithPassword.ts index c85a2ee1f..7843efb38 100644 --- a/packages/auth/src/loginWithPassword.ts +++ b/packages/auth/src/loginWithPassword.ts @@ -1,23 +1,25 @@ import { Api } from "./Api"; const loginWithPassword = async ( - config : { - api: Api; - }, { - user, - password, - code, - }: { - user: string; - password: string; - code?: string | number; -}) => { - const response = await config.api.post('/api/v1/login', { - user, - password, - code - }) - return response.data; -} + config: { + api: Api; + }, + { + user, + password, + code, + }: { + user: string; + password: string; + code?: string | number; + } +) => { + const response = await config.api.post("/api/v1/login", { + user, + password, + code, + }); + return response.data; +}; export default loginWithPassword; diff --git a/packages/auth/src/loginWithResumeToken.ts b/packages/auth/src/loginWithResumeToken.ts index e85407dbd..b9b1f2b6e 100644 --- a/packages/auth/src/loginWithResumeToken.ts +++ b/packages/auth/src/loginWithResumeToken.ts @@ -1,15 +1,15 @@ import { Api } from "./Api"; const loginWithResumeToken = async ( - config: { - api: Api - }, - credentials: { - resume: string - } + config: { + api: Api; + }, + credentials: { + resume: string; + } ) => { - const response = await config.api.post('/api/v1/login', credentials) - return response.data; -} + const response = await config.api.post("/api/v1/login", credentials); + return response.data; +}; export default loginWithResumeToken; diff --git a/packages/auth/src/loginWithRocketChatOAuth.ts b/packages/auth/src/loginWithRocketChatOAuth.ts index 7eea59823..de01ae295 100644 --- a/packages/auth/src/loginWithRocketChatOAuth.ts +++ b/packages/auth/src/loginWithRocketChatOAuth.ts @@ -52,17 +52,17 @@ width=800,height=600,left=-1000,top=-1000,rel=opener`; expiresIn, serviceName, }); - popup.close(); + popup.close(); resolve(response.data); } }; window.addEventListener("message", onMessage); const checkInterval = setInterval(() => { - if (popup.closed) { - clearInterval(checkInterval); - window.removeEventListener("message", onMessage); - } - }, 1000); + if (popup.closed) { + clearInterval(checkInterval); + window.removeEventListener("message", onMessage); + } + }, 1000); } else { throw new Error("Popup blocked"); } diff --git a/packages/auth/src/utils/constants.ts b/packages/auth/src/utils/constants.ts index 25b9dd64f..846757b54 100644 --- a/packages/auth/src/utils/constants.ts +++ b/packages/auth/src/utils/constants.ts @@ -1 +1 @@ -export const ROCKETCHAT_APP_ID = '4c977b2e-eda2-4627-8bfe-2d0358304a79'; +export const ROCKETCHAT_APP_ID = "4c977b2e-eda2-4627-8bfe-2d0358304a79"; diff --git a/packages/auth/src/utils/getRCAppBaseURL.ts b/packages/auth/src/utils/getRCAppBaseURL.ts index 4850de224..6416e06a6 100644 --- a/packages/auth/src/utils/getRCAppBaseURL.ts +++ b/packages/auth/src/utils/getRCAppBaseURL.ts @@ -1,6 +1,6 @@ -import { ROCKETCHAT_APP_ID } from "./constants" +import { ROCKETCHAT_APP_ID } from "./constants"; export const getRCAppBaseURL = (host: string) => { - const url = new URL(`api/apps/public/${ROCKETCHAT_APP_ID}`, host); - return url.toString(); -} + const url = new URL(`api/apps/public/${ROCKETCHAT_APP_ID}`, host); + return url.toString(); +}; diff --git a/packages/auth/src/utils/getRCAppInfo.ts b/packages/auth/src/utils/getRCAppInfo.ts index ea4e0d617..191cac93d 100644 --- a/packages/auth/src/utils/getRCAppInfo.ts +++ b/packages/auth/src/utils/getRCAppInfo.ts @@ -1,12 +1,12 @@ import { getRCAppBaseURL } from "./getRCAppBaseURL"; export const getRCAppInfo = async (host: string) => { - const rcAppBaseUrl = getRCAppBaseURL(host); - const infoUrl = rcAppBaseUrl + '/info'; - const response = await fetch(infoUrl.toString()); - if (!response.ok) { - return null; - } - const info = await response.json(); - return info; -} + const rcAppBaseUrl = getRCAppBaseURL(host); + const infoUrl = rcAppBaseUrl + "/info"; + const response = await fetch(infoUrl.toString()); + if (!response.ok) { + return null; + } + const info = await response.json(); + return info; +}; diff --git a/packages/auth/src/utils/getRCAuthorizeURL.ts b/packages/auth/src/utils/getRCAuthorizeURL.ts index a8c0a71c2..6ddec5606 100644 --- a/packages/auth/src/utils/getRCAuthorizeURL.ts +++ b/packages/auth/src/utils/getRCAuthorizeURL.ts @@ -1,8 +1,12 @@ -export const getRCAuthorizeURL = (host: string, redirectUri: string, clientId: string) => { - const url = new URL(`oauth/authorize`, host); - url.searchParams.set('response_type', 'code'); - url.searchParams.set('client_id', clientId); - url.searchParams.set('redirect_uri', redirectUri); - url.searchParams.set('state', encodeURIComponent(window.location.origin)); - return url.toString(); -} +export const getRCAuthorizeURL = ( + host: string, + redirectUri: string, + clientId: string +) => { + const url = new URL(`oauth/authorize`, host); + url.searchParams.set("response_type", "code"); + url.searchParams.set("client_id", clientId); + url.searchParams.set("redirect_uri", redirectUri); + url.searchParams.set("state", encodeURIComponent(window.location.origin)); + return url.toString(); +}; diff --git a/packages/e2e-react/package.json b/packages/e2e-react/package.json index 95db2f5f7..12f62bd10 100644 --- a/packages/e2e-react/package.json +++ b/packages/e2e-react/package.json @@ -8,7 +8,9 @@ "build": "tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview", - "test": "playwright test" + "test": "playwright test", + "format": "prettier --write 'src/' ", + "format:check": "prettier --check 'src/' " }, "dependencies": { "@embeddedchat/react": "*", diff --git a/packages/e2e-react/src/main.tsx b/packages/e2e-react/src/main.tsx index e63eef4a8..95e2bdc2c 100644 --- a/packages/e2e-react/src/main.tsx +++ b/packages/e2e-react/src/main.tsx @@ -1,9 +1,9 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.tsx' +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.tsx"; -ReactDOM.createRoot(document.getElementById('root')!).render( +ReactDOM.createRoot(document.getElementById("root")!).render( - , -) + +); diff --git a/packages/htmlembed/package.json b/packages/htmlembed/package.json index ce5b68820..33a837024 100644 --- a/packages/htmlembed/package.json +++ b/packages/htmlembed/package.json @@ -8,7 +8,9 @@ "private": true, "scripts": { "build": "vite build && node postbuild.cjs", - "preview": "npm run build && vite preview --port=4001" + "preview": "npm run build && vite preview --port=4001", + "format": "prettier --write 'src/' ", + "format:check": "prettier --check 'src/' " }, "dependencies": { "@embeddedchat/react": "0.1.12", diff --git a/packages/htmlembed/src/EmbeddedChat.jsx b/packages/htmlembed/src/EmbeddedChat.jsx index a771bfd1b..71fae93f4 100644 --- a/packages/htmlembed/src/EmbeddedChat.jsx +++ b/packages/htmlembed/src/EmbeddedChat.jsx @@ -1,37 +1,39 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import { EmbeddedChat as EmbeddedChatComponent } from '@embeddedchat/react'; +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( - - - - ) - }, - renderInElementWithSelector(config, selector) { - if(!selector) { - throw new Error("Please provide a valid selector to render embeddedchat"); - } - ReactDOM.createRoot(document.querySelector(selector)).render( - - - - ) - }, - renderInElement(config, element) { - if (!element) { - throw new Error("Please provide a valid element to render embeddedchat"); - } - ReactDOM.createRoot(element).render( - - - - ) - } -} + 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( + + + + ); + }, + renderInElementWithSelector(config, selector) { + if (!selector) { + throw new Error("Please provide a valid selector to render embeddedchat"); + } + ReactDOM.createRoot(document.querySelector(selector)).render( + + + + ); + }, + renderInElement(config, element) { + if (!element) { + throw new Error("Please provide a valid element to render embeddedchat"); + } + ReactDOM.createRoot(element).render( + + + + ); + }, +}; export default EmbeddedChat; diff --git a/packages/rc-app/endpoints/CallbackEndpoint.ts b/packages/rc-app/endpoints/CallbackEndpoint.ts index c230a716e..1a5e6560e 100644 --- a/packages/rc-app/endpoints/CallbackEndpoint.ts +++ b/packages/rc-app/endpoints/CallbackEndpoint.ts @@ -55,30 +55,42 @@ export class CallbackEndpoint extends ApiEndpoint { const response = await http.post(tokenUrl, { content: formData.toString(), headers: { - 'Content-Type': 'application/x-www-form-urlencoded', + "Content-Type": "application/x-www-form-urlencoded", }, - }) + }); if (response.statusCode !== 200) { - return { - status: response.statusCode, - content: await getCallbackContent(read, null, origin, response.data.error_description || 'Unknown'), - headers: { - 'Content-Security-Policy': "default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; frame-src 'self'; font-src 'self'; object-src 'none'", - } - } + return { + status: response.statusCode, + content: await getCallbackContent( + read, + null, + origin, + response.data.error_description || "Unknown" + ), + headers: { + "Content-Security-Policy": + "default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; frame-src 'self'; font-src 'self'; object-src 'none'", + }, + }; } return { status: 200, - content: await getCallbackContent(read, { - accessToken: response.data?.access_token, - expiresIn: response.data?.expires_in, - serviceName: customOAuthName, - }, origin, false), + content: await getCallbackContent( + read, + { + accessToken: response.data?.access_token, + expiresIn: response.data?.expires_in, + serviceName: customOAuthName, + }, + origin, + false + ), headers: { - 'Content-Security-Policy': "default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; frame-src 'self'; font-src 'self'; object-src 'none'", - } + "Content-Security-Policy": + "default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; frame-src 'self'; font-src 'self'; object-src 'none'", + }, }; } } diff --git a/packages/rc-app/endpoints/InfoEndpoint.ts b/packages/rc-app/endpoints/InfoEndpoint.ts index 8548bc8a1..ab0a69dd9 100644 --- a/packages/rc-app/endpoints/InfoEndpoint.ts +++ b/packages/rc-app/endpoints/InfoEndpoint.ts @@ -52,8 +52,8 @@ export class InfoEndpoint extends ApiEndpoint { client_id: !!client_id, client_secret: !!client_secret, custom_oauth_name: !!serviceName, - } - } - } + }, + }, + }; } } diff --git a/packages/rc-app/lib/getAllowedOrigins.ts b/packages/rc-app/lib/getAllowedOrigins.ts index ea30e038c..aa94c4d7f 100644 --- a/packages/rc-app/lib/getAllowedOrigins.ts +++ b/packages/rc-app/lib/getAllowedOrigins.ts @@ -1,8 +1,13 @@ export const getAllowedOrigins = async (read) => { - const allowedOrigins = await read.getEnvironmentReader().getSettings().getValueById("allowed-origins"); + const allowedOrigins = await read + .getEnvironmentReader() + .getSettings() + .getValueById("allowed-origins"); if (!allowedOrigins) { return []; } - const origins = allowedOrigins.split(',').filter((domain) => !!domain.trim()); + const origins = allowedOrigins + .split(",") + .filter((domain) => !!domain.trim()); return origins; -} +}; diff --git a/packages/rc-app/lib/getCallbackContent.ts b/packages/rc-app/lib/getCallbackContent.ts index c8c1a2898..165aa1c1b 100644 --- a/packages/rc-app/lib/getCallbackContent.ts +++ b/packages/rc-app/lib/getCallbackContent.ts @@ -5,22 +5,27 @@ interface ICredentials { accessToken: string; expiresIn: number; serviceName: string; -}; +} -export const getCallbackContent = async (read: IRead, credentials: ICredentials | null, origin: string, error) => { +export const getCallbackContent = async ( + read: IRead, + credentials: ICredentials | null, + origin: string, + error +) => { const { accessToken, expiresIn = 3600, serviceName } = credentials || {}; - const isAllowed = await isAllowedOrigin(read, origin);; + const isAllowed = await isAllowedOrigin(read, origin); let config: any = {}; if (error) { config = { success: false, error, - } + }; } else if (!isAllowed) { config = { success: false, - error: 'origin not allowed', - } + error: "origin not allowed", + }; } else { config = { success: true, @@ -29,8 +34,8 @@ export const getCallbackContent = async (read: IRead, credentials: ICredentials accessToken, expiresIn, serviceName, - } - } + }, + }; } const closeLinkHtml = `

${ config.success ? "Login Successful" : "Login Failed: " + config.error @@ -66,4 +71,4 @@ export const getCallbackContent = async (read: IRead, credentials: ICredentials `; -} +}; diff --git a/packages/rc-app/lib/getCallbackUrl.ts b/packages/rc-app/lib/getCallbackUrl.ts index 2d129497b..3174e7bbe 100644 --- a/packages/rc-app/lib/getCallbackUrl.ts +++ b/packages/rc-app/lib/getCallbackUrl.ts @@ -8,11 +8,12 @@ export const getCallbackUrl = async (app: IApp) => { .getValueById("Site_Url"); const callbackEndPoint = app .getAccessors() - .providedApiEndpoints.find( - (endpoint) => endpoint.path === "callback" - ); + .providedApiEndpoints.find((endpoint) => endpoint.path === "callback"); if (callbackEndPoint) { - const webhookURL = new URL(callbackEndPoint.computedPath || "", serverURL) + const webhookURL = new URL( + callbackEndPoint.computedPath || "", + serverURL + ); return webhookURL.toString(); } return ""; diff --git a/packages/rc-app/lib/getTokenUrl.ts b/packages/rc-app/lib/getTokenUrl.ts index b0a71a84d..c7128c5ac 100644 --- a/packages/rc-app/lib/getTokenUrl.ts +++ b/packages/rc-app/lib/getTokenUrl.ts @@ -2,7 +2,10 @@ import { IRead } from "@rocket.chat/apps-engine/definition/accessors"; import { URL } from "url"; export const getTokenUrl = async (read: IRead) => { - const serverURL = await read.getEnvironmentReader().getServerSettings().getValueById("Site_Url"); - const url = new URL('/oauth/token', serverURL); + const serverURL = await read + .getEnvironmentReader() + .getServerSettings() + .getValueById("Site_Url"); + const url = new URL("/oauth/token", serverURL); return url.toString(); -} +}; diff --git a/packages/rc-app/lib/isAllowedOrigin.ts b/packages/rc-app/lib/isAllowedOrigin.ts index ff6a26d58..1bf7e3019 100644 --- a/packages/rc-app/lib/isAllowedOrigin.ts +++ b/packages/rc-app/lib/isAllowedOrigin.ts @@ -8,4 +8,4 @@ export const isAllowedOrigin = async (read: IRead, origin: string) => { return true; } return allowedOrigins.includes(origin); -} +}; diff --git a/packages/rc-app/package.json b/packages/rc-app/package.json index a31494bc7..a55446ec3 100644 --- a/packages/rc-app/package.json +++ b/packages/rc-app/package.json @@ -7,5 +7,9 @@ "@types/node": "14.14.6", "tslint": "^5.10.0", "typescript": "^4.0.5" + }, + "scripts": { + "format": "prettier --write '*/**.ts'", + "format:check": "prettier --check '*/**.ts'" } } diff --git a/packages/rc-app/settings/settings.ts b/packages/rc-app/settings/settings.ts index fb925485b..268bb91b9 100644 --- a/packages/rc-app/settings/settings.ts +++ b/packages/rc-app/settings/settings.ts @@ -1,41 +1,46 @@ -import { ISetting, SettingType } from '@rocket.chat/apps-engine/definition/settings'; +import { + ISetting, + SettingType, +} from "@rocket.chat/apps-engine/definition/settings"; -export const settings:ISetting[] = [ - { - id: 'client-id', - i18nLabel: 'Client ID', - i18nDescription: 'The client id of the third party login app', - type: SettingType.STRING, - required: true, - public: false, - packageValue: '', - }, - { - id: 'client-secret', - i18nLabel: 'Client Secret', - i18nDescription: 'The client secret of the third party login app', - type: SettingType.PASSWORD, - required: true, - public: false, - packageValue: '', - }, +export const settings: ISetting[] = [ { - id: 'allowed-origins', - i18nLabel: 'Allowed origins', - i18nDescription: 'The allowed origins for third party login for EmbeddedChat (Comma separated). Leave blank to allow all origins.', - type: SettingType.STRING, - required: false, - public: false, - packageValue: '', + id: "client-id", + i18nLabel: "Client ID", + i18nDescription: "The client id of the third party login app", + type: SettingType.STRING, + required: true, + public: false, + packageValue: "", + }, + { + id: "client-secret", + i18nLabel: "Client Secret", + i18nDescription: "The client secret of the third party login app", + type: SettingType.PASSWORD, + required: true, + public: false, + packageValue: "", + }, + { + id: "allowed-origins", + i18nLabel: "Allowed origins", + i18nDescription: + "The allowed origins for third party login for EmbeddedChat (Comma separated). Leave blank to allow all origins.", + type: SettingType.STRING, + required: false, + public: false, + packageValue: "", multiline: true, - }, + }, { - id: 'custom-oauth-name', - i18nLabel: 'Custom OAuth Name', - i18nDescription: 'Provide name with which the custom oauth is saved. The custom oauth should be configured with the above third party login app.', - type: SettingType.STRING, - required: false, - public: false, - packageValue: '', - } -] + id: "custom-oauth-name", + i18nLabel: "Custom OAuth Name", + i18nDescription: + "Provide name with which the custom oauth is saved. The custom oauth should be configured with the above third party login app.", + type: SettingType.STRING, + required: false, + public: false, + packageValue: "", + }, +]; diff --git a/packages/react/.eslintignore b/packages/react/.eslintignore index 2f5d60c64..3d9e4d531 100644 --- a/packages/react/.eslintignore +++ b/packages/react/.eslintignore @@ -1 +1,2 @@ -rollup.config.js \ No newline at end of file +rollup.config.js +*.test.js diff --git a/packages/react/.gitignore b/packages/react/.gitignore index efccce6e7..ac494021e 100644 --- a/packages/react/.gitignore +++ b/packages/react/.gitignore @@ -105,3 +105,5 @@ dist # pnpm-lock pnpm-lock.yaml + +storybook-static/ diff --git a/packages/react/package.json b/packages/react/package.json index 971b1649d..5e9df2fe9 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -21,7 +21,9 @@ "test:unit": "cross-env CI=1 react-scripts test --env=jsdom", "test:watch": "react-scripts test --env=jsdom --coverage --collectCoverageFrom=src/components/**/*.js", "test:build": "run-s build", - "format": "prettier --write 'src/' --loglevel=silent", + "format": "prettier --write 'src/' ", + "format:check": "prettier --check 'src/' ", + "lint": "eslint 'src/**/*.js'", "lint:fix": "eslint 'src/**/*.js' --fix", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", diff --git a/packages/react/src/components/Attachments/AttachmentWindow.js b/packages/react/src/components/Attachments/AttachmentWindow.js index 9536ace88..3fce7ddfd 100644 --- a/packages/react/src/components/Attachments/AttachmentWindow.js +++ b/packages/react/src/components/Attachments/AttachmentWindow.js @@ -1,4 +1,5 @@ import React, { useContext, useState } from 'react'; +import { css } from '@emotion/react'; import useAttachmentWindowStore from '../../store/attachmentwindow'; import ValidateComponent from './AttachmentWindow/validateComponent'; import Backdrop from './AttachmentWindow/Backdrop'; @@ -7,7 +8,6 @@ import styles from './AttachmentWindow.module.css'; import { useMessageStore } from '../../store'; import { Box } from '../Box'; import { Icon } from '../Icon'; -import { css } from '@emotion/react'; function AttachmentWindow() { const { RCInstance, ECOptions } = useContext(RCContext); @@ -61,29 +61,30 @@ function AttachmentWindow() { - + diff --git a/packages/react/src/components/Attachments/AttachmentWindow.module.css b/packages/react/src/components/Attachments/AttachmentWindow.module.css index 8a5a6b1c3..16a27d2a3 100644 --- a/packages/react/src/components/Attachments/AttachmentWindow.module.css +++ b/packages/react/src/components/Attachments/AttachmentWindow.module.css @@ -54,7 +54,7 @@ } .attachment_window_close:active { - background-color: #8f9194; + background-color: #8f9194; } .attachment_window_input_container { @@ -109,8 +109,8 @@ outline: none; border: none; border-radius: 4px; - cursor: pointer; - background: #e4e7ea; + cursor: pointer; + background: #e4e7ea; margin-right: 5px; } diff --git a/packages/react/src/components/Attachments/AttachmentWindow/Backdrop.js b/packages/react/src/components/Attachments/AttachmentWindow/Backdrop.js index 038673b22..7cb4e2fc4 100644 --- a/packages/react/src/components/Attachments/AttachmentWindow/Backdrop.js +++ b/packages/react/src/components/Attachments/AttachmentWindow/Backdrop.js @@ -2,22 +2,21 @@ import React from 'react'; import { Box } from '../../Box'; const Backdrop = ({ children, onClick }) => ( - - {children} - + + {children} + ); export default Backdrop; diff --git a/packages/react/src/components/Attachments/AttachmentWindow/preview/image.js b/packages/react/src/components/Attachments/AttachmentWindow/preview/image.js index a14f45793..4905104a6 100644 --- a/packages/react/src/components/Attachments/AttachmentWindow/preview/image.js +++ b/packages/react/src/components/Attachments/AttachmentWindow/preview/image.js @@ -5,10 +5,7 @@ import { Box } from '../../../Box'; function PreviewImage({ previewURL }) { return ( - + ); } diff --git a/packages/react/src/components/Attachments/AttachmentWindow/validateComponent.js b/packages/react/src/components/Attachments/AttachmentWindow/validateComponent.js index 74083e4e7..67f77847b 100644 --- a/packages/react/src/components/Attachments/AttachmentWindow/validateComponent.js +++ b/packages/react/src/components/Attachments/AttachmentWindow/validateComponent.js @@ -11,12 +11,11 @@ const ValidateComponent = ({ data }) => { const [previewURL, setPreviewURL] = useState(''); const dispatchToastMessage = useToastBarDispatch(); - useEffect(() => { if (!data) { dispatchToastMessage({ type: 'error', - message: 'Media Type Not Accepted' + message: 'Media Type Not Accepted', }); } }, [data, dispatchToastMessage]); diff --git a/packages/react/src/components/Attachments/PinnedAttachment.js b/packages/react/src/components/Attachments/PinnedAttachment.js index 4e0588096..ae694b2a6 100644 --- a/packages/react/src/components/Attachments/PinnedAttachment.js +++ b/packages/react/src/components/Attachments/PinnedAttachment.js @@ -6,7 +6,7 @@ const PinnedAttachment = ({ attachment }) => ( {attachment?.author_name} diff --git a/packages/react/src/components/ChatBody/RecentMessageButton.js b/packages/react/src/components/ChatBody/RecentMessageButton.js index b02c46ac6..c843affd5 100644 --- a/packages/react/src/components/ChatBody/RecentMessageButton.js +++ b/packages/react/src/components/ChatBody/RecentMessageButton.js @@ -1,8 +1,7 @@ import React, { useState } from 'react'; +import { css } from '@emotion/react'; import { Button } from '../Button'; import { Icon } from '../Icon'; -import { css } from '@emotion/react'; - const buttonStyle = css` position: relative; @@ -55,11 +54,7 @@ const RecentMessageButton = ({ visible, onClick, text }) => { return ( } + {isReplyButton && ( + + )}

{message.tcount}
diff --git a/packages/react/src/components/Message/MessageToolbox.js b/packages/react/src/components/Message/MessageToolbox.js index 83cc3c7d8..8826bc026 100644 --- a/packages/react/src/components/Message/MessageToolbox.js +++ b/packages/react/src/components/Message/MessageToolbox.js @@ -18,7 +18,7 @@ const MessageToolboxWrapperCss = css` position: absolute; bottom: 100%; z-index: 90; - right:2rem; + right: 2rem; } `; @@ -41,7 +41,7 @@ const popupStyle = { margin: '0', position: 'absolute', right: '2rem', - top: '7.5rem' + top: '7.5rem', }; export const MessageToolbox = ({ @@ -98,11 +98,12 @@ export const MessageToolbox = ({ u._id === authenticatedUserId) - ? 'star-filled' - : 'star' - }`} + ? 'star-filled' + : 'star' + }`} onClick={() => handleStarMessage(message)} /> handlePinMessage(message)} /> )} @@ -167,7 +165,12 @@ export const MessageToolbox = ({ - Delete this message? + {' '} + Delete this message? diff --git a/packages/react/src/components/Modal/Modal.js b/packages/react/src/components/Modal/Modal.js index 260b9e016..791ee9e92 100644 --- a/packages/react/src/components/Modal/Modal.js +++ b/packages/react/src/components/Modal/Modal.js @@ -5,7 +5,17 @@ import { Box } from '../Box'; import { ModalBackdrop } from './ModalBackdrop'; export const Modal = forwardRef( - ({ className = '', style = {}, open = true, children, onClose = () => { }, ...props }, ref) => { + ( + { + className = '', + style = {}, + open = true, + children, + onClose = () => {}, + ...props + }, + ref + ) => { const { classNames, styleOverrides } = useComponentOverrides('Modal'); const backDropRef = useRef(null); const theme = useTheme(); @@ -36,11 +46,14 @@ export const Modal = forwardRef( [onClose] ); - const handleEscKey = useCallback((e) => { - if (e.key === 'Escape') { - onClose(); - } - }, [onClose]); + const handleEscKey = useCallback( + (e) => { + if (e.key === 'Escape') { + onClose(); + } + }, + [onClose] + ); useEffect(() => { window.addEventListener('keydown', handleEscKey); diff --git a/packages/react/src/components/Modal/ModalBackdrop.js b/packages/react/src/components/Modal/ModalBackdrop.js index 58fc13288..0b23e6fb0 100644 --- a/packages/react/src/components/Modal/ModalBackdrop.js +++ b/packages/react/src/components/Modal/ModalBackdrop.js @@ -1,8 +1,8 @@ import React, { forwardRef } from 'react'; import { Box } from '../Box'; -export const ModalBackdrop = forwardRef(({ children, onClick = () => { } }, ref) => { - return ( +export const ModalBackdrop = forwardRef( + ({ children, onClick = () => {} }, ref) => ( { } }, ref) {children} ) -}); +); diff --git a/packages/react/src/components/ReportMessage/MessageReportWindow.js b/packages/react/src/components/ReportMessage/MessageReportWindow.js index 5ada6ac4d..4ff0d0152 100644 --- a/packages/react/src/components/ReportMessage/MessageReportWindow.js +++ b/packages/react/src/components/ReportMessage/MessageReportWindow.js @@ -27,7 +27,7 @@ const MessageReportWindow = ({ messageId }) => { display: 'flex', justifyContent: 'center', marginBottom: '0.125rem', - padding:'0.6rem 0' + padding: '0.6rem 0', }} > { - + Report this message? diff --git a/packages/react/src/components/SearchMessage/SearchMessage.js b/packages/react/src/components/SearchMessage/SearchMessage.js index f5cc41c72..fa44ddf97 100644 --- a/packages/react/src/components/SearchMessage/SearchMessage.js +++ b/packages/react/src/components/SearchMessage/SearchMessage.js @@ -71,7 +71,12 @@ const Search = () => { className={classes.textInput} /> - + {messageList && messageList.map((msg, index, arr) => { diff --git a/packages/react/src/components/Skeleton/index.js b/packages/react/src/components/Skeleton/index.js index 680b47f18..b160869b2 100644 --- a/packages/react/src/components/Skeleton/index.js +++ b/packages/react/src/components/Skeleton/index.js @@ -1,2 +1 @@ export { default as Skeleton } from './Skeleton'; - diff --git a/packages/react/src/components/ToastBar/ToastContainer.js b/packages/react/src/components/ToastBar/ToastContainer.js index 34cf4db14..1b1f3c43c 100644 --- a/packages/react/src/components/ToastBar/ToastContainer.js +++ b/packages/react/src/components/ToastBar/ToastContainer.js @@ -1,5 +1,5 @@ import React, { useContext, useMemo, useCallback } from 'react'; -import { css, useTheme, keyframes} from '@emotion/react'; +import { css, useTheme, keyframes } from '@emotion/react'; import ToastContext from '../../context/ToastContext'; import { Box } from '../Box'; import ToastBar from './ToastBar'; @@ -25,7 +25,7 @@ const ToastContainer = () => { position: fixed; z-index: ${theme.zIndex.toastbar}; border-radius: 0.25em; - background-color:white; + background-color: white; animation: ${animation} ${2000}ms ease-in-out forwards; `; diff --git a/packages/react/src/components/Tooltip/Tooltip.js b/packages/react/src/components/Tooltip/Tooltip.js index 40e02a37f..a8cc0aac6 100644 --- a/packages/react/src/components/Tooltip/Tooltip.js +++ b/packages/react/src/components/Tooltip/Tooltip.js @@ -1,86 +1,83 @@ import React, { useState } from 'react'; const Tooltip = ({ children, text, position }) => { - const [isTooltipVisible, setTooltipVisible] = useState(false); + const [isTooltipVisible, setTooltipVisible] = useState(false); - const tooltipStyle = { - position: 'absolute', - left: '64%', - transform: 'translateX(-50%) ', - backgroundColor: 'rgba(97, 97, 97, 1)', - color: 'white', - padding: '4px', - borderRadius: '3px', - boxShadow: '0 2px 10px rgba(0, 0, 0, 0.2)', - zIndex: 9999, - fontSize: '12.5px', - whiteSpace: 'nowrap', - fontFamily: 'sans-serif' - } + const tooltipStyle = { + position: 'absolute', + left: '64%', + transform: 'translateX(-50%) ', + backgroundColor: 'rgba(97, 97, 97, 1)', + color: 'white', + padding: '4px', + borderRadius: '3px', + boxShadow: '0 2px 10px rgba(0, 0, 0, 0.2)', + zIndex: 9999, + fontSize: '12.5px', + whiteSpace: 'nowrap', + fontFamily: 'sans-serif', + }; - const tooltipArrowStyle = { - content: '""', - position: 'absolute', - left: '50%', - marginLeft: '-5px', - borderWidth: '6px', - borderStyle: 'solid', - borderColor: 'rgba(97, 97, 97, 1) transparent transparent transparent', - } + const tooltipArrowStyle = { + content: '""', + position: 'absolute', + left: '50%', + marginLeft: '-5px', + borderWidth: '6px', + borderStyle: 'solid', + borderColor: 'rgba(97, 97, 97, 1) transparent transparent transparent', + }; - // Add more positions according to your needs and modify tooltipStyle and tooltipArrowStyle accordingly + // Add more positions according to your needs and modify tooltipStyle and tooltipArrowStyle accordingly - if (position === "top") { - tooltipStyle.top = '-100%'; - tooltipArrowStyle.top = '100%'; - tooltipArrowStyle.transform = 'translateX(-50%)'; - } - else if (position === "bottom") { - tooltipStyle.top = '100%'; - tooltipArrowStyle.bottom = '100%'; - tooltipArrowStyle.transform = 'translateX(-50%) rotate(180deg)'; - } + if (position === 'top') { + tooltipStyle.top = '-100%'; + tooltipArrowStyle.top = '100%'; + tooltipArrowStyle.transform = 'translateX(-50%)'; + } else if (position === 'bottom') { + tooltipStyle.top = '100%'; + tooltipArrowStyle.bottom = '100%'; + tooltipArrowStyle.transform = 'translateX(-50%) rotate(180deg)'; + } + const handleMouseEnter = () => { + setTooltipVisible(true); + }; - const handleMouseEnter = () => { - setTooltipVisible(true); - }; + const handleMouseLeave = () => { + setTooltipVisible(false); + }; - const handleMouseLeave = () => { - setTooltipVisible(false); - }; + const handleTouchStart = () => { + touchTimer = setTimeout(() => { + setTooltipVisible(true); + }, 500); + }; - const handleTouchStart = () => { - touchTimer = setTimeout(() => { - setTooltipVisible(true); - }, 500); - }; + const handleTouchEnd = () => { + clearTimeout(touchTimer); + setTooltipVisible(false); + }; - const handleTouchEnd = () => { + let touchTimer; - clearTimeout(touchTimer); - setTooltipVisible(false); - }; - - let touchTimer; - - return ( -
- {children} - {isTooltipVisible && ( -
- {text.charAt(0).toUpperCase() + text.slice(1)} -
-
- )} + return ( +
+ {children} + {isTooltipVisible && ( +
+ {text.charAt(0).toUpperCase() + text.slice(1)} +
- ); + )} +
+ ); }; export default Tooltip; diff --git a/packages/react/src/components/Tooltip/index.js b/packages/react/src/components/Tooltip/index.js index fb3db17fc..49ab72ce0 100644 --- a/packages/react/src/components/Tooltip/index.js +++ b/packages/react/src/components/Tooltip/index.js @@ -1,2 +1 @@ -export {default as Tooltip} from "./Tooltip"; - +export { default as Tooltip } from './Tooltip'; diff --git a/packages/react/src/components/auth/LoginForm.js b/packages/react/src/components/auth/LoginForm.js index ce1f3bedf..ff0cdafce 100644 --- a/packages/react/src/components/auth/LoginForm.js +++ b/packages/react/src/components/auth/LoginForm.js @@ -21,23 +21,23 @@ export default function LoginForm() { ); const { handleLogin } = useRCAuth(); - useEffect(()=>{ - if(userOrEmail !== null && userOrEmail.trim() === ''){ + useEffect(() => { + if (userOrEmail !== null && userOrEmail.trim() === '') { setUsernameError(true); - }else{ + } else { setUsernameError(false); } - if(password !== null && password.trim() === ''){ + if (password !== null && password.trim() === '') { setPasswordError(true); - }else{ + } else { setPasswordError(false); } - },[userOrEmail,password]) + }, [userOrEmail, password]); const handleSubmit = () => { - if(!userOrEmail) setUserOrEmail(''); - if(!password) setPassword(''); + if (!userOrEmail) setUserOrEmail(''); + if (!password) setPassword(''); handleLogin(userOrEmail, password); }; const handleClose = () => { @@ -119,7 +119,11 @@ export default function LoginForm() { style={{ borderColor: usernameError ? 'red' : '' }} /> - {usernameError && This field is required} + {usernameError && ( + + This field is required + + )} @@ -139,7 +143,11 @@ export default function LoginForm() { {showPassword ? : } - {passwordError && This field is required} + {passwordError && ( + + This field is required + + )} { primary={block.style === 'primary'} danger={block.style === 'danger'} minWidth="4ch" - size='medium' + size="medium" value={block.value} onClick={action} > diff --git a/packages/react/src/hooks/useDropBox.js b/packages/react/src/hooks/useDropBox.js index 31a5acde6..bfd63360c 100644 --- a/packages/react/src/hooks/useDropBox.js +++ b/packages/react/src/hooks/useDropBox.js @@ -1,44 +1,48 @@ import { useState } from 'react'; import useAttachmentWindowStore from '../store/attachmentwindow'; - const useDropBox = () => { + const data = useAttachmentWindowStore((state) => state.data); + const setData = useAttachmentWindowStore((state) => state.setData); + const toggle = useAttachmentWindowStore((state) => state.toggle); - const data = useAttachmentWindowStore((state) => state.data); - const setData = useAttachmentWindowStore((state) => state.setData); - const toggle = useAttachmentWindowStore((state) => state.toggle); - - const [onDrag, setOnDrag] = useState(false); - const [leaveCount, setLeaveCount] = useState(0); - - const handleDrag = (e) => { - e.preventDefault(); - }; + const [onDrag, setOnDrag] = useState(false); + const [leaveCount, setLeaveCount] = useState(0); - const handleDragEnter = () => { - setOnDrag(true); - }; + const handleDrag = (e) => { + e.preventDefault(); + }; - const handleDragLeave = () => { - if ((leaveCount % 2) === 1) { - setOnDrag(false); - setLeaveCount(leaveCount + 1); - } else { - setLeaveCount(leaveCount + 1); - } - }; + const handleDragEnter = () => { + setOnDrag(true); + }; - const handleDragDrop = (e) => { - e.preventDefault(); + const handleDragLeave = () => { + if (leaveCount % 2 === 1) { setOnDrag(false); - setLeaveCount(0); - - toggle(); - setData(e.dataTransfer.files[0]); - }; - - - return { onDrag, data, handleDrag, handleDragEnter, handleDragLeave, handleDragDrop } + setLeaveCount(leaveCount + 1); + } else { + setLeaveCount(leaveCount + 1); + } + }; + + const handleDragDrop = (e) => { + e.preventDefault(); + setOnDrag(false); + setLeaveCount(0); + + toggle(); + setData(e.dataTransfer.files[0]); + }; + + return { + onDrag, + data, + handleDrag, + handleDragEnter, + handleDragLeave, + handleDragDrop, + }; }; export default useDropBox; diff --git a/packages/react/src/lib/createPendingMessage.js b/packages/react/src/lib/createPendingMessage.js index 6e46a2804..da8bdc304 100644 --- a/packages/react/src/lib/createPendingMessage.js +++ b/packages/react/src/lib/createPendingMessage.js @@ -1,5 +1,5 @@ const createRandomId = () => { - if ( typeof window !== 'undefined' ) { + if (typeof window !== 'undefined') { if (window.crypto.randomUUID) { return window.crypto.randomUUID().replaceAll('-', '').slice(0, 17); } diff --git a/packages/react/src/store/channelStore.js b/packages/react/src/store/channelStore.js index fddc512e6..d91bc7daa 100644 --- a/packages/react/src/store/channelStore.js +++ b/packages/react/src/store/channelStore.js @@ -6,7 +6,7 @@ const useChannelStore = create((set) => ({ setShowChannelinfo: (showChannelinfo) => set(() => ({ showChannelinfo })), channelInfo: {}, setChannelInfo: (channelInfo) => set(() => ({ channelInfo })), - setIsChannelPrivate: (isChannelPrivate) => set(() => ({ isChannelPrivate })) + setIsChannelPrivate: (isChannelPrivate) => set(() => ({ isChannelPrivate })), })); export default useChannelStore; diff --git a/packages/react/src/store/messageStore.js b/packages/react/src/store/messageStore.js index 9fdbcc2ef..092c2c692 100644 --- a/packages/react/src/store/messageStore.js +++ b/packages/react/src/store/messageStore.js @@ -12,7 +12,7 @@ const useMessageStore = create((set, get) => ({ isRecordingMessage: false, isThreadOpen: false, threadMainMessage: null, - headerTitle:null, + headerTitle: null, setFilter: (filter) => set(() => ({ filtered: filter })), setMessages: (messages) => set(() => ({ messages })), upsertMessage: (message, enableThreads = false) => { @@ -90,7 +90,7 @@ const useMessageStore = create((set, get) => ({ })); }, setThreadMessages: (messages) => set(() => ({ threadMessages: messages })), - setHeaderTitle: (title) => set(()=>({headerTitle:title})) + setHeaderTitle: (title) => set(() => ({ headerTitle: title })), })); export default useMessageStore; diff --git a/packages/react/src/store/userStore.js b/packages/react/src/store/userStore.js index 813d55643..bc69c2b6c 100644 --- a/packages/react/src/store/userStore.js +++ b/packages/react/src/store/userStore.js @@ -15,11 +15,9 @@ const useUserStore = create((set) => ({ }, avatarUrl: '', setUserAvatarUrl: (avatarUrl) => - set(() => { - return { - avatarUrl, - }; - }), + set(() => ({ + avatarUrl, + })), isUserAuthenticated: false, setIsUserAuthenticated: (isUserAuthenticated) => set(() => ({ isUserAuthenticated })), diff --git a/packages/react/tools/icons-generator.js b/packages/react/tools/icons-generator.js index 135d8d395..c39f180c6 100644 --- a/packages/react/tools/icons-generator.js +++ b/packages/react/tools/icons-generator.js @@ -104,4 +104,4 @@ iconsList.forEach((icon) => { }); fs.writeFileSync(path.join(svgIconOutputDir, 'index.js'), getIndexFileCode()); -execSync(`npx prettier --write '${svgIconOutputDir}' --loglevel=silent`); +execSync(`npx prettier --write '${svgIconOutputDir}' `);