mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-26 06:11:15 +00:00
Fix first loads not working
This commit is contained in:
parent
2a16c85ed0
commit
71336002e7
7 changed files with 73 additions and 80 deletions
13
package.json
13
package.json
|
@ -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",
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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>>;
|
||||||
|
|
|
@ -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>>[] = [
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue