mirror of
https://github.com/balzack/databag.git
synced 2025-04-24 02:25:26 +00:00
rendering contact info
This commit is contained in:
parent
00eb0b0d64
commit
20fe796a1c
@ -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',
|
||||
|
@ -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: 'Удаление ключа запечатывания навсегда отзовет доступ ко всем сообщениям с сквозным шифрованием со всех устройств',
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 (
|
||||
<div className={classes.contact}>
|
||||
<div className={classes.header}>
|
||||
{ close && (
|
||||
<IconX size={28} className={classes.match} />
|
||||
)}
|
||||
<Text className={classes.label}>{`${state.handle}${state.node ? '/' + state.node : ''}`}</Text>
|
||||
{ close && (
|
||||
<IconX size={30} className={classes.close} onClick={close} />
|
||||
)}
|
||||
</div>
|
||||
<div className={classes.image}>
|
||||
<Image radius="md" src={state.imageUrl} />
|
||||
</div>
|
||||
<div className={classes.divider} />
|
||||
{!state.name && (
|
||||
<Text className={classes.nameUnset}>{state.strings.name}</Text>
|
||||
)}
|
||||
{state.name && (
|
||||
<Text className={classes.nameSet}>{state.name}</Text>
|
||||
)}
|
||||
<div className={classes.entry}>
|
||||
<div className={classes.entryIcon}>
|
||||
<IconMapPin />
|
||||
<div className={classes.detail}>
|
||||
<div className={classes.header}>
|
||||
{ close && (
|
||||
<IconX size={28} className={classes.match} />
|
||||
)}
|
||||
<Text className={classes.label}>{`${state.handle}${state.node ? '/' + state.node : ''}`}</Text>
|
||||
{ close && (
|
||||
<IconX size={30} className={classes.close} onClick={close} />
|
||||
)}
|
||||
</div>
|
||||
{!state.location && (
|
||||
<Text className={classes.entryUnset}>
|
||||
{state.strings.location}
|
||||
</Text>
|
||||
<div className={classes.image}>
|
||||
<Image radius="md" src={state.imageUrl} />
|
||||
</div>
|
||||
<div className={classes.divider} />
|
||||
{!state.name && (
|
||||
<Text className={classes.nameUnset}>{state.strings.name}</Text>
|
||||
)}
|
||||
{state.location && (
|
||||
<Text className={classes.entrySet}>{state.location}</Text>
|
||||
{state.name && (
|
||||
<Text className={classes.nameSet}>{state.name}</Text>
|
||||
)}
|
||||
<div className={classes.entry}>
|
||||
<div className={classes.entryIcon}>
|
||||
<IconMapPin />
|
||||
</div>
|
||||
{!state.location && (
|
||||
<Text className={classes.entryUnset}>
|
||||
{state.strings.location}
|
||||
</Text>
|
||||
)}
|
||||
{state.location && (
|
||||
<Text className={classes.entrySet}>{state.location}</Text>
|
||||
)}
|
||||
</div>
|
||||
<div className={classes.entry}>
|
||||
<div className={classes.entryIcon}>
|
||||
<IconBook />
|
||||
</div>
|
||||
{!state.description && (
|
||||
<Text className={classes.entryUnset}>
|
||||
{state.strings.description}
|
||||
</Text>
|
||||
)}
|
||||
{state.description && (
|
||||
<Text className={classes.entrySet}>
|
||||
{state.description}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
<div className={classes.divider} />
|
||||
{ state.statusLabel === 'unknownStatus' && (
|
||||
<div className={classes.actions}>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconDeviceFloppy />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.save }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconAlertHexagon />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.report }</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{ state.statusLabel === 'savedStatus' && (
|
||||
<div className={classes.actions}>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconRoute2 />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.connect }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconUserX />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.remove }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconEyeOff />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.block }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconAlertHexagon />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.report }</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{ state.statusLabel === 'pendingStatus' && (
|
||||
<div className={classes.actions}>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconDeviceFloppy />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.save }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconCircleCheck />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.accept }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconVolumeOff />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.ignore }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconArrowsCross />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.deny }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconUserX />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.remove }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconEyeOff />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.block }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconAlertHexagon />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.report }</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{ state.statusLabel === 'requestedStatus' && (
|
||||
<div className={classes.actions}>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconCircleCheck />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.accept }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconVolumeOff />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.ignore }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconArrowsCross />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.deny }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconUserX />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.remove }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconEyeOff />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.block }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconAlertHexagon />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.report }</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{ state.statusLabel === 'connectingStatus' && (
|
||||
<div className={classes.actions}>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconCancel />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.cancel }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconUserX />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.remove }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconEyeOff />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.block }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconAlertHexagon />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.report }</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{ state.statusLabel === 'connectedStatus' && (
|
||||
<div className={classes.actions}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconRouteX2 size={32} />
|
||||
</ActionIcon>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconUserX />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.remove }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconEyeOff />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.block }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconAlertHexagon />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.report }</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{ state.statusLabel === 'offsyncStatus' && (
|
||||
<div className={classes.actions}>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconRefresh />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.resync }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconRouteX2 />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.disconnect }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconUserX />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.remove }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconEyeOff />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.block }</Text>
|
||||
</div>
|
||||
<div className={classes.action}>
|
||||
<ActionIcon variant="subtle">
|
||||
<IconAlertHexagon />
|
||||
</ActionIcon>
|
||||
<Text className={classes.actionLabel}>{ state.strings.report }</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={classes.entry}>
|
||||
<div className={classes.entryIcon}>
|
||||
<IconBook />
|
||||
</div>
|
||||
{!state.description && (
|
||||
<Text className={classes.entryUnset}>
|
||||
{state.strings.description}
|
||||
</Text>
|
||||
)}
|
||||
{state.description && (
|
||||
<Text className={classes.entrySet}>
|
||||
{state.description}
|
||||
</Text>
|
||||
)}
|
||||
<div className={classes.status}>
|
||||
<Text className={classes[state.statusLabel]}>{ state.strings[state.statusLabel] }</Text>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//save - DeviceFloppy - save
|
||||
//cancel - Cancel - cancel
|
||||
//block - EyeOff - block
|
||||
//report - AlertHexagon - report
|
||||
//resync - Refresh - resync
|
||||
//deny - ArrowsCross - deny
|
||||
//ignore - VolumeOff - ignore
|
||||
//accept - CircleCheck - accept
|
||||
//connect - Route2 - connect
|
||||
//disconnect - RouteX2 - disconnect
|
||||
//remove - UserX - remove
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@ export function useContact(params: ContactParams) {
|
||||
cardId: null as string | null,
|
||||
status: '',
|
||||
offsync: false,
|
||||
statusLabel: '',
|
||||
})
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@ -43,13 +44,39 @@ export function useContact(params: ContactParams) {
|
||||
updateState({ guid, handle, node, name, location, description, imageUrl, cardId, status, offsync });
|
||||
}, [params]);
|
||||
|
||||
const getStatusLabel = (card?: Card) => {
|
||||
if (card) {
|
||||
const { status, offsync } = card;
|
||||
if (status === 'confirmed') {
|
||||
return 'savedStatus'
|
||||
}
|
||||
if (status === 'pending') {
|
||||
return 'pendingStatus'
|
||||
}
|
||||
if (status === 'requested') {
|
||||
return 'requestedStatus'
|
||||
}
|
||||
if (status === 'connecting') {
|
||||
return 'connectingStatus'
|
||||
}
|
||||
if (status === 'connected' && !offsync) {
|
||||
return 'connectedStatus'
|
||||
}
|
||||
if (status === 'connected' && offsync) {
|
||||
return 'offsyncStatus'
|
||||
}
|
||||
}
|
||||
return 'unknownStatus'
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const card = state.cards.find(card => card.guid === state.guid);
|
||||
const statusLabel = getStatusLabel(card);
|
||||
if (card) {
|
||||
const { handle, node, name, location, description, imageUrl, cardId, status, offsync } = card;
|
||||
updateState({ handle, node, name, location, description, imageUrl, cardId, status, offsync });
|
||||
updateState({ handle, node, name, location, description, imageUrl, cardId, status, offsync, statusLabel });
|
||||
} else {
|
||||
updateState({ cardId: null, status: '', offsync: false });
|
||||
updateState({ cardId: null, status: '', offsync: false, statusLabel });
|
||||
}
|
||||
}, [state.cards, state.guid]);
|
||||
|
||||
|
@ -44,31 +44,31 @@
|
||||
overscroll-behavior: none;
|
||||
|
||||
.requested {
|
||||
border-right: 5px solid #aa44aa;
|
||||
border-right: 5px solid var(--mantine-color-status-3);
|
||||
}
|
||||
|
||||
.connecting {
|
||||
border-right: 5px solid #22aacc;
|
||||
border-right: 5px solid var(--mantine-color-status-4);
|
||||
}
|
||||
|
||||
.pending {
|
||||
border-right: 5px solid #aaaa44;
|
||||
border-right: 5px solid var(--mantine-color-status-2);
|
||||
}
|
||||
|
||||
.connected {
|
||||
border-right: 5px solid #44aa44;
|
||||
border-right: 5px solid var(--mantine-color-status-5);
|
||||
}
|
||||
|
||||
.confirmed {
|
||||
border-right: 5px solid #cccccc;
|
||||
border-right: 5px solid var(--mantine-color-status-1);
|
||||
}
|
||||
|
||||
.unknown {
|
||||
border-right: 5px solid #555555;
|
||||
border-right: 5px solid var(--mantine-color-status-0);
|
||||
}
|
||||
|
||||
.offsync {
|
||||
border-right: 5px solid #dd6633;
|
||||
border-right: 5px solid var(--mantine-color-status-6);
|
||||
}
|
||||
|
||||
.card {
|
||||
|
Loading…
x
Reference in New Issue
Block a user