diff --git a/qortal-ui-core/font/KoHo.ttf b/qortal-ui-core/font/KoHo.ttf
new file mode 100644
index 00000000..72841e9d
Binary files /dev/null and b/qortal-ui-core/font/KoHo.ttf differ
diff --git a/qortal-ui-core/font/Livvic.ttf b/qortal-ui-core/font/Livvic.ttf
new file mode 100644
index 00000000..f477b285
Binary files /dev/null and b/qortal-ui-core/font/Livvic.ttf differ
diff --git a/qortal-ui-core/font/Montserrat.ttf b/qortal-ui-core/font/Montserrat.ttf
new file mode 100644
index 00000000..656db666
Binary files /dev/null and b/qortal-ui-core/font/Montserrat.ttf differ
diff --git a/qortal-ui-core/font/material-icons.css b/qortal-ui-core/font/material-icons.css
index 2270c09d..422f0fa1 100644
--- a/qortal-ui-core/font/material-icons.css
+++ b/qortal-ui-core/font/material-icons.css
@@ -2,19 +2,42 @@
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
- src: url(MaterialIcons-Regular.eot); /* For IE6-8 */
+ src: url(MaterialIcons-Regular.eot);
+ /* For IE6-8 */
src: local('Material Icons'),
- local('MaterialIcons-Regular'),
- url(MaterialIcons-Regular.woff2) format('woff2'),
- url(MaterialIcons-Regular.woff) format('woff'),
- url(MaterialIcons-Regular.ttf) format('truetype');
+ local('MaterialIcons-Regular'),
+ url(MaterialIcons-Regular.woff2) format('woff2'),
+ url(MaterialIcons-Regular.woff) format('woff'),
+ url(MaterialIcons-Regular.ttf) format('truetype');
+}
+
+@font-face {
+ font-family: 'Montserrat';
+ src: local('Montserrat'),
+ local('Montserrat'),
+ url(Montserrat.ttf) format('truetype');
+}
+
+@font-face {
+ font-family: 'KoHo';
+ src: local('KoHo'),
+ local('KoHo'),
+ url(KoHo.ttf) format('truetype');
+}
+
+@font-face {
+ font-family: 'Livvic';
+ src: local('Livvic'),
+ local('Livvic'),
+ url(Livvic.ttf) format('truetype');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
- font-size: 24px; /* Preferred icon size */
+ font-size: 24px;
+ /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
@@ -33,4 +56,4 @@
/* Support for IE. */
font-feature-settings: 'liga';
-}
+}
\ No newline at end of file
diff --git a/qortal-ui-core/language/us.json b/qortal-ui-core/language/us.json
index c2bc9565..265fd645 100644
--- a/qortal-ui-core/language/us.json
+++ b/qortal-ui-core/language/us.json
@@ -465,8 +465,8 @@
"cchange3": "Blocked Users",
"cchange4": "New Message",
"cchange5": "(Click to scroll down)",
- "cchange6": "Type the name or address of who you want to chat with to send a private message!",
- "cchange7": "Name / Address",
+ "cchange6": "Type the name or address of who you want to chat with to send a private message! You can validate the person's name by clicking on the book icon.",
+ "cchange7": "Username / Address",
"cchange8": "Message...",
"cchange9": "Send",
"cchange10": "Blocked Users List",
@@ -478,7 +478,7 @@
"cchange16": "Successfully unblocked this user.",
"cchange17": "Error occurred when trying to unblock this user. Please try again!",
"cchange18": "unblock",
- "cchange19": "Invalid Name / Address, Check the name / address and retry...",
+ "cchange19": "Invalid Username / Address, Check the name / address and retry...",
"cchange20": "Message Sent Successfully!",
"cchange21": "Sending failed, Please retry...",
"cchange22": "Loading Messages...",
@@ -492,7 +492,11 @@
"cchange30": "Uploading image. This may take up to one minute.",
"cchange31": "Deleting image. This may take up to one minute.",
"cchange33": "Cancel",
- "cchange34": "This chat message is using an older message version and cannot use this feature."
+ "cchange34": "This chat message is using an older message version and cannot use this feature.",
+ "cchange35": "Error when trying to fetch the user's name. Please try again!",
+ "cchange36": "Search Results",
+ "cchange37": "No Results Found",
+ "cchange38": "User Verified"
},
"welcomepage": {
"wcchange1": "Welcome to Q-Chat",
@@ -521,7 +525,7 @@
"bcchange13": "Reaction",
"bcchange14": "Forward",
"bcchange15": "Message Forwarded",
- "bcchange16": "Choose recipient",
+ "bcchange16": "Choose Recipient or Search for One Below",
"bcchange17": "FORWARDED"
},
"grouppage": {
diff --git a/qortal-ui-plugins/plugins/core/components/ChatPage.js b/qortal-ui-plugins/plugins/core/components/ChatPage.js
index fbb48b94..9e33352c 100644
--- a/qortal-ui-plugins/plugins/core/components/ChatPage.js
+++ b/qortal-ui-plugins/plugins/core/components/ChatPage.js
@@ -14,19 +14,19 @@ import './ChatScroller.js';
import './LevelFounder.js';
import './NameMenu.js';
import './TimeAgo.js';
-import './ChatTextEditor';
-import './WrapperModal';
+import './ChatTextEditor.js';
+import './WrapperModal.js';
import './ChatSelect.js'
+import './ChatSeachResults.js';
import '@polymer/paper-spinner/paper-spinner-lite.js';
import '@material/mwc-button';
import '@material/mwc-dialog';
import '@material/mwc-icon';
import { replaceMessagesEdited } from '../../utils/replace-messages-edited.js';
import { publishData } from '../../utils/publish-image.js';
+import { EmojiPicker } from 'emoji-picker-js';
import WebWorker from 'web-worker:./computePowWorker.js';
import WebWorkerImage from 'web-worker:./computePowWorkerImage.js';
-import { EmojiPicker } from 'emoji-picker-js';
-
// const messagesCache = localForage.createInstance({
// name: "messages-cache",
@@ -67,469 +67,585 @@ class ChatPage extends LitElement {
chatEditorNewChat: { type: Object },
userLanguage: { type: String },
lastMessageRefVisible: { type: Boolean },
- isLoadingOldMessages: {type: Boolean},
+ isLoadingOldMessages: { type: Boolean },
isEditMessageOpen: { type: Boolean },
- webSocket: {attribute: false},
- chatHeads: {type: Array},
- forwardActiveChatHeadUrl: {type: String},
- openForwardOpen: {type: Boolean}
+ webSocket: { attribute: false },
+ chatHeads: { type: Array },
+ forwardActiveChatHeadUrl: { type: Object },
+ openForwardOpen: {type: Boolean },
+ userFound: { type: Array },
+ userFoundModalOpen: { type: Boolean },
}
}
static get styles() {
- return css`
- html {
- scroll-behavior: smooth;
- }
-
- .chat-head-container {
- display: flex;
- justify-content: flex-start;
- flex-direction: column;
- height: 50vh;
- overflow-y: auto;
- width: 100%;
- }
-
- .chat-container {
- display: grid;
- grid-template-rows: minmax(6%, 92vh) minmax(40px, auto);
- max-height: 100%;
- }
-
- .chat-text-area {
- display: flex;
- position: relative;
- justify-content: center;
- min-height: 60px;
- max-height: 100%;
- }
-
- .chat-text-area .typing-area {
- display: flex;
- flex-direction: column;
- width: 98%;
- box-sizing: border-box;
- margin-bottom: 8px;
- border: 1px solid var(--chat-bubble-bg);
- border-radius: 10px;
- background: var(--chat-bubble-bg);
- }
-
- .chat-text-area .typing-area textarea {
- display: none;
- }
-
- .chat-text-area .typing-area .chat-editor {
- display: flex;
- max-height: -webkit-fill-available;
- width: 100%;
- border-color: transparent;
- margin: 0;
- padding: 0;
- border: none;
- }
-
- .repliedTo-container {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- padding: 10px 10px 8px 10px;
- }
-
- .repliedTo-subcontainer {
- display: flex;
- flex-direction: row;
- align-items: center;
- gap: 15px;
- width: 100%;
- }
-
- .repliedTo-message {
- display: flex;
- flex-direction: column;
- gap: 5px;
- width: 100%;
- }
-
- .senderName {
- margin: 0;
- color: var(--mdc-theme-primary);
- font-weight: bold;
- user-select: none;
- }
-
- .original-message {
- color: var(--chat-bubble-msg-color);
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- margin: 0;
- width: 800px;
- }
-
- .reply-icon {
- width: 20px;
- color: var(--mdc-theme-primary);
- }
-
- .close-icon {
- color: #676b71;
- width: 18px;
- transition: all 0.1s ease-in-out;
- }
-
- .close-icon:hover {
- cursor: pointer;
- color: #494c50;
- }
-
- .chat-text-area .typing-area .chatbar {
- position: relative;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- height: auto;
- padding: 5px 5px 5px 7px;
- overflow-y: hidden;
- }
-
- .chatbar-container {
- width: 100%;
- display: flex;
- height: auto;
- overflow: hidden;
- }
-
- .chat-text-area .typing-area .emoji-button {
- width: 45px;
- height: 40px;
- padding-top: 4px;
- border: none;
- outline: none;
- background: transparent;
- cursor: pointer;
- max-height: 40px;
- color: var(--black);
- }
-
- .emoji-button-caption {
- width: 45px;
- height: 40px;
- padding-top: 4px;
- border: none;
- outline: none;
- background: transparent;
- cursor: pointer;
- max-height: 40px;
- color: var(--black);
- }
-
- .caption-container {
- width: 100%;
- display: flex;
- height: auto;
- overflow: hidden;
- justify-content: center;
- background-color: var(--white);
- padding: 5px;
- border-radius: 1px;
- }
-
- .chatbar-caption {
- font-family: Roboto, sans-serif;
- width: 70%;
- margin-right: 10px;
- outline: none;
- align-items: center;
- font-size: 18px;
- resize: none;
- border-top: 0;
- border-right: 0;
- border-left: 0;
- border-bottom: 1px solid #cac8c8;
- padding: 3px;
- }
-
- .message-size-container {
- display: flex;
- justify-content: flex-end;
- width: 100%;
- }
-
- .message-size {
- font-family: Roboto, sans-serif;
- font-size: 12px;
- color: black;
- }
-
- .lds-grid {
- width: 120px;
- height: 120px;
- position: absolute;
- left: 50%;
- top: 40%;
- }
-
- .lds-grid div {
- position: absolute;
- width: 34px;
- height: 34px;
- border-radius: 50%;
- background: #03a9f4;
- animation: lds-grid 1.2s linear infinite;
- }
-
- .lds-grid div:nth-child(1) {
- top: 4px;
- left: 4px;
- animation-delay: 0s;
- }
-
- .lds-grid div:nth-child(2) {
- top: 4px;
- left: 48px;
- animation-delay: -0.4s;
- }
-
- .lds-grid div:nth-child(3) {
- top: 4px;
- left: 90px;
- animation-delay: -0.8s;
- }
-
- .lds-grid div:nth-child(4) {
- top: 50px;
- left: 4px;
- animation-delay: -0.4s;
- }
-
- .lds-grid div:nth-child(5) {
- top: 50px;
- left: 48px;
- animation-delay: -0.8s;
- }
-
- .lds-grid div:nth-child(6) {
- top: 50px;
- left: 90px;
- animation-delay: -1.2s;
- }
-
- .lds-grid div:nth-child(7) {
- top: 95px;
- left: 4px;
- animation-delay: -0.8s;
- }
-
- .lds-grid div:nth-child(8) {
- top: 95px;
- left: 48px;
- animation-delay: -1.2s;
- }
-
- .lds-grid div:nth-child(9) {
- top: 95px;
- left: 90px;
- animation-delay: -1.6s;
- }
-
- @keyframes lds-grid {
- 0%, 100% {
- opacity: 1;
- }
- 50% {
- opacity: 0.5;
- }
- }
-
- .float-left {
- float: left;
- }
-
- img {
- border-radius: 25%;
- }
-
- .dialogCustom {
- position: fixed;
- z-index: 10000;
- display: flex;
- justify-content: center;
- flex-direction: column;
- align-items: center;
- top: 10px;
- right: 20px;
- user-select: none;
- }
-
- .dialogCustom p {
- color: var(--black)
- }
-
- .dialogCustomInner {
- min-width: 300px;
- height: 40px;
- background-color: var(--white);
- box-shadow: rgb(119 119 119 / 32%) 0px 4px 12px;
- padding: 10px;
- border-radius: 4px;
- }
-
- .dialogCustomInner ul {
- padding-left: 0px
- }
- .dialogCustomInner li {
- margin-bottom: 10px;
- }
-
- .marginLoader {
- margin-right: 8px;
- }
-
- .smallLoading,
- .smallLoading:after {
- border-radius: 50%;
- width: 2px;
- height: 2px;
- }
-
- .smallLoading {
- border-width: 0.8em;
- border-style: solid;
- border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2)
- rgba(3, 169, 244, 0.2) rgb(3, 169, 244);
- font-size: 10px;
- position: relative;
- text-indent: -9999em;
- transform: translateZ(0px);
- animation: 1.1s linear 0s infinite normal none running loadingAnimation;
- }
-
- @-webkit-keyframes loadingAnimation {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- @keyframes loadingAnimation {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg);
- }
- }
-
- /* Add Image Modal Dialog Styling */
-
- .dialog-container {
- position: relative;
- display: flex;
- align-items: center;
- flex-direction: column;
- padding: 0 10px;
- gap: 10px;
- height: 100%;
- }
-
- .dialog-container-title {
- color: var(--black);
- font-size: 18px;
- }
-
- .dialog-container-loader {
- position: relative;
- display: flex;
- align-items: center;
- padding: 0 10px;
- gap: 10px;
- height: 100%;
- }
-
- .dialog-image {
- width: 100%;
- max-height: 300px;
- border-radius: 0;
- object-fit: contain;
- }
-
- .last-message-ref {
- position: absolute;
- font-size: 18px;
- top: -40px;
- right: 30px;
- width: 50;
- height: 50;
- z-index: 5;
- color: black;
- background-color: white;
- border-radius: 50%;
- transition: all 0.1s ease-in-out;
- }
-
- .last-message-ref:hover {
- cursor: pointer;
- transform: scale(1.1);
- }
-
- .arrow-down-icon {
- transform: scale(1.15);
- }
-
- .modal-button-row {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- }
-
- .modal-button {
- font-family: Roboto, sans-serif;
- font-size: 16px;
- color: var(--mdc-theme-primary);
- background-color: transparent;
- padding: 8px 10px;
- border-radius: 5px;
- border: none;
- transition: all 0.3s ease-in-out;
- }
-
- .modal-button-red {
- font-family: Roboto, sans-serif;
- font-size: 16px;
- color: #F44336;
- background-color: transparent;
- padding: 8px 10px;
- border-radius: 5px;
- border: none;
- transition: all 0.3s ease-in-out;
- }
-
- .modal-button-red:hover {
- cursor: pointer;
- background-color: #f4433663;
- }
-
- .modal-button:hover {
- cursor: pointer;
- background-color: #03a8f475;
- }
- `
+ return css`
+ html {
+ scroll-behavior: smooth;
}
+ .chat-head-container {
+ display: flex;
+ justify-content: flex-start;
+ flex-direction: column;
+ height: 50vh;
+ overflow-y: auto;
+ overflow-x: hidden;
+ width: 100%;
+ }
+
+ .chat-container {
+ display: grid;
+ grid-template-rows: minmax(6%, 92vh) minmax(40px, auto);
+ max-height: 100%;
+ }
+
+ .chat-text-area {
+ display: flex;
+ position: relative;
+ justify-content: center;
+ min-height: 60px;
+ max-height: 100%;
+ }
+
+ .chat-text-area .typing-area {
+ display: flex;
+ flex-direction: column;
+ width: 98%;
+ box-sizing: border-box;
+ margin-bottom: 8px;
+ border: 1px solid var(--chat-bubble-bg);
+ border-radius: 10px;
+ background: var(--chat-bubble-bg);
+ }
+
+ .chat-text-area .typing-area textarea {
+ display: none;
+ }
+
+ .chat-text-area .typing-area .chat-editor {
+ display: flex;
+ max-height: -webkit-fill-available;
+ width: 100%;
+ border-color: transparent;
+ margin: 0;
+ padding: 0;
+ border: none;
+ }
+
+ .repliedTo-container {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ padding: 10px 10px 8px 10px;
+ }
+
+ .repliedTo-subcontainer {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 15px;
+ width: 100%;
+ }
+
+ .repliedTo-message {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ width: 100%;
+ }
+
+ .senderName {
+ margin: 0;
+ color: var(--mdc-theme-primary);
+ font-weight: bold;
+ user-select: none;
+ }
+
+ .original-message {
+ color: var(--chat-bubble-msg-color);
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ margin: 0;
+ width: 800px;
+ }
+
+ .reply-icon {
+ width: 20px;
+ color: var(--mdc-theme-primary);
+ }
+
+ .close-icon {
+ color: #676b71;
+ width: 18px;
+ transition: all 0.1s ease-in-out;
+ }
+
+ .close-icon:hover {
+ cursor: pointer;
+ color: #494c50;
+ }
+
+ .chat-text-area .typing-area .chatbar {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ height: auto;
+ padding: 5px 5px 5px 7px;
+ overflow-y: hidden;
+ }
+
+ .chatbar-container {
+ width: 100%;
+ display: flex;
+ height: auto;
+ overflow: hidden;
+ }
+
+ .chat-text-area .typing-area .emoji-button {
+ width: 45px;
+ height: 40px;
+ padding-top: 4px;
+ border: none;
+ outline: none;
+ background: transparent;
+ cursor: pointer;
+ max-height: 40px;
+ color: var(--black);
+ }
+
+ .emoji-button-caption {
+ width: 45px;
+ height: 40px;
+ padding-top: 4px;
+ border: none;
+ outline: none;
+ background: transparent;
+ cursor: pointer;
+ max-height: 40px;
+ color: var(--black);
+ }
+
+ .caption-container {
+ width: 100%;
+ display: flex;
+ height: auto;
+ overflow: hidden;
+ justify-content: center;
+ background-color: var(--white);
+ padding: 5px;
+ border-radius: 1px;
+ }
+
+ .chatbar-caption {
+ font-family: Roboto, sans-serif;
+ width: 70%;
+ margin-right: 10px;
+ outline: none;
+ align-items: center;
+ font-size: 18px;
+ resize: none;
+ border-top: 0;
+ border-right: 0;
+ border-left: 0;
+ border-bottom: 1px solid #cac8c8;
+ padding: 3px;
+ }
+
+ .message-size-container {
+ display: flex;
+ justify-content: flex-end;
+ width: 100%;
+ }
+
+ .message-size {
+ font-family: Roboto, sans-serif;
+ font-size: 12px;
+ color: black;
+ }
+
+ .lds-grid {
+ width: 120px;
+ height: 120px;
+ position: absolute;
+ left: 50%;
+ top: 40%;
+ }
+
+ .lds-grid div {
+ position: absolute;
+ width: 34px;
+ height: 34px;
+ border-radius: 50%;
+ background: #03a9f4;
+ animation: lds-grid 1.2s linear infinite;
+ }
+
+ .lds-grid div:nth-child(1) {
+ top: 4px;
+ left: 4px;
+ animation-delay: 0s;
+ }
+
+ .lds-grid div:nth-child(2) {
+ top: 4px;
+ left: 48px;
+ animation-delay: -0.4s;
+ }
+
+ .lds-grid div:nth-child(3) {
+ top: 4px;
+ left: 90px;
+ animation-delay: -0.8s;
+ }
+
+ .lds-grid div:nth-child(4) {
+ top: 50px;
+ left: 4px;
+ animation-delay: -0.4s;
+ }
+
+ .lds-grid div:nth-child(5) {
+ top: 50px;
+ left: 48px;
+ animation-delay: -0.8s;
+ }
+
+ .lds-grid div:nth-child(6) {
+ top: 50px;
+ left: 90px;
+ animation-delay: -1.2s;
+ }
+
+ .lds-grid div:nth-child(7) {
+ top: 95px;
+ left: 4px;
+ animation-delay: -0.8s;
+ }
+
+ .lds-grid div:nth-child(8) {
+ top: 95px;
+ left: 48px;
+ animation-delay: -1.2s;
+ }
+
+ .lds-grid div:nth-child(9) {
+ top: 95px;
+ left: 90px;
+ animation-delay: -1.6s;
+ }
+
+ @keyframes lds-grid {
+ 0%, 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.5;
+ }
+}
+
+ .float-left {
+ float: left;
+ }
+
+ img {
+ border-radius: 25%;
+ }
+
+ .dialogCustom {
+ position: fixed;
+ z-index: 10000;
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ align-items: center;
+ top: 10px;
+ right: 20px;
+ user-select: none;
+ }
+
+ .dialogCustom p {
+ color: var(--black)
+ }
+
+ .dialogCustomInner {
+ min-width: 300px;
+ height: 40px;
+ background-color: var(--white);
+ box-shadow: rgb(119 119 119 / 32%) 0px 4px 12px;
+ padding: 10px;
+ border-radius: 4px;
+ }
+
+ .dialogCustomInner ul {
+ padding-left: 0px
+ }
+
+ .dialogCustomInner li {
+ margin-bottom: 10px;
+ }
+
+ .marginLoader {
+ margin-right: 8px;
+ }
+
+ .smallLoading,
+ .smallLoading:after {
+ border-radius: 50%;
+ width: 2px;
+ height: 2px;
+ }
+
+ .smallLoading {
+ border-width: 0.8em;
+ border-style: solid;
+ border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2)
+ rgba(3, 169, 244, 0.2) rgb(3, 169, 244);
+ font-size: 10px;
+ position: relative;
+ text-indent: -9999em;
+ transform: translateZ(0px);
+ animation: 1.1s linear 0s infinite normal none running loadingAnimation;
+ }
+
+ @-webkit-keyframes loadingAnimation {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+ }
+
+ @keyframes loadingAnimation {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+ }
+
+ /* Add Image Modal Dialog Styling */
+
+ .dialog-container {
+ position: relative;
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ padding: 0 10px;
+ gap: 10px;
+ height: 100%;
+ }
+
+ .dialog-container-title {
+ font-family: Montserrat;
+ color: var(--black);
+ font-size: 20px;
+ margin: 15px 0 0 0;
+ }
+
+ .divider {
+ height: 1px;
+ background-color: var(--chat-bubble-msg-color);
+ user-select: none;
+ width: 70%;
+ margin-bottom: 20px;
+ }
+
+ .dialog-container-loader {
+ position: relative;
+ display: flex;
+ align-items: center;
+ padding: 0 10px;
+ gap: 10px;
+ height: 100%;
+ }
+
+ .dialog-image {
+ width: 100%;
+ max-height: 300px;
+ border-radius: 0;
+ object-fit: contain;
+ }
+
+ .last-message-ref {
+ position: absolute;
+ font-size: 18px;
+ top: -40px;
+ right: 30px;
+ width: 50;
+ height: 50;
+ z-index: 5;
+ color: black;
+ background-color: white;
+ border-radius: 50%;
+ transition: all 0.1s ease-in-out;
+}
+
+ .last-message-ref:hover {
+ cursor: pointer;
+ transform: scale(1.1);
+ }
+
+ .arrow-down-icon {
+ transform: scale(1.15);
+ }
+
+ .modal-button-row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ }
+
+ .modal-button {
+ font-family: Roboto, sans-serif;
+ font-size: 16px;
+ color: var(--mdc-theme-primary);
+ background-color: transparent;
+ padding: 8px 10px;
+ border-radius: 5px;
+ border: none;
+ transition: all 0.3s ease-in-out;
+ }
+
+ .modal-button-red {
+ font-family: Roboto, sans-serif;
+ font-size: 16px;
+ color: #F44336;
+ background-color: transparent;
+ padding: 8px 10px;
+ border-radius: 5px;
+ border: none;
+ transition: all 0.3s ease-in-out;
+ }
+
+ .modal-button-red:hover {
+ cursor: pointer;
+ background-color: #f4433663;
+ }
+
+ .modal-button:hover {
+ cursor: pointer;
+ background-color: #03a8f475;
+ }
+
+ .name-input {
+ width: 100%;
+ margin-bottom: 15px;
+ outline: 0;
+ border-width: 0 0 2px;
+ border-color: var(--mdc-theme-primary);
+ background-color: transparent;
+ padding: 10px;
+ font-family: Roboto, sans-serif;
+ font-size: 15px;
+ color: var(--chat-bubble-msg-color);
+ }
+
+ .name-input::selection {
+ background-color: var(--mdc-theme-primary);
+ color: white;
+ }
+
+ .name-input::placeholder {
+ opacity: 0.9;
+ color: var(--black);
+ }
+
+ .search-results-div {
+ position: absolute;
+ top: 25px;
+ right: 25px;
+ }
+
+ .search-field {
+ width: 100%;
+ position: relative;
+ margin-bottom: 5px;
+ }
+
+ .search-icon {
+ position: absolute;
+ right: 3px;
+ top: 0;
+ color: var(--chat-bubble-msg-color);
+ transition: all 0.3s ease-in-out;
+ background: none;
+ border-radius: 50%;
+ padding: 6px 3px;
+ font-size: 21px;
+ }
+
+ .search-icon:hover {
+ cursor: pointer;
+ background: #d7d7d75c;
+ }
+
+ .user-verified {
+ position: absolute;
+ top: 0;
+ right: 5px;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ color: #04aa2e;
+ font-size: 13px;
+ }
+
+ .user-selected {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin: 0;
+ box-shadow: rgb(0 0 0 / 16%) 0px 3px 6px, rgb(0 0 0 / 23%) 0px 3px 6px;
+ padding: 18px 20px;
+ color: var(--chat-bubble-msg-color);
+ border-radius: 5px;
+ background-color: #ececec96;
+ }
+
+ .user-selected-name {
+ font-family: Roboto, sans-serif;
+ margin: 0;
+ font-size: 16px;
+ }
+
+ .forwarding-container {
+ display: flex;
+ gap: 15px;
+ }
+
+ .user-selected-forwarding {
+ font-family: Livvic, sans-serif;
+ margin: 0;
+ font-size: 16px;
+ }
+
+ .close-forwarding {
+ color: #676b71;
+ width: 14px;
+ transition: all 0.1s ease-in-out;
+ }
+
+ .close-forwarding:hover {
+ cursor: pointer;
+ color: #4e5054;
+ }
+`
+}
+
constructor() {
super()
- this.changeMsgInput = this.changeMsgInput.bind(this)
this.getOldMessage = this.getOldMessage.bind(this)
this._sendMessage = this._sendMessage.bind(this)
this.insertImage = this.insertImage.bind(this)
@@ -570,11 +686,17 @@ class ChatPage extends LitElement {
boxShadow: 'rgba(4, 4, 5, 0.15) 0px 0px 0px 1px, rgba(0, 0, 0, 0.24) 0px 8px 16px 0px'
});
this.openForwardOpen = false
+ this.userFoundModalOpen = false
+ this.userFound = []
+ this.forwardActiveChatHeadUrl = {
+ url: "",
+ name: "",
+ selected: false
+ }
}
-
-
render() {
+ console.log(25, 'here');
return html`
@@ -651,9 +773,7 @@ class ChatPage extends LitElement {
.chatEditor=${this.chatEditor}
.imageFile=${this.imageFile}
.insertImage=${this.insertImage}
- .chatMessageInput=${this.chatMessageInput}
.editedMessageObj=${this.editedMessageObj}
- .mirrorChatInput=${this.mirrorChatInput}
?isLoading=${this.isLoading}
?isLoadingMessages=${this.isLoadingMessages}
?isEditMessageOpen=${this.isEditMessageOpen}>
@@ -676,9 +796,9 @@ class ChatPage extends LitElement {
`: ''}
{
- this.chatEditorNewChat.resetValue()
- this.removeImage()
+ .onClickFunc=${() => {
+ this.chatEditorNewChat.resetValue();
+ this.removeImage();
} }
style=${(this.imageFile && !this.isUploadingImage) ? "display: block" : "display: none"}>
@@ -705,14 +825,15 @@ class ChatPage extends LitElement {
{
- this.openForwardOpen = false
- this.forwardActiveChatHeadUrl = ""
+ .onClickFunc=${() => {
+ this.openForwardOpen = false;
+ this.forwardActiveChatHeadUrl = {};
+ this.chatEditor.enable();
+ this.requestUpdate();
} }
style=${this.openForwardOpen ? "display: block" : "display: none"}>
@@ -737,18 +860,88 @@ class ChatPage extends LitElement {
${translate("blockpage.bcchange16")}
+
- ${this.chatHeads.map((item)=> {
- return html` {
- this.forwardActiveChatHeadUrl = val
- }} chatInfo=${JSON.stringify(item)}>`
- })}
-
+
+
{
+ this.forwardActiveChatHeadUrl = {};
+ this.requestUpdate();
+ }
+ }
+ />
+ ${this.forwardActiveChatHeadUrl.selected ? (
+ html`
+
+
${translate("chatpage.cchange38")}
+
+
+ `
+ ) : (
+ html`
+
+
+ `
+ )}
+
+ ${this.forwardActiveChatHeadUrl.selected ? (
+ html`
+
+
+ ${this.forwardActiveChatHeadUrl.name}
+
+
+
+ Forwarding...
+
+
{
+ this.userFound = [];
+ this.forwardActiveChatHeadUrl = {};
+ this.requestUpdate();
+ this.shadowRoot.getElementById("sendTo").value = "";
+ }}>
+
+
+
+ `
+ ) : (
+ html`
+ ${this.chatHeads.map((item) => {
+ return html`
+
{
+ this.forwardActiveChatHeadUrl = {
+ ...this.forwardActiveChatHeadUrl,
+ url: val
+ };
+ this.userFound = [];
+ }}
+ chatInfo=${JSON.stringify(item)}>
+ `
+ })}
+ `
+ )}
+
@@ -763,47 +956,73 @@ class ChatPage extends LitElement {
-
+
+ {
+ this.forwardActiveChatHeadUrl = {
+ ...this.forwardActiveChatHeadUrl,
+ url: `direct/${result.owner}`,
+ name: result.name,
+ selected: true
+ };
+ this.userFound = [];
+ this.userFoundModalOpen = false;
+ }}
+ .closeFunc=${() => {
+ this.userFoundModalOpen = false;
+ this.userFound = [];
+ }}
+ .searchResults=${this.userFound}
+ ?isOpen=${this.userFoundModalOpen}
+ ?loading=${this.isLoading}>
+
+
+
`
}
+ async userSearch() {
+ const nameValue = this.shadowRoot.getElementById('sendTo').value;
+ if (!nameValue) {
+ this.userFound = [];
+ this.userFoundModalOpen = true;
+ return;
+ }
+ try {
+ const result = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/names/${nameValue}`
+ })
+ if (result.error === 401) {
+ this.userFound = [];
+ } else {
+ this.userFound = [
+ ...this.userFound,
+ result,
+ ];
+ }
+ this.userFoundModalOpen = true;
+ } catch (error) {
+ console.error(error);
+ let err4string = get("chatpage.cchange35");
+ parentEpml.request('showSnackBar', `${err4string}`)
+ }
+ }
+
setForwardProperties(forwardedMessage){
this.openForwardOpen = true
this.forwardedMessage = forwardedMessage
}
-
- async sendForwardMessage(){
- let parsedMessageObj = {}
- let publicKey = {
- hasPubKey: false,
- key: ''
- }
+
+ async sendForwardMessage() {
+ let parsedMessageObj = {};
try {
parsedMessageObj = JSON.parse(this.forwardedMessage);
-
- } catch (error) {
- parsedMessageObj = {}
- }
-
- try {
- const res = await parentEpml.request('apiCall', {
- type: 'api',
- url: `/addresses/publickey/${this.forwardChatId}`
- })
- if (res.error === 102) {
- publicKey.key = ''
- publicKey.hasPubKey = false
- } else if (res !== false) {
- publicKey.key = res
- publicKey.hasPubKey = true
- } else {
- publicKey.key = ''
- publicKey.hasPubKey = false
- }
- } catch (error) {
-
+ }
+ catch (error) {
+ parsedMessageObj = {};
}
try {
@@ -812,17 +1031,10 @@ class ChatPage extends LitElement {
type: 'forward'
}
delete message.reactions
- const stringifyMessageObject = JSON.stringify(message)
- this.sendMessage(stringifyMessageObject, undefined, '', true, {
- isReceipient: true,
- chatId: 'Qdxha59Cm1Ty4QkKMBWPnKrNigcDCDk6eq',
- publicKey: {
- hasPubKey: false,
- key: ''
- }
- })
+ const stringifyMessageObject = JSON.stringify(message);
+ this.sendMessage(stringifyMessageObject, undefined, '', true)
} catch (error) {
- console.log({error})
+ console.log({error});
}
}
@@ -842,9 +1054,6 @@ class ChatPage extends LitElement {
if (file.type.includes('image')) {
this.imageFile = file;
this.chatEditor.disable();
- // this.changeMsgInput('newChat')
- // this.initChatEditor();
- // this.chatEditor.disable();
return;
}
parentEpml.request('showSnackBar', get("chatpage.cchange28"));
@@ -955,10 +1164,20 @@ class ChatPage extends LitElement {
}
}
+
if (changedProperties && changedProperties.has('chatId') && changedProperties.get('chatId')) {
await this.initUpdate()
}
+
+ if (changedProperties && changedProperties.has('openForwardOpen')) {
+ if (this.openForwardOpen === true) {
+ this.chatEditor.disable();
+ }
+ }
+ if (changedProperties && changedProperties.has('forwardActiveChatHeadUrl')) {
+ console.log(this.forwardActiveChatHeadUrl, "forwardActiveChatHeadUrl here");
+ }
}
async renderPlaceholder() {
@@ -1454,7 +1673,7 @@ class ChatPage extends LitElement {
}
async _sendMessage(outSideMsg) {
-
+ console.log(outSideMsg);
// have params to determine if it's a reply or not
// have variable to determine if it's a response, holds signature in constructor
// need original message signature
@@ -1698,35 +1917,31 @@ class ChatPage extends LitElement {
users: [this.selectedAddress.address]
}]
}
-
const messageObject = {
...message,
reactions
-
}
const stringifyMessageObject = JSON.stringify(messageObject)
this.sendMessage(stringifyMessageObject, typeMessage, chatReference);
-
} else if (/^\s*$/.test(trimmedMessage)) {
this.isLoading = false;
this.chatEditor.enable();
- this.chatEditorNewChat.enable()
+ this.chatEditorNewChat.enable();
}
else if (this.repliedToMessageObj) {
- let chatReference = this.repliedToMessageObj.reference
-
+ let chatReference = this.repliedToMessageObj.reference;
if(this.repliedToMessageObj.chatReference){
- chatReference = this.repliedToMessageObj.chatReference
+ chatReference = this.repliedToMessageObj.chatReference;
}
- typeMessage = 'reply'
+ typeMessage = 'reply';
const messageObject = {
messageText: trimmedMessage,
images: [''],
repliedTo: chatReference,
version: 1
}
- const stringifyMessageObject = JSON.stringify(messageObject)
- this.sendMessage(stringifyMessageObject, typeMessage );
+ const stringifyMessageObject = JSON.stringify(messageObject);
+ this.sendMessage(stringifyMessageObject, typeMessage);
} else if (this.editedMessageObj) {
typeMessage = 'edit'
let chatReference = this.editedMessageObj.reference
@@ -1762,7 +1977,7 @@ class ChatPage extends LitElement {
}
}
- async sendMessage(messageText, typeMessage, chatReference, isForward, forwardParams) {
+ async sendMessage(messageText, typeMessage, chatReference, isForward) {
this.isLoading = true;
let _reference = new Uint8Array(64);
@@ -1811,19 +2026,67 @@ class ChatPage extends LitElement {
};
const sendForwardRequest = async () => {
- const { publicKey } = forwardParams
+ let publicKey = {
+ hasPubKey: false,
+ key: ''
+ };
- const isRecipient = this.forwardActiveChatHeadUrl.includes('direct') === true ? true : false;
+ if (this.forwardActiveChatHeadUrl.url) {
+ const activeChatHeadAddress = this.forwardActiveChatHeadUrl.url.split('/')[1]
+ try {
+ const res = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/addresses/publickey/${activeChatHeadAddress}`
+ })
+
+ if (res.error === 102) {
+ publicKey.key = ''
+ publicKey.hasPubKey = false
+ } else if (res !== false) {
+ publicKey.key = res
+ publicKey.hasPubKey = true
+ } else {
+ publicKey.key = ''
+ publicKey.hasPubKey = false
+ }
+ } catch (error) {
+ console.error(error);
+ }
+ }
+
+ if (!this.forwardActiveChatHeadUrl && this.shadowRoot.getElementById("sendTo").value !== "") {
+ try {
+ const res = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/addresses/publickey/${this.shadowRoot.getElementById("sendTo").value}`
+ })
+ if (res.error === 102) {
+ publicKey.key = ''
+ publicKey.hasPubKey = false
+ } else if (res !== false) {
+ publicKey.key = res
+ publicKey.hasPubKey = true
+ } else {
+ publicKey.key = ''
+ publicKey.hasPubKey = false
+ }
+ } catch (error) {
+ console.error(error);
+ }
+ }
+
+ const isRecipient = this.forwardActiveChatHeadUrl.url.includes('direct') === true ? true : false;
- const chatId = this.forwardActiveChatHeadUrl.split('/')[1];
- this.openForwardOpen = false
+ const recipientAddress = this.forwardActiveChatHeadUrl.url.split('/')[1];
+ this.openForwardOpen = false;
+ this.chatEditor.enable();
if (isRecipient === true) {
let chatResponse = await parentEpml.request('chat', {
type: 18,
nonce: this.selectedAddress.nonce,
params: {
timestamp: Date.now(),
- recipient: chatId,
+ recipient: recipientAddress,
recipientPublicKey: publicKey.key,
hasChatReference: 0,
chatReference: "",
@@ -1842,7 +2105,7 @@ class ChatPage extends LitElement {
nonce: this.selectedAddress.nonce,
params: {
timestamp: Date.now(),
- groupID: Number(chatId),
+ groupID: Number(recipientAddress),
hasReceipient: 0,
hasChatReference: 0,
chatReference: chatReference,
@@ -1910,9 +2173,9 @@ class ChatPage extends LitElement {
this.forwardActiveChatHeadUrl = ""
};
- if(isForward){
+ if (isForward) {
sendForwardRequest();
- return
+ return;
}
sendMessageRequest();
}
diff --git a/qortal-ui-plugins/plugins/core/components/ChatSeachResults.js b/qortal-ui-plugins/plugins/core/components/ChatSeachResults.js
new file mode 100644
index 00000000..2fdf8422
--- /dev/null
+++ b/qortal-ui-plugins/plugins/core/components/ChatSeachResults.js
@@ -0,0 +1,66 @@
+import { LitElement, html } from 'lit';
+import { render } from 'lit/html.js';
+import { chatSearchResultsStyles } from './ChatSearchResults-css.js'
+import { translate } from 'lit-translate';
+export class ChatSearchResults extends LitElement {
+ static get properties() {
+ return {
+ onClickFunc: { attribute: false },
+ closeFunc: { attribute: false },
+ searchResults: { type: Array },
+ isOpen: { type: Boolean },
+ loading: { type: Boolean }
+ }
+ }
+
+ static styles = [chatSearchResultsStyles]
+
+ render() {
+ return html`
+
+
this.closeFunc()}
+ icon="vaadin:close-small"
+ slot="icon"
+ class="close-icon"
+ >
+
+ ${this.loading ? (
+ html`
+
+ `
+ ) : (
+ html`
+
+
+
+ ${this.searchResults.length === 0 ? (
+ html`
${translate("chatpage.cchange37")}
`
+ ) : (
+ html`
+ ${this.searchResults.map((result) => {
+ return (
+ html`
+
{
+ this.shadowRoot.querySelector(".chat-result-card").classList.add("active");
+ this.onClickFunc(result);
+ }}>
+
+ ${result.name}
+
+
+ `
+ )}
+ )}
+ `
+ )}
+
+ `
+ )}
+
+ `;
+ }
+}
+customElements.define('chat-search-results', ChatSearchResults);
diff --git a/qortal-ui-plugins/plugins/core/components/ChatSearchResults-css.js b/qortal-ui-plugins/plugins/core/components/ChatSearchResults-css.js
new file mode 100644
index 00000000..4cff99f5
--- /dev/null
+++ b/qortal-ui-plugins/plugins/core/components/ChatSearchResults-css.js
@@ -0,0 +1,120 @@
+import { css } from 'lit'
+
+export const chatSearchResultsStyles = css`
+ .chat-results-card {
+ position: relative;
+ padding: 25px 20px;
+ box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
+ width: 300px;
+ min-height: 200px;
+ height: auto;
+ border-radius: 5px;
+ background-color: var(--white);
+ }
+
+ .chat-result-header {
+ color: var(--chat-bubble-msg-color);
+ font-size: 18px;
+ font-family: Montserrat, sans-serif;
+ text-align: center;
+ margin: 0 0 10px 0;
+ user-select: none;
+ }
+
+ .divider {
+ height: 1px;
+ background: var(--chat-bubble-msg-color);
+ margin: 0 40px;
+ user-select: none;
+ }
+
+ .no-results {
+ font-family: Roboto, sans-serif;
+ font-weight: 300;
+ letter-spacing: 0.3px;
+ font-size: 16px;
+ color: var(--chat-bubble-msg-color);
+ text-align: center;
+ margin: 20px 0 0 0;
+ user-select: none;
+ }
+
+ .chat-result-container {
+ height: 200px;
+ overflow-y: auto;
+ padding: 0 10px;
+ }
+
+ .chat-result-container::-webkit-scrollbar-track {
+ background-color: whitesmoke;
+ border-radius: 7px;
+ }
+
+ .chat-result-container::-webkit-scrollbar {
+ width: 6px;
+ border-radius: 7px;
+ background-color: whitesmoke;
+ }
+
+ .chat-result-container::-webkit-scrollbar-thumb {
+ background-color: rgb(180, 176, 176);
+ border-radius: 7px;
+ transition: all 0.3s ease-in-out;
+ }
+
+ .chat-result-container::-webkit-scrollbar-thumb:hover {
+ background-color: rgb(148, 146, 146);
+ cursor: pointer;
+ }
+
+ .chat-result-card {
+ padding: 12px;
+ margin-bottom: 15px;
+ margin-top: 15px;
+ transition: all 0.2s ease-in-out;
+ box-shadow: none;
+ }
+
+ .chat-result-card:active {
+ background-color: #09b814;
+ }
+
+ .chat-result-card:hover {
+ cursor: pointer;
+ border: none;
+ border-radius: 4px;
+ box-sizing: border-box;
+ -webkit-box-shadow: rgba(132, 132, 132, 40%) 0px 0px 6px -1px;
+ box-shadow: rgba(132, 132, 132, 40%) 0px 0px 6px -1px;
+ }
+
+ .chat-result {
+ font-family: Roboto, sans-serif;
+ font-weight: 300;
+ letter-spacing: 0.3px;
+ font-size: 15px;
+ color: var(--chat-bubble-msg-color);
+ margin: 0;
+ user-select: none;
+ }
+
+ .spinner-container {
+ display: flex;
+ width: 100%;
+ justify-content: center
+ }
+
+ .close-icon {
+ position: absolute;
+ top: 5px;
+ right: 5px;
+ color: var(--chat-bubble-msg-color);
+ font-size: 14px;
+ transition: all 0.1s ease-in-out;
+ }
+
+ .close-icon:hover {
+ cursor: pointer;
+ font-size: 15px;
+ }
+`
\ No newline at end of file
diff --git a/qortal-ui-plugins/plugins/core/components/ChatSelect.js b/qortal-ui-plugins/plugins/core/components/ChatSelect.js
index be069a2b..67fb3a0f 100644
--- a/qortal-ui-plugins/plugins/core/components/ChatSelect.js
+++ b/qortal-ui-plugins/plugins/core/components/ChatSelect.js
@@ -57,6 +57,10 @@ class ChatSelect extends LitElement {
color: #92959e;
}
+ .name {
+ user-select: none;
+ }
+
.clearfix:after {
visibility: hidden;
display: block;
@@ -122,13 +126,60 @@ class ChatSelect extends LitElement {
}
return html`
- this.getUrl(this.chatInfo.url)} class="clearfix ${this.activeChatHeadUrl === this.chatInfo.url ? 'active' : ''}">
- ${this.isImageLoaded ? html`${avatarImg}` : html`` }
- ${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName ? html`account_circle` : html`` }
- ${!this.isImageLoaded && this.chatInfo.name ? html`${this.chatInfo.name.charAt(0)}
`: ''}
- ${!this.isImageLoaded && this.chatInfo.groupName ? html`${this.chatInfo.groupName.charAt(0)}
`: ''}
+ this.getUrl(this.chatInfo.url)}
+ class="clearfix ${this.activeChatHeadUrl === this.chatInfo.url ? 'active' : ''}">
+ ${this.isImageLoaded ? html`${avatarImg}` : html``}
+ ${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName ? html`account_circle` :
+ html``
+ }
+ ${!this.isImageLoaded && this.chatInfo.name ?
+ html`
+
+ ${this.chatInfo.name.charAt(0)}
+
`:
+ ''}
+ ${!this.isImageLoaded && this.chatInfo.groupName ?
+ html`
+
+ ${this.chatInfo.groupName.charAt(0)}
+
`:
+ ''}
-
${this.chatInfo.groupName ? this.chatInfo.groupName : this.chatInfo.name !== undefined ? this.chatInfo.name : this.chatInfo.address.substr(0, 15)}
+
+
+ ${this.chatInfo.groupName ?
+ this.chatInfo.groupName :
+ this.chatInfo.name !== undefined ? this.chatInfo.name :
+ this.chatInfo.address.substr(0, 15)}
+
+
`
diff --git a/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js b/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js
index 6bd01d0c..dfc572bc 100644
--- a/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js
+++ b/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js
@@ -172,11 +172,14 @@ class ChatTextEditor extends LitElement {
}
return html`
-
{
- this.preventUserSendingImage(e)
- }}>
+
{
+ this.preventUserSendingImage(e)
+ }}>
+
${this.isLoading === false ? html`
{
- this.removeImage()
+ this.onClickFunc();
}}>
diff --git a/qortal-ui-plugins/plugins/core/messaging/q-chat/computePowWorker.src.js b/qortal-ui-plugins/plugins/core/messaging/q-chat/computePowWorker.src.js
new file mode 100644
index 00000000..2ed60a20
--- /dev/null
+++ b/qortal-ui-plugins/plugins/core/messaging/q-chat/computePowWorker.src.js
@@ -0,0 +1,82 @@
+import { Sha256 } from 'asmcrypto.js'
+
+
+function sbrk(size, heap){
+ let brk = 512 * 1024 // stack top
+ let old = brk
+ brk += size
+
+ if (brk > heap.length)
+ throw new Error('heap exhausted')
+
+ return old
+}
+
+
+
+self.addEventListener('message', async e => {
+ const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty)
+ postMessage(response)
+
+})
+
+
+const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })
+const heap = new Uint8Array(memory.buffer)
+
+
+
+const computePow = async (chatBytes, path, difficulty) => {
+
+ let response = null
+
+ await new Promise((resolve, reject)=> {
+
+ const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; });
+ const chatBytesArray = new Uint8Array(_chatBytesArray);
+ const chatBytesHash = new Sha256().process(chatBytesArray).finish().result;
+ const hashPtr = sbrk(32, heap);
+ const hashAry = new Uint8Array(memory.buffer, hashPtr, 32);
+ hashAry.set(chatBytesHash);
+
+
+ const workBufferLength = 8 * 1024 * 1024;
+ const workBufferPtr = sbrk(workBufferLength, heap);
+
+
+
+ const importObject = {
+ env: {
+ memory: memory
+ },
+ };
+
+ function loadWebAssembly(filename, imports) {
+ // Fetch the file and compile it
+ return fetch(filename)
+ .then(response => response.arrayBuffer())
+ .then(buffer => WebAssembly.compile(buffer))
+ .then(module => {
+
+ // Create the instance.
+ return new WebAssembly.Instance(module, importObject);
+ });
+}
+
+
+loadWebAssembly(path)
+ .then(wasmModule => {
+ response = {
+ nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty),
+ chatBytesArray
+ }
+
+ resolve()
+
+ });
+
+
+ })
+
+ return response
+}
\ No newline at end of file
diff --git a/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat-css.src.js b/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat-css.src.js
new file mode 100644
index 00000000..bab60e1d
--- /dev/null
+++ b/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat-css.src.js
@@ -0,0 +1,368 @@
+import { css } from 'lit'
+
+export const qchatStyles = css`
+ * {
+ --mdc-theme-primary: rgb(3, 169, 244);
+ --mdc-theme-secondary: var(--mdc-theme-primary);
+ --paper-input-container-focus-color: var(--mdc-theme-primary);
+ --mdc-theme-surface: var(--white);
+ --mdc-dialog-content-ink-color: var(--black);
+ --lumo-primary-text-color: rgb(0, 167, 245);
+ --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
+ --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
+ --lumo-primary-color: hsl(199, 100%, 48%);
+ --lumo-base-color: var(--white);
+ --lumo-body-text-color: var(--black);
+ --_lumo-grid-border-color: var(--border);
+ --_lumo-grid-secondary-border-color: var(--border2);
+ --mdc-dialog-min-width: 750px;
+ }
+
+ paper-spinner-lite {
+ height: 24px;
+ width: 24px;
+ --paper-spinner-color: var(--mdc-theme-primary);
+ --paper-spinner-stroke-width: 2px;
+ }
+
+ *,
+ *:before,
+ *:after {
+ box-sizing: border-box;
+ }
+
+ ul {
+ list-style: none;
+ padding: 0;
+ }
+
+ .container {
+ margin: 0 auto;
+ width: 100%;
+ background: var(--white);
+ }
+
+ .people-list {
+ width: 20vw;
+ float: left;
+ height: 100vh;
+ overflow-y: hidden;
+ border-right: 3px #ddd solid;
+ }
+
+ .people-list .blockedusers {
+ position: absolute;
+ bottom: 0;
+ width: 20vw;
+ height: 60px;
+ background: var(--white);
+ border-top: 1px solid var(--border);
+ border-right: 3px #ddd solid;
+ }
+
+ .people-list .search {
+ padding-top: 20px;
+ padding-left: 20px;
+ padding-right: 20px;
+ }
+
+ .center {
+ margin: 0;
+ position: absolute;
+ padding-top: 12px;
+ left: 50%;
+ -ms-transform: translateX(-50%);
+ transform: translateX(-50%);
+ }
+
+ .people-list .create-chat {
+ border-radius: 5px;
+ border: none;
+ display: inline-block;
+ padding: 14px;
+ color: #fff;
+ background: var(--tradehead);
+ width: 100%;
+ font-size: 15px;
+ text-align: center;
+ cursor: pointer;
+ }
+
+ .people-list .create-chat:hover {
+ opacity: .8;
+ box-shadow: 0 3px 5px rgba(0, 0, 0, .2);
+ }
+
+ .people-list ul {
+ padding: 0;
+ height: 85vh;
+ overflow-y: auto;
+ overflow-x: hidden;
+ }
+
+ .chat {
+ width: 80vw;
+ height: 100vh;
+ float: left;
+ background: var(--white);
+ border-top-right-radius: 5px;
+ border-bottom-right-radius: 5px;
+ color: #434651;
+ box-sizing: border-box;
+ }
+
+ .chat .new-message-bar {
+ display: flex;
+ flex: 0 1 auto;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0px 25px;
+ font-size: 14px;
+ font-weight: 500;
+ top: 0;
+ position: absolute;
+ left: 20vw;
+ right: 0;
+ z-index: 5;
+ background: var(--tradehead);
+ color: var(--white);
+ border-radius: 0 0 8px 8px;
+ min-height: 25px;
+ transition: opacity .15s;
+ text-transform: capitalize;
+ opacity: .85;
+ cursor: pointer;
+ }
+
+ .chat .new-message-bar:hover {
+ opacity: .75;
+ transform: translateY(-1px);
+ box-shadow: 0 3px 7px rgba(0, 0, 0, .2);
+ }
+
+ .hide-new-message-bar {
+ display: none !important;
+ }
+
+ .chat .chat-history {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 100%;
+ left: 20vw;
+ border-bottom: 2px solid var(--white);
+ overflow-y: hidden;
+ height: 100vh;
+ box-sizing: border-box;
+ }
+
+ .chat .chat-message {
+ padding: 10px;
+ height: 10%;
+ display: inline-block;
+ width: 100%;
+ background-color: #eee;
+ }
+
+ .chat .chat-message textarea {
+ width: 90%;
+ border: none;
+ font-size: 16px;
+ padding: 10px 20px;
+ border-radius: 5px;
+ resize: none;
+ }
+
+ .chat .chat-message button {
+ float: right;
+ color: #94c2ed;
+ font-size: 16px;
+ text-transform: uppercase;
+ border: none;
+ cursor: pointer;
+ font-weight: bold;
+ background: #f2f5f8;
+ padding: 10px;
+ margin-top: 4px;
+ margin-right: 4px;
+ }
+
+ .chat .chat-message button:hover {
+ color: #75b1e8;
+ }
+
+ .online,
+ .offline,
+ .me {
+ margin-right: 3px;
+ font-size: 10px;
+ }
+
+ .clearfix:after {
+ visibility: hidden;
+ display: block;
+ font-size: 0;
+ content: " ";
+ clear: both;
+ height: 0;
+ }
+
+ .red {
+ --mdc-theme-primary: red;
+ }
+
+ h2 {
+ margin:0;
+ }
+
+ h2, h3, h4, h5 {
+ color: var(--black);
+ font-weight: 400;
+ }
+
+ [hidden] {
+ display: hidden !important;
+ visibility: none !important;
+ }
+
+ .details {
+ display: flex;
+ font-size: 18px;
+ }
+
+ .title {
+ font-weight:600;
+ font-size:12px;
+ line-height: 32px;
+ opacity: 0.66;
+ }
+
+ .textarea {
+ width: 100%;
+ border: none;
+ display: inline-block;
+ font-size: 16px;
+ padding: 10px 20px;
+ border-radius: 5px;
+ height: 120px;
+ resize: none;
+ background: #eee;
+ }
+
+ .dialog-container {
+ position: relative;
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ padding: 0 10px;
+ gap: 10px;
+ height: 100%;
+ }
+
+ .dialog-header {
+ color: var(--chat-bubble-msg-color);
+ }
+
+ .dialog-subheader {
+ color: var(--chat-bubble-msg-color);
+ }
+
+ .modal-button-row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ }
+
+ .modal-button {
+ font-family: Roboto, sans-serif;
+ font-size: 16px;
+ color: var(--mdc-theme-primary);
+ background-color: transparent;
+ padding: 8px 10px;
+ border-radius: 5px;
+ border: none;
+ transition: all 0.3s ease-in-out;
+ }
+
+ .modal-button-red {
+ font-family: Roboto, sans-serif;
+ font-size: 16px;
+ color: #F44336;
+ background-color: transparent;
+ padding: 8px 10px;
+ border-radius: 5px;
+ border: none;
+ transition: all 0.3s ease-in-out;
+ }
+
+ .modal-button-red:hover {
+ cursor: pointer;
+ background-color: #f4433663;
+ }
+
+ .modal-button:hover {
+ cursor: pointer;
+ background-color: #03a8f475;
+ }
+
+ .name-input {
+ width: 100%;
+ outline: 0;
+ border-width: 0 0 2px;
+ border-color: var(--mdc-theme-primary);
+ background-color: transparent;
+ padding: 10px;
+ font-family: Roboto, sans-serif;
+ font-size: 15px;
+ color: var(--chat-bubble-msg-color);
+ }
+
+ .name-input::selection {
+ background-color: var(--mdc-theme-primary);
+ color: white;
+ }
+
+ .name-input::placeholder {
+ opacity: 0.9;
+ color: var(--black);
+ }
+
+ .search-field {
+ width: 100%;
+ position: relative;
+ }
+
+ .search-icon {
+ position: absolute;
+ right: 3px;
+ color: var(--chat-bubble-msg-color);
+ transition: all 0.3s ease-in-out;
+ background: none;
+ border-radius: 50%;
+ padding: 6px 3px;
+ font-size: 21px;
+ }
+
+ .search-icon:hover {
+ cursor: pointer;
+ background: #d7d7d75c;
+ }
+
+ .search-results-div {
+ position: absolute;
+ top: 25px;
+ right: 25px;
+ }
+
+ .user-verified {
+ position: absolute;
+ top: 0;
+ right: 5px;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ color: #04aa2e;
+ font-size: 13px;
+ }
+`
\ No newline at end of file
diff --git a/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat.src.js b/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat.src.js
index 9858766d..ca93bbbd 100644
--- a/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat.src.js
+++ b/qortal-ui-plugins/plugins/core/messaging/q-chat/q-chat.src.js
@@ -1,22 +1,26 @@
-import { LitElement, html, css } from 'lit'
-import { render } from 'lit/html.js'
-import { Epml } from '../../../../epml.js'
-import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
+import { LitElement, html, css } from 'lit';
+import { render } from 'lit/html.js';
+import { Epml } from '../../../../epml.js';
+import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate';
+import { qchatStyles } from './q-chat-css.src.js'
+import WebWorker from 'web-worker:./computePowWorker.src.js';
registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
})
-import '../../components/ChatWelcomePage.js'
-import '../../components/ChatHead.js'
-import '../../components/ChatPage.js'
-import snackbar from '../../components/snackbar.js'
-import '@polymer/paper-spinner/paper-spinner-lite.js'
-import '@material/mwc-button'
-import '@material/mwc-dialog'
-import '@material/mwc-icon'
-import '@material/mwc-snackbar'
-import '@vaadin/grid'
+import '../../components/ChatWelcomePage.js';
+import '../../components/ChatHead.js';
+import '../../components/ChatPage.js';
+import '../../components/WrapperModal.js';
+import '../../components/ChatSeachResults.js';
+import snackbar from '../../components/snackbar.js';
+import '@polymer/paper-spinner/paper-spinner-lite.js';
+import '@material/mwc-button';
+import '@material/mwc-dialog';
+import '@material/mwc-icon';
+import '@material/mwc-snackbar';
+import '@vaadin/grid';
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
@@ -35,272 +39,18 @@ class Chat extends LitElement {
theme: { type: String, reflect: true },
blockedUsers: { type: Array },
blockedUserList: { type: Array },
- activeChatHeadUrl: {type: String}
+ privateMessagePlaceholder: { type: String},
+ chatEditor: { type: Object },
+ imageFile: { type: Object },
+ activeChatHeadUrl: { type: String },
+ openPrivateMessage: { type: Boolean },
+ userFound: { type: Array},
+ userFoundModalOpen: { type: Boolean },
+ userSelected: { type: Object }
}
}
- static get styles() {
- return css`
- * {
- --mdc-theme-primary: rgb(3, 169, 244);
- --mdc-theme-secondary: var(--mdc-theme-primary);
- --paper-input-container-focus-color: var(--mdc-theme-primary);
- --mdc-theme-surface: var(--white);
- --mdc-dialog-content-ink-color: var(--black);
- --lumo-primary-text-color: rgb(0, 167, 245);
- --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
- --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
- --lumo-primary-color: hsl(199, 100%, 48%);
- --lumo-base-color: var(--white);
- --lumo-body-text-color: var(--black);
- --_lumo-grid-border-color: var(--border);
- --_lumo-grid-secondary-border-color: var(--border2);
- --mdc-dialog-min-width: 750px;
- }
-
- paper-spinner-lite {
- height: 24px;
- width: 24px;
- --paper-spinner-color: var(--mdc-theme-primary);
- --paper-spinner-stroke-width: 2px;
- }
-
- *,
- *:before,
- *:after {
- box-sizing: border-box;
- }
-
- ul {
- list-style: none;
- padding: 0;
- }
-
- .container {
- margin: 0 auto;
- width: 100%;
- background: var(--white);
- }
-
- .people-list {
- width: 20vw;
- float: left;
- height: 100vh;
- overflow-y: hidden;
- border-right: 3px #ddd solid;
- }
-
- .people-list .blockedusers {
- position: absolute;
- bottom: 0;
- width: 20vw;
- height: 60px;
- background: var(--white);
- border-top: 1px solid var(--border);
- border-right: 3px #ddd solid;
- }
-
- .people-list .search {
- padding-top: 20px;
- padding-left: 20px;
- padding-right: 20px;
- }
-
- .center {
- margin: 0;
- position: absolute;
- padding-top: 12px;
- left: 50%;
- -ms-transform: translateX(-50%);
- transform: translateX(-50%);
- }
-
- .people-list .create-chat {
- border-radius: 5px;
- border: none;
- display: inline-block;
- padding: 14px;
- color: #fff;
- background: var(--tradehead);
- width: 100%;
- font-size: 15px;
- text-align: center;
- cursor: pointer;
- }
-
- .people-list .create-chat:hover {
- opacity: .8;
- box-shadow: 0 3px 5px rgba(0, 0, 0, .2);
- }
-
- .people-list ul {
- padding: 0;
- height: 85vh;
- overflow-y: auto;
- overflow-x: hidden;
- }
-
- .chat {
- width: 80vw;
- height: 100vh;
- float: left;
- background: var(--white);
- border-top-right-radius: 5px;
- border-bottom-right-radius: 5px;
- color: #434651;
- box-sizing: border-box;
- }
-
- .chat .new-message-bar {
- display: flex;
- flex: 0 1 auto;
- align-items: center;
- justify-content: space-between;
- padding: 0px 25px;
- font-size: 14px;
- font-weight: 500;
- top: 0;
- position: absolute;
- left: 20vw;
- right: 0;
- z-index: 5;
- background: var(--tradehead);
- color: var(--white);
- border-radius: 0 0 8px 8px;
- min-height: 25px;
- transition: opacity .15s;
- text-transform: capitalize;
- opacity: .85;
- cursor: pointer;
- }
-
- .chat .new-message-bar:hover {
- opacity: .75;
- transform: translateY(-1px);
- box-shadow: 0 3px 7px rgba(0, 0, 0, .2);
- }
-
- .hide-new-message-bar {
- display: none !important;
- }
-
- .chat .chat-history {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 100%;
- left: 20vw;
- border-bottom: 2px solid var(--white);
- overflow-y: hidden;
- height: 100vh;
- box-sizing: border-box;
- }
-
- .chat .chat-message {
- padding: 10px;
- height: 10%;
- display: inline-block;
- width: 100%;
- background-color: #eee;
- }
-
- .chat .chat-message textarea {
- width: 90%;
- border: none;
- font-size: 16px;
- padding: 10px 20px;
- border-radius: 5px;
- resize: none;
- }
-
- .chat .chat-message button {
- float: right;
- color: #94c2ed;
- font-size: 16px;
- text-transform: uppercase;
- border: none;
- cursor: pointer;
- font-weight: bold;
- background: #f2f5f8;
- padding: 10px;
- margin-top: 4px;
- margin-right: 4px;
- }
-
- .chat .chat-message button:hover {
- color: #75b1e8;
- }
-
- .online,
- .offline,
- .me {
- margin-right: 3px;
- font-size: 10px;
- }
-
- .clearfix:after {
- visibility: hidden;
- display: block;
- font-size: 0;
- content: " ";
- clear: both;
- height: 0;
- }
-
- .red {
- --mdc-theme-primary: red;
- }
-
- h2 {
- margin:0;
- }
-
- h2, h3, h4, h5 {
- color: var(--black);
- font-weight: 400;
- }
-
- [hidden] {
- display: hidden !important;
- visibility: none !important;
- }
-
- .details {
- display: flex;
- font-size: 18px;
- }
-
- .title {
- font-weight:600;
- font-size:12px;
- line-height: 32px;
- opacity: 0.66;
- }
-
- .input {
- width: 100%;
- border: none;
- display: inline-block;
- font-size: 16px;
- padding: 10px 20px;
- border-radius: 5px;
- resize: none;
- background: #eee;
- }
-
- .textarea {
- width: 100%;
- border: none;
- display: inline-block;
- font-size: 16px;
- padding: 10px 20px;
- border-radius: 5px;
- height: 120px;
- resize: none;
- background: #eee;
- }
- `
- }
+ static styles = [qchatStyles]
constructor() {
super()
@@ -322,15 +72,21 @@ class Chat extends LitElement {
this.isLoading = false
this.showNewMesssageBar = this.showNewMesssageBar.bind(this)
this.hideNewMesssageBar = this.hideNewMesssageBar.bind(this)
+ this._sendMessage = this._sendMessage.bind(this)
+ this.insertImage = this.insertImage.bind(this)
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
this.blockedUsers = []
this.blockedUserList = []
+ this.privateMessagePlaceholder = ""
+ this.imageFile = null
this.activeChatHeadUrl = ''
-
-
+ this.openPrivateMessage = false
+ this.userFound = []
+ this.userFoundModalOpen = false
+ this.userSelected = {}
}
- async setActiveChatHeadUrl(url){
+ async setActiveChatHeadUrl(url) {
this.activeChatHeadUrl = ''
await this.updateComplete;
this.activeChatHeadUrl = url
@@ -341,7 +97,10 @@ class Chat extends LitElement {
-
this.shadowRoot.querySelector('#startChatDialog').show()}>${translate("chatpage.cchange1")}
+
{
+ this.openPrivateMessage = true;
+ }}>${translate("chatpage.cchange1")}
+
${this.isEmptyArray(this.chatHeads) ? this.renderLoadingText() : this.renderChatHead(this.chatHeads)}
@@ -365,35 +124,109 @@ class Chat extends LitElement {
-
-
-
${translate("chatpage.cchange1")}
-
-
-
- ${translate("chatpage.cchange6")}
-
-
-
-
-
-
-
- ${this.isLoading === false ? this.renderSendText() : html``}
-
-
- ${translate("general.close")}
-
-
+
{
+ this.chatEditor.resetValue();
+ this.openPrivateMessage = false;
+ this.shadowRoot.getElementById('sendTo').value = "";
+ this.userFoundModalOpen = false;
+ this.userFound = [];
+ } }
+ style=${this.openPrivateMessage ? "display: block" : "display: none"}>
+
+
+
+
+
+
{
+ this.userSelected = {};
+ this.requestUpdate();
+ }}
+ />
+ ${this.userSelected.name ? (
+ html`
+
+
${translate("chatpage.cchange38")}
+
+
+ `
+ ) : (
+ html`
+
+
+ `
+ )}
+
+
+
this.setChatEditor(editor)}
+ .chatEditor=${this.chatEditor}
+ .imageFile=${this.imageFile}
+ ._sendMessage=${this._sendMessage}
+ .insertImage=${this.insertImage}
+ ?isLoading=${this.isLoading}
+ .isLoadingMessages=${false}
+ id="messageBox"
+ >
+
+
+
+
+ {
+ this.userSelected = result;
+ this.userFound = [];
+ this.userFoundModalOpen = false;
+ }}
+ .closeFunc=${() => {
+ this.userFoundModalOpen = false;
+ this.userFound = [];
+ }}
+ .searchResults=${this.userFound}
+ ?isOpen=${this.userFoundModalOpen}
+ ?loading=${this.isLoading}>
+
+
+
+
@@ -445,9 +278,24 @@ class Chat extends LitElement {
return false;
}
- this.shadowRoot.getElementById('sendTo').addEventListener('keydown', stopKeyEventPropagation);
+ const nameInput = this.shadowRoot.getElementById('sendTo');
+
+ nameInput.addEventListener('keydown', stopKeyEventPropagation);
+
this.shadowRoot.getElementById('messageBox').addEventListener('keydown', stopKeyEventPropagation);
+ // let typingTimer;
+ // let doneTypingInterval = 3000;
+
+ // //on keyup, start the countdown
+ // nameInput.addEventListener('keyup', () => {
+ // clearTimeout(typingTimer);
+ // if (nameInput.value) {
+ // console.log("typing started!");
+ // typingTimer = setTimeout(this.userSearch, doneTypingInterval);
+ // }
+ // });
+
const getDataFromURL = () => {
let tempUrl = document.location.href
let splitedUrl = decodeURI(tempUrl).split('?')
@@ -547,6 +395,196 @@ class Chat extends LitElement {
parentEpml.imReady()
}
+ async userSearch() {
+ const nameValue = this.shadowRoot.getElementById('sendTo').value;
+ if(!nameValue) {
+ this.userFound = [];
+ this.userFoundModalOpen = true;
+ return;
+ }
+ try {
+ const result = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/names/${nameValue}`
+ })
+ if (result.error === 401) {
+ this.userFound = [];
+ } else {
+ this.userFound = [
+ ...this.userFound,
+ result,
+ ];
+ }
+ this.userFoundModalOpen = true;
+ } catch (error) {
+ console.error(error);
+ let err4string = get("chatpage.cchange35");
+ parentEpml.request('showSnackBar', `${err4string}`)
+ }
+ }
+
+ setChatEditor(editor) {
+ this.chatEditor = editor;
+ }
+
+ async _sendMessage() {
+ this.isLoading = true;
+ this.chatEditor.disable();
+ const messageText = this.chatEditor.mirror.value;
+ // Format and Sanitize Message
+ const sanitizedMessage = messageText.replace(/ /gi, ' ').replace(/
/gi, '\n');
+ const trimmedMessage = sanitizedMessage.trim();
+ if (/^\s*$/.test(trimmedMessage)) {
+ this.isLoading = false;
+ this.chatEditor.enable();
+ } else {
+ const messageObject = {
+ messageText: trimmedMessage,
+ images: [''],
+ repliedTo: '',
+ version: 1
+ }
+ const stringifyMessageObject = JSON.stringify(messageObject)
+ this.sendMessage(stringifyMessageObject);
+ }
+ }
+
+ async sendMessage(messageText) {
+ this.isLoading = true;
+
+ const _recipient = this.shadowRoot.getElementById('sendTo').value;
+
+ let recipient;
+
+ const validateName = async (receiverName) => {
+ let myRes;
+ try {
+ let myNameRes = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/names/${receiverName}`
+ });
+ if (myNameRes.error === 401) {
+ myRes = false;
+ } else {
+ myRes = myNameRes;
+ }
+ return myRes;
+ } catch (error) {
+ return "";
+ }
+ };
+
+ const myNameRes = await validateName(_recipient);
+ if (!myNameRes) {
+ recipient = _recipient;
+ } else {
+ recipient = myNameRes.owner;
+ };
+
+ const getAddressPublicKey = async () => {
+ let isEncrypted;
+ let _publicKey;
+
+ let addressPublicKey = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/addresses/publickey/${recipient}`
+ })
+
+ if (addressPublicKey.error === 102) {
+ _publicKey = false;
+ let err4string = get("chatpage.cchange19");
+ parentEpml.request('showSnackBar', `${err4string}`);
+ this.chatEditor.enable();
+ this.isLoading = false;
+ } else if (addressPublicKey !== false) {
+ isEncrypted = 1;
+ _publicKey = addressPublicKey;
+ sendMessageRequest(isEncrypted, _publicKey);
+ } else {
+ isEncrypted = 0;
+ _publicKey = this.selectedAddress.address;
+ sendMessageRequest(isEncrypted, _publicKey);
+ }
+ };
+ let _reference = new Uint8Array(64);
+ window.crypto.getRandomValues(_reference);
+ let reference = window.parent.Base58.encode(_reference);
+ const sendMessageRequest = async (isEncrypted, _publicKey) => {
+ let chatResponse = await parentEpml.request('chat', {
+ type: 18,
+ nonce: this.selectedAddress.nonce,
+ params: {
+ timestamp: Date.now(),
+ recipient: recipient,
+ recipientPublicKey: _publicKey,
+ hasChatReference: 0,
+ message: messageText,
+ lastReference: reference,
+ proofOfWorkNonce: 0,
+ isEncrypted: isEncrypted,
+ isText: 1
+ }
+ });
+
+ _computePow(chatResponse);
+ };
+
+ const _computePow = async (chatBytes) => {
+ const difficulty = this.balance === 0 ? 12 : 8;
+ const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full';
+ const worker = new WebWorker();
+ let nonce = null;
+ let chatBytesArray = null;
+ await new Promise((res, rej) => {
+ worker.postMessage({chatBytes, path, difficulty});
+ worker.onmessage = e => {
+ worker.terminate();
+ chatBytesArray = e.data.chatBytesArray;
+ nonce = e.data.nonce;
+ res();
+ }
+ });
+
+ let _response = await parentEpml.request('sign_chat', {
+ nonce: this.selectedAddress.nonce,
+ chatBytesArray: chatBytesArray,
+ chatNonce: nonce
+ });
+
+ getSendChatResponse(_response);
+ };
+
+ const getSendChatResponse = (response) => {
+ if (response === true) {
+ this.setActiveChatHeadUrl(`direct/${recipient}`);
+ this.shadowRoot.getElementById('sendTo').value = "";
+ this.openPrivateMessage = false;
+ this.chatEditor.resetValue();
+ } else if (response.error) {
+ parentEpml.request('showSnackBar', response.message);
+ } else {
+ let err2string = get("chatpage.cchange21");
+ parentEpml.request('showSnackBar', `${err2string}`);
+ }
+
+ this.isLoading = false;
+ this.chatEditor.enable();
+ };
+
+ // Exec..
+ getAddressPublicKey();
+
+ }
+
+ insertImage(file) {
+ if (file.type.includes('image')) {
+ this.imageFile = file;
+ this.chatEditor.disable();
+ return;
+ }
+ parentEpml.request('showSnackBar', get("chatpage.cchange28"));
+ }
+
renderLoadingText() {
return html`${translate("chatpage.cchange2")}`
}
@@ -720,7 +758,6 @@ class Chat extends LitElement {
const compareArgs = (a, b) => {
return b.timestamp - a.timestamp
}
-
this.chatHeads = chatHeadMasterList.sort(compareArgs)
}
@@ -735,163 +772,6 @@ class Chat extends LitElement {
}
}
- _sendMessage() {
-
- this.isLoading = true
-
- const recipient = this.shadowRoot.getElementById('sendTo').value
- const messageBox = this.shadowRoot.getElementById('messageBox')
- const messageText = messageBox.value
-
- if (recipient.length === 0) {
- this.isLoading = false
- } else if (messageText.length === 0) {
- this.isLoading = false
- } else {
- this.sendMessage()
- }
- }
-
- async sendMessage(e) {
-
- this.isLoading = true
-
- const _recipient = this.shadowRoot.getElementById('sendTo').value
- const messageBox = this.shadowRoot.getElementById('messageBox')
- const messageText = messageBox.value
- let recipient
-
- const validateName = async (receiverName) => {
-
- let myRes
- let myNameRes = await parentEpml.request('apiCall', {
- type: 'api',
- url: `/names/${receiverName}`
- })
-
- if (myNameRes.error === 401) {
- myRes = false
- } else {
- myRes = myNameRes
- }
- return myRes
- }
-
- const myNameRes = await validateName(_recipient)
- if (!myNameRes) {
-
- recipient = _recipient
- } else {
-
- recipient = myNameRes.owner
- }
-
- let _reference = new Uint8Array(64);
- window.crypto.getRandomValues(_reference);
-
- let sendTimestamp = Date.now()
-
- let reference = window.parent.Base58.encode(_reference)
-
- const getAddressPublicKey = async () => {
- let isEncrypted
- let _publicKey
-
- let addressPublicKey = await parentEpml.request('apiCall', {
- type: 'api',
- url: `/addresses/publickey/${recipient}`
- })
-
- if (addressPublicKey.error === 102) {
- _publicKey = false
- let err4string = get("chatpage.cchange19")
- parentEpml.request('showSnackBar', `${err4string}`)
- this.isLoading = false
- } else if (addressPublicKey !== false) {
- isEncrypted = 1
- _publicKey = addressPublicKey
- sendMessageRequest(isEncrypted, _publicKey)
- } else {
- isEncrypted = 0
- _publicKey = this.selectedAddress.address
- sendMessageRequest(isEncrypted, _publicKey)
- }
- };
-
- const sendMessageRequest = async (isEncrypted, _publicKey) => {
- const messageObject = {
- messageText,
- images: [''],
- repliedTo: '',
- version: 1
- }
- const stringifyMessageObject = JSON.stringify(messageObject)
- let chatResponse = await parentEpml.request('chat', {
- type: 18,
- nonce: this.selectedAddress.nonce,
- params: {
- timestamp: sendTimestamp,
- recipient: recipient,
- recipientPublicKey: _publicKey,
- hasChatReference: 0,
- message: stringifyMessageObject,
- lastReference: reference,
- proofOfWorkNonce: 0,
- isEncrypted: isEncrypted,
- isText: 1
- }
- })
-
- _computePow(chatResponse)
- }
-
- const _computePow = async (chatBytes) => {
-
- const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; });
- const chatBytesArray = new Uint8Array(_chatBytesArray)
- const chatBytesHash = new window.parent.Sha256().process(chatBytesArray).finish().result
- const hashPtr = window.parent.sbrk(32, window.parent.heap);
- const hashAry = new Uint8Array(window.parent.memory.buffer, hashPtr, 32)
-
- hashAry.set(chatBytesHash);
-
- const difficulty = this.balance === 0 ? 12 : 8
-
- const workBufferLength = 8 * 1024 * 1024;
- const workBufferPtr = window.parent.sbrk(workBufferLength, window.parent.heap)
-
- let nonce = window.parent.computePow(hashPtr, workBufferPtr, workBufferLength, difficulty)
-
- let _response = await parentEpml.request('sign_chat', {
- nonce: this.selectedAddress.nonce,
- chatBytesArray: chatBytesArray,
- chatNonce: nonce
- })
-
- getSendChatResponse(_response)
- }
-
- const getSendChatResponse = (response) => {
-
- if (response === true) {
- messageBox.value = ""
- let err5string = get("chatpage.cchange20")
- parentEpml.request('showSnackBar', `${err5string}`)
- this.isLoading = false
- } else if (response.error) {
- parentEpml.request('showSnackBar', response.message)
- this.isLoading = false
- } else {
- let err6string = get("chatpage.cchange21")
- parentEpml.request('showSnackBar', `${err6string}`)
- this.isLoading = false
- }
- }
-
- // Exec..
- getAddressPublicKey()
- }
-
_textMenu(event) {
const getSelectedText = () => {