expper's picture
old facebook page 2011
fceceaa verified
class AppFeed extends HTMLElement {
constructor() {
super();
this.posts = [];
}
connectedCallback() {
this.attachShadow({ mode: 'open' });
// Initial Skeleton
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
}
.post-card {
background-color: #242526;
border-radius: 5px;
margin-bottom: 15px;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
overflow: hidden;
}
.status-box {
background-color: #242526;
border-radius: 5px;
padding: 10px;
margin-bottom: 15px;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
display: flex;
gap: 10px;
}
.status-input {
flex: 1;
background-color: #3a3b3c;
border: 1px solid #3e4042;
border-radius: 5px;
padding: 8px;
color: #e4e6eb;
font-size: 14px;
}
.post-header {
padding: 10px;
display: flex;
align-items: center;
}
.avatar {
width: 40px;
height: 40px;
border-radius: 2px;
margin-right: 10px;
}
.info h4 {
margin: 0;
font-size: 14px;
color: #e4e6eb;
}
.info span {
font-size: 12px;
color: #b0b3b8;
}
.post-content {
padding: 0 10px 10px;
font-size: 14px;
line-height: 1.4;
color: #e4e6eb;
}
.post-image {
width: 100%;
display: block;
border-top: 1px solid #3e4042;
border-bottom: 1px solid #3e4042;
}
.post-actions {
padding: 5px 10px;
background-color: #323232;
display: flex;
border-top: 1px solid #3e4042;
}
.action-btn {
background: none;
border: none;
color: #b0b3b8;
font-size: 12px;
font-weight: bold;
padding: 5px 10px;
cursor: pointer;
display: flex;
align-items: center;
gap: 5px;
}
.action-btn:hover {
background-color: #3a3b3c;
border-radius: 3px;
}
.action-btn i {
width: 14px;
height: 14px;
}
.loading {
text-align: center;
padding: 20px;
color: #b0b3b8;
}
</style>
<div class="status-box">
<img src="http://static.photos/people/40x40/1" class="avatar" alt="Me">
<input type="text" class="status-input" placeholder="What's on your mind?">
</div>
<div id="feed-container">
<div class="loading">Updating News Feed...</div>
</div>
`;
this.fetchPosts();
}
async fetchPosts() {
try {
// Fetch dummy text data
const response = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=5');
const data = await response.json();
// Fetch dummy users for avatars
const usersResponse = await fetch('https://jsonplaceholder.typicode.com/users?_limit=5');
const users = await usersResponse.json();
this.posts = data.map((post, index) => ({
id: post.id,
title: post.title,
body: post.body,
user: users[index] || { name: 'Facebook User', id: 1 },
likes: Math.floor(Math.random() * 50) + 1,
imageSeed: Math.floor(Math.random() * 1000)
}));
this.renderFeed();
} catch (error) {
console.error("Error fetching posts:", error);
this.shadowRoot.getElementById('feed-container').innerHTML = '<div class="loading">Error loading feed.</div>';
}
}
renderFeed() {
const container = this.shadowRoot.getElementById('feed-container');
container.innerHTML = '';
this.posts.forEach(post => {
const card = document.createElement('div');
card.className = 'post-card';
card.innerHTML = `
<div class="post-header">
<img src="http://static.photos/people/40x40/${post.user.id}" class="avatar" alt="${post.user.name}">
<div class="info">
<a href="#">${post.user.name}</a>
<br>
<span>2 hours ago via iPhone</span>
</div>
</div>
<div class="post-content">
<p>${post.body}</p>
</div>
${Math.random() > 0.5 ? `<img src="http://static.photos/technology/640x360/${post.imageSeed}" class="post-image" alt="Post Image">` : ''}
<div class="post-actions">
<button class="action-btn like-btn" data-id="${post.id}">
<i data-feather="thumbs-up"></i> Like
</button>
<button class="action-btn">
<i data-feather="message-circle"></i> Comment
</button>
<button class="action-btn">
<i data-feather="share"></i> Share
</button>
</div>
`;
container.appendChild(card);
});
// Re-initialize icons for the new content
if (window.feather) {
feather.replace();
}
// Add event listeners for like buttons
const likeBtns = this.shadowRoot.querySelectorAll('.like-btn');
likeBtns.forEach(btn => {
btn.addEventListener('click', (e) => {
const icon = btn.querySelector('i');
// Simple toggle visual
if (btn.style.color === 'rgb(66, 103, 178)') {
btn.style.color = '#b0b3b8';
icon.style.fill = 'none';
} else {
btn.style.color = '#4267B2'; // FB Blue
icon.style.fill = '#4267B2';
// Dispatch event
this.dispatchEvent(new CustomEvent('post-liked', {
detail: { id: btn.dataset.id },
bubbles: true,
composed: true
}));
}
});
});
}
}
customElements.define('app-feed', AppFeed);