diff --git a/core/language/us.json b/core/language/us.json index 76458f9f..257c770b 100644 --- a/core/language/us.json +++ b/core/language/us.json @@ -1176,5 +1176,18 @@ "notify1": "Confirming transaction", "notify2": "Transaction confirmed", "explanation": "Your transaction is getting confirmed. To track its progress, click on the bell icon." + }, + "friends": { + "friend1": "Add name", + "friend2": "Add friend", + "friend3": "Adding a friend allows you to connect easily with that person. Be sure to also follow that user to support the hosting of their published resources.", + "friend4": "Notes", + "friend5": "Follow name", + "friend6": "Alias", + "friend7": "Add an alias to better remember your friend (Optional)", + "friend8": "Send a Q-Chat message", + "friend9": "Send a Q-Mail", + "friend10": "Edit friend", + "friend11": "Following" } } \ No newline at end of file diff --git a/core/src/components/app-view.js b/core/src/components/app-view.js index ca5a6732..814a18b9 100644 --- a/core/src/components/app-view.js +++ b/core/src/components/app-view.js @@ -43,6 +43,7 @@ import '../functional-components/side-menu-item.js' import './start-minting.js' import './notification-view/notification-bell.js' import './notification-view/notification-bell-general.js' +import './friends-view/friends-side-panel-parent.js' const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -559,8 +560,10 @@ class AppView extends connect(store)(LitElement) {
+ +
@@ -647,6 +650,8 @@ class AppView extends connect(store)(LitElement) {
+
+ ` } diff --git a/core/src/components/friends-view/ChatSideNavHeads.js b/core/src/components/friends-view/ChatSideNavHeads.js new file mode 100644 index 00000000..f74536d0 --- /dev/null +++ b/core/src/components/friends-view/ChatSideNavHeads.js @@ -0,0 +1,222 @@ +import { LitElement, html, css } from 'lit' +import { render } from 'lit/html.js' +import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' +import '@material/mwc-icon' +import '@vaadin/tooltip'; + +import './friend-item-actions' + +class ChatSideNavHeads extends LitElement { + static get properties() { + return { + selectedAddress: { type: Object }, + config: { type: Object }, + chatInfo: { type: Object }, + iconName: { type: String }, + activeChatHeadUrl: { type: String }, + isImageLoaded: { type: Boolean }, + setActiveChatHeadUrl: {attribute: false}, + openEditFriend: {attribute: false} + } + } + + static get styles() { + return css` + :host { + width: 100%; + } + ul { + list-style-type: none; + } + li { + padding: 10px 2px 10px 5px; + cursor: pointer; + width: 100%; + display: flex; + box-sizing: border-box; + font-size: 14px; + transition: 0.2s background-color; + } + + li:hover { + background-color: var(--lightChatHeadHover); + } + + .active { + background: var(--menuactive); + border-left: 4px solid #3498db; + } + + .img-icon { + font-size:40px; + color: var(--chat-group); + } + + .status { + color: #92959e; + } + + .clearfix { + display: flex; + align-items: center; + } + + .clearfix:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; + } + ` + } + + constructor() { + super() + this.selectedAddress = {} + this.config = { + user: { + node: { + + } + } + } + this.chatInfo = {} + this.iconName = '' + this.activeChatHeadUrl = '' + this.isImageLoaded = false + this.imageFetches = 0 + } + + createImage(imageUrl) { + const imageHTMLRes = new Image(); + imageHTMLRes.src = imageUrl; + imageHTMLRes.style= "width:30px; height:30px; float: left; border-radius:50%; font-size:14px"; + imageHTMLRes.onclick= () => { + this.openDialogImage = true; + } + imageHTMLRes.onload = () => { + this.isImageLoaded = true; + } + imageHTMLRes.onerror = () => { + if (this.imageFetches < 4) { + setTimeout(() => { + this.imageFetches = this.imageFetches + 1; + imageHTMLRes.src = imageUrl; + }, 500); + } else { + this.isImageLoaded = false + } + }; + return imageHTMLRes; + } + + render() { + let avatarImg = "" + if (this.chatInfo.name) { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port; + const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.name}/qortal_avatar?async=true&apiKey=${myNode.apiKey}`; + avatarImg = this.createImage(avatarUrl) + } + + return html` +
  • { + const target = e.target + const popover = + this.shadowRoot.querySelector('friend-item-actions'); + if (popover) { + popover.openPopover(target); + } + }} class="clearfix" id=${`friend-item-parent-${this.chatInfo.name}`}> +
    + ${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.willFollow ? html` + connect_without_contact + + + ` : ''} +
    +
  • + { + this.openEditFriend(this.chatInfo) + }} + name=${this.chatInfo.name} + > + ` + } + + + + shouldUpdate(changedProperties) { + if(changedProperties.has('activeChatHeadUrl')){ + return true + } + if(changedProperties.has('chatInfo')){ + return true + } + if(changedProperties.has('isImageLoaded')){ + return true + } + + return false + } + + getUrl(chatUrl) { + this.setActiveChatHeadUrl(chatUrl) + } + + +} + +window.customElements.define('chat-side-nav-heads', ChatSideNavHeads) diff --git a/core/src/components/friends-view/add-friends-modal.js b/core/src/components/friends-view/add-friends-modal.js new file mode 100644 index 00000000..eabe0adb --- /dev/null +++ b/core/src/components/friends-view/add-friends-modal.js @@ -0,0 +1,253 @@ +import { LitElement, html, css } from 'lit'; +import { render } from 'lit/html.js'; +import { + use, + get, + translate, + translateUnsafeHTML, + registerTranslateConfig, +} from 'lit-translate'; +import '@material/mwc-button'; +import '@material/mwc-dialog'; +import '@material/mwc-checkbox'; + +class AddFriendsModal extends LitElement { + static get properties() { + return { + isOpen: { type: Boolean }, + setIsOpen: { attribute: false }, + isLoading: { type: Boolean }, + userSelected: { type: Object }, + alias: { type: String }, + willFollow: { type: Boolean }, + notes: { type: String }, + onSubmit: {attribute: false}, + editContent: {type: Object}, + onClose: {attribute: false} + }; + } + + constructor() { + super(); + this.isOpen = false; + this.isLoading = false; + this.alias = ''; + this.willFollow = true; + this.notes = ''; + } + + static get styles() { + return css` + * { + --mdc-theme-primary: rgb(3, 169, 244); + --mdc-theme-secondary: var(--mdc-theme-primary); + --mdc-theme-surface: var(--white); + --mdc-dialog-content-ink-color: var(--black); + --mdc-dialog-min-width: 400px; + --mdc-dialog-max-width: 1024px; + } + .input { + width: 90%; + 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); + box-sizing: border-box; + } + + .input::selection { + background-color: var(--mdc-theme-primary); + color: white; + } + + .input::placeholder { + opacity: 0.6; + color: var(--black); + } + + .close-button { + display: block; + --mdc-theme-primary: red; + } + .checkbox-row { + position: relative; + display: flex; + align-items: center; + align-content: center; + font-family: Montserrat, sans-serif; + font-weight: 600; + color: var(--black); + } + .modal-overlay { + display: block; + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent backdrop */ + z-index: 1000; + } + + .modal-content { + position: fixed; + top: 50vh; + left: 50vw; + transform: translate(-50%, -50%); + background-color: var(--mdc-theme-surface); + width: 80vw; + max-width: 600px; + padding: 20px; + box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px; + z-index: 1001; + border-radius: 5px; + max-height: 80vh; + overflow: auto; + } + .modal-overlay.hidden { + display: none; + } + `; + } + + firstUpdated() {} + + clearFields(){ + this.alias = ''; + this.willFollow = true; + this.notes = ''; + } + + addFriend(){ + + this.onSubmit({ + name: this.userSelected.name, + alias: this.alias, + notes: this.notes, + willFollow: this.willFollow + }) + this.clearFields() + this.onClose() + } + + + async updated(changedProperties) { + if (changedProperties && changedProperties.has('editContent') && this.editContent) { + console.log('this.editedContent', this.editContent) + this.userSelected = { + name: this.editContent.name ?? '', + } + this.notes = this.editContent.notes ?? '' + this.willFollow = this.editContent.willFollow ?? true + this.alias = this.editContent.alias ?? '' + } + + + } + + render() { + console.log('hello2', this.editContent) + return html` + + `; + } +} + +customElements.define('add-friends-modal', AddFriendsModal); diff --git a/core/src/components/friends-view/friend-item-actions.js b/core/src/components/friends-view/friend-item-actions.js new file mode 100644 index 00000000..6b0f55af --- /dev/null +++ b/core/src/components/friends-view/friend-item-actions.js @@ -0,0 +1,224 @@ +// popover-component.js +import { LitElement, html, css } from 'lit'; +import { createPopper } from '@popperjs/core'; +import '@material/mwc-icon'; +import { use, get, translate } from 'lit-translate'; +import { store } from '../../store'; +import { connect } from 'pwa-helpers'; +import { setNewTab, setSideEffectAction } from '../../redux/app/app-actions'; +import ShortUniqueId from 'short-unique-id'; + +export class FriendItemActions extends connect(store)(LitElement) { + static styles = css` + :host { + display: none; + position: absolute; + background-color: var(--white); + border: 1px solid #ddd; + padding: 8px; + z-index: 10; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + color: var(--black); + max-width: 250px; + } + + .close-icon { + cursor: pointer; + float: right; + margin-left: 10px; + color: var(--black); + } + + .send-message-button { + font-family: Roboto, sans-serif; + letter-spacing: 0.3px; + font-weight: 300; + padding: 8px 5px; + border-radius: 3px; + text-align: center; + color: var(--mdc-theme-primary); + transition: all 0.3s ease-in-out; + } + + .send-message-button:hover { + cursor: pointer; + background-color: #03a8f485; + } + .action-parent { + display: flex; + flex-direction: column; + width: 100%; + } + + div[tabindex='0']:focus { + outline: none; + } + `; + + static get properties() { + return { + for: { type: String, reflect: true }, + message: { type: String }, + openEditFriend: { attribute: false }, + name: { type: String }, + }; + } + + constructor() { + super(); + this.message = ''; + this.nodeUrl = this.getNodeUrl(); + this.uid = new ShortUniqueId(); + this.getUserAddress = this.getUserAddress.bind(this) + } + getNodeUrl() { + const myNode = + store.getState().app.nodeConfig.knownNodes[ + window.parent.reduxStore.getState().app.nodeConfig.node + ]; + + const nodeUrl = + myNode.protocol + '://' + myNode.domain + ':' + myNode.port; + return nodeUrl; + } + + firstUpdated() { + // We'll defer the popper attachment to the openPopover() method to ensure target availability + } + + attachToTarget(target) { + console.log({ target }); + if (!this.popperInstance && target) { + this.popperInstance = createPopper(target, this, { + placement: 'bottom', + strategy: 'fixed', + }); + } + } + + openPopover(target) { + this.attachToTarget(target); + this.style.display = 'block'; + setTimeout(() => { + this.shadowRoot.getElementById('parent-div').focus(); + }, 50); + } + + closePopover() { + this.style.display = 'none'; + if (this.popperInstance) { + this.popperInstance.destroy(); + this.popperInstance = null; + } + this.requestUpdate(); + } + handleBlur() { + setTimeout(() => { + this.closePopover(); + }, 0); + } + + async getUserAddress() { + try { + const url = `${this.nodeUrl}/names/${this.name}`; + const res = await fetch(url); + const result = await res.json(); + if (result.error === 401) { + return ''; + } else { + return result.owner; + } + } catch (error) { + return ''; + } + } + + render() { + return html` +
    + close +
    +
    + ${translate('friends.friend10')} +
    +
    + ${translate('friends.friend8')} +
    +
    + ${translate('friends.friend9')} +
    +
    +
    + `; + } +} + +customElements.define('friend-item-actions', FriendItemActions); diff --git a/core/src/components/friends-view/friends-side-panel-parent.js b/core/src/components/friends-view/friends-side-panel-parent.js new file mode 100644 index 00000000..c8564523 --- /dev/null +++ b/core/src/components/friends-view/friends-side-panel-parent.js @@ -0,0 +1,61 @@ +import { LitElement, html, css } from 'lit'; +import '@material/mwc-icon'; +import './friends-side-panel.js'; +class FriendsSidePanelParent extends LitElement { + static get properties() { + return { + isOpen: {type: Boolean} + }; + } + + + constructor() { + super(); + this.isOpen = false + } + static styles = css` + .header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px; + border-bottom: 1px solid #e0e0e0; + } + + .content { + padding: 16px; + } + .close { + visibility: hidden; + position: fixed; + z-index: -100; + right: -1000px; + } + + .parent-side-panel { + transform: translateX(100%); /* start from outside the right edge */ + transition: transform 0.3s ease-in-out; + } + .parent-side-panel.open { + transform: translateX(0); /* slide in to its original position */ + + } + `; + + render() { + return html` + { + this.isOpen = !this.isOpen + }} style="color: var(--black); cursor:pointer" + >group + this.isOpen = val}> + + + `; + } + + +} + +customElements.define('friends-side-panel-parent', FriendsSidePanelParent); diff --git a/core/src/components/friends-view/friends-side-panel.js b/core/src/components/friends-view/friends-side-panel.js new file mode 100644 index 00000000..009e7d16 --- /dev/null +++ b/core/src/components/friends-view/friends-side-panel.js @@ -0,0 +1,61 @@ +import { LitElement, html, css } from 'lit'; +import '@material/mwc-icon'; +import './friends-view' +class FriendsSidePanel extends LitElement { + static get properties() { + return { + setIsOpen: { attribute: false}, + isOpen: {type: Boolean} + }; + } + + static styles = css` + :host { + display: block; + position: fixed; + top: 55px; + right: 0px; + width: 420px; + max-width: 95%; + height: calc(100vh - 55px); + background-color: var(--white); + border-left: 1px solid rgb(224, 224, 224); + overflow-y: auto; + z-index: 1; + transform: translateX(100%); /* start from outside the right edge */ + transition: transform 0.3s ease-in-out; + } + :host([isOpen]) { + transform: unset; /* slide in to its original position */ + } + + .header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px; + border-bottom: 1px solid #e0e0e0; + } + + .content { + padding: 16px; + } + `; + + render() { + return html` +
    + Panel Title + { + this.setIsOpen(false) + }}>close +
    +
    +
    + + `; + } + +} + +customElements.define('friends-side-panel', FriendsSidePanel); diff --git a/core/src/components/friends-view/friends-view-css.js b/core/src/components/friends-view/friends-view-css.js new file mode 100644 index 00000000..c1d2be4b --- /dev/null +++ b/core/src/components/friends-view/friends-view-css.js @@ -0,0 +1,178 @@ +import { css } from 'lit' + +export const friendsViewStyles = css` + .top-bar-icon { + cursor: pointer; + height: 18px; + width: 18px; + transition: 0.2s all; + } + + .top-bar-icon:hover { + color: var(--black); + } + + .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; + } + + .close-row { + width: 100%; + display: flex; + justify-content: flex-end; + height: 50px; + flex:0 + + } + + .container-body { + width: 100%; + display: flex; + flex-direction: column; + flex-grow: 1; + margin-top: 5px; + padding: 0px 6px; + box-sizing: border-box; + align-items: center; + } + + .container-body::-webkit-scrollbar-track { + background-color: whitesmoke; + border-radius: 7px; + } + + .container-body::-webkit-scrollbar { + width: 6px; + border-radius: 7px; + background-color: whitesmoke; + } + + .container-body::-webkit-scrollbar-thumb { + background-color: rgb(180, 176, 176); + border-radius: 7px; + transition: all 0.3s ease-in-out; + } + + .container-body::-webkit-scrollbar-thumb:hover { + background-color: rgb(148, 146, 146); + cursor: pointer; + } + + p { + color: var(--black); + margin: 0px; + padding: 0px; + word-break: break-all; + } + + .container { + display: flex; + width: 100%; + flex-direction: column; + height: 100%; + } + + .chat-right-panel-label { + font-family: Montserrat, sans-serif; + color: var(--group-header); + padding: 5px; + font-size: 13px; + user-select: none; + } + + .group-info { + display: flex; + flex-direction: column; + justify-content: flex-start; + gap: 10px; + } + + .group-name { + font-family: Raleway, sans-serif; + font-size: 20px; + color: var(--chat-bubble-msg-color); + text-align: center; + user-select: none; + } + + .group-description { + font-family: Roboto, sans-serif; + color: var(--chat-bubble-msg-color); + letter-spacing: 0.3px; + font-weight: 300; + font-size: 14px; + margin-top: 15px; + word-break: break-word; + user-select: none; + } + + .group-subheader { + font-family: Montserrat, sans-serif; + font-size: 14px; + color: var(--chat-bubble-msg-color); + } + + .group-data { + font-family: Roboto, sans-serif; + letter-spacing: 0.3px; + font-weight: 300; + font-size: 14px; + color: var(--chat-bubble-msg-color); + } + .search-results-div { + position: absolute; + top: 25px; + right: 25px; + } + + .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); + box-sizing: border-box; + } + + .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; + } +` diff --git a/core/src/components/friends-view/friends-view.js b/core/src/components/friends-view/friends-view.js new file mode 100644 index 00000000..c4f3c198 --- /dev/null +++ b/core/src/components/friends-view/friends-view.js @@ -0,0 +1,303 @@ +import { LitElement, html, css } from 'lit'; +import { render } from 'lit/html.js'; +import { connect } from 'pwa-helpers'; + +import '@material/mwc-button'; +import '@material/mwc-dialog'; +import '@polymer/paper-spinner/paper-spinner-lite.js'; +import '@polymer/paper-progress/paper-progress.js'; +import '@material/mwc-icon'; +import '@vaadin/icon' +import '@vaadin/icons' +import '@vaadin/button'; +import './ChatSideNavHeads'; +import '../../../../plugins/plugins/core/components/ChatSearchResults' +import './add-friends-modal' + +import { + use, + get, + translate, + translateUnsafeHTML, + registerTranslateConfig, +} from 'lit-translate'; +import { store } from '../../store'; +import { friendsViewStyles } from './friends-view-css'; +import { parentEpml } from '../show-plugin'; + +class FriendsView extends connect(store)(LitElement) { + static get properties() { + return { + error: { type: Boolean }, + toggle: { attribute: false }, + userName: { type: String }, + errorMessage: { type: String }, + successMessage: { type: String }, + setUserName: { attribute: false }, + friendList: { type: Array }, + userSelected: { type: Object }, + isLoading: {type: Boolean}, + userFoundModalOpen: {type: Boolean}, + userFound: { type: Array}, + isOpenAddFriendsModal: {type: Boolean}, + editContent: {type: Object} + }; + } + static get styles() { + return [friendsViewStyles]; + } + + constructor() { + super(); + this.error = false; + this.observerHandler = this.observerHandler.bind(this); + this.viewElement = ''; + this.downObserverElement = ''; + this.myAddress = + window.parent.reduxStore.getState().app.selectedAddress.address; + this.errorMessage = ''; + this.successMessage = ''; + this.friendList = [{ + + name: "Phil" + + }]; + this.userSelected = {}; + this.isLoading = false; + this.userFoundModalOpen = false + this.userFound = []; + this.nodeUrl = this.getNodeUrl(); + this.myNode = this.getMyNode(); + this.isOpenAddFriendsModal = false + this.editContent = null + this.addToFriendList = this.addToFriendList.bind(this) + } + + getNodeUrl() { + const myNode = + store.getState().app.nodeConfig.knownNodes[ + window.parent.reduxStore.getState().app.nodeConfig.node + ]; + + const nodeUrl = + myNode.protocol + '://' + myNode.domain + ':' + myNode.port; + return nodeUrl; + } + getMyNode() { + const myNode = + store.getState().app.nodeConfig.knownNodes[ + window.parent.reduxStore.getState().app.nodeConfig.node + ]; + + return myNode; + } + + getMoreFriends() {} + + firstUpdated() { + this.viewElement = this.shadowRoot.getElementById('viewElement'); + this.downObserverElement = + this.shadowRoot.getElementById('downObserver'); + this.elementObserver(); + } + + elementObserver() { + const options = { + root: this.viewElement, + rootMargin: '0px', + threshold: 1, + }; + // identify an element to observe + const elementToObserve = this.downObserverElement; + // passing it a callback function + const observer = new IntersectionObserver( + this.observerHandler, + options + ); + // call `observe()` on that MutationObserver instance, + // passing it the element to observe, and the options object + observer.observe(elementToObserve); + } + + observerHandler(entries) { + if (!entries[0].isIntersecting) { + return; + } else { + if (this.friendList.length < 20) { + return; + } + this.getMoreFriends(); + } + } + + async userSearch() { + const nameValue = this.shadowRoot.getElementById('sendTo').value + if(!nameValue) { + this.userFound = [] + this.userFoundModalOpen = true + return; + } + try { + const url = `${this.nodeUrl}/names/${nameValue}` + const res = await fetch(url) + const result = await res.json() + if (result.error === 401) { + this.userFound = [] + } else { + this.userFound = [ + ...this.userFound, + result, + ]; + } + this.userFoundModalOpen = true; + } catch (error) { + // let err4string = get("chatpage.cchange35"); + // parentEpml.request('showSnackBar', `${err4string}`) + } + } + + getApiKey() { + const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let apiKey = apiNode.apiKey + return apiKey + } + + async myFollowName(name) { + let items = [ + name + ] + let namesJsonString = JSON.stringify({ "items": items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + this.myFollowedNames = this.myFollowedNames.filter(item => item != name) + this.myFollowedNames.push(name) + } else { + let err3string = get("appspage.schange22") + parentEpml.request('showSnackBar', `${err3string}`) + } + return ret + } + addToFriendList(val){ + if(this.editContent){ + const findFriend = this.friendList.findIndex(item=> item.name === val.name) + if(findFriend !== -1){ + const copyList = [...this.friendList] + copyList[findFriend] = val + this.friendList = copyList + + } + + } else { + this.friendList = [...this.friendList, val] + } + if(val.willFollow){ + this.myFollowName(val.name) + } + + this.userSelected = {}; + this.isLoading = false; + this.isOpenAddFriendsModal = false + this.editContent = null + } + openEditFriend(val){ + this.isOpenAddFriendsModal = true + this.userSelected = val + this.editContent = val + } + + onClose(){ + console.log('hello100') + this.isLoading = false; + this.isOpenAddFriendsModal = false + this.editContent = null + this.userSelected = {} + } + + render() { + console.log('friends', this.userSelected); + return html` +
    +
    +

    My Friends

    +
    + { + if(e.key === 'Enter'){ + this.userSearch() + } + }} + /> + + + + +
    +
    + { + this.userSelected = result; + this.isOpenAddFriendsModal = true + + console.log({result}); + this.userFound = []; + this.userFoundModalOpen = false; + }} + .closeFunc=${() => { + this.userFoundModalOpen = false; + this.userFound = []; + }} + .searchResults=${this.userFound} + ?isOpen=${this.userFoundModalOpen} + ?loading=${this.isLoading}> + +
    +
    + + ${this.friendList.map((item) => { + return html` { + + }} + .chatInfo=${item} + .openEditFriend=${(val)=> this.openEditFriend(val)} + >`; + })} +
    +
    +
    + { + this.isOpenAddFriendsModal = val + }} + .userSelected=${this.userSelected} + .onSubmit=${(val)=> this.addToFriendList(val)} + .editContent=${this.editContent} + .onClose=${()=> this.onClose()} + > + + `; + } +} + +customElements.define('friends-view', FriendsView); diff --git a/core/src/components/notification-view/notification-bell-general.js b/core/src/components/notification-view/notification-bell-general.js index 125c8095..1a0a72fb 100644 --- a/core/src/components/notification-view/notification-bell-general.js +++ b/core/src/components/notification-view/notification-bell-general.js @@ -111,13 +111,13 @@ class NotificationBellGeneral extends connect(store)(LitElement) { > ${hasOngoing ? html` - notifications ` : html` notifications `} diff --git a/core/src/components/show-plugin.js b/core/src/components/show-plugin.js index c6ff4d34..abf21b9c 100644 --- a/core/src/components/show-plugin.js +++ b/core/src/components/show-plugin.js @@ -26,11 +26,9 @@ import '@vaadin/grid' import '@vaadin/text-field' import '../custom-elements/frag-file-input.js' -const chatLastSeen = localForage.createInstance({ - name: "chat-last-seen", -}) -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + +export const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) class ShowPlugin extends connect(store)(LitElement) { static get properties() { diff --git a/package-lock.json b/package-lock.json index 71aadf01..1c1fab36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7407,15 +7407,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -7462,15 +7453,6 @@ "is-potential-custom-element-name": "^1.0.0" } }, - "node_modules/is-valid-element-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-element-name/-/is-valid-element-name-1.0.0.tgz", - "integrity": "sha512-GZITEJY2LkSjQfaIPBha7eyZv+ge0PhBR7KITeCCWvy7VBQrCUdFkvpI+HrAPQjVtVjy1LvlEkqQTHckoszruw==", - "dev": true, - "dependencies": { - "is-potential-custom-element-name": "^1.0.0" - } - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -7758,19 +7740,6 @@ "node": ">= 0.8.0" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/lie": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", @@ -9746,18 +9715,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", diff --git a/plugins/plugins/core/components/ChatSearchResults.js b/plugins/plugins/core/components/ChatSearchResults.js index b8b19cb5..bf2d7075 100644 --- a/plugins/plugins/core/components/ChatSearchResults.js +++ b/plugins/plugins/core/components/ChatSearchResults.js @@ -1,12 +1,10 @@ import { LitElement, html } from 'lit' import { render } from 'lit/html.js' -import { Epml } from '../../../epml.js' import { chatSearchResultsStyles } from './ChatSearchResults-css.js' import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' import '@vaadin/icon' import '@vaadin/icons' -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) export class ChatSearchResults extends LitElement { static get properties() { @@ -19,7 +17,10 @@ export class ChatSearchResults extends LitElement { } } - static styles = [chatSearchResultsStyles] + static get styles() { + return [chatSearchResultsStyles]; + } + render() { return html` diff --git a/plugins/plugins/core/messaging/q-chat/q-chat.src.js b/plugins/plugins/core/messaging/q-chat/q-chat.src.js index f73558c4..b15388ca 100644 --- a/plugins/plugins/core/messaging/q-chat/q-chat.src.js +++ b/plugins/plugins/core/messaging/q-chat/q-chat.src.js @@ -221,6 +221,8 @@ class Chat extends LitElement { } render() { + console.log('chatHeads', this.chatHeads) + console.log('chatHeadsObj', this.chatHeadsObj) return html`
    @@ -516,6 +518,26 @@ class Chat extends LitElement { chatHeads = JSON.parse(chatHeads) this.getChatHeadFromState(chatHeads) }) + parentEpml.subscribe('side_effect_action', async sideEffectActionParam => { + const sideEffectAction = JSON.parse(sideEffectActionParam) + + if(sideEffectAction && sideEffectAction.type === 'openPrivateChat'){ + const name = sideEffectAction.data.name + const address = sideEffectAction.data.address + console.log({address}, this.chatHeadsObj) + if(this.chatHeadsObj.direct && this.chatHeadsObj.direct.find(item=> item.address === address)){ + this.setActiveChatHeadUrl(`direct/${address}`) + window.parent.reduxStore.dispatch( + window.parent.reduxAction.setSideEffectAction(null)) + } else { + this.setOpenPrivateMessage({ + open: true, + name: name + }) + } + + } + }) parentEpml.request('apiCall', { url: `/addresses/balance/${window.parent.reduxStore.getState().app.selectedAddress.address}` }).then(res => {