forked from Qortal/qortal-ui
started friends feed
This commit is contained in:
parent
a20cd240ef
commit
8eacfca4d1
@ -1185,8 +1185,8 @@
|
|||||||
"friend5": "Follow name",
|
"friend5": "Follow name",
|
||||||
"friend6": "Alias",
|
"friend6": "Alias",
|
||||||
"friend7": "Add an alias to better remember your friend (Optional)",
|
"friend7": "Add an alias to better remember your friend (Optional)",
|
||||||
"friend8": "Send a Q-Chat message",
|
"friend8": "Send Q-Chat",
|
||||||
"friend9": "Send a Q-Mail",
|
"friend9": "Send Q-Mail",
|
||||||
"friend10": "Edit friend",
|
"friend10": "Edit friend",
|
||||||
"friend11": "Following"
|
"friend11": "Following"
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ class ChatSideNavHeads extends LitElement {
|
|||||||
${this.chatInfo.groupName
|
${this.chatInfo.groupName
|
||||||
? this.chatInfo.groupName
|
? this.chatInfo.groupName
|
||||||
: this.chatInfo.name !== undefined
|
: this.chatInfo.name !== undefined
|
||||||
? this.chatInfo.name
|
? (this.chatInfo.alias || this.chatInfo.name)
|
||||||
: this.chatInfo.address.substr(0, 15)}
|
: this.chatInfo.address.substr(0, 15)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
341
core/src/components/friends-view/feed-item.js
Normal file
341
core/src/components/friends-view/feed-item.js
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
import { LitElement, html, css } from 'lit';
|
||||||
|
import {
|
||||||
|
get,
|
||||||
|
translate,
|
||||||
|
} from 'lit-translate';
|
||||||
|
import axios from 'axios'
|
||||||
|
import '@material/mwc-menu';
|
||||||
|
import '@material/mwc-list/mwc-list-item.js'
|
||||||
|
import { RequestQueueWithPromise } from '../../../../plugins/plugins/utils/queue';
|
||||||
|
const requestQueue = new RequestQueueWithPromise(5);
|
||||||
|
|
||||||
|
export class FeedItem extends LitElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
resource: { type: Object },
|
||||||
|
isReady: { type: Boolean},
|
||||||
|
status: {type: Object},
|
||||||
|
feedItem: {type: Object}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
* {
|
||||||
|
--mdc-theme-text-primary-on-background: var(--black);
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width:45vh;
|
||||||
|
max-height:40vh;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.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: 30px;
|
||||||
|
position: relative;
|
||||||
|
text-indent: -9999em;
|
||||||
|
transform: translateZ(0px);
|
||||||
|
animation: 1.1s linear 0s infinite normal none running loadingAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
.defaultSize {
|
||||||
|
width: 45vh;
|
||||||
|
height: 40vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
mwc-menu {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@-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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.resource = {
|
||||||
|
identifier: "",
|
||||||
|
name: "",
|
||||||
|
service: ""
|
||||||
|
}
|
||||||
|
this.status = {
|
||||||
|
status: ''
|
||||||
|
}
|
||||||
|
this.url = ""
|
||||||
|
this.isReady = false
|
||||||
|
this.nodeUrl = this.getNodeUrl()
|
||||||
|
this.myNode = this.getMyNode()
|
||||||
|
this.hasCalledWhenDownloaded = false
|
||||||
|
this.isFetching = false
|
||||||
|
|
||||||
|
this.observer = new IntersectionObserver(entries => {
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.isIntersecting && this.status.status !== 'READY') {
|
||||||
|
this._fetchImage();
|
||||||
|
// Stop observing after the image has started loading
|
||||||
|
this.observer.unobserve(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.feedItem = null
|
||||||
|
}
|
||||||
|
getNodeUrl(){
|
||||||
|
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||||
|
|
||||||
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
|
return nodeUrl
|
||||||
|
}
|
||||||
|
getMyNode(){
|
||||||
|
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||||
|
|
||||||
|
return myNode
|
||||||
|
}
|
||||||
|
|
||||||
|
getApiKey() {
|
||||||
|
const myNode =
|
||||||
|
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
|
||||||
|
window.parent.reduxStore.getState().app.nodeConfig.node
|
||||||
|
];
|
||||||
|
let apiKey = myNode.apiKey;
|
||||||
|
return apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchResource() {
|
||||||
|
try {
|
||||||
|
if(this.isFetching) return
|
||||||
|
this.isFetching = true
|
||||||
|
await axios.get(`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
|
||||||
|
this.isFetching = false
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
this.isFetching = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchVideoUrl() {
|
||||||
|
|
||||||
|
this.fetchResource()
|
||||||
|
this.url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?async=true&apiKey=${this.myNode.apiKey}`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRawData(){
|
||||||
|
const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
||||||
|
const response2 = await fetch(url, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const responseData2 = await response2.json()
|
||||||
|
return responseData2
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDisplayWithPlaceholders(display, resource, rawdata) {
|
||||||
|
const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g;
|
||||||
|
|
||||||
|
for (const key in display) {
|
||||||
|
const value = display[key];
|
||||||
|
|
||||||
|
display[key] = value.replace(pattern, (match, p1) => {
|
||||||
|
if (p1.startsWith('rawdata.')) {
|
||||||
|
const dataKey = p1.split('.')[1];
|
||||||
|
if (rawdata[dataKey] === undefined) {
|
||||||
|
console.error("rawdata key not found:", dataKey);
|
||||||
|
}
|
||||||
|
return rawdata[dataKey] || match;
|
||||||
|
} else if (p1.startsWith('resource.')) {
|
||||||
|
const resourceKey = p1.split('.')[1];
|
||||||
|
if (resource[resourceKey] === undefined) {
|
||||||
|
console.error("resource key not found:", resourceKey);
|
||||||
|
}
|
||||||
|
return resource[resourceKey] || match;
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async fetchStatus(){
|
||||||
|
let isCalling = false
|
||||||
|
let percentLoaded = 0
|
||||||
|
let timer = 24
|
||||||
|
const response = await axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
|
||||||
|
if(response && response.data && response.data.status === 'READY'){
|
||||||
|
const rawData = await this.getRawData()
|
||||||
|
const object = {
|
||||||
|
title: "$${rawdata.title}$$",
|
||||||
|
}
|
||||||
|
this.updateDisplayWithPlaceholders(object, {},rawData)
|
||||||
|
this.feedItem = object
|
||||||
|
this.status = response.data
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const intervalId = setInterval(async () => {
|
||||||
|
if (isCalling) return
|
||||||
|
isCalling = true
|
||||||
|
|
||||||
|
const data = await requestQueue.enqueue(() => {
|
||||||
|
return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
|
||||||
|
});
|
||||||
|
const res = data.data
|
||||||
|
|
||||||
|
isCalling = false
|
||||||
|
if (res.localChunkCount) {
|
||||||
|
if (res.percentLoaded) {
|
||||||
|
if (
|
||||||
|
res.percentLoaded === percentLoaded &&
|
||||||
|
res.percentLoaded !== 100
|
||||||
|
) {
|
||||||
|
timer = timer - 5
|
||||||
|
} else {
|
||||||
|
timer = 24
|
||||||
|
}
|
||||||
|
if (timer < 0) {
|
||||||
|
timer = 24
|
||||||
|
isCalling = true
|
||||||
|
this.status = {
|
||||||
|
...res,
|
||||||
|
status: 'REFETCHING'
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
isCalling = false
|
||||||
|
this.fetchResource()
|
||||||
|
}, 25000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
percentLoaded = res.percentLoaded
|
||||||
|
}
|
||||||
|
|
||||||
|
this.status = res
|
||||||
|
if(this.status.status === 'DOWNLOADED'){
|
||||||
|
this.fetchResource()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if progress is 100% and clear interval if true
|
||||||
|
if (res.status === 'READY') {
|
||||||
|
|
||||||
|
this.feedItem = await this.getRawData()
|
||||||
|
clearInterval(intervalId)
|
||||||
|
this.status = res
|
||||||
|
this.isReady = true
|
||||||
|
}
|
||||||
|
}, 5000) // 1 second interval
|
||||||
|
}
|
||||||
|
|
||||||
|
async _fetchImage() {
|
||||||
|
try {
|
||||||
|
this.fetchVideoUrl({
|
||||||
|
name: this.resource.name,
|
||||||
|
service: this.resource.service,
|
||||||
|
identifier: this.resource.identifier
|
||||||
|
})
|
||||||
|
this.fetchStatus()
|
||||||
|
} catch (error) { /* empty */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated(){
|
||||||
|
this.observer.observe(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
console.log('this.feedItem', this.feedItem)
|
||||||
|
return html`
|
||||||
|
<div
|
||||||
|
class=${[
|
||||||
|
`image-container`,
|
||||||
|
this.status.status !== 'READY'
|
||||||
|
? 'defaultSize'
|
||||||
|
: '',
|
||||||
|
this.status.status !== 'READY'
|
||||||
|
? 'hideImg'
|
||||||
|
: '',
|
||||||
|
].join(' ')}
|
||||||
|
>
|
||||||
|
${
|
||||||
|
this.status.status !== 'READY'
|
||||||
|
? html`
|
||||||
|
<div
|
||||||
|
style="display:flex;flex-direction:column;width:100%;height:100%;justify-content:center;align-items:center;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=${`smallLoading`}
|
||||||
|
></div>
|
||||||
|
<p style="color: var(--black)">${`${Math.round(this.status.percentLoaded || 0
|
||||||
|
).toFixed(0)}% `}${translate('chatpage.cchange94')}</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
${this.status.status === 'READY' && this.feedItem ? html`
|
||||||
|
<div style="position:relative">
|
||||||
|
ready
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('feed-item', FeedItem);
|
@ -38,6 +38,9 @@ export class FriendItemActions extends connect(store)(LitElement) {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--mdc-theme-primary);
|
color: var(--mdc-theme-primary);
|
||||||
transition: all 0.3s ease-in-out;
|
transition: all 0.3s ease-in-out;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px
|
||||||
}
|
}
|
||||||
|
|
||||||
.send-message-button:hover {
|
.send-message-button:hover {
|
||||||
@ -148,6 +151,9 @@ export class FriendItemActions extends connect(store)(LitElement) {
|
|||||||
this.openEditFriend();
|
this.openEditFriend();
|
||||||
this.closePopover();
|
this.closePopover();
|
||||||
}}"
|
}}"
|
||||||
|
>
|
||||||
|
<mwc-icon style="color: var(--black)"
|
||||||
|
>edit</mwc-icon
|
||||||
>
|
>
|
||||||
${translate('friends.friend10')}
|
${translate('friends.friend10')}
|
||||||
</div>
|
</div>
|
||||||
@ -186,6 +192,9 @@ export class FriendItemActions extends connect(store)(LitElement) {
|
|||||||
);
|
);
|
||||||
this.closePopover();
|
this.closePopover();
|
||||||
}}"
|
}}"
|
||||||
|
>
|
||||||
|
<mwc-icon style="color: var(--black)"
|
||||||
|
>send</mwc-icon
|
||||||
>
|
>
|
||||||
${translate('friends.friend8')}
|
${translate('friends.friend8')}
|
||||||
</div>
|
</div>
|
||||||
@ -212,6 +221,9 @@ export class FriendItemActions extends connect(store)(LitElement) {
|
|||||||
);
|
);
|
||||||
this.closePopover();
|
this.closePopover();
|
||||||
}}"
|
}}"
|
||||||
|
>
|
||||||
|
<mwc-icon style="color: var(--black)"
|
||||||
|
>mail</mwc-icon
|
||||||
>
|
>
|
||||||
${translate('friends.friend9')}
|
${translate('friends.friend9')}
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,6 +4,10 @@ import './friends-view'
|
|||||||
import { friendsViewStyles } from './friends-view-css';
|
import { friendsViewStyles } from './friends-view-css';
|
||||||
import { connect } from 'pwa-helpers';
|
import { connect } from 'pwa-helpers';
|
||||||
import { store } from '../../store';
|
import { store } from '../../store';
|
||||||
|
import './feed-item'
|
||||||
|
const perEndpointCount = 20;
|
||||||
|
const totalDesiredCount = 100;
|
||||||
|
const maxResultsInMemory = 300;
|
||||||
class FriendsFeed extends connect(store)(LitElement) {
|
class FriendsFeed extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
@ -15,6 +19,10 @@ class FriendsFeed extends connect(store)(LitElement) {
|
|||||||
this.feed = []
|
this.feed = []
|
||||||
this.nodeUrl = this.getNodeUrl();
|
this.nodeUrl = this.getNodeUrl();
|
||||||
this.myNode = this.getMyNode();
|
this.myNode = this.getMyNode();
|
||||||
|
this.endpoints = []
|
||||||
|
this.endpointOffsets = [] // Initialize offsets for each endpoint to 0
|
||||||
|
|
||||||
|
this.loadAndMergeData = this.loadAndMergeData.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
@ -51,7 +59,10 @@ class FriendsFeed extends connect(store)(LitElement) {
|
|||||||
|
|
||||||
const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true`
|
const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true`
|
||||||
const fullUrl = constructUrl(baseurl, feedData.search, dynamicVars);
|
const fullUrl = constructUrl(baseurl, feedData.search, dynamicVars);
|
||||||
console.log({fullUrl})
|
this.endpoints= ['http://127.0.0.1:12391/arbitrary/resources/search?reverse=true&query=-post-&identifier=q-blog-&service=BLOG_POST&exactmatchnames=true&limit=20']
|
||||||
|
this.endpointOffsets = Array(this.endpoints.length).fill(0); // Initialize offsets for each endpoint to 0
|
||||||
|
|
||||||
|
console.log('this.endpoints', this.endpoints)
|
||||||
const response = await fetch(fullUrl, {
|
const response = await fetch(fullUrl, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
@ -77,22 +88,109 @@ let clickValue1 = schemaObj.feed[0].click;
|
|||||||
const resolvedClickValue1 = replacePlaceholders(clickValue1, resource, schemaObj.feed[0].customParams);
|
const resolvedClickValue1 = replacePlaceholders(clickValue1, resource, schemaObj.feed[0].customParams);
|
||||||
|
|
||||||
console.log(resolvedClickValue1);
|
console.log(resolvedClickValue1);
|
||||||
|
this.loadAndMergeData();
|
||||||
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fetchDataFromEndpoint(endpointIndex, count) {
|
||||||
|
const offset = this.endpointOffsets[endpointIndex];
|
||||||
|
const url = `${this.endpoints[endpointIndex]}&limit=${count}&offset=${offset}`;
|
||||||
|
return fetch(url).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async initialLoad() {
|
||||||
|
let results = [];
|
||||||
|
let totalFetched = 0;
|
||||||
|
let i = 0;
|
||||||
|
let madeProgress = true;
|
||||||
|
let exhaustedEndpoints = new Set();
|
||||||
|
|
||||||
|
while (totalFetched < totalDesiredCount && madeProgress) {
|
||||||
|
madeProgress = false;
|
||||||
|
|
||||||
|
for (i = 0; i < this.endpoints.length; i++) {
|
||||||
|
if (exhaustedEndpoints.has(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const remainingCount = totalDesiredCount - totalFetched;
|
||||||
|
|
||||||
|
// If we've already reached the desired count, break
|
||||||
|
if (remainingCount <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fetchCount = Math.min(perEndpointCount, remainingCount);
|
||||||
|
let data = await this.fetchDataFromEndpoint(i, fetchCount);
|
||||||
|
|
||||||
|
// Increment the offset for this endpoint by the number of items fetched
|
||||||
|
this.endpointOffsets[i] += data.length;
|
||||||
|
|
||||||
|
if (data.length > 0) {
|
||||||
|
madeProgress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.length < fetchCount) {
|
||||||
|
exhaustedEndpoints.add(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
results = results.concat(data);
|
||||||
|
totalFetched += data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exhaustedEndpoints.size === this.endpoints.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim the results if somehow they are over the totalDesiredCount
|
||||||
|
return results.slice(0, totalDesiredCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
trimDataToLimit(data, limit) {
|
||||||
|
return data.slice(0, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeData(newData, existingData) {
|
||||||
|
const existingIds = new Set(existingData.map(item => item.identifier)); // Assume each item has a unique 'id'
|
||||||
|
const uniqueNewData = newData.filter(item => !existingIds.has(item.identifier));
|
||||||
|
return uniqueNewData.concat(existingData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async loadAndMergeData() {
|
||||||
|
let allData = this.feed
|
||||||
|
const newData = await this.initialLoad();
|
||||||
|
allData = this.mergeData(newData, allData);
|
||||||
|
allData.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first
|
||||||
|
allData = this.trimDataToLimit(allData, maxResultsInMemory); // Trim to the maximum allowed in memory
|
||||||
|
this.feed = [...allData]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
console.log('ron')
|
console.log('ron', this.feed)
|
||||||
return html`
|
return html`
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div id="viewElement" class="container-body" style=${"position: relative"}>
|
<div id="viewElement" class="container-body" style=${"position: relative"}>
|
||||||
hi
|
|
||||||
|
|
||||||
|
|
||||||
${this.feed.map((item) => {
|
${this.feed.map((item) => {
|
||||||
return html`<p>hello</p>`;
|
return html`<feed-item
|
||||||
|
.resource=${{
|
||||||
|
name: item.name,
|
||||||
|
service: item.service,
|
||||||
|
identifier: item.identifier,
|
||||||
|
}}
|
||||||
|
></feed-item>`;
|
||||||
})}
|
})}
|
||||||
<div id="downObserver"></div>
|
<div id="downObserver"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -198,6 +296,7 @@ export function replacePlaceholders(template, resource, customParams) {
|
|||||||
|
|
||||||
export const schema = {
|
export const schema = {
|
||||||
name: "Q-Blog",
|
name: "Q-Blog",
|
||||||
|
defaultFeedIndex: 0,
|
||||||
feed: [
|
feed: [
|
||||||
{
|
{
|
||||||
id:"post-creation",
|
id:"post-creation",
|
||||||
@ -213,7 +312,11 @@ export const schema = {
|
|||||||
exactmatchnames: true
|
exactmatchnames: true
|
||||||
},
|
},
|
||||||
click: "qortal://APP/Q-Blog/$${resource.name}$$/$${customParams.blogId}$$/$${customParams.shortIdentifier}$$",
|
click: "qortal://APP/Q-Blog/$${resource.name}$$/$${customParams.blogId}$$/$${customParams.shortIdentifier}$$",
|
||||||
display: "",
|
display: {
|
||||||
|
title: "$${rawdata.title}$$",
|
||||||
|
description: "$${rawdata.description}$$",
|
||||||
|
coverImage: "$${rawdata.image}$$"
|
||||||
|
},
|
||||||
customParams: {
|
customParams: {
|
||||||
blogId: "**methods.getBlogId(resource)**",
|
blogId: "**methods.getBlogId(resource)**",
|
||||||
shortIdentifier: "**methods.getShortId(resource)**"
|
shortIdentifier: "**methods.getShortId(resource)**"
|
||||||
|
@ -246,7 +246,7 @@ class FriendsView extends connect(store)(LitElement) {
|
|||||||
<vaadin-icon
|
<vaadin-icon
|
||||||
@click=${this.userSearch}
|
@click=${this.userSearch}
|
||||||
slot="icon"
|
slot="icon"
|
||||||
icon="vaadin:open-book"
|
icon="vaadin:search"
|
||||||
class="search-icon">
|
class="search-icon">
|
||||||
</vaadin-icon>
|
</vaadin-icon>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user