diff --git a/CometChat/components/AddMemberView/index.js b/CometChat/components/AddMemberView/index.js index 42e863b4..f21518d9 100644 --- a/CometChat/components/AddMemberView/index.js +++ b/CometChat/components/AddMemberView/index.js @@ -2,6 +2,7 @@ import { useState } from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import Avatar from "../Avatar"; import StatusIndicator from "../StatusIndicator"; @@ -15,6 +16,7 @@ import { selectionBoxStyle } from "./style"; +import { theme } from "../../resources/theme"; import inactiveIcon from "./resources/checkbox-inactive.svg"; import activeIcon from "./resources/checkbox-blue-active.svg"; @@ -59,17 +61,11 @@ const AddMemberView = (props) => { onMouseEnter={event => toggleTooltip(event, true)} onMouseLeave={event => toggleTooltip(event, false)}>
- + + borderColor={props.theme.borderColor.primary} />
{props.user.name}
@@ -86,4 +82,13 @@ const AddMemberView = (props) => { ) } +// Specifies the default values for props: +AddMemberView.defaultProps = { + theme: theme +}; + +AddMemberView.propTypes = { + theme: PropTypes.object +} + export default AddMemberView; \ No newline at end of file diff --git a/CometChat/components/Avatar/index.js b/CometChat/components/Avatar/index.js index 05c6c13a..4c14d813 100644 --- a/CometChat/components/Avatar/index.js +++ b/CometChat/components/Avatar/index.js @@ -2,10 +2,9 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; -import { - imgStyle -} from "./style"; +import { imgStyle } from "./style"; import srcIcon from "./resources/1px.png"; @@ -19,9 +18,9 @@ class Avatar extends React.Component { render() { - const borderWidth = this.props.borderWidth || '1px'; - const borderColor = this.props.borderColor || '#AAA'; - const cornerRadius = this.props.cornerRadius || '50%'; + const borderWidth = this.props.borderWidth; + const borderColor = this.props.borderColor; + const cornerRadius = this.props.cornerRadius; const image = this.props.image; let img = new Image(); @@ -36,9 +35,24 @@ class Avatar extends React.Component { const getStyle = () => ({ borderWidth: borderWidth, borderStyle: 'solid', borderColor: borderColor, 'borderRadius': cornerRadius }); return ( - Avatar { this.imgRef = el;}} /> + {image} { this.imgRef = el;}} /> ); } } +// Specifies the default values for props: +Avatar.defaultProps = { + borderWidth: "1px", + borderColor: "#AAA", + cornerRadius: "50%", + image: srcIcon +}; + +Avatar.propTypes = { + borderWidth: PropTypes.string, + borderColor: PropTypes.string, + cornerRadius: PropTypes.string, + image: PropTypes.string +} + export default Avatar; \ No newline at end of file diff --git a/CometChat/components/Backdrop/index.js b/CometChat/components/Backdrop/index.js index 1fd583a5..d2db8ad9 100644 --- a/CometChat/components/Backdrop/index.js +++ b/CometChat/components/Backdrop/index.js @@ -1,5 +1,6 @@ /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { backdropStyle @@ -9,4 +10,15 @@ const backdrop = (props) => ( props.show ?
: null ); +// Specifies the default values for props: +backdrop.defaultProps = { + count: 0, + clicked: () => {} +}; + +backdrop.propTypes = { + show: PropTypes.bool, + clicked: PropTypes.func, +} + export default backdrop; \ No newline at end of file diff --git a/CometChat/components/BadgeCount/index.js b/CometChat/components/BadgeCount/index.js index b70f8be1..86da7a95 100644 --- a/CometChat/components/BadgeCount/index.js +++ b/CometChat/components/BadgeCount/index.js @@ -1,9 +1,9 @@ /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; -import { - badgeStyle -} from "./style"; +import { theme } from "../../resources/theme"; +import { badgeStyle } from "./style"; const badgecount = (props) => { @@ -14,7 +14,19 @@ const badgecount = (props) => { {props.count} ); } + return count; } +// Specifies the default values for props: +badgecount.defaultProps = { + count: 0, + theme: theme +}; + +badgecount.propTypes = { + count: PropTypes.number, + theme: PropTypes.object +} + export default badgecount; \ No newline at end of file diff --git a/CometChat/components/BanMemberView/index.js b/CometChat/components/BanMemberView/index.js index b528cf6a..17d4a6bd 100644 --- a/CometChat/components/BanMemberView/index.js +++ b/CometChat/components/BanMemberView/index.js @@ -1,5 +1,6 @@ /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -14,18 +15,20 @@ import { actionStyle } from "./style"; +import Translator from "../../resources/localization/translator"; +import { theme } from "../../resources/theme"; import unban from "./resources/block.png"; const memberview = (props) => { const roles = {} - roles[CometChat.GROUP_MEMBER_SCOPE.ADMIN] = "Administrator"; - roles[CometChat.GROUP_MEMBER_SCOPE.MODERATOR] = "Moderator"; - roles[CometChat.GROUP_MEMBER_SCOPE.PARTICIPANT] = "Participant"; + roles[CometChat.GROUP_MEMBER_SCOPE.ADMIN] = Translator.translate("ADMINISTRATOR", props.lang); + roles[CometChat.GROUP_MEMBER_SCOPE.MODERATOR] = Translator.translate("MODERATOR", props.lang); + roles[CometChat.GROUP_MEMBER_SCOPE.PARTICIPANT] = Translator.translate("PARTICIPANT", props.lang); let name = props.member.name; let scope = roles[props.member.scope]; - let unBan = (Unban {props.actionGenerated("unban", props.member)}} />); + let unBan = ({Translator.translate("UNBAN", {props.actionGenerated("unban", props.member)}} />); //if the loggedin user is moderator, don't allow unban of banned moderators or administrators if(props.item.scope === CometChat.GROUP_MEMBER_SCOPE.MODERATOR @@ -57,7 +60,7 @@ const memberview = (props) => { } else { nameContainer.removeAttribute("title"); } - } + } return ( @@ -65,17 +68,11 @@ const memberview = (props) => { onMouseEnter={event => toggleTooltip(event, true)} onMouseLeave={event => toggleTooltip(event, false)}>
- + + borderColor={props.theme.borderColor.primary} />
{name}
@@ -85,4 +82,15 @@ const memberview = (props) => { ); } +// Specifies the default values for props: +memberview.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +memberview.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default memberview; \ No newline at end of file diff --git a/CometChat/components/BanMemberView/style.js b/CometChat/components/BanMemberView/style.js index e1952251..796fc820 100644 --- a/CometChat/components/BanMemberView/style.js +++ b/CometChat/components/BanMemberView/style.js @@ -8,11 +8,6 @@ export const tableRowStyle = (props) => { fontSize: "14px", "td": { padding: ".625em", - "img": { - width: "36px", - height: "36px", - float: "left", - } } } } @@ -22,10 +17,9 @@ export const avatarStyle = () => { return { display: "inline-block", float: "left", - "span": { - top: "26px", - left: "-8px", - } + width: "36px", + height: "36px", + marginRight: "8px", } } diff --git a/CometChat/components/CallAlert/index.js b/CometChat/components/CallAlert/index.js index c1ec754b..c5230860 100644 --- a/CometChat/components/CallAlert/index.js +++ b/CometChat/components/CallAlert/index.js @@ -2,14 +2,17 @@ import React from "react"; /** @jsx jsx */ import { jsx, keyframes } from "@emotion/core"; +import PropTypes from 'prop-types'; + import { CometChat } from "@cometchat-pro/chat"; import { CometChatManager } from "../../util/controller"; import * as enums from '../../util/enums.js'; - +import { validateWidgetSettings } from "../../util/common"; +import Translator from "../../resources/localization/translator"; import Avatar from "../Avatar"; import { SvgAvatar } from '../../util/svgavatar'; -import { validateWidgetSettings } from "../../util/common"; + import { CallAlertManager } from "./controller"; import { @@ -172,13 +175,13 @@ class CallAlert extends React.PureComponent { let callType = ( - Incoming audio callIncoming audio call + {Translator.translate("INCOMING_AUDIO_CALL",{Translator.translate("INCOMING_AUDIO_CALL", this.props.lang)} ); if (this.state.incomingCall.type === "video") { callType = ( - Incoming video callIncoming video call + {Translator.translate("INCOMING_VIDEO_CALL",{Translator.translate("INCOMING_VIDEO_CALL", this.props.lang)} ); } @@ -191,11 +194,13 @@ class CallAlert extends React.PureComponent {
{this.state.incomingCall.sender.name}
{callType}
-
+
+ +
- - + +
@@ -206,4 +211,13 @@ class CallAlert extends React.PureComponent { } } +// Specifies the default values for props: +CallAlert.defaultProps = { + lang: Translator.getDefaultLanguage(), +}; + +CallAlert.propTypes = { + lang: PropTypes.string, +} + export default CallAlert; diff --git a/CometChat/components/CallMessage/index.js b/CometChat/components/CallMessage/index.js index 99cd3e2d..ed45b0ea 100644 --- a/CometChat/components/CallMessage/index.js +++ b/CometChat/components/CallMessage/index.js @@ -2,9 +2,12 @@ import { useCallback } from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core' +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; +import Translator from "../../resources/localization/translator"; + import { callMessageStyle, callMessageTxtStyle } from "./style"; const CallMessage = (props) => { @@ -19,30 +22,40 @@ const CallMessage = (props) => { case CometChat.CALL_STATUS.INITIATED: { - message = "Call initiated"; + message = Translator.translate("CALL_INITIATED", props.lang); if (call.type === "audio") { if (call.receiverType === "user") { - message = (call.callInitiator.uid === loggedInUser.uid) ? "Outgoing audio call" : "Incoming audio call"; + + message = (call.callInitiator.uid === loggedInUser.uid) ? Translator.translate("OUTGOING_AUDIO_CALL", props.lang) : Translator.translate("INCOMING_AUDIO_CALL", props.lang); + } else if (call.receiverType === "group") { if (call.action === CometChat.CALL_STATUS.INITIATED) { - message = (call.callInitiator.uid === loggedInUser.uid) ? "Outgoing audio call" : "Incoming audio call"; + + message = (call.callInitiator.uid === loggedInUser.uid) ? Translator.translate("OUTGOING_AUDIO_CALL", props.lang) : Translator.translate("INCOMING_AUDIO_CALL", props.lang); + } else if (call.action === CometChat.CALL_STATUS.REJECTED) { - message = (call.sender.uid === loggedInUser.uid) ? "Call rejected" : `${call.sender.name} rejected call`; + + message = (call.sender.uid === loggedInUser.uid) ? Translator.translate("CALL_REJECTED", props.lang) : (`${call.sender.name} ${Translator.translate("REJECTED_CALL", props.lang)}`); } } } else if (call.type === "video") { if (call.receiverType === "user") { - message = (call.callInitiator.uid === loggedInUser.uid) ? "Outgoing video call" : "Incoming video call"; + + message = (call.callInitiator.uid === loggedInUser.uid) ? Translator.translate("OUTGOING_VIDEO_CALL", props.lang) : Translator.translate("INCOMING_VIDEO_CALL", props.lang); + } else if (call.receiverType === "group") { if (call.action === CometChat.CALL_STATUS.INITIATED) { - message = (call.callInitiator.uid === loggedInUser.uid) ? "Outgoing video call" : "Incoming video call"; + + message = (call.callInitiator.uid === loggedInUser.uid) ? Translator.translate("OUTGOING_VIDEO_CALL", props.lang) : Translator.translate("INCOMING_VIDEO_CALL", props.lang); + } else if (call.action === CometChat.CALL_STATUS.REJECTED) { - message = (call.sender.uid === loggedInUser.uid) ? "Call rejected" : `${call.sender.name} rejected call`; + + message = (call.sender.uid === loggedInUser.uid) ? Translator.translate("CALL_REJECTED", props.lang) : (`${call.sender.name} ${Translator.translate("REJECTED_CALL", props.lang)}`); } } } @@ -51,42 +64,57 @@ const CallMessage = (props) => { case CometChat.CALL_STATUS.ONGOING: { if (call.receiverType === "user") { - message = "Call accepted"; + + message = Translator.translate("CALL_ACCEPTED", props.lang); + } else if (call.receiverType === "group") { if (call.action === CometChat.CALL_STATUS.ONGOING) { - message = (call.sender.uid === loggedInUser.uid) ? "Call accepted" : `${call.sender.name} joined`; + + message = (call.sender.uid === loggedInUser.uid) ? Translator.translate("CALL_ACCEPTED", props.lang) : (`${call.sender.name} ${Translator.translate("JOINED", props.lang)}`); + } else if (call.action === CometChat.CALL_STATUS.REJECTED) { - message = (call.sender.uid === loggedInUser.uid) ? "Call rejected" : `${call.sender.name} rejected call`; + + message = (call.sender.uid === loggedInUser.uid) ? Translator.translate("CALL_REJECTED", props.lang) : (`${call.sender.name} ${Translator.translate("REJECTED_CALL", props.lang)}`); + } else if(call.action === "left") { - message = (call.sender.uid === loggedInUser.uid) ? "You left the call" : `${call.sender.name} left the call`; + + if (call.sender.uid === loggedInUser.uid) { + + message = `${Translator.translate("YOU", props.lang)} ${Translator.translate("LEFT_THE_CALL", props.lang)}`; + + } else { + message = `${call.sender.name} ${Translator.translate("LEFT_THE_CALL", props.lang)}`; + } } } - break; } case CometChat.CALL_STATUS.UNANSWERED: { - message = "Call unanswered"; + message = Translator.translate("CALL_UNANSWERED", props.lang); + if (call.type === "audio" && (call.receiverType === "user" || call.receiverType === "group")) { - message = (call.callInitiator.uid === loggedInUser.uid) ? "Unanswered audio call" : "Missed audio call"; + + message = (call.callInitiator.uid === loggedInUser.uid) ? Translator.translate("UNANSWERED_AUDIO_CALL", props.lang) : Translator.translate("MISSED_AUDIO_CALL", props.lang); + } else if (call.type === "video" && (call.receiverType === "user" || call.receiverType === "group")) { - message = (call.callInitiator.uid === loggedInUser.uid) ? "Unanswered video call" : "Missed video call"; + + message = (call.callInitiator.uid === loggedInUser.uid) ? Translator.translate("UNANSWERED_VIDEO_CALL", props.lang) : Translator.translate("MISSED_VIDEO_CALL", props.lang); } break; } - case CometChat.CALL_STATUS.REJECTED: { - message = "Call rejected"; + case CometChat.CALL_STATUS.REJECTED: + message = Translator.translate("CALL_REJECTED", props.lang); break; - } case CometChat.CALL_STATUS.ENDED: - message = "Call ended"; + message = Translator.translate("CALL_ENDED", props.lang); break; case CometChat.CALL_STATUS.CANCELLED: - message = "Call cancelled" + message = Translator.translate("CALL_CANCELLED", props.lang); break; case CometChat.CALL_STATUS.BUSY: - message = "Call busy"; + message = Translator.translate("CALL_BUSY", props.lang); break; default: break; @@ -100,4 +128,13 @@ const CallMessage = (props) => { ) } +// Specifies the default values for props: +CallMessage.defaultProps = { + lang: Translator.getDefaultLanguage(), +}; + +CallMessage.propTypes = { + lang: PropTypes.string, +} + export default CallMessage; \ No newline at end of file diff --git a/CometChat/components/CallScreen/index.js b/CometChat/components/CallScreen/index.js index 5a9b5a90..f3b08981 100644 --- a/CometChat/components/CallScreen/index.js +++ b/CometChat/components/CallScreen/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx, keyframes } from "@emotion/core"; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -9,7 +10,6 @@ import { CometChatManager } from "../../util/controller"; import * as enums from '../../util/enums.js'; import { SvgAvatar } from '../../util/svgavatar'; import { validateWidgetSettings } from "../../util/common"; - import { CallScreenManager } from "./controller"; import Avatar from "../Avatar"; @@ -28,6 +28,8 @@ import { errorContainerStyle } from "./style"; +import Translator from "../../resources/localization/translator"; +import { theme } from "../../resources/theme"; import callIcon from "./resources/call-end-white-icon.svg"; import { outgoingCallAlert } from "../../resources/audio/"; @@ -43,12 +45,17 @@ class CallScreen extends React.PureComponent { errorScreen: false, errorMessage: null, outgoingCallScreen: false, - callInProgress: null + callInProgress: null, } this.outgoingAlert = new Audio(outgoingCallAlert); } + //Set default props + static defaultProps = { + lang: Translator.getDefaultLanguage(), + } + playOutgoingAlert = () => { //if audio sound is disabled in chat widget @@ -349,7 +356,7 @@ class CallScreen extends React.PureComponent { outgoingCallScreen = (
- Calling... + { Translator.translate("CALLING", this.props.lang) }
{this.state.callInProgress.receiver.name}
@@ -379,4 +386,15 @@ class CallScreen extends React.PureComponent { } } +// Specifies the default values for props: +CallScreen.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CallScreen.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CallScreen; diff --git a/CometChat/components/CometChatAddMembers/index.js b/CometChat/components/CometChatAddMembers/index.js index cdf500bc..4b89ae5f 100644 --- a/CometChat/components/CometChatAddMembers/index.js +++ b/CometChat/components/CometChatAddMembers/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -28,12 +29,14 @@ import { contactMsgTxtStyle, } from "./style"; +import Translator from "../../resources/localization/translator"; +import { theme } from "../../resources/theme"; import searchIcon from './resources/search-grey-icon.png'; import clearIcon from "./resources/close.png"; class CometChatAddMembers extends React.Component { - decoratorMessage = "Loading..."; + decoratorMessage = Translator.translate("LOADING", Translator.getDefaultLanguage()); static contextType = GroupDetailContext; constructor(props) { @@ -41,7 +44,7 @@ class CometChatAddMembers extends React.Component { this.state = { userlist: [], membersToAdd: [], - filteredlist: [] + filteredlist: [], } } @@ -120,20 +123,20 @@ class CometChatAddMembers extends React.Component { }); if (filteredUserList.length === 0) { - this.decoratorMessage = "No users found"; + this.decoratorMessage = Translator.translate("NO_USERS_FOUND", this.props.lang); } this.setState({ userlist: [...this.state.userlist, ...userList], filteredlist: [...this.state.filteredlist, ...filteredUserList] }); }).catch((error) => { - this.decoratorMessage = "Error"; + this.decoratorMessage = Translator.translate("ERROR", this.props.lang); console.error("[CometChatAddMembers] getUsers fetchNext error", error); }); }).catch((error) => { - this.decoratorMessage = "Error"; + this.decoratorMessage = Translator.translate("ERROR", this.props.lang); console.log("[CometChatAddMembers] getUsers getLoggedInUser error", error); }); } @@ -205,6 +208,7 @@ class CometChatAddMembers extends React.Component { this.props.actionGenerated("addGroupParticipants", membersToAdd); } this.props.close(); + }).catch(error => { console.log("addMembersToGroup failed with exception:", error); }); @@ -240,6 +244,7 @@ class CometChatAddMembers extends React.Component {
- +
- + {messageContainer} {users} - +
Contacts{Translator.translate("USERS", this.props.lang)}
@@ -282,4 +287,15 @@ class CometChatAddMembers extends React.Component { } } +// Specifies the default values for props: +CometChatAddMembers.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CometChatAddMembers.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CometChatAddMembers; \ No newline at end of file diff --git a/CometChat/components/CometChatAddMembers/style.js b/CometChat/components/CometChatAddMembers/style.js index 2d5c3e48..3fb0fe64 100644 --- a/CometChat/components/CometChatAddMembers/style.js +++ b/CometChat/components/CometChatAddMembers/style.js @@ -64,13 +64,20 @@ export const modalTableStyle = () => { } } -export const tableCaptionStyle = () => { +export const tableCaptionStyle = (dir) => { + + const textAlignStyle = (dir === "rtl") ? { + textAlign: "right", + paddingRight: "32px", + } : { + textAlign: "left", + }; return { fontSize: "20px", marginBottom: "16px", fontWeight: "bold", - textAlign: "left", + ...textAlignStyle } } diff --git a/CometChat/components/CometChatBanMembers/index.js b/CometChat/components/CometChatBanMembers/index.js index 85b57651..07034e88 100644 --- a/CometChat/components/CometChatBanMembers/index.js +++ b/CometChat/components/CometChatBanMembers/index.js @@ -2,12 +2,12 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core' +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; import BanMemberView from "../BanMemberView"; import Backdrop from '../Backdrop'; - import GroupDetailContext from '../CometChatGroupDetail/context'; import { @@ -23,18 +23,23 @@ import { contactMsgTxtStyle } from "./style"; +import Translator from "../../resources/localization/translator"; +import { theme } from "../../resources/theme"; import clearIcon from "./resources/close.png"; class CometChatBanMembers extends React.Component { - decoratorMessage = "Loading..."; static contextType = GroupDetailContext; constructor(props) { + super(props); + + this.decoratorMessage = Translator.translate("LOADING", props.lang); + this.state = { membersToBan: [], - membersToUnBan: [] + membersToUnBan: [], } } @@ -84,6 +89,7 @@ class CometChatBanMembers extends React.Component { member={member} item={this.props.item} loggedinuser={group.loggedinuser} + lang={this.props.lang} widgetsettings={this.props.widgetsettings} actionGenerated={this.updateMembers} />); @@ -92,7 +98,7 @@ class CometChatBanMembers extends React.Component { let messageContainer = null; if (bannedMembers.length === 0) { - this.decoratorMessage = "No banned members found"; + this.decoratorMessage = Translator.translate("NO_BANNED_MEMBERS_FOUND", this.props.lang); messageContainer = (

{this.decoratorMessage}

@@ -103,16 +109,16 @@ class CometChatBanMembers extends React.Component { return ( -
- +
+
- + - - - + + + {messageContainer} @@ -125,4 +131,15 @@ class CometChatBanMembers extends React.Component { } } +// Specifies the default values for props: +CometChatBanMembers.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CometChatBanMembers.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CometChatBanMembers; \ No newline at end of file diff --git a/CometChat/components/CometChatBanMembers/style.js b/CometChat/components/CometChatBanMembers/style.js index 1bf9f217..a300e3f0 100644 --- a/CometChat/components/CometChatBanMembers/style.js +++ b/CometChat/components/CometChatBanMembers/style.js @@ -75,13 +75,21 @@ export const modalTableStyle = (props) => { } } -export const tableCaptionStyle = () => { +export const tableCaptionStyle = (dir) => { + + const textAlignStyle = (dir === "rtl") ? { + textAlign: "right", + paddingRight: "32px", + } : { + textAlign: "left", + }; + return { fontSize: "20px", marginBottom: "16px", fontWeight: "bold", - textAlign: "left", + ...textAlignStyle } } diff --git a/CometChat/components/CometChatConversationList/index.js b/CometChat/components/CometChatConversationList/index.js index ed329743..f52cdfb3 100644 --- a/CometChat/components/CometChatConversationList/index.js +++ b/CometChat/components/CometChatConversationList/index.js @@ -2,14 +2,15 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; -import { CometChatManager } from "../../util/controller"; import { ConversationListManager } from "./controller"; import { SvgAvatar } from '../../util/svgavatar'; import * as enums from '../../util/enums.js'; import { validateWidgetSettings } from "../../util/common"; +import Translator from "../../resources/localization/translator"; import ConversationView from "../ConversationView"; @@ -32,7 +33,6 @@ import { incomingOtherMessageAlert } from "../../resources/audio/"; class CometChatConversationList extends React.Component { loggedInUser = null; - decoratorMessage = "Loading..."; constructor(props) { @@ -41,12 +41,23 @@ class CometChatConversationList extends React.Component { this.state = { conversationlist: [], onItemClick: null, - selectedConversation: undefined + selectedConversation: undefined, + lang: props.lang } - this.chatListRef = React.createRef(); - this.theme = Object.assign({}, theme, this.props.theme); + this.decoratorMessage = Translator.translate("LOADING", props.lang); + this.chatListRef = React.createRef(); this.audio = new Audio(incomingOtherMessageAlert); + + CometChat.getLoggedInUser().then((user) => { + + this.loggedInUser = user; + + }).catch((error) => { + + this.decoratorMessage = Translator.translate("ERROR", this.state.lang); + console.log("[CometChatConversationList] getConversations getLoggedInUser error", error); + }); } componentDidMount() { @@ -54,6 +65,8 @@ class CometChatConversationList extends React.Component { this.ConversationListManager = new ConversationListManager(); this.getConversations(); this.ConversationListManager.attachListeners(this.conversationUpdated); + + window.addEventListener('languagechange', this.setState({ lang: Translator.getLanguage() })); } componentDidUpdate(prevProps) { @@ -175,6 +188,10 @@ class CometChatConversationList extends React.Component { this.setState({ conversationlist: conversationList }); } } + + if (prevProps.lang !== this.props.lang) { + this.setState({ lang: this.props.lang }); + } } componentWillUnmount() { @@ -559,46 +576,37 @@ class CometChatConversationList extends React.Component { getConversations = () => { - new CometChatManager().getLoggedInUser().then(user => { - - this.loggedInUser = user; - this.ConversationListManager.fetchNextConversation().then(conversationList => { + this.ConversationListManager.fetchNextConversation().then(conversationList => { - if(conversationList.length === 0) { - this.decoratorMessage = "No chats found"; - } + if(conversationList.length === 0) { + this.decoratorMessage = Translator.translate("NO_CHATS_FOUND", this.state.lang); + } - conversationList.forEach(conversation => { + conversationList.forEach(conversation => { - if(conversation.conversationType === "user" && !conversation.conversationWith.avatar) { - conversation.conversationWith.avatar = this.setAvatar(conversation); - } else if(conversation.conversationType === "group" && !conversation.conversationWith.icon) { - conversation.conversationWith.icon = this.setAvatar(conversation); - } + if(conversation.conversationType === "user" && !conversation.conversationWith.avatar) { + conversation.conversationWith.avatar = this.setAvatar(conversation); + } else if(conversation.conversationType === "group" && !conversation.conversationWith.icon) { + conversation.conversationWith.icon = this.setAvatar(conversation); + } - - if (this.props.hasOwnProperty("type") && this.props.hasOwnProperty("item") && this.props.type === conversation.conversationType) { + + if (this.props.hasOwnProperty("type") && this.props.hasOwnProperty("item") && this.props.type === conversation.conversationType) { - if ((conversation.conversationType === "user" && this.props.item.uid === conversation.conversationWith.uid) || - (conversation.conversationType === "group" && this.props.item.guid === conversation.conversationWith.guid)) { + if ((conversation.conversationType === "user" && this.props.item.uid === conversation.conversationWith.uid) || + (conversation.conversationType === "group" && this.props.item.guid === conversation.conversationWith.guid)) { - conversation.unreadMessageCount = 0; - } + conversation.unreadMessageCount = 0; } - - }); - this.setState({ conversationlist: [...this.state.conversationlist, ...conversationList] }); - - }).catch(error => { - - this.decoratorMessage = "Error"; - console.error("[CometChatConversationList] getConversations fetchNext error", error); + } + }); + this.setState({ conversationlist: [...this.state.conversationlist, ...conversationList] }); }).catch(error => { - this.decoratorMessage = "Error"; - console.log("[CometChatConversationList] getConversations getLoggedInUser error", error); + this.decoratorMessage = Translator.translate("ERROR", this.state.lang); + console.error("[CometChatConversationList] getConversations fetchNext error", error); }); } @@ -626,8 +634,9 @@ class CometChatConversationList extends React.Component { return ( -

{this.decoratorMessage}

+

{this.decoratorMessage}

); } @@ -650,14 +658,13 @@ class CometChatConversationList extends React.Component { let closeBtn = (
); if (!this.props.hasOwnProperty("enableCloseMenu") || (this.props.hasOwnProperty("enableCloseMenu") && this.props.enableCloseMenu === 0)) { closeBtn = null; - } + } return (
-
+
{closeBtn} -

Chats

-
+

{Translator.translate("CHATS", this.state.lang)}

{messageContainer}
this.chatListRef = el}>{conversationList}
@@ -666,4 +673,15 @@ class CometChatConversationList extends React.Component { } } +// Specifies the default values for props: +CometChatConversationList.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CometChatConversationList.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CometChatConversationList; diff --git a/CometChat/components/CometChatConversationList/style.js b/CometChat/components/CometChatConversationList/style.js index d37f55ac..dd0e9812 100644 --- a/CometChat/components/CometChatConversationList/style.js +++ b/CometChat/components/CometChatConversationList/style.js @@ -27,7 +27,7 @@ export const chatsWrapperStyle = () => { export const chatsHeaderStyle = (theme) => { return { - padding: "19px 16px", + padding: "16px", display: "flex", alignItems: "center", borderBottom: `1px solid ${theme.color.darkSecondary}` @@ -60,10 +60,13 @@ export const chatsHeaderTitleStyle = (props) => { return { margin: "0", display: "inline-block", - width: "66%", + width: "100%", textAlign: "left", fontSize: "20px", - ...alignment + ...alignment, + "&[dir=rtl]": { + textAlign: "right", + } } } diff --git a/CometChat/components/CometChatConversationListScreen/index.js b/CometChat/components/CometChatConversationListScreen/index.js index 467bf041..75ff3c39 100644 --- a/CometChat/components/CometChatConversationListScreen/index.js +++ b/CometChat/components/CometChatConversationListScreen/index.js @@ -2,11 +2,13 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; import { CometChatManager } from "../../util/controller"; import * as enums from '../../util/enums.js'; +import Translator from "../../resources/localization/translator"; import CometChatConversationList from "../CometChatConversationList"; import CometChatMessageListScreen from "../CometChatMessageListScreen"; @@ -55,10 +57,9 @@ class CometChatConversationListScreen extends React.Component { sidebarview: false, imageView: null, groupmessage: {}, - lastmessage: {} + lastmessage: {}, + lang: props.lang } - - this.theme = Object.assign({}, theme, this.props.theme); } componentDidMount() { @@ -71,8 +72,16 @@ class CometChatConversationListScreen extends React.Component { this.loggedInUser = user; }).catch((error) => { console.log("[CometChatUnified] getLoggedInUser error", error); - }); + + window.addEventListener('languagechange', this.setState({ lang: Translator.getLanguage() })); + } + + componentDidUpdate(prevProps) { + + if (prevProps.lang !== this.props.lang) { + this.setState({ lang: this.props.lang }); + } } changeTheme = (e) => { @@ -186,7 +195,7 @@ class CometChatConversationListScreen extends React.Component { updateThreadMessage = (message, action) => { - if (this.state.threadmessageview === false) { + if (this.state.threadmessageview === false || message.id !== this.state.threadmessageparent.id) { return false; } @@ -426,7 +435,7 @@ class CometChatConversationListScreen extends React.Component { const messageList = []; members.forEach(eachMember => { - const message = `${this.loggedInUser.name} added ${eachMember.name}`; + const message = `${this.loggedInUser.name} ${Translator.translate("ADDED", this.state.lang)} ${eachMember.name}`; const sentAt = new Date() / 1000 | 0; const messageObj = { "category": "action", "message": message, "type": enums.ACTION_TYPE_GROUPMEMBER, "sentAt": sentAt }; messageList.push(messageObj); @@ -440,7 +449,7 @@ class CometChatConversationListScreen extends React.Component { const messageList = []; members.forEach(eachMember => { - const message = `${this.loggedInUser.name} unbanned ${eachMember.name}`; + const message = `${this.loggedInUser.name} ${Translator.translate("UNBANNED", this.state.lang)} ${eachMember.name}`; const sentAt = new Date() / 1000 | 0; const messageObj = { "category": "action", "message": message, "type": enums.ACTION_TYPE_GROUPMEMBER, "sentAt": sentAt }; messageList.push(messageObj); @@ -455,7 +464,7 @@ class CometChatConversationListScreen extends React.Component { members.forEach(eachMember => { - const message = `${this.loggedInUser.name} made ${eachMember.name} ${eachMember.scope}`; + const message = `${this.loggedInUser.name} ${Translator.translate("MADE", this.state.lang)} ${eachMember.name} ${eachMember.scope}`; const sentAt = new Date() / 1000 | 0; const messageObj = { "category": "action", "message": message, "type": enums.ACTION_TYPE_GROUPMEMBER, "sentAt": sentAt }; messageList.push(messageObj); @@ -469,14 +478,15 @@ class CometChatConversationListScreen extends React.Component { let threadMessageView = null; if(this.state.threadmessageview) { threadMessageView = ( -
+
); @@ -488,22 +498,24 @@ class CometChatConversationListScreen extends React.Component { if(this.state.type === "user") { detailScreen = ( -
+
); } else if (this.state.type === "group") { detailScreen = ( -
+
); @@ -514,7 +526,7 @@ class CometChatConversationListScreen extends React.Component { if(Object.keys(this.state.item).length) { messageScreen = ( ); } let imageView = null; if (this.state.imageView) { - imageView = ( this.toggleImageView(null)} message={this.state.imageView} />); + imageView = ( this.toggleImageView(null)} message={this.state.imageView} lang={this.state.lang} />); } return ( -
-
+
+
{ this.setState({password: event.target.value}) } @@ -61,12 +68,12 @@ class CometChatCreateGroup extends React.Component { const groupType = this.state.type.trim(); if(!groupName) { - this.setState({error: "Group name cannnot be blank."}) + this.setState({ error: Translator.translate("GROUP_NAME_BLANK", this.props.lang) }) return false; } if(!groupType) { - this.setState({error: "Group type cannnot be blank."}) + this.setState({ error: Translator.translate("GROUP_TYPE_BLANK", this.props.lang) }) return false; } @@ -75,7 +82,7 @@ class CometChatCreateGroup extends React.Component { password = this.state.password; if(!password.length) { - this.setState({error: "Group password cannnot be blank."}) + this.setState({ error: Translator.translate("GROUP_PASSWORD_BLANK", this.props.lang) }) return false; } } @@ -134,7 +141,7 @@ class CometChatCreateGroup extends React.Component {
- +
Banned Members{Translator.translate("BANNED_MEMBERS", this.props.lang)}
NameScopeUnban{Translator.translate("NAME", this.props.lang)}{Translator.translate("SCOPE", this.props.lang)}{Translator.translate("UNBAN", this.props.lang)}
- + @@ -162,7 +169,7 @@ class CometChatCreateGroup extends React.Component { autoComplete="off" css={inputStyle(this.props)} className="search__input" - placeholder="Enter group name" + placeholder={Translator.translate("ENTER_GROUP_NAME", this.props.lang)} type="text" tabIndex="1" onChange={this.nameChangeHandler} @@ -177,10 +184,10 @@ class CometChatCreateGroup extends React.Component { onChange={this.typeChangeHandler} value={this.state.type} tabIndex="2"> - - - - + + + + @@ -188,7 +195,7 @@ class CometChatCreateGroup extends React.Component { - +
Create Group{Translator.translate("CREATE_GROUP", this.props.lang)}
{this.state.error}
@@ -199,4 +206,13 @@ class CometChatCreateGroup extends React.Component { } } +// Specifies the default values for props: +CometChatCreateGroup.defaultProps = { + lang: Translator.getDefaultLanguage(), +}; + +CometChatCreateGroup.propTypes = { + lang: PropTypes.string, +} + export default CometChatCreateGroup; \ No newline at end of file diff --git a/CometChat/components/CometChatCreatePoll/index.js b/CometChat/components/CometChatCreatePoll/index.js index 52b43fea..6cae1fdf 100644 --- a/CometChat/components/CometChatCreatePoll/index.js +++ b/CometChat/components/CometChatCreatePoll/index.js @@ -2,10 +2,12 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; import { CometChatManager } from "../../util/controller"; +import Translator from "../../resources/localization/translator"; import Backdrop from '../Backdrop'; import CreatePollView from "../CreatePollView"; @@ -37,13 +39,13 @@ class CometChatCreatePoll extends React.Component { error: null, options: [] } + this.questionRef = React.createRef(); this.optionOneRef = React.createRef(); this.optionTwoRef = React.createRef(); this.optionRef = React.createRef(); - } - componentDidMount() { + new CometChatManager().getLoggedInUser().then(user => { this.loggedInUser = user; }).catch((error) => { @@ -90,13 +92,13 @@ class CometChatCreatePoll extends React.Component { if (question.length === 0) { - this.setState({ error: "Question cannnot be blank." }) + this.setState({ error: Translator.translate("POLL_QUESTION_BLANK", this.props.lang) }) return false; } if (firstOption.length === 0 || secondOption.length === 0) { - this.setState({ error: "Option cannnot be blank." }) + this.setState({ error: Translator.translate("POLL_OPTION_BLANK", this.props.lang) }) return false; } @@ -155,7 +157,6 @@ class CometChatCreatePoll extends React.Component { } else { this.setState({ error: "Error" }); } - }); } @@ -168,6 +169,7 @@ class CometChatCreatePoll extends React.Component { key={index} option={option} tabIndex={index+4} + lang={this.props.lang} optionChangeHandler={this.optionChangeHandler} removePollOption={this.removePollOption} /> ); @@ -186,34 +188,34 @@ class CometChatCreatePoll extends React.Component {
- +
- + {errorContainer} - + - + {pollOptionView} - + @@ -221,7 +223,7 @@ class CometChatCreatePoll extends React.Component { - +
Create Poll{Translator.translate("CREATE_POLL", this.props.lang)}
- +
- +
  - +
 
@@ -232,4 +234,13 @@ class CometChatCreatePoll extends React.Component { } } +// Specifies the default values for props: +CometChatCreatePoll.defaultProps = { + lang: Translator.getDefaultLanguage(), +}; + +CometChatCreatePoll.propTypes = { + lang: PropTypes.string, +} + export default CometChatCreatePoll; \ No newline at end of file diff --git a/CometChat/components/CometChatGroupDetail/index.js b/CometChat/components/CometChatGroupDetail/index.js index 65fce142..deb6ad46 100644 --- a/CometChat/components/CometChatGroupDetail/index.js +++ b/CometChat/components/CometChatGroupDetail/index.js @@ -2,13 +2,14 @@ import React from 'react'; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; import { CometChatManager } from "../../util/controller"; import { SvgAvatar } from '../../util/svgavatar'; - import * as enums from '../../util/enums.js'; +import { validateWidgetSettings } from "../../util/common"; import { GroupDetailManager } from "./controller"; import GroupDetailContext from './context'; @@ -16,9 +17,11 @@ import GroupDetailContext from './context'; import CometChatViewMembers from "../CometChatViewMembers"; import CometChatAddMembers from "../CometChatAddMembers"; import CometChatBanMembers from "../CometChatBanMembers"; - import SharedMediaView from "../SharedMediaView"; +import Translator from "../../resources/localization/translator"; +import { theme } from "../../resources/theme"; + import { detailStyle, headerStyle, @@ -400,7 +403,7 @@ class CometChatGroupDetail extends React.Component { let viewMembersBtn = (
-
this.clickHandler("viewmember", true)}>View Members
+
this.clickHandler("viewmember", true)}>{Translator.translate("VIEW_MEMBERS", this.props.lang)}
); @@ -408,13 +411,13 @@ class CometChatGroupDetail extends React.Component { if(this.props.item.scope === CometChat.GROUP_MEMBER_SCOPE.ADMIN) { addMembersBtn = (
-
this.clickHandler("addmember", true)}>Add Members
+
this.clickHandler("addmember", true)}>{Translator.translate("ADD_MEMBERS", this.props.lang)}
); deleteGroupBtn = (
- Delete and Exit + {Translator.translate("DELETE_AND_EXIT", this.props.lang)}
); } @@ -422,69 +425,62 @@ class CometChatGroupDetail extends React.Component { if(this.props.item.scope !== CometChat.GROUP_MEMBER_SCOPE.PARTICIPANT) { bannedMembersBtn = (
-
this.clickHandler("banmember", true)}>Banned Members
+
this.clickHandler("banmember", true)}>{Translator.translate("BANNED_MEMBERS", this.props.lang)}
); } let leaveGroupBtn = (
- Leave Group + {Translator.translate("LEAVE_GROUP", this.props.lang)}
); let sharedmediaView = ( - + ); - if(this.props.hasOwnProperty("widgetsettings") - && this.props.widgetsettings - && this.props.widgetsettings.hasOwnProperty("main")) { - - //if view_group_members is disabled in chatwidget - if(this.props.widgetsettings.main.hasOwnProperty("view_group_members") - && this.props.widgetsettings.main["view_group_members"] === false - && this.props.widgetsettings.main.hasOwnProperty("allow_kick_ban_members") - && this.props.widgetsettings.main["allow_kick_ban_members"] === false - && this.props.widgetsettings.main.hasOwnProperty("allow_promote_demote_members") - && this.props.widgetsettings.main["allow_promote_demote_members"] === false) { - viewMembersBtn = null; - } + //if viewing, kicking/banning, promoting/demoting group membersare disabled in chatwidget + if (validateWidgetSettings(this.props.widgetsettings, "view_group_members") === false + && validateWidgetSettings(this.props.widgetsettings, "allow_kick_ban_members") === false + && validateWidgetSettings(this.props.widgetsettings, "allow_promote_demote_members") === false) { + viewMembersBtn = null; + } - //if add_group_members is disabled in chatwidget - if(this.props.widgetsettings.main.hasOwnProperty("allow_add_members") - && this.props.widgetsettings.main["allow_add_members"] === false) { - addMembersBtn = null; - } + //if adding group members is disabled in chatwidget + if (validateWidgetSettings(this.props.widgetsettings, "allow_add_members") === false) { + addMembersBtn = null; + } - //if allow_kick_ban_members is disabled in chatwidget - if(this.props.widgetsettings.main.hasOwnProperty("allow_kick_ban_members") - && this.props.widgetsettings.main["allow_kick_ban_members"] === false) { - bannedMembersBtn = null; - } + //if kicking/banning/unbanning group members is disabled in chatwidget + if (validateWidgetSettings(this.props.widgetsettings, "allow_kick_ban_members") === false) { + bannedMembersBtn = null; + } - //if delete_group is disabled in chatwidget - if(this.props.widgetsettings.main.hasOwnProperty("allow_delete_groups") - && this.props.widgetsettings.main["allow_delete_groups"] === false) { - deleteGroupBtn = null; - } + //if deleting group is disabled in chatwidget + if (validateWidgetSettings(this.props.widgetsettings, "allow_delete_groups") === false) { + deleteGroupBtn = null; + } - //if leave_group is disabled in chatwidgets - if(this.props.widgetsettings.main.hasOwnProperty("join_or_leave_groups") - && this.props.widgetsettings.main["join_or_leave_groups"] === false) { - leaveGroupBtn = null; - } + //if leaving group is disabled in chatwidget + if (validateWidgetSettings(this.props.widgetsettings, "join_or_leave_groups") === false) { + leaveGroupBtn = null; + } - //if view_shared_media is disabled in chatwidget - if(this.props.widgetsettings.main.hasOwnProperty("view_shared_media") - && this.props.widgetsettings.main["view_shared_media"] === false) { - sharedmediaView = null; - } + //if viewing shared media group is disabled in chatwidget + if (validateWidgetSettings(this.props.widgetsettings, "view_shared_media") === false) { + sharedmediaView = null; } let members = (
-
Members
+
{Translator.translate("MEMBERS", this.props.lang)}
{viewMembersBtn} {addMembersBtn} @@ -495,7 +491,7 @@ class CometChatGroupDetail extends React.Component { let options = (
-
Options
+
{Translator.translate("OPTIONS", this.props.lang)}
{leaveGroupBtn} {deleteGroupBtn} @@ -517,6 +513,7 @@ class CometChatGroupDetail extends React.Component { this.clickHandler("viewmember", false)} widgetsettings={this.props.widgetsettings} @@ -530,6 +527,7 @@ class CometChatGroupDetail extends React.Component { this.clickHandler("addmember", false)} widgetsettings={this.props.widgetsettings} @@ -543,6 +541,7 @@ class CometChatGroupDetail extends React.Component { this.clickHandler("banmember", false)} widgetsettings={this.props.widgetsettings} @@ -554,29 +553,40 @@ class CometChatGroupDetail extends React.Component {
-
-
this.props.actionGenerated("closeDetailClicked")}>
-

Details

-
-
- {members} - {options} - {sharedmediaView} -
- {viewMembers} - {addMembers} - {bannedMembers} +
+
this.props.actionGenerated("closeDetailClicked")}>
+

{Translator.translate("DETAILS", this.props.lang)}

+
+
+ {members} + {options} + {sharedmediaView} +
+ {viewMembers} + {addMembers} + {bannedMembers}
); } } +// Specifies the default values for props: +CometChatGroupDetail.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CometChatGroupDetail.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CometChatGroupDetail; \ No newline at end of file diff --git a/CometChat/components/CometChatGroupList/index.js b/CometChat/components/CometChatGroupList/index.js index 940d1c03..47a82412 100644 --- a/CometChat/components/CometChatGroupList/index.js +++ b/CometChat/components/CometChatGroupList/index.js @@ -1,22 +1,19 @@ import React from "react"; /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; import { CometChatManager } from "../../util/controller"; import { SvgAvatar } from '../../util/svgavatar'; - import * as enums from '../../util/enums.js'; - +import { validateWidgetSettings } from "../../util/common"; import { GroupListManager } from "./controller"; - import CometChatCreateGroup from "../CometChatCreateGroup"; import GroupView from "../GroupView"; -import { theme } from "../../resources/theme"; - import { groupWrapperStyle, groupHeaderStyle, @@ -30,6 +27,9 @@ import { groupListStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import searchIcon from './resources/search-grey-icon.png'; import navigateIcon from './resources/navigate.png'; import addIcon from './resources/creategroup.png'; @@ -37,7 +37,6 @@ import addIcon from './resources/creategroup.png'; class CometChatGroupList extends React.Component { timeout; loggedInUser = null; - decoratorMessage = "Loading..."; constructor(props) { @@ -46,10 +45,12 @@ class CometChatGroupList extends React.Component { this.state = { grouplist: [], createGroup: false, - selectedGroup: null + selectedGroup: null, + lang: props.lang } + + this.decoratorMessage = Translator.translate("LOADING", props.lang); this.groupListRef = React.createRef(); - this.theme = Object.assign({}, theme, this.props.theme); } componentDidMount() { @@ -57,6 +58,8 @@ class CometChatGroupList extends React.Component { this.GroupListManager = new GroupListManager(); this.getGroups(); this.GroupListManager.attachListeners(this.groupUpdated); + + window.addEventListener('languagechange', this.setState({ lang: Translator.getLanguage() })); } componentDidUpdate(prevProps) { @@ -113,7 +116,7 @@ class CometChatGroupList extends React.Component { groups.splice(groupKey, 1); this.setState({grouplist: groups}); if(groups.length === 0) { - this.decoratorMessage = "No groups found"; + this.decoratorMessage = Translator.translate("NO_GROUPS_FOUND", this.state.lang); } } } @@ -135,6 +138,9 @@ class CometChatGroupList extends React.Component { } } + if (prevProps.lang !== this.props.lang) { + this.setState({ lang: this.props.lang }); + } } componentWillUnmount() { @@ -300,19 +306,15 @@ class CometChatGroupList extends React.Component { if (group.hasJoined === false) { - if(this.props.hasOwnProperty("widgetsettings") - && this.props.widgetsettings - && this.props.widgetsettings.hasOwnProperty("main") - && this.props.widgetsettings.main.hasOwnProperty("join_or_leave_groups") - && this.props.widgetsettings.main["join_or_leave_groups"] === false) { - + //if join or leave groups is disabled in chat widget + if (validateWidgetSettings(this.props.widgetsettings, "join_or_leave_groups") === false) { console.log("Group joining disabled in widget settings"); return false; } let password = ""; if(group.type === CometChat.GROUP_TYPE.PASSWORD) { - password = prompt("Enter your password"); + password = prompt(Translator.translate("ENTER_YOUR_PASSWORD", this.state.lang)); } const guid = group.guid; @@ -391,7 +393,7 @@ class CometChatGroupList extends React.Component { this.GroupListManager.fetchNextGroups().then(groupList => { if(groupList.length === 0) { - this.decoratorMessage = "No groups found"; + this.decoratorMessage = Translator.translate("NO_GROUPS_FOUND", this.state.lang); } groupList.forEach(group => group = this.setAvatar(group)); @@ -399,13 +401,13 @@ class CometChatGroupList extends React.Component { }).catch(error => { - this.decoratorMessage = "Error"; + this.decoratorMessage = Translator.translate("ERROR", this.state.lang); console.error("[CometChatGroupList] getGroups fetchNextGroups error", error); }); }).catch(error => { - this.decoratorMessage = "Error"; + this.decoratorMessage = Translator.translate("ERROR", this.state.lang); console.log("[CometChatGroupList] getUsers getLoggedInUser error", error); }); } @@ -445,7 +447,7 @@ class CometChatGroupList extends React.Component { if(this.state.grouplist.length === 0) { messageContainer = (
-

