Feed display js

This commit is contained in:
Greg Shuflin 2025-02-02 14:09:11 -08:00
parent ec2cdc98d5
commit 29846aee3d
3 changed files with 194 additions and 6 deletions

View File

@ -286,4 +286,102 @@ body.with-sidebar {
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
/* Feed list styles */
#feedList {
margin-bottom: 2rem;
}
.feed-name {
display: block;
padding: 0.75rem;
margin: 0.25rem 0;
color: var(--text-color);
text-decoration: none;
border-radius: 4px;
transition: background-color 0.2s ease;
cursor: pointer;
position: relative;
padding-right: 2.5rem;
}
.feed-name:hover {
background-color: rgba(255, 255, 255, 0.1);
}
/* Dropdown styles */
.feed-menu-button {
position: absolute;
right: 0.5rem;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: var(--text-muted);
padding: 0.2rem 0.5rem;
cursor: pointer;
font-size: 1.2rem;
opacity: 0;
transition: opacity 0.2s ease;
}
.feed-name:hover .feed-menu-button {
opacity: 1;
}
.feed-menu-button:hover {
color: var(--text-color);
}
.feed-menu {
position: absolute;
right: 0.5rem;
top: 100%;
background-color: var(--sidebar-bg);
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
display: none;
z-index: 100;
}
.feed-menu.show {
display: block;
}
.feed-menu-item {
display: block;
padding: 0.5rem 1rem;
color: var(--text-color);
text-decoration: none;
white-space: nowrap;
cursor: pointer;
transition: background-color 0.2s ease;
}
.feed-menu-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.feed-menu-item.delete {
color: var(--primary-red);
}
.feed-menu-item.delete:hover {
background-color: rgba(244, 63, 63, 0.1);
}
.feed-empty {
color: var(--text-muted);
text-align: center;
padding: 1rem;
font-style: italic;
}
.feed-error {
color: var(--primary-red);
text-align: center;
padding: 1rem;
background-color: rgba(244, 63, 63, 0.1);
border-radius: 4px;
}

View File

@ -4,17 +4,109 @@ async function fetchFeeds() {
const response = await fetch('/feeds');
if (response.ok) {
const feeds = await response.json();
console.log('Feeds loaded:', feeds);
return feeds;
} else {
console.error('Failed to load feeds:', response.status);
return null;
}
} catch (error) {
console.error('Error loading feeds:', error);
return null;
}
}
// Close any open feed menus
function closeAllFeedMenus() {
document.querySelectorAll('.feed-menu.show').forEach(menu => {
menu.classList.remove('show');
});
}
// Add click handler to close menus when clicking outside
document.addEventListener('click', (e) => {
if (!e.target.closest('.feed-menu') && !e.target.closest('.feed-menu-button')) {
closeAllFeedMenus();
}
});
function renderFeedItem(feed) {
const container = document.createElement('div');
container.style.position = 'relative';
const name = document.createElement('span');
name.className = 'feed-name';
name.textContent = feed.name;
name.onclick = () => {
// TODO: Handle feed click
console.log('Feed clicked:', feed);
};
const menuButton = document.createElement('button');
menuButton.className = 'feed-menu-button';
menuButton.innerHTML = '⋮';
menuButton.title = 'Feed options';
menuButton.onclick = (e) => {
e.stopPropagation();
closeAllFeedMenus();
menu.classList.toggle('show');
};
const menu = document.createElement('div');
menu.className = 'feed-menu';
const deleteItem = document.createElement('a');
deleteItem.className = 'feed-menu-item delete';
deleteItem.textContent = 'Remove Feed';
deleteItem.onclick = async (e) => {
e.stopPropagation();
if (confirm(`Are you sure you want to delete "${feed.name}"?`)) {
try {
const response = await fetch(`/feeds/${feed.feed_id}`, {
method: 'DELETE',
});
if (response.ok) {
handleFeeds();
} else {
console.error('Failed to delete feed:', response.status);
}
} catch (error) {
console.error('Error deleting feed:', error);
}
}
menu.classList.remove('show');
};
menu.appendChild(deleteItem);
name.appendChild(menuButton);
name.appendChild(menu);
container.appendChild(name);
return container;
}
async function handleFeeds() {
const feeds = await fetchFeeds();
const feedList = document.getElementById('feedList');
if (feeds) {
feedList.innerHTML = '';
if (feeds.length === 0) {
const emptyMessage = document.createElement('div');
emptyMessage.className = 'feed-empty';
emptyMessage.textContent = 'No feeds added yet';
feedList.appendChild(emptyMessage);
} else {
feeds.forEach(feed => {
feedList.appendChild(renderFeedItem(feed));
});
}
} else {
feedList.innerHTML = '<div class="feed-error">Failed to load feeds</div>';
}
}
// Load feeds when page loads
document.addEventListener('DOMContentLoaded', fetchFeeds);
document.addEventListener('DOMContentLoaded', handleFeeds);
// Logout functionality
document.getElementById('logoutButton').addEventListener('click', async () => {
@ -101,7 +193,7 @@ confirmButton.addEventListener('click', async () => {
if (response.ok) {
hideModal();
// Refresh the feed list
fetchFeeds();
handleFeeds();
} else {
switch (response.status) {
case 409:

View File

@ -51,9 +51,7 @@
</ul>
</div>
<div class="main-content">
<h1>Welcome to RSS Reader</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<h1>RSS Reader</h1>
</div>
<script src="/static/js/app.js"></script>