From 5db44ebaffcff5df58a0cf42baaeb13fc9e28a43 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Wed, 28 Feb 2024 13:41:33 -0800 Subject: [PATCH] adding dark mode to contact page --- net/web/src/constants/Colors.js | 2 + net/web/src/context/useCardContext.hook.js | 5 +- net/web/src/session/Session.jsx | 10 +- net/web/src/session/Session.styled.js | 5 + net/web/src/session/account/Account.jsx | 4 +- .../src/session/account/profile/Profile.jsx | 4 +- .../session/account/profile/Profile.styled.js | 8 +- net/web/src/session/cards/Cards.jsx | 4 +- net/web/src/session/cards/Cards.styled.js | 1 + net/web/src/session/contact/Contact.jsx | 239 ++++++++++-------- net/web/src/session/contact/Contact.styled.js | 106 ++++++-- .../src/session/contact/useContact.hook.js | 22 +- net/web/src/session/listing/Listing.jsx | 78 +++--- net/web/src/session/listing/Listing.styled.js | 17 +- .../listing/listingItem/ListingItem.styled.js | 1 - 15 files changed, 312 insertions(+), 194 deletions(-) diff --git a/net/web/src/constants/Colors.js b/net/web/src/constants/Colors.js index b927f0d6..a1643551 100644 --- a/net/web/src/constants/Colors.js +++ b/net/web/src/constants/Colors.js @@ -65,6 +65,7 @@ export const LightTheme = { inputBorder: '#888888', sectionBorder: '#bbbbbb', headerBorder: '#aaaaaa', + drawerBorder: '#cccccc', }; export const DarkTheme = { @@ -94,5 +95,6 @@ export const DarkTheme = { inputBorder: '#aaaaaa', sectionBorder: '#777777', headerBorder: '#aaaaaa', + drawerBorder: '#444444', }; diff --git a/net/web/src/context/useCardContext.hook.js b/net/web/src/context/useCardContext.hook.js index 38f0c9b9..1eca5155 100644 --- a/net/web/src/context/useCardContext.hook.js +++ b/net/web/src/context/useCardContext.hook.js @@ -52,6 +52,7 @@ export function useCardContext() { }; const resyncCard = async (cardId) => { + let success = true; if (!syncing.current) { syncing.current = true; @@ -68,10 +69,12 @@ export function useCardContext() { } catch(err) { console.log(err); + success = false; } syncing.current = false; await sync(); } + return success; } const sync = async () => { @@ -359,7 +362,7 @@ export function useCardContext() { await resync(); }, resyncCard: async (cardId) => { - await resyncCard(cardId); + return await resyncCard(cardId); }, } diff --git a/net/web/src/session/Session.jsx b/net/web/src/session/Session.jsx index bec3b624..0b4c59d3 100644 --- a/net/web/src/session/Session.jsx +++ b/net/web/src/session/Session.jsx @@ -192,7 +192,7 @@ export function Session() { )} { state.contact && ( -
+
)} @@ -212,9 +212,9 @@ export function Session() { { state.cards && (
- +
@@ -318,7 +318,7 @@ export function Session() {
)} { state.contact && ( -
+
)} diff --git a/net/web/src/session/Session.styled.js b/net/web/src/session/Session.styled.js index 5bfee469..50afd67a 100644 --- a/net/web/src/session/Session.styled.js +++ b/net/web/src/session/Session.styled.js @@ -239,10 +239,15 @@ export const SessionWrapper = styled.div` display: flex; flex-direction: column; + .base { + background-color: ${props => props.theme.frameArea}; + } + .top { flex-grow: 1; position: relative; } + .bottom { height: 40px; position: relative; diff --git a/net/web/src/session/account/Account.jsx b/net/web/src/session/account/Account.jsx index baaa5481..85f05fb3 100644 --- a/net/web/src/session/account/Account.jsx +++ b/net/web/src/session/account/Account.jsx @@ -1,5 +1,5 @@ import { AccountWrapper } from './Account.styled'; -import { RightOutlined } from '@ant-design/icons'; +import { CloseOutlined } from '@ant-design/icons'; import { SettingOutlined } from '@ant-design/icons'; import { AccountAccess } from './profile/accountAccess/AccountAccess'; import { useAccount } from './useAccount.hook'; @@ -13,7 +13,7 @@ export function Account({ closeAccount, openProfile }) {
{state.strings.settings}
- +
diff --git a/net/web/src/session/account/profile/Profile.jsx b/net/web/src/session/account/profile/Profile.jsx index 5f5bffaf..3d0967ab 100644 --- a/net/web/src/session/account/profile/Profile.jsx +++ b/net/web/src/session/account/profile/Profile.jsx @@ -4,7 +4,7 @@ import { LogoutContent, ProfileWrapper, ProfileDetailsWrapper, ProfileImageWrapp import { useProfile } from './useProfile.hook'; import { Logo } from 'logo/Logo'; import { AccountAccess } from './accountAccess/AccountAccess'; -import { LogoutOutlined, RightOutlined, EditOutlined, BookOutlined, EnvironmentOutlined } from '@ant-design/icons'; +import { LogoutOutlined, CloseOutlined, EditOutlined, BookOutlined, EnvironmentOutlined } from '@ant-design/icons'; import Cropper from 'react-easy-crop'; export function Profile({ closeProfile }) { @@ -82,7 +82,7 @@ export function Profile({ closeProfile }) {
{ state.handle }
- +
)} diff --git a/net/web/src/session/account/profile/Profile.styled.js b/net/web/src/session/account/profile/Profile.styled.js index dc68b686..b6452939 100644 --- a/net/web/src/session/account/profile/Profile.styled.js +++ b/net/web/src/session/account/profile/Profile.styled.js @@ -97,7 +97,6 @@ export const ProfileWrapper = styled.div` justify-content: center; padding-top: 64px; padding-left: 32px; - align-items: center; } .rightContent { @@ -110,6 +109,10 @@ export const ProfileWrapper = styled.div` border-radius: 4px; padding: 8px; background-color: ${props => props.theme.selectedArea}; + + .details { + align-items: center; + } } .rightAccess { @@ -126,7 +129,6 @@ export const ProfileWrapper = styled.div` .details { display: flex; flex-direction: column; - padding-top: 16px; padding-left: 16px; padding-right: 16px; @@ -140,7 +142,6 @@ export const ProfileWrapper = styled.div` flex-direction: row; align-items: baseline; cursor: pointer; - justify-content: center; &:hover .icon { color: ${props => props.theme.linkText}; @@ -176,6 +177,7 @@ export const ProfileWrapper = styled.div` flex-direction: row; align-items: flex-start; padding-top: 8px; + max-width: 500px; .data { padding-left: 8px; diff --git a/net/web/src/session/cards/Cards.jsx b/net/web/src/session/cards/Cards.jsx index e8a728fc..7242b039 100644 --- a/net/web/src/session/cards/Cards.jsx +++ b/net/web/src/session/cards/Cards.jsx @@ -1,6 +1,6 @@ import { Input, Modal, List, Button } from 'antd'; import { CardsWrapper } from './Cards.styled'; -import { SortAscendingOutlined, RightOutlined, UserOutlined, SearchOutlined } from '@ant-design/icons'; +import { SortAscendingOutlined, CloseOutlined, UserOutlined, SearchOutlined } from '@ant-design/icons'; import { useCards } from './useCards.hook'; import { CardItem } from './cardItem/CardItem'; @@ -62,7 +62,7 @@ export function Cards({ closeCards, openContact, openChannel, openListing }) { { state.display === 'xlarge' && (
- +
)} diff --git a/net/web/src/session/cards/Cards.styled.js b/net/web/src/session/cards/Cards.styled.js index f8e9329b..38698565 100644 --- a/net/web/src/session/cards/Cards.styled.js +++ b/net/web/src/session/cards/Cards.styled.js @@ -31,6 +31,7 @@ export const CardsWrapper = styled.div` border-bottom: 1px solid ${props => props.theme.sectionBorder}; display: flex; flex-direction: row; + height: 48px; .filter { border: 1px solid ${props => props.theme.sectionBorder}; diff --git a/net/web/src/session/contact/Contact.jsx b/net/web/src/session/contact/Contact.jsx index 843f9f0d..e68a2cb0 100644 --- a/net/web/src/session/contact/Contact.jsx +++ b/net/web/src/session/contact/Contact.jsx @@ -1,14 +1,17 @@ -import { Modal } from 'antd'; +import { Modal, Button, Tooltip } from 'antd'; import { ContactWrapper } from './Contact.styled'; import { useContact } from './useContact.hook'; import { Logo } from 'logo/Logo'; -import { DatabaseOutlined, CloseOutlined, RightOutlined, BookOutlined, EnvironmentOutlined } from '@ant-design/icons'; +import { SyncOutlined, UserAddOutlined, UserDeleteOutlined, UserSwitchOutlined, StopOutlined, DeleteOutlined, DatabaseOutlined, CloseOutlined, BookOutlined, EnvironmentOutlined } from '@ant-design/icons'; export function Contact({ close, guid, listing }) { const [ modal, modalContext ] = Modal.useModal(); const { state, actions } = useContact(guid, listing, close); +console.log(state.busy); + + const updateContact = async (action) => { try { await action(); @@ -16,8 +19,9 @@ export function Contact({ close, guid, listing }) { catch (err) { console.log(err); modal.error({ - title: 'Failed to Update Contact', - content: 'Please try again.', + title: {state.strings.operationFailed}, + content: {state.strings.tryAgain}, + bodyStyle: { borderRadius: 8, padding: 16, ...state.menuStyle }, }); } } @@ -25,119 +29,140 @@ export function Contact({ close, guid, listing }) { return ( { modalContext } - { state.display === 'xlarge' && ( -
-
{ state.handle }
-
- -
-
- )} - { state.display !== 'xlarge' && ( -
-
-
+
+ { (state.display === 'xlarge' || state.display === 'small') && ( +
{ state.handle }
- { state.display === 'small' && ( -
- -
- )} - { state.display !== 'small' && ( -
- -
- )} +
+ +
-
- )} + )} + { (state.display !== 'xlarge' && state.display !== 'small') && ( +
{ state.handle }
+ )} -
-
- -
-
-
- { state.name && ( -
{ state.name }
- )} - { !state.name && ( -
name
+
+
+ { state.logoSet && ( + )}
- { state.node && ( +
+
+ { state.name && ( +
{ state.name }
+ )} + { !state.name && ( +
Name
+ )} +
+ { state.node && ( +
+ +
{ state.node }
+
+ )}
- -
{ state.node }
+ + { state.location && ( +
{ state.location }
+ )} + { !state.location && ( +
Location
+ )} +
+
+ + { state.description && ( +
{ state.description }
+ )} + { !state.description && ( +
Description
+ )}
- )} -
- - { state.location && ( -
{ state.location }
- )} - { !state.location && ( -
location
- )}
-
- - { state.description && ( -
{ state.description }
- )} - { !state.description && ( -
description
- )} -
- - { state.status === 'connected' && ( -
-
updateContact(actions.disconnect)}>Disconnect
-
updateContact(actions.disconnectRemove)}>Delete Contact
-
- )} - - { state.status === 'pending' && ( -
-
updateContact(actions.confirmContact)}>Save Contact
-
updateContact(actions.connect)}>Save and Accept
-
updateContact(actions.remove)}>Ignore Request
-
- )} - - { state.status === 'request received' && ( -
-
updateContact(actions.saveConnect)}>Accept Connection
-
updateContact(actions.disconnect)}>Ignore Request
-
- )} - - { state.status === 'request sent' && ( -
-
updateContact(actions.disconnect)}>Cancel Request
-
updateContact(actions.disconnectRemove)}>Delete Contact
-
- )} - - { state.status === 'saved' && ( -
-
updateContact(actions.connect)}>Request Connection
-
updateContact(actions.remove)}>Delete Contact
-
- )} - - { state.status === 'unsaved' && ( -
-
updateContact(actions.saveContact)}>Save Contact
-
updateContact(actions.saveConnect)}>Save and Request
-
- )} -
-
-
-
Status: { state.status }
+
+
Actions
+
+ { state.status === 'connected' && ( + + + + )} + { state.status === 'connected' && ( + + + + )} + { state.status === 'pending' && ( + + + + )} + { state.status === 'pending' && ( + + + + )} + { state.status === 'pending' && ( + + + + )} + { state.status === 'request received' && ( + + + + )} + { state.status === 'request received' && ( + + + + )} + { state.status === 'request sent' && ( + + + + )} + { state.status === 'request sent' && ( + + + + )} + { state.status === 'saved' && ( + + + + )} + { state.status === 'saved' && ( + + + + )} + { state.status === 'unsaved' && ( + + + + )} + { state.status === 'unsaved' && ( + + + + )} + { state.offsync && ( + + + + )} +
+
+ +
+
Status: { state.status }
+
); diff --git a/net/web/src/session/contact/Contact.styled.js b/net/web/src/session/contact/Contact.styled.js index f30c7494..da7ddfcc 100644 --- a/net/web/src/session/contact/Contact.styled.js +++ b/net/web/src/session/contact/Contact.styled.js @@ -1,34 +1,84 @@ import styled from 'styled-components'; -import { Colors } from 'constants/Colors'; export const ContactWrapper = styled.div` height: 100%; width: 100%; - display: flex; - flex-direction: column; - background-color: ${Colors.profileForm}; + .frame { + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + color: ${props => props.theme.mainText}; + } + + .drawer { + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + border-left: 1px solid ${props => props.theme.drawerBorder}; + background-color: ${props => props.theme.selectedArea}; + color: ${props => props.theme.mainText}; + } + + .actions { + display: flex; + flex-grow: 1; + justify-content: center; + padding-top: 16px; + flex-direction: column; + align-items: center; + + .label { + padding-top: 16px; + border-bottom: 1px solid ${props => props.theme.sectionBorder}; + color: ${props => props.theme.hintText}; + font-size: 12px; + width: 50%; + max-width: 300px; + display: flex; + align-items: center; + justify-content: center; + } + } + + .top { + height: 48px; + display: flex; + align-items: center; + justify-content: center; + font-size: 20px; + font-weight: bold; + } .header { margin-left: 16px; margin-right: 16px; height: 48px; - border-bottom: 1px solid ${Colors.profileDivider}; display: flex; + border-bottom: 1px solid ${props => props.theme.headerBorder}; flex-direction: row; align-items: center; + justify-content: center; flex-shrink: 0; + + .handle { + font-size: 20px; + font-weight: bold; + flex-grow: 1; + padding-left: 16px; + } + .handle { font-size: 20px; font-weight: bold; - flex-grow: 1; - padding-left: 16px; } .close { font-size: 18px; - color: ${Colors.primary}; + color: ${props => props.theme.hintText}; cursor: pointer; padding-right: 16px; } @@ -51,6 +101,18 @@ export const ContactWrapper = styled.div` display: flex; flex-direction: column; align-items: center; + + .details { + align-items: center; + padding-left: 16px; + padding-right: 16px; + max-width: 400px; + } + + .logo { + margin-top: 16px; + margin-bottom: 8px; + } } .logo { @@ -58,6 +120,8 @@ export const ContactWrapper = styled.div` width: 20vw; margin-right: 32px; margin-left: 32px; + width: 192px; + height: 192px; } .details { @@ -66,13 +130,14 @@ export const ContactWrapper = styled.div` .notset { font-style: italic; - color: ${Colors.grey}; + color: ${props => props.theme.hintText}; } .name { display: flex; flex-direction: row; align-items: center; + padding-bottom: 8px; .data { padding-right: 8px; @@ -127,7 +192,7 @@ export const ContactWrapper = styled.div` } .close { - color: ${Colors.primary}; + color: ${props => props.theme.mainText}; cursor: pointer; width: 64px; display: flex; @@ -140,19 +205,17 @@ export const ContactWrapper = styled.div` .controls { padding-top: 16px; padding-bottom: 16px; + display: flex; + flex-direction: row; + gap: 16px; .button { - width: 192px; - padding-top: 2px; - padding-bottom: 2px; - margin-top: 16px; display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - border-radius: 2px; - color: ${Colors.white}; - background-color: ${Colors.primary}; + } + + .anticon { + font-size: 18px; + padding-top: 2px; } .label { @@ -173,12 +236,11 @@ export const ContactWrapper = styled.div` } .footer { - flex-grow: 1; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 16px; - color: ${Colors.grey}; + color: ${props => props.theme.hintText}; } ` diff --git a/net/web/src/session/contact/useContact.hook.js b/net/web/src/session/contact/useContact.hook.js index ba608f3c..b5764e14 100644 --- a/net/web/src/session/contact/useContact.hook.js +++ b/net/web/src/session/contact/useContact.hook.js @@ -7,7 +7,9 @@ import { getCardByGuid } from 'context/cardUtil'; export function useContact(guid, listing, close) { const [state, setState] = useState({ + offsync: false, logo: null, + logoSet: false, name: null, cardId: null, location: null, @@ -17,6 +19,8 @@ export function useContact(guid, listing, close) { status: null, busy: false, buttonStatus: 'button idle', + strings: {}, + menuStyle: {}, }); const card = useContext(CardContext); @@ -47,22 +51,24 @@ export function useContact(guid, listing, close) { const { imageSet, name, location, description, handle, node } = profile; const status = statusMap(detail.status); const cardId = contact.id; + const offsync = contact.offsync; const logo = imageSet ? card.actions.getCardImageUrl(cardId) : null; - updateState({ logo, name, location, description, handle, node, status, cardId }); + updateState({ logoSet: true, offsync, logo, name, location, description, handle, node, status, cardId }); } else if (listing) { const { logo, name, location, description, handle, node } = listing; - updateState({ logo, name, location, description, handle, node, status: 'unsaved', cardId: null }); + updateState({ logoSet: true, logo, name, location, description, handle, node, status: 'unsaved', cardId: null }); } else { - updateState({ logo: null, name: null, cardId: null, location: null, description: null, handle: null, + updateState({ logoSet: true, logo: null, name: null, cardId: null, location: null, description: null, handle: null, status: null }); } // eslint-disable-next-line }, [card.state, guid, listing]); useEffect(() => { - updateState({ display: settings.state.display }); + const { display, strings, menuStyle } = settings.state; + updateState({ display, strings, menuStyle }); }, [settings.state]); const applyAction = async (action) => { @@ -149,6 +155,14 @@ export function useContact(guid, listing, close) { close(); }); }, + resync: async () => { + await applyAction(async () => { + const success = await card.actions.resyncCard(state.cardId); + if (!success) { + throw new Error("resync failed"); + } + }); + }, remove: async () => { await applyAction(async () => { await card.actions.removeCard(state.cardId); diff --git a/net/web/src/session/listing/Listing.jsx b/net/web/src/session/listing/Listing.jsx index 9583b299..ccbcb843 100644 --- a/net/web/src/session/listing/Listing.jsx +++ b/net/web/src/session/listing/Listing.jsx @@ -26,50 +26,52 @@ export function Listing({ closeListing, openContact }) { return ( { modalContext } -
- { !state.showFilter && ( -
- -
- )} - { state.showFilter && ( -
- -
- )} -
-
- } value={state.node} spellCheck="false" - disabled={state.disabled} onChange={(e) => actions.onNode(e.target.value)} /> -
+
+
+ { !state.showFilter && ( +
+ +
+ )} { state.showFilter && ( +
+ +
+ )} +
- } value={state.username} spellCheck="false" - onChange={(e) => actions.setUsername(e.target.value)} /> + } value={state.node} spellCheck="false" + disabled={state.disabled} onChange={(e) => actions.onNode(e.target.value)} /> +
+ { state.showFilter && ( +
+ } value={state.username} spellCheck="false" + onChange={(e) => actions.setUsername(e.target.value)} /> +
+ )} +
+
+ +
+ { state.display === 'small' && ( +
+
)}
-
- +
+ { state.contacts.length > 0 && ( + ( + openContact(item.guid, item)} /> + )} /> + )} + { state.contacts.length === 0 && ( +
No Contacts
+ )}
- { state.display === 'small' && ( -
- -
- )} -
-
- { state.contacts.length > 0 && ( - ( - openContact(item.guid, item)} /> - )} /> - )} - { state.contacts.length === 0 && ( -
No Contacts
- )}
); diff --git a/net/web/src/session/listing/Listing.styled.js b/net/web/src/session/listing/Listing.styled.js index ada76060..4dd3b84e 100644 --- a/net/web/src/session/listing/Listing.styled.js +++ b/net/web/src/session/listing/Listing.styled.js @@ -1,23 +1,26 @@ import styled from 'styled-components'; -import { Colors } from 'constants/Colors'; export const ListingWrapper = styled.div` height: 100%; width: 100%; - display: flex; - flex-direction: column; - background-color: ${props => props.theme.itemArea}; - color: ${props => props.theme.mainText}; .drawer { width: 100%; height: 100%; - border-left: 1px solid ${props => props.theme.sectionBorder}; + display: flex; + border-left: 1px solid ${props => props.theme.drawerBorder}; + flex-direction: column; + background-color: ${props => props.theme.itemArea}; + color: ${props => props.theme.mainText}; } - .screen { + .frame { width: 100%; height: 100%; + display: flex; + flex-direction: column; + background-color: ${props => props.theme.itemArea}; + color: ${props => props.theme.mainText}; } .view { diff --git a/net/web/src/session/listing/listingItem/ListingItem.styled.js b/net/web/src/session/listing/listingItem/ListingItem.styled.js index 8c1f72a9..f80983dd 100644 --- a/net/web/src/session/listing/listingItem/ListingItem.styled.js +++ b/net/web/src/session/listing/listingItem/ListingItem.styled.js @@ -1,5 +1,4 @@ import styled from 'styled-components'; -import { Colors } from 'constants/Colors'; export const ListingItemWrapper = styled.div` height: 48px;