diff --git a/core/language/us.json b/core/language/us.json index 8bb58d8e..6e22363d 100644 --- a/core/language/us.json +++ b/core/language/us.json @@ -1249,6 +1249,8 @@ "profile21": "Insert address from UI", "profile22": "Success", "profile23": "encrypted", - "profile24": "You must fill out both field name and field value to add a custom property" + "profile24": "You must fill out both field name and field value to add a custom property", + "profile25": "Is your friend", + "profile26": "Add as friend" } } diff --git a/core/src/components/friends-view/friend-item-actions.js b/core/src/components/friends-view/friend-item-actions.js index 1f62f045..da9ffe87 100644 --- a/core/src/components/friends-view/friend-item-actions.js +++ b/core/src/components/friends-view/friend-item-actions.js @@ -1,11 +1,11 @@ // popover-component.js -import {css, html, LitElement} from 'lit'; -import {createPopper} from '@popperjs/core'; +import { css, html, LitElement } from 'lit'; +import { createPopper } from '@popperjs/core'; import '@material/mwc-icon'; -import {translate} from 'lit-translate'; -import {store} from '../../store'; -import {connect} from 'pwa-helpers'; -import {setNewTab, setSideEffectAction} from '../../redux/app/app-actions'; +import { 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) { @@ -40,7 +40,7 @@ export class FriendItemActions extends connect(store)(LitElement) { transition: all 0.3s ease-in-out; display: flex; align-items: center; - gap: 10px + gap: 10px; } .send-message-button:hover { @@ -64,7 +64,7 @@ export class FriendItemActions extends connect(store)(LitElement) { message: { type: String }, openEditFriend: { attribute: false }, name: { type: String }, - closeSidePanel: {attribute: false, type: Object} + closeSidePanel: { attribute: false, type: Object }, }; } @@ -73,7 +73,7 @@ export class FriendItemActions extends connect(store)(LitElement) { this.message = ''; this.nodeUrl = this.getNodeUrl(); this.uid = new ShortUniqueId(); - this.getUserAddress = this.getUserAddress.bind(this) + this.getUserAddress = this.getUserAddress.bind(this); } getNodeUrl() { const myNode = @@ -93,7 +93,7 @@ export class FriendItemActions extends connect(store)(LitElement) { attachToTarget(target) { if (!this.popperInstance && target) { this.popperInstance = createPopper(target, this, { - placement: 'bottom' + placement: 'bottom', }); } } @@ -151,9 +151,7 @@ export class FriendItemActions extends connect(store)(LitElement) { this.closePopover(); }}" > - edit + edit ${translate('friends.friend10')}
- send + send ${translate('friends.friend8')}
- mail + mail ${translate('friends.friend9')}
+
+ person + ${translate('profile.profile18')} +
`; diff --git a/core/src/components/friends-view/friends-side-panel.js b/core/src/components/friends-view/friends-side-panel.js index 2fa558da..df8eb263 100644 --- a/core/src/components/friends-view/friends-side-panel.js +++ b/core/src/components/friends-view/friends-side-panel.js @@ -11,7 +11,8 @@ class FriendsSidePanel extends LitElement { isOpen: {type: Boolean}, selected: {type: String}, setHasNewFeed: {attribute: false}, - closeSidePanel: {attribute: false, type: Object} + closeSidePanel: {attribute: false, type: Object}, + openSidePanel: {attribute: false, type: Object} }; } @@ -19,6 +20,8 @@ class FriendsSidePanel extends LitElement { super() this.selected = 'friends' this.closeSidePanel = this.closeSidePanel.bind(this) + this.openSidePanel = this.openSidePanel.bind(this) + } static styles = css` @@ -112,6 +115,9 @@ class FriendsSidePanel extends LitElement { closeSidePanel(){ this.setIsOpen(false) } + openSidePanel(){ + this.setIsOpen(true) + } render() { return html` @@ -133,7 +139,7 @@ class FriendsSidePanel extends LitElement {
- this.refreshFeed()}> + this.refreshFeed()}>
this.setHasNewFeed(val)}> diff --git a/core/src/components/friends-view/friends-view.js b/core/src/components/friends-view/friends-view.js index 177cbf34..333c5170 100644 --- a/core/src/components/friends-view/friends-view.js +++ b/core/src/components/friends-view/friends-view.js @@ -36,7 +36,8 @@ class FriendsView extends connect(store)(LitElement) { editContent: {type: Object}, mySelectedFeeds: {type: Array}, refreshFeed: {attribute: false}, - closeSidePanel: {attribute: false, type: Object} + closeSidePanel: {attribute: false, type: Object}, + openSidePanel: {attribute:false, type: Object} }; } static get styles() { @@ -65,6 +66,7 @@ class FriendsView extends connect(store)(LitElement) { this.addToFriendList = this.addToFriendList.bind(this) this._updateFriends = this._updateFriends.bind(this) this._updateFeed = this._updateFeed.bind(this) + this._addFriend = this._addFriend.bind(this) } @@ -111,16 +113,35 @@ class FriendsView extends connect(store)(LitElement) { this.mySelectedFeeds = detail this.requestUpdate() } + _addFriend(event){ + const name = event.detail; + const findFriend = this.friendList.find((friend)=> friend.name === name) + if(findFriend){ + this.editContent = {...findFriend, mySelectedFeeds: this.mySelectedFeeds} + this.userSelected = findFriend; + + } else { + this.userSelected = { + name + }; + } + + this.isOpenAddFriendsModal = true + this.openSidePanel() + } connectedCallback() { super.connectedCallback() window.addEventListener('friends-my-friend-list-event', this._updateFriends) window.addEventListener('friends-my-selected-feeds-event', this._updateFeed) + window.addEventListener('add-friend', this._addFriend) } disconnectedCallback() { window.removeEventListener('friends-my-friend-list-event', this._updateFriends) window.addEventListener('friends-my-selected-feeds-event', this._updateFeed) + window.addEventListener('add-friend', this._addFriend) + super.disconnectedCallback() } diff --git a/core/src/components/friends-view/profile.js b/core/src/components/friends-view/profile.js index cbce23f8..be76df42 100644 --- a/core/src/components/friends-view/profile.js +++ b/core/src/components/friends-view/profile.js @@ -21,7 +21,11 @@ import { publishData } from '../../../../plugins/plugins/utils/publish-image.js' import { parentEpml } from '../show-plugin.js'; import '../notification-view/popover.js'; import './avatar.js'; -import { setNewTab, setProfileData } from '../../redux/app/app-actions.js'; +import { + setNewTab, + setProfileData, + setSideEffectAction, +} from '../../redux/app/app-actions.js'; import './profile-modal-update.js'; import { modalHelper } from '../../../../plugins/plugins/utils/publish-modal.js'; @@ -40,12 +44,13 @@ class ProfileQdn extends connect(store)(LitElement) { editContent: { type: Object }, profileData: { type: Object }, imageUrl: { type: String }, - dialogOpenedProfile: {type: Boolean}, - profileDataVisiting: {type: Object}, - nameVisiting: {type: String}, - hasName: {type: Boolean}, - resourceExistsVisiting: {type:Boolean}, - error: {type: String} + dialogOpenedProfile: { type: Boolean }, + profileDataVisiting: { type: Object }, + nameVisiting: { type: String }, + hasName: { type: Boolean }, + resourceExistsVisiting: { type: Boolean }, + error: { type: String }, + isFriend: { type: Boolean }, }; } @@ -55,7 +60,7 @@ class ProfileQdn extends connect(store)(LitElement) { this.getProfile = this.getProfile.bind(this); this._handleQortalRequestSetData = this._handleQortalRequestSetData.bind(this); - this._handleOpenVisiting = this._handleOpenVisiting.bind(this) + this._handleOpenVisiting = this._handleOpenVisiting.bind(this); this.setValues = this.setValues.bind(this); this.saveToQdn = this.saveToQdn.bind(this); this.syncPercentage = 0; @@ -75,25 +80,25 @@ class ProfileQdn extends connect(store)(LitElement) { this.profileData = null; this.qortalRequestCustomData = null; this.imageUrl = ''; - this.dialogOpenedProfile = false + this.dialogOpenedProfile = false; this.profileDataVisiting = null; - this.nameVisiting = "" - this.hasName = false - this.resourceExistsVisiting = undefined - this.error = "" + this.nameVisiting = ''; + this.hasName = false; + this.resourceExistsVisiting = undefined; + this.error = ''; + this.getUserAddress = this.getUserAddress.bind(this); + this.checkIfInFriendsList = this.checkIfInFriendsList.bind(this); + this.isFriend = undefined; } static styles = 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); - box-sizing: border-box; - } + --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); + box-sizing: border-box; + } - .header { display: flex; align-items: center; @@ -192,53 +197,53 @@ class ProfileQdn extends connect(store)(LitElement) { left: 210px; } - .data-info{ - margin-top: 10px; - margin-right: 25px; - display:flex; + .data-info { + margin-top: 10px; + margin-right: 25px; + display: flex; flex-direction: column; align-items: flex-start; min-height: 55vh; max-height: 55vh; - overflow: auto; + overflow: auto; } - + .data-info::-webkit-scrollbar-track { - background: #a1a1a1; - } + background: #a1a1a1; + } - .data-info::-webkit-scrollbar-thumb { - background-color: #6a6c75; - border-radius: 6px; - border: 3px solid #a1a1a1; - } + .data-info::-webkit-scrollbar-thumb { + background-color: #6a6c75; + border-radius: 6px; + border: 3px solid #a1a1a1; + } .data-info > * { - flex-shrink: 0; -} + flex-shrink: 0; + } .decline { - --mdc-theme-primary: var(--mdc-theme-error) - } + --mdc-theme-primary: var(--mdc-theme-error); + } - .warning { - --mdc-theme-primary: #f0ad4e; - } + .warning { + --mdc-theme-primary: #f0ad4e; + } - .green { - --mdc-theme-primary: #198754; - } + .green { + --mdc-theme-primary: #198754; + } - .buttons { - display: inline; - float: right; - margin-bottom: 5px; - } + .buttons { + display: inline; + float: right; + margin-bottom: 5px; + } - .paybutton { - display: inline; - float: left; - margin-bottom: 5px; - } - .round-fullinfo { + .paybutton { + display: inline; + float: left; + margin-bottom: 5px; + } + .round-fullinfo { position: relative; width: 120px; height: 120px; @@ -248,28 +253,35 @@ class ProfileQdn extends connect(store)(LitElement) { } h2 { - margin: 10px 0; - } + margin: 10px 0; + } h3 { margin-top: -80px; - color: #03a9f4; - font-size: 18px; + color: #03a9f4; + font-size: 18px; } - h4 { - margin: 5px 0; - } + h4 { + margin: 5px 0; + } - p { - margin-top: 5px; - line-height: 1.2; - font-size: 16px; - color: var(--black); - text-align: start; - overflow: hidden; - word-break: break-word; - } + p { + margin-top: 5px; + line-height: 1.2; + font-size: 16px; + color: var(--black); + text-align: start; + overflow: hidden; + word-break: break-word; + } + .send-message-button { + cursor: pointer; + transition: all 0.2s; + } + .send-message-button:hover { + transform: scale(1.1); + } `; getNodeUrl() { @@ -326,7 +338,6 @@ class ProfileQdn extends connect(store)(LitElement) { return ret; } - async setValues(response, resource) { if (response) { let data = { ...response }; @@ -365,8 +376,9 @@ class ProfileQdn extends connect(store)(LitElement) { async getVisitingProfile(name) { try { - this.isLoadingVisitingProfile = true - this.nameVisiting = name + this.isLoadingVisitingProfile = true; + this.nameVisiting = name; + this.checkIfInFriendsList(this.nameVisiting); const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=qortal_profile&name=${name}&prefix=true&exactmatchnames=true&excludeblocked=true&limit=20`; const res = await fetch(url); let data = ''; @@ -383,7 +395,7 @@ class ProfileQdn extends connect(store)(LitElement) { try { const response = await this.getRawData(dataItem); if (response.wallets) { - this.profileDataVisiting = response + this.profileDataVisiting = response; // this.setValues(response, dataItem); } else { // this.error = 'Cannot get saved user settings'; @@ -404,36 +416,31 @@ class ProfileQdn extends connect(store)(LitElement) { error: 'No resource found', }; } - } catch (error) { console.log({ error }); } finally { - this.isLoadingVisitingProfile = false - + this.isLoadingVisitingProfile = false; } } async getProfile() { try { - this.error = '' + this.error = ''; const arbFee = await this.getArbitraryFee(); this.fee = arbFee; this.hasAttemptedToFetchResource = true; let resource; - let nameObject + let nameObject; try { - nameObject = store.getState().app.accountInfo.names[0]; - - } catch (error) { - - } + nameObject = store.getState().app.accountInfo.names[0]; + } catch (error) {} if (!nameObject) { this.name = null; - this.error = 'no name' + this.error = 'no name'; throw new Error('no name'); } - this.hasName = true + this.hasName = true; const name = nameObject.name; this.name = name; const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=qortal_profile&name=${name}&prefix=true&exactmatchnames=true&excludeblocked=true&limit=20`; @@ -497,7 +504,12 @@ class ProfileQdn extends connect(store)(LitElement) { state.app.accountInfo && state.app.accountInfo.names.length && state.app.nodeStatus && - state.app.nodeStatus.syncPercent === 100 && this.hasName === false && this.hasAttemptedToFetchResource && state.app.accountInfo && state.app.accountInfo.names && state.app.accountInfo.names.length > 0 + state.app.nodeStatus.syncPercent === 100 && + this.hasName === false && + this.hasAttemptedToFetchResource && + state.app.accountInfo && + state.app.accountInfo.names && + state.app.accountInfo.names.length > 0 ) { this.getProfile(); } @@ -541,21 +553,24 @@ class ProfileQdn extends connect(store)(LitElement) { const getArbitraryFee = await this.getArbitraryFee(); const feeAmount = getArbitraryFee.fee; - let newObject = structuredClone(data) + let newObject = structuredClone(data); for (const key of Object.keys(newObject.customData || {})) { if (key.includes('-private')) { - const dataKey = newObject.customData[key] - let isBase64 = false + const dataKey = newObject.customData[key]; + let isBase64 = false; try { const decodedString = atob(dataKey); - isBase64 = decodedString.includes('qortalGroupEncryptedData') - } catch (e) { - console.log(e) - } - if(isBase64){ - newObject['customData'][key] = newObject.customData[key]; - } else { + isBase64 = decodedString.includes( + 'qortalGroupEncryptedData' + ); + } catch (e) { + console.log(e); + } + if (isBase64) { + newObject['customData'][key] = + newObject.customData[key]; + } else { const toBase64 = await objectToBase64( newObject.customData[key] ); @@ -564,14 +579,13 @@ class ProfileQdn extends connect(store)(LitElement) { publicKeys: [], }); newObject['customData'][key] = encryptedData; - } - + } } else { newObject['customData'][key] = newObject.customData[key]; } } const newObjectToBase64 = await objectToBase64(newObject); - + const worker = new WebWorker2(); try { const resPublish = await publishData({ @@ -593,8 +607,8 @@ class ProfileQdn extends connect(store)(LitElement) { this.resourceExists = true; this.profileData = data; store.dispatch(setProfileData(data)); - parentEpml.request('showSnackBar', get('profile.profile22')) - + parentEpml.request('showSnackBar', get('profile.profile22')); + worker.terminate(); } catch (error) { worker.terminate(); @@ -630,7 +644,7 @@ class ProfileQdn extends connect(store)(LitElement) { detail: detail, } ); - + iframeWindow.dispatchEvent(customEvent); }); } @@ -688,14 +702,12 @@ class ProfileQdn extends connect(store)(LitElement) { } } - _handleOpenVisiting(event){ + _handleOpenVisiting(event) { try { const name = event.detail; - this.getVisitingProfile(name) - this.dialogOpenedProfile = true - } catch (error) { - - } + this.getVisitingProfile(name); + this.dialogOpenedProfile = true; + } catch (error) {} } connectedCallback() { @@ -749,36 +761,68 @@ class ProfileQdn extends connect(store)(LitElement) { } openUserInfo() { - - const infoDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('user-info-view') - infoDialog.openUserInfo(this.nameVisiting) - + const infoDialog = document + .getElementById('main-app') + .shadowRoot.querySelector('app-view') + .shadowRoot.querySelector('user-info-view'); + infoDialog.openUserInfo(this.nameVisiting); } - openEdit(){ + openEdit() { this.isOpenProfileModalUpdate = !this.isOpenProfileModalUpdate; } - onCloseVisitingProfile(){ + onCloseVisitingProfile() { this.profileDataVisiting = null; - this.nameVisiting = "" + this.nameVisiting = ''; this.imageUrl = ''; - this.resourceExistsVisiting = undefined + this.resourceExistsVisiting = undefined; + this.isFriend = undefined; } - updated(changedProperties){ + updated(changedProperties) { if ( changedProperties && changedProperties.has('dialogOpenedProfile') && this.dialogOpenedProfile === false - ) { - - const prevVal = changedProperties.get('dialogOpenedProfile') - if(prevVal === true) this.onCloseVisitingProfile() + ) { + const prevVal = changedProperties.get('dialogOpenedProfile'); + if (prevVal === true) this.onCloseVisitingProfile(); } - + } + async getUserAddress() { + try { + const url = `${this.nodeUrl}/names/${this.nameVisiting}`; + const res = await fetch(url); + const result = await res.json(); + if (result.error === 401) { + return ''; + } else { + return result.owner; + } + } catch (error) { + return ''; + } + } + + checkIfInFriendsList(name) { + try { + this.isFriend = undefined; + const friendList = JSON.parse( + localStorage.getItem('friends-my-friend-list') || '[]' + ); + const findIndex = friendList.findIndex( + (friend) => friend.name === name + ); + if (findIndex !== -1) { + this.isFriend = true; + } else { + this.isFriend = false; + } + } catch (error) {} } render() { + return html` ${this.isSaving || (!this.error && this.resourceExists === undefined) @@ -897,15 +941,14 @@ class ProfileQdn extends connect(store)(LitElement) { ) { return; } - if(this.profileData){ - this.profileDataVisiting = this.profileData - this.nameVisiting = this.name - this.dialogOpenedProfile = true + if (this.profileData) { + this.profileDataVisiting = this.profileData; + this.nameVisiting = this.name; + this.dialogOpenedProfile = true; } else { this.isOpenProfileModalUpdate = - !this.isOpenProfileModalUpdate; + !this.isOpenProfileModalUpdate; } - }} > - - - ${this.dialogOpenedProfile ? html` - - -

${this.nameVisiting}

- - -
- ${this.isLoadingVisitingProfile ? html` -
- -
- ` : this.resourceExistsVisiting === false ? html` -
-

${translate('profile.profile16')}

-
- ` : this.profileDataVisiting === null ? html` -
-

${translate('profile.profile17')}

-
- ` : html` -

${translate('profile.profile4')}

-

${this.profileDataVisiting.tagline || translate('profile.profile15')}

-

${translate('profile.profile5')}

-

${this.profileDataVisiting.bio || translate('profile.profile15')}

-

${translate('profile.profile6')}

- ${Object.keys(this.profileDataVisiting.wallets).map((key, i)=> { - return html ` -

- ${key}: ${this.profileDataVisiting.wallets[key] || translate('profile.profile15')} -

- ` - })} - `} - -
- - -
- - this.openUserInfo()} - >${translate('profile.profile14')} - - - ${this.nameVisiting === this.name ? html` - this.openEdit()}>${translate("profile.profile3")} - ` : ''} - - { - this.dialogOpenedProfile = false - }} - >${translate('general.close')} - -
-
+ +

${this.nameVisiting}

+
+ ${this.nameVisiting !== this.name + ? html` +
+ send + + +
+ ` + : ''} + ${this.nameVisiting !== this.name + ? html` +
+ mail + + +
+ ` + : ''} + ${this.nameVisiting !== this.name && + this.isFriend === false + ? html` +
+ person_add + + +
+ ` + : ''} + ${this.nameVisiting !== this.name && + this.isFriend === true + ? html` +
+ person + + +
+ ` + : ''} +
+
+ ${this.isLoadingVisitingProfile + ? html` +
+ +
+ ` + : this.resourceExistsVisiting === false + ? html` +
+

+ ${translate( + 'profile.profile16' + )} +

+
+ ` + : this.profileDataVisiting === null + ? html` +
+

+ ${translate( + 'profile.profile17' + )} +

+
+ ` + : html` +

+ ${translate('profile.profile4')} +

+

+ ${this.profileDataVisiting + .tagline || + translate('profile.profile15')} +

+

+ ${translate('profile.profile5')} +

+

+ ${this.profileDataVisiting + .bio || + translate('profile.profile15')} +

+

+ ${translate('profile.profile6')} +

+ ${Object.keys( + this.profileDataVisiting.wallets + ).map((key, i) => { + return html` +

+ ${key}: + ${this + .profileDataVisiting + .wallets[key] || + translate( + 'profile.profile15' + )} +

+ `; + })} + `} +
- +
+ + this.openUserInfo()} + >${translate( + 'profile.profile14' + )} + + + ${this.nameVisiting === this.name + ? html` + + this.openEdit()} + >${translate( + 'profile.profile3' + )} + ` + : ''} - - - - - - + { + this.dialogOpenedProfile = false; + }} + >${translate( + 'general.close' + )} + +
+ + ` + : ''} `; } }