final fixes

This commit is contained in:
PhilReact 2023-10-11 23:14:10 -05:00
parent 435f6b1905
commit ba3b61f792
8 changed files with 152 additions and 96 deletions

View File

@ -1193,6 +1193,7 @@
"friend13": "Feed", "friend13": "Feed",
"friend14": "Remove friend", "friend14": "Remove friend",
"friend15": "Feed settings", "friend15": "Feed settings",
"friend16": "Select the Q-Apps you want updates from, especially those related to your friends." "friend16": "Select the Q-Apps you want updates from, especially those related to your friends.",
"friends17": "Friends"
} }
} }

View File

@ -560,7 +560,7 @@ class AppView extends connect(store)(LitElement) {
</span> </span>
</div> </div>
<div style="display:flex;align-items:center;gap:20px"> <div style="display:flex;align-items:center;gap:20px">
<save-settings-qdn></save-settings-qdn> <!-- <save-settings-qdn></save-settings-qdn> -->
<friends-side-panel-parent></friends-side-panel-parent> <friends-side-panel-parent></friends-side-panel-parent>
<notification-bell></notification-bell> <notification-bell></notification-bell>
<notification-bell-general></notification-bell-general> <notification-bell-general></notification-bell-general>

View File

@ -12,6 +12,7 @@ import '@material/mwc-dialog';
import '@material/mwc-checkbox'; import '@material/mwc-checkbox';
import { connect } from 'pwa-helpers'; import { connect } from 'pwa-helpers';
import { store } from '../../store'; import { store } from '../../store';
import '@polymer/paper-spinner/paper-spinner-lite.js'
class AddFriendsModal extends connect(store)(LitElement) { class AddFriendsModal extends connect(store)(LitElement) {
static get properties() { static get properties() {
@ -27,7 +28,8 @@ class AddFriendsModal extends connect(store)(LitElement) {
editContent: { type: Object }, editContent: { type: Object },
onClose: { attribute: false }, onClose: { attribute: false },
mySelectedFeeds: { type: Array }, mySelectedFeeds: { type: Array },
availableFeeedSchemas: {type: Array} availableFeeedSchemas: {type: Array},
isLoadingSchemas: {type: Boolean}
}; };
} }
@ -41,7 +43,8 @@ class AddFriendsModal extends connect(store)(LitElement) {
this.nodeUrl = this.getNodeUrl(); this.nodeUrl = this.getNodeUrl();
this.myNode = this.getMyNode(); this.myNode = this.getMyNode();
this.mySelectedFeeds = []; this.mySelectedFeeds = [];
this.availableFeeedSchemas = [] this.availableFeeedSchemas = [];
this.isLoadingSchemas= false;
} }
static get styles() { static get styles() {
@ -53,6 +56,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
--mdc-dialog-content-ink-color: var(--black); --mdc-dialog-content-ink-color: var(--black);
--mdc-dialog-min-width: 400px; --mdc-dialog-min-width: 400px;
--mdc-dialog-max-width: 1024px; --mdc-dialog-max-width: 1024px;
box-sizing:border-box;
} }
.input { .input {
width: 90%; width: 90%;
@ -145,9 +149,11 @@ class AddFriendsModal extends connect(store)(LitElement) {
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px; box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px;
z-index: 1001; z-index: 1001;
border-radius: 5px; border-radius: 5px;
max-height: 80vh; display: flex;
overflow: auto; flex-direction:column;
} }
.modal-overlay.hidden { .modal-overlay.hidden {
display: none; display: none;
} }
@ -155,7 +161,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
width: 36px; width: 36px;
height: 36px; height: 36px;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.app-name { .app-name {
@ -168,6 +174,30 @@ class AddFriendsModal extends connect(store)(LitElement) {
border-radius: 5px; border-radius: 5px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.inner-content {
display: flex;
flex-direction: column;
max-height: 75vh;
flex-grow: 1;
overflow: auto;
}
.inner-content::-webkit-scrollbar-track {
background-color: whitesmoke;
border-radius: 7px;
}
.inner-content::-webkit-scrollbar {
width: 12px;
border-radius: 7px;
background-color: whitesmoke;
}
.inner-content::-webkit-scrollbar-thumb {
background-color: rgb(180, 176, 176);
border-radius: 7px;
transition: all 0.3s ease-in-out;
}
`; `;
} }
@ -250,10 +280,10 @@ class AddFriendsModal extends connect(store)(LitElement) {
async getAvailableFeedSchemas() { async getAvailableFeedSchemas() {
try { try {
this.isLoadingSchemas= true
const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=ui_schema_feed&prefix=true`; const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=ui_schema_feed&prefix=true`;
const res = await fetch(url); const res = await fetch(url);
const data = await res.json(); const data = await res.json();
if (data.error === 401) { if (data.error === 401) {
this.availableFeeedSchemas = []; this.availableFeeedSchemas = [];
} else { } else {
@ -264,13 +294,17 @@ class AddFriendsModal extends connect(store)(LitElement) {
this.availableFeeedSchemas = result; this.availableFeeedSchemas = result;
} }
this.userFoundModalOpen = true; this.userFoundModalOpen = true;
} catch (error) {} } catch (error) {} finally {
this.isLoadingSchemas= false
}
} }
render() { render() {
return html` return html`
<div class="modal-overlay ${this.isOpen ? '' : 'hidden'}"> <div class="modal-overlay ${this.isOpen ? '' : 'hidden'}">
<div class="modal-content"> <div class="modal-content">
<div class="inner-content">
<div style="text-align:center"> <div style="text-align:center">
<h1> <h1>
${this.editContent ${this.editContent
@ -297,7 +331,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
?checked=${this.willFollow} ?checked=${this.willFollow}
></mwc-checkbox> ></mwc-checkbox>
</div> </div>
<div style="height: 15px"></div> <div style="height:15px"></div>
<div style="display: flex;flex-direction: column;"> <div style="display: flex;flex-direction: column;">
<label <label
for="name" for="name"
@ -315,7 +349,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
: ''} : ''}
/> />
</div> </div>
<div style="height: 15px"></div> <div style="height:15px"></div>
<div style="display: flex;flex-direction: column;"> <div style="display: flex;flex-direction: column;">
<label <label
for="alias" for="alias"
@ -332,7 +366,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
@change=${(e) => (this.alias = e.target.value)} @change=${(e) => (this.alias = e.target.value)}
/> />
</div> </div>
<div style="height: 15px"></div> <div style="height:15px"></div>
<div style="margin-bottom:0;"> <div style="margin-bottom:0;">
<textarea <textarea
class="input" class="input"
@ -344,12 +378,17 @@ class AddFriendsModal extends connect(store)(LitElement) {
rows="3" rows="3"
></textarea> ></textarea>
</div> </div>
<div style="height: 15px"></div> <div style="height:15px"></div>
<h2>${translate('friends.friend15')}</h2> <h2>${translate('friends.friend15')}</h2>
<div style="margin-bottom:0;"> <div style="margin-bottom:0;">
<p>${translate('friends.friend16')}</p> <p>${translate('friends.friend16')}</p>
</div> </div>
<div> <div>
${this.isLoadingSchemas ? html`
<div style="width:100%;display: flex; justify-content:center">
<paper-spinner-lite active></paper-spinner-lite>
</div>
` : ''}
${this.availableFeeedSchemas.map((schema) => { ${this.availableFeeedSchemas.map((schema) => {
const isAlreadySelected = this.mySelectedFeeds.find( const isAlreadySelected = this.mySelectedFeeds.find(
(item) => item.name === schema.name (item) => item.name === schema.name
@ -401,6 +440,7 @@ class AddFriendsModal extends connect(store)(LitElement) {
`; `;
})} })}
</div> </div>
</div>
<div <div
style="display:flex;justify-content:space-between;align-items:center;margin-top:20px" style="display:flex;justify-content:space-between;align-items:center;margin-top:20px"
> >

View File

@ -84,11 +84,24 @@ export class FeedItem extends connect(store)(LitElement) {
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
cursor: pointer; cursor: pointer;
font-size: 16px;
} }
.avatar { .avatar {
width: 42px; width: 36px;
height: 42px; height: 36px;
border-radius:50%;
overflow: hidden;
display:flex;
align-items:center;
} }
.avatarApp {
width: 30px;
height: 30px;
border-radius:50%;
overflow: hidden;
display:flex;
align-items:center;
}
.feed-item-name { .feed-item-name {
user-select: none; user-select: none;
color: #03a9f4; color: #03a9f4;
@ -433,14 +446,14 @@ getMyNode(){
const avatarUrl = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.resource.name}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`; const avatarUrl = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.resource.name}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`;
avatarImg = html`<img avatarImg = html`<img
src="${avatarUrl}" src="${avatarUrl}"
style="max-width:100%; max-height:100%;" style="width:100%; height:100%;"
onerror="this.onerror=null; this.src='/img/incognito.png';" onerror="this.onerror=null; this.src='/img/incognito.png';"
/>`; />`;
let avatarImgApp let avatarImgApp
const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.appName}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`; const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.appName}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`;
avatarImgApp = html`<img avatarImgApp = html`<img
src="${avatarUrl2}" src="${avatarUrl2}"
style="max-width:100%; max-height:100%;" style="width:100%; height:100%;"
onerror="this.onerror=null; this.src='/img/incognito.png';" onerror="this.onerror=null; this.src='/img/incognito.png';"
/>`; />`;
return html` return html`
@ -473,7 +486,7 @@ getMyNode(){
} }
${this.status.status === 'READY' && this.feedItem ? html` ${this.status.status === 'READY' && this.feedItem ? html`
<div class="parent-feed-item" style="position:relative" @click=${this.goToFeedLink}> <div class="parent-feed-item" style="position:relative" @click=${this.goToFeedLink}>
<div style="display:flex;gap:10px;margin-bottom:20px"> <div style="display:flex;gap:10px;margin-bottom:5px">
<div class="avatar"> <div class="avatar">
${avatarImg}</div> <span class="feed-item-name">${this.resource.name}</span> ${avatarImg}</div> <span class="feed-item-name">${this.resource.name}</span>
</div> </div>
@ -481,7 +494,7 @@ getMyNode(){
<p>${this.feedItem.title}</p> <p>${this.feedItem.title}</p>
</div> </div>
<div class="app-name"> <div class="app-name">
<div class="avatar"> <div class="avatarApp">
${avatarImgApp} ${avatarImgApp}
</div> </div>
<message-time <message-time

View File

@ -32,6 +32,8 @@ class FriendsFeed extends connect(store)(LitElement) {
this.hasInitialFetch = false this.hasInitialFetch = false
this.observerHandler = this.observerHandler.bind(this); this.observerHandler = this.observerHandler.bind(this);
this.elementObserver = this.elementObserver.bind(this) this.elementObserver = this.elementObserver.bind(this)
this.mySelectedFeeds = []
this.getSchemas = this.getSchemas.bind(this)
} }
@ -60,10 +62,9 @@ class FriendsFeed extends connect(store)(LitElement) {
return myNode; return myNode;
} }
async getSchemas(schemas){ async getSchemas(){
this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]")
const schemas = this.mySelectedFeeds
const getAllSchemas = (schemas || []).map( const getAllSchemas = (schemas || []).map(
async (schema) => { async (schema) => {
try { try {
@ -99,42 +100,49 @@ class FriendsFeed extends connect(store)(LitElement) {
} }
async getEndpoints(){
const dynamicVars = {
}
const schemas = await this.getSchemas()
const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
console.log({friendList})
const names = friendList.map(friend => `name=${friend.name}`).join('&');
if(names.length === 0){
this.endpoints= []
this.endpointOffsets = Array(this.endpoints.length).fill(0);
return
}
console.log({names})
const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&exactmatchnames=true&${names}`
let formEndpoints = []
schemas.forEach((schema)=> {
const feedData = schema.feed[0]
if(feedData){
const copyFeedData = {...feedData}
const fullUrl = constructUrl(baseurl, copyFeedData.search, dynamicVars);
if(fullUrl){
formEndpoints.push({
url: fullUrl, schemaName: schema.name, schema: copyFeedData
})
}
}
})
this.endpoints= formEndpoints
this.endpointOffsets = Array(this.endpoints.length).fill(0);
}
async firstUpdated(){ async firstUpdated(){
this.viewElement = this.shadowRoot.getElementById('viewElement'); this.viewElement = this.shadowRoot.getElementById('viewElement');
this.downObserverElement = this.downObserverElement =
this.shadowRoot.getElementById('downObserver'); this.shadowRoot.getElementById('downObserver');
this.elementObserver(); this.elementObserver();
let schemaObj = {...schema}
const dynamicVars = {
}
const getEndpoints = async () => {
const schemas = await this.getSchemas(schemaList)
const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
console.log({friendList})
const names = friendList.map(friend => `name=${friend.name}`).join('&');
console.log({names})
const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&exactmatchnames=true&${names}`
let formEndpoints = []
schemas.forEach((schema)=> {
const feedData = schema.feed[0]
if(feedData){
const copyFeedData = {...feedData}
const fullUrl = constructUrl(baseurl, copyFeedData.search, dynamicVars);
if(fullUrl){
formEndpoints.push({
url: fullUrl, schemaName: schema.name, schema: copyFeedData
})
}
}
})
this.endpoints= formEndpoints
this.endpointOffsets = Array(this.endpoints.length).fill(0);
}
try { try {
await getEndpoints() await this.getEndpoints()
this.loadAndMergeData(); this.loadAndMergeData();
this.getFeedOnInterval() this.getFeedOnInterval()
@ -151,6 +159,15 @@ this.getFeedOnInterval()
this.requestUpdate() this.requestUpdate()
} }
async refresh(){
try {
await this.getEndpoints()
this.reFetchFeedData()
} catch (error) {
}
}
elementObserver() { elementObserver() {
const options = { const options = {
@ -293,7 +310,7 @@ this.getFeedOnInterval()
async reFetchFeedData() { async reFetchFeedData() {
// Resetting offsets to start fresh. // Resetting offsets to start fresh.
this.endpointOffsets = Array(this.endpoints.length).fill(0); this.endpointOffsets = Array(this.endpoints.length).fill(0);
await this.getEndpoints()
const oldIdentifiers = new Set(this.feed.map(item => item.identifier)); const oldIdentifiers = new Set(this.feed.map(item => item.identifier));
const newData = await this.initialLoad(); const newData = await this.initialLoad();
@ -502,42 +519,4 @@ export function replacePlaceholders(template, resource, customParams) {
export const schemaList = [{
identifier: 'ui_schema_feed',
name: 'Q-Blog',
service: 'DOCUMENT'
}]
export const schema = {
name: "Q-Blog",
defaultFeedIndex: 0,
feed: [
{
id:"post-creation",
version: 1,
updated: 1696646223261,
title: "Q-Blog Post creations",
description: "blablabla",
search: {
query: "-post-",
identifier: "q-blog-",
service: "BLOG_POST",
exactmatchnames: true
},
click: "qortal://APP/Q-Blog/$${resource.name}$$/$${customParams.blogId}$$/$${customParams.shortIdentifier}$$",
display: {
title: "$${rawdata.title}$$"
},
customParams: {
blogId: "**methods.getBlogId(resource)**",
shortIdentifier: "**methods.getShortId(resource)**"
},
"methods": {
"getShortId": "return resource.identifier.split('-post-')[1];",
"getBlogId": "const arr = resource.identifier.split('-post-'); const id = arr[0]; return id.startsWith('q-blog-') ? id.substring(7) : id;"
}
}
]
}
export const listSchemas = [schema]

View File

@ -1,6 +1,10 @@
import { LitElement, html, css } from 'lit'; import { LitElement, html, css } from 'lit';
import '@material/mwc-icon'; import '@material/mwc-icon';
import './friends-side-panel.js'; import './friends-side-panel.js';
import '@vaadin/tooltip';
import { get } from 'lit-translate';
class FriendsSidePanelParent extends LitElement { class FriendsSidePanelParent extends LitElement {
static get properties() { static get properties() {
return { return {
@ -49,7 +53,7 @@ class FriendsSidePanelParent extends LitElement {
} }
render() { render() {
return html` return html`
<mwc-icon @click=${()=> { <mwc-icon id="friends-icon" @click=${()=> {
this.isOpen = !this.isOpen this.isOpen = !this.isOpen
if(this.isOpen && this.hasNewFeed){ if(this.isOpen && this.hasNewFeed){
localStorage.setItem('lastSeenFeed', Date.now()); localStorage.setItem('lastSeenFeed', Date.now());
@ -59,6 +63,13 @@ class FriendsSidePanelParent extends LitElement {
}} style="color: ${this.hasNewFeed ? 'green' : 'var(--black)'}; cursor:pointer;user-select:none" }} style="color: ${this.hasNewFeed ? 'green' : 'var(--black)'}; cursor:pointer;user-select:none"
>group</mwc-icon >group</mwc-icon
> >
<vaadin-tooltip
for="friends-icon"
position="bottom"
hover-delay=${200}
hide-delay=${1}
text=${get('friends.friends17')}>
</vaadin-tooltip>
<friends-side-panel .setHasNewFeed=${(val)=> this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val)=> this.isOpen = val}></friends-side-panel> <friends-side-panel .setHasNewFeed=${(val)=> this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val)=> this.isOpen = val}></friends-side-panel>
`; `;

View File

@ -99,6 +99,13 @@ class FriendsSidePanel extends LitElement {
`; `;
refreshFeed(){
this.shadowRoot.querySelector('friends-feed').refresh()
}
render() { render() {
return html` return html`
<div class="parent"> <div class="parent">
@ -109,7 +116,7 @@ class FriendsSidePanel extends LitElement {
</div> </div>
<div style="display:flex;gap:15px;align-items:center"> <div style="display:flex;gap:15px;align-items:center">
<mwc-icon @click=${()=> { <mwc-icon @click=${()=> {
this.shadowRoot.querySelector('friends-feed').reFetchFeedData() this.refreshFeed()
}} style="color: var(--black); cursor:pointer;">refresh</mwc-icon> }} style="color: var(--black); cursor:pointer;">refresh</mwc-icon>
<mwc-icon style="cursor:pointer" @click=${()=> { <mwc-icon style="cursor:pointer" @click=${()=> {
this.setIsOpen(false) this.setIsOpen(false)
@ -119,7 +126,7 @@ class FriendsSidePanel extends LitElement {
</div> </div>
<div class="content"> <div class="content">
<div class="${this.selected === 'friends' ? 'active-content' : 'default-content'}"> <div class="${this.selected === 'friends' ? 'active-content' : 'default-content'}">
<friends-view></friends-view> <friends-view .refreshFeed=${()=>this.refreshFeed()}></friends-view>
</div> </div>
<div class="${this.selected === 'feed' ? 'active-content' : 'default-content'}"> <div class="${this.selected === 'feed' ? 'active-content' : 'default-content'}">
<friends-feed .setHasNewFeed=${(val)=> this.setHasNewFeed(val)}></friends-feed> <friends-feed .setHasNewFeed=${(val)=> this.setHasNewFeed(val)}></friends-feed>

View File

@ -41,7 +41,8 @@ class FriendsView extends connect(store)(LitElement) {
userFound: { type: Array}, userFound: { type: Array},
isOpenAddFriendsModal: {type: Boolean}, isOpenAddFriendsModal: {type: Boolean},
editContent: {type: Object}, editContent: {type: Object},
mySelectedFeeds: {type: Array} mySelectedFeeds: {type: Array},
refreshFeed: {attribute: false}
}; };
} }
static get styles() { static get styles() {
@ -222,10 +223,14 @@ class FriendsView extends connect(store)(LitElement) {
} }
this.setMySelectedFeeds(val.mySelectedFeeds) this.setMySelectedFeeds(val.mySelectedFeeds)
this.userSelected = {}; this.userSelected = {};
this.shadowRoot.getElementById('sendTo').value = ''
this.isLoading = false; this.isLoading = false;
this.isOpenAddFriendsModal = false this.isOpenAddFriendsModal = false
this.editContent = null this.editContent = null
this.setMyFriends(this.friendList) this.setMyFriends(this.friendList)
if(!isRemove && this.friendList.length === 1){
this.refreshFeed()
}
} }
setMyFriends(friendList){ setMyFriends(friendList){
localStorage.setItem('friends-my-friend-list', JSON.stringify(friendList)); localStorage.setItem('friends-my-friend-list', JSON.stringify(friendList));