From 4a05b704713eecd3e78887ab47e5367a7c6af7eb Mon Sep 17 00:00:00 2001 From: balzack Date: Sun, 29 Dec 2024 15:06:17 -0800 Subject: [PATCH] rendering disconnected status --- app/client/mobile/src/constants/Strings.ts | 161 ++++++++++++++++-- .../mobile/src/session/Session.styled.ts | 3 + app/client/mobile/src/session/Session.tsx | 16 +- app/client/web/src/constants/Strings.ts | 2 +- app/client/web/src/session/Session.module.css | 23 +++ app/client/web/src/session/Session.tsx | 11 +- app/client/web/src/session/useSession.hook.ts | 21 ++- app/sdk/src/connection.ts | 2 +- 8 files changed, 215 insertions(+), 24 deletions(-) diff --git a/app/client/mobile/src/constants/Strings.ts b/app/client/mobile/src/constants/Strings.ts index 2bc808a8..5d34c303 100644 --- a/app/client/mobile/src/constants/Strings.ts +++ b/app/client/mobile/src/constants/Strings.ts @@ -1,13 +1,24 @@ import {NativeModules, Platform} from 'react-native'; export const en = { + textSmall: 'Small', + textMedium: 'Medium', + textLarge: 'Large', + processingError: 'Attachment Error', + unknownContact: 'Unknown Contact', + encrypted: 'Encrypted', unknown: 'Unknown', sealed: 'Sealed', + notSealed: 'Not Sealed', notes: 'Notes', server: 'Server', token: 'Token', delayMessage: 'Key generation can take several minutes.', + membership: 'Membership', + channelGuest: 'Topic Guest', + channelHost: 'Topic Host', + created: 'Created', code: 'en', settings: 'Settings', contacts: 'Contacts', @@ -40,8 +51,10 @@ export const en = { unsetSealing: 'Unset Sealing Key', newTopic: 'New Topic', + subject: 'Subject', noContacts: 'No Contacts', noTopics: 'No Topics', + noMessages: 'No Messages', noConnected: 'No Connected Contacts', subjectOptional: 'Subject (optional)', members: 'Members', @@ -222,9 +235,20 @@ export const en = { microphone: 'Microphone', camera: 'Camera', + flagMessage: 'Flag Message', + flagMessagePrompt: 'Are you sure you want to flag the message to the admin?', + flag: 'Flag', + blockMessage: 'Block Message', + blockMessagePrompt: 'Are you sure you want to block the message?', + + blockTopic: 'Blocking Topic', + blockTopicPrompt: 'Are you sure you want to block the topic?', + reportTopic: 'Flag Topic', + reportTopicPrompt: 'Are you sure you want to flag the topic for admin review?', + ignoring: 'Ignoring Contact', connfirmIgnoring: 'Are you sure you want to ignore the request?', - denying: 'Denyping Contact', + denying: 'Denying Contact', confirmDenying: 'Are you sure you want to deny the request?', reporting: 'Reporting Contact', confirmReporting: 'Are you sure you want to report the contact?', @@ -251,15 +275,36 @@ export const en = { disable: 'Disable', confirmDisable: 'Disabling Multi-Factor Authentication', disablePrompt: 'Are you sure you want to disable multi-factor authentication', -}; +} export const fr = { + textSmall: 'Petit', + textMedium: 'Moyen', + textLarge: 'Grand', + processingError: 'erreur de Pièce Jointe', + unknownContact: 'Contact Inconnu', + encrypted: 'Crypté', unknown: 'Inconnu', sealed: 'Scellé', + notSealed: 'Non Scellé', notes: 'Notes', server: 'Serveur', token: 'Code', delayMessage: 'La génération de clé peut prendre plusieurs minutes.', + blockTopic: 'Bloquer le sujet', + blockTopicPrompt: 'Êtes-vous sûr de vouloir bloquer ce sujet ?', + reportTopic: 'Signaler le sujet', + reportTopicPrompt: 'Êtes-vous sûr de vouloir signaler ce sujet pour examen par un administrateur ?', + + membership: 'Adhésion', + channelHost: 'Hôte du Sujet', + channelGuest: 'Invité du Sujet', + created: 'Créé', + flagMessage: 'Signaler le message', + flagMessagePrompt: 'Êtes-vous sûr de vouloir signaler le message à l\'administrateur?', + flag: 'Signaler', + blockMessage: 'Bloquer le message', + blockMessagePrompt: 'Êtes-vous sûr de vouloir bloquer le message?', code: 'fr', settings: 'Paramètres', @@ -318,8 +363,10 @@ export const fr = { unsetSealing: 'Clé de sécurité non définie', newTopic: 'Nouveau Sujet', + subject: 'Sujet', noContacts: 'Pas de Contacts', noTopics: 'Pas de Sujets', + noMessages: 'Pas de Messages', noConnected: 'Pas de Contacts Connecter', subjectOptional: 'Sujet (optionnel)', members: 'Membres', @@ -505,15 +552,36 @@ export const fr = { disable: 'Désactiver', confirmDisable: "Désactivation de l'authentification multi-facteurs", disablePrompt: "Êtes-vous sûr de vouloir désactiver l'authentification multi-facteurs", -}; +} export const sp = { + textSmall: 'Pequeño', + textMedium: 'Mediano', + textLarge: 'Grande', + processingError: 'Error al Adjuntar', + unkownContact: 'Contacto Desconocido', + encrypted: 'Cifrado', unknown: 'Desconocido', sealed: 'Sellado', + notSealed: 'No Sellado', notes: 'Notas', server: 'Server', token: 'Código', delayMessage: 'La generación de claves puede tardar varios minutos.', + blockTopic: 'Bloquear tema', + blockTopicPrompt: '¿Estás seguro de que deseas bloquear este tema?', + reportTopic: 'Reportar tema', + reportTopicPrompt: '¿Estás seguro de que deseas reportar este tema para revisión del administrador?', + + membership: 'Afiliación', + channelHost: 'Anfitrión del Tema', + channelGuest: 'Invitado de Tema', + created: 'Creado', + flagMessage: 'Marcar mensaje', + flagMessagePrompt: '¿Está seguro de que desea marcar el mensaje para el administrador?', + flag: 'Marcar', + blockMessage: 'Bloquear mensaje', + blockMessagePrompt: '¿Está seguro de que desea bloquear el mensaje?', code: 'sp', settings: 'Configuración', @@ -572,8 +640,10 @@ export const sp = { unsetSealing: 'Clave de seguridad no definida', newTopic: 'Nuevo tema', - noContacts: 'Sin contactos', - noTopics: 'Sin temas', + subject: 'Tema', + noContacts: 'Sin Contactos', + noTopics: 'Sin Temas', + noMessages: 'Sin Mensajes', noConnected: 'Ningún contacto conectado', subjectOptional: 'Tema (opcional)', members: 'Miembros', @@ -758,15 +828,36 @@ export const sp = { disable: 'Desactivar', confirmDisable: 'Desactivación de la autenticación de dos factores', disablePrompt: '¿Estás seguro de que quieres desactivar la autenticación de dos factores?', -}; +} export const pt = { + textSmall: 'Pequeno', + textMedium: 'Médio', + textLarge: 'Grande', + processingError: 'Erro de Anexo', + unknownContact: 'Contato Desconhecido', + encrypted: 'Criptografado', unknown: 'Desconhecido', sealed: 'Selado', + notSealed: 'Não Selado', notes: 'Notas', server: 'Servidor', token: 'Code', delayMessage: 'A geração da chave pode levar vários minutos.', + blockTopic: 'Bloquear tópico', + blockTopicPrompt: 'Tem certeza de que deseja bloquear este tópico?', + reportTopic: 'Denunciar tópico', + reportTopicPrompt: 'Tem certeza de que deseja denunciar este tópico para revisão do administrador?', + + membership: 'Associação', + channelHost: 'Anfitrião do Tópico', + channelGuest: 'Convidado do Tópico', + created: 'Criado', + flagMessage: 'Sinalizar mensagem', + flagMessagePrompt: 'Tem certeza de que deseja sinalizar a mensagem para o administrador?', + flag: 'Sinalizar', + blockMessage: 'Bloquear mensagem', + blockMessagePrompt: 'Tem certeza de que deseja bloquear a mensagem?', code: 'pt', settings: 'Configurações', @@ -825,8 +916,10 @@ export const pt = { unsetSealing: 'Chave de segurança não definida', newTopic: 'Novo tópico', - noContacts: 'Sem contatos', - noTopics: 'Sem tópicos', + subject: 'Assunto', + noContacts: 'Sem Contatos', + noTopics: 'Sem Tópicos', + noMessages: 'Sem Mensagem', noConnected: 'Nenhum contato conectado', subjectOptional: 'Assunto (opcional)', members: 'Membros', @@ -1011,15 +1104,36 @@ export const pt = { disable: 'Desativar', confirmDisable: 'Desativando Autenticação de Dois Fatores', disablePrompt: 'Tem certeza de que deseja desativar a autenticação de dois fatores?', -}; +} export const de = { + textSmall: 'Klein', + textMedium: 'Mittel', + textLarge: 'Groß', + processingError: 'Anhangsfehler', + unknwonContact: 'Unbekannter Kontakt', + encrypted: 'Verschlüsselt', unknown: 'Unbekannt', sealed: 'Versiegelt', + notSealed: 'Nicht Versiegelt', notes: 'Notizen', server: 'Servierer', token: 'Token', delayMessage: 'Die Schlüsselgenerierung kann mehrere Minuten dauern.', + membership: 'Mitgliedschaft', + blockTopic: 'Thema blockieren', + blockTopicPrompt: 'Sind Sie sicher, dass Sie dieses Thema blockieren möchten?', + reportTopic: 'Thema melden', + reportTopicPrompt: 'Sind Sie sicher, dass Sie dieses Thema zur Überprüfung durch den Administrator melden möchten?', + + channelHost: 'Themenhost', + channelGuest: 'Thema Gast', + created: 'Erstellt', + flagMessage: 'Nachricht melden', + flagMessagePrompt: 'Sind Sie sicher, dass Sie die Nachricht an den Administrator melden möchten?', + flag: 'Melden', + blockMessage: 'Nachricht blockieren', + blockMessagePrompt: 'Sind Sie sicher, dass Sie die Nachricht blockieren möchten?', code: 'de', settings: 'Einstellungen', @@ -1078,8 +1192,10 @@ export const de = { unsetSealing: 'Sicherheitsschlüssel nicht festgelegt', newTopic: 'Neues Thema', + subject: 'Betreff', noContacts: 'Keine Kontakte', noTopics: 'Keine Themen', + noMessages: 'Keine Nachrichten', noConnected: 'Keine verbundenen Kontakte', subjectOptional: 'Betreff (optional)', members: 'Mitglieder', @@ -1264,15 +1380,36 @@ export const de = { disable: 'Deaktivieren', confirmDisable: 'Deaktivierung der Zwei-Faktor-Authentifizierung', disablePrompt: 'Sind Sie sicher, dass Sie die Zwei-Faktor-Authentifizierung deaktivieren möchten?', -}; +} export const ru = { + textSmall: 'Маленький', + textMedium: 'Средний', + textLarge: 'Большой', + processingError: 'Ошибка прикрепления', + unknownContact: 'Неизвестный контакт', + encrypted: 'Зашифрованный', unknown: 'Неизвестно', sealed: 'Запечатано', + notSealed: 'Не Запечатано', notes: 'Заметки', server: 'Сервер', token: 'Токен', delayMessage: 'Генерация ключа может занять несколько минут.', + created: 'Созданный', + blockTopic: 'Заблокировать тему', + blockTopicPrompt: 'Вы уверены, что хотите заблокировать эту тему?', + reportTopic: 'Пожаловаться на тему', + reportTopicPrompt: 'Вы уверены, что хотите отправить эту тему на рассмотрение администратору?', + + membership: 'Членство', + channelHost: 'Ведущий темы', + channelGuest: 'Тема Гость', + flagMessage: 'Пожаловаться на сообщение', + flagMessagePrompt: 'Вы уверены, что хотите пожаловаться на сообщение администратору?', + flag: 'Пожаловаться', + blockMessage: 'Заблокировать сообщение', + blockMessagePrompt: 'Вы уверены, что хотите заблокировать сообщение?', code: 'ru', settings: 'Настройки', @@ -1331,8 +1468,10 @@ export const ru = { unsetSealing: 'Ключ безопасности не установлен', newTopic: 'Новая тема', + subject: 'Тема', noContacts: 'Нет контактов', noTopics: 'Нет тем', + noMessages: 'Нет сообщений', noConnected: 'Нет подключенных контактов', subjectOptional: 'Тема (необязательно)', members: 'Участники', @@ -1517,7 +1656,7 @@ export const ru = { disable: 'Отключить', confirmDisable: 'Отключение двухфакторной аутентификации', disablePrompt: 'Вы уверены, что хотите отключить двухфакторную аутентификацию?', -}; +} export function getLanguageStrings() { const locale = Platform.OS === 'ios' ? NativeModules.SettingsManager?.settings.AppleLocale || NativeModules.SettingsManager?.settings.AppleLanguages[0] : NativeModules.I18nManager?.localeIdentifier; diff --git a/app/client/mobile/src/session/Session.styled.ts b/app/client/mobile/src/session/Session.styled.ts index 66179c83..f7981249 100644 --- a/app/client/mobile/src/session/Session.styled.ts +++ b/app/client/mobile/src/session/Session.styled.ts @@ -2,6 +2,9 @@ import {StyleSheet} from 'react-native'; import { Colors } from '../constants/Colors'; export const styles = StyleSheet.create({ + session: { + position: 'relative', + }, container: { width: '100%', height: '100%', diff --git a/app/client/mobile/src/session/Session.tsx b/app/client/mobile/src/session/Session.tsx index 34e84ed9..a23efb55 100644 --- a/app/client/mobile/src/session/Session.tsx +++ b/app/client/mobile/src/session/Session.tsx @@ -135,14 +135,6 @@ export function Session() { )} - { state.disconnected && ( - - - - { state.strings.disconnected } - - - )} )} @@ -153,6 +145,14 @@ export function Session() { )} + { state.disconnected && ( + + + + { state.strings.disconnected } + + + )} ); } diff --git a/app/client/web/src/constants/Strings.ts b/app/client/web/src/constants/Strings.ts index 4120d9c6..bb5bbc27 100644 --- a/app/client/web/src/constants/Strings.ts +++ b/app/client/web/src/constants/Strings.ts @@ -23,7 +23,7 @@ export const en = { logout: 'Logout', confirmLogout: 'Are you sure you want to logout?', contactsUpdated: 'Updated contact status', - disconnected: 'Disconnected from server', + disconnected: 'Disconnected from Server', allDevices: 'Logout of all devices', ok: 'OK', cancel: 'Cancel', diff --git a/app/client/web/src/session/Session.module.css b/app/client/web/src/session/Session.module.css index 69a827ee..1bdfda4a 100644 --- a/app/client/web/src/session/Session.module.css +++ b/app/client/web/src/session/Session.module.css @@ -3,6 +3,29 @@ width: 100%; height: 100%; + .alert { + position: absolute; + top: 33%; + width: 100%; + display: flex; + justify-content: center; + + .alertArea { + display: flex; + gap: 8px; + padding-top: 8px; + padding-bottom: 8px; + padding-left: 16px; + padding-right: 16px; + border-radius: 16px; + background: var(--mantine-color-surface-2); + + .alertLabel { + color: var(--mantine-color-red-2); + } + } + } + .show { display: flex; width: 100%; diff --git a/app/client/web/src/session/Session.tsx b/app/client/web/src/session/Session.tsx index ec26f0f1..7aafb583 100644 --- a/app/client/web/src/session/Session.tsx +++ b/app/client/web/src/session/Session.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react' -import { Drawer } from '@mantine/core' +import { Text, Drawer } from '@mantine/core' import { DisplayContext } from '../context/DisplayContext' import { ContextType } from '../context/ContextType' import classes from './Session.module.css' @@ -15,6 +15,7 @@ import { Content } from '../content/Content' import { Conversation } from '../conversation/Conversation' import { Focus } from 'databag-client-sdk' import { useDisclosure } from '@mantine/hooks' +import { IconAlertCircle } from '@tabler/icons-react' export function Session() { const { state } = useSession(); @@ -176,6 +177,14 @@ export function Session() { )} + { state.disconnected && ( +
+
+ + { state.strings.disconnected } +
+
+ )} ) } diff --git a/app/client/web/src/session/useSession.hook.ts b/app/client/web/src/session/useSession.hook.ts index 31e3ab08..79b8efec 100644 --- a/app/client/web/src/session/useSession.hook.ts +++ b/app/client/web/src/session/useSession.hook.ts @@ -10,6 +10,8 @@ export function useSession() { const [state, setState] = useState({ focus: null as Focus | null, layout: null, + strings: display.state.strings, + disconnected: false, }) // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -18,8 +20,23 @@ export function useSession() { } useEffect(() => { - const { layout } = display.state - updateState({ layout }) + const setStatus = (status: string) => { + if (status === 'disconnected') { + updateState({ disconnected: true }); + } if (status === 'connected') { + updateState({ disconnected: false }); + } + } + const session = app.state.session; + if (session) { + session.addStatusListener(setStatus); + return () => session.removeStatusListener(); + } + }, [app.state.session]); + + useEffect(() => { + const { layout, strings } = display.state + updateState({ layout, strings }) }, [display.state]) useEffect(() => { diff --git a/app/sdk/src/connection.ts b/app/sdk/src/connection.ts index 5d98900a..afaed7b9 100644 --- a/app/sdk/src/connection.ts +++ b/app/sdk/src/connection.ts @@ -20,7 +20,7 @@ export class Connection { this.stale = setInterval(() => { if (this.websocket?.readyState == 1) { - this.websocket.ping(); + this.websocket.ping?.(); // not defined in browser } }, PING_INTERVAL); }