{this.decoratorMessage}

+

{this.decoratorMessage}

); } @@ -454,27 +456,24 @@ class CometChatGroupList extends React.Component { return ( ); }); - let creategroup = (
this.createGroupHandler(true)}> - Create Group + let creategroup = (
this.createGroupHandler(true)}> + {Translator.translate("CREATE_GROUP",
); - if(this.props.hasOwnProperty("config") - && this.props.config - && this.props.config.hasOwnProperty("group-create") - && this.props.config["group-create"] === false) { + + //if create group is disabled in v1 chat widget + if (validateWidgetSettings(this.props.config, "group-create") === false) { creategroup = null; } - if(this.props.hasOwnProperty("widgetsettings") - && this.props.widgetsettings - && this.props.widgetsettings.hasOwnProperty("main") - && this.props.widgetsettings.main.hasOwnProperty("create_groups") - && this.props.widgetsettings.main["create_groups"] === false) { + //if create group is disabled in chat widget + if (validateWidgetSettings(this.props.widgetsettings, "create_groups") === false) { creategroup = null; } @@ -485,24 +484,25 @@ class CometChatGroupList extends React.Component { return (
-
+
{closeBtn} -

Groups

+

{Translator.translate("GROUPS", this.state.lang)}

{creategroup}
{messageContainer}
this.groupListRef = el}>{groups}
this.createGroupHandler(false)} actionGenerated={this.createGroupActionHandler} /> @@ -511,4 +511,15 @@ class CometChatGroupList extends React.Component { } } +// Specifies the default values for props: +CometChatGroupList.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CometChatGroupList.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CometChatGroupList; \ No newline at end of file diff --git a/CometChat/components/CometChatGroupList/style.js b/CometChat/components/CometChatGroupList/style.js index bdc877c5..aa2a2fdb 100644 --- a/CometChat/components/CometChatGroupList/style.js +++ b/CometChat/components/CometChatGroupList/style.js @@ -27,7 +27,7 @@ export const groupWrapperStyle = () => { export const groupHeaderStyle = (theme) => { return { - padding: "19px 16px", + padding: "16px", position: "relative", display: "flex", justifyContent: "space-between", @@ -63,10 +63,13 @@ export const groupHeaderTitleStyle = (props) => { margin: "0", fontWeight: "700", display: "inline-block", - width: "66%", + width: "100%", textAlign: "left", fontSize: "20px", - ...alignment + ...alignment, + "&[dir=rtl]": { + textAlign: "right", + } } } diff --git a/CometChat/components/CometChatGroupListScreen/index.js b/CometChat/components/CometChatGroupListScreen/index.js index 72048123..5f055d75 100644 --- a/CometChat/components/CometChatGroupListScreen/index.js +++ b/CometChat/components/CometChatGroupListScreen/index.js @@ -2,11 +2,13 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; import { CometChatManager } from "../../util/controller"; import * as enums from '../../util/enums.js'; +import Translator from "../../resources/localization/translator"; import CometChatGroupList from "../CometChatGroupList"; import CometChatMessageListScreen from "../CometChatMessageListScreen"; @@ -52,10 +54,9 @@ class CometChatGroupListScreen extends React.Component { callmessage: {}, sidebarview: false, imageView: null, - groupmessage: {} + groupmessage: {}, + lang: props.lang } - - this.theme = Object.assign({}, theme, this.props.theme); } componentDidMount() { @@ -70,6 +71,15 @@ class CometChatGroupListScreen extends React.Component { console.log("[CometChatUnified] getLoggedInUser error", error); }); + + window.addEventListener('languagechange', this.setState({ lang: Translator.getLanguage() })); + } + + componentDidUpdate(prevProps) { + + if (prevProps.lang !== this.props.lang) { + this.setState({ lang: this.props.lang }); + } } changeTheme = (e) => { @@ -172,7 +182,7 @@ class CometChatGroupListScreen extends React.Component { updateThreadMessage = (message, action) => { - if (this.state.threadmessageview === false) { + if (this.state.threadmessageview === false|| message.id !== this.state.threadmessageparent.id) { return false; } @@ -449,14 +459,15 @@ class CometChatGroupListScreen extends React.Component { let threadMessageView = null; if(this.state.threadmessageview) { threadMessageView = ( -
+
); @@ -466,11 +477,12 @@ class CometChatGroupListScreen extends React.Component { if(this.state.viewdetailscreen) { detailScreen = ( -
+
); @@ -481,7 +493,7 @@ class CometChatGroupListScreen extends React.Component { if(Object.keys(this.state.item).length) { messageScreen = ( ); } let imageView = null; if (this.state.imageView) { - imageView = ( this.toggleImageView(null)} message={this.state.imageView} />); + imageView = ( this.toggleImageView(null)} message={this.state.imageView} lang={this.state.lang} />); } return ( -
-
+
+
{ @@ -109,8 +118,13 @@ class CometChatMessageListScreen extends React.PureComponent { this.props.actionGenerated("messageComposed", messages); break; } - case "messageUpdated": + case "onMessageEdited": { + this.updateMessages(messages); + //update the parent message of thread message + this.props.actionGenerated("updateThreadMessage", messages, "edit"); + + } break; case "messageFetched": this.prependMessages(messages); @@ -118,8 +132,13 @@ class CometChatMessageListScreen extends React.PureComponent { case "messageFetchedAgain": this.prependMessagesAndScrollBottom(messages); break; - case "messageDeleted": + case "messageDeleted": { + this.removeMessages(messages); + //remove the thread message + this.props.actionGenerated("updateThreadMessage", messages, "delete"); + + } break; case "viewMessageThread": this.props.actionGenerated("viewMessageThread", messages); @@ -203,6 +222,11 @@ class CometChatMessageListScreen extends React.PureComponent { const messageId = message.id; CometChat.deleteMessage(messageId).then(deletedMessage => { + + //remove edit preview when message is deleted + if (deletedMessage.id === this.state.messageToBeEdited.id) { + this.setState({ messageToBeEdited: "" }); + } this.removeMessages([deletedMessage]); @@ -381,9 +405,10 @@ class CometChatMessageListScreen extends React.PureComponent { let messageComposer = ( { this.composerRef = el; } } - theme={this.theme} + theme={this.props.theme} item={this.props.item} type={this.props.type} + lang={this.state.lang} widgetsettings={this.props.widgetsettings} loggedInUser={this.props.loggedInUser} messageToBeEdited={this.state.messageToBeEdited} @@ -402,18 +427,19 @@ class CometChatMessageListScreen extends React.PureComponent { if (this.state.liveReaction) { liveReactionView = (
- +
); } return ( -
+
this.props.actionGenerated("itemClicked", type, item)} />; @@ -53,6 +55,7 @@ class Navbar extends React.Component { theme={this.props.theme} item={this.props.item} type={this.props.type} + lang={this.props.lang} groupToUpdate={this.props.groupToUpdate} messageToMarkRead={this.props.messageToMarkRead} lastMessage={this.props.lastMessage} @@ -64,6 +67,7 @@ class Navbar extends React.Component { theme={this.props.theme} item={this.props.item} type={this.props.type} + lang={this.props.lang} groupToLeave={this.props.groupToLeave} groupToDelete={this.props.groupToDelete} groupToUpdate={this.props.groupToUpdate} @@ -73,14 +77,13 @@ class Navbar extends React.Component { case "info": return this.props.actionGenerated("itemClicked", type, item)} />; default: return null; } - } - render() { const chatsTabActive = (this.props.tab === "conversations") ? true : false; @@ -94,23 +97,45 @@ class Navbar extends React.Component {
this.props.actionGenerated('tabChanged', 'conversations')}> -
+
this.props.actionGenerated('tabChanged', 'contacts')}> -
+
this.props.actionGenerated('tabChanged', 'groups')}> -
+
this.props.actionGenerated('tabChanged', 'info')}> -
+
) - } } +// Specifies the default values for props: +Navbar.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +Navbar.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default Navbar; \ No newline at end of file diff --git a/CometChat/components/CometChatUnified/index.js b/CometChat/components/CometChatUnified/index.js index f5bd8ff9..3363a8a7 100644 --- a/CometChat/components/CometChatUnified/index.js +++ b/CometChat/components/CometChatUnified/index.js @@ -2,11 +2,13 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; import { CometChatManager } from "../../util/controller"; import * as enums from '../../util/enums.js'; +import Translator from "../../resources/localization/translator"; import NavBar from "./NavBar"; import CometChatMessageListScreen from "../CometChatMessageListScreen"; @@ -55,19 +57,17 @@ class CometChatUnified extends React.Component { sidebarview: false, imageView: null, groupmessage: {}, - lastmessage: {} + lastmessage: {}, + lang: props.lang, } - new CometChatManager().getLoggedInUser().then((user) => { + CometChat.getLoggedInUser().then((user) => { this.loggedInUser = user; }).catch((error) => { console.log("[CometChatUnified] getLoggedInUser error", error); - }); - - this.theme = Object.assign({}, theme, this.props.theme); - } + } componentDidMount() { @@ -75,14 +75,14 @@ class CometChatUnified extends React.Component { this.toggleSideBar(); } - // new CometChatManager().getLoggedInUser().then((user) => { - // this.loggedInUser = user; + window.addEventListener('languagechange', this.setState({ lang: Translator.getLanguage() })); + } - // }).catch((error) => { - // console.log("[CometChatUnified] getLoggedInUser error", error); - - // }); - + componentDidUpdate(prevProps) { + + if (prevProps.lang !== this.props.lang) { + this.setState({ lang: this.props.lang }); + } } changeTheme = (e) => { @@ -219,7 +219,7 @@ class CometChatUnified extends React.Component { updateThreadMessage = (message, action) => { - if (this.state.threadmessageview === false) { + if (this.state.threadmessageview === false || message.id !== this.state.threadmessageparent.id) { return false; } @@ -504,14 +504,15 @@ class CometChatUnified extends React.Component { let threadMessageView = null; if(this.state.threadmessageview) { threadMessageView = ( -
+
); @@ -523,11 +524,12 @@ class CometChatUnified extends React.Component { if(this.state.type === "user") { detailScreen = ( -
+
); @@ -535,11 +537,12 @@ class CometChatUnified extends React.Component { } else if (this.state.type === "group") { detailScreen = ( -
+
); @@ -550,7 +553,7 @@ class CometChatUnified extends React.Component { if(Object.keys(this.state.item).length) { messageScreen = ( ); } let imageView = null; if (this.state.imageView) { - imageView = ( this.toggleImageView(null)} message={this.state.imageView} />); + imageView = ( this.toggleImageView(null)} message={this.state.imageView} lang={this.state.lang} />); } - + return ( -
-
+
+
@@ -587,12 +592,14 @@ class CometChatUnified extends React.Component { {detailScreen} {threadMessageView} this.props.actionGenerated("unblockUser")}>Unblock User
+
this.props.actionGenerated("unblockUser")}>{Translator.translate("UNBLOCK_USER", this.props.lang)}
); } else { blockUserText = ( -
this.props.actionGenerated("blockUser")}>Block User
+
this.props.actionGenerated("blockUser")}>{Translator.translate("BLOCK_USER", this.props.lang)}
); } let blockUserView = (
-
Options
+
{Translator.translate("OPTIONS", this.props.lang)}
{blockUserText}
@@ -45,31 +48,30 @@ class CometChatUserDetail extends React.Component { ); let sharedmediaView = ( - + ); - if(this.props.hasOwnProperty("widgetsettings") - && this.props.widgetsettings - && this.props.widgetsettings.hasOwnProperty("main")) { - - //if block_user is disabled in chatwidget - if(this.props.widgetsettings.main.hasOwnProperty("block_user") - && this.props.widgetsettings.main["block_user"] === false) { - blockUserView = null; - } + //if block/unblock user is disabled in chat widget + if (validateWidgetSettings(this.props.widgetsettings, "block_user") === false) { + blockUserView = null; + } - //if view_shared_media is disabled in chatwidget - if(this.props.widgetsettings.main.hasOwnProperty("view_shared_media") - && this.props.widgetsettings.main["view_shared_media"] === false) { - sharedmediaView = null; - } + //if shared media is disabled in chat widget + if (validateWidgetSettings(this.props.widgetsettings, "view_shared_media") === false) { + sharedmediaView = null; } return (
this.props.actionGenerated("closeDetailClicked")}>
-

Details

+

{Translator.translate("DETAILS", this.props.lang)}

{blockUserView} @@ -80,4 +82,13 @@ class CometChatUserDetail extends React.Component { } } +// Specifies the default values for props: +CometChatUserDetail.defaultProps = { + lang: Translator.getDefaultLanguage(), +}; + +CometChatUserDetail.propTypes = { + lang: PropTypes.string +} + export default CometChatUserDetail; \ No newline at end of file diff --git a/CometChat/components/CometChatUserInfoScreen/index.js b/CometChat/components/CometChatUserInfoScreen/index.js index 06a4d370..ac0111b7 100644 --- a/CometChat/components/CometChatUserInfoScreen/index.js +++ b/CometChat/components/CometChatUserInfoScreen/index.js @@ -2,13 +2,12 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChatManager } from "../../util/controller"; import { SvgAvatar } from '../../util/svgavatar'; import Avatar from "../Avatar"; -import { theme } from "../../resources/theme"; - import { userInfoScreenStyle, headerStyle, @@ -25,13 +24,15 @@ import { optionNameStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import notificationIcon from "./resources/notification-black-icon.svg"; import privacyIcon from "./resources/privacy-black-icon.svg"; import chatIcon from "./resources/chat-black-icon.svg"; import helpIcon from "./resources/help-black-icon.svg"; import reportIcon from "./resources/report-black-icon.svg"; - class CometChatUserInfoScreen extends React.Component { constructor(props) { @@ -41,8 +42,6 @@ class CometChatUserInfoScreen extends React.Component { this.state = { user: {}, } - - this.theme = Object.assign({}, theme, this.props.theme); } componentDidMount() { @@ -69,52 +68,47 @@ class CometChatUserInfoScreen extends React.Component { const char = user.getName().charAt(0).toUpperCase(); user.setAvatar(SvgAvatar.getAvatar(uid, char)) } - } render() { let avatar = null; if(Object.keys(this.state.user).length) { - avatar = (); + avatar = (); } return ( -
-
-

More

+
+
+

{Translator.translate("MORE", this.props.lang)}

{avatar}
-
+
{this.state.user.name}
-

Online

+

{Translator.translate("ONLINE", this.props.lang)}

-
Preferences
+
{Translator.translate("PREFERENCES", this.props.lang)}
-
Notifications
+
{Translator.translate("NOTIFICATIONS", this.props.lang)}
-
Privacy and Security
+
{Translator.translate("PRIVACY_AND_SECURITY", this.props.lang)}
-
Chats
+
{Translator.translate("CHATS", this.props.lang)}
-
Other
+
{Translator.translate("OTHER", this.props.lang)}
-
Help
+
{Translator.translate("HELP", this.props.lang)}
-
Report a Problem
+
{Translator.translate("REPORT_PROBLEM", this.props.lang)}
@@ -123,4 +117,15 @@ class CometChatUserInfoScreen extends React.Component { } } +// Specifies the default values for props: +CometChatUserInfoScreen.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CometChatUserInfoScreen.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CometChatUserInfoScreen; \ No newline at end of file diff --git a/CometChat/components/CometChatUserInfoScreen/style.js b/CometChat/components/CometChatUserInfoScreen/style.js index 86236968..3cc1f0d3 100644 --- a/CometChat/components/CometChatUserInfoScreen/style.js +++ b/CometChat/components/CometChatUserInfoScreen/style.js @@ -15,7 +15,7 @@ export const userInfoScreenStyle = (theme) =>{ export const headerStyle = (theme) => { return { - padding: "19px 16px", + padding: "16px", position: "relative", borderBottom: `1px solid ${theme.borderColor.primary}` } @@ -33,7 +33,7 @@ export const headerTitleStyle = () => { export const detailStyle = () => { return { - padding: "19px 16px", + padding: "16px", display: "flex", flexDirection: "row", justifyContent: "left", @@ -56,7 +56,11 @@ export const userDetailStyle = () => { return { width: "calc(100% - 45px)", flexGrow: "1", - paddingLeft: "15px", + paddingLeft: "16px", + "&[dir=rtl]": { + paddingRight: "16px", + paddingLeft: "0", + } } } diff --git a/CometChat/components/CometChatUserList/index.js b/CometChat/components/CometChatUserList/index.js index 0a82165a..780fa06f 100644 --- a/CometChat/components/CometChatUserList/index.js +++ b/CometChat/components/CometChatUserList/index.js @@ -1,7 +1,8 @@ import React from "react"; /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChatManager } from "../../util/controller"; import { SvgAvatar } from '../../util/svgavatar'; @@ -9,8 +10,6 @@ import { UserListManager } from "./controller"; import UserView from "../UserView"; -import { theme } from "../../resources/theme"; - import { contactWrapperStyle, contactHeaderStyle, @@ -24,13 +23,14 @@ import { contactAlphabetStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; import searchIcon from './resources/search-grey-icon.png'; import navigateIcon from './resources/navigate.png'; class CometChatUserList extends React.PureComponent { timeout; friendsOnly = false; - decoratorMessage = "Loading..."; constructor(props) { @@ -38,14 +38,20 @@ class CometChatUserList extends React.PureComponent { this.state = { userlist: [], - selectedUser: null + selectedUser: null, + lang: props.lang } + + this.decoratorMessage = Translator.translate("LOADING", props.lang); this.userListRef = React.createRef(); - this.theme = Object.assign({}, theme, this.props.theme); } componentDidMount() { + window.addEventListener('languagechange', () => { + this.setState({ lang: Translator.getLanguage() }); + }); + if(this.props.hasOwnProperty("friendsOnly")) { this.friendsOnly = this.props.friendsOnly; } @@ -114,6 +120,10 @@ class CometChatUserList extends React.PureComponent { this.setState({ userlist: userlist }); } } + + if (prevProps.lang !== this.props.lang) { + this.setState({ lang: this.props.lang }); + } } componentWillUnmount() { @@ -188,7 +198,7 @@ class CometChatUserList extends React.PureComponent { this.UserListManager.fetchNextUsers().then((userList) => { if(userList.length === 0) { - this.decoratorMessage = "No users found"; + this.decoratorMessage = Translator.translate("NO_USERS_FOUND", this.state.lang); } userList.forEach(user => user = this.setAvatar(user)); @@ -196,13 +206,13 @@ class CometChatUserList extends React.PureComponent { }).catch((error) => { - this.decoratorMessage = "Error"; + this.decoratorMessage = Translator.translate("ERROR", this.state.lang); console.error("[CometChatUserList] getUsers fetchNext error", error); }); }).catch((error) => { - this.decoratorMessage = "Error"; + this.decoratorMessage = Translator.translate("ERROR", this.state.lang); console.log("[CometChatUserList] getUsers getLoggedInUser error", error); }); } @@ -224,7 +234,7 @@ class CometChatUserList extends React.PureComponent { if(this.state.userlist.length === 0) { messageContainer = (
-

{this.decoratorMessage}

+

