mirror of https://github.com/qortal/qortal-ui
Phillip Lang Martinez
2 years ago
14 changed files with 1900 additions and 1035 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -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` |
||||
<div class="chat-results-card" style=${this.isOpen ? "display: block;" : "display: none;"}> |
||||
<vaadin-icon
|
||||
@click=${() => this.closeFunc()}
|
||||
icon="vaadin:close-small"
|
||||
slot="icon" |
||||
class="close-icon" |
||||
> |
||||
</vaadin-icon> |
||||
${this.loading ? ( |
||||
html` |
||||
<div class="spinner-container"> |
||||
<paper-spinner-lite active></paper-spinner-lite> |
||||
</div> |
||||
` |
||||
) : ( |
||||
html` |
||||
<p class="chat-result-header">${translate("chatpage.cchange36")}</p> |
||||
<div class="divider"></div> |
||||
<div class="chat-result-container"> |
||||
${this.searchResults.length === 0 ? ( |
||||
html`<p class="no-results">${translate("chatpage.cchange37")}</p>` |
||||
) : ( |
||||
html` |
||||
${this.searchResults.map((result) => { |
||||
return ( |
||||
html` |
||||
<div class="chat-result-card" @click=${() => { |
||||
this.shadowRoot.querySelector(".chat-result-card").classList.add("active"); |
||||
this.onClickFunc(result); |
||||
}}> |
||||
<p class="chat-result"> |
||||
${result.name} |
||||
</p> |
||||
</div> |
||||
` |
||||
)} |
||||
)} |
||||
` |
||||
)} |
||||
</div> |
||||
` |
||||
)} |
||||
</div> |
||||
`;
|
||||
} |
||||
} |
||||
customElements.define('chat-search-results', ChatSearchResults); |
@ -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; |
||||
} |
||||
` |
@ -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 |
||||
} |
@ -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; |
||||
} |
||||
` |
Loading…
Reference in new issue