Create community, Create post, and instances pages done.

This commit is contained in:
Dessalines 2020-09-07 17:24:48 -05:00
parent cde3c266f2
commit a5aeba3ad0
9 changed files with 308 additions and 324 deletions

View file

@ -52,13 +52,16 @@ export class Communities extends Component<any, CommunitiesState> {
constructor(props: any, context: any) { constructor(props: any, context: any) {
super(props, context); super(props, context);
this.state = this.emptyState; this.state = this.emptyState;
this.parseMessage = this.parseMessage.bind(this);
this.parseMessage = this.parseMessage.bind(this);
this.subscription = wsSubscribe(this.parseMessage); this.subscription = wsSubscribe(this.parseMessage);
// Only fetch the data if coming from another route // Only fetch the data if coming from another route
if (this.isoData.path == this.context.router.route.match.url) { if (this.isoData.path == this.context.router.route.match.url) {
this.state.communities = this.isoData.routeData[0].communities; this.state.communities = this.isoData.routeData[0].communities;
this.state.communities.sort(
(a, b) => b.number_of_subscribers - a.number_of_subscribers
);
this.state.loading = false; this.state.loading = false;
} else { } else {
this.refetch(); this.refetch();

View file

@ -6,7 +6,6 @@ import {
CommunityForm as CommunityFormI, CommunityForm as CommunityFormI,
UserOperation, UserOperation,
Category, Category,
ListCategoriesResponse,
CommunityResponse, CommunityResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
Community, Community,
@ -20,6 +19,7 @@ import { ImageUploadForm } from './image-upload-form';
interface CommunityFormProps { interface CommunityFormProps {
community?: Community; // If a community is given, that means this is an edit community?: Community; // If a community is given, that means this is an edit
categories: Category[];
onCancel?(): any; onCancel?(): any;
onCreate?(community: Community): any; onCreate?(community: Community): any;
onEdit?(community: Community): any; onEdit?(community: Community): any;
@ -28,7 +28,6 @@ interface CommunityFormProps {
interface CommunityFormState { interface CommunityFormState {
communityForm: CommunityFormI; communityForm: CommunityFormI;
categories: Category[];
loading: boolean; loading: boolean;
} }
@ -43,12 +42,11 @@ export class CommunityForm extends Component<
communityForm: { communityForm: {
name: null, name: null,
title: null, title: null,
category_id: null, category_id: this.props.categories[0].id,
nsfw: false, nsfw: false,
icon: null, icon: null,
banner: null, banner: null,
}, },
categories: [],
loading: false, loading: false,
}; };
@ -88,8 +86,6 @@ export class CommunityForm extends Component<
err => console.error(err), err => console.error(err),
() => console.log('complete') () => console.log('complete')
); );
WebSocketService.Instance.listCategories();
} }
componentDidUpdate() { componentDidUpdate() {
@ -218,7 +214,7 @@ export class CommunityForm extends Component<
value={this.state.communityForm.category_id} value={this.state.communityForm.category_id}
onInput={linkEvent(this, this.handleCommunityCategoryChange)} onInput={linkEvent(this, this.handleCommunityCategoryChange)}
> >
{this.state.categories.map(category => ( {this.props.categories.map(category => (
<option value={category.id}>{category.name}</option> <option value={category.id}>{category.name}</option>
))} ))}
</select> </select>
@ -344,13 +340,6 @@ export class CommunityForm extends Component<
this.state.loading = false; this.state.loading = false;
this.setState(this.state); this.setState(this.state);
return; return;
} else if (res.op == UserOperation.ListCategories) {
let data = res.data as ListCategoriesResponse;
this.state.categories = data.categories;
if (!this.props.community) {
this.state.communityForm.category_id = data.categories[0].id;
}
this.setState(this.state);
} else if (res.op == UserOperation.CreateCommunity) { } else if (res.op == UserOperation.CreateCommunity) {
let data = res.data as CommunityResponse; let data = res.data as CommunityResponse;
this.state.loading = false; this.state.loading = false;

View file

@ -1,87 +1,95 @@
import { Component } from 'inferno'; import { Component } from 'inferno';
import { Helmet } from 'inferno-helmet'; import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators';
import { CommunityForm } from './community-form'; import { CommunityForm } from './community-form';
import { import {
Community, Community,
UserOperation, UserOperation,
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse,
Site, Site,
ListCategoriesResponse,
Category,
} from 'lemmy-js-client'; } from 'lemmy-js-client';
import { toast, wsJsonToRes } from '../utils'; import {
setIsoData,
toast,
wsJsonToRes,
wsSubscribe,
isBrowser,
lemmyHttp,
} from '../utils';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
interface CreateCommunityState { interface CreateCommunityState {
site: Site; site: Site;
categories: Category[];
loading: boolean;
} }
export class CreateCommunity extends Component<any, CreateCommunityState> { export class CreateCommunity extends Component<any, CreateCommunityState> {
private isoData = setIsoData(this.context);
private subscription: Subscription; private subscription: Subscription;
private emptyState: CreateCommunityState = { private emptyState: CreateCommunityState = {
site: { site: this.isoData.site.site,
id: undefined, categories: [],
name: undefined, loading: true,
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,
},
}; };
constructor(props: any, context: any) { constructor(props: any, context: any) {
super(props, context); super(props, context);
this.handleCommunityCreate = this.handleCommunityCreate.bind(this); this.handleCommunityCreate = this.handleCommunityCreate.bind(this);
this.state = this.emptyState; this.state = this.emptyState;
this.parseMessage = this.parseMessage.bind(this);
this.subscription = wsSubscribe(this.parseMessage);
// TODO not sure if this works
if (!UserService.Instance.user) { if (!UserService.Instance.user) {
toast(i18n.t('not_logged_in'), 'danger'); toast(i18n.t('not_logged_in'), 'danger');
this.context.router.history.push(`/login`); this.context.router.history.push(`/login`);
} }
this.subscription = WebSocketService.Instance.subject // Only fetch the data if coming from another route
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10)))) if (this.isoData.path == this.context.router.route.match.url) {
.subscribe( this.state.categories = this.isoData.routeData[0].categories;
msg => this.parseMessage(msg), this.state.loading = false;
err => console.error(err), } else {
() => console.log('complete') WebSocketService.Instance.listCategories();
); }
WebSocketService.Instance.getSite();
} }
componentWillUnmount() { componentWillUnmount() {
if (isBrowser()) {
this.subscription.unsubscribe(); this.subscription.unsubscribe();
} }
}
get documentTitle(): string { get documentTitle(): string {
if (this.state.site.name) {
return `${i18n.t('create_community')} - ${this.state.site.name}`; return `${i18n.t('create_community')} - ${this.state.site.name}`;
} else {
return 'Lemmy';
}
} }
render() { render() {
return ( return (
<div class="container"> <div class="container">
<Helmet title={this.documentTitle} /> <Helmet title={this.documentTitle} />
{this.state.loading ? (
<h5>
<svg class="icon icon-spinner spin">
<use xlinkHref="#icon-spinner"></use>
</svg>
</h5>
) : (
<div class="row"> <div class="row">
<div class="col-12 col-lg-6 offset-lg-3 mb-4"> <div class="col-12 col-lg-6 offset-lg-3 mb-4">
<h5>{i18n.t('create_community')}</h5> <h5>{i18n.t('create_community')}</h5>
<CommunityForm <CommunityForm
categories={this.state.categories}
onCreate={this.handleCommunityCreate} onCreate={this.handleCommunityCreate}
enableNsfw={this.state.site.enable_nsfw} enableNsfw={this.state.site.enable_nsfw}
/> />
</div> </div>
</div> </div>
)}
</div> </div>
); );
} }
@ -90,15 +98,20 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
this.props.history.push(`/c/${community.name}`); this.props.history.push(`/c/${community.name}`);
} }
static fetchInitialData(_auth: string, _path: string): Promise<any>[] {
return [lemmyHttp.listCategories()];
}
parseMessage(msg: WebSocketJsonResponse) { parseMessage(msg: WebSocketJsonResponse) {
console.log(msg); console.log(msg);
let res = wsJsonToRes(msg); let res = wsJsonToRes(msg);
if (msg.error) { if (msg.error) {
// Toast errors are already handled by community-form // Toast errors are already handled by community-form
return; return;
} else if (res.op == UserOperation.GetSite) { } else if (res.op == UserOperation.ListCategories) {
let data = res.data as GetSiteResponse; let data = res.data as ListCategoriesResponse;
this.state.site = data.site; this.state.categories = data.categories;
this.state.loading = false;
this.setState(this.state); this.setState(this.state);
} }
} }

View file

@ -1,40 +1,41 @@
import { Component } from 'inferno'; import { Component } from 'inferno';
import { Helmet } from 'inferno-helmet'; import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators';
import { PostForm } from './post-form'; import { PostForm } from './post-form';
import { toast, wsJsonToRes } from '../utils'; import {
import { WebSocketService, UserService } from '../services'; lemmyHttp,
setAuth,
setIsoData,
toast,
wsJsonToRes,
wsSubscribe,
} from '../utils';
import { UserService, WebSocketService } from '../services';
import { import {
UserOperation, UserOperation,
PostFormParams, PostFormParams,
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, ListCommunitiesResponse,
Community,
Site, Site,
ListCommunitiesForm,
SortType,
} from 'lemmy-js-client'; } from 'lemmy-js-client';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
interface CreatePostState { interface CreatePostState {
site: Site; site: Site;
communities: Community[];
loading: boolean;
} }
export class CreatePost extends Component<any, CreatePostState> { export class CreatePost extends Component<any, CreatePostState> {
private isoData = setIsoData(this.context);
private subscription: Subscription; private subscription: Subscription;
private emptyState: CreatePostState = { private emptyState: CreatePostState = {
site: { site: this.isoData.site.site,
id: undefined, communities: [],
name: undefined, loading: true,
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,
},
}; };
constructor(props: any, context: any) { constructor(props: any, context: any) {
@ -47,15 +48,24 @@ export class CreatePost extends Component<any, CreatePostState> {
this.context.router.history.push(`/login`); this.context.router.history.push(`/login`);
} }
this.subscription = WebSocketService.Instance.subject this.parseMessage = this.parseMessage.bind(this);
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10)))) this.subscription = wsSubscribe(this.parseMessage);
.subscribe(
msg => this.parseMessage(msg),
err => console.error(err),
() => console.log('complete')
);
WebSocketService.Instance.getSite(); // Only fetch the data if coming from another route
if (this.isoData.path == this.context.router.route.match.url) {
this.state.communities = this.isoData.routeData[0].communities;
this.state.loading = false;
} else {
this.refetch();
}
}
refetch() {
let listCommunitiesForm: ListCommunitiesForm = {
sort: SortType.TopAll,
limit: 9999,
};
WebSocketService.Instance.listCommunities(listCommunitiesForm);
} }
componentWillUnmount() { componentWillUnmount() {
@ -63,21 +73,25 @@ export class CreatePost extends Component<any, CreatePostState> {
} }
get documentTitle(): string { get documentTitle(): string {
if (this.state.site.name) {
return `${i18n.t('create_post')} - ${this.state.site.name}`; return `${i18n.t('create_post')} - ${this.state.site.name}`;
} else {
return 'Lemmy';
}
} }
render() { render() {
return ( return (
<div class="container"> <div class="container">
<Helmet title={this.documentTitle} /> <Helmet title={this.documentTitle} />
{this.state.loading ? (
<h5>
<svg class="icon icon-spinner spin">
<use xlinkHref="#icon-spinner"></use>
</svg>
</h5>
) : (
<div class="row"> <div class="row">
<div class="col-12 col-lg-6 offset-lg-3 mb-4"> <div class="col-12 col-lg-6 offset-lg-3 mb-4">
<h5>{i18n.t('create_post')}</h5> <h5>{i18n.t('create_post')}</h5>
<PostForm <PostForm
communities={this.state.communities}
onCreate={this.handlePostCreate} onCreate={this.handlePostCreate}
params={this.params} params={this.params}
enableDownvotes={this.state.site.enable_downvotes} enableDownvotes={this.state.site.enable_downvotes}
@ -85,6 +99,7 @@ export class CreatePost extends Component<any, CreatePostState> {
/> />
</div> </div>
</div> </div>
)}
</div> </div>
); );
} }
@ -110,22 +125,32 @@ export class CreatePost extends Component<any, CreatePostState> {
return lastLocation.split('/c/')[1]; return lastLocation.split('/c/')[1];
} }
} }
return; return null;
} }
handlePostCreate(id: number) { handlePostCreate(id: number) {
this.props.history.push(`/post/${id}`); this.props.history.push(`/post/${id}`);
} }
static fetchInitialData(auth: string, _path: string): Promise<any>[] {
let listCommunitiesForm: ListCommunitiesForm = {
sort: SortType.TopAll,
limit: 9999,
};
setAuth(listCommunitiesForm, auth);
return [lemmyHttp.listCommunities(listCommunitiesForm)];
}
parseMessage(msg: WebSocketJsonResponse) { parseMessage(msg: WebSocketJsonResponse) {
console.log(msg); console.log(msg);
let res = wsJsonToRes(msg); let res = wsJsonToRes(msg);
if (msg.error) { if (msg.error) {
toast(i18n.t(msg.error), 'danger'); toast(i18n.t(msg.error), 'danger');
return; return;
} else if (res.op == UserOperation.GetSite) { } else if (res.op == UserOperation.ListCommunities) {
let data = res.data as GetSiteResponse; let data = res.data as ListCommunitiesResponse;
this.state.site = data.site; this.state.communities = data.communities;
this.state.loading = false;
this.setState(this.state); this.setState(this.state);
} }
} }