{this.decoratorMessage}

); } @@ -246,9 +256,10 @@ class CometChatUserList extends React.PureComponent { {firstChar} @@ -263,18 +274,18 @@ class CometChatUserList extends React.PureComponent { return (
-
+
{closeBtn} -

Contacts

+

{Translator.translate("USERS", this.state.lang)}

{messageContainer} @@ -284,4 +295,15 @@ class CometChatUserList extends React.PureComponent { } } +// Specifies the default values for props: +CometChatUserList.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CometChatUserList.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CometChatUserList; diff --git a/CometChat/components/CometChatUserList/style.js b/CometChat/components/CometChatUserList/style.js index 8162e347..8a1723a9 100644 --- a/CometChat/components/CometChatUserList/style.js +++ b/CometChat/components/CometChatUserList/style.js @@ -26,7 +26,7 @@ export const contactWrapperStyle = () => { export const contactHeaderStyle = (theme) => { return { - padding: "19px 16px", + padding: "16px", position: "relative", display: "flex", alignItems: "center", @@ -61,10 +61,13 @@ export const contactHeaderTitleStyle = (props) => { margin: "0", fontWeight: "700", display: "inline-block", - width: "66%", + width: "100%", textAlign: "left", fontSize: "20px", - ...alignment + ...alignment, + "&[dir=rtl]": { + textAlign: "right", + } } } @@ -129,7 +132,7 @@ export const contactListStyle = () => { export const contactAlphabetStyle = () => { return { - padding: "0 15px", + padding: "0 16px", margin: "5px 0", width: "100%", fontSize: "14px" diff --git a/CometChat/components/CometChatUserListScreen/index.js b/CometChat/components/CometChatUserListScreen/index.js index 083966d8..1bfe61aa 100644 --- a/CometChat/components/CometChatUserListScreen/index.js +++ b/CometChat/components/CometChatUserListScreen/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -15,8 +16,6 @@ import CallAlert from "../CallAlert"; import CallScreen from "../CallScreen"; import ImageView from "../ImageView"; -import { theme } from "../../resources/theme"; - import { userScreenStyle, userScreenSidebarStyle, @@ -24,6 +23,9 @@ import { userScreenSecondaryStyle } from "./style" +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + class CometChatUserListScreen extends React.Component { loggedInUser = null; @@ -48,9 +50,8 @@ class CometChatUserListScreen extends React.Component { callmessage: {}, sidebarview: false, imageView: null, + lang: props.lang } - - this.theme = Object.assign({}, theme, this.props.theme); } componentDidMount() { @@ -67,6 +68,13 @@ class CometChatUserListScreen extends React.Component { }); } + componentDidUpdate(prevProps) { + + if (prevProps.lang !== this.props.lang) { + this.setState({ lang: this.props.lang }); + } + } + changeTheme = (e) => { const theme = this.state.darktheme; @@ -147,7 +155,7 @@ class CometChatUserListScreen extends React.Component { updateThreadMessage = (message, action) => { - if (this.state.threadmessageview === false) { + if (this.state.threadmessageview === false || message.id !== this.state.threadmessageparent.id) { return false; } @@ -346,14 +354,15 @@ class CometChatUserListScreen extends React.Component { let threadMessageView = null; if(this.state.threadmessageview) { threadMessageView = ( -
+
); @@ -362,11 +371,12 @@ class CometChatUserListScreen extends React.Component { let detailScreen; if(this.state.viewdetailscreen) { detailScreen = ( -
+
); } @@ -374,28 +384,30 @@ class CometChatUserListScreen extends React.Component { let messageScreen = null; if(Object.keys(this.state.item).length) { messageScreen = (); } let imageView = null; if (this.state.imageView) { - imageView = ( this.toggleImageView(null)} message={this.state.imageView} />); + imageView = ( this.toggleImageView(null)} message={this.state.imageView} lang={this.state.lang} />); } return ( -
-
+
+
@@ -404,15 +416,17 @@ class CometChatUserListScreen extends React.Component { {detailScreen} {threadMessageView} {imageView}
@@ -420,4 +434,15 @@ class CometChatUserListScreen extends React.Component { } } +// Specifies the default values for props: +CometChatUserListScreen.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CometChatUserListScreen.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CometChatUserListScreen; diff --git a/CometChat/components/CometChatViewMembers/index.js b/CometChat/components/CometChatViewMembers/index.js index 49129b67..cc3c4596 100644 --- a/CometChat/components/CometChatViewMembers/index.js +++ b/CometChat/components/CometChatViewMembers/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core' +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -21,6 +22,8 @@ import { actionColumnStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; import clearIcon from "./resources/close.png"; class CometChatViewMembers extends React.Component { @@ -112,6 +115,7 @@ class CometChatViewMembers extends React.Component { key={key} member={member} item={this.props.item} + lang={this.props.lang} widgetsettings={this.props.widgetsettings} actionGenerated={this.updateMembers} />); }); @@ -121,8 +125,8 @@ class CometChatViewMembers extends React.Component { editAccess = ( - Ban - Kick + {Translator.translate("BAN", this.props.lang)} + {Translator.translate("KICK", this.props.lang)} ); @@ -141,14 +145,14 @@ class CometChatViewMembers extends React.Component {
- +
- + - - + + {editAccess} @@ -161,4 +165,15 @@ class CometChatViewMembers extends React.Component { } } +// Specifies the default values for props: +CometChatViewMembers.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +CometChatViewMembers.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default CometChatViewMembers; \ No newline at end of file diff --git a/CometChat/components/ConversationView/index.js b/CometChat/components/ConversationView/index.js index 510eeca8..dd7b9e66 100644 --- a/CometChat/components/ConversationView/index.js +++ b/CometChat/components/ConversationView/index.js @@ -1,7 +1,8 @@ import React from "react"; import dateFormat from "dateformat"; /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from '@cometchat-pro/chat'; @@ -22,6 +23,9 @@ import { itemLastMsgTimeStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + class ConversationView extends React.Component { constructor(props) { @@ -30,7 +34,7 @@ class ConversationView extends React.Component { this.state = { lastMessage: "", - lastMessageTimestamp: "" + lastMessageTimestamp: "", } } @@ -47,7 +51,7 @@ class ConversationView extends React.Component { const previousItem = JSON.stringify(prevProps.conversation); const currentItem = JSON.stringify(this.props.conversation); - if (previousItem !== currentItem) { + if (previousItem !== currentItem || prevProps.lang !== this.props.lang) { const message = this.getLastMessage(); const timestamp = this.getLastMessageTimestamp(); @@ -71,7 +75,7 @@ class ConversationView extends React.Component { if (lastMessage.hasOwnProperty("deletedAt")) { - message = (this.props.loggedInUser.uid === lastMessage.sender.uid) ? "⚠ You deleted this message." : "⚠ This message was deleted."; + message = (this.props.loggedInUser.uid === lastMessage.sender.uid) ? `${Translator.translate("YOU_DELETED_THIS_MESSAGE", this.props.lang)}` : `${Translator.translate("THIS_MESSAGE_DELETED", this.props.lang)}`; } else { @@ -92,7 +96,6 @@ class ConversationView extends React.Component { break; } } - return message; } @@ -116,18 +119,19 @@ class ConversationView extends React.Component { const currentTimestamp = Date.now(); const diffTimestamp = currentTimestamp - messageTimestamp; - + if (diffTimestamp < 24 * 60 * 60 * 1000) { timestamp = dateFormat(messageTimestamp, "shortTime"); } else if (diffTimestamp < 48 * 60 * 60 * 1000) { - timestamp = "Yesterday"; + timestamp = Translator.translate("YESTERDAY", this.props.lang); } else if (diffTimestamp < 7 * 24 * 60 * 60 * 1000) { - timestamp = dateFormat(messageTimestamp, "dddd"); + timestamp = dateFormat(messageTimestamp, "dddd").toUpperCase(); + timestamp = Translator.translate(timestamp, this.props.lang); } else { @@ -140,23 +144,36 @@ class ConversationView extends React.Component { getCustomMessage = (lastMessage) => { let message = null; + const sender = (this.props.loggedInUser.uid !== lastMessage.sender.uid) ? `${lastMessage.sender.name}: ` : ``; + switch(lastMessage.type) { - case enums.CUSTOM_TYPE_POLL: - message = "📊 Poll"; - break; - case enums.CUSTOM_TYPE_STICKER: - message = "💟 Sticker"; - break; - case enums.CUSTOM_TYPE_DOCUMENT: - message = "📃 Document"; - break; - case enums.CUSTOM_TYPE_WHITEBOARD: - message = "📝 Whiteboard"; - break; + case enums.CUSTOM_TYPE_POLL: { + + const pollMessage = Translator.translate("CUSTOM_MESSAGE_POLL", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${pollMessage}` : `${pollMessage}`; + } + break; + case enums.CUSTOM_TYPE_STICKER: { + + const stickerMessage = Translator.translate("CUSTOM_MESSAGE_STICKER", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${stickerMessage}` : `${stickerMessage}`; + } + break; + case enums.CUSTOM_TYPE_DOCUMENT: { + + const docMessage = Translator.translate("CUSTOM_MESSAGE_DOCUMENT", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${docMessage}` : `${docMessage}`; + } + break; + case enums.CUSTOM_TYPE_WHITEBOARD: { + + const whiteboardMessage = Translator.translate("CUSTOM_MESSAGE_WHITEBOARD", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${whiteboardMessage}` : `${whiteboardMessage}`; + } + break; default: - break; + break; } - return message; } @@ -190,37 +207,59 @@ class ConversationView extends React.Component { } return messageText; - } getMessage = (lastMessage) => { let message = null; + const sender = (this.props.loggedInUser.uid !== lastMessage.sender.uid) ? `${lastMessage.sender.name}: ` : ``; + switch (lastMessage.type) { - case CometChat.MESSAGE_TYPE.TEXT: - message = this.getTextMessage(lastMessage); - break; - case CometChat.MESSAGE_TYPE.MEDIA: - message = "Media message"; - break; - case CometChat.MESSAGE_TYPE.IMAGE: - message = "📷 Image "; - break - case CometChat.MESSAGE_TYPE.FILE: - message = "📁 File"; - break; - case CometChat.MESSAGE_TYPE.VIDEO: - message = "🎥 Video"; - break; - case CometChat.MESSAGE_TYPE.AUDIO: - message = "🎵 Audio"; - break; - case CometChat.MESSAGE_TYPE.CUSTOM: - message = "Custom message"; - break; + case CometChat.MESSAGE_TYPE.TEXT: { + + const textMessage = this.getTextMessage(lastMessage); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${textMessage}` : `${textMessage}`; + } + break; + case CometChat.MESSAGE_TYPE.MEDIA: { + + const mediaMessage = Translator.translate("MEDIA_MESSAGE", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${mediaMessage}` : `${mediaMessage}`; + } + break; + case CometChat.MESSAGE_TYPE.IMAGE: { + + const imageMessage = Translator.translate("MESSAGE_IMAGE", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${imageMessage}` : `${imageMessage}`; + } + break + case CometChat.MESSAGE_TYPE.FILE: { + + const fileMessage = Translator.translate("MESSAGE_FILE", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${fileMessage}` : `${fileMessage}`; + } + break; + case CometChat.MESSAGE_TYPE.VIDEO: { + + const videoMessage = Translator.translate("MESSAGE_VIDEO", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${videoMessage}` : `${videoMessage}`; + } + break; + case CometChat.MESSAGE_TYPE.AUDIO: { + + const audioMessage = Translator.translate("MESSAGE_AUDIO", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${audioMessage}` : `${audioMessage}`; + } + break; + case CometChat.MESSAGE_TYPE.CUSTOM: { + + const customMessage = Translator.translate("CUSTOM_MESSAGE", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${customMessage}` : `${customMessage}`; + } + break; default: - break; + break; } return message; @@ -229,19 +268,28 @@ class ConversationView extends React.Component { getCallMessage = (lastMessage) => { let message = null; + const sender = (this.props.loggedInUser.uid !== lastMessage.sender.uid) ? `${lastMessage.sender.name}: ` : ``; + switch (lastMessage.type) { - case CometChat.MESSAGE_TYPE.VIDEO: - message = "Video call"; - break; - case CometChat.MESSAGE_TYPE.AUDIO: - message = "Audio call"; - break; + case CometChat.MESSAGE_TYPE.VIDEO: { + + const videoMessage = Translator.translate("VIDEO_CALL", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${videoMessage}` : `${videoMessage}`; + } + break; + case CometChat.MESSAGE_TYPE.AUDIO: { + + const audioMessage = Translator.translate("AUDIO_CALL", this.props.lang); + message = (lastMessage.receiverType === CometChat.RECEIVER_TYPE.GROUP) ? `${sender} ${audioMessage}` : `${audioMessage}`; + } + break; default: - break; + break; } return message; } + toggleTooltip = (event, flag) => { const elem = event.target; @@ -288,23 +336,17 @@ class ConversationView extends React.Component { + borderColor={this.props.theme.borderColor.primary} /> ); } return (
this.props.handleClick(this.props.conversation, this.props.conversationKey)}>
- + {presence}
-
+
this.toggleTooltip(event, true)} @@ -324,4 +366,15 @@ class ConversationView extends React.Component { } } +// Specifies the default values for props: +ConversationView.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +ConversationView.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default ConversationView; \ No newline at end of file diff --git a/CometChat/components/ConversationView/style.js b/CometChat/components/ConversationView/style.js index c5c5805a..4d60773e 100644 --- a/CometChat/components/ConversationView/style.js +++ b/CometChat/components/ConversationView/style.js @@ -11,11 +11,11 @@ export const listItem = (props) => { alignItems: "center", cursor: "pointer", width: "100%", - padding: "10px 20px", + padding: "8px 16px", ...selectedState, '&:hover': { backgroundColor: `${props.theme.backgroundColor.primary}` - } + }, } } @@ -34,7 +34,11 @@ export const itemDetailStyle = () => { return { width: "calc(100% - 45px)", flexGrow: "1", - paddingLeft: "15px", + paddingLeft: "16px", + "&[dir=rtl]": { + paddingRight: "16px", + paddingLeft: "0", + } } } diff --git a/CometChat/components/CreatePollView/index.js b/CometChat/components/CreatePollView/index.js index 6d72e5bb..a2aaeeb6 100644 --- a/CometChat/components/CreatePollView/index.js +++ b/CometChat/components/CreatePollView/index.js @@ -1,10 +1,12 @@ /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; +import { iconWrapperStyle } from "../CometChatCreatePoll/style"; import { removeOptionIconStyle } from "./style"; +import Translator from "../../resources/localization/translator"; import removeIcon from "./resources/remove.png"; -import { iconWrapperStyle } from "../CometChatCreatePoll/style"; const createpollview = (props) => { @@ -17,7 +19,7 @@ const createpollview = (props) => { tabIndex={props.tabIndex} type="text" autoComplete="off" - placeholder="Enter your option" + placeholder={Translator.translate("ENTER_YOUR_OPTION", props.lang)} value={props.value} onChange={(event) => props.optionChangeHandler(event, props.option)} /> @@ -28,4 +30,13 @@ const createpollview = (props) => { ); } +// Specifies the default values for props: +createpollview.defaultProps = { + lang: Translator.getDefaultLanguage(), +}; + +createpollview.propTypes = { + lang: PropTypes.string, +} + export default createpollview; \ No newline at end of file diff --git a/CometChat/components/DeletedMessageBubble/index.js b/CometChat/components/DeletedMessageBubble/index.js index 281c6be9..39ac9fb8 100644 --- a/CometChat/components/DeletedMessageBubble/index.js +++ b/CometChat/components/DeletedMessageBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; import dateFormat from "dateformat"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { SvgAvatar } from '../../util/svgavatar'; import Avatar from "../Avatar"; @@ -19,6 +20,9 @@ import { nameStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + const deletedmessagebubble = (props) => { let message = null; @@ -28,7 +32,7 @@ const deletedmessagebubble = (props) => { message = (
-

You deleted this message.

+

{Translator.translate("YOU_DELETED_THIS_MESSAGE", props.lang)}

{dateFormat(messageDate, "shortTime")} @@ -59,7 +63,10 @@ const deletedmessagebubble = (props) => { image={props.message.sender.avatar} />
) - name = (
{props.message.sender.name}
); + name = ( +
+ {props.message.sender.name} +
); } message = ( @@ -68,7 +75,7 @@ const deletedmessagebubble = (props) => {
{name}
-

This message was deleted.

+

{Translator.translate("THIS_MESSAGE_DELETED", props.lang)}

{dateFormat(messageDate, "shortTime")} @@ -85,4 +92,15 @@ const deletedmessagebubble = (props) => { ) } +// Specifies the default values for props: +deletedmessagebubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +deletedmessagebubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default deletedmessagebubble; \ No newline at end of file diff --git a/CometChat/components/EmojiView/index.js b/CometChat/components/EmojiView/index.js index a5fecda2..35fa9f27 100644 --- a/CometChat/components/EmojiView/index.js +++ b/CometChat/components/EmojiView/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from "@emotion/core"; +import PropTypes from 'prop-types'; import { Picker } from "emoji-mart"; @@ -9,25 +10,84 @@ import { pickerStyle } from "./style"; +import Translator from "../../resources/localization/translator"; + class EmojiView extends React.Component { + categories = {}; + title = ""; + + constructor(props) { + + super(props); + + const categories = { + people: Translator.translate("SMILEY_PEOPLE", props.lang), + nature: Translator.translate("ANIMALES_NATURE", props.lang), + foods: Translator.translate("FOOD_DRINK", props.lang), + activity: Translator.translate("ACTIVITY", props.lang), + places: Translator.translate("TRAVEL_PLACES", props.lang), + objects: Translator.translate("OBJECTS", props.lang), + symbols: Translator.translate("SYMBOLS", props.lang), + flags: Translator.translate("FLAGS", props.lang) + } + + const title = Translator.translate("PICK_YOUR_EMOJI", props.lang); + + this.state = { + categories: categories, + title: title + } + } + + componentDidUpdate(prevProps) { + + if(prevProps.lang !== this.props.lang) { + + const categories = { + search: Translator.translate("SEARCH", this.props.lang), + people: Translator.translate("SMILEY_PEOPLE", this.props.lang), + nature: Translator.translate("ANIMALES_NATURE", this.props.lang), + foods: Translator.translate("FOOD_DRINK", this.props.lang), + activity: Translator.translate("ACTIVITY", this.props.lang), + places: Translator.translate("TRAVEL_PLACES", this.props.lang), + objects: Translator.translate("OBJECTS", this.props.lang), + symbols: Translator.translate("SYMBOLS", this.props.lang), + flags: Translator.translate("FLAGS", this.props.lang) + } + + const title = Translator.translate("PICK_YOUR_EMOJI", this.props.lang); + + this.setState({ categories: { ...categories}, title: title }); + } + } + render() { const exclude = ["search", "recent"]; return(
); } +} + +// Specifies the default values for props: +EmojiView.defaultProps = { + lang: Translator.getDefaultLanguage(), +}; +EmojiView.propTypes = { + lang: PropTypes.string, } export default EmojiView; \ No newline at end of file diff --git a/CometChat/components/GroupView/index.js b/CometChat/components/GroupView/index.js index 3f1e4075..4dc5c3e9 100644 --- a/CometChat/components/GroupView/index.js +++ b/CometChat/components/GroupView/index.js @@ -1,5 +1,6 @@ /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import Avatar from "../Avatar"; @@ -13,6 +14,9 @@ import { listItemName } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import shieldIcon from "./resources/shield.png"; import lockIcon from "./resources/lock.png"; @@ -39,33 +43,40 @@ const groupview = (props) => { let groupTypeIcon = null; if(props.group.type === "private") { - groupTypeIcon = (Private Group); + groupTypeIcon = ({Translator.translate("PRIVATE_GROUP",); } else if(props.group.type === "password") { - groupTypeIcon = (Protected Group); + groupTypeIcon = ({Translator.translate("PROTECTED_GROUP",); } return (
props.clickHandler(props.group)}>
- +
-
+
toggleTooltip(event, true)} onMouseLeave={event => toggleTooltip(event, false)}>

{props.group.name}

