Fix first loads not working

This commit is contained in:
abias 2023-06-16 18:12:14 -04:00
parent 2a16c85ed0
commit 71336002e7
7 changed files with 73 additions and 80 deletions

View file

@ -17,9 +17,16 @@
"start": "yarn build:dev --watch" "start": "yarn build:dev --watch"
}, },
"lint-staged": { "lint-staged": {
"*.{ts,tsx,js}": ["prettier --write", "eslint --fix"], "*.{ts,tsx,js}": [
"*.{css, scss}": ["prettier --write"], "prettier --write",
"package.json": ["sortpack"] "eslint --fix"
],
"*.{css, scss}": [
"prettier --write"
],
"package.json": [
"sortpack"
]
}, },
"dependencies": { "dependencies": {
"@babel/plugin-proposal-decorators": "^7.21.0", "@babel/plugin-proposal-decorators": "^7.21.0",

View file

@ -17,13 +17,10 @@ import {
ILemmyConfig, ILemmyConfig,
InitialFetchRequest, InitialFetchRequest,
IsoDataOptionalSite, IsoDataOptionalSite,
RouteData,
} from "../shared/interfaces"; } from "../shared/interfaces";
import { routes } from "../shared/routes"; import { routes } from "../shared/routes";
import { import { FailedRequestState, wrapClient } from "../shared/services/HttpService";
FailedRequestState,
RequestState,
wrapClient,
} from "../shared/services/HttpService";
import { import {
ErrorPageData, ErrorPageData,
favIconPngUrl, favIconPngUrl,
@ -140,7 +137,7 @@ server.get("/*", async (req, res) => {
// This bypasses errors, so that the client can hit the error on its own, // This bypasses errors, so that the client can hit the error on its own,
// in order to remove the jwt on the browser. Necessary for wrong jwts // in order to remove the jwt on the browser. Necessary for wrong jwts
let site: GetSiteResponse | undefined = undefined; let site: GetSiteResponse | undefined = undefined;
let routeData: Record<string, RequestState<any>> = {}; let routeData: RouteData = {};
let errorPageData: ErrorPageData | undefined = undefined; let errorPageData: ErrorPageData | undefined = undefined;
let try_site = await client.getSite(getSiteForm); let try_site = await client.getSite(getSiteForm);
if (try_site.state === "failed" && try_site.msg == "not_logged_in") { if (try_site.state === "failed" && try_site.msg == "not_logged_in") {
@ -164,7 +161,7 @@ server.get("/*", async (req, res) => {
return res.redirect("/setup"); return res.redirect("/setup");
} }
if (site) { if (site && activeRoute?.fetchInitialData) {
const initialFetchReq: InitialFetchRequest = { const initialFetchReq: InitialFetchRequest = {
client, client,
auth, auth,
@ -173,19 +170,7 @@ server.get("/*", async (req, res) => {
site, site,
}; };
if (activeRoute?.fetchInitialData) { routeData = await activeRoute.fetchInitialData(initialFetchReq);
const routeDataKeysAndVals = await Promise.all(
Object.entries(activeRoute.fetchInitialData(initialFetchReq)).map(
async ([key, val]) => [key, await val]
)
);
routeData = routeDataKeysAndVals.reduce((acc, [key, val]) => {
acc[key] = val;
return acc;
}, {});
}
} }
} else if (try_site.state === "failed") { } else if (try_site.state === "failed") {
errorPageData = getErrorPageData(new Error(try_site.msg), site); errorPageData = getErrorPageData(new Error(try_site.msg), site);

View file

@ -124,6 +124,39 @@ type HomeData = RouteDataResponse<{
trendingCommunitiesRes: ListCommunitiesResponse; trendingCommunitiesRes: ListCommunitiesResponse;
}>; }>;
function getRss(listingType: ListingType) {
const { sort } = getHomeQueryParams();
const auth = myAuth();
let rss: string | undefined = undefined;
switch (listingType) {
case "All": {
rss = `/feeds/all.xml?sort=${sort}`;
break;
}
case "Local": {
rss = `/feeds/local.xml?sort=${sort}`;
break;
}
case "Subscribed": {
rss = auth ? `/feeds/front/${auth}.xml?sort=${sort}` : undefined;
break;
}
}
return (
rss && (
<>
<a href={rss} rel={relTags} title="RSS">
<Icon icon="rss" classes="text-muted small" />
</a>
<link rel="alternate" type="application/atom+xml" href={rss} />
</>
)
);
}
function getDataTypeFromQuery(type?: string): DataType { function getDataTypeFromQuery(type?: string): DataType {
return type ? DataType[type] : DataType.Post; return type ? DataType[type] : DataType.Post;
} }
@ -235,11 +268,8 @@ export class Home extends Component<any, HomeState> {
// Only fetch the data if coming from another route // Only fetch the data if coming from another route
if (FirstLoadService.isFirstLoad) { if (FirstLoadService.isFirstLoad) {
const { const { trendingCommunitiesRes, commentsRes, postsRes } =
trendingCommunitiesRes: trendingCommunitiesRes, this.isoData.routeData;
commentsRes: commentsRes,
postsRes: postsRes,
} = this.isoData.routeData;
this.state = { this.state = {
...this.state, ...this.state,
@ -360,7 +390,7 @@ export class Home extends Component<any, HomeState> {
></div> ></div>
)} )}
<div className="d-block d-md-none">{this.mobileView}</div> <div className="d-block d-md-none">{this.mobileView}</div>
{this.posts()} {this.posts}
</main> </main>
<aside className="d-none d-md-block col-md-4"> <aside className="d-none d-md-block col-md-4">
{this.mySidebar} {this.mySidebar}
@ -575,7 +605,7 @@ export class Home extends Component<any, HomeState> {
await this.fetchData(); await this.fetchData();
} }
posts() { get posts() {
const { page } = getHomeQueryParams(); const { page } = getHomeQueryParams();
return ( return (
@ -594,7 +624,7 @@ export class Home extends Component<any, HomeState> {
const siteRes = this.state.siteRes; const siteRes = this.state.siteRes;
if (dataType === DataType.Post) { if (dataType === DataType.Post) {
switch (this.state.postsRes?.state) { switch (this.state.postsRes.state) {
case "loading": case "loading":
return ( return (
<h5> <h5>
@ -700,44 +730,11 @@ export class Home extends Component<any, HomeState> {
<span className="mr-2"> <span className="mr-2">
<SortSelect sort={sort} onChange={this.handleSortChange} /> <SortSelect sort={sort} onChange={this.handleSortChange} />
</span> </span>
{this.getRss(listingType)} {getRss(listingType)}
</div> </div>
); );
} }
getRss(listingType: ListingType) {
const { sort } = getHomeQueryParams();
const auth = myAuth();
let rss: string | undefined = undefined;
switch (listingType) {
case "All": {
rss = `/feeds/all.xml?sort=${sort}`;
break;
}
case "Local": {
rss = `/feeds/local.xml?sort=${sort}`;
break;
}
case "Subscribed": {
rss = auth ? `/feeds/front/${auth}.xml?sort=${sort}` : undefined;
break;
}
}
return (
rss && (
<>
<a href={rss} rel={relTags} title="RSS">
<Icon icon="rss" classes="text-muted small" />
</a>
<link rel="alternate" type="application/atom+xml" href={rss} />
</>
)
);
}
async fetchTrendingCommunities() { async fetchTrendingCommunities() {
this.setState({ trendingCommunitiesRes: { state: "loading" } }); this.setState({ trendingCommunitiesRes: { state: "loading" } });
this.setState({ this.setState({

View file

@ -35,7 +35,7 @@ export interface CreatePostProps {
} }
type CreatePostData = RouteDataResponse<{ type CreatePostData = RouteDataResponse<{
communityResponse?: GetCommunityResponse; communityResponse: GetCommunityResponse;
initialCommunitiesRes: ListCommunitiesResponse; initialCommunitiesRes: ListCommunitiesResponse;
}>; }>;
@ -244,6 +244,7 @@ export class CreatePost extends Component<
>): Promise<CreatePostData> { >): Promise<CreatePostData> {
const data: CreatePostData = { const data: CreatePostData = {
initialCommunitiesRes: await fetchCommunitiesForOptions(client), initialCommunitiesRes: await fetchCommunitiesForOptions(client),
communityResponse: { state: "empty" },
}; };
if (communityId) { if (communityId) {

View file

@ -6,16 +6,16 @@ import { ErrorPageData } from "./utils";
/** /**
* This contains serialized data, it needs to be deserialized before use. * This contains serialized data, it needs to be deserialized before use.
*/ */
export interface IsoData<T extends Record<string, RequestState<any>> = any> { export interface IsoData<T extends RouteData = any> {
path: string; path: string;
routeData: T; routeData: T;
site_res: GetSiteResponse; site_res: GetSiteResponse;
errorPageData?: ErrorPageData; errorPageData?: ErrorPageData;
} }
export type IsoDataOptionalSite< export type IsoDataOptionalSite<T extends RouteData = any> = Partial<
T extends Record<string, RequestState<any>> = any IsoData<T>
> = Partial<IsoData<T>> & > &
Pick<IsoData<T>, Exclude<keyof IsoData<T>, "site_res">>; Pick<IsoData<T>, Exclude<keyof IsoData<T>, "site_res">>;
export interface ILemmyConfig { export interface ILemmyConfig {
@ -82,3 +82,5 @@ export interface CommentNodeI {
children: Array<CommentNodeI>; children: Array<CommentNodeI>;
depth: number; depth: number;
} }
export type RouteData = Record<string, RequestState<any>>;

View file

@ -21,13 +21,10 @@ import { CreatePost } from "./components/post/create-post";
import { Post } from "./components/post/post"; import { Post } from "./components/post/post";
import { CreatePrivateMessage } from "./components/private_message/create-private-message"; import { CreatePrivateMessage } from "./components/private_message/create-private-message";
import { Search } from "./components/search"; import { Search } from "./components/search";
import { InitialFetchRequest } from "./interfaces"; import { InitialFetchRequest, RouteData } from "./interfaces";
import { RequestState } from "./services/HttpService";
interface IRoutePropsWithFetch<T extends Record<string, RequestState<any>>> interface IRoutePropsWithFetch<T extends RouteData> extends IRouteProps {
extends IRouteProps { fetchInitialData?(req: InitialFetchRequest): Promise<T>;
// TODO Make sure this one is good.
fetchInitialData?(req: InitialFetchRequest): T;
} }
export const routes: IRoutePropsWithFetch<Record<string, any>>[] = [ export const routes: IRoutePropsWithFetch<Record<string, any>>[] = [

View file

@ -43,7 +43,13 @@ import tippy from "tippy.js";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import { getHttpBase } from "./env"; import { getHttpBase } from "./env";
import { i18n, languages } from "./i18next"; import { i18n, languages } from "./i18next";
import { CommentNodeI, DataType, IsoData, VoteType } from "./interfaces"; import {
CommentNodeI,
DataType,
IsoData,
RouteData,
VoteType,
} from "./interfaces";
import { HttpService, UserService } from "./services"; import { HttpService, UserService } from "./services";
import { RequestState } from "./services/HttpService"; import { RequestState } from "./services/HttpService";
@ -1166,9 +1172,7 @@ export function isBrowser() {
return typeof window !== "undefined"; return typeof window !== "undefined";
} }
export function setIsoData<T extends Record<string, RequestState<any>>>( export function setIsoData<T extends RouteData>(context: any): IsoData<T> {
context: any
): IsoData<T> {
// If its the browser, you need to deserialize the data from the window // If its the browser, you need to deserialize the data from the window
if (isBrowser()) { if (isBrowser()) {
return window.isoData; return window.isoData;