diff --git a/CHANGELOG.md b/CHANGELOG.md index 65c4d0895..65501839c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## 1.3.1 - 2020-02-12 + * [FIX] Add Cross-tab communication on the same origin (#364) + * [FIX] Corrected German title for finished chat (#363) + * [FIX] Update polish translation (#324) + ## 1.3.0 - 2019-12-12 * [NEW] Add Service Offline callback (#341) * [NEW] Persian translation (#330) diff --git a/package.json b/package.json index cb881acf3..98e331665 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rocket.chat/livechat", - "version": "1.3.0", + "version": "1.3.1", "files": [ "/build" ], diff --git a/src/components/helpers.js b/src/components/helpers.js index 1cc4e5b55..acb24b2aa 100644 --- a/src/components/helpers.js +++ b/src/components/helpers.js @@ -90,7 +90,7 @@ export function getInsertIndex(array, item, ranking) { return array.length > 0 ? array.length : 0; } -export function upsert(array, item, predicate, ranking) { +export function upsert(array = [], item, predicate, ranking) { const index = array.findIndex(predicate); if (index > -1) { diff --git a/src/i18n/de.json b/src/i18n/de.json index 44e354411..070950313 100644 --- a/src/i18n/de.json +++ b/src/i18n/de.json @@ -6,7 +6,7 @@ "cancel_caeb1e68": "Abbrechen", "change_department_1d671538": "Abteilung wechseln", "change_department_523a16e8": "Abteilung wechseln", - "chat_finished_effbd589": "Chat Beendet", + "chat_finished_effbd589": "Chat beendet", "choose_a_department_b106da55": "Wählen Sie eine Abteilung", "choose_a_department_fe9755fd": "Wählen Sie eine Abteilung", "choose_an_option_26ac97d2": "Wählen Sie eine Option", diff --git a/src/i18n/pl.json b/src/i18n/pl.json index 7337676f4..7569e93a0 100644 --- a/src/i18n/pl.json +++ b/src/i18n/pl.json @@ -1,80 +1,80 @@ { "pl": { - "are_you_sure_you_want_to_finish_this_chat_1db5c13b": "Are you sure you want to finish this chat?", - "are_you_sure_you_want_to_remove_all_of_your_person_426720f1": "Are you sure you want to remove all of your personal data?", - "are_you_sure_you_want_to_switch_the_department_d50a0b08": "Are you sure you want to switch the department?", + "are_you_sure_you_want_to_finish_this_chat_1db5c13b": "Czy na pewno chcesz zakończyć rozmowę?", + "are_you_sure_you_want_to_remove_all_of_your_person_426720f1": "Czy na pewno chcesz usunąć wszystkie dane dotyczące rozmowy?", + "are_you_sure_you_want_to_switch_the_department_d50a0b08": "Czy na pewno chcesz zmienić dział?", "cancel_caeb1e68": "Anuluj", - "change_department_1d671538": "Change department", - "change_department_523a16e8": "Change Department", - "chat_finished_effbd589": "Chat Finished", - "choose_a_department_b106da55": "Choose a department...", - "choose_a_department_fe9755fd": "Choose a department", - "choose_an_option_26ac97d2": "Choose an option...", + "change_department_1d671538": "Zmień dział", + "change_department_523a16e8": "Zmień Dział", + "chat_finished_effbd589": "Rozmowa Zakończona", + "choose_a_department_b106da55": "Wybierz dział...", + "choose_a_department_fe9755fd": "Wybierz dział", + "choose_an_option_26ac97d2": "Wybierz opcję...", "conversation_finished_6a0f2811": "Rozmowa zakończona", "count_new_messages_since_since_47c9d2a0": { - "one": "One new message since %{since}", - "other": "%{count} new messages since %{since}" + "one": "Jedna nowa wiadomość od %{since}", + "other": "%{count} nowych wiadomości od %{since}" }, - "department_switched_cff305cf": "Zmieniono departament", - "departments_3826b025": "Departments", - "disable_notifications_dd6a3180": "Disable notifications", - "dismiss_this_alert_ea9b3104": "Dismiss this alert", - "drop_here_to_upload_a_file_e5f4dd60": "Drop here to upload a file", + "department_switched_cff305cf": "Zmieniono dział", + "departments_3826b025": "Działy", + "disable_notifications_dd6a3180": "Wyłącz powiadomienia", + "dismiss_this_alert_ea9b3104": "Odrzuć powiadomienie", + "drop_here_to_upload_a_file_e5f4dd60": "Upuść tutaj, aby przesłać plik", "email_22a7d52d": "Email", - "enable_notifications_a3daf4b1": "Enable notifications", - "error_closing_chat_4c5e29d7": "Error closing chat.", - "error_removing_user_data_ce507478": "Error removing user data.", - "error_starting_a_new_conversation_reason_a1b491a1": "Error starting a new conversation: %{reason}", - "expand_chat_a0045dbd": "Expand chat", - "file_exceeds_allowed_size_of_size_bd65c389": "File exceeds allowed size of %{size}.", - "fileupload_error_9eedee68": "FileUpload Error", - "finish_this_chat_87b79542": "Finish this chat", - "forget_remove_my_data_e1d68cdd": "Forget/Remove my data", - "gdpr_8b366c2b": "GDPR", - "go_to_menu_options_forget_remove_my_personal_data__99c40934": "Go to **menu options → Forget/Remove my personal data** to request the immediate removal of your data.", - "i_agree_df2ecbd4": "I Agree", - "i_need_help_with_61054e21": "I need help with...", - "if_you_have_any_other_questions_just_press_the_but_ceaadfa0": "If you have any other questions, just press the button below to start a new chat.", - "insert_your_email_here_2e37fc94": "Insert your email here...", - "insert_your_name_here_3a8f5f46": "Insert your name here...", - "leave_a_message_5b581048": "Leave a message", - "livechat_connected_afee1c5b": "Livechat connected.", - "livechat_is_not_connected_b40328ca": "Livechat is not connected.", - "media_types_not_accepted_4e25676a": "Media Types Not Accepted.", - "message_5c38209d": "Message", - "minimize_chat_804b3135": "Minimize chat", - "name_1aed4a1b": "Name", - "need_help_803a61": "Need help?", - "new_chat_f525c39e": "New Chat", - "no_available_agents_to_transfer_3ae30cec": "No available agents to transfer", + "enable_notifications_a3daf4b1": "Włącz powiadomienia", + "error_closing_chat_4c5e29d7": "Wystąpił błąd podczas zamykania rozmowy.", + "error_removing_user_data_ce507478": "Wystąpił błąd podczas usuwania danych.", + "error_starting_a_new_conversation_reason_a1b491a1": "Wystąpił błąd podczas tworzenia rozmowy: %{reason}", + "expand_chat_a0045dbd": "Otwórz w nowym oknie", + "file_exceeds_allowed_size_of_size_bd65c389": "Plik przekroczył dopuszczalny rozmiar %{size}.", + "fileupload_error_9eedee68": "Błąd podczas wysyłania pliku", + "finish_this_chat_87b79542": "Zakończ rozmowę", + "forget_remove_my_data_e1d68cdd": "Zapomnij/Usuń moje dane", + "gdpr_8b366c2b": "RODO", + "go_to_menu_options_forget_remove_my_personal_data__99c40934": "Idź do **Opcje → Zapomnij/Usuń moje dane**, aby usunąć dane dotyczące rozmowy.", + "i_agree_df2ecbd4": "Zgadzam się", + "i_need_help_with_61054e21": "Potrzebuję pomocy...", + "if_you_have_any_other_questions_just_press_the_but_ceaadfa0": "Jeśli masz jeszcze jakieś pytania, naciśnij poniższy przycisk, aby rozpocząć rozmowę.", + "insert_your_email_here_2e37fc94": "Podaj swój adres email...", + "insert_your_name_here_3a8f5f46": "Wpisz swoje imię...", + "leave_a_message_5b581048": "Zostaw wiadomość", + "livechat_connected_afee1c5b": "Połączono.", + "livechat_is_not_connected_b40328ca": "Nie połączono.", + "media_types_not_accepted_4e25676a": "Format pliku niedozwolony.", + "message_5c38209d": "Wiadomość", + "minimize_chat_804b3135": "Minimalizuj okno", + "name_1aed4a1b": "Imię", + "need_help_803a61": "Potrzebujesz pomocy?", + "new_chat_f525c39e": "Nowa rozmowa", + "no_available_agents_to_transfer_3ae30cec": "Żaden konsultant nie jest dostępny", "no_e16d9132": "Nie", "ok_c47544a2": "OK", "options_3ab0ea65": "Opcje", - "please_tell_us_some_information_to_start_the_chat_ac135cbb": "Please, tell us some information to start the chat", - "please_wait_for_the_next_available_agent_b2a49c4c": "Please, wait for the next available agent..", + "please_tell_us_some_information_to_start_the_chat_ac135cbb": "Wyślij wiadomość, aby rozpocząć rozmowę", + "please_wait_for_the_next_available_agent_b2a49c4c": "Proszę zaczekać na konsultanta..", "powered_by_rocket_chat_4d7c2ab4": "Powered by Rocket.Chat", - "restore_chat_3bfecf2b": "Restore chat", - "room_name_changed_9c42350a": "Room name changed", + "restore_chat_3bfecf2b": "Przywróć rozmowę", + "room_name_changed_9c42350a": "Nazwa rozmowy została zmieniona", "send_e3bd0ed0": "Wyślij", - "sound_is_off_a743f419": "Sound is off", - "sound_is_on_98a9ec58": "Sound is on", - "start_chat_8606d464": "Start chat", - "thanks_for_talking_with_us_719cce22": "Thanks for talking with us", - "the_controller_of_your_personal_data_is_company_na_c82f5567": "The controller of your personal data is [Company Name], with registered office at [Company Address]. To start the chat you agree that your personal data shall be processed and trasmitted in accordance with the General Data Protection Regulation (GDPR).", - "type_your_message_here_6a05bd0f": "Type your message here", - "unread_messages_5e18e7b7": "unread messages", - "user_added_by_525b6b11": "User added by", + "sound_is_off_a743f419": "Wyłącz dźwięk", + "sound_is_on_98a9ec58": "Włącz dźwiek", + "start_chat_8606d464": "Rozpocznij rozmowę", + "thanks_for_talking_with_us_719cce22": "Dziękujemy za kontakt", + "the_controller_of_your_personal_data_is_company_na_c82f5567": "Administratorem twoich danych osobowych jest [Company Name], z siedzibą przy ulicy [Company Address]. Rozpoczynając rozmowę, wyrażasz zgodę na przetwarzanie i przesyłanie twoich danych osobowych zgodnie z ogólnym rozporządzeniem o ochronie danych (RODO).", + "type_your_message_here_6a05bd0f": "Wpisz tu swoją wiadomość", + "unread_messages_5e18e7b7": "nieprzeczytane wiadomości", + "user_added_by_525b6b11": "Użytkownik dodany przez", "user_joined_407ba0d": "Użytkownik dołączył", "user_left_58ed9c36": "Użytkownik wyszedł", - "user_removed_by_e990f856": "User removed by", - "waiting_queue_800061da": "Waiting queue...", + "user_removed_by_e990f856": "Użytkownik usunięty przez", + "waiting_queue_800061da": "Oczekiwanie w kolejce...", "we_are_not_online_right_now_please_leave_a_message_57df1966": "Nie jesteśmy teraz online. Proszę zostawić wiadomość.", - "welcome_dd4e7151": "Welcome", - "write_your_message_6eee0188": "Write your message...", + "welcome_dd4e7151": "Witamy", + "write_your_message_6eee0188": "Wpisz swoją wiadomość...", "yes_dde87d5": "Tak", - "you_browser_doesn_t_support_audio_element_3391386f": "You browser doesn't support audio element", - "you_browser_doesn_t_support_video_element_e9cbd81e": "You browser doesn't support video element", - "your_spot_is_spot_a35cd288": "Your spot is #%{spot}", - "your_spot_is_spot_estimated_wait_time_estimatedwai_d0ff46e0": "Your spot is #%{spot} (Estimated wait time: %{estimatedWaitTime})" + "you_browser_doesn_t_support_audio_element_3391386f": "Twoja przeglądarka nie wspiera elementów audio", + "you_browser_doesn_t_support_video_element_e9cbd81e": "Twoja przeglądarka nie wspiera elementów video", + "your_spot_is_spot_a35cd288": "Twoje miejsce to #%{spot}", + "your_spot_is_spot_estimated_wait_time_estimatedwai_d0ff46e0": "Twoje miejsce to #%{spot} (Szacowany czas oczekiwania: %{estimatedWaitTime})" } } \ No newline at end of file diff --git a/src/lib/room.js b/src/lib/room.js index 66f40e820..8481f44d7 100644 --- a/src/lib/room.js +++ b/src/lib/room.js @@ -199,3 +199,12 @@ export const defaultRoomParams = () => { return params; }; + +store.on('change', (state, prevState) => { + // Cross-tab communication + // Detects when a room is created and then route to the correct container + if (!prevState.room && state.room) { + route('/'); + } +}); + diff --git a/src/routes/Chat/container.js b/src/routes/Chat/container.js index aeb68dc54..ee8f4b0c5 100644 --- a/src/routes/Chat/container.js +++ b/src/routes/Chat/container.js @@ -14,6 +14,7 @@ import { normalizeQueueAlert } from '../../lib/api'; export class ChatContainer extends Component { state = { + room: null, connectingAgent: false, queueSpot: 0, triggerQueueMessage: true, @@ -37,6 +38,15 @@ export class ChatContainer extends Component { } } + checkRoom = () => { + const { room } = this.props; + const { room: stateRoom } = this.state; + if (room && (!stateRoom || room._id !== stateRoom._id)) { + this.state.room = room; + setTimeout(loadMessages, 500); + } + } + grantUser = async () => { const { token, user, guest } = this.props; @@ -270,8 +280,8 @@ export class ChatContainer extends Component { }); } - componentDidMount() { - this.checkConnectingAgent(); + async componentDidMount() { + await this.checkConnectingAgent(); loadMessages(); } @@ -291,8 +301,9 @@ export class ChatContainer extends Component { } } - componentDidUpdate() { - this.checkConnectingAgent(); + async componentDidUpdate() { + await this.checkConnectingAgent(); + this.checkRoom(); } componentWillUnmount() { @@ -387,7 +398,7 @@ export const ChatConnector = ({ ref, ...props }) => ( } : undefined, } : undefined} room={room} - messages={messages.filter((message) => canRenderMessage(message))} + messages={messages && messages.filter((message) => canRenderMessage(message))} noMoreMessages={noMoreMessages} emoji={false} uploads={uploads} diff --git a/src/store/Store.js b/src/store/Store.js index 6bd32b2c0..9512851b7 100644 --- a/src/store/Store.js +++ b/src/store/Store.js @@ -20,6 +20,21 @@ export default class Store extends EventEmitter { } this._state = { ...initialState, ...storedState }; + + window.addEventListener("storage", (e) => { + // Cross-tab communication + if (e.key !== this.localStorageKey) { + return; + } + + if (!e.newValue) { + // The localStorage has been removed + return location.reload(); + } + + const storedState = JSON.parse(e.newValue); + this.setStoredState(storedState); + }); } get state() { @@ -40,4 +55,15 @@ export default class Store extends EventEmitter { this.persist(); this.emit('change', this._state, prevState, partialState); } + + setStoredState(storedState) { + const prevState = this._state; + + const nonPeristable = {}; + for (const ignoredKey of this.dontPersist) { + nonPeristable[ignoredKey] = prevState[ignoredKey]; + } + this._state = { ...storedState, ...nonPeristable }; + this.emit('change', this._state, prevState); + } } diff --git a/src/store/index.js b/src/store/index.js index 12ad05864..cdcb4aaf2 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -37,7 +37,8 @@ const initialState = { unread: null, }; -export const store = new Store(initialState, { dontPersist: ['messages', 'typing'] }); +const dontPersist = ['messages', 'typing', 'loading', 'alerts', 'unread', 'noMoreMessages']; +export const store = new Store(initialState, { dontPersist }); if (process.env.NODE_ENV === 'development') { store.on('change', (state, prevState, partialState) => {