{groupTypeIcon}
-
{props.group.membersCount} members
+
{`${props.group.membersCount} ${Translator.translate("MEMBERS", props.lang).toLowerCase()}`}
) } +// Specifies the default values for props: +groupview.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +groupview.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default groupview; \ No newline at end of file diff --git a/CometChat/components/GroupView/style.js b/CometChat/components/GroupView/style.js index cbc819aa..bd9c6b2f 100644 --- a/CometChat/components/GroupView/style.js +++ b/CometChat/components/GroupView/style.js @@ -11,7 +11,7 @@ export const listItem = (props) => { alignItems: "center", cursor: "pointer", width: "100%", - padding: "10px 20px", + padding: "8px 16px", ...selectedState, '&:hover': { backgroundColor: `${props.theme.backgroundColor.primary}` @@ -54,7 +54,11 @@ export const itemDetailStyle = () => { return { width: "calc(100% - 70px)", flexGrow: "1", - paddingLeft: "15px", + paddingLeft: "16px", + "&[dir=rtl]": { + paddingRight: "16px", + paddingLeft: "0", + } } } diff --git a/CometChat/components/ImageView/index.js b/CometChat/components/ImageView/index.js index a4a213d9..485539a5 100644 --- a/CometChat/components/ImageView/index.js +++ b/CometChat/components/ImageView/index.js @@ -2,6 +2,9 @@ import React, { useRef } from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; + +import Backdrop from "../Backdrop"; import { imageWrapperStyle, @@ -11,8 +14,6 @@ import { import srcIcon from "./resources/ring.svg"; import closeIcon from "./resources/close.png"; -import Backdrop from "../Backdrop"; - const ImageView = (props) => { let imgRef = useRef(); @@ -30,9 +31,22 @@ const ImageView = (props) => {
- Full Screen View { imgRef = el; }} /> + {srcIcon} { imgRef = el; }} />
) } + + +// Specifies the default values for props: +ImageView.defaultProps = { + count: 0, + close: () => { } +}; + +ImageView.propTypes = { + show: PropTypes.bool, + close: PropTypes.func, +} + export default ImageView; \ No newline at end of file diff --git a/CometChat/components/LinkPreview/index.js b/CometChat/components/LinkPreview/index.js index 01c2bc7a..e4658da5 100644 --- a/CometChat/components/LinkPreview/index.js +++ b/CometChat/components/LinkPreview/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; @@ -16,6 +17,9 @@ import { previewTextStyle, } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + class LinkPreview extends React.PureComponent { constructor(props) { @@ -34,7 +38,7 @@ class LinkPreview extends React.PureComponent { const linkObject = linkPreviewData["links"][0]; const pattern = /(http:|https:)?\/\/(www\.)?(youtube.com|youtu.be)(\S+)?/; - const linkText = (linkObject["url"].match(pattern)) ? "View on Youtube" : "Visit"; + const linkText = (linkObject["url"].match(pattern)) ? Translator.translate("VIEW_ON_YOUTUBE", this.props.lang) : Translator.translate("VISIT", this.props.lang); return (
@@ -54,4 +58,15 @@ class LinkPreview extends React.PureComponent { } } +// Specifies the default values for props: +LinkPreview.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +LinkPreview.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default LinkPreview; \ No newline at end of file diff --git a/CometChat/components/MemberView/index.js b/CometChat/components/MemberView/index.js index 21a92004..ad12283e 100644 --- a/CometChat/components/MemberView/index.js +++ b/CometChat/components/MemberView/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core' +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -22,6 +23,8 @@ import { scopeSelectionStyle } from "./style"; +import Translator from "../../resources/localization/translator"; + import scopeIcon from "./resources/edit.png"; import doneIcon from "./resources/done.png"; import clearIcon from "./resources/close.png"; @@ -42,15 +45,25 @@ class MemberView extends React.Component { defaultValue={this.props.member.scope}> ) + this.state = { + showChangeScope: false, + scope: null + } + this.roles = {} - this.roles[CometChat.GROUP_MEMBER_SCOPE.ADMIN] = "Administrator"; - this.roles[CometChat.GROUP_MEMBER_SCOPE.MODERATOR] = "Moderator"; - this.roles[CometChat.GROUP_MEMBER_SCOPE.PARTICIPANT] = "Participant"; + this.roles[CometChat.GROUP_MEMBER_SCOPE.ADMIN] = Translator.translate("ADMINISTRATOR", props.lang); + this.roles[CometChat.GROUP_MEMBER_SCOPE.MODERATOR] = Translator.translate("MODERATOR", props.lang); + this.roles[CometChat.GROUP_MEMBER_SCOPE.PARTICIPANT] = Translator.translate("PARTICIPANT", props.lang); } - - state = { - showChangeScope: false, - scope: null + + componentDidUpdate(prevProps) { + + if (prevProps.lang !== this.props.lang) { + + this.roles[CometChat.GROUP_MEMBER_SCOPE.ADMIN] = Translator.translate("ADMINISTRATOR", this.props.lang); + this.roles[CometChat.GROUP_MEMBER_SCOPE.MODERATOR] = Translator.translate("MODERATOR", this.props.lang); + this.roles[CometChat.GROUP_MEMBER_SCOPE.PARTICIPANT] = Translator.translate("PARTICIPANT", this.props.lang); + } } toggleChangeScope = (flag) => { @@ -94,8 +107,8 @@ class MemberView extends React.Component { let name = this.props.member.name; let scope = ({this.roles[this.props.member.scope]}); let changescope = null; - let ban = (Ban {this.props.actionGenerated("ban", this.props.member)}} />); - let kick = (Kick {this.props.actionGenerated("kick", this.props.member)}} />); + let ban = ({Translator.translate("BAN", {this.props.actionGenerated("ban", this.props.member)}} />); + let kick = ({Translator.translate("KICK", {this.props.actionGenerated("kick", this.props.member)}} />); if(this.state.showChangeScope) { @@ -126,8 +139,8 @@ class MemberView extends React.Component { className="scope__select" onChange={this.scopeChangeHandler} defaultValue={this.props.member.scope}>{options} - Change Scope - Change Scope this.toggleChangeScope(false)} /> + {Translator.translate("CHANGE_SCOPE", + {Translator.translate("CHANGE_SCOPE", this.toggleChangeScope(false)} />
); @@ -139,7 +152,7 @@ class MemberView extends React.Component { changescope = ( {scope} - Change Scope this.toggleChangeScope(true)} /> + {Translator.translate("CHANGE_SCOPE", this.toggleChangeScope(true)} /> ); } @@ -147,7 +160,7 @@ class MemberView extends React.Component { //disable change scope, kick, ban of group owner if(this.props.item.owner === this.props.member.uid) { - scope = ({"Owner"}); + scope = ({Translator.translate("OWNER", this.props.lang)}); changescope = scope; ban = null; kick = null; @@ -155,7 +168,7 @@ class MemberView extends React.Component { //disable change scope, kick, ban of self if(group.loggedinuser.uid === this.props.member.uid) { - name = "You"; + name = Translator.translate("YOU", this.props.lang); changescope = scope; ban = null; kick = null; @@ -197,14 +210,12 @@ class MemberView extends React.Component { //if kick_ban_members is disabled in chatwidget if (this.props.widgetsettings.main.hasOwnProperty("allow_kick_ban_members") && this.props.widgetsettings.main["allow_kick_ban_members"] === false) { - editAccess = null; } //if promote_demote_members is disabled in chatwidget if (this.props.widgetsettings.main.hasOwnProperty("allow_promote_demote_members") && this.props.widgetsettings.main["allow_promote_demote_members"] === false) { - changescope = scope; } } @@ -214,9 +225,7 @@ class MemberView extends React.Component { + borderColor={this.props.theme.borderColor.primary} /> ); return ( @@ -225,11 +234,7 @@ class MemberView extends React.Component { onMouseEnter={event => this.toggleTooltip(event, true)} onMouseLeave={event => this.toggleTooltip(event, false)}>
- + {userPresence}
{name}
@@ -241,4 +246,13 @@ class MemberView extends React.Component { } } +// Specifies the default values for props: +MemberView.defaultProps = { + lang: Translator.getDefaultLanguage(), +}; + +MemberView.propTypes = { + lang: PropTypes.string, +} + export default MemberView; \ No newline at end of file diff --git a/CometChat/components/MemberView/style.js b/CometChat/components/MemberView/style.js index 22f29cb9..57a9fdde 100644 --- a/CometChat/components/MemberView/style.js +++ b/CometChat/components/MemberView/style.js @@ -13,11 +13,6 @@ export const tableColumnStyle = () => { return { padding: "8px", - "img": { - width: "36px", - height: "36px", - float: "left", - } } } @@ -32,10 +27,9 @@ export const avatarStyle = (participantView) => { return { display: "inline-block", float: "left", - "span": { - top: "26px", - left: "-8px", - }, + width: "36px", + height: "36px", + marginRight: "8px", [mq[0]]: { ...displayProp } diff --git a/CometChat/components/MessageComposer/index.js b/CometChat/components/MessageComposer/index.js index 7b67de8b..9c2d864a 100644 --- a/CometChat/components/MessageComposer/index.js +++ b/CometChat/components/MessageComposer/index.js @@ -3,6 +3,7 @@ import React from "react"; /** @jsx jsx */ import { jsx, keyframes } from "@emotion/core"; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -38,6 +39,9 @@ import { stickerBtnStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import roundedPlus from "./resources/attach.png"; import videoIcon from "./resources/attachvideo.png"; import audioIcon from "./resources/attachaudio.png"; @@ -85,6 +89,13 @@ class MessageComposer extends React.PureComponent { this.audio = new Audio(outgoingMessageAlert); } + componentDidMount() { + + if (this.messageInputRef && this.messageInputRef.current) { + this.messageInputRef.current.focus(); + } + } + componentDidUpdate(prevProps, prevState) { if (prevProps.messageToBeEdited !== this.props.messageToBeEdited) { @@ -128,8 +139,13 @@ class MessageComposer extends React.PureComponent { } if (prevProps.item !== this.props.item) { + this.messageInputRef.current.textContent = ""; this.setState({ stickerViewer: false, emojiViewer: false, replyPreview: null, messageToBeEdited: "", messageInput: "" }); + + if (this.messageInputRef && this.messageInputRef.current) { + this.messageInputRef.current.focus(); + } } } @@ -683,12 +699,13 @@ class MessageComposer extends React.PureComponent { render() { let liveReactionBtn = null; + const liveReactionText = Translator.translate("LIVE_REACTION", this.props.lang); if (enums.LIVE_REACTIONS.hasOwnProperty(this.props.reaction)) { const reactionName = this.props.reaction; const imgSrc = enums.LIVE_REACTIONS[reactionName]; liveReactionBtn = ( -
+
{reactionName}
); @@ -699,86 +716,97 @@ class MessageComposer extends React.PureComponent { disabledState = true; } + const docText = Translator.translate("ATTACH_FILE", this.props.lang); let docs = (
{ this.openFileDialogue("file") }}> - Attach a file + {docText}
); + const videoText = Translator.translate("ATTACH_VIDEO", this.props.lang); + const audioText = Translator.translate("ATTACH_AUDIO", this.props.lang); + const imageText = Translator.translate("ATTACH_IMAGE", this.props.lang); let avp = ( -
{ this.openFileDialogue("video") }}> - Attach video +
{ this.openFileDialogue("video") }}> + {videoText}
-
{ this.openFileDialogue("audio") }}> - Attach audio +
{ this.openFileDialogue("audio") }}> + {audioText}
-
{ this.openFileDialogue("image") }}> - Attach an image +
{ this.openFileDialogue("image") }}> + {imageText}
); + const pollText = Translator.translate("CREATE_POLL", this.props.lang); let createPollBtn = (
- Create a poll + {pollText}
); + const collaborativeDocText = Translator.translate("COLLABORATE_USING_DOCUMENT", this.props.lang); let collaborativeDocBtn = (
- Collaborate using a document + {collaborativeDocText}
); + const collaborativeBoardText = Translator.translate("COLLABORATE_USING_WHITEBOARD", this.props.lang); let collaborativeBoardBtn = (
- Collaborate using a document + {collaborativeBoardText}
); + const emojiText = Translator.translate("EMOJI", this.props.lang); let emojiBtn = (
{ - this.toggleEmojiPicker(); - this.setState({ messageToReact: "" }); - }}>Insert Emoticon
+ this.toggleEmojiPicker(); + this.setState({ messageToReact: "" });}}> + {emojiText} +
); + const StickerText = Translator.translate("STICKER", this.props.lang); let stickerBtn = (
Add Sticker
+ onClick={this.toggleStickerPicker} > {StickerText}
); + const sendMessageText = Translator.translate("SEND_MESSAGE", this.props.lang); let sendBtn = ( -
- Send Message +
+ {sendMessageText}
); @@ -827,12 +855,13 @@ class MessageComposer extends React.PureComponent { sendBtn = null; } + const attachText = Translator.translate("ATTACH", this.props.lang); let attach = (
-
- Attach +
+ {attachText}
-
+
{avp} {docs} @@ -857,6 +886,7 @@ class MessageComposer extends React.PureComponent { type={this.props.type} open={this.state.createPoll} close={this.closeCreatePoll} + lang={this.props.lang} widgetsettings={this.props.widgetsettings} actionGenerated={this.actionHandler} /> ); @@ -898,7 +928,7 @@ class MessageComposer extends React.PureComponent { editPreview = (
-
Edit message
+
{Translator.translate("EDIT_MESSAGE", this.props.lang)}
{messageText}
@@ -929,6 +959,7 @@ class MessageComposer extends React.PureComponent { theme={this.props.theme} item={this.props.item} type={this.props.type} + lang={this.props.lang} widgetsettings={this.props.widgetsettings} actionGenerated={this.actionHandler} /> ); @@ -937,7 +968,7 @@ class MessageComposer extends React.PureComponent { let emojiViewer = null; if (this.state.emojiViewer) { emojiViewer = ( - + ); } @@ -953,8 +984,8 @@ class MessageComposer extends React.PureComponent { css={messageInputStyle(disabledState)} className="input__message-input" contentEditable="true" - placeholder="Enter your message here" - dir="ltr" + placeholder={Translator.translate("ENTER_YOUR_MESSAGE_HERE", this.props.lang)} + dir={Translator.getDirection(this.props.lang)} onInput={this.changeHandler} onBlur={this.endTyping} onKeyDown={this.sendMessageOnEnter} @@ -976,4 +1007,15 @@ class MessageComposer extends React.PureComponent { } } +// Specifies the default values for props: +MessageComposer.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +MessageComposer.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default MessageComposer; diff --git a/CometChat/components/MessageComposer/style.js b/CometChat/components/MessageComposer/style.js index 6e6dfe50..c90f1505 100644 --- a/CometChat/components/MessageComposer/style.js +++ b/CometChat/components/MessageComposer/style.js @@ -1,7 +1,7 @@ export const chatComposerStyle = (props) => { return { - padding: "14px 16px", + padding: "16px", backgroundColor: `${props.theme.backgroundColor.white}`, zIndex: "1", order: "3", @@ -172,7 +172,7 @@ export const attachmentIconStyle = () => { export const filePickerStyle = (state) => { const active = (state.showFilePicker) ? { - width: "100%", + width: "calc(100% - 100px)", opacity: "1", } : {}; @@ -186,7 +186,11 @@ export const filePickerStyle = (state) => { textAlign: "center", opacity: "0", transition: "width 0.5s linear", - ...active + ...active, + "&[dir=rtl]": { + left: "0", + right: "48px", + } } } @@ -197,9 +201,7 @@ export const fileListStyle = () => { display: "flex", flexDirection: "row", alignItems: "center", - "div:not(:last-of-type)": { - marginRight: "14px" - } + justifyContent: "space-between" } } @@ -234,27 +236,19 @@ export const stickyAttachButtonStyle = () => { export const stickyButtonStyle = (props, state) => { - const mq = [...props.theme.breakPoints]; - const active = (state.showFilePicker) ? { display: "none", } : { display: "flex", }; - return { display: "flex", alignItems: "center", - justifyContent: "space-between", - "div:not(:last-of-type)": { - marginRight: "14px" - }, + justifyContent: "space-around", cursor: "pointer", - maxWidth: "100px", - [`@media ${mq[0]}`]: { - ...active - } + width: "100px", + ...active } } diff --git a/CometChat/components/MessageHeader/index.js b/CometChat/components/MessageHeader/index.js index c9c313e2..d0480ea3 100644 --- a/CometChat/components/MessageHeader/index.js +++ b/CometChat/components/MessageHeader/index.js @@ -1,15 +1,16 @@ import React from "react"; import dateFormat from "dateformat"; /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { MessageHeaderManager } from "./controller"; import StatusIndicator from "../StatusIndicator"; import Avatar from "../Avatar"; import { SvgAvatar } from '../../util/svgavatar'; - import * as enums from '../../util/enums.js'; +import { validateWidgetSettings } from "../../util/common"; import { chatHeaderStyle, @@ -23,6 +24,9 @@ import { chatOptionStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import menuIcon from './resources/menuicon.png'; import audioCallIcon from './resources/audiocall.png'; import videoCallIcon from './resources/videocall.png'; @@ -57,18 +61,24 @@ class MessageHeader extends React.Component { this.MessageHeaderManager = new MessageHeaderManager(); this.MessageHeaderManager.attachListeners(this.updateHeader); - if (this.props.type === 'user' && prevProps.item.uid !== this.props.item.uid) { + if (this.props.type === 'user' + && (prevProps.item.uid !== this.props.item.uid + || (prevProps.item.uid === this.props.item.uid && prevProps.lang !== this.props.lang))) { + this.setStatusForUser(); + } else if (this.props.type === 'group' && (prevProps.item.guid !== this.props.item.guid - || (prevProps.item.guid === this.props.item.guid && prevProps.item.membersCount !== this.props.item.membersCount)) ) { + || (prevProps.item.guid === this.props.item.guid && prevProps.item.membersCount !== this.props.item.membersCount) + || (prevProps.item.guid === this.props.item.guid && prevProps.lang !== this.props.lang)) ) { + this.setStatusForGroup(); } } setStatusForUser = () => { - let status = this.props.item.status; + let status = ""; const presence = (this.props.item.status === "online") ? "online" : "offline"; if(this.props.item.status === "offline" && this.props.item.lastActiveAt) { @@ -76,9 +86,15 @@ class MessageHeader extends React.Component { const lastActive = (this.props.item.lastActiveAt * 1000); const messageDate = dateFormat(lastActive, "d mmmm yyyy, h:MM TT"); - status = "Last active at: " + messageDate; + status = `${Translator.translate("LAST_ACTIVE_AT", this.props.lang)} : ${messageDate}`; + } else if(this.props.item.status === "offline") { - status = "offline"; + + status = (Translator.translate("OFFLINE", this.props.lang)); + + } else if (this.props.item.status === "online") { + + status = (Translator.translate("ONLINE", this.props.lang)); } this.setState({status: status, presence: presence}); @@ -86,7 +102,8 @@ class MessageHeader extends React.Component { setStatusForGroup = () => { - const status = `${this.props.item.membersCount} members`; + let membersText = (Translator.translate("MEMBERS", this.props.lang)).toLowerCase(); + const status = `${this.props.item.membersCount} ${membersText}`; this.setState({status: status}); } @@ -104,12 +121,11 @@ class MessageHeader extends React.Component { case enums.USER_OFFLINE: { if(this.props.type === "user" && this.props.item.uid === item.uid) { - if(this.props.widgetsettings - && this.props.widgetsettings.hasOwnProperty("main") - && this.props.widgetsettings.main.hasOwnProperty("show_user_presence") - && this.props.widgetsettings.main["show_user_presence"] === false) { + //if user presence is disabled in chat widget + if (validateWidgetSettings(this.props.widgetsettings, "show_user_presence") === false) { return false; } + this.setState({ status: item.status, presence: item.status }); } break; @@ -122,7 +138,7 @@ class MessageHeader extends React.Component { && this.props.loggedInUser.uid !== groupUser.uid) { let membersCount = parseInt(item.membersCount); - const status = `${membersCount} members`; + const status = `${membersCount} ${Translator.translate("MEMBERS", this.props.lang).toLowerCase()}`; this.setState({status: status}); } break; @@ -130,7 +146,7 @@ class MessageHeader extends React.Component { if(this.props.type === "group" && this.props.item.guid === item.guid) { let membersCount = parseInt(item.membersCount); - const status = `${membersCount} members`; + const status = `${membersCount} ${(Translator.translate("MEMBERS", this.props.lang)).toLowerCase()}`; this.setState({status: status}); } break; @@ -138,7 +154,7 @@ class MessageHeader extends React.Component { if(this.props.type === "group" && this.props.item.guid === item.guid) { let membersCount = parseInt(item.membersCount); - const status = `${membersCount} members`; + const status = `${membersCount} ${(Translator.translate("MEMBERS", this.props.lang)).toLowerCase()}`; this.setState({status: status}); } break; @@ -146,15 +162,17 @@ class MessageHeader extends React.Component { if (this.props.type === "group" && this.props.type === item.receiverType && this.props.item.guid === item.receiverId) { - this.setState({ status: `${item.sender.name} is typing...` }); + const typingText = `${item.sender.name} ${Translator.translate("IS_TYPING", this.props.lang)}`; + this.setState({ status: typingText }); this.props.actionGenerated("showReaction", item); } else if (this.props.type === "user" && this.props.type === item.receiverType && this.props.item.uid === item.sender.uid) { - this.setState({ status: "typing..." }); + const typingText = `${Translator.translate("TYPING", this.props.lang)}`; + this.setState({ status: typingText }); this.props.actionGenerated("showReaction", item); - } + break; } case enums.TYPING_ENDED: { @@ -217,9 +235,7 @@ class MessageHeader extends React.Component { + borderColor={this.props.theme.borderColor.primary} /> ); } else { @@ -237,16 +253,21 @@ class MessageHeader extends React.Component { {this.state.status} ); - let audioCallBtn = ( -
this.props.actionGenerated("audioCall")} css={chatOptionStyle(audioCallIcon)}> - Voice call + const audioCallText = Translator.translate("AUDIO_CALL", this.props.lang); + let audioCallBtn = ( +
this.props.actionGenerated("audioCall")} css={chatOptionStyle(audioCallIcon)}> + {audioCallText}
); + + const videoCallText = Translator.translate("VIDEO_CALL", this.props.lang); let videoCallBtn = ( -
this.props.actionGenerated("videoCall")} css={chatOptionStyle(videoCallIcon)}> - Video call +
this.props.actionGenerated("videoCall")} css={chatOptionStyle(videoCallIcon)}> + {videoCallText}
); - let viewDetailBtn = (
this.props.actionGenerated("viewDetail")} css={chatOptionStyle(detailPaneIcon)}> - View detail + + const viewDetailText = Translator.translate("VIEW_DETAIL", this.props.lang); + let viewDetailBtn = (
this.props.actionGenerated("viewDetail")} css={chatOptionStyle(detailPaneIcon)}> + {viewDetailText}
); if(this.props.viewdetail === false) { @@ -261,24 +282,19 @@ class MessageHeader extends React.Component { videoCallBtn = null; } - if(this.props.widgetsettings && this.props.widgetsettings.hasOwnProperty("main")) { - - if(this.props.widgetsettings.main.hasOwnProperty("enable_voice_calling") - && this.props.widgetsettings.main["enable_voice_calling"] === false) { - audioCallBtn = null; - } + //if audiocall is disabled in chat widget + if (validateWidgetSettings(this.props.widgetsettings, "enable_voice_calling") === false) { + audioCallBtn = null; + } - if(this.props.widgetsettings.main.hasOwnProperty("enable_video_calling") - && this.props.widgetsettings.main["enable_video_calling"] === false) { - videoCallBtn = null; - } + //if videocall is disabled in chat widget + if (validateWidgetSettings(this.props.widgetsettings, "enable_video_calling") === false) { + videoCallBtn = null; + } - if(this.props.widgetsettings.main.hasOwnProperty("show_user_presence") - && this.props.widgetsettings.main["show_user_presence"] === false - && this.props.type === "user") { - status = null; - } - + //if user presence is disabled in chat widget + if (validateWidgetSettings(this.props.widgetsettings, "show_user_presence") === false && this.props.type === "user") { + status = null; } return ( @@ -286,11 +302,7 @@ class MessageHeader extends React.Component {
this.props.actionGenerated("menuClicked")}>
- + {presence}
@@ -310,4 +322,15 @@ class MessageHeader extends React.Component { } } +// Specifies the default values for props: +MessageHeader.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +MessageHeader.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default MessageHeader; \ No newline at end of file diff --git a/CometChat/components/MessageHeader/style.js b/CometChat/components/MessageHeader/style.js index 69d1e7cb..7bddd853 100644 --- a/CometChat/components/MessageHeader/style.js +++ b/CometChat/components/MessageHeader/style.js @@ -138,12 +138,9 @@ export const chatOptionWrapStyle = () => { return { display: "flex", flexDirection: "row", - justifyContent: "center", + justifyContent: "space-between", alignItems: "center", width: "110px", - "div:not(:last-of-type)": { - marginRight: "14px" - }, } } diff --git a/CometChat/components/MessageList/index.js b/CometChat/components/MessageList/index.js index a68b5639..38bd4eeb 100644 --- a/CometChat/components/MessageList/index.js +++ b/CometChat/components/MessageList/index.js @@ -1,13 +1,13 @@ import React from "react"; import dateFormat from "dateformat"; /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; import { CometChatManager } from "../../util/controller"; import { MessageListManager } from "./controller"; - import * as enums from "../../util/enums.js"; import { validateWidgetSettings } from "../../util/common"; @@ -33,6 +33,9 @@ import ReceiverWhiteboardBubble from "../ReceiverWhiteboardBubble"; import CallMessage from "../CallMessage"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import { chatListStyle, listWrapperStyle, @@ -48,7 +51,7 @@ class MessageList extends React.PureComponent { loggedInUser = null; lastScrollTop = 0; times = 0; - decoratorMessage = "Loading..."; + decoratorMessage = Translator.translate("LOADING", Translator.getDefaultLanguage()); constructor(props) { @@ -80,7 +83,7 @@ class MessageList extends React.PureComponent { if (this.props.type === 'user' && prevProps.item.uid !== this.props.item.uid) { - this.decoratorMessage = "Loading..."; + this.decoratorMessage = Translator.translate("LOADING", this.props.lang); this.MessageListManager.removeListeners(); if (this.props.parentMessageId) { @@ -94,7 +97,7 @@ class MessageList extends React.PureComponent { } else if (this.props.type === 'group' && prevProps.item.guid !== this.props.item.guid){ - this.decoratorMessage = "Loading..."; + this.decoratorMessage = Translator.translate("LOADING", this.props.lang); this.MessageListManager.removeListeners(); if (this.props.parentMessageId) { @@ -108,7 +111,7 @@ class MessageList extends React.PureComponent { } else if(prevProps.parentMessageId !== this.props.parentMessageId) { - this.decoratorMessage = "Loading..."; + this.decoratorMessage = Translator.translate("LOADING", this.props.lang); this.MessageListManager.removeListeners(); this.MessageListManager = new MessageListManager(this.props.widgetsettings, this.props.item, this.props.type, this.props.parentMessageId); this.getMessages(); @@ -142,7 +145,7 @@ class MessageList extends React.PureComponent { this.MessageListManager.fetchPreviousMessages().then(messageList => { if (messageList.length === 0) { - this.decoratorMessage = "No messages found"; + this.decoratorMessage = Translator.translate("NO_MESSAGES_FOUND", this.props.lang); } messageList.forEach((message) => { @@ -188,12 +191,12 @@ class MessageList extends React.PureComponent { }).catch((error) => { //TODO Handle the erros in contact list. console.error("[MessageList] getMessages fetchPrevious error", error); - this.decoratorMessage = "Error"; + this.decoratorMessage = Translator.translate("ERROR", this.props.lang); }); }).catch((error) => { console.log("[MessageList] getMessages getLoggedInUser error", error); - this.decoratorMessage = "Error"; + this.decoratorMessage = Translator.translate("ERROR", this.props.lang); }); } @@ -269,7 +272,7 @@ class MessageList extends React.PureComponent { const newMessageObj = Object.assign({}, messageObj, message); messageList.splice(messageKey, 1, newMessageObj); - this.props.actionGenerated("messageUpdated", messageList); + this.props.actionGenerated("onMessageEdited", messageList); } } @@ -426,8 +429,6 @@ class MessageList extends React.PureComponent { && message.getReceiverType() === 'user' && message.getSender().uid === this.props.item.uid) { - console.log("inside 1st else if"); - triggerCustomMessageReceived(message); } else if (this.props.type === 'user' @@ -435,12 +436,8 @@ class MessageList extends React.PureComponent { && this.loggedInUser.uid === message.getSender().uid && message.getReceiverId() === this.props.item.uid && (message.type === enums.CUSTOM_TYPE_DOCUMENT || message.type === enums.CUSTOM_TYPE_WHITEBOARD)) { - console.log("inside 2nd else if"); - triggerCustomMessageReceived(message); - } - } addMetadataToCustomData = (message) => { @@ -535,25 +532,25 @@ class MessageList extends React.PureComponent { if(message.hasOwnProperty("deletedAt")) { - component = (); + component = (); } else { switch (message.type) { case CometChat.MESSAGE_TYPE.TEXT: - component = (message.text ? : null); + component = (message.text ? : null); break; case CometChat.MESSAGE_TYPE.IMAGE: - component = (message.data.url ? : null); + component = (message.data.url ? : null); break; case CometChat.MESSAGE_TYPE.FILE: - component = (message.data.attachments ? : null); + component = (message.data.attachments ? : null); break; case CometChat.MESSAGE_TYPE.VIDEO: - component = (message.data.url ? : null); + component = (message.data.url ? : null); break; case CometChat.MESSAGE_TYPE.AUDIO: - component = (message.data.url ? : null); + component = (message.data.url ? : null); break; default: break; @@ -570,26 +567,26 @@ class MessageList extends React.PureComponent { if(message.hasOwnProperty("deletedAt")) { - component = (); + component = (); } else { switch (message.type) { case "message": case CometChat.MESSAGE_TYPE.TEXT: - component = (message.text ? : null); + component = (message.text ? : null); break; case CometChat.MESSAGE_TYPE.IMAGE: - component = (message.data.url ? : null); + component = (message.data.url ? : null); break; case CometChat.MESSAGE_TYPE.FILE: - component = (message.data.attachments ? : null); + component = (message.data.attachments ? : null); break; case CometChat.MESSAGE_TYPE.AUDIO: - component = (message.data.url ? : null); + component = (message.data.url ? : null); break; case CometChat.MESSAGE_TYPE.VIDEO: - component = (message.data.url ? : null); + component = (message.data.url ? : null); break; default: break; @@ -602,21 +599,21 @@ class MessageList extends React.PureComponent { let component; if (message.hasOwnProperty("deletedAt")) { - component = (); + component = (); } else { switch (message.type) { case enums.CUSTOM_TYPE_POLL: - component = ; + component = ; break; case enums.CUSTOM_TYPE_STICKER: - component = ; + component = ; break; case enums.CUSTOM_TYPE_DOCUMENT: - component = ; + component = ; break; case enums.CUSTOM_TYPE_WHITEBOARD: - component = ; + component = ; break; default: break; @@ -630,21 +627,21 @@ class MessageList extends React.PureComponent { let component; if (message.hasOwnProperty("deletedAt")) { - component = (); + component = (); } else { switch (message.type) { case enums.CUSTOM_TYPE_POLL: - component = ; + component = ; break; case enums.CUSTOM_TYPE_STICKER: - component = ; + component = ; break; case enums.CUSTOM_TYPE_DOCUMENT: - component = ; + component = ; break; case enums.CUSTOM_TYPE_WHITEBOARD: - component = ; + component = ; break; default: break; @@ -656,14 +653,13 @@ class MessageList extends React.PureComponent { getCallMessageComponent = (message, key) => { return ( - + ); } getActionMessageComponent = (message, key) => { let component = null; - //console.log("getActionMessageComponent message", message); if(message.message) { component = ( @@ -738,7 +734,9 @@ class MessageList extends React.PureComponent { const messageDate = (message.sentAt * 1000); const messageSentDate = dateFormat(messageDate, "dd/mm/yyyy"); if (cDate !== messageSentDate) { - dateSeparator = (
{messageSentDate}
); + dateSeparator = (
+ {messageSentDate} +
); } cDate = messageSentDate; @@ -766,4 +764,15 @@ class MessageList extends React.PureComponent { } } +// Specifies the default values for props: +MessageList.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +MessageList.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default MessageList; diff --git a/CometChat/components/MessageThread/controller.js b/CometChat/components/MessageThread/controller.js deleted file mode 100644 index 6ce899c5..00000000 --- a/CometChat/components/MessageThread/controller.js +++ /dev/null @@ -1,24 +0,0 @@ -import { CometChat } from "@cometchat-pro/chat"; - -import * as enums from '../../util/enums.js'; - -export class MessageThreadManager { - - msgListenerId = "threadmessage_" + new Date().getTime(); - - attachListeners(callback) { - - CometChat.addMessageListener( - this.msgListenerId, - new CometChat.MessageListener({ - onMessageEdited: editedMessage => { - callback(enums.MESSAGE_EDITED, editedMessage); - } - }) - ); - } - - removeListeners() { - CometChat.removeMessageListener(this.msgListenerId); - } -} \ No newline at end of file diff --git a/CometChat/components/MessageThread/index.js b/CometChat/components/MessageThread/index.js index 5fbcfdef..9e682318 100644 --- a/CometChat/components/MessageThread/index.js +++ b/CometChat/components/MessageThread/index.js @@ -2,12 +2,12 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; import { checkMessageForExtensionsData } from "../../util/common"; import * as enums from "../../util/enums.js"; -import { MessageThreadManager } from "./controller"; import MessageList from "../MessageList"; import MessageComposer from "../MessageComposer"; @@ -45,6 +45,9 @@ import { messageReplyStyle, } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import clearIcon from "./resources/close.png"; class MessageThread extends React.PureComponent { @@ -53,9 +56,6 @@ class MessageThread extends React.PureComponent { super(props); - this.MessageThreadManager = new MessageThreadManager(); - this.MessageThreadManager.attachListeners(this.listenerCallback); - this.composerRef = React.createRef(); this.loggedInUser = props.loggedInUser; @@ -82,18 +82,6 @@ class MessageThread extends React.PureComponent { } } - listenerCallback = (key, message) => { - - switch (key) { - - case enums.MESSAGE_EDITED: - this.parentMessageEdited(message); - break; - default: - break; - } - } - parentMessageEdited = (message) => { const parentMessage = { ...this.props.parentMessage }; @@ -138,7 +126,7 @@ class MessageThread extends React.PureComponent { this.props.actionGenerated("threadMessageComposed", messages); } break; - case "messageUpdated": + case "onMessageEdited": this.updateMessages(messages); break; case "messageFetched": @@ -270,19 +258,19 @@ class MessageThread extends React.PureComponent { switch (message.type) { case CometChat.MESSAGE_TYPE.TEXT: - component = ; + component = ; break; case CometChat.MESSAGE_TYPE.IMAGE: - component = ; + component = ; break; case CometChat.MESSAGE_TYPE.FILE: - component = ; + component = ; break; case CometChat.MESSAGE_TYPE.VIDEO: - component = ; + component = ; break; case CometChat.MESSAGE_TYPE.AUDIO: - component = ; + component = ; break; default: break; @@ -298,19 +286,19 @@ class MessageThread extends React.PureComponent { switch (message.type) { case "message": case CometChat.MESSAGE_TYPE.TEXT: - component = ; + component = ; break; case CometChat.MESSAGE_TYPE.IMAGE: - component = ; + component = ; break; case CometChat.MESSAGE_TYPE.FILE: - component = ; + component = ; break; case CometChat.MESSAGE_TYPE.AUDIO: - component = ; + component = ; break; case CometChat.MESSAGE_TYPE.VIDEO: - component = ; + component = ; break; default: break; @@ -325,16 +313,16 @@ class MessageThread extends React.PureComponent { switch (message.type) { case enums.CUSTOM_TYPE_POLL: - component = ; + component = ; break; case enums.CUSTOM_TYPE_STICKER: - component = ; + component = ; break; case enums.CUSTOM_TYPE_DOCUMENT: - component = ; + component = ; break; case enums.CUSTOM_TYPE_WHITEBOARD: - component = ; + component = ; break; default: break; @@ -348,16 +336,16 @@ class MessageThread extends React.PureComponent { let component; switch (message.type) { case enums.CUSTOM_TYPE_POLL: - component = ; + component = ; break; case enums.CUSTOM_TYPE_STICKER: - component = ; + component = ; break; case enums.CUSTOM_TYPE_DOCUMENT: - component = ; + component = ; break; case enums.CUSTOM_TYPE_WHITEBOARD: - component = ; + component = ; break; default: break; @@ -411,7 +399,7 @@ class MessageThread extends React.PureComponent { if (this.state.parentMessage.hasOwnProperty("replyCount")) { const replyCount = this.state.parentMessage.replyCount; - const replyText = (replyCount === 1) ? `${replyCount} reply` : `${replyCount} replies`; + const replyText = (replyCount === 1) ? (`${replyCount} ${Translator.translate("REPLY", this.props.lang)}`) : (`${replyCount} ${Translator.translate("REPLIES", this.props.lang)}`); seperator = (
@@ -426,7 +414,7 @@ class MessageThread extends React.PureComponent {
-
Thread
+
{Translator.translate("THREAD", this.props.lang)}
{this.props.item.name}
this.props.actionGenerated("closeThreadClicked")}>
@@ -445,12 +433,14 @@ class MessageThread extends React.PureComponent { widgetsettings={this.props.widgetsettings} parentMessageId={this.props.parentMessage.id} loggedInUser={this.props.loggedInUser} + lang={this.props.lang} actionGenerated={this.actionHandler} /> { this.composerRef = el; }} theme={this.props.theme} item={this.props.item} type={this.props.type} + lang={this.props.lang} widgetsettings={this.props.widgetsettings} parentMessageId={this.props.parentMessage.id} messageToBeEdited={this.state.messageToBeEdited} @@ -463,4 +453,15 @@ class MessageThread extends React.PureComponent { } } +// Specifies the default values for props: +MessageThread.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +MessageThread.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default MessageThread; \ No newline at end of file diff --git a/CometChat/components/ReadReciept/index.js b/CometChat/components/ReadReciept/index.js index 248b97d4..56c2fefc 100644 --- a/CometChat/components/ReadReciept/index.js +++ b/CometChat/components/ReadReciept/index.js @@ -2,11 +2,15 @@ import React from "react"; import dateFormat from "dateformat"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { validateWidgetSettings } from "../../util/common"; import { msgTimestampStyle } from "./style"; +import Translator from "../../resources/localization/translator"; +import { theme } from "../../resources/theme"; + import blueDoubleTick from "./resources/blue-double-tick-icon.png"; import greyDoubleTick from "./resources/grey-double-tick-icon.png"; import greyTick from "./resources/grey-tick-icon.png"; @@ -33,14 +37,17 @@ class ReadReceipt extends React.PureComponent { render() { - let ticks = null; + let ticks, receiptText = null; if(this.state.message.messageFrom === "sender") { ticks = blueDoubleTick; + receiptText = "SEEN"; if (this.props.message.sentAt && !this.props.message.readAt && !this.props.message.deliveredAt) { ticks = greyTick; + receiptText = "SENT"; } else if (this.props.message.sentAt && !this.props.message.readAt && this.props.message.deliveredAt) { ticks = greyDoubleTick; + receiptText = "DELIVERED"; } } @@ -49,7 +56,7 @@ class ReadReceipt extends React.PureComponent { ticks = null; } - const receipt = (ticks) ? time : null; + const receipt = (ticks) ? {Translator.translate(receiptText, : null; const messageDate = (this.state.message.sentAt * 1000); const timestamp = dateFormat(messageDate, "shortTime"); @@ -60,4 +67,15 @@ class ReadReceipt extends React.PureComponent { } } +// Specifies the default values for props: +ReadReceipt.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme, +}; + +ReadReceipt.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default ReadReceipt; \ No newline at end of file diff --git a/CometChat/components/ReceiverAudioBubble/index.js b/CometChat/components/ReceiverAudioBubble/index.js index e361fa2b..84b9580c 100644 --- a/CometChat/components/ReceiverAudioBubble/index.js +++ b/CometChat/components/ReceiverAudioBubble/index.js @@ -1,7 +1,8 @@ import React from "react"; /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; import { SvgAvatar } from '../../util/svgavatar'; @@ -12,6 +13,8 @@ import ReplyCount from "../ReplyCount"; import ReadReciept from "../ReadReciept"; import RegularReactionView from "../RegularReactionView"; +import { theme } from "../../resources/theme"; + import { messageContainerStyle, messageWrapperStyle, @@ -70,15 +73,13 @@ class ReceiverAudioBubble extends React.Component { avatar = (
- +
); - name = (
{this.state.message.sender.name}
); + name = (
+ {this.state.message.sender.name} +
); } let messageReactions = null; @@ -88,13 +89,7 @@ class ReceiverAudioBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -103,7 +98,6 @@ class ReceiverAudioBubble extends React.Component { return (
-
{avatar}
@@ -128,7 +122,15 @@ class ReceiverAudioBubble extends React.Component {
) } +} + +// Specifies the default values for props: +ReceiverAudioBubble.defaultProps = { + theme: theme +}; +ReceiverAudioBubble.propTypes = { + theme: PropTypes.object } export default ReceiverAudioBubble; \ No newline at end of file diff --git a/CometChat/components/ReceiverDocumentBubble/index.js b/CometChat/components/ReceiverDocumentBubble/index.js index ade3284d..cbe9f02a 100644 --- a/CometChat/components/ReceiverDocumentBubble/index.js +++ b/CometChat/components/ReceiverDocumentBubble/index.js @@ -2,6 +2,8 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; + import { checkMessageForExtensionsData } from "../../util/common"; import ToolTip from "../ToolTip"; @@ -27,6 +29,9 @@ import { messageReactionsWrapperStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import documentIcon from "./resources/receiverdocument.png"; class ReceiverDocumentBubble extends React.PureComponent { @@ -86,15 +91,13 @@ class ReceiverDocumentBubble extends React.PureComponent { avatar = (
- +
); - name = (
{this.props.message.sender.name}
); + name = (
+ {this.props.message.sender.name} +
); } let messageReactions = null; @@ -104,19 +107,13 @@ class ReceiverDocumentBubble extends React.PureComponent { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } } - const documentTitle = this.state.message.sender.name + " has shared a collaborative document"; + const documentTitle = `${this.state.message.sender.name} ${Translator.translate("SHARED_COLLABORATIVE_DOCUMENT", this.props.lang)}`; return (
@@ -129,13 +126,13 @@ class ReceiverDocumentBubble extends React.PureComponent {
- Collaborative Document + {Translator.translate("COLLABORATIVE_DOCUMENT",

{documentTitle}

  • -

    Launch

    +

    {Translator.translate("JOIN", this.props.lang)}

@@ -154,4 +151,15 @@ class ReceiverDocumentBubble extends React.PureComponent { } } +// Specifies the default values for props: +ReceiverDocumentBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +ReceiverDocumentBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default ReceiverDocumentBubble; \ No newline at end of file diff --git a/CometChat/components/ReceiverFileBubble/index.js b/CometChat/components/ReceiverFileBubble/index.js index 4c04672c..dd84ee2e 100644 --- a/CometChat/components/ReceiverFileBubble/index.js +++ b/CometChat/components/ReceiverFileBubble/index.js @@ -2,7 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; - +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; import { SvgAvatar } from '../../util/svgavatar'; @@ -26,6 +26,9 @@ import { messageReactionsWrapperStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import blueFile from "./resources/receiverfile.png"; class ReceiverFileBubble extends React.Component { @@ -71,15 +74,13 @@ class ReceiverFileBubble extends React.Component { avatar = (
- +
); - name = (
{this.state.message.sender.name}
); + name = (
+ {this.state.message.sender.name} +
); } let messageReactions = null; @@ -89,13 +90,7 @@ class ReceiverFileBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -112,7 +107,7 @@ class ReceiverFileBubble extends React.Component {
@@ -131,4 +126,15 @@ class ReceiverFileBubble extends React.Component { } } +// Specifies the default values for props: +ReceiverFileBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +ReceiverFileBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default ReceiverFileBubble; \ No newline at end of file diff --git a/CometChat/components/ReceiverImageBubble/index.js b/CometChat/components/ReceiverImageBubble/index.js index 39ac14dd..b8cc58db 100644 --- a/CometChat/components/ReceiverImageBubble/index.js +++ b/CometChat/components/ReceiverImageBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from "@emotion/core"; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; import { SvgAvatar } from '../../util/svgavatar'; @@ -27,6 +28,9 @@ import { import srcIcon from "./resources/1px.png"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + class ReceiverImageBubble extends React.PureComponent { messageFrom = "receiver"; @@ -177,15 +181,13 @@ class ReceiverImageBubble extends React.PureComponent { avatar = (
- +
); - name = (
{this.state.message.sender.name}
); + name = (
+ {this.state.message.sender.name} +
); } let messageReactions = null; @@ -195,13 +197,7 @@ class ReceiverImageBubble extends React.PureComponent { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -217,7 +213,7 @@ class ReceiverImageBubble extends React.PureComponent {
- message { this.imgRef = el; }} /> + {this.state.imageUrl} { this.imgRef = el; }} />
@@ -234,4 +230,15 @@ class ReceiverImageBubble extends React.PureComponent { } } +// Specifies the default values for props: +ReceiverImageBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +ReceiverImageBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default ReceiverImageBubble; \ No newline at end of file diff --git a/CometChat/components/ReceiverMessageBubble/index.js b/CometChat/components/ReceiverMessageBubble/index.js index 51b42c4f..c49aed21 100644 --- a/CometChat/components/ReceiverMessageBubble/index.js +++ b/CometChat/components/ReceiverMessageBubble/index.js @@ -1,6 +1,7 @@ import React from "react"; import twemoji from "twemoji"; import ReactHtmlParser from "react-html-parser"; +import PropTypes from 'prop-types'; /** @jsx jsx */ import { jsx } from '@emotion/core'; @@ -29,6 +30,9 @@ import { messageReactionsWrapperStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + class ReceiverMessageBubble extends React.Component { messageFrom = "receiver"; @@ -127,15 +131,13 @@ class ReceiverMessageBubble extends React.Component { avatar = (
- +
); - name = (
{this.state.message.sender.name}
); + name = (
+ {this.state.message.sender.name} +
); } let messageText = this.getMessageText(); @@ -156,13 +158,7 @@ class ReceiverMessageBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -191,4 +187,15 @@ class ReceiverMessageBubble extends React.Component { } } +// Specifies the default values for props: +ReceiverMessageBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +ReceiverMessageBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default ReceiverMessageBubble; \ No newline at end of file diff --git a/CometChat/components/ReceiverPollBubble/index.js b/CometChat/components/ReceiverPollBubble/index.js index 93b97af4..1abe834c 100644 --- a/CometChat/components/ReceiverPollBubble/index.js +++ b/CometChat/components/ReceiverPollBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -32,6 +33,9 @@ import { messageReactionsWrapperStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import checkIcon from "./resources/check.svg"; class ReceiverPollBubble extends React.Component { @@ -109,15 +113,13 @@ class ReceiverPollBubble extends React.Component { avatar = (
- +
); - name = (
{this.props.message.sender.name}
); + name = (
+ {this.props.message.sender.name} +
); } const pollOptions = []; @@ -125,8 +127,17 @@ class ReceiverPollBubble extends React.Component { this.pollId = pollExtensionData.id; const total = pollExtensionData.results.total; - const totalText = (total === 1) ? `${total} vote` : `${total} votes`; + let totalText = Translator.translate("NO_VOTE", this.props.lang); + if(total === 1) { + + totalText = `${total} ${Translator.translate("VOTE", this.props.lang)}`; + + } else if (total > 1) { + + totalText = `${total} ${Translator.translate("VOTES", this.props.lang)}`; + } + for (const option in pollExtensionData.options) { const optionData = pollExtensionData.results.options[option]; @@ -158,13 +169,7 @@ class ReceiverPollBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -201,4 +206,15 @@ class ReceiverPollBubble extends React.Component { } } +// Specifies the default values for props: +ReceiverPollBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +ReceiverPollBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default ReceiverPollBubble; \ No newline at end of file diff --git a/CometChat/components/ReceiverStickerBubble/index.js b/CometChat/components/ReceiverStickerBubble/index.js index 9e4c9b11..8c1e7b13 100644 --- a/CometChat/components/ReceiverStickerBubble/index.js +++ b/CometChat/components/ReceiverStickerBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core' +import PropTypes from 'prop-types'; import { SvgAvatar } from '../../util/svgavatar'; @@ -26,6 +27,9 @@ import { messageReactionsWrapperStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + class ReceiverStickerBubble extends React.Component { messageFrom = "receiver"; @@ -67,15 +71,13 @@ class ReceiverStickerBubble extends React.Component { avatar = (
- +
); - name = (
{this.state.message.sender.name}
); + name = (
+ {this.state.message.sender.name} +
); } let stickerData = null; @@ -85,7 +87,7 @@ class ReceiverStickerBubble extends React.Component { stickerData = this.state.message.data.customData; if (stickerData.hasOwnProperty("sticker_url")) { - const stickerName = (stickerData.hasOwnProperty("sticker_name")) ? stickerData.sticker_name : "Sticker"; + const stickerName = (stickerData.hasOwnProperty("sticker_name")) ? stickerData.sticker_name : Translator.translate("STICKER", this.props.lang); stickerImg = ({stickerName}); } } @@ -97,13 +99,7 @@ class ReceiverStickerBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -134,4 +130,15 @@ class ReceiverStickerBubble extends React.Component { } } +// Specifies the default values for props: +ReceiverStickerBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +ReceiverStickerBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default ReceiverStickerBubble; \ No newline at end of file diff --git a/CometChat/components/ReceiverVideoBubble/index.js b/CometChat/components/ReceiverVideoBubble/index.js index d9fb8e9a..9fd01f9b 100644 --- a/CometChat/components/ReceiverVideoBubble/index.js +++ b/CometChat/components/ReceiverVideoBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from "@emotion/core"; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; import { SvgAvatar } from '../../util/svgavatar'; @@ -25,6 +26,8 @@ import { messageReactionsWrapperStyle } from "./style"; +import { theme } from "../../resources/theme"; + class ReceiverVideoBubble extends React.Component { messageFrom = "receiver"; @@ -76,15 +79,13 @@ class ReceiverVideoBubble extends React.Component { avatar = (
- +
); - name = (
{this.props.message.sender.name}
); + name = (
+ {this.props.message.sender.name} +
); } let messageReactions = null; @@ -94,13 +95,7 @@ class ReceiverVideoBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -135,4 +130,13 @@ class ReceiverVideoBubble extends React.Component { } } +// Specifies the default values for props: +ReceiverVideoBubble.defaultProps = { + theme: theme +}; + +ReceiverVideoBubble.propTypes = { + theme: PropTypes.object +} + export default ReceiverVideoBubble; \ No newline at end of file diff --git a/CometChat/components/ReceiverWhiteboardBubble/index.js b/CometChat/components/ReceiverWhiteboardBubble/index.js index 5f25b0fc..e356b845 100644 --- a/CometChat/components/ReceiverWhiteboardBubble/index.js +++ b/CometChat/components/ReceiverWhiteboardBubble/index.js @@ -2,6 +2,8 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; + import { checkMessageForExtensionsData } from "../../util/common"; import ToolTip from "../ToolTip"; @@ -27,6 +29,9 @@ import { messageReactionsWrapperStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import whiteboardIcon from "./resources/receiverwhiteboard.png"; class ReceiverWhiteboardBubble extends React.PureComponent { @@ -88,15 +93,13 @@ class ReceiverWhiteboardBubble extends React.PureComponent { avatar = (
- +
); - name = (
{this.props.message.sender.name}
); + name = (
+ {this.props.message.sender.name} +
); } let messageReactions = null; @@ -106,19 +109,13 @@ class ReceiverWhiteboardBubble extends React.PureComponent { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } } - const documentTitle = this.state.message.sender.name + " has shared a collaborative whiteboard"; + const documentTitle = `${this.state.message.sender.name} ${Translator.translate("SHARED_COLLABORATIVE_WHITEBOARD", this.props.lang)}`; return (
@@ -131,13 +128,13 @@ class ReceiverWhiteboardBubble extends React.PureComponent {
- Collaborative Document + {Translator.translate("COLLABORATIVE_WHITEBOARD",

{documentTitle}

  • -

    Launch

    +

    {Translator.translate("JOIN", this.props.lang)}

@@ -156,4 +153,15 @@ class ReceiverWhiteboardBubble extends React.PureComponent { } } +// Specifies the default values for props: +ReceiverWhiteboardBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +ReceiverWhiteboardBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default ReceiverWhiteboardBubble; \ No newline at end of file diff --git a/CometChat/components/RegularReactionView/index.js b/CometChat/components/RegularReactionView/index.js index 594db1ac..fdae1a66 100644 --- a/CometChat/components/RegularReactionView/index.js +++ b/CometChat/components/RegularReactionView/index.js @@ -2,6 +2,8 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; + import { Emoji } from "emoji-mart"; import { CometChat } from "@cometchat-pro/chat"; @@ -13,6 +15,9 @@ import { emojiButtonStyle, } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import reactIcon from "./resources/add-reaction.png"; class RegularReactionView extends React.Component { @@ -75,8 +80,10 @@ class RegularReactionView extends React.Component { } if (userList.length) { + reactionTitle = userList.join(", "); - reactionTitle = reactionTitle.concat(" reacted"); + const str = ` ${Translator.translate("REACTED", this.props.lang)}`; + reactionTitle = reactionTitle.concat(str); } const reactionClassName = `reaction reaction__${reactionName}`; @@ -112,7 +119,7 @@ class RegularReactionView extends React.Component { key="-1" css={messageReactionsStyle(this.props, {})} className="reaction reaction__add" - title="Add reaction..."> + title={Translator.translate("ADD_REACTION", this.props.lang)}> - //
- // ); - if (messageReactions !== null && messageReactions.length && addReactionEmoji !== null) { if (this.props.message.messageFrom === "receiver") { @@ -193,4 +151,15 @@ class RegularReactionView extends React.Component { } } +// Specifies the default values for props: +RegularReactionView.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +RegularReactionView.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default RegularReactionView; \ No newline at end of file diff --git a/CometChat/components/ReplyCount/index.js b/CometChat/components/ReplyCount/index.js index 205c9610..c6f7c966 100644 --- a/CometChat/components/ReplyCount/index.js +++ b/CometChat/components/ReplyCount/index.js @@ -1,16 +1,24 @@ /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { validateWidgetSettings } from "../../util/common"; import { replyCountStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + const replycount = (props) => { const replyCount = props.message.replyCount; - const replyText = (replyCount === 1) ? `${replyCount} reply` : `${replyCount} replies`; + const replyText = (replyCount === 1) ? (`${replyCount} ${Translator.translate("REPLY", props.lang)}`) : (`${replyCount} ${Translator.translate("REPLIES", props.lang)}`); - let replies = ( props.actionGenerated("viewMessageThread", props.message)}>{replyText}); + let replies = ( + props.actionGenerated("viewMessageThread", props.message)}>{replyText}); if(props.message.hasOwnProperty("replyCount") === false) { replies = null; @@ -30,4 +38,15 @@ const replycount = (props) => { return replies; } +// Specifies the default values for props: +replycount.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +replycount.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default replycount; \ No newline at end of file diff --git a/CometChat/components/ReplyPreview/index.js b/CometChat/components/ReplyPreview/index.js index c55ec8f5..7c4ec879 100644 --- a/CometChat/components/ReplyPreview/index.js +++ b/CometChat/components/ReplyPreview/index.js @@ -1,5 +1,6 @@ /** @jsx jsx */ import { jsx, keyframes } from '@emotion/core'; +import PropTypes from 'prop-types'; import { previewWrapperStyle, @@ -9,6 +10,8 @@ import { previewOptionStyle, } from "./style"; +import { theme } from "../../resources/theme"; + import closeIcon from "./resources/close.png"; const ReplyPreview = (props) => { @@ -28,4 +31,13 @@ const ReplyPreview = (props) => { ) } +// Specifies the default values for props: +ReplyPreview.defaultProps = { + theme: theme +}; + +ReplyPreview.propTypes = { + theme: PropTypes.object +} + export default ReplyPreview; diff --git a/CometChat/components/SenderAudioBubble/index.js b/CometChat/components/SenderAudioBubble/index.js index 43d3002f..8bdb3e05 100644 --- a/CometChat/components/SenderAudioBubble/index.js +++ b/CometChat/components/SenderAudioBubble/index.js @@ -51,13 +51,7 @@ class SenderAudioBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } diff --git a/CometChat/components/SenderDocumentBubble/index.js b/CometChat/components/SenderDocumentBubble/index.js index 07014502..15855fb7 100644 --- a/CometChat/components/SenderDocumentBubble/index.js +++ b/CometChat/components/SenderDocumentBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; @@ -21,6 +22,9 @@ import { messageReactionsWrapperStyle, } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import documentIcon from "./resources/senderdocument.png"; class SenderDocumentBubble extends React.PureComponent { @@ -71,19 +75,13 @@ class SenderDocumentBubble extends React.PureComponent { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } } - const documentTitle = "You’ve created a new collaborative document"; + const documentTitle = Translator.translate("CREATED_DOCUMENT", this.props.lang); return (
@@ -92,12 +90,12 @@ class SenderDocumentBubble extends React.PureComponent {
- Collaborative Document + {Translator.translate("COLLABORATIVE_DOCUMENT",

{documentTitle}

  • -

    Launch

    +

    {Translator.translate("LAUNCH", this.props.lang)}

@@ -115,4 +113,15 @@ class SenderDocumentBubble extends React.PureComponent { } } +// Specifies the default values for props: +SenderDocumentBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +SenderDocumentBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default SenderDocumentBubble; \ No newline at end of file diff --git a/CometChat/components/SenderFileBubble/index.js b/CometChat/components/SenderFileBubble/index.js index 8a9399be..a77a50dd 100644 --- a/CometChat/components/SenderFileBubble/index.js +++ b/CometChat/components/SenderFileBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; @@ -18,6 +19,7 @@ import { messageReactionsWrapperStyle } from "./style"; +import { theme } from "../../resources/theme"; import blueFile from "./resources/senderfile.png"; class SenderFileBubble extends React.Component { @@ -56,13 +58,7 @@ class SenderFileBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -93,4 +89,14 @@ class SenderFileBubble extends React.Component { } } +// Specifies the default values for props: +SenderFileBubble.defaultProps = { + theme: theme +}; + +SenderFileBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default SenderFileBubble; \ No newline at end of file diff --git a/CometChat/components/SenderImageBubble/index.js b/CometChat/components/SenderImageBubble/index.js index 88e58336..ffe4ef31 100644 --- a/CometChat/components/SenderImageBubble/index.js +++ b/CometChat/components/SenderImageBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; @@ -18,6 +19,8 @@ import { messageReactionsWrapperStyle } from "./style"; +import { theme } from "../../resources/theme"; + import srcIcon from "./resources/1px.png"; class SenderImageBubble extends React.PureComponent { @@ -164,13 +167,7 @@ class SenderImageBubble extends React.PureComponent { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -183,7 +180,7 @@ class SenderImageBubble extends React.PureComponent {
- message { this.imgRef = el; }} /> + {this.state.imageUrl} { this.imgRef = el; }} />
@@ -198,4 +195,13 @@ class SenderImageBubble extends React.PureComponent { } } +// Specifies the default values for props: +SenderImageBubble.defaultProps = { + theme: theme +}; + +SenderImageBubble.propTypes = { + theme: PropTypes.object +} + export default SenderImageBubble; \ No newline at end of file diff --git a/CometChat/components/SenderMessageBubble/index.js b/CometChat/components/SenderMessageBubble/index.js index a086937c..08b8850e 100644 --- a/CometChat/components/SenderMessageBubble/index.js +++ b/CometChat/components/SenderMessageBubble/index.js @@ -4,6 +4,7 @@ import ReactHtmlParser from "react-html-parser"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { linkify, checkMessageForExtensionsData, validateWidgetSettings } from "../../util/common"; @@ -22,6 +23,8 @@ import { messageReactionsWrapperStyle, } from "./style"; +import { theme } from "../../resources/theme"; + class SenderMessageBubble extends React.PureComponent { messageFrom = "sender"; @@ -124,13 +127,7 @@ class SenderMessageBubble extends React.PureComponent { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -153,4 +150,13 @@ class SenderMessageBubble extends React.PureComponent { } } +// Specifies the default values for props: +SenderMessageBubble.defaultProps = { + theme: theme +}; + +SenderMessageBubble.propTypes = { + theme: PropTypes.object +} + export default SenderMessageBubble; \ No newline at end of file diff --git a/CometChat/components/SenderPollBubble/index.js b/CometChat/components/SenderPollBubble/index.js index 97ee79a9..033ac260 100644 --- a/CometChat/components/SenderPollBubble/index.js +++ b/CometChat/components/SenderPollBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; @@ -23,6 +24,9 @@ import { messageReactionsWrapperStyle, } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + class SenderPollBubble extends React.Component { pollId; requestInProgress = null; @@ -73,7 +77,16 @@ class SenderPollBubble extends React.Component { this.pollId = pollExtensionData.id; const total = pollExtensionData.results.total; - const totalText = (total === 1) ? `${total} vote` : `${total} votes`; + let totalText = Translator.translate("NO_VOTE", this.props.lang); + + if (total === 1) { + + totalText = `${total} ${Translator.translate("VOTE", this.props.lang)}`; + + } else if (total > 1) { + + totalText = `${total} ${Translator.translate("VOTES", this.props.lang)}`; + } for (const option in pollExtensionData.results.options) { @@ -106,13 +119,7 @@ class SenderPollBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -144,4 +151,15 @@ class SenderPollBubble extends React.Component { } } +// Specifies the default values for props: +SenderPollBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +SenderPollBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default SenderPollBubble; \ No newline at end of file diff --git a/CometChat/components/SenderStickerBubble/index.js b/CometChat/components/SenderStickerBubble/index.js index 0a86194d..7bfd642d 100644 --- a/CometChat/components/SenderStickerBubble/index.js +++ b/CometChat/components/SenderStickerBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; @@ -18,6 +19,9 @@ import { messageReactionsWrapperStyle, } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + class SenderStickerBubble extends React.Component { messageFrom = "sender"; @@ -53,7 +57,7 @@ class SenderStickerBubble extends React.Component { stickerData = this.state.message.data.customData; if (stickerData.hasOwnProperty("sticker_url")) { - const stickerName = (stickerData.hasOwnProperty("sticker_name")) ? stickerData.sticker_name : "Sticker"; + const stickerName = (stickerData.hasOwnProperty("sticker_name")) ? stickerData.sticker_name : Translator.translate("STICKER", this.props.lang); stickerImg = ({stickerName}); } } @@ -65,13 +69,7 @@ class SenderStickerBubble extends React.Component { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } @@ -99,4 +97,15 @@ class SenderStickerBubble extends React.Component { } } +// Specifies the default values for props: +SenderStickerBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +SenderStickerBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default SenderStickerBubble; \ No newline at end of file diff --git a/CometChat/components/SenderVideoBubble/index.js b/CometChat/components/SenderVideoBubble/index.js index ef5b6d5a..feee2074 100644 --- a/CometChat/components/SenderVideoBubble/index.js +++ b/CometChat/components/SenderVideoBubble/index.js @@ -1,6 +1,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; @@ -54,13 +55,7 @@ class SenderVideoBubble extends React.PureComponent { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } diff --git a/CometChat/components/SenderWhiteboardBubble/index.js b/CometChat/components/SenderWhiteboardBubble/index.js index 7a371fba..b27db032 100644 --- a/CometChat/components/SenderWhiteboardBubble/index.js +++ b/CometChat/components/SenderWhiteboardBubble/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { checkMessageForExtensionsData } from "../../util/common"; @@ -21,6 +22,9 @@ import { messageReactionsWrapperStyle, } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import whiteboardIcon from "./resources/senderwhiteboard.png"; class SenderWhiteboardBubble extends React.PureComponent { @@ -73,19 +77,13 @@ class SenderWhiteboardBubble extends React.PureComponent { if (Object.keys(reactionsData).length) { messageReactions = (
- +
); } } - const documentTitle = "You’ve created a new collaborative whiteboard"; + const documentTitle = Translator.translate("CREATED_WHITEBOARD", this.props.lang); return (
@@ -94,12 +92,12 @@ class SenderWhiteboardBubble extends React.PureComponent {
- Collaborative Whiteboard + {Translator.translate("COLLABORATIVE_WHITEBOARD",

{documentTitle}

  • -

    Launch

    +

    {Translator.translate("LAUNCH", this.props.lang)}

@@ -117,4 +115,15 @@ class SenderWhiteboardBubble extends React.PureComponent { } } +// Specifies the default values for props: +SenderWhiteboardBubble.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +SenderWhiteboardBubble.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default SenderWhiteboardBubble; \ No newline at end of file diff --git a/CometChat/components/SharedMediaView/index.js b/CometChat/components/SharedMediaView/index.js index 4bef8fab..79ca6ff8 100644 --- a/CometChat/components/SharedMediaView/index.js +++ b/CometChat/components/SharedMediaView/index.js @@ -2,10 +2,10 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChatManager } from "../../util/controller"; import { SharedMediaManager } from "./controller"; - import * as enums from '../../util/enums.js'; import { @@ -19,6 +19,9 @@ import { } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import fileIcon from "./resources/file.png"; class SharedMediaView extends React.Component { @@ -142,23 +145,6 @@ class SharedMediaView extends React.Component { this.setState({messagetype: type, messageList: []}); } - lazyLoad = (target) => { - const obs = new IntersectionObserver((entries, observer) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - const img = entry.target.querySelector("img"); - const src = img.getAttribute('data-lazy'); - - img.setAttribute('src', src); - img.classList.add('fadeIn'); - - observer.disconnect(); - } - }); - }); - obs.observe(target); - } - render() { const template = (message, key) => { @@ -167,7 +153,7 @@ class SharedMediaView extends React.Component { return (
- Media Item + {Translator.translate("SHARED_MEDIA",
); @@ -198,16 +184,16 @@ class SharedMediaView extends React.Component { return (
-
Shared Media
+
{Translator.translate("SHARED_MEDIA", this.props.lang)}
- this.mediaClickHandler("image")}>Photos - this.mediaClickHandler("video")}>Videos - this.mediaClickHandler("file")}>Docs + this.mediaClickHandler("image")}>{Translator.translate("PHOTOS", this.props.lang)} + this.mediaClickHandler("video")}>{Translator.translate("VIDEOS", this.props.lang)} + this.mediaClickHandler("file")}>{Translator.translate("DOCS", this.props.lang)}
this.messageContainer = el} - onScroll={this.handleScroll}>{(messageList.length) ? messageList : "No records found."} + onScroll={this.handleScroll}>{(messageList.length) ? messageList : Translator.translate("NO_RECORDS_FOUND", this.props.lang)}
@@ -220,4 +206,15 @@ class SharedMediaView extends React.Component { } } +// Specifies the default values for props: +SharedMediaView.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +SharedMediaView.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default SharedMediaView; diff --git a/CometChat/components/StatusIndicator/index.js b/CometChat/components/StatusIndicator/index.js index f98af2c7..e0769b6e 100644 --- a/CometChat/components/StatusIndicator/index.js +++ b/CometChat/components/StatusIndicator/index.js @@ -1,29 +1,40 @@ /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; -import { - presenceStyle -} from "./style"; +import { validateWidgetSettings } from "../../util/common"; + +import { presenceStyle } from "./style"; const statusindicator = (props) => { - if(props.hasOwnProperty("widgetsettings") - && props.widgetsettings - && props.widgetsettings.hasOwnProperty("main") - && props.widgetsettings.main.hasOwnProperty("show_user_presence") - && props.widgetsettings.main["show_user_presence"] === false) { + //if user presence is disabled in chat widget + if (validateWidgetSettings(props.widgetsettings, "show_user_presence") === false) { return null; } - const borderWidth = props.borderWidth || '1px'; - const borderColor = props.borderColor || '#AAA'; - const cornerRadius = props.cornerRadius || '50%'; + const borderWidth = props.borderWidth; + const borderColor = props.borderColor; + const cornerRadius = props.cornerRadius; - const getStyle = () => ({borderWidth:borderWidth, borderStyle:'solid',borderColor:borderColor ,'borderRadius': cornerRadius}) + const getStyle = () => ({borderWidth:borderWidth, borderStyle:'solid', borderColor:borderColor , 'borderRadius': cornerRadius}) return ( ); } +// Specifies the default values for props: +statusindicator.defaultProps = { + borderWidth: "1px", + borderColor: "#AAA", + cornerRadius: "50%", +}; + +statusindicator.propTypes = { + borderWidth: PropTypes.string, + borderColor: PropTypes.string, + cornerRadius: PropTypes.string, +} + export default statusindicator; \ No newline at end of file diff --git a/CometChat/components/StickerView/index.js b/CometChat/components/StickerView/index.js index 245f6b6d..c7827ebc 100644 --- a/CometChat/components/StickerView/index.js +++ b/CometChat/components/StickerView/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx, keyframes } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -16,14 +17,18 @@ import { stickerCloseStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import closeIcon from "./resources/close.png"; class StickerView extends React.PureComponent { constructor(props) { + super(props); - this.decoratorMessage = "Loading..."; + this.decoratorMessage = Translator.translate("LOADING", props.lang); this.state = { stickerlist: [], @@ -57,7 +62,7 @@ class StickerView extends React.PureComponent { const stickerList = [...defaultStickers, ...customStickers]; if (stickerList.length === 0) { - this.decoratorMessage = "No stickers found"; + this.decoratorMessage = Translator.translate("NO_STICKERS_FOUND", this.props.lang); } const stickerSet = stickerList.reduce((r, sticker, index) => { @@ -95,7 +100,7 @@ class StickerView extends React.PureComponent { // Some error occured console.warn("Error: ", error); - this.decoratorMessage = "No stickers found"; + this.decoratorMessage = Translator.translate("NO_STICKERS_FOUND", this.props.lang); this.setState({ "activestickerlist": [], "stickerset": {} }); @@ -174,7 +179,17 @@ class StickerView extends React.PureComponent {
); } +} + +// Specifies the default values for props: +StickerView.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; +StickerView.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object } export default StickerView; \ No newline at end of file diff --git a/CometChat/components/ToolTip/index.js b/CometChat/components/ToolTip/index.js index 0e6f6d06..e4af5efc 100644 --- a/CometChat/components/ToolTip/index.js +++ b/CometChat/components/ToolTip/index.js @@ -2,6 +2,7 @@ import React from "react"; /** @jsx jsx */ import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import { CometChat } from "@cometchat-pro/chat"; @@ -13,6 +14,9 @@ import { groupButtonStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + import replyIcon from "./resources/startthread.png"; import deleteIcon from "./resources/deletemessage.png"; import editIcon from "./resources/edit.png"; @@ -20,14 +24,6 @@ import reactIcon from "./resources/add-reaction.png"; class Tooltip extends React.PureComponent { - constructor(props) { - super(props); - - this.state = { - - } - } - toggleTooltip = (event, flag) => { const elem = event.target; @@ -49,7 +45,7 @@ class Tooltip extends React.PureComponent { onMouseLeave={event => this.toggleTooltip(event, false)} css={groupButtonStyle(reactIcon)} className="group__button button__reacttomessage" - data-title="Add reaction" + data-title={Translator.translate("ADD_REACTION", this.props.lang)} onClick={() => this.props.actionGenerated("reactToMessage", this.props.message)}> ); @@ -67,7 +63,7 @@ class Tooltip extends React.PureComponent { onMouseLeave={event => this.toggleTooltip(event, false)} css={groupButtonStyle(replyIcon)} className="group__button button__threadedchats" - data-title={(this.props.message.replyCount) ? "Reply to thread" : "Reply in thread"} + data-title={(this.props.message.replyCount) ? Translator.translate("REPLY_TO_THREAD", this.props.lang) : Translator.translate("REPLY_IN_THREAD", this.props.lang) } onClick={() => this.props.actionGenerated("viewMessageThread", this.props.message)}> ); @@ -87,7 +83,7 @@ class Tooltip extends React.PureComponent { onMouseLeave={event => this.toggleTooltip(event, false)} css={groupButtonStyle(deleteIcon)} className="group__button button__delete" - data-title="Delete message" + data-title={Translator.translate("DELETE_MESSAGE", this.props.lang)} onClick={() => this.props.actionGenerated("deleteMessage", this.props.message)}> ); @@ -106,7 +102,7 @@ class Tooltip extends React.PureComponent { onMouseLeave={event => this.toggleTooltip(event, false)} css={groupButtonStyle(editIcon)} className="group__button button__edit" - data-title="Edit message" + data-title={Translator.translate("EDIT_MESSAGE", this.props.lang)} onClick={() => this.props.actionGenerated("editMessage", this.props.message)}> ); @@ -135,4 +131,15 @@ class Tooltip extends React.PureComponent { } } +// Specifies the default values for props: +Tooltip.defaultProps = { + lang: Translator.getDefaultLanguage(), + theme: theme +}; + +Tooltip.propTypes = { + lang: PropTypes.string, + theme: PropTypes.object +} + export default Tooltip; \ No newline at end of file diff --git a/CometChat/components/UserView/index.js b/CometChat/components/UserView/index.js index 7bf77952..7d718155 100644 --- a/CometChat/components/UserView/index.js +++ b/CometChat/components/UserView/index.js @@ -1,20 +1,22 @@ /** @jsx jsx */ -import { jsx } from '@emotion/core' +import { jsx } from '@emotion/core'; +import PropTypes from 'prop-types'; import Avatar from "../Avatar"; import StatusIndicator from "../StatusIndicator"; import { listItem, itemThumbnailStyle, itemDetailStyle, itemNameStyle, itemDescStyle } from "./style"; +import { theme } from "../../resources/theme"; +import Translator from "../../resources/localization/translator"; + const userview = (props) => { let userPresence = ( + borderColor={props.theme.borderColor.primary} /> ); const toggleTooltip = (event, flag) => { @@ -38,14 +40,10 @@ const userview = (props) => { return (
props.clickeHandler(props.user)} className="list__item">
- + {userPresence}
-
+
toggleTooltip(event, true)} onMouseLeave={event => toggleTooltip(event, false)}>{props.user.name}
@@ -55,4 +53,13 @@ const userview = (props) => { ) } +// Specifies the default values for props: +userview.defaultProps = { + theme: theme +}; + +userview.propTypes = { + theme: PropTypes.object +} + export default userview; diff --git a/CometChat/components/UserView/style.js b/CometChat/components/UserView/style.js index ae6f5c2b..cc5376d7 100644 --- a/CometChat/components/UserView/style.js +++ b/CometChat/components/UserView/style.js @@ -11,7 +11,7 @@ export const listItem = (props) => { alignItems: "center", cursor: "pointer", width: "100%", - padding: "10px 20px", + padding: "8px 16px", ...selectedState, '&:hover': { backgroundColor: `${props.theme.backgroundColor.primary}` @@ -34,7 +34,11 @@ export const itemDetailStyle = () => { return { width: "calc(100% - 45px)", flexGrow: 1, - paddingLeft: "15px" + paddingLeft: "16px", + "&[dir=rtl]": { + paddingRight: "16px", + paddingLeft: "0", + } } } diff --git a/CometChat/resources/localization/locales/ar/translation.json b/CometChat/resources/localization/locales/ar/translation.json new file mode 100644 index 00000000..e122fd82 --- /dev/null +++ b/CometChat/resources/localization/locales/ar/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "المستخدمون", + "CHATS": "دردشات", + "GROUPS": "المجموعات", + "MORE": "المزيد", + "MESSAGE_IMAGE": "📷 صورة", + "MESSAGE_FILE": "📁 ملف", + "MESSAGE_VIDEO": "📹 فيديو", + "MESSAGE_AUDIO": "🎵 الصوت", + "CUSTOM_MESSAGE": "لديك رسالة", + "MISSED_VOICE_CALL": "مكالمة صوتية غاب", + "MISSED_VIDEO_CALL": "مكالمة فيديو غاب", + "CUSTOM_MESSAGE_POLL": "📊 استطلاع للرأي", + "CUSTOM_MESSAGE_STICKER": "💟 ملصق", + "CUSTOM_MESSAGE_DOCUMENT": "📃 وثيقة", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 السبورة", + "ONLINE": "عبر الإنترنت", + "ADMINISTRATOR": "مدير", + "MODERATOR": "مدير الجلسة", + "PARTICIPANT": "مشارك", + "PUBLIC": "عامة", + "PRIVATE": "خاص", + "PASSWORD_PROTECTED": "محمية بكلمة مرور", + "PRIVACY_AND_SECURITY": "الخصوصية والأمان", + "PREFERENCES": "التفضيلات", + "MEMBERS": "الأعضاء", + "TODAY": "اليوم", + "YESTERDAY": "البارحة", + "TYPING": "كتابة...", + "IS_TYPING": "هو كتابة...", + "CLOSE": "إغلاق", + "ENTER_GROUP_NAME": "أدخل اسم المجموعة", + "ADD_MEMBERS": "إضافة أعضاء", + "SEND_MESSAGE": "ارسل رسالة", + "UNBLOCK_USER": "إلغاء حظر المستخدم", + "BLOCK_USER": "كتلة المستخدم", + "DELETE_AND_EXIT": "حذف وخروج", + "LEAVE_GROUP": "ترك المجموعة", + "CREATE_GROUP": "إنشاء مجموعة", + "SHARED_MEDIA": "وسائل الإعلام المشتركة", + "VIDEO_CALL": "مكالمة فيديو", + "AUDIO_CALL": "مكالمة صوتية", + "LOADING": "التحميل...", + "REPLY": "الرد", + "REPLIES": "الردود", + "LAUNCH": "إطلاق", + "SHARED_COLLABORATIVE_DOCUMENT": "وقد شارك وثيقة تعاونية", + "SHARED_COLLABORATIVE_WHITEBOARD": "مشاركة السبورة التعاونية", + "CREATED_WHITEBOARD": "لقد قمت بإنشاء لوحة بيضاء تعاونية جديدة", + "CREATED_DOCUMENT": "لقد قمت بإنشاء مستند تعاوني جديد", + "PHOTOS": "صور", + "VIDEOS": "فيديوهات", + "DOCUMENT": "مستند", + "YOU_DELETED_THIS_MESSAGE": "⚠️ قمت بحذف هذه الرسالة", + "THIS_MESSAGE_DELETED": "⚠️ تم حذف هذه الرسالة", + "VIEW_ON_YOUTUBE": "عرض على يوتيوب", + "SEARCH": "البحث", + "NO_USERS_FOUND": "لم يتم العثور على المستخدمين", + "ERROR": "خطأ", + "NO_GROUPS_FOUND": "لم يتم العثور على مجموعات", + "NO_CHATS_FOUND": "لم يتم العثور على دردشات", + "MEDIA_MESSAGE": "رسالة إعلامية", + "INCOMING_AUDIO_CALL": "مكالمة صوتية واردة", + "INCOMING_VIDEO_CALL": "مكالمة فيديو واردة", + "DECLINE": "انخفاض", + "ACCEPT": "قبول", + "CALL_INITIATED": "بدأ الاتصال", + "OUTGOING_AUDIO_CALL": "مكالمة صوتية صادرة", + "OUTGOING_VIDEO_CALL": "مكالمة فيديو صادرة", + "CALL_REJECTED": "تم رفض المكالمة", + "REJECTED_CALL": "مكالمة مرفوضة", + "CALL_ACCEPTED": "تم قبول المكالمة", + "JOINED": "انضم", + "LEFT_THE_CALL": "ترك المكالمة", + "UNANSWERED_AUDIO_CALL": "مكالمة صوتية لم تتم الإجابة عليها", + "UNANSWERED_VIDEO_CALL": "مكالمة فيديو لم تتم الإجابة عليها", + "CALL_ENDED": "انتهت المكالمة", + "CALL_CANCELLED": "تم إلغاء المكالمة", + "CALL_BUSY": "استدعاء مشغول", + "CALLING": "الدعوة...", + "ADD": "إضافة", + "NO_BANNED_MEMBERS_FOUND": "لم يتم العثور على أعضاء محظورين", + "BANNED_MEMBERS": "الأعضاء المحظورين", + "NAME": "اسم", + "SCOPE": "النطاق", + "UNBAN": "نبان", + "SELECT_GROUP_TYPE": "تحديد نوع المجموعة", + "ENTER_GROUP_PASSWORD": "أدخل كلمة مرور المجموعة", + "CREATE": "إنشاء", + "CREATE_POLL": "إنشاء استطلاع للرأي", + "QUESTION": "سؤال", + "ENTER_YOUR_QUESTION": "أدخل سؤالك", + "OPTIONS": "خيارات", + "ENTER_YOUR_OPTION": "أدخل الخيار الخاص بك", + "ADD_NEW_OPTION": "إضافة خيار جديد", + "VIEW_MEMBERS": "عرض الأعضاء", + "DETAILS": "تفاصيل", + "NOTIFICATIONS": "الإشعارات", + "OTHER": "أخرى", + "HELP": "مساعدة", + "REPORT_PROBLEM": "الإبلاغ عن مشكلة", + "GROUP_MEMBERS": "أعضاء المجموعة", + "BAN": "بان", + "KICK": "ركلة", + "PICK_YOUR_EMOJI": "اختيار الرموز التعبيرية الخاصة بك", + "PRIVATE_GROUP": "مجموعة خاصة", + "PROTECTED_GROUP": "المجموعة المحمية", + "VISIT": "زيارة", + "ATTACH": "إرفاق", + "ATTACH_FILE": "إرفاق ملف", + "ATTACH_VIDEO": "إرفاق الفيديو", + "ATTACH_AUDIO": "إرفاق الصوت", + "ATTACH_IMAGE": "إرفاق صورة", + "COLLABORATE_USING_DOCUMENT": "التعاون باستخدام مستند", + "COLLABORATE_USING_WHITEBOARD": "التعاون باستخدام لوح معلومات", + "EMOJI": "رمز تعبيري", + "ENTER_YOUR_MESSAGE_HERE": "أدخل رسالتك هنا", + "NO_MESSAGES_FOUND": "لم يتم العثور على رسائل", + "THREAD": "الموضوع", + "COLLABORATIVE_DOCUMENT": "وثيقة تعاونية", + "COLLABORATIVE_WHITEBOARD": "السبورة التعاونية", + "ADD_REACTION": "إضافة رد فعل", + "NO_STICKERS_FOUND": "لم يتم العثور على ملصقات", + "REPLY_TO_THREAD": "الرد على موضوع", + "REPLY_IN_THREAD": "الرد في موضوع", + "DELETE_MESSAGE": "حذف الرسالة", + "EDIT_MESSAGE": "تحرير الرسالة", + "SUNDAY": "الأحد", + "MONDAY": "الاثنين", + "TUESDAY": "الثلاثاء", + "WEDNESDAY": "الأربعاء", + "THURSDAY": "الخميس", + "FRIDAY": "الجمعة", + "SATURDAY": "السبت", + "GROUP_NAME_BLANK": "اسم المجموعة لا يمكن أن تكون فارغة", + "GROUP_TYPE_BLANK": "نوع المجموعة لا يمكن أن تكون فارغة", + "GROUP_PASSWORD_BLANK": "كلمة مرور المجموعة لا يمكن أن تكون فارغة", + "POLL_QUESTION_BLANK": "السؤال لا يمكن أن تكون فارغة", + "POLL_OPTION_BLANK": "الخيار لا يمكن أن تكون فارغة", + "OWNER": "مالك", + "CHANGE_SCOPE": "تغيير النطاق", + "STICKER": "ملصق", + "LAST_ACTIVE_AT": "آخر نشط في", + "VOICE_CALL": "مكالمة صوتية", + "VIEW_DETAIL": "عرض التفاصيل", + "VOTES": "التصويت", + "VOTE": "تصويت", + "NO_VOTE": "لا تصويت", + "REACTED": "رد فعل", + "ADDED": "أضاف", + "UNBANNED": "غير محظور", + "MADE": "صنع", + "CALL_UNANSWERED": "اتصل دون إجابة", + "MISSED_AUDIO_CALL": "مكالمة صوتية فائتة", + "ENTER_YOUR_PASSWORD": "أدخل كلمة المرور", + "DOCS": "مستندات", + "NO_RECORDS_FOUND": "لم يتم العثور على سجلات", + "LIVE_REACTION": "رد فعل حي", + "SMILEY_PEOPLE": "الوجوه الضاحكة والناس", + "ANIMALES_NATURE": "الحيوانات والطبيعة", + "FOOD_DRINK": "الطعام والشراب", + "ACTIVITY": "النشاط", + "TRAVEL_PLACES": "السفر والأماكن", + "OBJECTS": "كائنات", + "SYMBOLS": "الرموز", + "FLAGS": "أعلام", + "SENT": "أرسلت", + "SEEN": "شاهد", + "DELIVERED": "سلمت", + "CALLS": "المكالمات", + "CUSTOM_MESSAGE_LOCATION": "📍 الموقع", + "OFFLINE": "غير متصل", + "YOU": "أنت", + "PRIVACY": "الخصوصية", + "BLOCKED_USERS": "المستخدمون المحظورون", + "YOU'VE_BLOCKED": "لقد حظرت", + "NO_PHOTOS": "لا توجد صور", + "NO_VIDEOS": "لا توجد فيديوهات", + "NO_DOCUMENTS": "لا توجد وثائق", + "JOIN": "جوي" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/de/translation.json b/CometChat/resources/localization/locales/de/translation.json new file mode 100644 index 00000000..09a54924 --- /dev/null +++ b/CometChat/resources/localization/locales/de/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "Nutzer", + "CHATS": "Chats", + "GROUPS": "Gruppen", + "MORE": "mehr", + "MESSAGE_IMAGE": "📷 Bild", + "MESSAGE_FILE": "📁 Datei", + "MESSAGE_VIDEO": "📹 Video", + "MESSAGE_AUDIO": "🎵 Audio", + "CUSTOM_MESSAGE": "Du hast eine Nachricht", + "MISSED_VOICE_CALL": "Sprachanruf verpasst", + "MISSED_VIDEO_CALL": "Videoanruf verpasst", + "CUSTOM_MESSAGE_POLL": "📊 Umfrage", + "CUSTOM_MESSAGE_STICKER": "💟 Aufkleber", + "CUSTOM_MESSAGE_DOCUMENT": "📃 Dokument", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 Whiteboard", + "ONLINE": "Online", + "ADMINISTRATOR": "Verwalter", + "MODERATOR": "Moderator", + "PARTICIPANT": "Teilnehmerin", + "PUBLIC": "Öffentlich", + "PRIVATE": "Privat", + "PASSWORD_PROTECTED": "Passwort-geschützt", + "PRIVACY_AND_SECURITY": "Datenschutz und Sicherheit", + "PREFERENCES": "Präferenzen", + "MEMBERS": "Mitglieder", + "TODAY": "heute", + "YESTERDAY": "Gestern", + "TYPING": "tippen...", + "IS_TYPING": "tippt...", + "CLOSE": "schliessen", + "ENTER_GROUP_NAME": "Gruppennamen eingeben", + "ADD_MEMBERS": "Mitglieder hinzufügen", + "SEND_MESSAGE": "Nachricht senden", + "UNBLOCK_USER": "Benutzer entsperren", + "BLOCK_USER": "Benutzer blockieren", + "DELETE_AND_EXIT": "Löschen und beenden", + "LEAVE_GROUP": "Verlasse die Gruppe", + "CREATE_GROUP": "Gruppe erstellen", + "SHARED_MEDIA": "Geteilte Medien", + "VIDEO_CALL": "Videoanruf", + "AUDIO_CALL": "Audio-Anruf", + "LOADING": "Wird geladen...", + "REPLY": "Antwort", + "REPLIES": "Antworten", + "LAUNCH": "starten", + "SHARED_COLLABORATIVE_DOCUMENT": "hat ein gemeinschaftliches Dokument geteilt", + "SHARED_COLLABORATIVE_WHITEBOARD": "hat ein kollaboratives Whiteboard geteilt", + "CREATED_WHITEBOARD": "Du hast ein neues kollaboratives Whiteboard erstellt", + "CREATED_DOCUMENT": "Sie haben ein neues kollaboratives Dokument erstellt", + "PHOTOS": "Fotos", + "VIDEOS": "VIDEOS", + "DOCUMENT": "dokument", + "YOU_DELETED_THIS_MESSAGE": "⚠️ Du hast diese Nachricht gelöscht", + "THIS_MESSAGE_DELETED": "⚠️ Diese Nachricht wurde gelöscht", + "VIEW_ON_YOUTUBE": "Auf Youtube ansehen", + "SEARCH": "Suche", + "NO_USERS_FOUND": "Keine Benutzer gefunden", + "ERROR": "Fehler", + "NO_GROUPS_FOUND": "Keine Gruppen gefunden", + "NO_CHATS_FOUND": "Keine Chats gefunden", + "MEDIA_MESSAGE": "Mediale Botschaft", + "INCOMING_AUDIO_CALL": "Eingehender Audioanruf", + "INCOMING_VIDEO_CALL": "Eingehender Videoanruf", + "DECLINE": "Rückgang", + "ACCEPT": "Akzeptieren", + "CALL_INITIATED": "Anruf initiiert", + "OUTGOING_AUDIO_CALL": "Ausgehender Audioanruf", + "OUTGOING_VIDEO_CALL": "Ausgehender Videoanruf", + "CALL_REJECTED": "Anruf abgelehnt", + "REJECTED_CALL": "Anruf abgelehnt", + "CALL_ACCEPTED": "Anruf akzeptiert", + "JOINED": "verbunden", + "LEFT_THE_CALL": "hat den Anruf verlassen", + "UNANSWERED_AUDIO_CALL": "Unbeantworteter Audioan", + "UNANSWERED_VIDEO_CALL": "Unbeantworteter Videoan", + "CALL_ENDED": "Anruf endete", + "CALL_CANCELLED": "Anruf wurde abgebrochen", + "CALL_BUSY": "Anruf beschäftigt", + "CALLING": "Rufen...", + "ADD": "Add", + "NO_BANNED_MEMBERS_FOUND": "Keine verbotenen Mitglieder gefunden", + "BANNED_MEMBERS": "Verbotene Mitglieder", + "NAME": "Nennen", + "SCOPE": "Scope", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "Gruppentyp wählen", + "ENTER_GROUP_PASSWORD": "Gruppenkennwort eingeben", + "CREATE": "erstellen", + "CREATE_POLL": "Umfrage erstellen", + "QUESTION": "Frage", + "ENTER_YOUR_QUESTION": "Gib deine Frage ein", + "OPTIONS": "Optionen", + "ENTER_YOUR_OPTION": "Geben Sie Ihre Option", + "ADD_NEW_OPTION": "Neue Option hinzufügen", + "VIEW_MEMBERS": "Mitglieder ansehen", + "DETAILS": "Einzelheiten", + "NOTIFICATIONS": "Benachrichtigungen", + "OTHER": "andere", + "HELP": "Hilfe", + "REPORT_PROBLEM": "Melden Sie ein Problem", + "GROUP_MEMBERS": "Mitglieder der Gruppe", + "BAN": "Ban", + "KICK": "Tritt", + "PICK_YOUR_EMOJI": "Wähle dein Emoji", + "PRIVATE_GROUP": "Private Gruppe", + "PROTECTED_GROUP": "Geschützte Gruppe", + "VISIT": "Besuch", + "ATTACH": "anhängen", + "ATTACH_FILE": "Datei anhängen", + "ATTACH_VIDEO": "Video anhängen", + "ATTACH_AUDIO": "Anhängen von Audio", + "ATTACH_IMAGE": "Bild anhängen", + "COLLABORATE_USING_DOCUMENT": "Zusammenarbeit mit einem Dokument", + "COLLABORATE_USING_WHITEBOARD": "Arbeiten Sie mit einem Whiteboard zusammen", + "EMOJI": "Emoji", + "ENTER_YOUR_MESSAGE_HERE": "Gib hier deine Nachricht ein", + "NO_MESSAGES_FOUND": "Keine Nachrichten gefunden", + "THREAD": "Gewinde", + "COLLABORATIVE_DOCUMENT": "Gemeinschaftliches Dokument", + "COLLABORATIVE_WHITEBOARD": "Kollaboratives Whiteboard", + "ADD_REACTION": "Reaktion hinzufügen", + "NO_STICKERS_FOUND": "Keine Aufkleber gefunden", + "REPLY_TO_THREAD": "Antwort auf Thread", + "REPLY_IN_THREAD": "Antwort im Thread", + "DELETE_MESSAGE": "Nachricht löschen", + "EDIT_MESSAGE": "Nachricht bearbeiten", + "SUNDAY": "SONNTAG", + "MONDAY": "MONTAG", + "TUESDAY": "DIENSTAG", + "WEDNESDAY": "MITTWOCH", + "THURSDAY": "DONNERSTAG", + "FRIDAY": "FREITAG", + "SATURDAY": "SAMSTAG", + "GROUP_NAME_BLANK": "Gruppenname ist nicht leer", + "GROUP_TYPE_BLANK": "Gruppentyp ist nicht leer", + "GROUP_PASSWORD_BLANK": "Gruppenkennwort darf nicht leer sein", + "POLL_QUESTION_BLANK": "Frage wird nicht leer sein", + "POLL_OPTION_BLANK": "Option kannte nicht leer sein", + "OWNER": "Inhaber", + "CHANGE_SCOPE": "Umfang ändern", + "STICKER": "aufkleber", + "LAST_ACTIVE_AT": "Zuletzt aktiv bei", + "VOICE_CALL": "Sprach-Anruf", + "VIEW_DETAIL": "Details anzeigen", + "VOTES": "Wahlen", + "VOTE": "Abstimmung", + "NO_VOTE": "Keine Abstimmung", + "REACTED": "reagiert", + "ADDED": "hinzugefügt", + "UNBANNED": "unverbannt", + "MADE": "hergestellt", + "CALL_UNANSWERED": "Anruf unbeantwortet", + "MISSED_AUDIO_CALL": "Audioanruf verpasst", + "ENTER_YOUR_PASSWORD": "Geben Sie Ihr Passwort ein", + "DOCS": "docs", + "NO_RECORDS_FOUND": "Keine Aufzeichnungen gefunden", + "LIVE_REACTION": "Live-Reaktion", + "SMILEY_PEOPLE": "Smileys & Leute", + "ANIMALES_NATURE": "Tiere & Natur", + "FOOD_DRINK": "Essen & Trinken", + "ACTIVITY": "Die Aktivität", + "TRAVEL_PLACES": "Reisen & Orte", + "OBJECTS": "objekte", + "SYMBOLS": "Die Symbole", + "FLAGS": "Flaggen", + "SENT": "Gesendet", + "SEEN": "Gesehen", + "DELIVERED": "Ausgeliefert", + "CALLS": "Anrufe", + "CUSTOM_MESSAGE_LOCATION": "📍 Standort", + "OFFLINE": "Offline", + "YOU": "Du", + "PRIVACY": "Datenschutz", + "BLOCKED_USERS": "Gesperrte", + "YOU'VE_BLOCKED": "Du hast geblockt", + "NO_PHOTOS": "Keine Fotos", + "NO_VIDEOS": "Keine Videos", + "NO_DOCUMENTS": "Keine Dokumente", + "JOIN": "Joi" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/en-gb/translation.json b/CometChat/resources/localization/locales/en-gb/translation.json new file mode 100644 index 00000000..6aa3ce83 --- /dev/null +++ b/CometChat/resources/localization/locales/en-gb/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "Users", + "CHATS": "Chats", + "GROUPS": "Groups", + "MORE": "More", + "MESSAGE_IMAGE": "📷 Image", + "MESSAGE_FILE": "📁 File", + "MESSAGE_VIDEO": "📹 Video", + "MESSAGE_AUDIO": "🎵 Audio", + "CUSTOM_MESSAGE": "You have a message", + "MISSED_VOICE_CALL": "Missed voice call", + "MISSED_VIDEO_CALL": "Missed video call", + "CUSTOM_MESSAGE_POLL": "📊 Poll", + "CUSTOM_MESSAGE_STICKER": "💟 Sticker", + "CUSTOM_MESSAGE_DOCUMENT": "📃 Document", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 Whiteboard", + "ONLINE": "Online", + "ADMINISTRATOR": "Administrator", + "MODERATOR": "Moderator", + "PARTICIPANT": "Participant", + "PUBLIC": "Public", + "PRIVATE": "Private", + "PASSWORD_PROTECTED": "Password Protected", + "PRIVACY_AND_SECURITY": "Privacy and Security", + "PREFERENCES": "Preferences", + "MEMBERS": "Members", + "TODAY": "Today", + "YESTERDAY": "Yesterday", + "TYPING": "typing...", + "IS_TYPING": "is typing...", + "CLOSE": "Close", + "ENTER_GROUP_NAME": "Enter group name", + "ADD_MEMBERS": "Add Members", + "SEND_MESSAGE": "Send Message", + "UNBLOCK_USER": "Unblock User", + "BLOCK_USER": "Block User", + "DELETE_AND_EXIT": "Delete and Exit", + "LEAVE_GROUP": "Leave Group", + "CREATE_GROUP": "Create Group", + "SHARED_MEDIA": "Shared Media", + "VIDEO_CALL": "Video call", + "AUDIO_CALL": "Audio call", + "LOADING": "Loading...", + "REPLY": "reply", + "REPLIES": "replies", + "LAUNCH": "Launch", + "SHARED_COLLABORATIVE_DOCUMENT": "has shared a collaborative document", + "SHARED_COLLABORATIVE_WHITEBOARD": "has shared a collaborative whiteboard", + "CREATED_WHITEBOARD": "You’ve created a new collaborative whiteboard", + "CREATED_DOCUMENT": "You’ve created a new collaborative document", + "PHOTOS": "Photos", + "VIDEOS": "Videos", + "DOCUMENT": "Document", + "YOU_DELETED_THIS_MESSAGE": "⚠️ You deleted this message", + "THIS_MESSAGE_DELETED": "⚠️ This message was deleted", + "VIEW_ON_YOUTUBE": "View on Youtube", + "SEARCH": "Search", + "NO_USERS_FOUND": "No users found", + "ERROR": "Error", + "NO_GROUPS_FOUND": "No groups found", + "NO_CHATS_FOUND": "No chats found", + "MEDIA_MESSAGE": "Media message", + "INCOMING_AUDIO_CALL": "Incoming audio call", + "INCOMING_VIDEO_CALL": "Incoming video call", + "DECLINE": "Decline", + "ACCEPT": "Accept", + "CALL_INITIATED": "Call initiated", + "OUTGOING_AUDIO_CALL": "Outgoing audio call", + "OUTGOING_VIDEO_CALL": "Outgoing video call", + "CALL_REJECTED": "Call rejected", + "REJECTED_CALL": "rejected call", + "CALL_ACCEPTED": "Call accepted", + "JOINED": "joined", + "LEFT_THE_CALL": "left the call", + "UNANSWERED_AUDIO_CALL": "Unanswered audio call", + "UNANSWERED_VIDEO_CALL": "Unanswered video call", + "CALL_ENDED": "Call ended", + "CALL_CANCELLED": "Call cancelled", + "CALL_BUSY": "Call busy", + "CALLING": "Calling...", + "ADD": "Add", + "NO_BANNED_MEMBERS_FOUND": "No banned members found", + "BANNED_MEMBERS": "Banned Members", + "NAME": "Name", + "SCOPE": "Scope", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "Select group type", + "ENTER_GROUP_PASSWORD": "Enter group password", + "CREATE": "Create", + "CREATE_POLL": "Create Poll", + "QUESTION": "Question", + "ENTER_YOUR_QUESTION": "Enter your question", + "OPTIONS": "Options", + "ENTER_YOUR_OPTION": "Enter your option", + "ADD_NEW_OPTION": "Add new option", + "VIEW_MEMBERS": "View Members", + "DETAILS": "Details", + "NOTIFICATIONS": "Notifications", + "OTHER": "Other", + "HELP": "Help", + "REPORT_PROBLEM": "Report a Problem", + "GROUP_MEMBERS": "Group Members", + "BAN": "Ban", + "KICK": "Kick", + "PICK_YOUR_EMOJI": "Pick your emoji", + "PRIVATE_GROUP": "Private Group", + "PROTECTED_GROUP": "Protected Group", + "VISIT": "Visit", + "ATTACH": "Attach", + "ATTACH_FILE": "Attach file", + "ATTACH_VIDEO": "Attach video", + "ATTACH_AUDIO": "Attach audio", + "ATTACH_IMAGE": "Attach image", + "COLLABORATE_USING_DOCUMENT": "Collaborate using a document", + "COLLABORATE_USING_WHITEBOARD": "Collaborate using a whiteboard", + "EMOJI": "Emoji", + "ENTER_YOUR_MESSAGE_HERE": "Enter your message here", + "NO_MESSAGES_FOUND": "No messages found", + "THREAD": "Thread", + "COLLABORATIVE_DOCUMENT": "Collaborative Document", + "COLLABORATIVE_WHITEBOARD": "Collaborative Whiteboard", + "ADD_REACTION": "Add reaction", + "NO_STICKERS_FOUND": "No stickers found", + "REPLY_TO_THREAD": "Reply to thread", + "REPLY_IN_THREAD": "Reply in thread", + "DELETE_MESSAGE": "Delete message", + "EDIT_MESSAGE": "Edit message", + "SUNDAY": "SUNDAY", + "MONDAY": "MONDAY", + "TUESDAY": "TUESDAY", + "WEDNESDAY": "WEDNESDAY", + "THURSDAY": "THURSDAY", + "FRIDAY": "FRIDAY", + "SATURDAY": "SATURDAY", + "GROUP_NAME_BLANK": "Group name cannnot be blank", + "GROUP_TYPE_BLANK": "Group type cannnot be blank", + "GROUP_PASSWORD_BLANK": "Group password cannnot be blank", + "POLL_QUESTION_BLANK": "Question cannnot be blank", + "POLL_OPTION_BLANK": "Option cannnot be blank", + "OWNER": "Owner", + "CHANGE_SCOPE": "Change Scope", + "STICKER": "Sticker", + "LAST_ACTIVE_AT": "Last Active At", + "VOICE_CALL": "Voice call", + "VIEW_DETAIL": "View Detail", + "VOTES": "votes", + "VOTE": "vote", + "NO_VOTE": "No vote", + "REACTED": "reacted", + "ADDED": "added", + "UNBANNED": "unbanned", + "MADE": "made", + "CALL_UNANSWERED": "Call unanswered", + "MISSED_AUDIO_CALL": "Missed audio call", + "ENTER_YOUR_PASSWORD": "Enter your password", + "DOCS": "Docs", + "NO_RECORDS_FOUND": "No records found", + "LIVE_REACTION": "Live Reaction", + "SMILEY_PEOPLE": "Smileys & People", + "ANIMALES_NATURE": "Animals & Nature", + "FOOD_DRINK": "Food & Drink", + "ACTIVITY": "Activity", + "TRAVEL_PLACES": "Travel & Places", + "OBJECTS": "Objects", + "SYMBOLS": "Symbols", + "FLAGS": "Flags", + "SENT": "Sent", + "SEEN": "Seen", + "DELIVERED": "Delivered", + "CALLS": "Calls", + "CUSTOM_MESSAGE_LOCATION": "📍Location", + "OFFLINE": "Offline", + "YOU": "You", + "PRIVACY": "Privacy", + "BLOCKED_USERS": "Blocked Users", + "YOU'VE_BLOCKED": "You've blocked", + "NO_PHOTOS": "No Photos", + "NO_VIDEOS": "No Videos", + "NO_DOCUMENTS": "No Documents", + "JOIN": "Join" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/en-us/translation.json b/CometChat/resources/localization/locales/en-us/translation.json new file mode 100644 index 00000000..5b8ca267 --- /dev/null +++ b/CometChat/resources/localization/locales/en-us/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "Users", + "CHATS": "Chats", + "GROUPS": "Groups", + "MORE": "More", + "MESSAGE_IMAGE": "📷 Image", + "MESSAGE_FILE": "📁 File", + "MESSAGE_VIDEO": "📹 Video", + "MESSAGE_AUDIO": "🎵 Audio", + "CUSTOM_MESSAGE": "You have a message", + "MISSED_VOICE_CALL": "Missed voice call", + "MISSED_VIDEO_CALL": "Missed video call", + "CUSTOM_MESSAGE_POLL": "📊 Poll", + "CUSTOM_MESSAGE_STICKER": "💟 Sticker", + "CUSTOM_MESSAGE_DOCUMENT": "📃 Document", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 Whiteboard", + "ONLINE": "Online", + "ADMINISTRATOR": "Administrator", + "MODERATOR": "Moderator", + "PARTICIPANT": "Participant", + "PUBLIC": "Public", + "PRIVATE": "Private", + "PASSWORD_PROTECTED": "Password Protected", + "PRIVACY_AND_SECURITY": "Privacy and Security", + "PREFERENCES": "Preferences", + "MEMBERS": "Members", + "TODAY": "Today", + "YESTERDAY": "Yesterday", + "TYPING": "typing...", + "IS_TYPING": "is typing...", + "CLOSE": "Close", + "ENTER_GROUP_NAME": "Enter group name", + "ADD_MEMBERS": "Add Members", + "SEND_MESSAGE": "Send Message", + "UNBLOCK_USER": "Unblock User", + "BLOCK_USER": "Block User", + "DELETE_AND_EXIT": "Delete and Exit", + "LEAVE_GROUP": "Leave Group", + "CREATE_GROUP": "Create Group", + "SHARED_MEDIA": "Shared Media", + "VIDEO_CALL": "Video call", + "AUDIO_CALL": "Audio call", + "LOADING": "Loading...", + "REPLY": "reply", + "REPLIES": "replies", + "LAUNCH": "Launch", + "SHARED_COLLABORATIVE_DOCUMENT": "has shared a collaborative document", + "SHARED_COLLABORATIVE_WHITEBOARD": "has shared a collaborative whiteboard", + "CREATED_WHITEBOARD": "You’ve created a new collaborative whiteboard", + "CREATED_DOCUMENT": "You’ve created a new collaborative document", + "PHOTOS": "Photos", + "VIDEOS": "Videos", + "DOCUMENT": "Document", + "YOU_DELETED_THIS_MESSAGE": "⚠️ You deleted this message", + "THIS_MESSAGE_DELETED": "⚠️ This message was deleted", + "VIEW_ON_YOUTUBE": "View on Youtube", + "SEARCH": "Search", + "NO_USERS_FOUND": "No users found", + "ERROR": "Error", + "NO_GROUPS_FOUND": "No groups found", + "NO_CHATS_FOUND": "No chats found", + "MEDIA_MESSAGE": "Media message", + "INCOMING_AUDIO_CALL": "Incoming audio call", + "INCOMING_VIDEO_CALL": "Incoming video call", + "DECLINE": "Decline", + "ACCEPT": "Accept", + "CALL_INITIATED": "Call initiated", + "OUTGOING_AUDIO_CALL": "Outgoing audio call", + "OUTGOING_VIDEO_CALL": "Outgoing video call", + "CALL_REJECTED": "Call rejected", + "REJECTED_CALL": "rejected call", + "CALL_ACCEPTED": "Call accepted", + "JOINED": "joined", + "LEFT_THE_CALL": "left the call", + "UNANSWERED_AUDIO_CALL": "Unanswered audio call", + "UNANSWERED_VIDEO_CALL": "Unanswered video call", + "CALL_ENDED": "Call ended", + "CALL_CANCELLED": "Call cancelled", + "CALL_BUSY": "Call busy", + "CALLING": "Calling...", + "ADD": "Add", + "NO_BANNED_MEMBERS_FOUND": "No banned members found", + "BANNED_MEMBERS": "Banned Members", + "NAME": "Name", + "SCOPE": "Scope", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "Select group type", + "ENTER_GROUP_PASSWORD": "Enter group password", + "CREATE": "Create", + "CREATE_POLL": "Create Poll", + "QUESTION": "Question", + "ENTER_YOUR_QUESTION": "Enter your question", + "OPTIONS": "Options", + "ENTER_YOUR_OPTION": "Enter your option", + "ADD_NEW_OPTION": "Add new option", + "VIEW_MEMBERS": "View Members", + "DETAILS": "Details", + "NOTIFICATIONS": "Notifications", + "OTHER": "Other", + "HELP": "Help", + "REPORT_PROBLEM": "Report a Problem", + "GROUP_MEMBERS": "Group Members", + "BAN": "Ban", + "KICK": "Kick", + "PICK_YOUR_EMOJI": "Pick your emoji", + "PRIVATE_GROUP": "Private Group", + "PROTECTED_GROUP": "Protected Group", + "VISIT": "Visit", + "ATTACH": "Attach", + "ATTACH_FILE": "Attach file", + "ATTACH_VIDEO": "Attach video", + "ATTACH_AUDIO": "Attach audio", + "ATTACH_IMAGE": "Attach image", + "COLLABORATE_USING_DOCUMENT": "Collaborate using a document", + "COLLABORATE_USING_WHITEBOARD": "Collaborate using a whiteboard", + "EMOJI": "Emoji", + "ENTER_YOUR_MESSAGE_HERE": "Enter your message here", + "NO_MESSAGES_FOUND": "No messages found", + "THREAD": "Thread", + "COLLABORATIVE_DOCUMENT": "Collaborative Document", + "COLLABORATIVE_WHITEBOARD": "Collaborative Whiteboard", + "ADD_REACTION": "Add reaction", + "NO_STICKERS_FOUND": "No stickers found", + "REPLY_TO_THREAD": "Reply to thread", + "REPLY_IN_THREAD": "Reply in thread", + "DELETE_MESSAGE": "Delete message", + "EDIT_MESSAGE": "Edit message", + "SUNDAY": "SUNDAY", + "MONDAY": "MONDAY", + "TUESDAY": "TUESDAY", + "WEDNESDAY": "WEDNESDAY", + "THURSDAY": "THURSDAY", + "FRIDAY": "FRIDAY", + "SATURDAY": "SATURDAY", + "GROUP_NAME_BLANK": "Group name cannnot be blank", + "GROUP_TYPE_BLANK": "Group type cannnot be blank", + "GROUP_PASSWORD_BLANK": "Group password cannnot be blank", + "POLL_QUESTION_BLANK": "Question cannnot be blank", + "POLL_OPTION_BLANK": "Option cannnot be blank", + "OWNER": "Owner", + "CHANGE_SCOPE": "Change Scope", + "STICKER": "Sticker", + "LAST_ACTIVE_AT": "Last Active At", + "VOICE_CALL": "Voice call", + "VIEW_DETAIL": "View Detail", + "VOTES": "votes", + "VOTE": "vote", + "NO_VOTE": "No vote", + "REACTED": "reacted", + "ADDED": "added", + "UNBANNED": "unbanned", + "MADE": "made", + "CALL_UNANSWERED": "Call unanswered", + "MISSED_AUDIO_CALL": "Missed audio call", + "ENTER_YOUR_PASSWORD": "Enter your password", + "DOCS": "Docs", + "NO_RECORDS_FOUND": "No records found", + "LIVE_REACTION": "Live Reaction", + "SMILEY_PEOPLE": "Smileys & People", + "ANIMALES_NATURE": "Animals & Nature", + "FOOD_DRINK": "Food & Drink", + "ACTIVITY": "Activity", + "TRAVEL_PLACES": "Travel & Places", + "OBJECTS": "Objects", + "SYMBOLS": "Symbols", + "FLAGS": "Flags", + "SENT": "Sent", + "SEEN": "Seen", + "DELIVERED": "Delivered", + "CALLS": "Calls", + "CUSTOM_MESSAGE_LOCATION": "📍Location", + "OFFLINE": "Offline", + "YOU": "You", + "PRIVACY": "Privacy", + "BLOCKED_USERS": "Blocked Users", + "YOU'VE_BLOCKED": "You've blocked", + "NO_PHOTOS": "No Photos", + "NO_VIDEOS": "No Videos", + "NO_DOCUMENTS": "No Documents", + "JOIN": "Join" +} diff --git a/CometChat/resources/localization/locales/en/translation.json b/CometChat/resources/localization/locales/en/translation.json new file mode 100644 index 00000000..6aa3ce83 --- /dev/null +++ b/CometChat/resources/localization/locales/en/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "Users", + "CHATS": "Chats", + "GROUPS": "Groups", + "MORE": "More", + "MESSAGE_IMAGE": "📷 Image", + "MESSAGE_FILE": "📁 File", + "MESSAGE_VIDEO": "📹 Video", + "MESSAGE_AUDIO": "🎵 Audio", + "CUSTOM_MESSAGE": "You have a message", + "MISSED_VOICE_CALL": "Missed voice call", + "MISSED_VIDEO_CALL": "Missed video call", + "CUSTOM_MESSAGE_POLL": "📊 Poll", + "CUSTOM_MESSAGE_STICKER": "💟 Sticker", + "CUSTOM_MESSAGE_DOCUMENT": "📃 Document", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 Whiteboard", + "ONLINE": "Online", + "ADMINISTRATOR": "Administrator", + "MODERATOR": "Moderator", + "PARTICIPANT": "Participant", + "PUBLIC": "Public", + "PRIVATE": "Private", + "PASSWORD_PROTECTED": "Password Protected", + "PRIVACY_AND_SECURITY": "Privacy and Security", + "PREFERENCES": "Preferences", + "MEMBERS": "Members", + "TODAY": "Today", + "YESTERDAY": "Yesterday", + "TYPING": "typing...", + "IS_TYPING": "is typing...", + "CLOSE": "Close", + "ENTER_GROUP_NAME": "Enter group name", + "ADD_MEMBERS": "Add Members", + "SEND_MESSAGE": "Send Message", + "UNBLOCK_USER": "Unblock User", + "BLOCK_USER": "Block User", + "DELETE_AND_EXIT": "Delete and Exit", + "LEAVE_GROUP": "Leave Group", + "CREATE_GROUP": "Create Group", + "SHARED_MEDIA": "Shared Media", + "VIDEO_CALL": "Video call", + "AUDIO_CALL": "Audio call", + "LOADING": "Loading...", + "REPLY": "reply", + "REPLIES": "replies", + "LAUNCH": "Launch", + "SHARED_COLLABORATIVE_DOCUMENT": "has shared a collaborative document", + "SHARED_COLLABORATIVE_WHITEBOARD": "has shared a collaborative whiteboard", + "CREATED_WHITEBOARD": "You’ve created a new collaborative whiteboard", + "CREATED_DOCUMENT": "You’ve created a new collaborative document", + "PHOTOS": "Photos", + "VIDEOS": "Videos", + "DOCUMENT": "Document", + "YOU_DELETED_THIS_MESSAGE": "⚠️ You deleted this message", + "THIS_MESSAGE_DELETED": "⚠️ This message was deleted", + "VIEW_ON_YOUTUBE": "View on Youtube", + "SEARCH": "Search", + "NO_USERS_FOUND": "No users found", + "ERROR": "Error", + "NO_GROUPS_FOUND": "No groups found", + "NO_CHATS_FOUND": "No chats found", + "MEDIA_MESSAGE": "Media message", + "INCOMING_AUDIO_CALL": "Incoming audio call", + "INCOMING_VIDEO_CALL": "Incoming video call", + "DECLINE": "Decline", + "ACCEPT": "Accept", + "CALL_INITIATED": "Call initiated", + "OUTGOING_AUDIO_CALL": "Outgoing audio call", + "OUTGOING_VIDEO_CALL": "Outgoing video call", + "CALL_REJECTED": "Call rejected", + "REJECTED_CALL": "rejected call", + "CALL_ACCEPTED": "Call accepted", + "JOINED": "joined", + "LEFT_THE_CALL": "left the call", + "UNANSWERED_AUDIO_CALL": "Unanswered audio call", + "UNANSWERED_VIDEO_CALL": "Unanswered video call", + "CALL_ENDED": "Call ended", + "CALL_CANCELLED": "Call cancelled", + "CALL_BUSY": "Call busy", + "CALLING": "Calling...", + "ADD": "Add", + "NO_BANNED_MEMBERS_FOUND": "No banned members found", + "BANNED_MEMBERS": "Banned Members", + "NAME": "Name", + "SCOPE": "Scope", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "Select group type", + "ENTER_GROUP_PASSWORD": "Enter group password", + "CREATE": "Create", + "CREATE_POLL": "Create Poll", + "QUESTION": "Question", + "ENTER_YOUR_QUESTION": "Enter your question", + "OPTIONS": "Options", + "ENTER_YOUR_OPTION": "Enter your option", + "ADD_NEW_OPTION": "Add new option", + "VIEW_MEMBERS": "View Members", + "DETAILS": "Details", + "NOTIFICATIONS": "Notifications", + "OTHER": "Other", + "HELP": "Help", + "REPORT_PROBLEM": "Report a Problem", + "GROUP_MEMBERS": "Group Members", + "BAN": "Ban", + "KICK": "Kick", + "PICK_YOUR_EMOJI": "Pick your emoji", + "PRIVATE_GROUP": "Private Group", + "PROTECTED_GROUP": "Protected Group", + "VISIT": "Visit", + "ATTACH": "Attach", + "ATTACH_FILE": "Attach file", + "ATTACH_VIDEO": "Attach video", + "ATTACH_AUDIO": "Attach audio", + "ATTACH_IMAGE": "Attach image", + "COLLABORATE_USING_DOCUMENT": "Collaborate using a document", + "COLLABORATE_USING_WHITEBOARD": "Collaborate using a whiteboard", + "EMOJI": "Emoji", + "ENTER_YOUR_MESSAGE_HERE": "Enter your message here", + "NO_MESSAGES_FOUND": "No messages found", + "THREAD": "Thread", + "COLLABORATIVE_DOCUMENT": "Collaborative Document", + "COLLABORATIVE_WHITEBOARD": "Collaborative Whiteboard", + "ADD_REACTION": "Add reaction", + "NO_STICKERS_FOUND": "No stickers found", + "REPLY_TO_THREAD": "Reply to thread", + "REPLY_IN_THREAD": "Reply in thread", + "DELETE_MESSAGE": "Delete message", + "EDIT_MESSAGE": "Edit message", + "SUNDAY": "SUNDAY", + "MONDAY": "MONDAY", + "TUESDAY": "TUESDAY", + "WEDNESDAY": "WEDNESDAY", + "THURSDAY": "THURSDAY", + "FRIDAY": "FRIDAY", + "SATURDAY": "SATURDAY", + "GROUP_NAME_BLANK": "Group name cannnot be blank", + "GROUP_TYPE_BLANK": "Group type cannnot be blank", + "GROUP_PASSWORD_BLANK": "Group password cannnot be blank", + "POLL_QUESTION_BLANK": "Question cannnot be blank", + "POLL_OPTION_BLANK": "Option cannnot be blank", + "OWNER": "Owner", + "CHANGE_SCOPE": "Change Scope", + "STICKER": "Sticker", + "LAST_ACTIVE_AT": "Last Active At", + "VOICE_CALL": "Voice call", + "VIEW_DETAIL": "View Detail", + "VOTES": "votes", + "VOTE": "vote", + "NO_VOTE": "No vote", + "REACTED": "reacted", + "ADDED": "added", + "UNBANNED": "unbanned", + "MADE": "made", + "CALL_UNANSWERED": "Call unanswered", + "MISSED_AUDIO_CALL": "Missed audio call", + "ENTER_YOUR_PASSWORD": "Enter your password", + "DOCS": "Docs", + "NO_RECORDS_FOUND": "No records found", + "LIVE_REACTION": "Live Reaction", + "SMILEY_PEOPLE": "Smileys & People", + "ANIMALES_NATURE": "Animals & Nature", + "FOOD_DRINK": "Food & Drink", + "ACTIVITY": "Activity", + "TRAVEL_PLACES": "Travel & Places", + "OBJECTS": "Objects", + "SYMBOLS": "Symbols", + "FLAGS": "Flags", + "SENT": "Sent", + "SEEN": "Seen", + "DELIVERED": "Delivered", + "CALLS": "Calls", + "CUSTOM_MESSAGE_LOCATION": "📍Location", + "OFFLINE": "Offline", + "YOU": "You", + "PRIVACY": "Privacy", + "BLOCKED_USERS": "Blocked Users", + "YOU'VE_BLOCKED": "You've blocked", + "NO_PHOTOS": "No Photos", + "NO_VIDEOS": "No Videos", + "NO_DOCUMENTS": "No Documents", + "JOIN": "Join" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/es/translation.json b/CometChat/resources/localization/locales/es/translation.json new file mode 100644 index 00000000..a8314d32 --- /dev/null +++ b/CometChat/resources/localization/locales/es/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "Usuarios", + "CHATS": "Chats", + "GROUPS": "Grupos", + "MORE": "Más", + "MESSAGE_IMAGE": "📷 Imagen", + "MESSAGE_FILE": "📁 Archivo", + "MESSAGE_VIDEO": "📹 Vídeo", + "MESSAGE_AUDIO": "🎵 Audio", + "CUSTOM_MESSAGE": "Tienes un mensaje", + "MISSED_VOICE_CALL": "Llamada de voz perdida", + "MISSED_VIDEO_CALL": "Videollamada perdida", + "CUSTOM_MESSAGE_POLL": "📊 Encuesta", + "CUSTOM_MESSAGE_STICKER": "💟 Pegatina", + "CUSTOM_MESSAGE_DOCUMENT": "📃 Documento", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 Pizarra blanca", + "ONLINE": "En línea", + "ADMINISTRATOR": "Administrador", + "MODERATOR": "Moderador", + "PARTICIPANT": "Participante", + "PUBLIC": "Público", + "PRIVATE": "Privado", + "PASSWORD_PROTECTED": "Protegido con contraseña", + "PRIVACY_AND_SECURITY": "Privacidad y Seguridad", + "PREFERENCES": "Preferencias", + "MEMBERS": "Miembros", + "TODAY": "Hoy", + "YESTERDAY": "Ayer", + "TYPING": "escribiendo...", + "IS_TYPING": "está escribiendo...", + "CLOSE": "Cerrar", + "ENTER_GROUP_NAME": "Introducir nombre de grupo", + "ADD_MEMBERS": "Agregar miembros", + "SEND_MESSAGE": "Enviar mensaje", + "UNBLOCK_USER": "Desbloquear usuario", + "BLOCK_USER": "Bloquear usuario", + "DELETE_AND_EXIT": "Eliminar y salir", + "LEAVE_GROUP": "Salir del grupo", + "CREATE_GROUP": "Crear grupo", + "SHARED_MEDIA": "Medios compartidos", + "VIDEO_CALL": "Videollamada", + "AUDIO_CALL": "Llamada de audio", + "LOADING": "Cargando...", + "REPLY": "responder", + "REPLIES": "respuestas", + "LAUNCH": "Lanzamiento", + "SHARED_COLLABORATIVE_DOCUMENT": "ha compartido un documento colaborativo", + "SHARED_COLLABORATIVE_WHITEBOARD": "ha compartido una pizarra colaborativa", + "CREATED_WHITEBOARD": "Has creado una nueva pizarra colaborativa", + "CREATED_DOCUMENT": "Ha creado un nuevo documento colaborativo", + "PHOTOS": "Fotos", + "VIDEOS": "Vídeos", + "DOCUMENT": "Documento", + "YOU_DELETED_THIS_MESSAGE": "⚠️ Has eliminado este mensaje", + "THIS_MESSAGE_DELETED": "⚠️ Este mensaje fue eliminado", + "VIEW_ON_YOUTUBE": "Ver en Youtube", + "SEARCH": "Buscar", + "NO_USERS_FOUND": "No se han encontrado usuarios", + "ERROR": "Error", + "NO_GROUPS_FOUND": "No se han encontrado grupos", + "NO_CHATS_FOUND": "No se encontraron chats", + "MEDIA_MESSAGE": "Mensaje multimedia", + "INCOMING_AUDIO_CALL": "Llamada de audio entrante", + "INCOMING_VIDEO_CALL": "Videollamada entrante", + "DECLINE": "Declive", + "ACCEPT": "Aceptar", + "CALL_INITIATED": "Llamada iniciada", + "OUTGOING_AUDIO_CALL": "Llamada de audio saliente", + "OUTGOING_VIDEO_CALL": "Videollamada saliente", + "CALL_REJECTED": "Llamada rechazada", + "REJECTED_CALL": "llamada rechazada", + "CALL_ACCEPTED": "Llamada aceptada", + "JOINED": "se unieron", + "LEFT_THE_CALL": "dejó la llamada", + "UNANSWERED_AUDIO_CALL": "Llamada de audio sin respuesta", + "UNANSWERED_VIDEO_CALL": "Videollamada sin respuesta", + "CALL_ENDED": "Llamada finalizada", + "CALL_CANCELLED": "Llamada cancelada", + "CALL_BUSY": "Llamada ocupada", + "CALLING": "Llamando...", + "ADD": "Añadir", + "NO_BANNED_MEMBERS_FOUND": "No se encontraron miembros prohibidos", + "BANNED_MEMBERS": "Miembros prohibidos", + "NAME": "Nombre", + "SCOPE": "Ámbito", + "UNBAN": "Unban la prohibición", + "SELECT_GROUP_TYPE": "Seleccionar tipo de grupo", + "ENTER_GROUP_PASSWORD": "Introducir contraseña de grupo", + "CREATE": "Crear", + "CREATE_POLL": "Crear encuesta", + "QUESTION": "Pregunta", + "ENTER_YOUR_QUESTION": "Introduce tu pregunta", + "OPTIONS": "Opciones", + "ENTER_YOUR_OPTION": "Introduce tu opción", + "ADD_NEW_OPTION": "Agregar nueva opción", + "VIEW_MEMBERS": "Ver miembros", + "DETAILS": "Detalles", + "NOTIFICATIONS": "Notificaciones", + "OTHER": "Otro", + "HELP": "Ayudar", + "REPORT_PROBLEM": "Informar de un problema", + "GROUP_MEMBERS": "Miembros del grupo", + "BAN": "Prohibición", + "KICK": "Patada", + "PICK_YOUR_EMOJI": "Elige tu emoji", + "PRIVATE_GROUP": "Grupo Privado", + "PROTECTED_GROUP": "Grupo protegido", + "VISIT": "Visitar", + "ATTACH": "Adjuntar", + "ATTACH_FILE": "Adjuntar archivo", + "ATTACH_VIDEO": "Adjuntar vídeo", + "ATTACH_AUDIO": "Adjuntar audio", + "ATTACH_IMAGE": "Adjuntar imagen", + "COLLABORATE_USING_DOCUMENT": "Colaborar con un documento", + "COLLABORATE_USING_WHITEBOARD": "Colaborar con una pizarra", + "EMOJI": "Emoji", + "ENTER_YOUR_MESSAGE_HERE": "Introduzca su mensaje aquí", + "NO_MESSAGES_FOUND": "No se han encontrado mensajes", + "THREAD": "Rosca", + "COLLABORATIVE_DOCUMENT": "Documento colaborativo", + "COLLABORATIVE_WHITEBOARD": "Pizarra colaborativa", + "ADD_REACTION": "Añadir reacción", + "NO_STICKERS_FOUND": "No se encontraron pegatinas", + "REPLY_TO_THREAD": "Responder al hilo", + "REPLY_IN_THREAD": "Responder en hilo", + "DELETE_MESSAGE": "Eliminar mensaje", + "EDIT_MESSAGE": "Editar mensaje", + "SUNDAY": "DOMINGO", + "MONDAY": "LUNES", + "TUESDAY": "MARTES", + "WEDNESDAY": "MIÉRCOLES", + "THURSDAY": "JUEVES", + "FRIDAY": "VIERNES", + "SATURDAY": "SÁBADO", + "GROUP_NAME_BLANK": "El nombre del grupo no puede estar en blanco", + "GROUP_TYPE_BLANK": "El tipo de grupo no puede estar en blanco", + "GROUP_PASSWORD_BLANK": "La contraseña de grupo no puede estar en blanco", + "POLL_QUESTION_BLANK": "La pregunta no puede estar en blanco", + "POLL_OPTION_BLANK": "La opción no puede estar en blanco", + "OWNER": "Propietario", + "CHANGE_SCOPE": "Cambiar ámbito", + "STICKER": "Pegatina", + "LAST_ACTIVE_AT": "Último activo en", + "VOICE_CALL": "Llamada de voz", + "VIEW_DETAIL": "Ver detalle", + "VOTES": "votos", + "VOTE": "Votar", + "NO_VOTE": "Sin voto", + "REACTED": "reaccionó", + "ADDED": "añadido", + "UNBANNED": "no prohibida", + "MADE": "hecho", + "CALL_UNANSWERED": "Llamada sin respuesta", + "MISSED_AUDIO_CALL": "Llamada de audio perdida", + "ENTER_YOUR_PASSWORD": "Introduce tu contraseña", + "DOCS": "Documentos", + "NO_RECORDS_FOUND": "No se encontraron registros", + "LIVE_REACTION": "Reacción en vivo", + "SMILEY_PEOPLE": "Smileys & Gente", + "ANIMALES_NATURE": "Animales y Naturaleza", + "FOOD_DRINK": "Comida y bebida", + "ACTIVITY": "Actividad", + "TRAVEL_PLACES": "Viajes y Lugares", + "OBJECTS": "Objetos", + "SYMBOLS": "Símbolos", + "FLAGS": "Banderas", + "SENT": "Enviado", + "SEEN": "Visto", + "DELIVERED": "Entregado", + "CALLS": "Llamadas", + "CUSTOM_MESSAGE_LOCATION": "📍 Ubicación", + "OFFLINE": "Offline", + "YOU": "Usted", + "PRIVACY": "Privacidad", + "BLOCKED_USERS": "Usuarios bloqueados", + "YOU'VE_BLOCKED": "Has bloqueado", + "NO_PHOTOS": "No hay fotos", + "NO_VIDEOS": "No hay vídeos", + "NO_DOCUMENTS": "Sin documentos", + "JOIN": "Joi" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/fr/translation.json b/CometChat/resources/localization/locales/fr/translation.json new file mode 100644 index 00000000..b868e897 --- /dev/null +++ b/CometChat/resources/localization/locales/fr/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "Utilisateurs", + "CHATS": "Discussions", + "GROUPS": "Groupes", + "MORE": "Plus", + "MESSAGE_IMAGE": "📷 Image", + "MESSAGE_FILE": "📁 Fichier", + "MESSAGE_VIDEO": "📹 Vidéo", + "MESSAGE_AUDIO": "🎵 Audio", + "CUSTOM_MESSAGE": "Vous avez un message", + "MISSED_VOICE_CALL": "Appel vocal manqué", + "MISSED_VIDEO_CALL": "Appel vidéo manqué", + "CUSTOM_MESSAGE_POLL": "📊 Sondage", + "CUSTOM_MESSAGE_STICKER": "💟 Autocollant", + "CUSTOM_MESSAGE_DOCUMENT": "📃 Document", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 Tableau blanc", + "ONLINE": "En ligne", + "ADMINISTRATOR": "Administrateur", + "MODERATOR": "Modérateur", + "PARTICIPANT": "Participant", + "PUBLIC": "Public", + "PRIVATE": "Privé", + "PASSWORD_PROTECTED": "Mot de passe", + "PRIVACY_AND_SECURITY": "Confidentialité et sécurité", + "PREFERENCES": "Préférences", + "MEMBERS": "Membres", + "TODAY": "Aujourd'hui", + "YESTERDAY": "Hier", + "TYPING": "dactylographie...", + "IS_TYPING": "est en train de taper...", + "CLOSE": "Fermer", + "ENTER_GROUP_NAME": "Saisir le nom du groupe", + "ADD_MEMBERS": "Ajouter des membres", + "SEND_MESSAGE": "Envoyer un message", + "UNBLOCK_USER": "Débloquer l'utilisateur", + "BLOCK_USER": "Bloquer l'utilisateur", + "DELETE_AND_EXIT": "Supprimer et quitter", + "LEAVE_GROUP": "Groupe de congé", + "CREATE_GROUP": "Créer un groupe", + "SHARED_MEDIA": "Médias partagés", + "VIDEO_CALL": "Appel vidéo", + "AUDIO_CALL": "Appel audio", + "LOADING": "Chargement...", + "REPLY": "répondre", + "REPLIES": "réponses", + "LAUNCH": "Lancement", + "SHARED_COLLABORATIVE_DOCUMENT": "a partagé un document collaboratif", + "SHARED_COLLABORATIVE_WHITEBOARD": "a partagé un tableau blanc collaboratif", + "CREATED_WHITEBOARD": "Vous avez créé un nouveau tableau blanc collaboratif", + "CREATED_DOCUMENT": "Vous avez créé un nouveau document collaboratif", + "PHOTOS": "Photos", + "VIDEOS": "Vidéos", + "DOCUMENT": "Document", + "YOU_DELETED_THIS_MESSAGE": "⚠️ Vous avez supprimé ce message", + "THIS_MESSAGE_DELETED": "⚠️ Ce message a été supprimé", + "VIEW_ON_YOUTUBE": "Voir sur Youtube", + "SEARCH": "Rechercher", + "NO_USERS_FOUND": "Aucun utilisateur trouvé", + "ERROR": "Erreur", + "NO_GROUPS_FOUND": "Aucun groupe trouvé", + "NO_CHATS_FOUND": "Aucun chat trouvé", + "MEDIA_MESSAGE": "Message pour les médias", + "INCOMING_AUDIO_CALL": "Appel audio entrant", + "INCOMING_VIDEO_CALL": "Appel vidéo entrant", + "DECLINE": "Refuser", + "ACCEPT": "Accepter", + "CALL_INITIATED": "Appel lancé", + "OUTGOING_AUDIO_CALL": "Appel audio sortant", + "OUTGOING_VIDEO_CALL": "Appel vidéo sortant", + "CALL_REJECTED": "Appel rejeté", + "REJECTED_CALL": "appel rejeté", + "CALL_ACCEPTED": "Appel accepté", + "JOINED": "joint", + "LEFT_THE_CALL": "a quitté l'appel", + "UNANSWERED_AUDIO_CALL": "Appel audio sans réponse", + "UNANSWERED_VIDEO_CALL": "Appel vidéo sans réponse", + "CALL_ENDED": "Appel terminé", + "CALL_CANCELLED": "Appel annulé", + "CALL_BUSY": "Appeler occupé", + "CALLING": "Appeler...", + "ADD": "Ajouter", + "NO_BANNED_MEMBERS_FOUND": "Aucun membre interdit n'a été trouvé", + "BANNED_MEMBERS": "Membres interdits", + "NAME": "Nom", + "SCOPE": "Portée", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "Sélectionner le type de groupe", + "ENTER_GROUP_PASSWORD": "Saisir le mot de passe", + "CREATE": "Créer", + "CREATE_POLL": "Créer un sondage", + "QUESTION": "Question", + "ENTER_YOUR_QUESTION": "Saisissez votre question", + "OPTIONS": "Options", + "ENTER_YOUR_OPTION": "Saisissez votre option", + "ADD_NEW_OPTION": "Ajouter une nouvelle option", + "VIEW_MEMBERS": "Afficher les membres", + "DETAILS": "Détails", + "NOTIFICATIONS": "Notifications", + "OTHER": "Autres", + "HELP": "Aide", + "REPORT_PROBLEM": "Signaler un problème", + "GROUP_MEMBERS": "Membres du groupe", + "BAN": "Interdiction", + "KICK": "Coup de pied", + "PICK_YOUR_EMOJI": "Choisissez vos emoji", + "PRIVATE_GROUP": "Groupe privé", + "PROTECTED_GROUP": "Groupe protégé", + "VISIT": "Visitez", + "ATTACH": "Attacher", + "ATTACH_FILE": "Joindre le fichier", + "ATTACH_VIDEO": "Joindre une vidéo", + "ATTACH_AUDIO": "Attacher audio", + "ATTACH_IMAGE": "Joindre l'image", + "COLLABORATE_USING_DOCUMENT": "Collaborer à l'aide d'un document", + "COLLABORATE_USING_WHITEBOARD": "Collaborez à l'aide d'un tableau blanc", + "EMOJI": "Emoji", + "ENTER_YOUR_MESSAGE_HERE": "Entrez votre message ici", + "NO_MESSAGES_FOUND": "Aucun message trouvé", + "THREAD": "Fil", + "COLLABORATIVE_DOCUMENT": "Document collaboratif", + "COLLABORATIVE_WHITEBOARD": "Tableau blanc collaboratif", + "ADD_REACTION": "Ajouter une réaction", + "NO_STICKERS_FOUND": "Aucun autocollant trouvé", + "REPLY_TO_THREAD": "Répondre au fil", + "REPLY_IN_THREAD": "Répondre dans le thread", + "DELETE_MESSAGE": "Supprimer un message", + "EDIT_MESSAGE": "Modifier le message", + "SUNDAY": "DIMANCHE", + "MONDAY": "LUNDI", + "TUESDAY": "MARDI", + "WEDNESDAY": "MERCREDI", + "THURSDAY": "JEUDI", + "FRIDAY": "VENDREDI", + "SATURDAY": "SAMEDI", + "GROUP_NAME_BLANK": "Le nom du groupe ne peut pas être vide", + "GROUP_TYPE_BLANK": "Le type de groupe ne peut pas être vide", + "GROUP_PASSWORD_BLANK": "Le mot de passe du groupe ne peut pas être vide", + "POLL_QUESTION_BLANK": "La question ne peut pas être vide", + "POLL_OPTION_BLANK": "Option ne peut pas être vide", + "OWNER": "Propriétaire", + "CHANGE_SCOPE": "Modifier l'étendue", + "STICKER": "Autocollant", + "LAST_ACTIVE_AT": "Dernier actif à", + "VOICE_CALL": "Appel vocal", + "VIEW_DETAIL": "Afficher les détails", + "VOTES": "votes", + "VOTE": "vote", + "NO_VOTE": "Pas de vote", + "REACTED": "réagissait", + "ADDED": "ajoutée", + "UNBANNED": "non interdite", + "MADE": "confectionné", + "CALL_UNANSWERED": "Appel sans réponse", + "MISSED_AUDIO_CALL": "Appel audio manqué", + "ENTER_YOUR_PASSWORD": "Entrez votre mot de passe", + "DOCS": "Docs", + "NO_RECORDS_FOUND": "Aucun enregistrement trouvé", + "LIVE_REACTION": "Réaction en direct", + "SMILEY_PEOPLE": "Smileys & Personnes", + "ANIMALES_NATURE": "Animaux & Nature", + "FOOD_DRINK": "Nourriture et boissons", + "ACTIVITY": "Activité", + "TRAVEL_PLACES": "Voyages & Lieux", + "OBJECTS": "Objets", + "SYMBOLS": "Symboles", + "FLAGS": "Drapeaux", + "SENT": "Envoyé", + "SEEN": "Vu", + "DELIVERED": "Livré", + "CALLS": "Appels", + "CUSTOM_MESSAGE_LOCATION": "📍 Emplacement", + "OFFLINE": "Hors ligne", + "YOU": "Vous", + "PRIVACY": "Vie privée", + "BLOCKED_USERS": "Utilisateurs bloqués", + "YOU'VE_BLOCKED": "Vous avez bloqué", + "NO_PHOTOS": "Pas de photos", + "NO_VIDEOS": "Pas de vidéos", + "NO_DOCUMENTS": "Aucun document", + "JOIN": "Joii" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/hi/translation.json b/CometChat/resources/localization/locales/hi/translation.json new file mode 100644 index 00000000..1547ca62 --- /dev/null +++ b/CometChat/resources/localization/locales/hi/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "उपयोक्ता", + "CHATS": "चैट", + "GROUPS": "समूह", + "MORE": "अधिक", + "MESSAGE_IMAGE": "📷 छवि", + "MESSAGE_FILE": "📁 फ़ाइल", + "MESSAGE_VIDEO": "📹 वीडियो", + "MESSAGE_AUDIO": "🎵 ऑडियो", + "CUSTOM_MESSAGE": "आपके पास एक संदेश है", + "MISSED_VOICE_CALL": "मिस्ड वॉयस कॉल", + "MISSED_VIDEO_CALL": "मिस्ड वीडियो कॉल", + "CUSTOM_MESSAGE_POLL": "📊 पोल", + "CUSTOM_MESSAGE_STICKER": "💟 स्टीकर", + "CUSTOM_MESSAGE_DOCUMENT": "📃 दस्तावेज़", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 व्हाइटबोर्ड", + "ONLINE": "ऑनलाइन", + "ADMINISTRATOR": "प्रशासक", + "MODERATOR": "मॉडरेटर", + "PARTICIPANT": "प्रतिभागी", + "PUBLIC": "पब्लिक", + "PRIVATE": "निजी", + "PASSWORD_PROTECTED": "कूटशब्द सुरक्षित", + "PRIVACY_AND_SECURITY": "गोपनीयता और सुरक्षा", + "PREFERENCES": "प्राथमिकताएं", + "MEMBERS": "सदस्य", + "TODAY": "आज", + "YESTERDAY": "कल", + "TYPING": "टाइपिंग...", + "IS_TYPING": "टाइप कर रहा है...", + "CLOSE": "बंद करें", + "ENTER_GROUP_NAME": "समूह नाम भरें", + "ADD_MEMBERS": "सदस्य जोड़ें", + "SEND_MESSAGE": "संदेश भेजें", + "UNBLOCK_USER": "उपयोगकर्ता अनवरोधित करें", + "BLOCK_USER": "अवरोधित उपयोक्ता", + "DELETE_AND_EXIT": "मिटाएँ और बाहर निकलें", + "LEAVE_GROUP": "समूह छोड़ें", + "CREATE_GROUP": "समूह बनाएँ", + "SHARED_MEDIA": "साझा मीडिया", + "VIDEO_CALL": "वीडियो कॉल", + "AUDIO_CALL": "ऑडियो कॉल", + "LOADING": "लोड हो रहा है...", + "REPLY": "उत्तर", + "REPLIES": "उत्तर", + "LAUNCH": "लांच", + "SHARED_COLLABORATIVE_DOCUMENT": "ने एक सहयोगी दस्तावेज़ साझा किया है", + "SHARED_COLLABORATIVE_WHITEBOARD": "ने एक सहयोगी व्हाइटबोर्ड साझा किया है", + "CREATED_WHITEBOARD": "आपने एक नया सहयोगी व्हाइटबोर्ड बनाया है", + "CREATED_DOCUMENT": "आपने एक नया सहयोगी दस्तावेज़ बनाया है", + "PHOTOS": "तस्वीरें", + "VIDEOS": "वीडियो", + "DOCUMENT": "दस्तावेज़", + "YOU_DELETED_THIS_MESSAGE": "⚠️ आपने यह संदेश हटा दिया है", + "THIS_MESSAGE_DELETED": "⚠️ यह संदेश मिटाया गया था", + "VIEW_ON_YOUTUBE": "यूट्यूब पर देखें", + "SEARCH": "खोज", + "NO_USERS_FOUND": "कोई उपयोक्ता नहीं मिला", + "ERROR": "त्रुटि", + "NO_GROUPS_FOUND": "कोई समूह नहीं मिला", + "NO_CHATS_FOUND": "कोई चैट नहीं मिला", + "MEDIA_MESSAGE": "मीडिया संदेश", + "INCOMING_AUDIO_CALL": "आवक ऑडियो कॉल", + "INCOMING_VIDEO_CALL": "आने वाली वीडियो कॉल", + "DECLINE": "अस्वीकार", + "ACCEPT": "स्वीकार करें", + "CALL_INITIATED": "कॉल आरंभिक", + "OUTGOING_AUDIO_CALL": "जावक ऑडियो कॉल", + "OUTGOING_VIDEO_CALL": "जावक वीडियो कॉल", + "CALL_REJECTED": "कॉल अस्वीकृत", + "REJECTED_CALL": "अस्वीकृत कॉल", + "CALL_ACCEPTED": "कॉल स्वीकृत", + "JOINED": "शामिल हो गए", + "LEFT_THE_CALL": "कॉल छोड़ दिया", + "UNANSWERED_AUDIO_CALL": "अनुत्तरित ऑडियो कॉल", + "UNANSWERED_VIDEO_CALL": "अनुत्तरित वीडियो कॉल", + "CALL_ENDED": "कॉल समाप्त", + "CALL_CANCELLED": "कॉल रद्द", + "CALL_BUSY": "व्यस्त कॉल करें", + "CALLING": "कॉल कर रहा है...", + "ADD": "जोड़ें", + "NO_BANNED_MEMBERS_FOUND": "कोई प्रतिबंधित सदस्य नहीं मिला", + "BANNED_MEMBERS": "प्रतिबंधित सदस्य", + "NAME": "नाम", + "SCOPE": "स्कोप", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "समूह क़िस्म चुनें", + "ENTER_GROUP_PASSWORD": "समूह कूटशब्द भरें", + "CREATE": "बनाएँ", + "CREATE_POLL": "सर्वेक्षण बनाएँ", + "QUESTION": "प्रश्न", + "ENTER_YOUR_QUESTION": "अपना प्रश्न दर्ज करें", + "OPTIONS": "विकल्प", + "ENTER_YOUR_OPTION": "अपना विकल्प दर्ज करें", + "ADD_NEW_OPTION": "नया विकल्प जोड़ें", + "VIEW_MEMBERS": "सदस्य देखें", + "DETAILS": "विवरण", + "NOTIFICATIONS": "सूचनाएँ", + "OTHER": "अन्य", + "HELP": "मदद", + "REPORT_PROBLEM": "किसी समस्या की रिपोर्ट करें", + "GROUP_MEMBERS": "समूह के सदस्य", + "BAN": "बान", + "KICK": "लात", + "PICK_YOUR_EMOJI": "अपने इमोजी उठाओ", + "PRIVATE_GROUP": "निजी समूह", + "PROTECTED_GROUP": "सुरक्षित समूह", + "VISIT": "विज़िट करें", + "ATTACH": "संलग्न करें", + "ATTACH_FILE": "फ़ाइल संलग्न करें", + "ATTACH_VIDEO": "वीडियो संलग्न करें", + "ATTACH_AUDIO": "ऑडियो संलग्न करें", + "ATTACH_IMAGE": "छवि संलग्न करें", + "COLLABORATE_USING_DOCUMENT": "दस्तावेज़ का उपयोग करके सहयोग करें", + "COLLABORATE_USING_WHITEBOARD": "व्हाइटबोर्ड का उपयोग करके सहयोग करें", + "EMOJI": "इमोजी", + "ENTER_YOUR_MESSAGE_HERE": "अपना संदेश यहाँ दर्ज करें", + "NO_MESSAGES_FOUND": "कोई संदेश नहीं मिला", + "THREAD": "धागा", + "COLLABORATIVE_DOCUMENT": "सहयोगी दस्तावेज़", + "COLLABORATIVE_WHITEBOARD": "सहयोगी व्हाइटबोर्ड", + "ADD_REACTION": "प्रतिक्रिया जोड़ें", + "NO_STICKERS_FOUND": "कोई स्टिकर नहीं मिला", + "REPLY_TO_THREAD": "थ्रेड को जवाब दें", + "REPLY_IN_THREAD": "थ्रेड में जवाब दें", + "DELETE_MESSAGE": "संदेश मिटाएँ", + "EDIT_MESSAGE": "संदेश संपादित करें", + "SUNDAY": "रविवार", + "MONDAY": "सोमवार", + "TUESDAY": "मंगलवार", + "WEDNESDAY": "बुधवार", + "THURSDAY": "गुरुवार", + "FRIDAY": "शुक्रवार", + "SATURDAY": "शनिवार", + "GROUP_NAME_BLANK": "समूह का नाम खाली नहीं होना चाहिए", + "GROUP_TYPE_BLANK": "समूह प्रकार कैननॉट खाली हो", + "GROUP_PASSWORD_BLANK": "समूह कूटशब्द खाली नहीं होना चाहिए", + "POLL_QUESTION_BLANK": "प्रश्न कैनॉट खाली हो", + "POLL_OPTION_BLANK": "विकल्प कैननॉट खाली हो", + "OWNER": "मालिक", + "CHANGE_SCOPE": "स्कोप बदलें", + "STICKER": "स्टीकर", + "LAST_ACTIVE_AT": "पर अंतिम सक्रिय", + "VOICE_CALL": "वॉयस कॉल", + "VIEW_DETAIL": "विवरण देखें", + "VOTES": "वोट", + "VOTE": "वोट", + "NO_VOTE": "कोई वोट नहीं", + "REACTED": "प्रतिक्रिया व्यक्त की", + "ADDED": "जोड़ा गया", + "UNBANNED": "अप्रतिबंधित", + "MADE": "बनाया", + "CALL_UNANSWERED": "अनुत्तरित कॉल करें", + "MISSED_AUDIO_CALL": "मिस ऑडियो कॉल", + "ENTER_YOUR_PASSWORD": "अपना पासवर्ड दर्ज करें", + "DOCS": "डॉक्स", + "NO_RECORDS_FOUND": "कोई रिकॉर्ड नहीं मिला", + "LIVE_REACTION": "लाइव रिएक्शन", + "SMILEY_PEOPLE": "स्माइली और लोग", + "ANIMALES_NATURE": "पशु और प्रकृति", + "FOOD_DRINK": "खाद्य और पेय", + "ACTIVITY": "गतिविधि", + "TRAVEL_PLACES": "यात्रा और स्थान", + "OBJECTS": "वस्तुएँ", + "SYMBOLS": "प्रतीक", + "FLAGS": "झंडे", + "SENT": "भेजा गया", + "SEEN": "देखा", + "DELIVERED": "डिलीवर", + "CALLS": "कॉल", + "CUSTOM_MESSAGE_LOCATION": "📍 स्थान", + "OFFLINE": "ऑफ़लाइन", + "YOU": "आप", + "PRIVACY": "निजता", + "BLOCKED_USERS": "अवरोधित उपयोगकर्ता", + "YOU'VE_BLOCKED": "आपने अवरोधित किया है", + "NO_PHOTOS": "कोई तस्वीरें नहीं", + "NO_VIDEOS": "कोई वीडियो नहीं", + "NO_DOCUMENTS": "कोई दस्तावेज़ नहीं", + "JOIN": "जॉय" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/ms/translation.json b/CometChat/resources/localization/locales/ms/translation.json new file mode 100644 index 00000000..68b06229 --- /dev/null +++ b/CometChat/resources/localization/locales/ms/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "Pengguna", + "CHATS": "Sembang", + "GROUPS": "Kumpulan", + "MORE": "Lagi", + "MESSAGE_IMAGE": "📷 Imej", + "MESSAGE_FILE": "📁 Fail", + "MESSAGE_VIDEO": "📹 Video", + "MESSAGE_AUDIO": "🎵 Audio", + "CUSTOM_MESSAGE": "Anda mempunyai mesej", + "MISSED_VOICE_CALL": "Panggilan suara tidak dijawab", + "MISSED_VIDEO_CALL": "Panggilan video tidak dijawab", + "CUSTOM_MESSAGE_POLL": "📊 Undian", + "CUSTOM_MESSAGE_STICKER": "💟 Pelekat", + "CUSTOM_MESSAGE_DOCUMENT": "📃 Dokumen", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 Papan Putih", + "ONLINE": "Dalam Talian", + "ADMINISTRATOR": "Pentadbir", + "MODERATOR": "Moderator", + "PARTICIPANT": "Peserta", + "PUBLIC": "Awam", + "PRIVATE": "Persendirian", + "PASSWORD_PROTECTED": "Dilindungi", + "PRIVACY_AND_SECURITY": "Privasi dan Keselamatan", + "PREFERENCES": "Keutamaan", + "MEMBERS": "Ahli-ahli", + "TODAY": "Hari ini", + "YESTERDAY": "Semalam", + "TYPING": "menaip...", + "IS_TYPING": "sedang menaip...", + "CLOSE": "Tutup", + "ENTER_GROUP_NAME": "Masukkan nama kumpulan", + "ADD_MEMBERS": "Tambah Ahli", + "SEND_MESSAGE": "Hantar Mesej", + "UNBLOCK_USER": "Nyahsekat Pengguna", + "BLOCK_USER": "Sekat Pengguna", + "DELETE_AND_EXIT": "Padam dan Keluar", + "LEAVE_GROUP": "Tinggalkan Kumpulan", + "CREATE_GROUP": "Cipta Kumpulan", + "SHARED_MEDIA": "Media Kongsi", + "VIDEO_CALL": "Panggilan video", + "AUDIO_CALL": "Panggilan audio", + "LOADING": "Memuatkan...", + "REPLY": "jawapan", + "REPLIES": "balasannya", + "LAUNCH": "Pelancaran", + "SHARED_COLLABORATIVE_DOCUMENT": "telah berkongsi dokumen kolaboratif", + "SHARED_COLLABORATIVE_WHITEBOARD": "telah berkongsi papan putih kolaboratif", + "CREATED_WHITEBOARD": "Anda telah membuat papan putih kolaboratif baru", + "CREATED_DOCUMENT": "Anda telah membuat dokumen kolaboratif baru", + "PHOTOS": "Foto", + "VIDEOS": "Video", + "DOCUMENT": "Dokumen", + "YOU_DELETED_THIS_MESSAGE": "⚠️ Anda memadam mesej ini", + "THIS_MESSAGE_DELETED": "⚠️ Mesej ini telah dipadamkan", + "VIEW_ON_YOUTUBE": "Lihat di Youtube", + "SEARCH": "Cari", + "NO_USERS_FOUND": "Tiada pengguna ditemui", + "ERROR": "Ralat", + "NO_GROUPS_FOUND": "Tiada kumpulan ditemui", + "NO_CHATS_FOUND": "Tiada sembang ditemui", + "MEDIA_MESSAGE": "Mesej media", + "INCOMING_AUDIO_CALL": "Panggilan audio masuk", + "INCOMING_VIDEO_CALL": "Panggilan video masuk", + "DECLINE": "Tolak", + "ACCEPT": "Terima", + "CALL_INITIATED": "Panggilan dimulakan", + "OUTGOING_AUDIO_CALL": "Panggilan audio keluar", + "OUTGOING_VIDEO_CALL": "Panggilan video keluar", + "CALL_REJECTED": "Panggilan ditolak", + "REJECTED_CALL": "panggilan ditolak", + "CALL_ACCEPTED": "Panggilan diterima", + "JOINED": "menyertai", + "LEFT_THE_CALL": "meninggalkan panggilan", + "UNANSWERED_AUDIO_CALL": "Panggilan audio tidak dijawab", + "UNANSWERED_VIDEO_CALL": "Panggilan video tidak dijawab", + "CALL_ENDED": "Panggilan berakhir", + "CALL_CANCELLED": "Panggilan dibatalkan", + "CALL_BUSY": "Panggilan sibuk", + "CALLING": "Memanggil...", + "ADD": "Tambah", + "NO_BANNED_MEMBERS_FOUND": "Tiada ahli yang diharamkan ditemui", + "BANNED_MEMBERS": "Ahli diharamkan", + "NAME": "Nama", + "SCOPE": "Skop", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "Pilih jenis kumpulan", + "ENTER_GROUP_PASSWORD": "Masukkan kata laluan kumpulan", + "CREATE": "Cipta", + "CREATE_POLL": "Buat Undian", + "QUESTION": "Soalan", + "ENTER_YOUR_QUESTION": "Masukkan soalan anda", + "OPTIONS": "Pilihan", + "ENTER_YOUR_OPTION": "Masukkan pilihan anda", + "ADD_NEW_OPTION": "Tambah opsyen baru", + "VIEW_MEMBERS": "Lihat Ahli", + "DETAILS": "Perincian", + "NOTIFICATIONS": "Pemberitahuan", + "OTHER": "Lain-lain", + "HELP": "Bantuan", + "REPORT_PROBLEM": "Laporkan Masalah", + "GROUP_MEMBERS": "Ahli Kumpulan", + "BAN": "Ban", + "KICK": "Kick", + "PICK_YOUR_EMOJI": "Pilih emoji anda", + "PRIVATE_GROUP": "Kumpulan Persendirian", + "PROTECTED_GROUP": "Kumpulan Terlindung", + "VISIT": "Lawati", + "ATTACH": "Lampirkan", + "ATTACH_FILE": "Lampirkan fail", + "ATTACH_VIDEO": "Lampirkan video", + "ATTACH_AUDIO": "Lampirkan audio", + "ATTACH_IMAGE": "Lampirkan imej", + "COLLABORATE_USING_DOCUMENT": "Berkolaborasi menggunakan dokumen", + "COLLABORATE_USING_WHITEBOARD": "Berkolaborasi menggunakan papan putih", + "EMOJI": "Emotikon", + "ENTER_YOUR_MESSAGE_HERE": "Masukkan mesej anda di sini", + "NO_MESSAGES_FOUND": "Tiada mesej ditemui", + "THREAD": "Thread", + "COLLABORATIVE_DOCUMENT": "Dokumen Kerjasama", + "COLLABORATIVE_WHITEBOARD": "Papan Putih Kolaboratif", + "ADD_REACTION": "Tambah reaksi", + "NO_STICKERS_FOUND": "Tiada pelekat ditemui", + "REPLY_TO_THREAD": "Balas kepada bebenang", + "REPLY_IN_THREAD": "Balas dalam bebenang", + "DELETE_MESSAGE": "Padam mesej", + "EDIT_MESSAGE": "Sunting mesej", + "SUNDAY": "AHAD", + "MONDAY": "ISNIN", + "TUESDAY": "SELASA", + "WEDNESDAY": "RABU", + "THURSDAY": "KHAMIS", + "FRIDAY": "JUMAAT", + "SATURDAY": "SABTU", + "GROUP_NAME_BLANK": "Nama kumpulan tidak boleh kosong", + "GROUP_TYPE_BLANK": "Jenis kumpulan meriam tidak kosong", + "GROUP_PASSWORD_BLANK": "Kata laluan kumpulan tidak boleh kosong", + "POLL_QUESTION_BLANK": "Soalan meriam tidak kosong", + "POLL_OPTION_BLANK": "Opsyen meriam tidak kosong", + "OWNER": "Pemilik", + "CHANGE_SCOPE": "Tukar Skop", + "STICKER": "Pelekat", + "LAST_ACTIVE_AT": "Terakhir Aktif di", + "VOICE_CALL": "Panggilan suara", + "VIEW_DETAIL": "Lihat Perincian", + "VOTES": "undi", + "VOTE": "undi", + "NO_VOTE": "Tiada undi", + "REACTED": "bertindak balas", + "ADDED": "campurkan", + "UNBANNED": "tidak diharamkan", + "MADE": "diperbuat", + "CALL_UNANSWERED": "Panggilan tidak dijawab", + "MISSED_AUDIO_CALL": "Panggilan audio tidak dijawab", + "ENTER_YOUR_PASSWORD": "Masukkan kata laluan anda", + "DOCS": "Dokumen", + "NO_RECORDS_FOUND": "Tiada rekod ditemui", + "LIVE_REACTION": "Reaksi Langsung", + "SMILEY_PEOPLE": "Smiley & People", + "ANIMALES_NATURE": "Haiwan & Alam Semula Jadi", + "FOOD_DRINK": "Makanan & Minuman", + "ACTIVITY": "Aktiviti", + "TRAVEL_PLACES": "Perjalanan & Tempat", + "OBJECTS": "Objek", + "SYMBOLS": "Simbol", + "FLAGS": "Bendera", + "SENT": "Dihantar", + "SEEN": "Seen", + "DELIVERED": "Dihantar", + "CALLS": "Panggilan", + "CUSTOM_MESSAGE_LOCATION": "📍 Lokasi", + "OFFLINE": "Luar Talian", + "YOU": "Anda", + "PRIVACY": "Privasi", + "BLOCKED_USERS": "Pengguna Dihalang", + "YOU'VE_BLOCKED": "Anda telah menyekat", + "NO_PHOTOS": "Tiada Foto", + "NO_VIDEOS": "Tiada Video", + "NO_DOCUMENTS": "Tiada Dokumen", + "JOIN": "Joi" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/pt/translation.json b/CometChat/resources/localization/locales/pt/translation.json new file mode 100644 index 00000000..becfa110 --- /dev/null +++ b/CometChat/resources/localization/locales/pt/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "Usuários", + "CHATS": "Bate-papo", + "GROUPS": "Grupos", + "MORE": "Mais", + "MESSAGE_IMAGE": "📷 Imagem", + "MESSAGE_FILE": "📁 Arquivo", + "MESSAGE_VIDEO": "📹 Vídeo", + "MESSAGE_AUDIO": "🎵 Áudio", + "CUSTOM_MESSAGE": "Você tem uma mensagem", + "MISSED_VOICE_CALL": "Chamada de voz perdida", + "MISSED_VIDEO_CALL": "Chamada de vídeo perdida", + "CUSTOM_MESSAGE_POLL": "📊 Enquete", + "CUSTOM_MESSAGE_STICKER": "💟 Adesivo", + "CUSTOM_MESSAGE_DOCUMENT": "📃 Documento", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 quadro branco", + "ONLINE": "On-line", + "ADMINISTRATOR": "Administrador", + "MODERATOR": "Moderador", + "PARTICIPANT": "Participante", + "PUBLIC": "Público", + "PRIVATE": "Privado", + "PASSWORD_PROTECTED": "Protegido por senha", + "PRIVACY_AND_SECURITY": "Privacidade e Segurança", + "PREFERENCES": "Preferências", + "MEMBERS": "Membros", + "TODAY": "Hoje", + "YESTERDAY": "Ontem", + "TYPING": "digitando...", + "IS_TYPING": "está digitando...", + "CLOSE": "Fechar", + "ENTER_GROUP_NAME": "Digite o nome do grupo", + "ADD_MEMBERS": "Adicionar Membros", + "SEND_MESSAGE": "Enviar Mensagem", + "UNBLOCK_USER": "Desbloquear Usuário", + "BLOCK_USER": "Bloquear usuário", + "DELETE_AND_EXIT": "Excluir e sair", + "LEAVE_GROUP": "Sair do grupo", + "CREATE_GROUP": "Criar grupo", + "SHARED_MEDIA": "Mídia compartilhada", + "VIDEO_CALL": "Chamada de vídeo", + "AUDIO_CALL": "Chamada de áudio", + "LOADING": "Carregando...", + "REPLY": "resposta", + "REPLIES": "respostas", + "LAUNCH": "Lançamento", + "SHARED_COLLABORATIVE_DOCUMENT": "compartilhou um documento colaborativo", + "SHARED_COLLABORATIVE_WHITEBOARD": "compartilhou um quadro de comunicações colaborativo", + "CREATED_WHITEBOARD": "Você criou um novo quadro de comunicações colaborativo", + "CREATED_DOCUMENT": "Você criou um novo documento colaborativo", + "PHOTOS": "Fotos", + "VIDEOS": "Vídeos", + "DOCUMENT": "Documento", + "YOU_DELETED_THIS_MESSAGE": "⚠️ Você excluiu esta mensagem", + "THIS_MESSAGE_DELETED": "⚠️ Esta mensagem foi excluída", + "VIEW_ON_YOUTUBE": "Ver no Youtube", + "SEARCH": "Pesquisar", + "NO_USERS_FOUND": "Nenhum usuário encontrado", + "ERROR": "Erro", + "NO_GROUPS_FOUND": "Nenhum grupo encontrado", + "NO_CHATS_FOUND": "Não foram encontrados chats", + "MEDIA_MESSAGE": "Mensagem de mídia", + "INCOMING_AUDIO_CALL": "Chamada de áudio recebida", + "INCOMING_VIDEO_CALL": "Chamada de vídeo recebida", + "DECLINE": "Declínio", + "ACCEPT": "Aceitar", + "CALL_INITIATED": "Chamada iniciada", + "OUTGOING_AUDIO_CALL": "Chamada de áudio de saída", + "OUTGOING_VIDEO_CALL": "Chamada de vídeo de saída", + "CALL_REJECTED": "Chamada rejeitada", + "REJECTED_CALL": "chamada rejeitada", + "CALL_ACCEPTED": "Chamada aceita", + "JOINED": "ingressou", + "LEFT_THE_CALL": "deixou a chamada", + "UNANSWERED_AUDIO_CALL": "Chamada de áudio sem resposta", + "UNANSWERED_VIDEO_CALL": "Chamada de vídeo sem resposta", + "CALL_ENDED": "Chamada encerrada", + "CALL_CANCELLED": "Chamada cancelada", + "CALL_BUSY": "Ligue ocupado", + "CALLING": "Chamando...", + "ADD": "Adicionar", + "NO_BANNED_MEMBERS_FOUND": "Não foram encontrados membros proibidos", + "BANNED_MEMBERS": "Membros Banidos", + "NAME": "Nome", + "SCOPE": "Âmbito", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "Selecionar tipo de grupo", + "ENTER_GROUP_PASSWORD": "Digite a senha do grupo", + "CREATE": "Criar", + "CREATE_POLL": "Criar enquete", + "QUESTION": "Pergunta", + "ENTER_YOUR_QUESTION": "Insira sua pergunta", + "OPTIONS": "Opções", + "ENTER_YOUR_OPTION": "Introduza a sua opção", + "ADD_NEW_OPTION": "Adicionar nova opção", + "VIEW_MEMBERS": "Ver Membros", + "DETAILS": "Detalhes", + "NOTIFICATIONS": "Notificações", + "OTHER": "Outros", + "HELP": "Ajuda", + "REPORT_PROBLEM": "Denunciar um problema", + "GROUP_MEMBERS": "Membros do Grupo", + "BAN": "Proibição", + "KICK": "Chute", + "PICK_YOUR_EMOJI": "Escolha o seu emoji", + "PRIVATE_GROUP": "Grupo Privado", + "PROTECTED_GROUP": "Grupo protegido", + "VISIT": "Visitar", + "ATTACH": "Anexar", + "ATTACH_FILE": "Anexar arquivo", + "ATTACH_VIDEO": "Anexar vídeo", + "ATTACH_AUDIO": "Anexar áudio", + "ATTACH_IMAGE": "Anexar imagem", + "COLLABORATE_USING_DOCUMENT": "Colaborar usando um documento", + "COLLABORATE_USING_WHITEBOARD": "Colaborar usando um quadro branco", + "EMOJI": "Emoji", + "ENTER_YOUR_MESSAGE_HERE": "Introduza aqui a sua mensagem", + "NO_MESSAGES_FOUND": "Nenhuma mensagem encontrada", + "THREAD": "Rosca", + "COLLABORATIVE_DOCUMENT": "Documento Colaborativo", + "COLLABORATIVE_WHITEBOARD": "Quadro Colaborativo", + "ADD_REACTION": "Adicionar reação", + "NO_STICKERS_FOUND": "Não foram encontrados adesivos", + "REPLY_TO_THREAD": "Responder ao thread", + "REPLY_IN_THREAD": "Responder no tópico", + "DELETE_MESSAGE": "Excluir mensagem", + "EDIT_MESSAGE": "Editar mensagem", + "SUNDAY": "DOMINGO", + "MONDAY": "SEGUNDA-FEIRA", + "TUESDAY": "TERÇA-FEIRA", + "WEDNESDAY": "QUARTA-FEIRA", + "THURSDAY": "QUINTA-FEIRA", + "FRIDAY": "SEXTA-FEIRA", + "SATURDAY": "SÁBADO", + "GROUP_NAME_BLANK": "O nome do grupo não pode estar em branco", + "GROUP_TYPE_BLANK": "Tipo de grupo não pode estar em branco", + "GROUP_PASSWORD_BLANK": "A senha do grupo não pode estar em branco", + "POLL_QUESTION_BLANK": "Pergunta não pode ser em branco", + "POLL_OPTION_BLANK": "Opção não estar em branco", + "OWNER": "Proprietário", + "CHANGE_SCOPE": "Alterar escopo", + "STICKER": "Adesivo", + "LAST_ACTIVE_AT": "Último ativo em", + "VOICE_CALL": "Chamada de voz", + "VIEW_DETAIL": "Ver detalhes", + "VOTES": "vota", + "VOTE": "votar", + "NO_VOTE": "Sem votação", + "REACTED": "reagiu", + "ADDED": "adicionada", + "UNBANNED": "não banido", + "MADE": "fez", + "CALL_UNANSWERED": "Chamada sem resposta", + "MISSED_AUDIO_CALL": "Chamada de áudio perdida", + "ENTER_YOUR_PASSWORD": "Digite sua senha", + "DOCS": "Documentos", + "NO_RECORDS_FOUND": "Nenhum registro encontrado", + "LIVE_REACTION": "Reação ao vivo", + "SMILEY_PEOPLE": "Smileys & Pessoas", + "ANIMALES_NATURE": "Animais & Natureza", + "FOOD_DRINK": "Comidas & Bebidas", + "ACTIVITY": "Atividade", + "TRAVEL_PLACES": "Viagens e lugares", + "OBJECTS": "Objetos", + "SYMBOLS": "Símbolos", + "FLAGS": "Bandeiras", + "SENT": "Enviado", + "SEEN": "Visto", + "DELIVERED": "Entregue", + "CALLS": "Chamadas", + "CUSTOM_MESSAGE_LOCATION": "📍 Localização", + "OFFLINE": "Offline", + "YOU": "Você", + "PRIVACY": "Privacidade", + "BLOCKED_USERS": "Usuários bloqueados", + "YOU'VE_BLOCKED": "Você bloqueou", + "NO_PHOTOS": "Sem Fotos", + "NO_VIDEOS": "Sem vídeos", + "NO_DOCUMENTS": "Sem Documentos", + "JOIN": "Joi" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/ru/translation.json b/CometChat/resources/localization/locales/ru/translation.json new file mode 100644 index 00000000..b5cd943e --- /dev/null +++ b/CometChat/resources/localization/locales/ru/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "Пользователи", + "CHATS": "Чаты", + "GROUPS": "Группы", + "MORE": "Больше", + "MESSAGE_IMAGE": "📷 Изображение", + "MESSAGE_FILE": "📁 Файл", + "MESSAGE_VIDEO": "📹 Видео", + "MESSAGE_AUDIO": "🎵 Аудио", + "CUSTOM_MESSAGE": "У вас есть сообщение", + "MISSED_VOICE_CALL": "Пропущенный голосовой вызов", + "MISSED_VIDEO_CALL": "Пропущенный видеозвонок", + "CUSTOM_MESSAGE_POLL": "📊 Опрос", + "CUSTOM_MESSAGE_STICKER": "💟 наклейка", + "CUSTOM_MESSAGE_DOCUMENT": "📃 Документ", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 Белая доска", + "ONLINE": "Онлайн", + "ADMINISTRATOR": "Администратор", + "MODERATOR": "Модератор", + "PARTICIPANT": "Участник", + "PUBLIC": "Публичный", + "PRIVATE": "Частные", + "PASSWORD_PROTECTED": "Защищен паролем", + "PRIVACY_AND_SECURITY": "Конфиденциальность и безопасность", + "PREFERENCES": "Предпочтения", + "MEMBERS": "Члены", + "TODAY": "Сегодня", + "YESTERDAY": "Вчера", + "TYPING": "набрав...", + "IS_TYPING": "набирает...", + "CLOSE": "Закрыть", + "ENTER_GROUP_NAME": "Введите имя группы", + "ADD_MEMBERS": "Добавить участников", + "SEND_MESSAGE": "Отправить сообщение", + "UNBLOCK_USER": "Разблокировать пользователя", + "BLOCK_USER": "Блокировать пользователя", + "DELETE_AND_EXIT": "Удаление и выход", + "LEAVE_GROUP": "Выйти из группы", + "CREATE_GROUP": "Создать группу", + "SHARED_MEDIA": "Общий носитель", + "VIDEO_CALL": "Видеозвонок", + "AUDIO_CALL": "Аудио вызов", + "LOADING": "Загрузка...", + "REPLY": "Ответить", + "REPLIES": "ответы", + "LAUNCH": "Запустить", + "SHARED_COLLABORATIVE_DOCUMENT": "опубликовал совместный документ", + "SHARED_COLLABORATIVE_WHITEBOARD": "поделился совместной доске", + "CREATED_WHITEBOARD": "Вы создали новую доску для совместной работы", + "CREATED_DOCUMENT": "Вы создали новый документ для совместной работы", + "PHOTOS": "Фотографии", + "VIDEOS": "Видео", + "DOCUMENT": "Документ", + "YOU_DELETED_THIS_MESSAGE": "⚠️ Вы удалили это сообщение", + "THIS_MESSAGE_DELETED": "⚠️ Это сообщение было удалено", + "VIEW_ON_YOUTUBE": "Посмотреть на Youtube", + "SEARCH": "Поиск", + "NO_USERS_FOUND": "Пользователи не найдены", + "ERROR": "Ошибка", + "NO_GROUPS_FOUND": "Группы не найдены", + "NO_CHATS_FOUND": "Чаты не найдены", + "MEDIA_MESSAGE": "Сообщение мультимедиа", + "INCOMING_AUDIO_CALL": "Входящий аудиовызов", + "INCOMING_VIDEO_CALL": "Входящий видеозвонок", + "DECLINE": "Отклонить", + "ACCEPT": "Принять", + "CALL_INITIATED": "Вызов инициирован", + "OUTGOING_AUDIO_CALL": "Исходящий аудиовызов", + "OUTGOING_VIDEO_CALL": "Исходящий видеозвонок", + "CALL_REJECTED": "Вызов отклонен", + "REJECTED_CALL": "отклоненный вызов", + "CALL_ACCEPTED": "Звонок принят", + "JOINED": "совместный", + "LEFT_THE_CALL": "оставил вызов", + "UNANSWERED_AUDIO_CALL": "Звуковой звонок без ответа", + "UNANSWERED_VIDEO_CALL": "Видеозвонок без ответа", + "CALL_ENDED": "Вызов завершен", + "CALL_CANCELLED": "Звонок отменен", + "CALL_BUSY": "Звонок занят", + "CALLING": "Звоню...", + "ADD": "Добавить", + "NO_BANNED_MEMBERS_FOUND": "Запрещенные участники не найдены", + "BANNED_MEMBERS": "Запрещенные участники", + "NAME": "Имя", + "SCOPE": "Область применения", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "Выберите тип группы", + "ENTER_GROUP_PASSWORD": "Введите пароль группы", + "CREATE": "Создать", + "CREATE_POLL": "Создать опрос", + "QUESTION": "Вопрос", + "ENTER_YOUR_QUESTION": "Введите свой вопрос", + "OPTIONS": "Опции", + "ENTER_YOUR_OPTION": "Введите свой вариант", + "ADD_NEW_OPTION": "Добавить новую опцию", + "VIEW_MEMBERS": "Просмотр участников", + "DETAILS": "Подробности", + "NOTIFICATIONS": "Уведомления", + "OTHER": "Прочее", + "HELP": "Помощь", + "REPORT_PROBLEM": "Сообщить о проблеме", + "GROUP_MEMBERS": "Члены группы", + "BAN": "Запрет", + "KICK": "Удар", + "PICK_YOUR_EMOJI": "Выберите свой эмодзи", + "PRIVATE_GROUP": "Частная группа", + "PROTECTED_GROUP": "Защищенная группа", + "VISIT": "Посетить", + "ATTACH": "Прикрепить", + "ATTACH_FILE": "Прикрепить файл", + "ATTACH_VIDEO": "Прикрепить видео", + "ATTACH_AUDIO": "Прикрепить аудио", + "ATTACH_IMAGE": "Прикрепить изображение", + "COLLABORATE_USING_DOCUMENT": "Совместная работа с использованием документа", + "COLLABORATE_USING_WHITEBOARD": "Совместная работа с помощью доски", + "EMOJI": "смайлик", + "ENTER_YOUR_MESSAGE_HERE": "Введите свое сообщение здесь", + "NO_MESSAGES_FOUND": "Сообщения не найдены", + "THREAD": "Нить", + "COLLABORATIVE_DOCUMENT": "Совместный документ", + "COLLABORATIVE_WHITEBOARD": "Совместная доска", + "ADD_REACTION": "Добавить реакцию", + "NO_STICKERS_FOUND": "Стикеры не найдены", + "REPLY_TO_THREAD": "Ответить на тему", + "REPLY_IN_THREAD": "Ответ в потоке", + "DELETE_MESSAGE": "Удалить сообщение", + "EDIT_MESSAGE": "Редактировать сообщение", + "SUNDAY": "ВОСКРЕСЕНЬЕ", + "MONDAY": "ПОНЕДЕЛЬНИК", + "TUESDAY": "ВТОРНИК", + "WEDNESDAY": "СРЕДА", + "THURSDAY": "ЧЕТВЕРГ", + "FRIDAY": "ПЯТНИЦА", + "SATURDAY": "СУББОТА", + "GROUP_NAME_BLANK": "Имя группы не может быть пустым", + "GROUP_TYPE_BLANK": "Тип группы не может быть пустым", + "GROUP_PASSWORD_BLANK": "Пароль группы не может быть пустым", + "POLL_QUESTION_BLANK": "Вопрос не может быть пустым", + "POLL_OPTION_BLANK": "Опция не может быть пустой", + "OWNER": "Владелец", + "CHANGE_SCOPE": "Изменить область", + "STICKER": "Наклейка", + "LAST_ACTIVE_AT": "Последний активный в", + "VOICE_CALL": "Голосовой вызов", + "VIEW_DETAIL": "Посмотреть деталь", + "VOTES": "голосов", + "VOTE": "голосования", + "NO_VOTE": "Нет голоса", + "REACTED": "отреагировал", + "ADDED": "добавил", + "UNBANNED": "незапрещенный", + "MADE": "сделал", + "CALL_UNANSWERED": "Звоните без ответа", + "MISSED_AUDIO_CALL": "Пропущенный аудиовызов", + "ENTER_YOUR_PASSWORD": "Введите пароль", + "DOCS": "Документы", + "NO_RECORDS_FOUND": "Записи не найдены", + "LIVE_REACTION": "Живая реакция", + "SMILEY_PEOPLE": "Смайлики и люди", + "ANIMALES_NATURE": "Животные и природа", + "FOOD_DRINK": "Еда и напитки", + "ACTIVITY": "Деятельность", + "TRAVEL_PLACES": "Путешествия и места", + "OBJECTS": "Объекты", + "SYMBOLS": "Символы", + "FLAGS": "Флаги", + "SENT": "Отправлено", + "SEEN": "Видел", + "DELIVERED": "Доставлено", + "CALLS": "Звонки", + "CUSTOM_MESSAGE_LOCATION": "📍 Расположение", + "OFFLINE": "Оффлайн", + "YOU": "Ты", + "PRIVACY": "Privacy", + "BLOCKED_USERS": "Заблокированные пользователи", + "YOU'VE_BLOCKED": "Вы заблокировали", + "NO_PHOTOS": "Нет фотографий", + "NO_VIDEOS": "Нет видео", + "NO_DOCUMENTS": "Нет документов", + "JOIN": "Joi" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/zh-tw/translation.json b/CometChat/resources/localization/locales/zh-tw/translation.json new file mode 100644 index 00000000..835d2a69 --- /dev/null +++ b/CometChat/resources/localization/locales/zh-tw/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "使用者", + "CHATS": "聊天", + "GROUPS": "群組", + "MORE": "更多", + "MESSAGE_IMAGE": "📷 圖片", + "MESSAGE_FILE": "📁 檔案", + "MESSAGE_VIDEO": "📹 影片", + "MESSAGE_AUDIO": "🎵 音訊", + "CUSTOM_MESSAGE": "你有一個訊息", + "MISSED_VOICE_CALL": "未接語音通話", + "MISSED_VIDEO_CALL": "未接視訊通話", + "CUSTOM_MESSAGE_POLL": "📊 投票", + "CUSTOM_MESSAGE_STICKER": "💟 貼紙", + "CUSTOM_MESSAGE_DOCUMENT": "📃 文件", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 白板", + "ONLINE": "線上", + "ADMINISTRATOR": "管理員", + "MODERATOR": "主持人", + "PARTICIPANT": "參與者", + "PUBLIC": "公共", + "PRIVATE": "私人", + "PASSWORD_PROTECTED": "密碼保護", + "PRIVACY_AND_SECURITY": "隱私權與安全性", + "PREFERENCES": "偏好設定", + "MEMBERS": "成員", + "TODAY": "今天", + "YESTERDAY": "昨天", + "TYPING": "輸入...", + "IS_TYPING": "正在輸入...", + "CLOSE": "關閉", + "ENTER_GROUP_NAME": "輸入群組名稱", + "ADD_MEMBERS": "加入成員", + "SEND_MESSAGE": "傳送訊息", + "UNBLOCK_USER": "解除封鎖使用者", + "BLOCK_USER": "封鎖使用者", + "DELETE_AND_EXIT": "刪除並結束", + "LEAVE_GROUP": "離開群組", + "CREATE_GROUP": "建立群組", + "SHARED_MEDIA": "共用媒體", + "VIDEO_CALL": "視訊通話", + "AUDIO_CALL": "音訊通話", + "LOADING": "正在載入中...", + "REPLY": "回覆", + "REPLIES": "回覆", + "LAUNCH": "啟動", + "SHARED_COLLABORATIVE_DOCUMENT": "已共用協同合作文件", + "SHARED_COLLABORATIVE_WHITEBOARD": "共享了一個合作白板", + "CREATED_WHITEBOARD": "您已建立新的協同合作白板", + "CREATED_DOCUMENT": "您已建立新的協同合作文件", + "PHOTOS": "相片", + "VIDEOS": "影片", + "DOCUMENT": "文件", + "YOU_DELETED_THIS_MESSAGE": "⚠️ 您刪除了此訊息", + "THIS_MESSAGE_DELETED": "⚠️ 此訊息已被刪除", + "VIEW_ON_YOUTUBE": "在 YouTube 上觀看", + "SEARCH": "搜尋", + "NO_USERS_FOUND": "找不到使用者", + "ERROR": "錯誤", + "NO_GROUPS_FOUND": "找不到群組", + "NO_CHATS_FOUND": "找不到對話", + "MEDIA_MESSAGE": "媒體訊息", + "INCOMING_AUDIO_CALL": "來電音訊通話", + "INCOMING_VIDEO_CALL": "來電視訊通話", + "DECLINE": "拒絕", + "ACCEPT": "接受", + "CALL_INITIATED": "呼叫已啟動", + "OUTGOING_AUDIO_CALL": "撥出音訊通話", + "OUTGOING_VIDEO_CALL": "撥出視訊通話", + "CALL_REJECTED": "電話拒絕", + "REJECTED_CALL": "拒絕的呼叫", + "CALL_ACCEPTED": "已接聽電話", + "JOINED": "加入", + "LEFT_THE_CALL": "留下電話", + "UNANSWERED_AUDIO_CALL": "未接聽的音訊通話", + "UNANSWERED_VIDEO_CALL": "未接聽視訊通話", + "CALL_ENDED": "呼叫結束", + "CALL_CANCELLED": "來電已取消", + "CALL_BUSY": "呼叫忙碌", + "CALLING": "呼叫...", + "ADD": "新增", + "NO_BANNED_MEMBERS_FOUND": "找不到被禁用的會員", + "BANNED_MEMBERS": "禁止的會員", + "NAME": "名稱", + "SCOPE": "範圍", + "UNBAN": "取消禁止", + "SELECT_GROUP_TYPE": "選取群組類型", + "ENTER_GROUP_PASSWORD": "輸入群組密碼", + "CREATE": "建立", + "CREATE_POLL": "建立投票", + "QUESTION": "問題", + "ENTER_YOUR_QUESTION": "輸入您的問題", + "OPTIONS": "選項", + "ENTER_YOUR_OPTION": "輸入您的選項", + "ADD_NEW_OPTION": "新增選項", + "VIEW_MEMBERS": "檢視成員", + "DETAILS": "詳細資料", + "NOTIFICATIONS": "通知", + "OTHER": "其他", + "HELP": "說明", + "REPORT_PROBLEM": "報告問題", + "GROUP_MEMBERS": "群組成員", + "BAN": "禁令", + "KICK": "踢", + "PICK_YOUR_EMOJI": "挑選您的表情符號", + "PRIVATE_GROUP": "私人群組", + "PROTECTED_GROUP": "受保護群組", + "VISIT": "造訪", + "ATTACH": "貼附", + "ATTACH_FILE": "附加檔案", + "ATTACH_VIDEO": "附加視訊", + "ATTACH_AUDIO": "附加音訊", + "ATTACH_IMAGE": "貼附影像", + "COLLABORATE_USING_DOCUMENT": "使用文件共同作業", + "COLLABORATE_USING_WHITEBOARD": "使用白板進行協同作業", + "EMOJI": "表情符號", + "ENTER_YOUR_MESSAGE_HERE": "在此輸入您的訊息", + "NO_MESSAGES_FOUND": "找不到訊息", + "THREAD": "螺紋", + "COLLABORATIVE_DOCUMENT": "協同合作文件", + "COLLABORATIVE_WHITEBOARD": "協同合作白板", + "ADD_REACTION": "加入反應", + "NO_STICKERS_FOUND": "找不到貼圖", + "REPLY_TO_THREAD": "回覆執行緒", + "REPLY_IN_THREAD": "在執行緒中回覆", + "DELETE_MESSAGE": "刪除訊息", + "EDIT_MESSAGE": "編輯訊息", + "SUNDAY": "星期日", + "MONDAY": "星期一", + "TUESDAY": "星期二", + "WEDNESDAY": "星期三", + "THURSDAY": "星期四", + "FRIDAY": "星期五", + "SATURDAY": "星期六", + "GROUP_NAME_BLANK": "群組名稱不能為空白", + "GROUP_TYPE_BLANK": "群組類型不能為空白", + "GROUP_PASSWORD_BLANK": "群組密碼不能為空白", + "POLL_QUESTION_BLANK": "問題不能為空白", + "POLL_OPTION_BLANK": "選項不能為空白", + "OWNER": "擁有者", + "CHANGE_SCOPE": "變更範圍", + "STICKER": "貼紙", + "LAST_ACTIVE_AT": "上次作用中日期", + "VOICE_CALL": "語音通話", + "VIEW_DETAIL": "檢視詳細資料", + "VOTES": "票", + "VOTE": "投票", + "NO_VOTE": "沒有投票", + "REACTED": "反應", + "ADDED": "添加", + "UNBANNED": "取消禁止", + "MADE": "製作", + "CALL_UNANSWERED": "未接聽來電", + "MISSED_AUDIO_CALL": "未接的音訊通話", + "ENTER_YOUR_PASSWORD": "輸入您的密碼", + "DOCS": "文件", + "NO_RECORDS_FOUND": "找不到記錄", + "LIVE_REACTION": "即時反應", + "SMILEY_PEOPLE": "笑臉與人", + "ANIMALES_NATURE": "動物與自然", + "FOOD_DRINK": "食物與飲料", + "ACTIVITY": "活動", + "TRAVEL_PLACES": "旅遊與地點", + "OBJECTS": "物件", + "SYMBOLS": "符號", + "FLAGS": "旗標", + "SENT": "已送出", + "SEEN": "見過", + "DELIVERED": "已遞送", + "CALLS": "呼叫", + "CUSTOM_MESSAGE_LOCATION": "📍 位置", + "OFFLINE": "離線", + "YOU": "你", + "PRIVACY": "隱私", + "BLOCKED_USERS": "封鎖的使用者", + "YOU'VE_BLOCKED": "您已封鎖", + "NO_PHOTOS": "沒有相片", + "NO_VIDEOS": "沒有視訊", + "NO_DOCUMENTS": "沒有文件", + "JOIN": "喬伊" +} \ No newline at end of file diff --git a/CometChat/resources/localization/locales/zh/translation.json b/CometChat/resources/localization/locales/zh/translation.json new file mode 100644 index 00000000..618c4875 --- /dev/null +++ b/CometChat/resources/localization/locales/zh/translation.json @@ -0,0 +1,181 @@ +{ + "USERS": "用户", + "CHATS": "聊天", + "GROUPS": "团体", + "MORE": "更多", + "MESSAGE_IMAGE": "📷 图片", + "MESSAGE_FILE": "📁 文件", + "MESSAGE_VIDEO": "📹 视频", + "MESSAGE_AUDIO": "🎵 音频", + "CUSTOM_MESSAGE": "你有消息", + "MISSED_VOICE_CALL": "未接的语音通话", + "MISSED_VIDEO_CALL": "错过视频通话", + "CUSTOM_MESSAGE_POLL": "📊 民意调查", + "CUSTOM_MESSAGE_STICKER": "💟 贴纸", + "CUSTOM_MESSAGE_DOCUMENT": "📃 文档", + "CUSTOM_MESSAGE_WHITEBOARD": "📝 白板", + "ONLINE": "在线", + "ADMINISTRATOR": "管理员", + "MODERATOR": "主持人", + "PARTICIPANT": "参与者", + "PUBLIC": "公开", + "PRIVATE": "私人", + "PASSWORD_PROTECTED": "密码保护", + "PRIVACY_AND_SECURITY": "隐私和安全", + "PREFERENCES": "偏好", + "MEMBERS": "会员", + "TODAY": "今天", + "YESTERDAY": "昨天", + "TYPING": "打字...", + "IS_TYPING": "正在打字...", + "CLOSE": "关闭", + "ENTER_GROUP_NAME": "输入组名", + "ADD_MEMBERS": "添加成员", + "SEND_MESSAGE": "发送消息", + "UNBLOCK_USER": "解锁用户", + "BLOCK_USER": "阻止用户", + "DELETE_AND_EXIT": "删除并退出", + "LEAVE_GROUP": "离开小组", + "CREATE_GROUP": "创建群组", + "SHARED_MEDIA": "共享媒体", + "VIDEO_CALL": "视频通话", + "AUDIO_CALL": "音频通话", + "LOADING": "正在加载...", + "REPLY": "答复", + "REPLIES": "回复", + "LAUNCH": "启动", + "SHARED_COLLABORATIVE_DOCUMENT": "共享了协作文档", + "SHARED_COLLABORATIVE_WHITEBOARD": "共享了协作式白板", + "CREATED_WHITEBOARD": "你创建了一个新的协作白板", + "CREATED_DOCUMENT": "你创建了一个新的协作文档", + "PHOTOS": "照片", + "VIDEOS": "视频", + "DOCUMENT": "文档", + "YOU_DELETED_THIS_MESSAGE": "⚠️ 你删除了此消息", + "THIS_MESSAGE_DELETED": "⚠️ 此消息已删除", + "VIEW_ON_YOUTUBE": "在 Youtube 上查看", + "SEARCH": "搜索", + "NO_USERS_FOUND": "找不到用户", + "ERROR": "错误", + "NO_GROUPS_FOUND": "没有找到团体", + "NO_CHATS_FOUND": "没有找到聊天", + "MEDIA_MESSAGE": "媒体消息", + "INCOMING_AUDIO_CALL": "来音频通话", + "INCOMING_VIDEO_CALL": "来的视频通话", + "DECLINE": "拒绝", + "ACCEPT": "接受", + "CALL_INITIATED": "呼叫已启动", + "OUTGOING_AUDIO_CALL": "传出音频通话", + "OUTGOING_VIDEO_CALL": "外出的视频通话", + "CALL_REJECTED": "来电已拒绝", + "REJECTED_CALL": "拒绝的电话", + "CALL_ACCEPTED": "电话已接受", + "JOINED": "已加入", + "LEFT_THE_CALL": "离开了电话", + "UNANSWERED_AUDIO_CALL": "未应答的音频通话", + "UNANSWERED_VIDEO_CALL": "未应答的视频通话", + "CALL_ENDED": "呼叫已结束", + "CALL_CANCELLED": "电话已取消", + "CALL_BUSY": "呼叫忙", + "CALLING": "打电话...", + "ADD": "添加", + "NO_BANNED_MEMBERS_FOUND": "没有找到被禁的成员", + "BANNED_MEMBERS": "被禁的会员", + "NAME": "姓名", + "SCOPE": "范围", + "UNBAN": "Unban", + "SELECT_GROUP_TYPE": "选择群组类型", + "ENTER_GROUP_PASSWORD": "输入群组密码", + "CREATE": "创建", + "CREATE_POLL": "创建投票", + "QUESTION": "问题", + "ENTER_YOUR_QUESTION": "输入你的问题", + "OPTIONS": "选项", + "ENTER_YOUR_OPTION": "输入你的选项", + "ADD_NEW_OPTION": "添加新选项", + "VIEW_MEMBERS": "查看会员", + "DETAILS": "详情", + "NOTIFICATIONS": "通知", + "OTHER": "其他", + "HELP": "帮助", + "REPORT_PROBLEM": "报告问题", + "GROUP_MEMBERS": "集团成员", + "BAN": "禁", + "KICK": "踢", + "PICK_YOUR_EMOJI": "选择你的表情符号", + "PRIVATE_GROUP": "私人团体", + "PROTECTED_GROUP": "受保护的组", + "VISIT": "访问", + "ATTACH": "附上", + "ATTACH_FILE": "附加文件", + "ATTACH_VIDEO": "附上视频", + "ATTACH_AUDIO": "附加音频", + "ATTACH_IMAGE": "附上图片", + "COLLABORATE_USING_DOCUMENT": "使用文档进行协作", + "COLLABORATE_USING_WHITEBOARD": "使用白板进行协作", + "EMOJI": "表情符号", + "ENTER_YOUR_MESSAGE_HERE": "在这里输入你的消息", + "NO_MESSAGES_FOUND": "没有找到消息", + "THREAD": "线程", + "COLLABORATIVE_DOCUMENT": "协作文档", + "COLLABORATIVE_WHITEBOARD": "协作白板", + "ADD_REACTION": "添加反应", + "NO_STICKERS_FOUND": "找不到贴纸", + "REPLY_TO_THREAD": "回复线程", + "REPLY_IN_THREAD": "在线程中回复", + "DELETE_MESSAGE": "删除留言", + "EDIT_MESSAGE": "编辑消息", + "SUNDAY": "周日", + "MONDAY": "周一", + "TUESDAY": "周二", + "WEDNESDAY": "周三", + "THURSDAY": "周四", + "FRIDAY": "周五", + "SATURDAY": "周六", + "GROUP_NAME_BLANK": "组名不能为空", + "GROUP_TYPE_BLANK": "群组类型不能为空", + "GROUP_PASSWORD_BLANK": "组密码不能为空", + "POLL_QUESTION_BLANK": "问题不能为空", + "POLL_OPTION_BLANK": "选项不能为空", + "OWNER": "所有者", + "CHANGE_SCOPE": "更改范围", + "STICKER": "贴纸", + "LAST_ACTIVE_AT": "最后活动在", + "VOICE_CALL": "语音通话", + "VIEW_DETAIL": "查看详情", + "VOTES": "选票", + "VOTE": "投票", + "NO_VOTE": "没有投票", + "REACTED": "反应", + "ADDED": "添加", + "UNBANNED": "未被禁止", + "MADE": "制作", + "CALL_UNANSWERED": "来电未应答", + "MISSED_AUDIO_CALL": "错过了音频通话", + "ENTER_YOUR_PASSWORD": "输入你的密码", + "DOCS": "文档", + "NO_RECORDS_FOUND": "没有找到记录", + "LIVE_REACTION": "实时反应", + "SMILEY_PEOPLE": "笑脸与人", + "ANIMALES_NATURE": "动物与自然", + "FOOD_DRINK": "食物 & 饮料", + "ACTIVITY": "活动", + "TRAVEL_PLACES": "旅行 & 地点", + "OBJECTS": "对象", + "SYMBOLS": "符号", + "FLAGS": "旗", + "SENT": "已发送", + "SEEN": "看见", + "DELIVERED": "已交付", + "CALLS": "来电", + "CUSTOM_MESSAGE_LOCATION": "📍 位置", + "OFFLINE": "离线", + "YOU": "你", + "PRIVACY": "隐私", + "BLOCKED_USERS": "封锁的用户", + "YOU'VE_BLOCKED": "你已经封锁了", + "NO_PHOTOS": "没有照片", + "NO_VIDEOS": "没有视频", + "NO_DOCUMENTS": "没有文档", + "JOIN": "Joi" +} \ No newline at end of file diff --git a/CometChat/resources/localization/translator.js b/CometChat/resources/localization/translator.js new file mode 100644 index 00000000..801eb25f --- /dev/null +++ b/CometChat/resources/localization/translator.js @@ -0,0 +1,98 @@ +import * as enums from "../../util/enums.js"; + +import translationAR from "./locales/ar/translation.json"; +import translationDE from "./locales/de/translation.json"; +import translationEN from "./locales/en/translation.json"; +import translationENGB from "./locales/en-gb/translation.json"; +import translationENUS from "./locales/en-us/translation.json"; +import translationES from "./locales/es/translation.json"; +import translationFR from "./locales/fr/translation.json"; +import translationHI from "./locales/hi/translation.json"; +import translationMS from "./locales/ms/translation.json"; +import translationPT from "./locales/pt/translation.json"; +import translationRU from "./locales/ru/translation.json"; +import translationZH from "./locales/zh/translation.json"; +import translationZHTW from "./locales/zh-tw/translation.json"; + +// the translations +const translations = { + "ar": translationAR, + "de": translationDE, + "en": translationEN, + "en-gb": translationENGB, + "en-us": translationENUS, + "es": translationES, + "fr": translationFR, + "hi": translationHI, + "ms": translationMS, + "pt": translationPT, + "ru": translationRU, + "zh": translationZH, + "zh-tw": translationZHTW +}; + +window.addEventListener('languagechange', () => { + let language = Translator.getBrowserLanguage().toLowerCase(); + Translator.setLanguage(language); +}); + +class Translator { + + static key = enums["LOCALE_KEY"]; + static rtlLanguages = ["ar"]; + + static getLanguage = () => { + + return localStorage.getItem(this.key); + } + + static setLanguage = (language) => { + + const item = this.key; + localStorage.setItem(item, language); + } + + static getBrowserLanguage = () => ((navigator.languages && navigator.languages[0]) || navigator.language || navigator.userLanguage); + + static getDefaultLanguage = () => { + + let language = this.getLanguage(); + if (language) { + + return language; + + } else { + + let language = this.getBrowserLanguage().toLowerCase(); + this.setLanguage(language); + + return language; + } + } + + static getDirection(language) { + return this.rtlLanguages.includes(language) ? "rtl" : "ltr"; + } + + static translate(str, language) { + + try { + + const languageDb = translations[language]; + + if (languageDb.hasOwnProperty(str)) { + return languageDb[str]; + } + + return str; + + } catch (error) { + + console.error("Error while translating::translateWord", error); + // If something goes wrong return the word as it is. + return str; + } + } +} + +export default Translator; \ No newline at end of file diff --git a/CometChat/resources/theme.js b/CometChat/resources/theme.js index 12176b44..e9260efa 100644 --- a/CometChat/resources/theme.js +++ b/CometChat/resources/theme.js @@ -13,6 +13,8 @@ export const theme = { }, borderColor: { primary: "#eaeaea", + secondary: "#cccccc", + darkSecondary: "#eaeaea", white: "#fff", blue: "#39f", }, diff --git a/CometChat/util/common.js b/CometChat/util/common.js index d35ee7fa..1bbc1ea8 100644 --- a/CometChat/util/common.js +++ b/CometChat/util/common.js @@ -1,3 +1,4 @@ +/* eslint-disable no-extend-native */ const emailPattern = new RegExp("[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}", "gi");///([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi; const urlPattern = new RegExp("(^|[\\s.:;?\\-\\]<\\(])"+"((https?://|www\\.|pic\\.)[-\\w;/?:@&=+$\\|\\_.!~*\\|'()\\[\\]%#,☺]+[\\w/#](\\(\\))?)"+"(?=$|[\\s',\\|\\(\\).:;?\\-\\[\\]>\\)])", "gi"); ///(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|])/gi; const phoneNumPattern = new RegExp("^\\s*(?:\\+?(\\d{1,3}))?([-. (]*(\\d{3})[-. )]*)?((\\d{3})[-. ]*(\\d{2,4})(?:[-.x ]*(\\d+))?)\\s*", "gi"); @@ -11,7 +12,6 @@ export const linkify = (message) => { return outputStr; } - export const validateWidgetSettings = (wSettings, checkAgainst) => { let output = null; diff --git a/CometChat/util/enums.js b/CometChat/util/enums.js index ccebd342..f4d5e5be 100644 --- a/CometChat/util/enums.js +++ b/CometChat/util/enums.js @@ -52,4 +52,6 @@ export const CALL_TYPE_AUDIO = "audio"; export const CALL_TYPE_VIDEO = "video"; export const LIVE_REACTION_KEY = "live_reaction"; -export const LIVE_REACTIONS = { "heart": "./resources/heart.png", "thumbsup": "👍", "clap": "👏", "wink": "😉" }; \ No newline at end of file +export const LIVE_REACTIONS = { "heart": "./resources/heart.png", "thumbsup": "👍", "clap": "👏", "wink": "😉" }; + +export const LOCALE_KEY = "cometchat:locale"; \ No newline at end of file diff --git a/README.md b/README.md index 6ed995f0..09bbf5ea 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,75 @@ +
+
+
+ CometChat +
+
+
+ +

