Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add refresh button on main feed page #53

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions src/components/post/feed/feed-checker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import {
Component,
createMemo,
createResource,
onCleanup,
ResourceFetcherInfo,
Show,
} from "solid-js";
import { RequestHandler } from ".";
import { useFeedContext } from "./feed-context";
import { useSearchParams } from "@solidjs/router";
import { useAuthContext } from "~/lib/auth-context";
import { Button } from "~/components/ui/button";

export interface FeedCheckerProps {
checkHandler: RequestHandler;
delayMs: number;
}

interface NewPostTracker {
post_id?: string;
count: number;
}

export const FeedChecker: Component<FeedCheckerProps> = (props) => {
const feedContext = useFeedContext();
const authContext = useAuthContext();

// function to check for whether there are new posts, and update accordingly
const postChecker = async (cur: NewPostTracker) => {
let since_id = cur.post_id;
console.log(`Current post count: ${cur.count}`);
if (since_id == undefined) {
const newest_post = feedContext
.postList()
?.find((post) => post.pinned == false);
if (newest_post == undefined) {
console.warn("Unable to get latest post info");
return cur;
}
// Try to get newest post from the existing feed (excluding pinned)
since_id = newest_post.id;
}

const params = {
local: false,
limit: 25,
since_id: since_id,
};

let response = await props.checkHandler(authContext, params);
if (response == null) {
console.warn(
"While checking for new posts, got null from handler function"
);
return cur;
}

if (response.data.length > 0) {
const topLevelPosts = response.data.filter(
(post) =>
post.in_reply_to_id == null &&
post.reblog?.in_reply_to_id == null
);
console.log(`Found ${topLevelPosts.length} top-level posts`);
cur.count += topLevelPosts.length;
cur.post_id = response.data[0].id;
}
console.log(`Returning new count ${cur.count}`);
return cur;
};

// resource to call said post checker
const [newPostInfo, postInfoActions] = createResource(
() => {
return {
count: 0,
};
},
(cur: NewPostTracker, info: ResourceFetcherInfo<NewPostTracker>) =>
postChecker(info.value ?? cur)
);

const checkTimer = setInterval(() => {
if ((newPostInfo()?.count ?? 0) == 0) {
console.log("checking for new posts...");
postInfoActions.refetch();
}
}, props.delayMs);

onCleanup(() => {
console.log("cleaning up...");
clearInterval(checkTimer);
});

const newPosts = createMemo((last) => {
if (newPostInfo.loading) {
return last;
}

const postInfo = newPostInfo()!;
console.log(`newPostInfo exists! Count is ${postInfo.count}`);
return postInfo.count > 0;
}, false);

return (
<Show when={newPosts()}>
<div class="md:px-12">
<Button
variant="secondary"
class="w-full my-4"
onClick={() => {
feedContext.resetFeed();
postInfoActions.mutate({ count: 0 });
}}
>
{"New posts available. Click here to refresh."}
</Button>
</div>
</Show>
);
};
10 changes: 9 additions & 1 deletion src/components/post/feed/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import {
createSignal,
ErrorBoundary,
For,
Show,
} from "solid-js";
import { AuthProviderProps, useAuthContext } from "~/lib/auth-context";
import Post from "..";
import { PageNav } from "~/components/ui/page-footer";
import { Button } from "~/components/ui/button";
import { FeedContext } from "./feed-context";
import { FeedChecker } from "./feed-checker";

interface GetTimelineOptionsApi {
local?: boolean;
Expand All @@ -25,7 +27,7 @@ interface GetTimelineOptionsApi {

export interface GetTimelineOptions extends GetTimelineOptionsApi {}

type RequestHandler = (
export type RequestHandler = (
authContext: AuthProviderProps,
timelineOptions: GetTimelineOptions
) => Promise<Response<Array<Status>> | undefined> | undefined;
Expand Down Expand Up @@ -100,6 +102,12 @@ export const PostFeed: Component<PostFeedProps> = (props) => {
<FeedContext.Provider value={feedContext}>
<div>
<ErrorBoundary fallback={<div>Failed to load posts.</div>}>
<Show when={searchParams.after == null}>
<FeedChecker
delayMs={60000}
checkHandler={props.onRequest}
/>
</Show>
<For each={postList()}>
{(status, index) => (
<Post status={status} fetchShareParent={false} />
Expand Down
Loading