377 lines
22 KiB
HTML
Raw Normal View History

2023-12-12 12:11:44 +01:00
<html>
<head>
2023-12-15 09:02:26 +01:00
<!--
features todo:
- optional queries ✔
- accountId ✔, feedId ✔
- pageSize ✔
- read ✔, starred ✔, ascending ✔
- request next page ✔
- sanity check url params ✔
- mark read - page
- mark read/unread - individual
- mark star/unstar - individual
- render read/unread/starred
- missing thumbnail
- search/filter?
- UI to select unead only/starred only/all?
- Loading spinners
- feed selector
- error management
- cleaner code
-->
2023-12-12 12:11:44 +01:00
<style type="text/css">
body {
font-family: Roboto, sans-serif;
color: #999999;
background-color: #171717;
}
.template {
display: none;
}
.entry {
2023-12-15 09:02:26 +01:00
max-width: 720px;
smax-width: 100%;
2023-12-12 12:11:44 +01:00
xborder: 1px solid red;
padding: 20px;
margin: 3px auto;
text-align: left;
font-size: 13px;
box-sizing: border-box;
background-color: #262626;
}
.entry .wrapper {
display: flex;
align-items: stretch;
}
.entry .thumb {
xborder: 1px solid blue;
xmax-height: 100px;
xmax-width: 200px;
}
.entry .thumb img {
xheight: 100%;
}
.entry .thumb_actual {
background-image: url(data:image/jpeg;base64,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
width: 222px;
height: 156px;
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
border-radius: 3px;
}
.entry .preview {
xborder: 1px solid green;
display: flex;
flex-direction: column;
justify-content: space-between;
margin-left: 20px;
}
.entry .title {
color: #CECECE;
font-size: 16px;
font-weight: bold;
max-height: 60px;
overflow: hidden;
line-height: 20px;
text-overflow: ellipsis;
text-decoration: none;
}
.entry .feed {
margin-top: 4px;
color: #888888;
}
.entry .content {
margin-top: 6px;
margin-bottom: 6px;
font-size: 14px;
line-height: 20px;
overflow: hidden;
text-overflow: ellipsis;
max-height: 60px;
word-break: break-word;
}
.entry .footer {
display: flex;
align-items: center;
justify-content: space-between;
}
.entry .date {
color: #888888;
}
2023-12-15 09:02:26 +01:00
.articles_post {
max-width: 720px;
padding: 20px;
margin: 3px auto;
text-align: center;
font-size: 13px;
box-sizing: border-box;
background-color: #262626;
}
button.next_page {
font-size: 18px;
font-weight: bold;
}
2023-12-12 12:11:44 +01:00
</style>
</head>
<body>
<article class="template entry">
<div class="wrapper">
<div class="thumb">
<div class="thumb_actual"></div>
</div>
<div class="preview">
<div class="titlefeedcontent">
<a class="title" href=""></a>
<div class="feed"></div><div class="author"></div>
<div class="content"></div>
</div>
<div class="footer">
<div class="date"></div>
</div>
</div>
</div>
</article>
2023-12-15 09:02:26 +01:00
<div>
<section class="articles">
</section>
<section class="articles_post">
<button class="next_page">Next Page</button>
</section>
</div>
2023-12-12 12:11:44 +01:00
<script type="text/javascript">
2023-12-15 09:02:26 +01:00
function attachHandlers() {
document.querySelector("button.next_page").addEventListener("click", onNextPageClicked);
}
function processParams() {
let params = new URLSearchParams(window.location.search);
let elemArticles = document.querySelector("section.articles");
if (params.has("feed"))
elemArticles.setAttribute("data-rssg-feed", params.get("feed"));
if (params.has("account")) {
let accountId = helpers.checkIntOrThrow(
params.get("account"), "account"
);
elemArticles.setAttribute("data-rssg-account", accountId);
}
if (params.has("row_limit")) {
let row_limit = helpers.checkIntOrThrow(
params.get("row_limit"), "row_limit"
);
elemArticles.setAttribute("data-rssg-row-limit", row_limit);
}
{
let newest_first = params.get("newest_first") || "true";
newest_first = helpers.checkBoolOrThrow(newest_first, "newest_first");
elemArticles.setAttribute("data-rssg-newest-first", newest_first);
}
{
let unread_only = params.get("unread_only") || "true";
unread_only = helpers.checkBoolOrThrow(unread_only, "unread_only");
elemArticles.setAttribute("data-rssg-unread-only", unread_only);
}
{
let starred_only = params.get("starred_only") || "false";
starred_only = helpers.checkBoolOrThrow(starred_only, "starred_only");
elemArticles.setAttribute("data-rssg-starred-only", starred_only);
}
}
function assembleRpcCall() {
2023-12-12 12:11:44 +01:00
let jsonRpcCall = {
method: "ArticlesFromFeed",
data: {
newest_first: true,
unread_only: true,
row_offset: 0,
2023-12-15 09:02:26 +01:00
row_limit: 10
2023-12-12 12:11:44 +01:00
}
}
2023-12-15 09:02:26 +01:00
let elemArticles = document.querySelector("section.articles");
if (elemArticles.hasAttribute("data-rssg-row-offset"))
jsonRpcCall.data.row_offset = +elemArticles.getAttribute("data-rssg-row-offset");
if (elemArticles.hasAttribute("data-rssg-after-date")) {
delete jsonRpcCall.data.row_offset;
jsonRpcCall.data.start_after_article_date = +elemArticles.getAttribute("data-rssg-after-date");
}
if (elemArticles.hasAttribute("data-rssg-feed"))
jsonRpcCall.data.feed = elemArticles.getAttribute("data-rssg-feed");
if (elemArticles.hasAttribute("data-rssg-account"))
jsonRpcCall.data.account = +elemArticles.getAttribute("data-rssg-account");
if (elemArticles.hasAttribute("data-rssg-row-limit"))
jsonRpcCall.data.row_limit = +elemArticles.getAttribute("data-rssg-row-limit");
jsonRpcCall.data.newest_first = elemArticles.getAttribute("data-rssg-newest-first") == "true";
jsonRpcCall.data.unread_only = elemArticles.getAttribute("data-rssg-unread-only") == "true";
jsonRpcCall.data.starred_only = elemArticles.getAttribute("data-rssg-starred-only") == "true";
return jsonRpcCall;
}
function fetchMessages() {
let jsonRpcCall = assembleRpcCall();
2023-12-12 12:11:44 +01:00
let urlApi = "http://localhost:54123";
let jsonPayload = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(jsonRpcCall)
}
fetch(urlApi, jsonPayload)
.then(function(response) {
return response.json()
})
.then(function(content) {
renderMessages(content.data);
});
}
function renderMessages(jsonMessages) {
2023-12-15 09:02:26 +01:00
let elemArticles = document.querySelector("section.articles");
elemArticles.innerHTML = "";
window.scrollTo(0,0);
2023-12-12 12:11:44 +01:00
jsonMessages.forEach(function(jsonMessage) {
transformMessage(jsonMessage);
let article = fillTemplate(jsonMessage);
2023-12-15 09:02:26 +01:00
elemArticles.appendChild(article);
2023-12-12 12:11:44 +01:00
});
}
function transformMessage(jsonMessage) {
2023-12-15 09:02:26 +01:00
jsonMessage.date = new Date(jsonMessage.date_created);
jsonMessage.dateHuman = helpers.getHumanDate(jsonMessage.date);
2023-12-12 12:11:44 +01:00
jsonMessage.enclosedUrlA = helpers.getEnclosedImageUrl(jsonMessage.enclosures);
let elemContent = document.createElement("div");
elemContent.innerHTML = jsonMessage.contents;
jsonMessage.contentShort = elemContent.textContent;
if (jsonMessage.contentShort.length > 300)
jsonMessage.contentShort = jsonMessage.contentShort.substring(0, 300) + "...";
}
function fillTemplate(jsonMessage) {
let template = document.querySelector("article.template");
let article = template.cloneNode(true);
article.classList.remove("template");
2023-12-15 09:02:26 +01:00
article.setAttribute("data-rssg-id", jsonMessage.id);
article.setAttribute("data-rssg-customid", jsonMessage.custom_id);
article.setAttribute("data-rssg-date", jsonMessage.date_created);
article.setAttribute("data-rssg-feed", jsonMessage.feed_custom_id);
article.setAttribute("data-rssg-account", jsonMessage.account_id);
article.setAttribute("data-rssg-read", jsonMessage.is_read);
article.setAttribute("data-rssg-important", jsonMessage.is_important);
article.setAttribute("data-rssg-rtl", jsonMessage.is_rtl);
2023-12-12 12:11:44 +01:00
article.querySelectorAll(".title").forEach(e => e.textContent = jsonMessage.title);
article.querySelectorAll(".author").forEach(e => e.textContent = jsonMessage.author);
article.querySelectorAll(".content").forEach(e => e.textContent = jsonMessage.contentShort);
2023-12-15 09:02:26 +01:00
article.querySelectorAll(".feed").forEach(e => e.textContent = jsonMessage.feed_title);
2023-12-12 12:11:44 +01:00
article.querySelectorAll(".author").forEach(e => e.textContent = jsonMessage.author);
article.querySelectorAll(".date").forEach(e => e.textContent = jsonMessage.dateHuman);
if (jsonMessage.enclosedUrlA) {
article.querySelectorAll(".thumb_actual").forEach(function(e) {
e.setAttribute("style", "background-image: url(" + jsonMessage.enclosedUrlA + ");");
});
}
return article;
}
2023-12-15 09:02:26 +01:00
function onNextPageClicked() {
let elemArticles = document.querySelector("section.articles");
let articleEntryLast = elemArticles.querySelector("article.entry:last-child");
if (!articleEntryLast) return;
if (!articleEntryLast.hasAttribute("data-rssg-date")) return;
let dateAfter = +articleEntryLast.getAttribute("data-rssg-date");
elemArticles.removeAttribute("data-rssg-row-offset");
elemArticles.setAttribute("data-rssg-after-date", dateAfter);
fetchMessages();
}
2023-12-12 12:11:44 +01:00
let helpers = {
2023-12-15 09:02:26 +01:00
checkIntOrThrow: function(value, name) {
value = +value;
if (Number.isInteger(value)) return value;
let message = "Invalid parameter, must be an integer: " + name;
alert(message);
throw message;
},
checkBoolOrThrow: function(value, name) {
value = value.toLowerCase();
if (value == "true" || value == "false") return value == "true";
let message = "Invalid parameter, must be boolean: " + name;
alert(message);
throw message;
},
2023-12-12 12:11:44 +01:00
getHumanDate: function(date) {
let dateHuman = date.toDateString();
dateHuman += " " + date.getHours();
dateHuman += ":" + date.getMinutes().toString().padStart(2, "0");
return dateHuman;
},
getEnclosedImageUrl: function(enclosures) {
for (let i = 0; i < enclosures.length; i++) {
let enclosure = enclosures[i];
if (enclosure.url.indexOf("http") > -1) return enclosure.url;
}
}
};
2023-12-15 09:02:26 +01:00
processParams();
attachHandlers();
fetchMessages();
2023-12-12 12:11:44 +01:00
</script>
</body>
</html>