import { Component, linkEvent } from 'inferno';
import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs';
-import { retryWhen, delay, take } from 'rxjs/operators';
import {
UserOperation,
SiteResponse,
SiteConfigForm,
GetSiteConfigResponse,
WebSocketJsonResponse,
+ GetSiteConfig,
} from 'lemmy-js-client';
import { WebSocketService } from '../services';
-import { wsJsonToRes, capitalizeFirstLetter, toast, randomStr } from '../utils';
+import {
+ wsJsonToRes,
+ capitalizeFirstLetter,
+ toast,
+ randomStr,
+ setIsoData,
+ wsSubscribe,
+ isBrowser,
+ lemmyHttp,
+ setAuth,
+} from '../utils';
import autosize from 'autosize';
import { SiteForm } from './site-form';
import { UserListing } from './user-listing';
export class AdminSettings extends Component<any, AdminSettingsState> {
private siteConfigTextAreaId = `site-config-${randomStr()}`;
+ private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: AdminSettingsState = {
- siteRes: {
- site: {
- id: null,
- name: null,
- creator_id: null,
- creator_name: null,
- published: null,
- number_of_users: null,
- number_of_posts: null,
- number_of_comments: null,
- number_of_communities: null,
- enable_downvotes: null,
- open_registration: null,
- enable_nsfw: null,
- },
- admins: [],
- banned: [],
- online: null,
- version: null,
- federated_instances: null,
- },
+ siteRes: this.isoData.site,
siteConfigForm: {
config_hjson: null,
auth: null,
this.state = this.emptyState;
- this.subscription = WebSocketService.Instance.subject
- .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
- .subscribe(
- msg => this.parseMessage(msg),
- err => console.error(err),
- () => console.log('complete')
- );
+ this.parseMessage = this.parseMessage.bind(this);
+ this.subscription = wsSubscribe(this.parseMessage);
+
+ // Only fetch the data if coming from another route
+ if (this.isoData.path == this.context.router.route.match.url) {
+ this.state.siteConfigRes = this.isoData.routeData[0];
+ this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
+ this.state.siteConfigLoading = false;
+ this.state.loading = false;
+ } else {
+ WebSocketService.Instance.getSiteConfig();
+ }
+ }
- WebSocketService.Instance.getSite();
- WebSocketService.Instance.getSiteConfig();
+ static fetchInitialData(auth: string, _path: string): Promise<any>[] {
+ let form: GetSiteConfig = {};
+ setAuth(form, auth);
+ return [lemmyHttp.getSiteConfig(form)];
+ }
+
+ componentDidMount() {
+ if (isBrowser()) {
+ var textarea: any = document.getElementById(this.siteConfigTextAreaId);
+ autosize(textarea);
+ }
}
componentWillUnmount() {
- this.subscription.unsubscribe();
+ if (isBrowser()) {
+ this.subscription.unsubscribe();
+ }
}
get documentTitle(): string {
- if (this.state.siteRes.site.name) {
- return `${i18n.t('admin_settings')} - ${this.state.siteRes.site.name}`;
- } else {
- return 'Lemmy';
- }
+ return `${i18n.t('admin_settings')} - ${this.state.siteRes.site.name}`;
}
render() {
this.setState(this.state);
return;
} else if (msg.reconnect) {
- } else if (res.op == UserOperation.GetSite) {
- let data = res.data as GetSiteResponse;
-
- // This means it hasn't been set up yet
- if (!data.site) {
- this.context.router.history.push('/setup');
- }
- this.state.siteRes = data;
- this.setState(this.state);
} else if (res.op == UserOperation.EditSite) {
let data = res.data as SiteResponse;
this.state.siteRes.site = data.site;
import { Helmet } from 'inferno-helmet';
import { Link } from 'inferno-router';
import { Subscription } from 'rxjs';
-import { retryWhen, delay, take } from 'rxjs/operators';
import {
UserOperation,
GetModlogForm,
ModAddCommunity,
ModAdd,
WebSocketJsonResponse,
- GetSiteResponse,
Site,
} from 'lemmy-js-client';
import { WebSocketService } from '../services';
-import { wsJsonToRes, addTypeInfo, fetchLimit, toast } from '../utils';
+import {
+ wsJsonToRes,
+ addTypeInfo,
+ fetchLimit,
+ toast,
+ setIsoData,
+ wsSubscribe,
+ isBrowser,
+ lemmyHttp,
+} from '../utils';
import { MomentTime } from './moment-time';
import moment from 'moment';
import { i18n } from '../i18next';
}
export class Modlog extends Component<any, ModlogState> {
+ private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: ModlogState = {
combined: [],
page: 1,
loading: true,
- site: undefined,
+ site: this.isoData.site.site,
};
constructor(props: any, context: any) {
this.state.communityId = this.props.match.params.community_id
? Number(this.props.match.params.community_id)
: undefined;
- this.subscription = WebSocketService.Instance.subject
- .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
- .subscribe(
- msg => this.parseMessage(msg),
- err => console.error(err),
- () => console.log('complete')
- );
- this.refetch();
- WebSocketService.Instance.getSite();
+ this.parseMessage = this.parseMessage.bind(this);
+ this.subscription = wsSubscribe(this.parseMessage);
+
+ // Only fetch the data if coming from another route
+ if (this.isoData.path == this.context.router.route.match.url) {
+ let data = this.isoData.routeData[0];
+ this.setCombined(data);
+ this.state.loading = false;
+ } else {
+ this.refetch();
+ }
}
componentWillUnmount() {
- this.subscription.unsubscribe();
+ if (isBrowser()) {
+ this.subscription.unsubscribe();
+ }
}
setCombined(res: GetModlogResponse) {
this.state.combined.sort((a, b) =>
b.data.when_.localeCompare(a.data.when_)
);
-
- this.setState(this.state);
}
combined() {
WebSocketService.Instance.getModlog(modlogForm);
}
+ static fetchInitialData(_auth: string, path: string): Promise<any>[] {
+ let pathSplit = path.split('/');
+ let communityId = pathSplit[3];
+ let promises: Promise<any>[] = [];
+
+ let modlogForm: GetModlogForm = {
+ page: 1,
+ limit: fetchLimit,
+ };
+
+ if (communityId) {
+ modlogForm.community_id = Number(communityId);
+ }
+
+ promises.push(lemmyHttp.getModlog(modlogForm));
+ return promises;
+ }
+
parseMessage(msg: WebSocketJsonResponse) {
console.log(msg);
let res = wsJsonToRes(msg);
this.state.loading = false;
window.scrollTo(0, 0);
this.setCombined(data);
- } else if (res.op == UserOperation.GetSite) {
- let data = res.data as GetSiteResponse;
- this.state.site = data.site;
this.setState(this.state);
}
}
import { Component, linkEvent } from 'inferno';
import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs';
-import { retryWhen, delay, take } from 'rxjs/operators';
import {
UserOperation,
Post,
PostResponse,
CommentResponse,
WebSocketJsonResponse,
- GetSiteResponse,
Site,
} from 'lemmy-js-client';
import { WebSocketService } from '../services';
createCommentLikeRes,
createPostLikeFindRes,
commentsToFlatNodes,
- getPageFromProps,
+ setIsoData,
+ wsSubscribe,
+ lemmyHttp,
+ setAuth,
} from '../utils';
import { PostListing } from './post-listing';
import { UserListing } from './user-listing';
import { CommentNodes } from './comment-nodes';
import { i18n } from '../i18next';
-interface SearchState {
+interface SearchProps {
q: string;
type_: SearchType;
sort: SortType;
page: number;
- searchResponse: SearchResponse;
- loading: boolean;
- site: Site;
- searchText: string;
}
-interface SearchProps {
+interface SearchState {
q: string;
type_: SearchType;
sort: SortType;
page: number;
+ searchResponse: SearchResponse;
+ loading: boolean;
+ site: Site;
+ searchText: string;
}
interface UrlParams {
}
export class Search extends Component<any, SearchState> {
+ private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: SearchState = {
- q: Search.getSearchQueryFromProps(this.props),
- type_: Search.getSearchTypeFromProps(this.props),
- sort: Search.getSortTypeFromProps(this.props),
- page: getPageFromProps(this.props),
- searchText: Search.getSearchQueryFromProps(this.props),
+ q: Search.getSearchQueryFromProps(this.props.match.params.q),
+ type_: Search.getSearchTypeFromProps(this.props.match.params.type),
+ sort: Search.getSortTypeFromProps(this.props.match.params.sort),
+ page: Search.getPageFromProps(this.props.match.params.page),
+ searchText: Search.getSearchQueryFromProps(this.props.match.params.q),
searchResponse: {
type_: null,
posts: [],
users: [],
},
loading: false,
- site: {
- id: undefined,
- name: undefined,
- creator_id: undefined,
- published: undefined,
- creator_name: undefined,
- number_of_users: undefined,
- number_of_posts: undefined,
- number_of_comments: undefined,
- number_of_communities: undefined,
- enable_downvotes: undefined,
- open_registration: undefined,
- enable_nsfw: undefined,
- },
+ site: this.isoData.site.site,
};
- static getSearchQueryFromProps(props: any): string {
- return props.match.params.q ? props.match.params.q : '';
+ static getSearchQueryFromProps(q: string): string {
+ return q || '';
+ }
+
+ static getSearchTypeFromProps(type_: string): SearchType {
+ return type_ ? routeSearchTypeToEnum(type_) : SearchType.All;
}
- static getSearchTypeFromProps(props: any): SearchType {
- return props.match.params.type
- ? routeSearchTypeToEnum(props.match.params.type)
- : SearchType.All;
+ static getSortTypeFromProps(sort: string): SortType {
+ return sort ? routeSortTypeToEnum(sort) : SortType.TopAll;
}
- static getSortTypeFromProps(props: any): SortType {
- return props.match.params.sort
- ? routeSortTypeToEnum(props.match.params.sort)
- : SortType.TopAll;
+ static getPageFromProps(page: string): number {
+ return page ? Number(page) : 1;
}
constructor(props: any, context: any) {
this.state = this.emptyState;
this.handleSortChange = this.handleSortChange.bind(this);
- this.subscription = WebSocketService.Instance.subject
- .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
- .subscribe(
- msg => this.parseMessage(msg),
- err => console.error(err),
- () => console.log('complete')
- );
+ this.parseMessage = this.parseMessage.bind(this);
+ this.subscription = wsSubscribe(this.parseMessage);
- WebSocketService.Instance.getSite();
-
- if (this.state.q) {
- this.search();
+ // Only fetch the data if coming from another route
+ if (this.state.q != '') {
+ if (this.isoData.path == this.context.router.route.match.url) {
+ this.state.searchResponse = this.isoData.routeData[0];
+ this.state.loading = false;
+ } else {
+ this.search();
+ }
}
}
static getDerivedStateFromProps(props: any): SearchProps {
return {
- q: Search.getSearchQueryFromProps(props),
- type_: Search.getSearchTypeFromProps(props),
- sort: Search.getSortTypeFromProps(props),
- page: getPageFromProps(props),
+ q: Search.getSearchQueryFromProps(props.match.params.q),
+ type_: Search.getSearchTypeFromProps(props.match.params.type),
+ sort: Search.getSortTypeFromProps(props.match.params.sort),
+ page: Search.getPageFromProps(props.match.params.page),
};
}
+ static fetchInitialData(auth: string, path: string): Promise<any>[] {
+ let pathSplit = path.split('/');
+ let promises: Promise<any>[] = [];
+
+ let form: SearchForm = {
+ q: this.getSearchQueryFromProps(pathSplit[3]),
+ type_: this.getSearchTypeFromProps(pathSplit[5]),
+ sort: this.getSortTypeFromProps(pathSplit[7]),
+ page: this.getPageFromProps(pathSplit[9]),
+ limit: fetchLimit,
+ };
+ setAuth(form, auth);
+
+ if (form.q != '') {
+ promises.push(lemmyHttp.search(form));
+ }
+
+ return promises;
+ }
+
componentDidUpdate(_: any, lastState: SearchState) {
if (
lastState.q !== this.state.q ||
<div class="col-12">
{i.type_ == 'posts' && (
<PostListing
+ communities={[]}
key={(i.data as Post).id}
post={i.data as Post}
showCommunity
<div class="row">
<div class="col-12">
<PostListing
+ communities={[]}
post={post}
showCommunity
enableDownvotes={this.state.site.enable_downvotes}
let data = res.data as PostResponse;
createPostLikeFindRes(data, this.state.searchResponse.posts);
this.setState(this.state);
- } else if (res.op == UserOperation.GetSite) {
- let data = res.data as GetSiteResponse;
- this.state.site = data.site;
- this.setState(this.state);
}
}
}
}
get documentTitle(): string {
- if (this.state.site) {
- return `${i18n.t('sponsors')} - ${this.state.site.name}`;
- } else {
- return 'Lemmy';
- }
+ return `${i18n.t('sponsors')} - ${this.state.site.name}`;
}
render() {
{
path: `/modlog/community/:community_id`,
component: Modlog,
+ fetchInitialData: (auth, path) => Modlog.fetchInitialData(auth, path),
+ },
+ {
+ path: `/modlog`,
+ component: Modlog,
+ fetchInitialData: (auth, path) => Modlog.fetchInitialData(auth, path),
},
- { path: `/modlog`, component: Modlog },
{ path: `/setup`, component: Setup },
- { path: `/admin`, component: AdminSettings },
+ {
+ path: `/admin`,
+ component: AdminSettings,
+ fetchInitialData: (auth, path) =>
+ AdminSettings.fetchInitialData(auth, path),
+ },
{
path: `/search/q/:q/type/:type/sort/:sort/page/:page`,
component: Search,
+ fetchInitialData: (auth, path) => Search.fetchInitialData(auth, path),
+ },
+ {
+ path: `/search`,
+ component: Search,
+ fetchInitialData: (auth, path) => Search.fetchInitialData(auth, path),
},
- { path: `/search`, component: Search },
{ path: `/sponsors`, component: Sponsors },
{
path: `/password_change/:token`,
}
export function routeSearchTypeToEnum(type: string): SearchType {
- return SearchType[capitalizeFirstLetter(type)];
+ return SearchType[type];
}
export async function getPageTitle(url: string) {