/** * Prints VRE d4s-social-posts (from @from to @quantity number) */ window.customElements.define('d4s-social-posts', class extends HTMLElement { #basepath = 'https://api.d4science.org' #from = 1 #quantity = 10 #nextIdx = null #busy = false #boot = null #shadowRoot = null #unorderedlist = null //#restRecentPosts = '/rest/2/posts/get-posts-vre' // old get, gets all posts unfiltered #restRecentPosts = '/rest/2/posts/get-recent-posts-vre-by-range' #restComments = '/rest/2/comments/get-comments-by-post-id' #style = `` constructor() { super() this.#boot = document.querySelector("d4s-boot-2") this.#shadowRoot = this.attachShadow({mode: 'open'}) var template = document.createElement('template') template.innerHTML = this.#style this.#shadowRoot.appendChild(template.content.cloneNode(true)) var ul = document.createElement('ul') ul.classList.add('d4s-social-posts') this.#unorderedlist = ul this.#shadowRoot.appendChild(ul) } connectedCallback() { if (this.#boot) { this.#nextIdx = this.#from this.loadPosts() } else { console.error(' webcomponent not found in this page') } } loadPosts(nr) { if (this.#busy) { return } else { this.#busy = true const url = new URL(this.#basepath + this.#restRecentPosts) if (this.#nextIdx <= 0) { this.#busy = false throw 'Out of range index found' } var quparam = nr ? Number(nr) : this.#quantity var params = {from: this.#nextIdx, quantity: quparam } url.search = new URLSearchParams(params).toString() console.log("url=" + url.href) this.#boot.secureFetch(url).then(reply => { if(reply.status !== 200) throw "status=" + reply.status return reply.json() }).then(data => { //console.log(data) //this.#nextIdx = Number(data.result.last_returned_post_timeline_index) this.#nextIdx = Number(data.result.last_returned_post_timeline_index) - 1 //this.#nextIdx = this.#from + this.#quantity this.renderPosts(data.result.posts) //this.rawRenderResponse(data) }).catch(err => { const msg = 'Unable to load posts. ' console.error(msg + err) throw msg }).finally(() => { this.#busy = false }) } } morePosts(nr) { this.loadPosts(nr) } renderPosts(posts) { const ul = this.#unorderedlist posts.forEach(post => { //console.log(post) var li = document.createElement('li') li.id = post.key li.classList.add('d4s-social-post') const thumbnail = (!post.thumbnail_url.startsWith('http')) ? 'https://' + this.#boot.clientId + post.thumbnail_url : post.thumbnail_url const datetime = new Date(0) datetime.setUTCMilliseconds(post.time) const datetimestr = datetime.toLocaleString([], {year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit'}) li.innerHTML = `
${post.description}
` if (post.comments_no != "0") { var commsnr = document.createElement('div') commsnr.classList.add('comments-nr') commsnr.innerHTML += ` ${post.comments_no} ` li.querySelector('.d4s-post-footer').appendChild(commsnr) } if (post.likes_no != "0") { var likesnr = document.createElement('div') likesnr.classList.add('likes-nr') likesnr.innerHTML += ` ${post.likes_no} ` li.querySelector('.d4s-post-footer').appendChild(likesnr) } if (post.link_title !== "") { var attimg = document.createElement('div') attimg.classList.add('attachment-div') if (post.uri_thumbnail != "null") { attimg.innerHTML += `` li.querySelector('.d4s-post-attachment').appendChild(attimg) } var attdesc = document.createElement('div') attdesc.classList.add('attachment-info') attdesc.innerHTML += `
${post.link_title}
${post.uri}
${post.link_description}
` li.querySelector('.d4s-post-attachment').appendChild(attdesc) } else { li.querySelector('.d4s-post-attachment').remove() } ul.appendChild(li) let aimg = li.querySelector(".attachment-img") if (aimg) { aimg.addEventListener('load', (ev) => { let prop = aimg.naturalWidth / aimg.naturalHeight if (prop < 0.5 || prop > 2) { aimg.style.objectFit = 'contain' } }) } if (post.comments_no > 0) { this.fetchComments(post.key) } }) } rawRenderResponse(data) { var pre = document.createElement('pre') pre.innerText = JSON.stringify(data, null, " ") this.#shadowRoot.appendChild(pre) } fetchComments(postid) { const url = new URL(this.#basepath + this.#restComments) var params = {key: postid} url.search = new URLSearchParams(params).toString() this.#boot.secureFetch(url).then(reply => { if(reply.status !== 200) throw "status=" + reply.status return reply.json() }).then(data => { this.renderComments(postid, data) }).catch(err => console.error(`Unable to fetch comments for post ${postid}. ` + err)) } renderComments(postid, comments) { var li = this.#shadowRoot.getElementById(postid) var cul = document.createElement('ul') cul.classList.add('d4s-post-comments') comments.result.forEach(comment => { var cli = document.createElement('li') cli.id = comment.feedid cli.classList.add('d4s-post-comment') const thumbnail = (!comment.thumbnail_url.startsWith('http')) ? 'https://' + this.#boot.clientId + comment.thumbnail_url : comment.thumbnail_url const datetime = new Date(0) datetime.setUTCMilliseconds(comment.time) const datetimestr = datetime.toLocaleString([], {year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit'}) cli.innerHTML = `
${comment.full_name}
${comment.text}
` cul.appendChild(cli) }) li.appendChild(cul) } static get observedAttributes() { return ["url", "from", "quantity"]; } attributeChangedCallback(name, oldValue, newValue) { if (oldValue !== newValue) { switch (name) { case "url": this.#basepath = newValue break case "from": this.#from = Number(newValue) break case "quantity": this.#quantity = Number(newValue) break } } } get url() { return this.#basepath } set url(url) { this.#basepath = url this.setAttribute("url", url) } get from() { return this.#from } set from(from) { this.#from = Number(from) this.setAttribute("from", from) } get quantity() { return this.#quantity } set quantity(quantity) { this.#quantity = Number(quantity) this.setAttribute("quantity", quantity) } });