From 109e4637244612188fc5eb376bd5f17ec4bc08e7 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 28 Jan 2026 21:01:03 +1100 Subject: [PATCH] LikeandCommentSave --- index.html | 20 +++++- script.js | 168 ++++++++++++++++++++++++++++++++++++++++++++++++ styles/main.css | 82 +++++++++++++++++++++++ 3 files changed, 268 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index bcb8efa..edc3c81 100644 --- a/index.html +++ b/index.html @@ -108,7 +108,7 @@
-
+
User @@ -142,10 +142,18 @@

sarah_j Exploring the Cinque Terre! ๐Ÿ‡ฎ๐Ÿ‡นโœจ

+ +
+
+
+ + +
+
-
+
User @@ -179,6 +187,14 @@

mike_photo Golden hour in the mountains ๐Ÿ”๏ธ

+ +
+
+
+ + +
+
diff --git a/script.js b/script.js index ce1b009..02d987d 100644 --- a/script.js +++ b/script.js @@ -96,6 +96,9 @@ document.addEventListener('DOMContentLoaded', () => { void feedView.offsetWidth; feedView.classList.add('fade-in'); + // Load persisted state for posts + loadPostState(); + // Remove fade-in class after animation to fix fixed positioning context setTimeout(() => { feedView.classList.remove('fade-in'); @@ -159,4 +162,169 @@ document.addEventListener('DOMContentLoaded', () => { } }); } + + // --- PERSISTENCE LOGIC --- + function getPostState() { + return JSON.parse(localStorage.getItem('socialAppPostState') || '{}'); + } + + function savePostState(state) { + localStorage.setItem('socialAppPostState', JSON.stringify(state)); + } + + function loadPostState() { + const state = getPostState(); + const posts = document.querySelectorAll('.post-card'); + + posts.forEach(card => { + const id = card.getAttribute('data-post-id'); + if (id && state[id]) { + const data = state[id]; + + // Restore Likes + const likeIcon = card.querySelector('.heart-icon'); + const likesText = card.querySelector('.likes'); + + if (data.liked) { + likeIcon.classList.add('liked'); + likeIcon.style.fill = '#EF4444'; + likeIcon.style.stroke = '#EF4444'; + } else { + likeIcon.classList.remove('liked'); + likeIcon.style.fill = 'none'; + likeIcon.style.stroke = 'white'; + } + likesText.innerText = data.likesCount + ' likes'; + + // Restore Comments + const commentsContainer = card.querySelector('.added-comments'); + commentsContainer.innerHTML = ''; // Clear existing to prevent dupes on re-run + if (data.comments && data.comments.length > 0) { + data.comments.forEach(text => { + const commentEl = document.createElement('div'); + commentEl.classList.add('comment-item'); + commentEl.innerHTML = `you ${text}`; + commentsContainer.appendChild(commentEl); + }); + } + } + }); + } + + // --- FEED INTERACTIONS --- + if (feedView) { + feedView.addEventListener('click', (e) => { + const target = e.target; + + // 1. LIKE ACTION + const likeBtn = target.closest('.heart-icon')?.closest('.icon-btn'); + if (likeBtn) { + const icon = likeBtn.querySelector('.heart-icon'); + const postCard = likeBtn.closest('.post-card'); + const likesText = postCard.querySelector('.likes'); + const postId = postCard.getAttribute('data-post-id'); + + // Toggle State + icon.classList.toggle('liked'); + + // Update Count (Simple parsing) + let count = parseInt(likesText.innerText); + let isLiked = false; + + if (icon.classList.contains('liked')) { + icon.style.fill = '#EF4444'; + icon.style.stroke = '#EF4444'; + count++; + isLiked = true; + } else { + icon.style.fill = 'none'; + icon.style.stroke = 'white'; + count--; + isLiked = false; + } + likesText.innerText = count + ' likes'; + + // Save State + if (postId) { + const state = getPostState(); + if (!state[postId]) state[postId] = { comments: [] }; + state[postId].liked = isLiked; + state[postId].likesCount = count; + // Preserve existing comments if we didn't just load them + if (!state[postId].comments) state[postId].comments = []; + savePostState(state); + } + return; + } + + // 2. COMMENT TOGGLE ACTION + const commentBtn = target.closest('.icon-btn'); + if (commentBtn && !commentBtn.querySelector('.heart-icon')) { + // Check if it's the comment button (has specific path) + const path = commentBtn.querySelector('path'); + if (path && (path.getAttribute('d').startsWith('M21 11.5') || path.closest('svg')?.innerHTML.includes('M21 11.5'))) { + const postCard = commentBtn.closest('.post-card'); + const commentSection = postCard.querySelector('.comment-section'); + commentSection.classList.toggle('active'); + if (commentSection.classList.contains('active')) { + commentSection.querySelector('input').focus(); + } + return; + } + } + + // 3. POST COMMENT ACTION + if (target.classList.contains('post-btn')) { + const wrapper = target.closest('.comment-input-wrapper'); + const input = wrapper.querySelector('.comment-input'); + const text = input.value.trim(); + const postCard = wrapper.closest('.post-card'); + const postId = postCard.getAttribute('data-post-id'); + + if (text) { + addComment(wrapper.closest('.comment-section'), text); + + if (postId) { + const state = getPostState(); + if (!state[postId]) state[postId] = { liked: false, likesCount: parseInt(postCard.querySelector('.likes').innerText) || 0, comments: [] }; + if (!state[postId].comments) state[postId].comments = []; + state[postId].comments.push(text); + savePostState(state); + } + input.value = ''; + } + } + }); + + // Enter key for comments + feedView.addEventListener('keydown', (e) => { + if (e.key === 'Enter' && e.target.classList.contains('comment-input')) { + const text = e.target.value.trim(); + const wrapper = e.target.closest('.comment-input-wrapper'); + const postCard = wrapper.closest('.post-card'); + const postId = postCard.getAttribute('data-post-id'); + + if (text) { + addComment(e.target.closest('.comment-section'), text); + + if (postId) { + const state = getPostState(); + if (!state[postId]) state[postId] = { liked: false, likesCount: parseInt(postCard.querySelector('.likes').innerText) || 0, comments: [] }; + if (!state[postId].comments) state[postId].comments = []; + state[postId].comments.push(text); + savePostState(state); + } + e.target.value = ''; + } + } + }); + } + + function addComment(section, text) { + const container = section.querySelector('.added-comments'); + const commentEl = document.createElement('div'); + commentEl.classList.add('comment-item'); + commentEl.innerHTML = `you ${text}`; + container.appendChild(commentEl); + } }); diff --git a/styles/main.css b/styles/main.css index 153feb6..13474d2 100644 --- a/styles/main.css +++ b/styles/main.css @@ -518,6 +518,88 @@ p { color: var(--text-main); } +/* Feed Interactions */ +.icon-btn .heart-icon.liked { + fill: #EF4444; + stroke: #EF4444; + animation: likeBounce 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +@keyframes likeBounce { + 0% { + transform: scale(1); + } + + 50% { + transform: scale(1.3); + } + + 100% { + transform: scale(1); + } +} + +/* Comment Section */ +.comment-section { + padding: 0 15px 15px; + display: none; + /* Hidden by default */ +} + +.comment-section.active { + display: block; + animation: fadeIn 0.3s ease-out; +} + +.comment-input-wrapper { + display: flex; + gap: 10px; + margin-top: 10px; +} + +.comment-input { + flex: 1; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--glass-border); + border-radius: var(--radius-full); + padding: 8px 15px; + color: var(--text-main); + font-size: 13px; + outline: none; +} + +.comment-input:focus { + border-color: var(--text-muted); +} + +.post-btn { + background: none; + border: none; + color: #3B82F6; + /* Blue accent */ + font-weight: 600; + font-size: 13px; + cursor: pointer; +} + +.added-comments { + margin-top: 10px; + font-size: 13px; + color: var(--text-main); + display: flex; + flex-direction: column; + gap: 6px; +} + +.comment-item { + line-height: 1.4; +} + +.comment-user { + font-weight: 600; + margin-right: 5px; +} + /* Bottom Navigation */ .bottom-nav { position: fixed;