Compare commits

...

4 Commits

Author SHA1 Message Date
Marcus Noble 43c6017397 Show feed list on mobile 2020-11-18 19:45:39 +00:00
Marcus Noble f6ebdc480e Background refresh 2020-11-18 19:18:08 +00:00
Marcus Noble c836fe576d Fix unread count 2020-11-18 19:12:31 +00:00
Marcus Noble 649595ed14 Fix posts with relative image/links 2020-11-18 19:02:31 +00:00
3 changed files with 71 additions and 8 deletions

View File

@ -30,12 +30,17 @@
<link rel="stylesheet" href="/static/style.css">
</head>
<body class="hack">
<div class="container">
<div id="app" class="container">
<header>
<button class="feed-toggle" v-on:click="toggleFeeds">
<svg width="24" height="24" viewbox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M24 16a3.5 3.5 0 110-7 3.5 3.5 0 010 7z" fill="#212121"/><path d="M24 27.5a3.5 3.5 0 110-7 3.5 3.5 0 010 7z" fill="#212121"/><path d="M20.5 35.5a3.5 3.5 0 107 0 3.5 3.5 0 00-7 0z" fill="#212121"/></svg>
</button>
<h1 class="title">
Gopherss
</h1>
</header>
<div id="app">
<div>
<div class="menu">
<button title="Show Read" v-on:click="toggleShowRead()">
<svg width="30" height="30" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 9a4 4 0 110 8 4 4 0 010-8zm0-3.5a10 10 0 019.7 7.6.8.8 0 01-1.5.3 8.5 8.5 0 00-16.4 0 .8.8 0 01-1.5-.3A10 10 0 0112 5.5z" :style="{'fill': showRead ? '#ff2e88' : '' }" fill-rule="nonzero"/></svg>
@ -186,6 +191,7 @@
window.location.hash = feed;
},
loadItem(item) {
this.setBusy(true);
if (this.selectedItem === item.ID) {
this.selectedItem = undefined;
} else {
@ -194,6 +200,7 @@
item.PendingRead = true;
fetch(`/api/read/${item.ID}`, {method: "POST"})
}
this.setBusy(false);
},
saveItem(item) {
this.setBusy(true);
@ -332,13 +339,16 @@
}
return "https://s2.googleusercontent.com/s2/favicons?domain_url=" + (feed.HomepageURL || feed.FeedURL);
},
toggleFeeds() {
document.querySelector('.feeds').classList.toggle('show-mobile');
}
},
created() {
this.setBusy(true);
Promise.all([
fetch(`/api/feeds`).then(res => res.json()).then(feeds => this.feeds = feeds),
fetch(`/api/unread`).then(res => res.json()).then(items => this.items = items),
fetch(`/api/unread`).then(res => res.json()).then(items => this.items = items.map(item => {item.PendingRead = false; return item;})),
fetch(`/api/saved`).then(res => res.json()).then(items => this.savedItems = items)
])
.then(() => {
@ -375,6 +385,19 @@
}
};
// Fetch updates every 5 minutes
setInterval(() => {
fetch(`/api/unread`)
.then(res => res.json())
.then(items => {
for (let item of items) {
if (!this.items.some(i => i.ID == item.ID)) {
this.items.push(item);
}
}
})
}, 5 * 60 * 1000);
document.addEventListener('keydown', this._keyListener.bind(this));
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {

View File

@ -69,7 +69,21 @@ class FeedItem extends HTMLElement {
if (p.innerText.trim() == "") {
p.remove();
}
})
});
let url = new URL(item.URL);
[...this.shadowRoot.querySelectorAll('img[src^="/"]')].forEach(i => {
i.src = url.origin + i.getAttribute('src');
});
[...this.shadowRoot.querySelectorAll('a[href^="/"]')].forEach(a => {
a.href = url.origin + a.getAttribute('src');
});
[...this.shadowRoot.querySelectorAll('img:not([src^=http])')].forEach(i => {
i.src = url.origin +'/'+ i.getAttribute('src');
});
[...this.shadowRoot.querySelectorAll('a:not([href^=http])')].forEach(a => {
a.href = url.origin +'/'+ a.getAttribute('src');
});
})
}

View File

@ -25,6 +25,14 @@ body {
position: relative;
}
header {
display: flex;
}
header h1 {
width: -moz-available;
}
.item-heading .item-title {
margin-bottom: 0;
@ -82,17 +90,17 @@ body {
text-align: right;
}
.menu button {
button {
background: none;
border: none;
cursor: pointer;
}
.menu button:disabled {
button:disabled {
cursor: not-allowed;
}
.menu button:not(:disabled):hover svg path {
button:not(:disabled):hover svg path {
fill: #ff2e88;
}
@ -111,13 +119,31 @@ body {
box-shadow: 1px 2px 3px #333
}
@media only screen and (min-width: 701px) {
.feed-toggle {
display: none;
}
}
@media only screen and (max-width: 700px) {
.feeds{ display: none !important; }
.feeds{
position: initial;
width: 100%;
height: 0px;
margin: 0;
overflow: hidden;
transition: all 2s;
}
.container {
max-width: 100em;
}
}
.feeds.show-mobile {
height: 50vh;
overflow-y: scroll;
}
.dark {
background: #333;
}