View file

@ -1,68 +1,32 @@
import { Component } from 'inferno'; import { Component } from 'inferno';
import { Helmet } from 'inferno-helmet'; import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs'; import { GetSiteResponse } from 'lemmy-js-client';
import { retryWhen, delay, take } from 'rxjs/operators'; import { setIsoData } from '../utils';
import {
UserOperation,
WebSocketJsonResponse,
GetSiteResponse,
} from 'lemmy-js-client';
import { WebSocketService } from '../services';
import { wsJsonToRes, toast, isBrowser } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
interface InstancesState { interface InstancesState {
loading: boolean;
siteRes: GetSiteResponse; siteRes: GetSiteResponse;
} }
export class Instances extends Component<any, InstancesState> { export class Instances extends Component<any, InstancesState> {
private subscription: Subscription; private isoData = setIsoData(this.context);
private emptyState: InstancesState = { private emptyState: InstancesState = {
loading: true, siteRes: this.isoData.site,
siteRes: undefined,
}; };
constructor(props: any, context: any) { constructor(props: any, context: any) {
super(props, context); super(props, context);
this.state = this.emptyState; this.state = this.emptyState;
if (isBrowser()) {
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')
);
WebSocketService.Instance.getSite();
}
}
componentWillUnmount() {
this.subscription.unsubscribe();
} }
get documentTitle(): string { get documentTitle(): string {
if (this.state.siteRes) {
return `${i18n.t('instances')} - ${this.state.siteRes.site.name}`; return `${i18n.t('instances')} - ${this.state.siteRes.site.name}`;
} else {
return 'Lemmy';
}
} }
render() { render() {
return ( return (
<div class="container"> <div class="container">
<Helmet title={this.documentTitle} /> <Helmet title={this.documentTitle} />
{this.state.loading ? (
<h5 class="">
<svg class="icon icon-spinner spin">
<use xlinkHref="#icon-spinner"></use>
</svg>
</h5>
) : (
<div> <div>
<h5>{i18n.t('linked_instances')}</h5> <h5>{i18n.t('linked_instances')}</h5>
{this.state.siteRes && {this.state.siteRes &&
@ -80,22 +44,7 @@ export class Instances extends Component<any, InstancesState> {
<div>{i18n.t('none_found')}</div> <div>{i18n.t('none_found')}</div>
)} )}
</div> </div>
)}
</div> </div>
); );
} }
parseMessage(msg: WebSocketJsonResponse) {
console.log(msg);
let res = wsJsonToRes(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
} else if (res.op == UserOperation.GetSite) {
let data = res.data as GetSiteResponse;
this.state.siteRes = data;
this.state.loading = false;
this.setState(this.state);
}
}
} }

