diff --git a/app/client/web/src/App.tsx b/app/client/web/src/App.tsx index 3451afa2..f5d09cb9 100644 --- a/app/client/web/src/App.tsx +++ b/app/client/web/src/App.tsx @@ -124,6 +124,30 @@ const theme = createTheme({ '#aaaaaa', '#aaaaaa', ], + 'dark-status': [ + '#555555', + '#cccccc', + '#aaaa44', + '#aa44aa', + '#22aacc', + '#44aa44', + '#dd6633', + '#888888', + '#888888', + '#888888', + ], + 'light-status': [ + '#555555', + '#cccccc', + '#aaaa44', + '#aa44aa', + '#22aacc', + '#44aa44', + '#dd6633', + '#888888', + '#888888', + '#888888', + ], dbgreen: virtualColor({ name: 'dbgreen', dark: 'dark-databag-green', @@ -139,6 +163,11 @@ const theme = createTheme({ dark: 'dark-surface', light: 'light-surface', }), + status: virtualColor({ + name: 'status', + dark: 'dark-status', + light: 'light-status', + }), text: virtualColor({ name: 'text', dark: 'dark-text', diff --git a/app/client/web/src/constants/Strings.ts b/app/client/web/src/constants/Strings.ts index 17cc776d..6ae08be2 100644 --- a/app/client/web/src/constants/Strings.ts +++ b/app/client/web/src/constants/Strings.ts @@ -92,6 +92,14 @@ export const en = { confirmedTip: 'Disconnected Contact', unsavedTip: 'Unknown Contact', + unknownStatus: 'Unsaved Contact', + savedStatus: 'Saved Contact', + pendingStatus: 'Unknown Contact Request', + connectingStatus: 'Connection Requested', + requestedStatus: 'Connection Requested by Contact', + connectedStatus: 'Connected Contact', + offsyncStatus: 'Offsync Contact', + actions: 'Actions', resync: 'Resync', connect: 'Connect', @@ -107,6 +115,12 @@ export const en = { cancelRequest: 'Cancel Request', resyncContact: 'Resync Contact', + block: 'Block', + report: 'Report', + deny: 'Deny', + ignore: 'Ignore', + accept: 'Accept', + login: 'Login', create: 'Create', createAccount: 'Create Account', @@ -235,6 +249,19 @@ export const fr = { forgotPassword: 'Mot de Passe Oublié', manageTopics: 'Gérer la clé de sécurité', + unknownStatus: 'Contact Inconnu', + savedStatus: 'Contact Enregistré', + pendingStatus: 'Demande de Contact Inconnue', + connectingStatus: 'Demande de Connexion Envoyée', + requestedStatus: 'Demande de Connexion par le Contact', + connectedStatus: 'Contact Connecté', + offsyncStatus: 'Contact Désynchronisé', + + block: 'Bloquer', + report: 'Signaler', + deny: 'Refuser', + ignore: 'Ignorer', + accept: 'Accepter', sealUnlock: 'Déverrouiller la clé de scellement pour accéder aux messages chiffrés de bout en bout', sealForget: 'Oublier la clé de scellement pour révoquer l\'accès aux messages chiffrés de bout en bout pour cet appareil uniquement', @@ -460,6 +487,20 @@ export const sp = { forgotPassword: 'Contraseña Olvidada', manageTopics: 'Administrar clave de seguridad', + unknownStatus: 'Contacto Desconocido', + savedStatus: 'Contacto Guardado', + pendingStatus: 'Solicitud de Contacto Desconocido', + connectingStatus: 'Solicitud de Conexión Enviada', + requestedStatus: 'Solicitud de Conexión por el Contacto', + connectedStatus: 'Contacto Conectado', + offsyncStatus: 'Contacto Fuera de Sincronización', + + block: 'Bloquear', + report: 'Reportar', + deny: 'Denegar', + ignore: 'Ignorar', + accept: 'Aceptar', + sealUnlock: 'Desbloquear la clave de sellado para acceder a los mensajes cifrados de extremo a extremo', sealForget: 'Olvidar la clave de sellado para revocar el acceso a los mensajes cifrados de extremo a extremo solo en este dispositivo', sealDelete: 'Eliminar la clave de sellado revocará permanentemente el acceso a todos los mensajes cifrados de extremo a extremo desde todos los dispositivos', @@ -682,6 +723,20 @@ export const pt = { forgotPassword: 'Senha Esquecida', manageTopics: 'Gerenciar Chave de Selagem', + unknownStatus: 'Contato Desconhecido', + savedStatus: 'Contato Salvo', + pendingStatus: 'Solicitação de Contato Desconhecido', + connectingStatus: 'Solicitação de Conexão Enviada', + requestedStatus: 'Solicitação de Conexão pelo Contato', + connectedStatus: 'Contato Conectado', + offsyncStatus: 'Contato Fora de Sincronização', + + block: 'Bloquear', + report: 'Denunciar', + deny: 'Negar', + ignore: 'Ignorar', + accept: 'Aceitar', + sealUnlock: 'Desbloquear a chave de selagem para acessar mensagens criptografadas de ponta a ponta', sealForget: 'Esquecer a chave de selagem para revogar o acesso às mensagens criptografadas de ponta a ponta apenas para este dispositivo', sealDelete: 'Excluir a chave de selagem revogará permanentemente o acesso a todas as mensagens criptografadas de ponta a ponta de todos os dispositivos', @@ -904,6 +959,20 @@ export const de = { forgotPassword: 'Passwort Vergessen', manageTopics: 'Sicherheitsschlüssel verwalten', + unknownStatus: 'Unbekannter Kontakt', + savedStatus: 'Gespeicherter Kontakt', + pendingStatus: 'Unbekannte Kontaktanfrage', + connectingStatus: 'Verbindungsanfrage Gesendet', + requestedStatus: 'Verbindungsanfrage vom Kontakt', + connectedStatus: 'Verbunden Kontakt', + offsyncStatus: 'Unsynchronisierter Kontakt', + + block: 'Blockieren', + report: 'Melden', + deny: 'Ablehnen', + ignore: 'Ignorieren', + accept: 'Akzeptieren', + sealUnlock: 'Entsperren Sie den Versiegelungsschlüssel, um auf Ende-zu-Ende-verschlüsselte Nachrichten zuzugreifen', sealForget: 'Versiegelungsschlüssel vergessen, um den Zugriff auf Ende-zu-Ende-verschlüsselte Nachrichten nur für dieses Gerät zu widerrufen', sealDelete: 'Das Löschen des Versiegelungsschlüssels widerruft dauerhaft den Zugriff auf alle Ende-zu-Ende-verschlüsselten Nachrichten von allen Geräten', @@ -1127,6 +1196,20 @@ export const ru = { forgotPassword: 'Пароль забыт', manageTopics: 'Управление ключом запечатывания', + unknownStatus: 'Неизвестный Контакт', + savedStatus: 'Сохранённый Контакт', + pendingStatus: 'Запрос Неизвестного Контакта', + connectingStatus: 'Запрос на Подключение Отправлен', + requestedStatus: 'Запрос на Подключение от Контакта', + connectedStatus: 'Подключённый Контакт', + offsyncStatus: 'Несинхронизированный Контакт', + + block: 'Заблокировать', + report: 'Пожаловаться', + deny: 'Отклонить', + ignore: 'Игнорировать', + accept: 'Принять', + sealUnlock: 'Разблокировать ключ запечатывания для доступа к сообщениям с сквозным шифрованием', sealForget: 'Забыть ключ запечатывания, чтобы отозвать доступ к сообщениям с сквозным шифрованием только для этого устройства', sealDelete: 'Удаление ключа запечатывания навсегда отзовет доступ ко всем сообщениям с сквозным шифрованием со всех устройств', diff --git a/app/client/web/src/contact/Contact.module.css b/app/client/web/src/contact/Contact.module.css index d7b2047e..450e87c3 100644 --- a/app/client/web/src/contact/Contact.module.css +++ b/app/client/web/src/contact/Contact.module.css @@ -5,8 +5,19 @@ padding-left: 16px; padding-right: 16px; padding-top: 8px; - padding-bottom: 8px; - gap: 2px; + padding-bottom: 4px; + height: 100%; + width: 100%; + + .detail { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; + flex-grow: 1; + width: 100%; + } .header { display: flex; @@ -91,5 +102,66 @@ color: var(--mantine-color-text-9); } } + + .actions { + display: flex; + flex-direction: row; + flex-grow: 1; + gap: 12px; + padding-top: 16px; + + .action { + display: flex; + flex-direction: column; + align-items: center; + cursor: pointer; + + .actionLabel { + font-size: 8px; + color: var(--mantine-color-dbgreen-1); + } + } + } + + .status { + flex-shrink: 1; + display: flex; + align-items: center; + justify-content: center; + + .unknownStatus { + color: var(--mantine-color-status-0); + font-size: 12px; + } + + .savedStatus { + color: var(--mantine-color-status-1); + font-size: 12px; + } + + .pendingStatus { + color: var(--mantine-color-status-2); + font-size: 12px; + } + + .requestedStatus { + color: var(--mantine-color-status-3); + font-size: 12px; + } + + .connectingStatus { + color: var(--mantine-color-status-4); + font-size: 12px; + } + + .connectedStatus { + color: var(--mantine-color-status-5); + font-size: 12px; + } + + .offsyncStatus { + color: var(--mantine-color-status-6); + font-size: 12px; + } + } } - diff --git a/app/client/web/src/contact/Contact.tsx b/app/client/web/src/contact/Contact.tsx index 6c2b52d6..f02b4ea1 100644 --- a/app/client/web/src/contact/Contact.tsx +++ b/app/client/web/src/contact/Contact.tsx @@ -1,10 +1,12 @@ import React, {useEffect} from 'react'; import { useContact } from './useContact.hook'; import classes from './Contact.module.css'; -import { IconX, IconMapPin, IconBook } from '@tabler/icons-react'; +import { IconX, IconMapPin, IconBook, IconUserX, IconRouteX2, IconRoute2, IconCircleCheck, IconVolumeOff, IconArrowsCross, IconRefresh, IconAlertHexagon, IconEyeOff, IconCancel, IconDeviceFloppy } from '@tabler/icons-react'; import { Text, Image, + ActionIcon, + Button, } from '@mantine/core' export type ContactParams = { @@ -25,54 +27,291 @@ export function Contact({ params, close }: { params: ContactParams, close?: ()=> return (