New version of social webcomponent

This commit is contained in:
Vincenzo Cestone 2022-12-14 10:59:14 +01:00
parent 1dcba773d7
commit b096cf5f59
1 changed files with 240 additions and 50 deletions

View File

@ -4,63 +4,212 @@
window.customElements.define('d4s-social-posts', class extends HTMLElement { window.customElements.define('d4s-social-posts', class extends HTMLElement {
#basepath = 'https://api.d4science.org/rest' #basepath = 'https://api.d4science.org/rest'
//#basepath = 'https://api.dev.d4science.org/rest'
#from = 1 #from = 1
#quantity = 10 #quantity = 10
#boot = null #nextIdx = null
#data = null #busy = false
#shadowRoot = null
//const url = this.#basepath + '/2/posts/get-posts-vre' // old get, gets all posts unfiltered #boot = null
#shadowRoot = null
#unorderedlist = null
//#restRecentPosts = '/2/posts/get-posts-vre' // old get, gets all posts unfiltered
#restRecentPosts = '/2/posts/get-recent-posts-vre-by-range' #restRecentPosts = '/2/posts/get-recent-posts-vre-by-range'
#restComments = '/2/comments/get-comments-by-post-id' #restComments = '/2/comments/get-comments-by-post-id'
#style = `<style>
.d4s-social-posts {
list-style: none;
padding-left: 0;
}
.d4s-social-post {
margin: 5px 0 5px 0;
padding: 5px 0 5px 0;
border-bottom: 1px solid lightgray;
}
.d4s-social-post:last-child {
border-bottom: none;
}
.d4s-post-heading {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 5px;
}
.d4s-post-avatar img {
object-fit: cover;
width: 40px;
height: 40px;
border-radius: 50%;
}
.d4s-post-meta {
display: flex;
flex-flow: column;
}
.d4s-post-meta .fullname {
font-weight: bold;
}
.d4s-post-meta .time {
font-size: small;
}
.d4s-post-body {
color: var(--color);
}
.d4s-post-footer {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.d4s-post-comments {
list-style: none;
}
.d4s-post-comment {
display: flex;
flex-wrap: wrap;
gap: 5px;
}
.d4s-comment-avatar img {
object-fit: cover;
width: 40px;
height: 40px;
border-radius: 50%;
}
.d4s-comment {
font-size: small;
margin: 0 5px;
}
.d4s-comment-body {
padding: 6px;
background-color: #f0f0f0;
border-radius: 9px;
}
.d4s-comment-body .fullname {
font-weight: bold;
}
.d4s-comment-footer {
margin: 3px 5px 6px 5px;
}
.d4s-post-footer {
margin: 8px 0 6px 0;
}
.comments-nr {
display: flex;
gap: 5px;
}
.likes-nr {
display: flex;
gap: 5px;
}
.d4s-post-attachment {
word-break: break-word;
font-size: small;
margin-top: 8px;
display: flex;
border: 1px solid lightgray;
border-radius: 2px;
}
.d4s-post-attachment .attachment-div {
display: contents;
}
.d4s-post-attachment .attachment-img {
object-fit: cover;
width: 120px;
height: 100px;
}
.d4s-post-attachment .attachment-info {
display: flex;
flex-flow: column;
gap: 8px;
padding: 8px;
background-color: #f0f0f0;
flex: 1;
}
.d4s-post-attachment .attachment-info .title {
word-break: break-word;
}
</style>`
constructor() { constructor() {
super() super()
this.#boot = document.querySelector("d4s-boot-2") this.#boot = document.querySelector("d4s-boot-2")
this.#shadowRoot = this.attachShadow({mode: 'open'}) 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() { connectedCallback() {
if (this.#boot) { if (this.#boot) {
this.fetchPosts() this.#nextIdx = this.#from
this.loadPosts()
} else { } else {
console.error('<d4s-boot-2> webcomponent not found in this page') console.error('<d4s-boot-2> webcomponent not found in this page')
} }
} }
fetchPosts() { loadPosts(nr) {
const url = new URL(this.#basepath + this.#restRecentPosts) if (this.#busy) {
var params = {from: this.#from, quantity: this.#quantity} return
url.search = new URLSearchParams(params).toString()
this.#boot.secureFetch(url).then(reply => { } else {
if(reply.status !== 200) throw "status=" + reply.status this.#busy = true
return reply.json() 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)
}).then(data => { this.#boot.secureFetch(url).then(reply => {
//console.log(data) if(reply.status !== 200) throw "status=" + reply.status
this.#data = data return reply.json()
this.renderPosts()
//this.rawRenderPosts()
}).catch(err => console.error("Unable to fetch posts. " + err)) }).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
})
}
} }
renderPosts() { morePosts(nr) {
var ul = document.createElement('ul') this.loadPosts(nr)
this.#data.result.posts.forEach(post => { }
renderPosts(posts) {
const ul = this.#unorderedlist
posts.forEach(post => {
//console.log(post)
var li = document.createElement('li') var li = document.createElement('li')
li.id = post.key li.id = post.key
li.classList.add('d4s-social-post') li.classList.add('d4s-social-post')
const thumbnail = (!post.thumbnail_url.startsWith('http')) ? 'https://' + this.#boot.clientId + post.thumbnail_url : post.thumbnail_url const thumbnail = (!post.thumbnail_url.startsWith('http')) ? 'https://' + this.#boot.clientId + post.thumbnail_url : post.thumbnail_url
const datetime = new Date(0) const datetime = new Date(0)
datetime.setUTCMilliseconds(post.time) datetime.setUTCMilliseconds(post.time)
const datetimestr = datetime.toLocaleString() const datetimestr = datetime.toLocaleString([], {year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit'})
li.innerHTML = ` li.innerHTML = `
<div class="d4s-post-heading"> <div class="d4s-post-heading">
<div class="d4s-post-avatar"> <div class="d4s-post-avatar">
<img src="${thumbnail}" onerror="this.style.display='none'" width="32px" height="32px"></slot> <img src="${thumbnail}" onerror="this.style.display='none'"></slot>
</div> </div>
<div class="d4s-post-meta"> <div class="d4s-post-meta">
<div class="fullname">${post.full_name}</div> <div class="fullname">${post.full_name}</div>
@ -68,24 +217,68 @@ window.customElements.define('d4s-social-posts', class extends HTMLElement {
</div> </div>
</div> </div>
<div class="d4s-post-body">${post.description}</div> <div class="d4s-post-body">${post.description}</div>
<div class="d4s-post-footer"> <div class="d4s-post-attachment"></div>
<div class="comments-nr">${post.comments_no}</div> <div class="d4s-post-footer"></div>
<div class="likes-nr">${post.likes_no}</div>
</div>
` `
if (post.comments_no != "0") {
var commsnr = document.createElement('div')
commsnr.classList.add('comments-nr')
commsnr.innerHTML += `
<img src="assets/comment-ellipsis.svg" width="18"/>
<span>${post.comments_no}</span>
`
li.querySelector('.d4s-post-footer').appendChild(commsnr)
}
if (post.likes_no != "0") {
var likesnr = document.createElement('div')
likesnr.classList.add('likes-nr')
likesnr.innerHTML += `
<img src="assets/thumbs-up.svg" width="18" />
<span>${post.likes_no}</span>
`
li.querySelector('.d4s-post-footer').appendChild(likesnr)
}
if (post.link_title !== "") {
var attimg = document.createElement('div')
attimg.classList.add('attachment-div')
attimg.innerHTML += `<img src="${post.uri_thumbnail}" class="attachment-img" onerror="this.style.display='none'"/>`
li.querySelector('.d4s-post-attachment').appendChild(attimg)
var attdesc = document.createElement('div')
attdesc.classList.add('attachment-info')
attdesc.innerHTML += `
<div class="title"><a href="${post.uri}">${post.link_title}</a></div>
<div class="url">${post.uri}</div>
<div class="description">${post.link_description}</div>
`
li.querySelector('.d4s-post-attachment').appendChild(attdesc)
} else {
li.querySelector('.d4s-post-attachment').remove()
}
ul.appendChild(li) 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) { if (post.comments_no > 0) {
this.fetchComments(post.key) this.fetchComments(post.key)
} }
}) })
this.#shadowRoot.appendChild(ul)
} }
rawRenderPosts() { rawRenderResponse(data) {
var pre = document.createElement('pre') var pre = document.createElement('pre')
console.log(this.#data) pre.innerText = JSON.stringify(data, null, " ")
pre.innerText = JSON.stringify(this.#data, null, " ")
this.#shadowRoot.appendChild(pre) this.#shadowRoot.appendChild(pre)
} }
@ -105,32 +298,30 @@ window.customElements.define('d4s-social-posts', class extends HTMLElement {
} }
renderComments(postid, comments) { renderComments(postid, comments) {
console.log(comments)
var li = this.#shadowRoot.getElementById(postid) var li = this.#shadowRoot.getElementById(postid)
console.log(li)
var cul = document.createElement('ul') var cul = document.createElement('ul')
cul.classList.add('d4s-post-comments') cul.classList.add('d4s-post-comments')
comments.result.forEach(comment => { comments.result.forEach(comment => {
var cli = document.createElement('li') var cli = document.createElement('li')
cli.id = comment.feedid cli.id = comment.feedid
cli.classList.add('d4s-comment') cli.classList.add('d4s-post-comment')
const thumbnail = (!comment.thumbnail_url.startsWith('http')) ? 'https://' + this.#boot.clientId + comment.thumbnail_url : comment.thumbnail_url const thumbnail = (!comment.thumbnail_url.startsWith('http')) ? 'https://' + this.#boot.clientId + comment.thumbnail_url : comment.thumbnail_url
const datetime = new Date(0) const datetime = new Date(0)
datetime.setUTCMilliseconds(comment.time) datetime.setUTCMilliseconds(comment.time)
const datetimestr = datetime.toLocaleString() const datetimestr = datetime.toLocaleString([], {year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit'})
cli.innerHTML = ` cli.innerHTML = `
<div class="d4s-comment-heading"> <div class="d4s-comment-avatar">
<div class="d4s-comment-avatar"> <img src="${thumbnail}" onerror="this.style.display='none'"></slot>
<img src="${thumbnail}" onerror="this.style.display='none'" width="32px" height="32px"></slot> </div>
</div> <div class="d4s-comment">
<div class="d4s-comment-meta"> <div class="d4s-comment-body">
<div class="fullname">${comment.full_name}</div> <div class="fullname">${comment.full_name}</div>
<div class="d4s-comment-text">${comment.text}</div>
</div>
<div class="d4s-comment-footer">
<div class="time">${datetimestr}</div> <div class="time">${datetimestr}</div>
</div> </div>
</div> </div>
<div class="d4s-comment-body">${comment.text}</div>
<div class="d4s-comment-footer">
</div>
` `
cul.appendChild(cli) cul.appendChild(cli)
}) })
@ -148,10 +339,10 @@ window.customElements.define('d4s-social-posts', class extends HTMLElement {
this.#basepath = newValue this.#basepath = newValue
break break
case "from": case "from":
this.#from = newValue this.#from = Number(newValue)
break break
case "quantity": case "quantity":
this.#quantity = newValue this.#quantity = Number(newValue)
break break
} }
} }
@ -171,7 +362,7 @@ window.customElements.define('d4s-social-posts', class extends HTMLElement {
} }
set from(from) { set from(from) {
this.#from = from this.#from = Number(from)
this.setAttribute("from", from) this.setAttribute("from", from)
} }
@ -180,8 +371,7 @@ window.customElements.define('d4s-social-posts', class extends HTMLElement {
} }
set quantity(quantity) { set quantity(quantity) {
this.#quantity = quantity this.#quantity = Number(quantity)
this.setAttribute("quantity", quantity) this.setAttribute("quantity", quantity)
} }
}) });