View file

@ -8,10 +8,10 @@ import {
setupTribute, setupTribute,
pictrsDeleteToast, pictrsDeleteToast,
setupTippy, setupTippy,
isBrowser,
} from '../utils'; } from '../utils';
import { UserService } from '../services'; import { UserService } from '../services';
import autosize from 'autosize'; import autosize from 'autosize';
import Tribute from 'tributejs/src/Tribute.js';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
interface MarkdownTextAreaProps { interface MarkdownTextAreaProps {
@ -41,7 +41,7 @@ export class MarkdownTextArea extends Component<
> { > {
private id = `comment-textarea-${randomStr()}`; private id = `comment-textarea-${randomStr()}`;
private formId = `comment-form-${randomStr()}`; private formId = `comment-form-${randomStr()}`;
private tribute: Tribute; private tribute: any;
private emptyState: MarkdownTextAreaState = { private emptyState: MarkdownTextAreaState = {
content: this.props.initialContent, content: this.props.initialContent,
previewMode: false, previewMode: false,
@ -52,8 +52,9 @@ export class MarkdownTextArea extends Component<
constructor(props: any, context: any) { constructor(props: any, context: any) {
super(props, context); super(props, context);
// TODO if (isBrowser()) {
/* this.tribute = setupTribute(); */ this.tribute = setupTribute();
}
this.state = this.emptyState; this.state = this.emptyState;
} }

View file

@ -3,7 +3,6 @@ import { Prompt } from 'inferno-router';
import { PostListings } from './post-listings'; import { PostListings } from './post-listings';
import { MarkdownTextArea } from './markdown-textarea'; import { MarkdownTextArea } from './markdown-textarea';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators';
import { import {
PostForm as PostFormI, PostForm as PostFormI,
PostFormParams, PostFormParams,
@ -11,8 +10,6 @@ import {
PostResponse, PostResponse,
UserOperation, UserOperation,
Community, Community,
ListCommunitiesResponse,
ListCommunitiesForm,
SortType, SortType,
SearchForm, SearchForm,
SearchType, SearchType,
@ -34,14 +31,22 @@ import {
hostname, hostname,
pictrsDeleteToast, pictrsDeleteToast,
validTitle, validTitle,
wsSubscribe,
isBrowser,
} from '../utils'; } from '../utils';
import Choices from 'choices.js';
var Choices;
if (isBrowser()) {
Choices = require('choices.js');
}
import { i18n } from '../i18next'; import { i18n } from '../i18next';
const MAX_POST_TITLE_LENGTH = 200; const MAX_POST_TITLE_LENGTH = 200;
interface PostFormProps { interface PostFormProps {
post?: Post; // If a post is given, that means this is an edit post?: Post; // If a post is given, that means this is an edit
communities: Community[];
params?: PostFormParams; params?: PostFormParams;
onCancel?(): any; onCancel?(): any;
onCreate?(id: number): any; onCreate?(id: number): any;
@ -52,7 +57,6 @@ interface PostFormProps {
interface PostFormState { interface PostFormState {
postForm: PostFormI; postForm: PostFormI;
communities: Community[];
loading: boolean; loading: boolean;
imageLoading: boolean; imageLoading: boolean;
previewMode: boolean; previewMode: boolean;
@ -64,7 +68,7 @@ interface PostFormState {
export class PostForm extends Component<PostFormProps, PostFormState> { export class PostForm extends Component<PostFormProps, PostFormState> {
private id = `post-form-${randomStr()}`; private id = `post-form-${randomStr()}`;
private subscription: Subscription; private subscription: Subscription;
private choices: Choices; private choices: any;
private emptyState: PostFormState = { private emptyState: PostFormState = {
postForm: { postForm: {
name: null, name: null,
@ -72,7 +76,6 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
auth: null, auth: null,
community_id: null, community_id: null,
}, },
communities: [],
loading: false, loading: false,
imageLoading: false, imageLoading: false,
previewMode: false, previewMode: false,
@ -112,24 +115,12 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
} }
} }
this.subscription = WebSocketService.Instance.subject this.subscription = wsSubscribe(this.parseMessage);
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
.subscribe(
msg => this.parseMessage(msg),
err => console.error(err),
() => console.log('complete')
);
let listCommunitiesForm: ListCommunitiesForm = {
sort: SortType.TopAll,
limit: 9999,
};
WebSocketService.Instance.listCommunities(listCommunitiesForm);
} }
componentDidMount() { componentDidMount() {
setupTippy(); setupTippy();
this.setupCommunities();
} }
componentDidUpdate() { componentDidUpdate() {
@ -209,7 +200,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
onChange={linkEvent(this, this.handleImageUpload)} onChange={linkEvent(this, this.handleImageUpload)}
/> />
</form> </form>
{validURL(this.state.postForm.url) && ( {this.state.postForm.url && validURL(this.state.postForm.url) && (
<a <a
href={`${archiveUrl}/?run=1&url=${encodeURIComponent( href={`${archiveUrl}/?run=1&url=${encodeURIComponent(
this.state.postForm.url this.state.postForm.url
@ -305,7 +296,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
onInput={linkEvent(this, this.handlePostCommunityChange)} onInput={linkEvent(this, this.handlePostCommunityChange)}
> >
<option>{i18n.t('select_a_community')}</option> <option>{i18n.t('select_a_community')}</option>
{this.state.communities.map(community => ( {this.props.communities.map(community => (
<option value={community.id}> <option value={community.id}>
{community.local {community.local
? community.name ? community.name
@ -531,63 +522,53 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
}); });
} }
parseMessage(msg: WebSocketJsonResponse) { setupCommunities() {
let res = wsJsonToRes(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.state.loading = false;
this.setState(this.state);
return;
} else if (res.op == UserOperation.ListCommunities) {
let data = res.data as ListCommunitiesResponse;
this.state.communities = data.communities;
if (this.props.post) { if (this.props.post) {
this.state.postForm.community_id = this.props.post.community_id; this.state.postForm.community_id = this.props.post.community_id;
} else if (this.props.params && this.props.params.community) { } else if (this.props.params && this.props.params.community) {
let foundCommunityId = data.communities.find( let foundCommunityId = this.props.communities.find(
r => r.name == this.props.params.community r => r.name == this.props.params.community
).id; ).id;
this.state.postForm.community_id = foundCommunityId; this.state.postForm.community_id = foundCommunityId;
} else { } else {
// By default, the null valued 'Select a Community' // By default, the null valued 'Select a Community'
} }
this.setState(this.state);
// Set up select searching // Set up select searching
if (isBrowser()) {
let selectId: any = document.getElementById('post-community'); let selectId: any = document.getElementById('post-community');
if (selectId) { if (selectId) {
// TODO this.choices = new Choices(selectId, {
/* this.choices = new Choices(selectId, { */ shouldSort: false,
/* shouldSort: false, */ classNames: {
/* classNames: { */ containerOuter: 'choices',
/* containerOuter: 'choices', */ containerInner: 'choices__inner bg-secondary border-0',
/* containerInner: 'choices__inner bg-secondary border-0', */ input: 'form-control',
/* input: 'form-control', */ inputCloned: 'choices__input--cloned',
/* inputCloned: 'choices__input--cloned', */ list: 'choices__list',
/* list: 'choices__list', */ listItems: 'choices__list--multiple',
/* listItems: 'choices__list--multiple', */ listSingle: 'choices__list--single',
/* listSingle: 'choices__list--single', */ listDropdown: 'choices__list--dropdown',
/* listDropdown: 'choices__list--dropdown', */ item: 'choices__item bg-secondary',
/* item: 'choices__item bg-secondary', */ itemSelectable: 'choices__item--selectable',
/* itemSelectable: 'choices__item--selectable', */ itemDisabled: 'choices__item--disabled',
/* itemDisabled: 'choices__item--disabled', */ itemChoice: 'choices__item--choice',
/* itemChoice: 'choices__item--choice', */ placeholder: 'choices__placeholder',
/* placeholder: 'choices__placeholder', */ group: 'choices__group',
/* group: 'choices__group', */ groupHeading: 'choices__heading',
/* groupHeading: 'choices__heading', */ button: 'choices__button',
/* button: 'choices__button', */ activeState: 'is-active',
/* activeState: 'is-active', */ focusState: 'is-focused',
/* focusState: 'is-focused', */ openState: 'is-open',
/* openState: 'is-open', */ disabledState: 'is-disabled',
/* disabledState: 'is-disabled', */ highlightedState: 'text-info',
/* highlightedState: 'text-info', */ selectedState: 'text-info',
/* selectedState: 'text-info', */ flippedState: 'is-flipped',
/* flippedState: 'is-flipped', */ loadingState: 'is-loading',
/* loadingState: 'is-loading', */ noResults: 'has-no-results',
/* noResults: 'has-no-results', */ noChoices: 'has-no-choices',
/* noChoices: 'has-no-choices', */ },
/* }, */ });
/* }); */
this.choices.passedElement.element.addEventListener( this.choices.passedElement.element.addEventListener(
'choice', 'choice',
(e: any) => { (e: any) => {
@ -597,6 +578,16 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
false false
); );
} }
}
}
parseMessage(msg: WebSocketJsonResponse) {
let res = wsJsonToRes(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.state.loading = false;
this.setState(this.state);
return;
} else if (res.op == UserOperation.CreatePost) { } else if (res.op == UserOperation.CreatePost) {
let data = res.data as PostResponse; let data = res.data as PostResponse;
if (data.post.creator_id == UserService.Instance.user.id) { if (data.post.creator_id == UserService.Instance.user.id) {

View file

@ -28,8 +28,17 @@ export const routes: IRoutePropsWithFetch[] = [
component: Main, component: Main,
}, },
{ path: `/login`, component: Login }, { path: `/login`, component: Login },
{ path: `/create_post`, component: CreatePost }, {
{ path: `/create_community`, component: CreateCommunity }, path: `/create_post`,
component: CreatePost,
fetchInitialData: (auth, path) => CreatePost.fetchInitialData(auth, path),
},
{
path: `/create_community`,
component: CreateCommunity,
fetchInitialData: (auth, path) =>
CreateCommunity.fetchInitialData(auth, path),
},
{ {
path: `/create_private_message`, path: `/create_private_message`,
component: CreatePrivateMessage, component: CreatePrivateMessage,

View file

@ -50,7 +50,10 @@ import { httpUri } from './env';
import { CommentSortType, DataType, IsoData } from './interfaces'; import { CommentSortType, DataType, IsoData } from './interfaces';
import { UserService, WebSocketService } from './services'; import { UserService, WebSocketService } from './services';
// import Tribute from 'tributejs'; var Tribute;
if (isBrowser()) {
Tribute = require('tributejs');
}
import markdown_it from 'markdown-it'; import markdown_it from 'markdown-it';
import markdown_it_sub from 'markdown-it-sub'; import markdown_it_sub from 'markdown-it-sub';
import markdown_it_sup from 'markdown-it-sup'; import markdown_it_sup from 'markdown-it-sup';
@ -266,6 +269,7 @@ export function isVideo(url: string) {
// TODO this broke // TODO this broke
export function validURL(str: string) { export function validURL(str: string) {
console.log(str);
// try { // try {
return !!new URL(str); return !!new URL(str);
// } catch { // } catch {
@ -648,71 +652,71 @@ function notify(info: NotifyInfo, router: any) {
} }
} }
// export function setupTribute(): Tribute<{}> { export function setupTribute() {
// return new Tribute({ return new Tribute({
// noMatchTemplate: function () { noMatchTemplate: function () {
// return ''; return '';
// }, },
// collection: [ collection: [
// // Emojis // Emojis
// { {
// trigger: ':', trigger: ':',
// menuItemTemplate: (item: any) => { menuItemTemplate: (item: any) => {
// let shortName = `:${item.original.key}:`; let shortName = `:${item.original.key}:`;
// return `${item.original.val} ${shortName}`; return `${item.original.val} ${shortName}`;
// }, },
// selectTemplate: (item: any) => { selectTemplate: (item: any) => {
// return `:${item.original.key}:`; return `:${item.original.key}:`;
// }, },
// values: Object.entries(emojiShortName).map(e => { values: Object.entries(emojiShortName).map(e => {
// return { key: e[1], val: e[0] }; return { key: e[1], val: e[0] };
// }), }),
// allowSpaces: false, allowSpaces: false,
// autocompleteMode: true, autocompleteMode: true,
// // TODO // TODO
// // menuItemLimit: mentionDropdownFetchLimit, // menuItemLimit: mentionDropdownFetchLimit,
// menuShowMinLength: 2, menuShowMinLength: 2,
// }, },
// // Users // Users
// { {
// trigger: '@', trigger: '@',
// selectTemplate: (item: any) => { selectTemplate: (item: any) => {
// let link = item.original.local let link = item.original.local
// ? `[${item.original.key}](/u/${item.original.name})` ? `[${item.original.key}](/u/${item.original.name})`
// : `[${item.original.key}](/user/${item.original.id})`; : `[${item.original.key}](/user/${item.original.id})`;
// return link; return link;
// }, },
// values: (text: string, cb: any) => { values: (text: string, cb: any) => {
// userSearch(text, (users: any) => cb(users)); userSearch(text, (users: any) => cb(users));
// }, },
// allowSpaces: false, allowSpaces: false,
// autocompleteMode: true, autocompleteMode: true,
// // TODO // TODO
// // menuItemLimit: mentionDropdownFetchLimit, // menuItemLimit: mentionDropdownFetchLimit,
// menuShowMinLength: 2, menuShowMinLength: 2,
// }, },
// // Communities // Communities
// { {
// trigger: '!', trigger: '!',
// selectTemplate: (item: any) => { selectTemplate: (item: any) => {
// let link = item.original.local let link = item.original.local
// ? `[${item.original.key}](/c/${item.original.name})` ? `[${item.original.key}](/c/${item.original.name})`
// : `[${item.original.key}](/community/${item.original.id})`; : `[${item.original.key}](/community/${item.original.id})`;
// return link; return link;
// }, },
// values: (text: string, cb: any) => { values: (text: string, cb: any) => {
// communitySearch(text, (communities: any) => cb(communities)); communitySearch(text, (communities: any) => cb(communities));
// }, },
// allowSpaces: false, allowSpaces: false,
// autocompleteMode: true, autocompleteMode: true,
// // TODO // TODO
// // menuItemLimit: mentionDropdownFetchLimit, // menuItemLimit: mentionDropdownFetchLimit,
// menuShowMinLength: 2, menuShowMinLength: 2,
// }, },
// ], ],
// }); });
// } }
// TODO // TODO
// let tippyInstance = tippy('[data-tippy-content]'); // let tippyInstance = tippy('[data-tippy-content]');