adding a card view

This commit is contained in:
Roland Osborne 2024-02-25 09:21:26 -08:00
parent 18127e2442
commit 330b98f835
10 changed files with 98 additions and 81 deletions

View File

@ -10,6 +10,7 @@ export const en = {
ok: 'OK',
cancel: 'Cancel',
new: 'New',
newMessage: 'New Message',
topics: 'Topics',
unsetSealing: 'Unset Sealing Key',
@ -33,6 +34,7 @@ export const en = {
operationFailed: 'Operation Failed',
tryAgain: 'Please try again.',
add: 'Add',
save: 'Save',
forget: 'Forget',
unlock: 'Unlock',
@ -53,7 +55,7 @@ export const en = {
registry: 'Visible in Registry',
sealedTopics: 'Sealed Topics',
changeLogin: 'Change Login',
selectImage: 'Select Image',
selectImage: 'Select',
profileImage: 'Profile Image',
profileDetails: 'Profile Details',
enableSealed: 'Enabled Sealed Topics',
@ -64,6 +66,15 @@ export const en = {
delete: 'delete',
username: 'Username',
updateProfile: 'Update Profile',
syncError: 'Sync Error',
callTip: 'Call Contact',
messageTip: 'Message Contact',
connectedTip: 'Connected Contact',
requestedTip: 'Connection Requested by Contact',
connectingTip: 'Connection Requested',
pendingTip: 'Connection Requested by Unknown Contact',
confirmedTip: 'Disconnected Contact',
};
export const fr = {
@ -78,6 +89,7 @@ export const fr = {
ok: 'OK',
cancel: 'Annuler',
new: 'Nouveau',
newMessage: 'Nouveau Message',
topics: 'Sujets',
unsetSealing: 'Clé de sécurité non définie',
@ -101,6 +113,7 @@ export const fr = {
operationFailed: 'Opération Échouée',
tryAgain: 'Veuillez réessayer.',
add: 'Ajouter',
save: 'Enregistrer',
forget: 'Oublier',
unlock: 'Déverrouiller',
@ -121,7 +134,7 @@ export const fr = {
registry: 'Visible dans le Registre',
sealedTopics: 'Sujets Sécurisé',
changeLogin: 'Changer Identifiants',
selectImage: 'Sélectionner une Image',
selectImage: 'Sélectionner',
profileImage: 'Image de Profil',
profileDetails: 'Détails du Profil',
enableSealed: 'Activer les Sujets Sécurisé',
@ -132,5 +145,14 @@ export const fr = {
delete: 'supprimer',
username: 'Nom d\'Utilisateur',
updateProfile: 'Mettre à Jour le Profil',
syncError: 'Erreur de synchronisation',
callTip: 'Appeler le Contact',
messageTip: 'Envoyer un message au contact',
connectedTip: 'Contact connecté',
requestedTip: 'Demande de connexion envoyée par le contact',
connectingTip: 'Demande de connexion en cours',
pendingTip: 'Demande de connexion envoyée par un contact inconnu',
confirmedTip: 'Contact déconnecté'
};

View File

@ -158,7 +158,7 @@ export function Session() {
actions.closeDetails();
}
const drawerStyle = { padding: 0, backgroundColor: settings.state.colors.baseArea };
const drawerStyle = { overscrollBehavior: 'none', padding: 0, backgroundColor: settings.state.colors.baseArea };
return (
<ThemeProvider theme={settings.state.colors}>

View File

@ -6,7 +6,7 @@ import { useAccount } from './useAccount.hook';
export function Account({ closeAccount, openProfile }) {
const { state, actions } = useAccount();
const { state } = useAccount();
return (
<AccountWrapper>

View File

@ -17,9 +17,9 @@ export function Cards({ closeCards, openContact, openChannel, openListing }) {
catch (err) {
console.log(err);
modal.error({
title: 'Failed to Create Topic',
content: 'Please try again.',
bodyStyle: { padding: 16 },
title: <span style={state.menuStyle}>{state.strings.operationFailed}</span>,
content: <span style={state.menuStyle}>{state.strings.tryAgain}</span>,
bodyStyle: { borderRadius: 8, padding: 16, ...state.menuStyle },
});
};
};
@ -31,9 +31,9 @@ export function Cards({ closeCards, openContact, openChannel, openListing }) {
catch (err) {
console.log(err);
modal.error({
title: 'Failed to Start Call',
content: 'Please try again.',
bodyStyle: { padding: 16 },
title: <span style={state.menuStyle}>{state.strings.operationFailed}</span>,
content: <span style={state.menuStyle}>{state.strings.tryAgain}</span>,
bodyStyle: { borderRadius: 8, padding: 16, ...state.menuStyle },
});
};
};
@ -53,11 +53,11 @@ export function Cards({ closeCards, openContact, openChannel, openListing }) {
</div>
)}
<div className="filter">
<Input bordered={false} allowClear={true} placeholder="Contacts" prefix={<SearchOutlined />}
<Input className="filterControl" bordered={false} placeholder={state.strings.contacts} prefix={<SearchOutlined />}
spellCheck="false" onChange={(e) => actions.onFilter(e.target.value)} />
</div>
<div className="inline">
<Button type="primary" icon={<UserOutlined />} onClick={openListing}>Add</Button>
<Button type="primary" icon={<UserOutlined />} onClick={openListing}>{state.strings.add}</Button>
</div>
{ state.display === 'xlarge' && (
<div className="inline">
@ -72,7 +72,7 @@ export function Cards({ closeCards, openContact, openChannel, openListing }) {
<List local={{ emptyText: '' }} itemLayout="horizontal" dataSource={state.cards} gutter="0"
renderItem={item => (
<CardItem item={item} enableIce={state.enableIce} tooltip={state.tooltip} resync={() => actions.resync(item.cardId)}
open={() => openContact(item.guid)} message={() => message(item.cardId)}
open={() => openContact(item.guid)} message={() => message(item.cardId)} strings={state.strings}
call={() => call(item)} display={state.display} canMessage={state.allowUnsealed || (item.seal && state.sealable)} />
)} />
)}

View File

@ -6,7 +6,8 @@ export const CardsWrapper = styled.div`
width: 100%;
display: flex;
flex-direction: column;
background-color: ${Colors.card};
background-color: ${props => props.theme.itemArea};
color: ${props => props.theme.mainText};
.view {
min-height: 0;
@ -18,23 +19,48 @@ export const CardsWrapper = styled.div`
align-items: center;
justify-content: center;
font-style: italic;
color: ${Colors.grey};
color: ${props => props.theme.hintText};
height: 100%;
}
}
.search {
border-bottom: 1px solid ${Colors.divider};
display: flex;
flex-direction: row;
height: 48px;
padding-left: 16px;
padding-right: 16px;
padding-top: 8px;
padding-bottom: 8px;
padding-left: 16px;
padding-right: 16px;
border-bottom: 1px solid ${props => props.theme.sectionBorder};
display: flex;
flex-direction: row;
.filter {
border: 1px solid ${props => props.theme.sectionBorder};
background-color: ${props => props.theme.inputArea};
border-radius: 8px;
flex-grow: 1;
.filterControl {
color: ${props => props.theme.mainText};
input {
padding-left: 4px;
color: ${props => props.theme.mainText};
}
input::placeholder {
color: ${props => props.theme.placeholderText};
}
}
}
.dismiss {
font-size: 18px;
color: ${props => props.theme.hintText};
cursor: pointer;
}
.sorted {
color: ${Colors.enabled};
color: ${props => props.theme.mainText};
font-size: 18px;
padding-right: 8px;
display: flex;
@ -43,7 +69,7 @@ export const CardsWrapper = styled.div`
}
.unsorted {
color: ${Colors.disabled};
color: ${props => props.theme.hintText};
font-size: 18px;
padding-right: 8px;
display: flex;
@ -51,14 +77,6 @@ export const CardsWrapper = styled.div`
cursor: pointer;
}
.filter {
border: 1px solid ${Colors.divider};
background-color: ${Colors.white};
border-radius: 8px;
flex-grow: 1;
}
.inline {
padding-left: 8px;
display: flex;
@ -69,34 +87,12 @@ export const CardsWrapper = styled.div`
align-items: center;
justify-content: center;
.add {
display: flex;
flex-direction: row;
color: ${Colors.white};
background-color: ${Colors.primary};
align-items: center;
justify-content: center;
padding-left: 16px;
padding-right: 16px;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
height: 100%;
flex-shrink: 0;
.label {
padding-left: 8px;
.anticon {
color: ${props => props.theme.enabledText};
}
}
}
.dismiss {
font-size: 18px;
color: ${Colors.text};
cursor: pointer;
}
}
.bar {
height: 48px;
width: 100%;
@ -105,8 +101,8 @@ export const CardsWrapper = styled.div`
flex-direction: row;
align-items: center;
justify-content: center;
background-color: ${Colors.formBackground};
border-top: 1px solid ${Colors.divider};
background-color: ${props => props.theme.enabledArea};
border-top: 1px solid ${props => props.theme.sectionBorder};
padding-bottom: 12px;
padding-top: 12px;
position: relative;
@ -114,7 +110,7 @@ export const CardsWrapper = styled.div`
.add {
display: flex;
flex-direction: row;
color: ${Colors.primary};
color: ${props => props.theme.mainText};
align-items: center;
justify-content: center;
padding-left: 16px;

View File

@ -6,7 +6,7 @@ import { Logo } from 'logo/Logo';
import { Tooltip } from 'antd';
import { MessageOutlined, PhoneOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
export function CardItem({ item, tooltip, enableIce, resync, open, call, message, display, canMessage }) {
export function CardItem({ item, tooltip, enableIce, resync, open, call, message, display, canMessage, strings }) {
const onResync = (e) => {
e.stopPropagation();
@ -31,13 +31,8 @@ export function CardItem({ item, tooltip, enableIce, resync, open, call, message
<div className="handle">{ item.handle }</div>
</div>
<div className="markup">
{ item.offsync && !item.tooltip && (
<StatusError onClick={onResync}>
<ExclamationCircleOutlined />
</StatusError>
)}
{ item.offsync && item.tooltip && (
<Tooltip placement="left" title="sync error">
{ item.offsync && (
<Tooltip placement="left" title={strings.syncError}>
<StatusError onClick={onResync}>
<ExclamationCircleOutlined />
</StatusError>
@ -60,39 +55,39 @@ export function CardItem({ item, tooltip, enableIce, resync, open, call, message
{ item.status === 'connected' && display !== 'small' && (
<ComOptions>
{ canMessage && (
<Tooltip className="option" placement="left" title="message contact">
<Tooltip className="option" placement="left" title={strings.messageTip}>
<MessageOutlined onClick={onMessage} />
</Tooltip>
)}
{ enableIce && (
<Tooltip className="option" placement="left" title="call contact">
<Tooltip className="option" placement="left" title={strings.callTip}>
<PhoneOutlined onClick={onCall} />
</Tooltip>
)}
</ComOptions>
)}
{ item.status === 'connected' && (
<Tooltip placement="left" title="connected contact">
<Tooltip placement="left" title={strings.connectedTip}>
<StatusConnected />
</Tooltip>
)}
{ item.status === 'requested' && (
<Tooltip placement="left" title="connection requested by contact">
<Tooltip placement="left" title={strings.requestedTip}>
<StatusRequested />
</Tooltip>
)}
{ item.status === 'connecting' && (
<Tooltip placement="left" title="requested contact connection">
<Tooltip placement="left" title={strings.connectingTip}>
<StatusConnecting />
</Tooltip>
)}
{ item.status === 'pending' && (
<Tooltip placement="left" title="unknwon contact connection request">
<Tooltip placement="left" title={strings.pendingTip}>
<StatusPending />
</Tooltip>
)}
{ item.status === 'confirmed' && (
<Tooltip placement="left" title="disconnected contact">
<Tooltip placement="left" title={strings.confirmedTip}>
<StatusConfirmed />
</Tooltip>
)}

View File

@ -6,12 +6,13 @@ export const CardItemWrapper = styled.div`
width: 100%;
display: flex;
align-items: center;
border-bottom: 1px solid ${Colors.divider};
border-bottom: 1px solid ${props => props.theme.itemBorder};
color: ${props => props.theme.mainText};
padding-left: 16px;
padding-right: 16px;
&:hover {
background-color: ${Colors.formHover};
background-color: ${props => props.theme.hoverArea};
cursor: pointer;
}
@ -50,13 +51,13 @@ export const CardItemWrapper = styled.div`
`;
export const StatusError = styled.div`
color: ${Colors.error};
color: ${props => props.theme.alertText};
font-size: 14px;
padding-right: 12px;
`
export const ComOptions = styled.div`
color: ${Colors.primary};
color: ${props => props.theme.linkText};
font-size: 16px;
display: flex;
flex-direction: row;

View File

@ -17,6 +17,8 @@ export function useCards() {
display: 'small',
enableIce: false,
sealable: false,
strings: {},
menuStyle: {},
allowUnsealed: false,
cards: [],
});
@ -33,8 +35,8 @@ export function useCards() {
}
useEffect(() => {
const { display } = settings.state;
updateState({ display });
const { display, strings, menuStyle } = settings.state;
updateState({ display, strings, menuStyle });
}, [settings.state]);
useEffect(() => {

View File

@ -18,12 +18,12 @@ export function Channels({ open, active }) {
<ChannelsWrapper>
<div className="search">
<div className="filter">
<Input className="filterControl" bordered={false} allowClear={true} placeholder={state.strings.topics} prefix={<SearchOutlined />}
<Input className="filterControl" bordered={false} placeholder={state.strings.topics} prefix={<SearchOutlined />}
spellCheck="false" onChange={(e) => actions.onFilter(e.target.value)} />
</div>
{ state.display === 'small' && (
<div className="inline">
<Button type="primary" disabled={!state.allowAdd} icon={<CommentOutlined />} onClick={actions.setShowAdd}>New</Button>
<Button type="primary" disabled={!state.allowAdd} icon={<CommentOutlined />} onClick={actions.setShowAdd}>{state.strings.new}</Button>
</div>
)}
</div>

View File

@ -38,6 +38,7 @@ export const ChannelsWrapper = styled.div`
border-radius: 8px;
flex-grow: 1;
.filterControl {
color: ${props => props.theme.mainText};