# React Chat UI Kit -React Chat UI Kit is a collection of custom UI Components and UI Screens designed to build chat application with fully customizable UI. It is designed to avoid boilerplate code for building UI. -![alt text](https://files.readme.io/68c7762-launch_cometchat.png "UI Unified") +

-It has the following 3 ways of implementation: -* [UI Unified](https://prodocs.cometchat.com/docs/react-ui-kit-ui-unified) -* [UI Screens](https://prodocs.cometchat.com/docs/react-ui-kit-ui-screens) -* [UI Components](https://prodocs.cometchat.com/docs/react-ui-kit-ui-components) + + + -## Requirements - 1. [CometChat Account](#cometchat-account) + + + -### CometChat Account -To use this library, you need application keys from your CometChat account. If you don't have an account, you can create one here. + + + -1. Sign in to your CometChat Dashboard -2. Click **Add New App** -3. Give your app a name, and select a region and click Add App -4. Click your new app to open its settings. -5. Locate API Keys and Create Auth Key. You'll need `App ID`, `Auth Key` and `Region` +

-## Installation +
-1. Install CometChat SDK +
+
+
+ Main +
+
+
+ +
+ +React Chat UI Kit is a collection of custom **UI Components** and **UI Screens** designed to build chat application with fully customizable UI. It is designed to avoid boilerplate code for building UI. + +___ -```javascript - npm install @cometchat-pro/chat@2.1.5 --save -``` -2. See UI kit's package.json file and add the missing packages in your project's package.json file. -3. Import CometChat Object +## Installing React Chat UI Kit + +## 1. Setup + +To install React UI Kit, you need to first register on CometChat Dashboard. Click here to sign up + +### i. Get your Application Keys + +* Create a new app +* Head over to the Quick Start or API & Auth Keys section and note the `App ID`, `Auth Key`, and `Region`. + +### ii. Add the CometChat Dependency ```javascript - import { CometChat } from "@cometchat-pro/" + npm install @cometchat-pro/chat@2.1.5 --save ``` -4. Initialize CometChat +
+ +## 2. Configure CometChat inside your app + +### i. Initialize CometChat The `init()` method initializes the settings required for CometChat. - We suggest calling the `init()` method on app startup, preferably in the `onCreate()` method of the Application class. +We suggest calling the `init()` method on app startup, preferably in the `onCreate()` method of the Application class. + ```javascript const appID = "APP_ID"; const region = "REGION"; @@ -56,42 +85,17 @@ CometChat.init(appID, appSetting).then( } ); ``` -**Note:** -Replace APP_ID and REGION with your CometChat `App ID` and `REGION` in the above code. - -5. Create & Login your User +**Note:**
+* Replace APP_ID and REGION with your CometChat `App ID` and `Region` in the above code. -Once initialization is successful, you will need to create a user. -To create users on the fly, you can use the `createUser()` method. This method takes a User object and the `Auth Key` as input parameters and returns the created User object if the request is successful. - -```javascript -const authKey = "AUTH_KEY"; -const uid = "UID"; -const name = "NAME"; -const user = new CometChat.User(uid); +### ii. Login your user -user.setName(name); - -CometChat.createUser(user, authKey).then( - user => { - console.log("user created", user); - },error => { - console.log("error", error); - } -); -``` -**Note:**
-* Replace `AUTH_KEY` with your CometChat `Auth Key` in the above code. -* Replace `UID` and `NAME` with the uid and name of the user to be created. -* We have setup 5 users for testing having UIDs: `SUPERHERO1`, `SUPERHERO2`, `SUPERHERO3`,`SUPERHERO4` and `SUPERHERO5`. - - -Once you have created the user successfully, you need to use the `login()` method. +This method takes `UID` and `Auth Key` as input parameters and returns the User object containing all the information of the logged-in user.. ```javascript const authKey = "AUTH_KEY"; -const uid = "UID"; +const uid = "SUPERHERO1"; CometChat.login(uid, authKey).then( user => { @@ -104,26 +108,55 @@ CometChat.login(uid, authKey).then( ``` **Note:**
* Replace `AUTH_KEY` with your CometChat `Auth Key` in the above code. -* Replace `UID` with the uid of the user created. -6. Import the components. +* We have setup 5 users for testing having UIDs: `SUPERHERO1`, `SUPERHERO2`, `SUPERHERO3`,`SUPERHERO4` and `SUPERHERO5`. -Here is an implementation of UI Unified. +
+## 3. Add UI Kit to your project + +Clone this repository and copy the CometChat folder to your source folder + +
+ +## 4. Launch UI Unified + +**UI Unified** is an option to launch a fully functional chat application using the UI Kit. In UI Unified all the UI Screens and UI Components are interlinked and work together to launch a fully functional chat on your website/application. ```html import {CometChatUnified} from "./CometChat"; + render() { - return ( - - ); + + return (); } ``` -
+
+ +## Checkout our sample app + +Visit our [React sample app] (https://github.com/cometchat-pro/javascript-react-chat-app) repo to run the React sample app. + +
+ +## Troubleshooting + +- To read the full documentation on UI Kit integration visit our [Documentation](https://prodocs.cometchat.com/docs/react-ui-kit). + +- Facing any issues while integrating or installing the UI Kit please connect with us via real time support present in CometChat Dashboard. + +
+ +## Contributors + +Thanks to the following people who have contributed to this project: + +[@priyadarshininadar](https://github.com/priyadarshininadar)
+[@ajaygajra](https://github.com/ajaygajra)
## Further Information - Please refer our [Documentation](https://prodocs.cometchat.com/docs/react-ui-kit) for more information about how to integrate UI Kit to your applications. +Please refer our Documentation for more information about how to integrate UI Kit to your applications. Please visit our [Forum](https://forum.cometchat.com/) if you are facing any issues while installation or integration of this library. diff --git a/Screenshots/logo.png b/Screenshots/logo.png new file mode 100644 index 00000000..27b5aab8 Binary files /dev/null and b/Screenshots/logo.png differ diff --git a/Screenshots/main.png b/Screenshots/main.png new file mode 100644 index 00000000..b6b41dc4 Binary files /dev/null and b/Screenshots/main.png differ
Group Members{Translator.translate("GROUP_MEMBERS", this.props.lang)}
NameScope{Translator.translate("NAME", this.props.lang)}{Translator.translate("SCOPE", this.props.lang)}