rendering disconnected status

This commit is contained in:
balzack 2024-12-29 15:06:17 -08:00
parent 325daba136
commit 4a05b70471
8 changed files with 215 additions and 24 deletions

View File

@ -1,13 +1,24 @@
import {NativeModules, Platform} from 'react-native'; import {NativeModules, Platform} from 'react-native';
export const en = { export const en = {
textSmall: 'Small',
textMedium: 'Medium',
textLarge: 'Large',
processingError: 'Attachment Error',
unknownContact: 'Unknown Contact',
encrypted: 'Encrypted',
unknown: 'Unknown', unknown: 'Unknown',
sealed: 'Sealed', sealed: 'Sealed',
notSealed: 'Not Sealed',
notes: 'Notes', notes: 'Notes',
server: 'Server', server: 'Server',
token: 'Token', token: 'Token',
delayMessage: 'Key generation can take several minutes.', delayMessage: 'Key generation can take several minutes.',
membership: 'Membership',
channelGuest: 'Topic Guest',
channelHost: 'Topic Host',
created: 'Created',
code: 'en', code: 'en',
settings: 'Settings', settings: 'Settings',
contacts: 'Contacts', contacts: 'Contacts',
@ -40,8 +51,10 @@ export const en = {
unsetSealing: 'Unset Sealing Key', unsetSealing: 'Unset Sealing Key',
newTopic: 'New Topic', newTopic: 'New Topic',
subject: 'Subject',
noContacts: 'No Contacts', noContacts: 'No Contacts',
noTopics: 'No Topics', noTopics: 'No Topics',
noMessages: 'No Messages',
noConnected: 'No Connected Contacts', noConnected: 'No Connected Contacts',
subjectOptional: 'Subject (optional)', subjectOptional: 'Subject (optional)',
members: 'Members', members: 'Members',
@ -222,9 +235,20 @@ export const en = {
microphone: 'Microphone', microphone: 'Microphone',
camera: 'Camera', 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', ignoring: 'Ignoring Contact',
connfirmIgnoring: 'Are you sure you want to ignore the request?', 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?', confirmDenying: 'Are you sure you want to deny the request?',
reporting: 'Reporting Contact', reporting: 'Reporting Contact',
confirmReporting: 'Are you sure you want to report the contact?', confirmReporting: 'Are you sure you want to report the contact?',
@ -251,15 +275,36 @@ export const en = {
disable: 'Disable', disable: 'Disable',
confirmDisable: 'Disabling Multi-Factor Authentication', confirmDisable: 'Disabling Multi-Factor Authentication',
disablePrompt: 'Are you sure you want to disable multi-factor authentication', disablePrompt: 'Are you sure you want to disable multi-factor authentication',
}; }
export const fr = { export const fr = {
textSmall: 'Petit',
textMedium: 'Moyen',
textLarge: 'Grand',
processingError: 'erreur de Pièce Jointe',
unknownContact: 'Contact Inconnu',
encrypted: 'Crypté',
unknown: 'Inconnu', unknown: 'Inconnu',
sealed: 'Scellé', sealed: 'Scellé',
notSealed: 'Non Scellé',
notes: 'Notes', notes: 'Notes',
server: 'Serveur', server: 'Serveur',
token: 'Code', token: 'Code',
delayMessage: 'La génération de clé peut prendre plusieurs minutes.', 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', code: 'fr',
settings: 'Paramètres', settings: 'Paramètres',
@ -318,8 +363,10 @@ export const fr = {
unsetSealing: 'Clé de sécurité non définie', unsetSealing: 'Clé de sécurité non définie',
newTopic: 'Nouveau Sujet', newTopic: 'Nouveau Sujet',
subject: 'Sujet',
noContacts: 'Pas de Contacts', noContacts: 'Pas de Contacts',
noTopics: 'Pas de Sujets', noTopics: 'Pas de Sujets',
noMessages: 'Pas de Messages',
noConnected: 'Pas de Contacts Connecter', noConnected: 'Pas de Contacts Connecter',
subjectOptional: 'Sujet (optionnel)', subjectOptional: 'Sujet (optionnel)',
members: 'Membres', members: 'Membres',
@ -505,15 +552,36 @@ export const fr = {
disable: 'Désactiver', disable: 'Désactiver',
confirmDisable: "Désactivation de l'authentification multi-facteurs", confirmDisable: "Désactivation de l'authentification multi-facteurs",
disablePrompt: "Êtes-vous sûr de vouloir désactiver l'authentification multi-facteurs", disablePrompt: "Êtes-vous sûr de vouloir désactiver l'authentification multi-facteurs",
}; }
export const sp = { export const sp = {
textSmall: 'Pequeño',
textMedium: 'Mediano',
textLarge: 'Grande',
processingError: 'Error al Adjuntar',
unkownContact: 'Contacto Desconocido',
encrypted: 'Cifrado',
unknown: 'Desconocido', unknown: 'Desconocido',
sealed: 'Sellado', sealed: 'Sellado',
notSealed: 'No Sellado',
notes: 'Notas', notes: 'Notas',
server: 'Server', server: 'Server',
token: 'Código', token: 'Código',
delayMessage: 'La generación de claves puede tardar varios minutos.', 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', code: 'sp',
settings: 'Configuración', settings: 'Configuración',
@ -572,8 +640,10 @@ export const sp = {
unsetSealing: 'Clave de seguridad no definida', unsetSealing: 'Clave de seguridad no definida',
newTopic: 'Nuevo tema', newTopic: 'Nuevo tema',
noContacts: 'Sin contactos', subject: 'Tema',
noTopics: 'Sin temas', noContacts: 'Sin Contactos',
noTopics: 'Sin Temas',
noMessages: 'Sin Mensajes',
noConnected: 'Ningún contacto conectado', noConnected: 'Ningún contacto conectado',
subjectOptional: 'Tema (opcional)', subjectOptional: 'Tema (opcional)',
members: 'Miembros', members: 'Miembros',
@ -758,15 +828,36 @@ export const sp = {
disable: 'Desactivar', disable: 'Desactivar',
confirmDisable: 'Desactivación de la autenticación de dos factores', confirmDisable: 'Desactivación de la autenticación de dos factores',
disablePrompt: '¿Estás seguro de que quieres desactivar la autenticación de dos factores?', disablePrompt: '¿Estás seguro de que quieres desactivar la autenticación de dos factores?',
}; }
export const pt = { export const pt = {
textSmall: 'Pequeno',
textMedium: 'Médio',
textLarge: 'Grande',
processingError: 'Erro de Anexo',
unknownContact: 'Contato Desconhecido',
encrypted: 'Criptografado',
unknown: 'Desconhecido', unknown: 'Desconhecido',
sealed: 'Selado', sealed: 'Selado',
notSealed: 'Não Selado',
notes: 'Notas', notes: 'Notas',
server: 'Servidor', server: 'Servidor',
token: 'Code', token: 'Code',
delayMessage: 'A geração da chave pode levar vários minutos.', 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', code: 'pt',
settings: 'Configurações', settings: 'Configurações',
@ -825,8 +916,10 @@ export const pt = {
unsetSealing: 'Chave de segurança não definida', unsetSealing: 'Chave de segurança não definida',
newTopic: 'Novo tópico', newTopic: 'Novo tópico',
noContacts: 'Sem contatos', subject: 'Assunto',
noTopics: 'Sem tópicos', noContacts: 'Sem Contatos',
noTopics: 'Sem Tópicos',
noMessages: 'Sem Mensagem',
noConnected: 'Nenhum contato conectado', noConnected: 'Nenhum contato conectado',
subjectOptional: 'Assunto (opcional)', subjectOptional: 'Assunto (opcional)',
members: 'Membros', members: 'Membros',
@ -1011,15 +1104,36 @@ export const pt = {
disable: 'Desativar', disable: 'Desativar',
confirmDisable: 'Desativando Autenticação de Dois Fatores', confirmDisable: 'Desativando Autenticação de Dois Fatores',
disablePrompt: 'Tem certeza de que deseja desativar a autenticação de dois fatores?', disablePrompt: 'Tem certeza de que deseja desativar a autenticação de dois fatores?',
}; }
export const de = { export const de = {
textSmall: 'Klein',
textMedium: 'Mittel',
textLarge: 'Groß',
processingError: 'Anhangsfehler',
unknwonContact: 'Unbekannter Kontakt',
encrypted: 'Verschlüsselt',
unknown: 'Unbekannt', unknown: 'Unbekannt',
sealed: 'Versiegelt', sealed: 'Versiegelt',
notSealed: 'Nicht Versiegelt',
notes: 'Notizen', notes: 'Notizen',
server: 'Servierer', server: 'Servierer',
token: 'Token', token: 'Token',
delayMessage: 'Die Schlüsselgenerierung kann mehrere Minuten dauern.', 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', code: 'de',
settings: 'Einstellungen', settings: 'Einstellungen',
@ -1078,8 +1192,10 @@ export const de = {
unsetSealing: 'Sicherheitsschlüssel nicht festgelegt', unsetSealing: 'Sicherheitsschlüssel nicht festgelegt',
newTopic: 'Neues Thema', newTopic: 'Neues Thema',
subject: 'Betreff',
noContacts: 'Keine Kontakte', noContacts: 'Keine Kontakte',
noTopics: 'Keine Themen', noTopics: 'Keine Themen',
noMessages: 'Keine Nachrichten',
noConnected: 'Keine verbundenen Kontakte', noConnected: 'Keine verbundenen Kontakte',
subjectOptional: 'Betreff (optional)', subjectOptional: 'Betreff (optional)',
members: 'Mitglieder', members: 'Mitglieder',
@ -1264,15 +1380,36 @@ export const de = {
disable: 'Deaktivieren', disable: 'Deaktivieren',
confirmDisable: 'Deaktivierung der Zwei-Faktor-Authentifizierung', confirmDisable: 'Deaktivierung der Zwei-Faktor-Authentifizierung',
disablePrompt: 'Sind Sie sicher, dass Sie die Zwei-Faktor-Authentifizierung deaktivieren möchten?', disablePrompt: 'Sind Sie sicher, dass Sie die Zwei-Faktor-Authentifizierung deaktivieren möchten?',
}; }
export const ru = { export const ru = {
textSmall: 'Маленький',
textMedium: 'Средний',
textLarge: 'Большой',
processingError: 'Ошибка прикрепления',
unknownContact: 'Неизвестный контакт',
encrypted: 'Зашифрованный',
unknown: 'Неизвестно', unknown: 'Неизвестно',
sealed: 'Запечатано', sealed: 'Запечатано',
notSealed: 'Не Запечатано',
notes: 'Заметки', notes: 'Заметки',
server: 'Сервер', server: 'Сервер',
token: 'Токен', token: 'Токен',
delayMessage: 'Генерация ключа может занять несколько минут.', delayMessage: 'Генерация ключа может занять несколько минут.',
created: 'Созданный',
blockTopic: 'Заблокировать тему',
blockTopicPrompt: 'Вы уверены, что хотите заблокировать эту тему?',
reportTopic: 'Пожаловаться на тему',
reportTopicPrompt: 'Вы уверены, что хотите отправить эту тему на рассмотрение администратору?',
membership: 'Членство',
channelHost: 'Ведущий темы',
channelGuest: 'Тема Гость',
flagMessage: 'Пожаловаться на сообщение',
flagMessagePrompt: 'Вы уверены, что хотите пожаловаться на сообщение администратору?',
flag: 'Пожаловаться',
blockMessage: 'Заблокировать сообщение',
blockMessagePrompt: 'Вы уверены, что хотите заблокировать сообщение?',
code: 'ru', code: 'ru',
settings: 'Настройки', settings: 'Настройки',
@ -1331,8 +1468,10 @@ export const ru = {
unsetSealing: 'Ключ безопасности не установлен', unsetSealing: 'Ключ безопасности не установлен',
newTopic: 'Новая тема', newTopic: 'Новая тема',
subject: 'Тема',
noContacts: 'Нет контактов', noContacts: 'Нет контактов',
noTopics: 'Нет тем', noTopics: 'Нет тем',
noMessages: 'Нет сообщений',
noConnected: 'Нет подключенных контактов', noConnected: 'Нет подключенных контактов',
subjectOptional: 'Тема (необязательно)', subjectOptional: 'Тема (необязательно)',
members: 'Участники', members: 'Участники',
@ -1517,7 +1656,7 @@ export const ru = {
disable: 'Отключить', disable: 'Отключить',
confirmDisable: 'Отключение двухфакторной аутентификации', confirmDisable: 'Отключение двухфакторной аутентификации',
disablePrompt: 'Вы уверены, что хотите отключить двухфакторную аутентификацию?', disablePrompt: 'Вы уверены, что хотите отключить двухфакторную аутентификацию?',
}; }
export function getLanguageStrings() { export function getLanguageStrings() {
const locale = Platform.OS === 'ios' ? NativeModules.SettingsManager?.settings.AppleLocale || NativeModules.SettingsManager?.settings.AppleLanguages[0] : NativeModules.I18nManager?.localeIdentifier; const locale = Platform.OS === 'ios' ? NativeModules.SettingsManager?.settings.AppleLocale || NativeModules.SettingsManager?.settings.AppleLanguages[0] : NativeModules.I18nManager?.localeIdentifier;

View File

@ -2,6 +2,9 @@ import {StyleSheet} from 'react-native';
import { Colors } from '../constants/Colors'; import { Colors } from '../constants/Colors';
export const styles = StyleSheet.create({ export const styles = StyleSheet.create({
session: {
position: 'relative',
},
container: { container: {
width: '100%', width: '100%',
height: '100%', height: '100%',

View File

@ -135,14 +135,6 @@ export function Session() {
)} )}
</View> </View>
</View> </View>
{ state.disconnected && (
<View style={styles.alert}>
<Surface elevation={5} style={styles.alertArea}>
<Icon color={Colors.offsync} size={20} source="alert-circle-outline" />
<Text style={styles.alertLabel}>{ state.strings.disconnected }</Text>
</Surface>
</View>
)}
</SafeAreaView> </SafeAreaView>
</Surface> </Surface>
)} )}
@ -153,6 +145,14 @@ export function Session() {
</View> </View>
</NavigationContainer> </NavigationContainer>
)} )}
{ state.disconnected && (
<View style={styles.alert}>
<Surface elevation={5} style={styles.alertArea}>
<Icon color={Colors.offsync} size={20} source="alert-circle-outline" />
<Text style={styles.alertLabel}>{ state.strings.disconnected }</Text>
</Surface>
</View>
)}
</View> </View>
); );
} }

View File

@ -23,7 +23,7 @@ export const en = {
logout: 'Logout', logout: 'Logout',
confirmLogout: 'Are you sure you want to logout?', confirmLogout: 'Are you sure you want to logout?',
contactsUpdated: 'Updated contact status', contactsUpdated: 'Updated contact status',
disconnected: 'Disconnected from server', disconnected: 'Disconnected from Server',
allDevices: 'Logout of all devices', allDevices: 'Logout of all devices',
ok: 'OK', ok: 'OK',
cancel: 'Cancel', cancel: 'Cancel',

View File

@ -3,6 +3,29 @@
width: 100%; width: 100%;
height: 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 { .show {
display: flex; display: flex;
width: 100%; width: 100%;

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import { Drawer } from '@mantine/core' import { Text, Drawer } from '@mantine/core'
import { DisplayContext } from '../context/DisplayContext' import { DisplayContext } from '../context/DisplayContext'
import { ContextType } from '../context/ContextType' import { ContextType } from '../context/ContextType'
import classes from './Session.module.css' import classes from './Session.module.css'
@ -15,6 +15,7 @@ import { Content } from '../content/Content'
import { Conversation } from '../conversation/Conversation' import { Conversation } from '../conversation/Conversation'
import { Focus } from 'databag-client-sdk' import { Focus } from 'databag-client-sdk'
import { useDisclosure } from '@mantine/hooks' import { useDisclosure } from '@mantine/hooks'
import { IconAlertCircle } from '@tabler/icons-react'
export function Session() { export function Session() {
const { state } = useSession(); const { state } = useSession();
@ -176,6 +177,14 @@ export function Session() {
</Drawer> </Drawer>
</div> </div>
)} )}
{ state.disconnected && (
<div className={classes.alert}>
<div className={classes.alertArea}>
<IconAlertCircle className={classes.alertLabel} />
<Text className={classes.alertLabel}>{ state.strings.disconnected }</Text>
</div>
</div>
)}
</div> </div>
) )
} }

View File

@ -10,6 +10,8 @@ export function useSession() {
const [state, setState] = useState({ const [state, setState] = useState({
focus: null as Focus | null, focus: null as Focus | null,
layout: null, layout: null,
strings: display.state.strings,
disconnected: false,
}) })
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -18,8 +20,23 @@ export function useSession() {
} }
useEffect(() => { useEffect(() => {
const { layout } = display.state const setStatus = (status: string) => {
updateState({ layout }) 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]) }, [display.state])
useEffect(() => { useEffect(() => {

View File

@ -20,7 +20,7 @@ export class Connection {
this.stale = setInterval(() => { this.stale = setInterval(() => {
if (this.websocket?.readyState == 1) { if (this.websocket?.readyState == 1) {
this.websocket.ping(); this.websocket.ping?.(); // not defined in browser
} }
}, PING_INTERVAL); }, PING_INTERVAL);
} }