Make posts appear in feed
This commit is contained in:
parent
187bc6fde2
commit
e35464dcfa
|
@ -8,7 +8,7 @@ import outgoingMessagesReducer from "../features/outgoingMessages/outgoingMessag
|
|||
import linkReducer from "../features/link/linkSlice";
|
||||
import accountPageReducer from "../features/accountPage/accountPageSlice";
|
||||
|
||||
export default configureStore({
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
user: userReducer,
|
||||
currentUser: currentUserReducer,
|
||||
|
@ -20,3 +20,17 @@ export default configureStore({
|
|||
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;
|
||||
|
|
|
@ -22,7 +22,7 @@ import { currentUserUpdated } from "../features/currentUser/currentUserSlice";
|
|||
|
||||
import { usersUpdated } from "../features/users/usersSlice";
|
||||
|
||||
import { postsUpdated } from "../features/posts/postsSlice";
|
||||
import { postsLoaded, postsUpdated } from "../features/posts/postsSlice";
|
||||
|
||||
import { incomingMessagesUpdated } from "../features/incomingMessages/incomingMessagesSlice";
|
||||
|
||||
|
@ -40,6 +40,8 @@ const LOGIN_URL = `${API_BASE}/login`;
|
|||
|
||||
const USERS_URL = `${API_BASE}/users`;
|
||||
|
||||
const POSTS_URL = `${API_BASE}/posts`;
|
||||
|
||||
const LS_TOKEN = "fakebook.jwt";
|
||||
|
||||
const LS_USER_ID = "fakebook.user_id";
|
||||
|
@ -149,6 +151,16 @@ export function subscribeAuth() {
|
|||
isEmailVerified: !!u.isEmailVerified,
|
||||
})
|
||||
);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// cold-start: get the full feed once
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
subscribePosts(); // <—— fetches /posts and dispatches postsLoaded
|
||||
|
||||
currentUserOnline(); // mark myself online immediately
|
||||
} catch (err) {
|
||||
console.warn("[Auth] subscribeAuth failed:", err.message);
|
||||
|
||||
|
@ -229,6 +241,8 @@ export async function signInUser(user) {
|
|||
);
|
||||
|
||||
store.dispatch(errorOccured(""));
|
||||
|
||||
currentUserOnline(); // mark myself online immediately
|
||||
} catch (err) {
|
||||
store.dispatch(errorOccured(err.message));
|
||||
|
||||
|
@ -314,6 +328,14 @@ function openSocket() {
|
|||
hub.on("fakebook.users.put", (raw) => {
|
||||
store.dispatch(usersUpdated([parseMsg(raw)]));
|
||||
});
|
||||
|
||||
hub.on("fakebook.posts.post", (raw) =>
|
||||
store.dispatch(postsUpdated([JSON.parse(raw)]))
|
||||
);
|
||||
|
||||
hub.on("fakebook.posts.put", (raw) =>
|
||||
store.dispatch(postsUpdated([JSON.parse(raw)]))
|
||||
);
|
||||
})
|
||||
|
||||
.catch((err) => {
|
||||
|
@ -510,21 +532,36 @@ export function subscribeUsers() {
|
|||
};
|
||||
}
|
||||
|
||||
/* ------------------------- posts ------------------------------------- */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
/* posts subscription: replaces old in-memory mock version */
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
export function subscribePosts() {
|
||||
setTimeout(() => {
|
||||
store.dispatch(
|
||||
postsUpdated(
|
||||
DB.posts.map((p) => ({
|
||||
...p,
|
||||
timestamp: new Date(p.timestamp).toLocaleString(),
|
||||
}))
|
||||
)
|
||||
);
|
||||
}, 0);
|
||||
let cancelled = false;
|
||||
|
||||
return () => {};
|
||||
(async () => {
|
||||
try {
|
||||
const token = localStorage.getItem(LS_TOKEN);
|
||||
|
||||
const arr = await $fetch(`${POSTS_URL}?limit=-1`, {
|
||||
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
||||
});
|
||||
|
||||
if (!cancelled) {
|
||||
store.dispatch(postsLoaded(arr)); // full list once
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("[subscribePosts] failed:", err.message);
|
||||
}
|
||||
})();
|
||||
|
||||
/* return unsubscribe fn (keeps contract identical) */
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}
|
||||
|
||||
export async function upload(post) {
|
||||
|
|
|
@ -1,17 +1,65 @@
|
|||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
import mapRestPost from "../../utils/mapRestPost";
|
||||
|
||||
export const postsSlice = createSlice({
|
||||
name: "posts",
|
||||
initialState: [],
|
||||
|
||||
initialState: [], // still an array
|
||||
|
||||
reducers: {
|
||||
/* full reload (initial screen) --------------------------------- */
|
||||
|
||||
postsLoaded: (_, action) => action.payload.map(mapRestPost),
|
||||
|
||||
/* incremental updates: insert new or patch existing ------------ */
|
||||
|
||||
postsUpdated: (state, action) => {
|
||||
const updatedState = [];
|
||||
action.payload.forEach((post) => updatedState.push(post));
|
||||
return updatedState;
|
||||
const incoming = action.payload; // array of raw rows
|
||||
|
||||
incoming.forEach((raw) => {
|
||||
const postID = raw.post_id ?? raw.postID;
|
||||
|
||||
const idx = state.findIndex((p) => p.postID === postID);
|
||||
|
||||
if (idx === -1) {
|
||||
/* NEW */
|
||||
|
||||
state.push(mapRestPost(raw));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* MERGE PARTIAL UPDATE */
|
||||
|
||||
const cur = state[idx];
|
||||
|
||||
const next = { ...cur };
|
||||
|
||||
if (raw.text !== undefined) next.text = raw.text;
|
||||
|
||||
if (raw.photoURL !== undefined) next.photoURL = raw.photoURL;
|
||||
|
||||
if (raw.youtubeURL !== undefined) next.youtubeURL = raw.youtubeURL;
|
||||
|
||||
if (raw.isPhoto !== undefined) next.isPhoto = !!raw.isPhoto;
|
||||
|
||||
if (raw.isYoutube !== undefined) next.isYoutube = !!raw.isYoutube;
|
||||
|
||||
if (raw.comments !== undefined)
|
||||
next.comments = JSON.parse(raw.comments);
|
||||
|
||||
if (raw.likes !== undefined) next.likes = JSON.parse(raw.likes);
|
||||
|
||||
if (raw.timestamp !== undefined)
|
||||
next.timestamp = new Date(raw.timestamp);
|
||||
|
||||
state[idx] = next;
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { postsUpdated } = postsSlice.actions;
|
||||
export const { postsLoaded, postsUpdated } = postsSlice.actions;
|
||||
|
||||
export default postsSlice.reducer;
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* Converts the “Magic / Firebase” row into the shape the UI expects.
|
||||
|
||||
– comments / likes arrive as JSON-encoded strings
|
||||
|
||||
– timestamp comes as “2025-03-18 14:18:43” (UTC); we store it as Date
|
||||
|
||||
– isPhoto / isYoutube arrive as 0|1 (or false|true) → boolean
|
||||
|
||||
*/
|
||||
|
||||
export default function mapRestPost(row) {
|
||||
/* helper – coerce all falsy / 0 / "0" / false values to boolean */
|
||||
|
||||
const bool = (v) => v === true || v === 1 || v === "1";
|
||||
|
||||
return {
|
||||
postID: row.post_id,
|
||||
|
||||
userID: row.user_id,
|
||||
|
||||
text: row.text,
|
||||
|
||||
photoURL: row.photoURL,
|
||||
|
||||
youtubeURL: row.youtubeURL,
|
||||
|
||||
isPhoto: bool(row.isPhoto),
|
||||
|
||||
isYoutube: bool(row.isYoutube),
|
||||
|
||||
comments: JSON.parse(row.comments || "[]"),
|
||||
|
||||
likes: JSON.parse(row.likes || "[]"),
|
||||
|
||||
/* keep the original ISO string too if you need it elsewhere */
|
||||
|
||||
timestamp: new Date(row.timestamp).toLocaleString(),
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue