From 3629f300292c23d1f227239a6d95df4b684bab1c Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Sat, 2 Mar 2024 21:29:18 -0800 Subject: [PATCH] adding dark mode and translation to thread component --- net/web/src/constants/Strings.js | 22 +++++ .../src/session/conversation/Conversation.jsx | 26 +++--- .../conversation/Conversation.styled.js | 20 ++-- .../conversation/addTopic/AddTopic.jsx | 92 +++++++++++-------- .../conversation/addTopic/AddTopic.styled.js | 22 ++++- .../channelHeader/ChannelHeader.styled.js | 8 +- .../conversation/topicItem/TopicItem.jsx | 55 +++++------ .../topicItem/TopicItem.styled.js | 36 +++++--- .../topicItem/useTopicItem.hook.js | 2 +- .../conversation/useConversation.hook.js | 39 ++++++-- todo | 5 - 11 files changed, 202 insertions(+), 125 deletions(-) diff --git a/net/web/src/constants/Strings.js b/net/web/src/constants/Strings.js index a5ef5c55..e4507877 100644 --- a/net/web/src/constants/Strings.js +++ b/net/web/src/constants/Strings.js @@ -149,6 +149,17 @@ export const en = { webPassword: 'WebRTC Password', failedLoad: 'Failed to Load', limit: 'Limit', + + deleteMessage: 'Deleting Message', + messageHint: 'Are you sure you want to delete the message?', + newMessage: 'New Message', + attachImage: 'Attach Image', + attachVideo: 'Attach Video', + attachAudio: 'Attach Audio', + attachFile: 'Attach File', + fontColor: 'Change Font Color', + fontSize: 'Change Font Size', + postMessage: 'Post Message', }; export const fr = { @@ -302,5 +313,16 @@ export const fr = { webPassword: 'Mot de Passe WebRTC', failedLoad: 'Échec du Chargement', limit: 'Limite', + + deleteMessage: 'Suppression du Message', + messageHint: 'Êtes-vous Sûr de Vouloir Supprimer le Message?', + newMessage: 'Nouveau Message', + attachImage: 'Joindre une Image', + attachVideo: 'Joindre une Vidéo', + attachAudio: 'Joindre un Audio', + attachFile: 'Joindre un Fichier', + fontColor: 'Changer la Couleur du Message', + fontSize: 'Changer la Taille du Message', + postMessage: 'Publier le Message', }; diff --git a/net/web/src/session/conversation/Conversation.jsx b/net/web/src/session/conversation/Conversation.jsx index 598b9fa3..5877fcf5 100644 --- a/net/web/src/session/conversation/Conversation.jsx +++ b/net/web/src/session/conversation/Conversation.jsx @@ -18,6 +18,8 @@ export function Conversation({ closeConversation, openDetails, cardId, channelId remove={() => actions.removeTopic(topic.id)} update={(text) => actions.updateTopic(topic, text)} sealed={state.sealed && !state.contentKey} + strings={state.strings} + menuStyle={state.menuStyle} />) } @@ -43,9 +45,9 @@ export function Conversation({ closeConversation, openDetails, cardId, channelId return ( -
+
{ state.delayed && state.topics.length === 0 && ( -
This Topic Has No Messages
+
This Topic Has No Messages
)} { state.topics.length !== 0 && ( @@ -59,34 +61,34 @@ export function Conversation({ closeConversation, openDetails, cardId, channelId )} { state.loadingInit && ( -
+
)} { state.loadingMore && ( -
+
)}
-
-
+
+
{ state.uploadError && ( -
+
)} { state.upload && !state.uploadError && ( -
+
)} { !state.upload && ( -
+
)}
-
+
{ (!state.sealed || state.contentKey) && ( - + )} { state.uploadError && ( -
+
{ state.display === 'small' && (
actions.clearUploadErrors(cardId, channelId)}> diff --git a/net/web/src/session/conversation/Conversation.styled.js b/net/web/src/session/conversation/Conversation.styled.js index 9ff5f801..63c287ad 100644 --- a/net/web/src/session/conversation/Conversation.styled.js +++ b/net/web/src/session/conversation/Conversation.styled.js @@ -1,18 +1,17 @@ import styled from 'styled-components'; -import { Colors } from 'constants/Colors'; export const ConversationWrapper = styled.div` height: 100%; width: 100%; display: flex; flex-direction: column; - background-color: ${Colors.profileForm}; + background-color: ${props => props.theme.selectedArea}; .header { margin-left: 16px; margin-right: 16px; height: 48px; - border-bottom: 1px solid ${Colors.profileDivider}; + border-bottom: 1px solid ${props => props.theme.headerBorder}; display: flex; flex-direction: row; align-items: center; @@ -27,6 +26,7 @@ export const ConversationWrapper = styled.div` flex-direction: row; align-items: center; min-width: 0; + color: ${props => props.theme.mainText}; .label { padding-left: 8px; @@ -43,7 +43,7 @@ export const ConversationWrapper = styled.div` .button { font-size: 18px; - color: ${Colors.grey}; + color: ${props => props.theme.hintText}; cursor: pointer; padding-right: 16px; padding-left: 16px; @@ -65,7 +65,7 @@ export const ConversationWrapper = styled.div` align-items: center; justify-content: center; font-size: 20; - color: ${Colors.grey}; + color: ${props => props.theme.hintText}; } .loading { @@ -85,21 +85,21 @@ export const ConversationWrapper = styled.div` padding-right: 16px; .line { - border-top: 1px solid ${Colors.divider}; + border-top: 1px solid ${props => props.theme.itemBorder}; } .progress-idle { - border-top: 1px solid ${Colors.divider}; + border-top: 1px solid ${props => props.theme.itemBorder}; height: 1px; } .progress-active { - border-top: 1px solid ${Colors.primary}; + border-top: 1px solid ${props => props.theme.linkText}; height: 1px; } .progress-error { - border-top: 1px solid ${Colors.alert}; + border-top: 1px solid ${props => props.theme.alertText}; width: 100%; height: 1px; display: flex; @@ -122,7 +122,7 @@ export const ConversationWrapper = styled.div` ` export const StatusError = styled.div` - color: ${Colors.error}; + color: ${props => props.theme.alertText}; font-size: 14px; padding-left: 8px; cursor: pointer; diff --git a/net/web/src/session/conversation/addTopic/AddTopic.jsx b/net/web/src/session/conversation/addTopic/AddTopic.jsx index c304b69e..53b1734b 100644 --- a/net/web/src/session/conversation/addTopic/AddTopic.jsx +++ b/net/web/src/session/conversation/addTopic/AddTopic.jsx @@ -1,6 +1,6 @@ import { AddTopicWrapper } from './AddTopic.styled'; import { useAddTopic } from './useAddTopic.hook'; -import { Modal, Input, Menu, Dropdown, Spin } from 'antd'; +import { Modal, Tooltip, Input, Menu, Dropdown, Spin } from 'antd'; import { useRef } from 'react'; import { FieldBinaryOutlined, SoundOutlined, VideoCameraOutlined, PictureOutlined, FontColorsOutlined, FontSizeOutlined, SendOutlined } from '@ant-design/icons'; import { SketchPicker } from "react-color"; @@ -10,7 +10,7 @@ import { BinaryFile } from './binaryFile/BinaryFile'; import { Carousel } from 'carousel/Carousel'; import { Gluejar } from '@charliewilco/gluejar' -export function AddTopic({ contentKey }) { +export function AddTopic({ contentKey, strings, menuStyle }) { const { state, actions } = useAddTopic(contentKey); @@ -35,9 +35,9 @@ export function AddTopic({ contentKey }) { catch (err) { console.log(err); modal.error({ - title: 'Failed to Post Message', - content: 'Please try again.', - bodyStyle: { padding: 16 }, + title: {strings.operationFailed}, + content: {strings.tryAgain}, + bodyStyle: { borderRadius: 8, padding: 16, ...menuStyle }, }); } } @@ -121,54 +121,68 @@ export function AddTopic({ contentKey }) { onSelectVideo(e)} style={{display: 'none'}}/> onSelectBinary(e)} style={{display: 'none'}}/> { state.assets.length > 0 && ( -
+
)} -
- + keyDown(e)} onChange={(e) => actions.setMessageText(e.target.value)} value={state.messageText} autocapitalize="none" />
-
+
{ state.enableImage && ( -
attachImage.current.click()}> - -
+ +
attachImage.current.click()}> + +
+
)} { state.enableVideo && ( -
attachVideo.current.click()}> - -
+ +
attachVideo.current.click()}> + +
+
)} { state.enableAudio && ( -
attachAudio.current.click()}> - -
+ +
attachAudio.current.click()}> + +
+
)} -
attachBinary.current.click()}> - -
-
-
- - - + +
attachBinary.current.click()}> + +
+
+
+
+ + + + +
-
- - - +
+ + + + +
-
-
- { state.busy && ( - - )} - { !state.busy && ( - - )} -
+
+ +
+ { state.busy && ( + + )} + { !state.busy && ( + + )} +
+
diff --git a/net/web/src/session/conversation/addTopic/AddTopic.styled.js b/net/web/src/session/conversation/addTopic/AddTopic.styled.js index e628b7ac..7cd8ecd2 100644 --- a/net/web/src/session/conversation/addTopic/AddTopic.styled.js +++ b/net/web/src/session/conversation/addTopic/AddTopic.styled.js @@ -1,10 +1,22 @@ import styled from 'styled-components'; -import { Colors } from 'constants/Colors'; export const AddTopicWrapper = styled.div` width: 100%; display: flex; flex-direction: column; + background-color: ${props => props.theme.selectedArea}; + color: ${props => props.theme.mainText}; + + textarea { + padding-left: 8px; + background-color: ${props => props.theme.inputArea}; + border: 1px solid ${props => props.theme.sectionBorder}; + color: ${props => props.theme.mainText}; + } + + textarea::placeholder { + color: ${props => props.theme.placeholderText}; + } .message { width: 100%; @@ -30,7 +42,7 @@ export const AddTopicWrapper = styled.div` align-items: center; .bar { - border-left: 1px solid ${Colors.encircle}; + border-left: 1px solid ${props => props.theme.sectionBorder}; height: 36px; padding-right 8px; margin-left: 8px; @@ -44,10 +56,10 @@ export const AddTopicWrapper = styled.div` width: 36px; height: 36px; cursor: pointer; - border: 1px solid ${Colors.divider}; - background-color: ${Colors.white}; + border: 1px solid ${props => props.theme.sectionBorder}; + background-color: ${props => props.theme.inputArea}; font-size: 18px; - color: ${Colors.enabled}; + color: ${props => props.theme.descriptionText}; } .space { diff --git a/net/web/src/session/conversation/channelHeader/ChannelHeader.styled.js b/net/web/src/session/conversation/channelHeader/ChannelHeader.styled.js index e92f5470..143ab17a 100644 --- a/net/web/src/session/conversation/channelHeader/ChannelHeader.styled.js +++ b/net/web/src/session/conversation/channelHeader/ChannelHeader.styled.js @@ -1,11 +1,10 @@ import styled from 'styled-components'; -import { Colors } from 'constants/Colors'; export const ChannelHeaderWrapper = styled.div` margin-left: 16px; margin-right: 16px; height: 48px; - border-bottom: 1px solid ${Colors.profileDivider}; + border-bottom: 1px solid ${props => props.theme.headerBorder}; display: flex; flex-direction: row; align-items: center; @@ -22,6 +21,7 @@ export const ChannelHeaderWrapper = styled.div` min-width: 0; .label { + color: ${props => props.theme.mainText}; padding-left: 8px; white-space: nowrap; text-overflow: ellipsis; @@ -36,7 +36,7 @@ export const ChannelHeaderWrapper = styled.div` .button { font-size: 18px; - color: ${Colors.grey}; + color: ${props => props.theme.hintText}; cursor: pointer; padding-right: 16px; padding-left: 16px; @@ -44,7 +44,7 @@ export const ChannelHeaderWrapper = styled.div` ` export const StatusError = styled.div` - color: ${Colors.error}; + color: ${props => props.theme.alertText}; font-size: 14px; padding-left: 8px; cursor: pointer; diff --git a/net/web/src/session/conversation/topicItem/TopicItem.jsx b/net/web/src/session/conversation/topicItem/TopicItem.jsx index 57a775a2..df505ff9 100644 --- a/net/web/src/session/conversation/topicItem/TopicItem.jsx +++ b/net/web/src/session/conversation/topicItem/TopicItem.jsx @@ -9,18 +9,19 @@ import { ExclamationCircleOutlined, DeleteOutlined, EditOutlined, FireOutlined, import { Carousel } from 'carousel/Carousel'; import { useTopicItem } from './useTopicItem.hook'; -export function TopicItem({ host, contentKey, sealed, topic, update, remove }) { +export function TopicItem({ host, contentKey, sealed, topic, update, remove, strings, menuStyle }) { const [ modal, modalContext ] = Modal.useModal(); const { state, actions } = useTopicItem(topic, contentKey); const removeTopic = () => { modal.confirm({ - title: 'Do you want to delete this message?', + title: {strings.deleteMessage}, + content: {strings.messageHint}, + bodyStyle: { borderRadius: 8, padding: 16, ...menuStyle }, icon: , - bodyStyle: { padding: 16 }, - okText: 'Yes, Delete', - cancelText: 'No, Cancel', + okText: strings.remove, + cancelText: strings.cancel, onOk: async () => { try { await remove(); @@ -28,9 +29,9 @@ export function TopicItem({ host, contentKey, sealed, topic, update, remove }) { catch(err) { console.log(err); modal.error({ - title: 'Failed to Delete Message', - content: 'Please try again.', - bodyStyle: { padding: 16 }, + title: {strings.operationFailed}, + content: {strings.tryAgain}, + bodyStyle: { borderRadius: 8, padding: 16, ...menuStyle }, }); } }, @@ -45,9 +46,9 @@ export function TopicItem({ host, contentKey, sealed, topic, update, remove }) { catch(err) { console.log(err); modal.error({ - title: 'Failed to Update Message', - content: 'Please try again.', - bodyStyle: { padding: 16 }, + title: {strings.operationFailed}, + content: {strings.tryAgain}, + bodyStyle: { borderRadius: 8, padding: 16, ...menuStyle }, }); } }; @@ -71,23 +72,23 @@ export function TopicItem({ host, contentKey, sealed, topic, update, remove }) { return ( { modalContext } -
-
+
+
-
-
{ topic.name }
+
+
{ topic.name }
{ topic.createdStr }
-
-
+
+
{ !sealed && topic.creator && ( -
actions.setEditing(topic.text)}> +
actions.setEditing(topic.text)}>
)} { (host || topic.creator) && ( -
+
)} @@ -95,7 +96,7 @@ export function TopicItem({ host, contentKey, sealed, topic, update, remove }) {
{ topic.status !== 'confirmed' && ( -
+
)} @@ -104,36 +105,36 @@ export function TopicItem({ host, contentKey, sealed, topic, update, remove }) { { topic.assets?.length && ( <> { topic.transform === 'error' && ( -
+
)} { topic.transform === 'incomplete' && ( -
+
)} { topic.transform === 'complete' && ( -
+
)} )} { sealed && ( -
sealed message
+
sealed message
)} { !sealed && !state.editing && ( -
+
{ topic.clickable }
)} { state.editing && ( -
+
actions.setMessage(e.target.value)} rows={3} bordered={false}/> -
+
diff --git a/net/web/src/session/conversation/topicItem/TopicItem.styled.js b/net/web/src/session/conversation/topicItem/TopicItem.styled.js index 3314539f..ea634e2c 100644 --- a/net/web/src/session/conversation/topicItem/TopicItem.styled.js +++ b/net/web/src/session/conversation/topicItem/TopicItem.styled.js @@ -1,10 +1,10 @@ import styled from 'styled-components'; -import { Colors } from 'constants/Colors'; export const TopicItemWrapper = styled.div` display: flex; flex-direction: column; width: 100%; + color: ${props => props.theme.mainText}; .topic-header { display: flex; @@ -13,7 +13,7 @@ export const TopicItemWrapper = styled.div` padding-left: 16px; margin-right: 16px; padding-top: 8px; - border-top: 1px solid #dddddd; + border-top: 1px solid ${props => props.theme.itemBorder}; &:hover .topic-options { visibility: visible; @@ -29,7 +29,7 @@ export const TopicItemWrapper = styled.div` display: flex; flex-direction: row; border-radius: 4px; - background-color: #eeeeee; + background-color: ${props => props.theme.modalArea}; margin-top: 2px; .button { @@ -40,11 +40,11 @@ export const TopicItemWrapper = styled.div` } .remove { - color: ${Colors.warn}; + color: ${props => props.theme.alertText}; } .edit { - color: ${Colors.primary}; + color: ${props => props.theme.linkText}; } } } @@ -63,18 +63,18 @@ export const TopicItemWrapper = styled.div` .comments { padding-left: 8px; cursor: pointer; - color: #888888; + color: ${props => props.theme.descriptionText}; } .set { font-weight: bold; - color: #444444; + color: ${props => props.theme.mainText}; padding-right: 8px; } .unset { font-weight: bold; font-style: italic; - color: #888888; + color: ${props => props.theme.descriptionText}; padding-right: 8px; } .unknown { @@ -87,7 +87,7 @@ export const TopicItemWrapper = styled.div` .sealed-message { font-style: italic; - color: #aaaaaa; + color: ${props => props.theme.placeholderText}; padding-left: 72px; } @@ -97,8 +97,8 @@ export const TopicItemWrapper = styled.div` display: flex; align-items: center; justify-content: center; - background-color: #eeeeee; - color: #888888; + background-color: ${props => props.theme.frameArea}; + color: ${props => props.theme.placeholderText}; margin-left: 72px; } @@ -118,18 +118,30 @@ export const TopicItemWrapper = styled.div` padding-left: 72px; white-space: pre-line; min-height: 4px; + color: ${props => props.theme.mainText}; } .editing { display: flex; flex-direction: column; border-radius: 4px; - border: 1px solid #aaaaaa; + border: 1px solid ${props => props.theme.sectionBorder}; + background-color: ${props => props.theme.inputArea}; margin-top: 8px; margin-bottom: 8px; margin-right: 16px; margin-left: 72px; + textarea { + padding-left: 8px; + background-color: ${props => props.theme.inputArea}; + color: ${props => props.theme.mainText}; + } + + textarea::placeholder { + color: ${props => props.theme.placeholderText}; + } + .controls { display: flex; flex-direction: row; diff --git a/net/web/src/session/conversation/topicItem/useTopicItem.hook.js b/net/web/src/session/conversation/topicItem/useTopicItem.hook.js index 9d04cef0..eaf626f4 100644 --- a/net/web/src/session/conversation/topicItem/useTopicItem.hook.js +++ b/net/web/src/session/conversation/topicItem/useTopicItem.hook.js @@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'; import { fetchWithTimeout } from 'api/fetchUtil'; import { decryptBlock } from 'context/sealUtil'; -export function useTopicItem(topic, contentKey) { +export function useTopicItem(topic, contentKey, strings, menuStyle) { const [state, setState] = useState({ editing: false, diff --git a/net/web/src/session/conversation/useConversation.hook.js b/net/web/src/session/conversation/useConversation.hook.js index e15f5d2b..3f533f30 100644 --- a/net/web/src/session/conversation/useConversation.hook.js +++ b/net/web/src/session/conversation/useConversation.hook.js @@ -22,6 +22,9 @@ export function useConversation(cardId, channelId) { sealed: false, contentKey: null, busy: false, + colors: {}, + strings: {}, + menuStyle: {}, }); const profile = useContext(ProfileContext); @@ -41,8 +44,9 @@ export function useConversation(cardId, channelId) { } useEffect(() => { - updateState({ display: settings.state.display }); - }, [settings]); + const { strings, menuStyle, display, colors } = settings.state; + updateState({ strings, menuStyle, display, colors }); + }, [settings.state]); useEffect(() => { const { dataType, data } = conversation.state.channel?.data?.channelDetail || {}; @@ -125,7 +129,7 @@ export function useConversation(cardId, channelId) { syncChannel(); // eslint-disable-next-line - }, [conversation.state, profile.state, card.state]); + }, [conversation.state, profile.state, card.state, settings.state]); useEffect(() => { topics.current = new Map(); @@ -171,13 +175,28 @@ export function useConversation(cardId, channelId) { const now = new Date(); const offset = now.getTime() - date.getTime(); if(offset < 86400000) { - item.createdStr = date.toLocaleTimeString([], {hour: 'numeric', minute:'2-digit'}); + if (settings.state.timeFormat === '12h') { + item.createdStr = date.toLocaleTimeString("en-US", {hour: 'numeric', minute:'2-digit'}); + } + else { + item.createdStr = date.toLocaleTimeString("en-GB", {hour: 'numeric', minute:'2-digit'}); + } } else if (offset < 31449600000) { - item.createdStr = date.toLocaleDateString("en-US", {day: 'numeric', month:'numeric'}); + if (settings.state.dateFormat === 'mm/dd') { + item.createdStr = date.toLocaleDateString("en-US", {day: 'numeric', month:'numeric'}); + } + else { + item.createdStr = date.toLocaleDateString("en-GB", {day: 'numeric', month:'numeric'}); + } } else { - item.createdStr = date.toLocaleDateString("en-US"); + if (settings.state.dateFormat === 'mm/dd') { + item.createdStr = date.toLocaleDateString("en-US"); + } + else { + item.createdStr = date.toLocaleDateString("en-GB"); + } } if (detail.guid === identity.guid) { @@ -188,7 +207,7 @@ export function useConversation(cardId, channelId) { item.nameSet = true; } else { - item.name = identity.node ? `${identity.handle}@${identity.node}` : identity.handle ? identity.handle : 'unknown'; + item.name = identity.node ? `${identity.handle}/${identity.node}` : identity.handle ? identity.handle : 'unknown'; item.nameSet = false; } } @@ -202,7 +221,7 @@ export function useConversation(cardId, channelId) { item.nameSet = true; } else { - item.name = contact.node ? `${contact.handle}@${contact.node}` : contact.handle ? contact.handle : 'unknown'; + item.name = contact.node ? `${contact.handle}/${contact.node}` : contact.handle ? contact.handle : 'unknown'; item.nameSet = false; } } @@ -220,7 +239,7 @@ export function useConversation(cardId, channelId) { item.assets = message.assets; item.text = message.text; item.clickable = clickableText(message.text); - item.textColor = message.textColor ? message.textColor : '#444444'; + item.textColor = message.textColor ? message.textColor : state.colors.mainText; item.textSize = message.textSize ? message.textSize : 14; } if (detail.dataType === 'sealedtopic' && state.contentKey) { @@ -228,7 +247,7 @@ export function useConversation(cardId, channelId) { item.assets = subject.message.assets; item.text = subject.message.text; item.clickable = clickableText(subject.message.text); - item.textColor = subject.message.textColor ? subject.message.textColor : '#444444'; + item.textColor = subject.message.textColor ? subject.message.textColor : state.colors.mainText; item.textSize = subject.message.textSize ? subject.message.textSize : 14; } } diff --git a/todo b/todo index 02a0194c..c187a7be 100644 --- a/todo +++ b/todo @@ -1,9 +1,4 @@ -thread: - - dark style - - translation - - button tool tip - details: - back button - dark style