Make Like and Comment buttons work on posts

This commit is contained in:
Alex Erdei 2025-05-03 17:14:35 +01:00
parent 70d6700fe8
commit 22d934c769
3 changed files with 81 additions and 87 deletions

View File

@ -9,28 +9,16 @@ import linkReducer from "../features/link/linkSlice";
import accountPageReducer from "../features/accountPage/accountPageSlice"; import accountPageReducer from "../features/accountPage/accountPageSlice";
const store = configureStore({ const store = configureStore({
reducer: { reducer: {
user: userReducer, user: userReducer,
currentUser: currentUserReducer, currentUser: currentUserReducer,
users: usersReducer, users: usersReducer,
posts: postsReducer, posts: postsReducer,
incomingMessages: incomingMessagesReducer, incomingMessages: incomingMessagesReducer,
outgoingMessages: outgoingMessagesReducer, outgoingMessages: outgoingMessagesReducer,
link: linkReducer, link: linkReducer,
accountPage: accountPageReducer, accountPage: accountPageReducer,
}, },
}); });
if (import.meta.env.DEV) {
store.subscribe(() => {
const s = store.getState();
console.log("[DEBUG] users:", s.users);
console.log("[DEBUG] currentUser:", s.currentUser);
console.log("[DEBUG] posts:", s.posts);
});
}
export default store; export default store;

View File

@ -329,13 +329,13 @@ function openSocket() {
store.dispatch(usersUpdated([parseMsg(raw)])); store.dispatch(usersUpdated([parseMsg(raw)]));
}); });
hub.on("fakebook.posts.post", (raw) => hub.on("fakebook.posts.post", (raw) => {
store.dispatch(postsUpdated([JSON.parse(raw)])) store.dispatch(postsUpdated([JSON.parse(raw)]));
); });
hub.on("fakebook.posts.put", (raw) => hub.on("fakebook.posts.put", (raw) => {
store.dispatch(postsUpdated([JSON.parse(raw)])) store.dispatch(postsUpdated([JSON.parse(raw)]));
); });
}) })
.catch((err) => { .catch((err) => {
@ -470,31 +470,12 @@ async function patchOnline(isOnline) {
await $fetch(USERS_URL, { await $fetch(USERS_URL, {
method: "PUT", method: "PUT",
mode: "cors",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ body: JSON.stringify({
user_id, user_id,
isOnline: isOnline ? 1 : 0, // DB needs 1/0 isOnline: isOnline ? 1 : 0, // DB needs 1/0
}), }),
}); });
/* -------- optimistic Redux update (merge, not overwrite) -------- */
const cur = store.getState().currentUser;
store.dispatch(currentUserUpdated({ ...cur, isOnline })); // boolean
const usersNew = store
.getState()
.users.map((u) => (u.userID === user_id ? { ...u, isOnline } : u));
store.dispatch(usersUpdated(usersNew));
} catch (err) { } catch (err) {
console.warn("[online/offline] PUT failed:", err.message); console.warn("[online/offline] PUT failed:", err.message);
} }
@ -578,13 +559,41 @@ export async function upload(post) {
return { id: doc.postID }; return { id: doc.postID };
} }
export function updatePost(post, postID) { /* --------------------------------------------------------------
const idx = DB.posts.findIndex((p) => p.postID === postID);
if (idx !== -1) { Update a post (likes, comments, text, etc.)
DB.posts[idx] = { ...DB.posts[idx], ...post };
persist(); post partial object in Redux/UI format
}
postID numeric/string id in the REST DB
-------------------------------------------------------------- */
export async function updatePost(post, postID) {
const token = localStorage.getItem(LS_TOKEN);
if (!token) throw new Error("Not authenticated");
/* 1. Map Redux-shape → Magic API shape ----------------------- */
const body = { post_id: postID }; // mandatory key
if (post.comments !== undefined)
body.comments = JSON.stringify(post.comments);
if (post.likes !== undefined) body.likes = JSON.stringify(post.likes);
/* 2. Fire PUT /posts ---------------------------------------- */
await $fetch(POSTS_URL, {
method: "PUT",
body: JSON.stringify(body),
});
/* 3. Refresh Redux state (merge) ---------------------------- */
//store.dispatch(postsUpdated([updatedRow]));
} }
/* ------------------------- storage ----------------------------------- */ /* ------------------------- storage ----------------------------------- */

View File

@ -3,61 +3,58 @@ import { createSlice } from "@reduxjs/toolkit";
import mapRestPost from "../../utils/mapRestPost"; import mapRestPost from "../../utils/mapRestPost";
export const postsSlice = createSlice({ export const postsSlice = createSlice({
name: "posts", name: "posts",
initialState: [], // still an array initialState: [],
reducers: { reducers: {
/* full reload (initial screen) --------------------------------- */ /* full reload (initial screen) --------------------------------- */
postsLoaded: (_, action) => action.payload.map(mapRestPost), postsLoaded: (_state, action) =>
// API returns oldest → newest, so reverse once
/* incremental updates: insert new or patch existing ------------ */ action.payload.map(mapRestPost).reverse(),
postsUpdated: (state, action) => { /* incremental updates: insert new or patch existing ------------ */
const incoming = action.payload; // array of raw rows
incoming.forEach((raw) => { postsUpdated: (state, action) => {
const postID = raw.post_id ?? raw.postID; const incoming = action.payload; // array of raw rows
const idx = state.findIndex((p) => p.postID === postID); incoming.forEach((raw) => {
const postID = raw.post_id ?? raw.postID;
if (idx === -1) { const idx = state.findIndex((p) => p.postID === postID);
/* NEW */
state.push(mapRestPost(raw)); if (idx === -1) {
/* NEW → put at the front so list stays newest-first */
return; state.unshift(mapRestPost(raw));
}
/* MERGE PARTIAL UPDATE */ return;
}
const cur = state[idx]; /* MERGE PARTIAL UPDATE (order unchanged) ------------------ */
const next = { ...cur }; const cur = state[idx];
if (raw.text !== undefined) next.text = raw.text; if (raw.text !== undefined) cur.text = raw.text;
if (raw.photoURL !== undefined) next.photoURL = raw.photoURL; if (raw.photoURL !== undefined) cur.photoURL = raw.photoURL;
if (raw.youtubeURL !== undefined) next.youtubeURL = raw.youtubeURL; if (raw.youtubeURL !== undefined) cur.youtubeURL = raw.youtubeURL;
if (raw.isPhoto !== undefined) next.isPhoto = !!raw.isPhoto; if (raw.isPhoto !== undefined) cur.isPhoto = !!raw.isPhoto;
if (raw.isYoutube !== undefined) next.isYoutube = !!raw.isYoutube; if (raw.isYoutube !== undefined) cur.isYoutube = !!raw.isYoutube;
if (raw.comments !== undefined) if (raw.comments !== undefined) cur.comments = JSON.parse(raw.comments);
next.comments = JSON.parse(raw.comments);
if (raw.likes !== undefined) next.likes = JSON.parse(raw.likes); if (raw.likes !== undefined) cur.likes = JSON.parse(raw.likes);
if (raw.timestamp !== undefined) /* raw.timestamp never changes, so we leave it untouched */
next.timestamp = new Date(raw.timestamp); });
},
state[idx] = next; },
});
},
},
}); });
export const { postsLoaded, postsUpdated } = postsSlice.actions; export const { postsLoaded, postsUpdated } = postsSlice.actions;