summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorDessalines <tyhou13@gmx.com>2019-04-07 22:19:02 -0700
committerDessalines <tyhou13@gmx.com>2019-04-07 22:19:02 -0700
commit49bf16e7d451388d894f93a994f3bf18571f9594 (patch)
tree1802bf775a0dd97503670c38ceb13d9aa78d95b6 /ui
parenta61516439406b7884e19d9ae8a1875c728bbe628 (diff)
Adding user details / overview page.
- Fixes #19
Diffstat (limited to 'ui')
-rw-r--r--ui/package.json3
-rw-r--r--ui/src/components/comment-form.tsx93
-rw-r--r--ui/src/components/comment-node.tsx148
-rw-r--r--ui/src/components/comment-nodes.tsx30
-rw-r--r--ui/src/components/communities.tsx12
-rw-r--r--ui/src/components/community-form.tsx22
-rw-r--r--ui/src/components/community.tsx12
-rw-r--r--ui/src/components/create-community.tsx4
-rw-r--r--ui/src/components/create-post.tsx4
-rw-r--r--ui/src/components/home.tsx1
-rw-r--r--ui/src/components/login.tsx20
-rw-r--r--ui/src/components/main.tsx10
-rw-r--r--ui/src/components/moment-time.tsx4
-rw-r--r--ui/src/components/navbar.tsx7
-rw-r--r--ui/src/components/post-form.tsx23
-rw-r--r--ui/src/components/post-listing.tsx21
-rw-r--r--ui/src/components/post-listings.tsx36
-rw-r--r--ui/src/components/post.tsx279
-rw-r--r--ui/src/components/sidebar.tsx10
-rw-r--r--ui/src/components/user.tsx264
-rw-r--r--ui/src/index.tsx6
-rw-r--r--ui/src/interfaces.ts41
-rw-r--r--ui/src/main.css9
-rw-r--r--ui/src/services/WebSocketService.ts9
-rw-r--r--ui/src/utils.ts1
-rw-r--r--ui/yarn.lock36
26 files changed, 740 insertions, 365 deletions
diff --git a/ui/package.json b/ui/package.json
index 1b82db12..b5bb14ef 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -15,7 +15,10 @@
},
"engineStrict": true,
"dependencies": {
+ "@types/autosize": "^3.0.6",
"@types/js-cookie": "^2.2.1",
+ "@types/jwt-decode": "^2.2.1",
+ "@types/markdown-it": "^0.0.7",
"autosize": "^4.0.2",
"classcat": "^1.1.3",
"dotenv": "^6.1.0",
diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx
new file mode 100644
index 00000000..a87dd356
--- /dev/null
+++ b/ui/src/components/comment-form.tsx
@@ -0,0 +1,93 @@
+import { Component, linkEvent } from 'inferno';
+import { CommentNode as CommentNodeI, CommentForm as CommentFormI } from '../interfaces';
+import { WebSocketService } from '../services';
+import * as autosize from 'autosize';
+
+interface CommentFormProps {
+ postId?: number;
+ node?: CommentNodeI;
+ onReplyCancel?(): any;
+ edit?: boolean;
+}
+
+interface CommentFormState {
+ commentForm: CommentFormI;
+ buttonTitle: string;
+}
+
+export class CommentForm extends Component<CommentFormProps, CommentFormState> {
+
+ private emptyState: CommentFormState = {
+ commentForm: {
+ auth: null,
+ content: null,
+ post_id: this.props.node ? this.props.node.comment.post_id : this.props.postId
+ },
+ buttonTitle: !this.props.node ? "Post" : this.props.edit ? "Edit" : "Reply"
+ }
+
+ constructor(props: any, context: any) {
+ super(props, context);
+
+ this.state = this.emptyState;
+
+ if (this.props.node) {
+ if (this.props.edit) {
+ this.state.commentForm.edit_id = this.props.node.comment.id;
+ this.state.commentForm.parent_id = this.props.node.comment.parent_id;
+ this.state.commentForm.content = this.props.node.comment.content;
+ } else {
+ // A reply gets a new parent id
+ this.state.commentForm.parent_id = this.props.node.comment.id;
+ }
+ }
+ }
+
+ componentDidMount() {
+ autosize(document.querySelectorAll('textarea'));
+ }
+
+ render() {
+ return (
+ <div>
+ <form onSubmit={linkEvent(this, this.handleCommentSubmit)}>
+ <div class="form-group row">
+ <div class="col-sm-12">
+ <textarea class="form-control" value={this.state.commentForm.content} onInput={linkEvent(this, this.handleCommentContentChange)} placeholder="Comment here" required />
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-sm-12">
+ <button type="submit" class="btn btn-sm btn-secondary mr-2">{this.state.buttonTitle}</button>
+ {this.props.node && <button type="button" class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.handleReplyCancel)}>Cancel</button>}
+ </div>
+ </div>
+ </form>
+ </div>
+ );
+ }
+
+ handleCommentSubmit(i: CommentForm, event: any) {
+ if (i.props.edit) {
+ WebSocketService.Instance.editComment(i.state.commentForm);
+ } else {
+ WebSocketService.Instance.createComment(i.state.commentForm);
+ }
+
+ i.state.commentForm.content = undefined;
+ i.setState(i.state);
+ event.target.reset();
+ if (i.props.node) {
+ i.props.onReplyCancel();
+ }
+ }
+
+ handleCommentContentChange(i: CommentForm, event: any) {
+ i.state.commentForm.content = event.target.value;
+ i.setState(i.state);
+ }
+
+ handleReplyCancel(i: CommentForm) {
+ i.props.onReplyCancel();
+ }
+}
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
new file mode 100644
index 00000000..55be7621
--- /dev/null
+++ b/ui/src/components/comment-node.tsx
@@ -0,0 +1,148 @@
+import { Component, linkEvent } from 'inferno';
+import { Link } from 'inferno-router';
+import { CommentNode as CommentNodeI, CommentLikeForm, CommentForm as CommentFormI } from '../interfaces';
+import { WebSocketService, UserService } from '../services';
+import { mdToHtml } from '../utils';
+import { MomentTime } from './moment-time';
+import { CommentForm } from './comment-form';
+import { CommentNodes } from './comment-nodes';
+
+interface CommentNodeState {
+ showReply: boolean;
+ showEdit: boolean;
+}
+
+interface CommentNodeProps {
+ node: CommentNodeI;
+ noIndent?: boolean;
+ viewOnly?: boolean;
+}
+
+export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
+
+ private emptyState: CommentNodeState = {
+ showReply: false,
+ showEdit: false
+ }
+
+ constructor(props: any, context: any) {
+ super(props, context);
+
+ this.state = this.emptyState;
+ this.handleReplyCancel = this.handleReplyCancel.bind(this);
+ this.handleCommentLike = this.handleCommentLike.bind(this);
+ this.handleCommentDisLike = this.handleCommentDisLike.bind(this);
+ }
+
+ render() {
+ let node = this.props.node;
+ return (
+ <div id={`comment-${node.comment.id}`} className={`comment ${node.comment.parent_id && !this.props.noIndent ? 'ml-4' : ''}`}>
+ <div className={`float-left small text-center ${this.props.viewOnly && 'no-click'}`}>
+ <div className={`pointer upvote ${node.comment.my_vote == 1 ? 'text-info' : 'text-muted'}`} onClick={linkEvent(node, this.handleCommentLike)}>▲</div>
+ <div>{node.comment.score}</div>
+ <div className={`pointer downvote ${node.comment.my_vote == -1 && 'text-danger'}`} onClick={linkEvent(node, this.handleCommentDisLike)}>▼</div>
+ </div>
+ <div className="details ml-4">
+ <ul class="list-inline mb-0 text-muted small">
+ <li className="list-inline-item">
+ <Link to={`/user/${node.comment.creator_id}`}>{node.comment.creator_name}</Link>
+ </li>
+ <li className="list-inline-item">
+ <span>(
+ <span className="text-info">+{node.comment.upvotes}</span>
+ <span> | </span>
+ <span className="text-danger">-{node.comment.downvotes}</span>
+ <span>) </span>
+ </span>
+ </li>
+ <li className="list-inline-item">
+ <span><MomentTime data={node.comment} /></span>
+ </li>
+ </ul>
+ {this.state.showEdit && <CommentForm node={node} edit onReplyCancel={this.handleReplyCancel} />}
+ {!this.state.showEdit &&
+ <div>
+ <div className="md-div" dangerouslySetInnerHTML={mdToHtml(node.comment.content)} />
+ <ul class="list-inline mb-1 text-muted small font-weight-bold">
+ {!this.props.viewOnly &&
+ <span class="mr-2">
+ <li className="list-inline-item">
+ <span class="pointer" onClick={linkEvent(this, this.handleReplyClick)}>reply</span>
+ </li>
+ {this.myComment &&
+ <li className="list-inline-item">
+ <span class="pointer" onClick={linkEvent(this, this.handleEditClick)}>edit</span>
+ </li>
+ }
+ {this.myComment &&
+ <li className="list-inline-item">
+ <span class="pointer" onClick={linkEvent(this, this.handleDeleteClick)}>delete</span>
+ </li>
+ }
+ </span>
+ }
+ <li className="list-inline-item">
+ <Link className="text-muted" to={`/post/${node.comment.post_id}/comment/${node.comment.id}`} target="_blank">link</Link>
+ </li>
+ </ul>
+ </div>
+ }
+ </div>
+ {this.state.showReply && <CommentForm node={node} onReplyCancel={this.handleReplyCancel} />}
+ {this.props.node.children && <CommentNodes nodes={this.props.node.children} />}
+ </div>
+ )
+ }
+
+ private get myComment(): boolean {
+ return UserService.Instance.loggedIn && this.props.node.comment.creator_id == UserService.Instance.user.id;
+ }
+
+ handleReplyClick(i: CommentNode) {
+ i.state.showReply = true;
+ i.setState(i.state);
+ }
+
+ handleEditClick(i: CommentNode) {
+ i.state.showEdit = true;
+ i.setState(i.state);
+ }
+
+ handleDeleteClick(i: CommentNode) {
+ let deleteForm: CommentFormI = {
+ content: "*deleted*",
+ edit_id: i.props.node.comment.id,
+ post_id: i.props.node.comment.post_id,
+ parent_id: i.props.node.comment.parent_id,
+ auth: null
+ };
+ WebSocketService.Instance.editComment(deleteForm);
+ }
+
+ handleReplyCancel() {
+ this.state.showReply = false;
+ this.state.showEdit = false;
+ this.setState(this.state);
+ }
+
+
+ handleCommentLike(i: CommentNodeI) {
+
+ let form: CommentLikeForm = {
+ comment_id: i.comment.id,
+ post_id: i.comment.post_id,
+ score: (i.comment.my_vote == 1) ? 0 : 1
+ };
+ WebSocketService.Instance.likeComment(form);
+ }
+
+ handleCommentDisLike(i: CommentNodeI) {
+ let form: CommentLikeForm = {
+ comment_id: i.comment.id,
+ post_id: i.comment.post_id,
+ score: (i.comment.my_vote == -1) ? 0 : -1
+ };
+ WebSocketService.Instance.likeComment(form);
+ }
+}
diff --git a/ui/src/components/comment-nodes.tsx b/ui/src/components/comment-nodes.tsx
new file mode 100644
index 00000000..76d5c57e
--- /dev/null
+++ b/ui/src/components/comment-nodes.tsx
@@ -0,0 +1,30 @@
+import { Component } from 'inferno';
+import { CommentNode as CommentNodeI } from '../interfaces';
+import { CommentNode } from './comment-node';
+
+interface CommentNodesState {
+}
+
+interface CommentNodesProps {
+ nodes: Array<CommentNodeI>;
+ noIndent?: boolean;
+ viewOnly?: boolean;
+}
+
+export class CommentNodes extends Component<CommentNodesProps, CommentNodesState> {
+
+ constructor(props: any, context: any) {
+ super(props, context);
+ }
+
+ render() {
+ return (
+ <div className="comments">
+ {this.props.nodes.map(node =>
+ <CommentNode node={node} noIndent={this.props.noIndent} viewOnly={this.props.viewOnly}/>
+ )}
+ </div>
+ )
+ }
+}
+
diff --git a/ui/src/components/communities.tsx b/ui/src/components/communities.tsx
index c3cde177..b81b11cd 100644
--- a/ui/src/components/communities.tsx
+++ b/ui/src/components/communities.tsx
@@ -2,9 +2,9 @@ import { Component, linkEvent } from 'inferno';
import { Link } from 'inferno-router';
import { Subscription } from "rxjs";
import { retryWhen, delay, take } from 'rxjs/operators';
-import { UserOperation, Community, Post as PostI, GetPostResponse, PostResponse, Comment, CommentForm as CommentFormI, CommentResponse, CommentLikeForm, CommentSortType, CreatePostLikeResponse, ListCommunitiesResponse, CommunityResponse, FollowCommunityForm } from '../interfaces';
-import { WebSocketService, UserService } from '../services';
-import { msgOp, hotRank,mdToHtml } from '../utils';
+import { UserOperation, Community, ListCommunitiesResponse, CommunityResponse, FollowCommunityForm } from '../interfaces';
+import { WebSocketService } from '../services';
+import { msgOp } from '../utils';
declare const Sortable: any;
@@ -18,7 +18,7 @@ export class Communities extends Component<any, CommunitiesState> {
communities: []
}
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
this.subscription = WebSocketService.Instance.subject
@@ -32,6 +32,10 @@ export class Communities extends Component<any, CommunitiesState> {
}
+ componentWillUnmount() {
+ this.subscription.unsubscribe();
+ }
+
componentDidMount() {
let table = document.querySelector('#community_table');
Sortable.initTable(table);
diff --git a/ui/src/components/community-form.tsx b/ui/src/components/community-form.tsx
index 0cf67983..6250ef9c 100644
--- a/ui/src/components/community-form.tsx
+++ b/ui/src/components/community-form.tsx
@@ -2,16 +2,16 @@ import { Component, linkEvent } from 'inferno';
import { Subscription } from "rxjs";
import { retryWhen, delay, take } from 'rxjs/operators';
import { CommunityForm as CommunityFormI, UserOperation, Category, ListCategoriesResponse, CommunityResponse } from '../interfaces';
-import { WebSocketService, UserService } from '../services';
+import { WebSocketService } from '../services';
import { msgOp } from '../utils';
import { Community } from '../interfaces';
interface CommunityFormProps {
community?: Community; // If a community is given, that means this is an edit
- onCancel?();
- onCreate?(id: number);
- onEdit?(community: Community);
+ onCancel?(): any;
+ onCreate?(id: number): any;
+ onEdit?(community: Community): any;
}
interface CommunityFormState {
@@ -31,7 +31,7 @@ export class CommunityForm extends Component<CommunityFormProps, CommunityFormSt
categories: []
}
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
@@ -104,7 +104,7 @@ export class CommunityForm extends Component<CommunityFormProps, CommunityFormSt
);
}
- handleCreateCommunitySubmit(i: CommunityForm, event) {
+ handleCreateCommunitySubmit(i: CommunityForm, event: any) {
event.preventDefault();
if (i.props.community) {
WebSocketService.Instance.editCommunity(i.state.communityForm);
@@ -113,27 +113,27 @@ export class CommunityForm extends Component<CommunityFormProps, CommunityFormSt
}
}
- handleCommunityNameChange(i: CommunityForm, event) {
+ handleCommunityNameChange(i: CommunityForm, event: any) {
i.state.communityForm.name = event.target.value;
i.setState(i.state);
}
- handleCommunityTitleChange(i: CommunityForm, event) {
+ handleCommunityTitleChange(i: CommunityForm, event: any) {
i.state.communityForm.title = event.target.value;
i.setState(i.state);
}
- handleCommunityDescriptionChange(i: CommunityForm, event) {
+ handleCommunityDescriptionChange(i: CommunityForm, event: any) {
i.state.communityForm.description = event.target.value;
i.setState(i.state);
}
- handleCommunityCategoryChange(i: CommunityForm, event) {
+ handleCommunityCategoryChange(i: CommunityForm, event: any) {
i.state.communityForm.category_id = Number(event.target.value);
i.setState(i.state);
}
- handleCancel(i: CommunityForm, event) {
+ handleCancel(i: CommunityForm) {
i.props.onCancel();
}
diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx
index 0d6d353d..ed693c55 100644
--- a/ui/src/components/community.tsx
+++ b/ui/src/components/community.tsx
@@ -1,13 +1,11 @@
-import { Component, linkEvent } from 'inferno';
-import { Link } from 'inferno-router';
+import { Component } from 'inferno';
import { Subscription } from "rxjs";
import { retryWhen, delay, take } from 'rxjs/operators';
-import { UserOperation, Community as CommunityI, GetCommunityResponse, CommunityResponse, Post, GetPostsForm, ListingSortType, ListingType, GetPostsResponse, CreatePostLikeForm, CreatePostLikeResponse, CommunityUser} from '../interfaces';
-import { WebSocketService, UserService } from '../services';
-import { MomentTime } from './moment-time';
+import { UserOperation, Community as CommunityI, GetCommunityResponse, CommunityResponse, CommunityUser} from '../interfaces';
+import { WebSocketService } from '../services';
import { PostListings } from './post-listings';
import { Sidebar } from './sidebar';
-import { msgOp, mdToHtml } from '../utils';
+import { msgOp } from '../utils';
interface State {
community: CommunityI;
@@ -36,7 +34,7 @@ export class Community extends Component<any, State> {
communityId: Number(this.props.match.params.id)
}
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
diff --git a/ui/src/components/create-community.tsx b/ui/src/components/create-community.tsx
index e98352a2..5f397411 100644
--- a/ui/src/components/create-community.tsx
+++ b/ui/src/components/create-community.tsx
@@ -1,9 +1,9 @@
-import { Component, linkEvent } from 'inferno';
+import { Component } from 'inferno';
import { CommunityForm } from './community-form';
export class CreateCommunity extends Component<any, any> {
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.handleCommunityCreate = this.handleCommunityCreate.bind(this);
}
diff --git a/ui/src/components/create-post.tsx b/ui/src/components/create-post.tsx
index 784465a0..041ffd17 100644
--- a/ui/src/components/create-post.tsx
+++ b/ui/src/components/create-post.tsx
@@ -1,9 +1,9 @@
-import { Component, linkEvent } from 'inferno';
+import { Component } from 'inferno';
import { PostForm } from './post-form';
export class CreatePost extends Component<any, any> {
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.handlePostCreate = this.handlePostCreate.bind(this);
}
diff --git a/ui/src/components/home.tsx b/ui/src/components/home.tsx
index 356534f7..8fced5be 100644
--- a/ui/src/components/home.tsx
+++ b/ui/src/components/home.tsx
@@ -1,5 +1,4 @@
import { Component } from 'inferno';
-import { repoUrl } from '../utils';
import { Main } from './main';
export class Home extends Component<any, any> {
diff --git a/ui/src/components/login.tsx b/ui/src/components/login.tsx
index 30b0aabc..0cb02616 100644
--- a/ui/src/components/login.tsx
+++ b/ui/src/components/login.tsx
@@ -25,7 +25,7 @@ let emptyState: State = {
export class Login extends Component<any, State> {
private subscription: Subscription;
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.state = emptyState;
@@ -122,42 +122,42 @@ export class Login extends Component<any, State> {
);
}
- handleLoginSubmit(i: Login, event) {
+ handleLoginSubmit(i: Login, event: any) {
event.preventDefault();
WebSocketService.Instance.login(i.state.loginForm);
}
- handleLoginUsernameChange(i: Login, event) {
+ handleLoginUsernameChange(i: Login, event: any) {
i.state.loginForm.username_or_email = event.target.value;
i.setState(i.state);
}
- handleLoginPasswordChange(i: Login, event) {
+ handleLoginPasswordChange(i: Login, event: any) {
i.state.loginForm.password = event.target.value;
i.setState(i.state);
}
- handleRegisterSubmit(i: Login, event) {
+ handleRegisterSubmit(i: Login, event: any) {
event.preventDefault();
WebSocketService.Instance.register(i.state.registerForm);
}
- handleRegisterUsernameChange(i: Login, event) {
+ handleRegisterUsernameChange(i: Login, event: any) {
i.state.registerForm.username = event.target.value;
i.setState(i.state);
}
- handleRegisterEmailChange(i: Login, event) {
+ handleRegisterEmailChange(i: Login, event: any) {
i.state.registerForm.email = event.target.value;
i.setState(i.state);
}
- handleRegisterPasswordChange(i: Login, event) {
+ handleRegisterPasswordChange(i: Login, event: any) {
i.state.registerForm.password = event.target.value;
i.setState(i.state);
}
- handleRegisterPasswordVerifyChange(i: Login, event) {
+ handleRegisterPasswordVerifyChange(i: Login, event: any) {
i.state.registerForm.password_verify = event.target.value;
i.setState(i.state);
}
@@ -170,7 +170,7 @@ export class Login extends Component<any, State> {
} else {
if (op == UserOperation.Register || op == UserOperation.Login) {
let res: LoginResponse = msg;
- UserService.Instance.login(msg);
+ UserService.Instance.login(res);
this.props.history.push('/');
}
}
diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx
index b7b0a562..aa3c3a8c 100644
--- a/ui/src/components/main.tsx
+++ b/ui/src/components/main.tsx
@@ -1,13 +1,11 @@
-import { Component, linkEvent } from 'inferno';
+import { Component } from 'inferno';
import { Link } from 'inferno-router';
import { Subscription } from "rxjs";
import { retryWhen, delay, take } from 'rxjs/operators';
-import { UserOperation, Community as CommunityI, GetCommunityResponse, CommunityResponse, Post, GetPostsForm, ListingSortType, ListingType, GetPostsResponse, CreatePostLikeForm, CreatePostLikeResponse, CommunityUser, GetFollowedCommunitiesResponse } from '../interfaces';
+import { UserOperation, CommunityUser, GetFollowedCommunitiesResponse } from '../interfaces';
import { WebSocketService, UserService } from '../services';
-import { MomentTime } from './moment-time';
import { PostListings } from './post-listings';
-import { Sidebar } from './sidebar';
-import { msgOp, mdToHtml } from '../utils';
+import { msgOp } from '../utils';
interface State {
subscribedCommunities: Array<CommunityUser>;
@@ -20,7 +18,7 @@ export class Main extends Component<any, State> {
subscribedCommunities: []
}
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
diff --git a/ui/src/components/moment-time.tsx b/ui/src/components/moment-time.tsx
index e0886cbc..f07f04a3 100644
--- a/ui/src/components/moment-time.tsx
+++ b/ui/src/components/moment-time.tsx
@@ -1,4 +1,4 @@
-import { Component, linkEvent } from 'inferno';
+import { Component } from 'inferno';
import * as moment from 'moment';
interface MomentTimeProps {
@@ -10,7 +10,7 @@ interface MomentTimeProps {
export class MomentTime extends Component<MomentTimeProps, any> {
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
}
diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx
index 2032d49b..9754c935 100644
--- a/ui/src/components/navbar.tsx
+++ b/ui/src/components/navbar.tsx
@@ -5,7 +5,7 @@ import { UserService } from '../services';
export class Navbar extends Component<any, any> {
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.state = {isLoggedIn: UserService.Instance.loggedIn, expanded: false};
@@ -62,12 +62,11 @@ export class Navbar extends Component<any, any> {
);
}
- handleLogoutClick(i: Navbar, event) {
+ handleLogoutClick() {
UserService.Instance.logout();
- // i.props.history.push('/');
}
- expandNavbar(i: Navbar, event) {
+ expandNavbar(i: Navbar) {
i.state.expanded = !i.state.expanded;
i.setState(i.state);
}
diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx
index a8621ced..1f23cae0 100644
--- a/ui/src/components/post-form.tsx
+++ b/ui/src/components/post-form.tsx
@@ -2,15 +2,14 @@ import { Component, linkEvent } from 'inferno';
import { Subscription } from "rxjs";
import { retryWhen, delay, take } from 'rxjs/operators';
import { PostForm as PostFormI, Post, PostResponse, UserOperation, Community, ListCommunitiesResponse } from '../interfaces';
-import { WebSocketService, UserService } from '../services';
+import { WebSocketService } from '../services';
import { msgOp } from '../utils';
-import { MomentTime } from './moment-time';
interface PostFormProps {
post?: Post; // If a post is given, that means this is an edit
- onCancel?();
- onCreate?(id: number);
- onEdit?(post: Post);
+ onCancel?(): any;
+ onCreate?(id: number): any;
+ onEdit?(post: Post): any;
}
interface PostFormState {
@@ -30,7 +29,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
communities: []
}
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
@@ -104,7 +103,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
);
}
- handlePostSubmit(i: PostForm, event) {
+ handlePostSubmit(i: PostForm, event: any) {
event.preventDefault();
if (i.props.post) {
WebSocketService.Instance.editPost(i.state.postForm);
@@ -113,27 +112,27 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
}
}
- handlePostUrlChange(i: PostForm, event) {
+ handlePostUrlChange(i: PostForm, event: any) {
i.state.postForm.url = event.target.value;
i.setState(i.state);
}
- handlePostNameChange(i: PostForm, event) {
+ handlePostNameChange(i: PostForm, event: any) {
i.state.postForm.name = event.target.value;
i.setState(i.state);
}
- handlePostBodyChange(i: PostForm, event) {
+ handlePostBodyChange(i: PostForm, event: any) {
i.state.postForm.body = event.target.value;
i.setState(i.state);
}
- handlePostCommunityChange(i: PostForm, event) {
+ handlePostCommunityChange(i: PostForm, event: any) {
i.state.postForm.community_id = Number(event.target.value);
i.setState(i.state);
}
- handleCancel(i: PostForm, event) {
+ handleCancel(i: PostForm) {
i.props.onCancel();
}
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx
index c5052efb..f3145eff 100644
--- a/ui/src/components/post-listing.tsx
+++ b/ui/src/components/post-listing.tsx
@@ -1,9 +1,7 @@
import { Component, linkEvent } from 'inferno';
import { Link } from 'inferno-router';
-import { Subscription } from "rxjs";
-import { retryWhen, delay, take } from 'rxjs/operators';
import { WebSocketService, UserService } from '../services';
-import { Post, CreatePostLikeResponse, CreatePostLikeForm, PostForm as PostFormI } from '../interfaces';
+import { Post, CreatePostLikeForm, PostForm as PostFormI } from '../interfaces';
import { MomentTime } from './moment-time';
import { PostForm } from './post-form';
import { mdToHtml } from '../utils';
@@ -18,6 +16,7 @@ interface PostListingProps {
editable?: boolean;
showCommunity?: boolean;
showBody?: boolean;
+ viewOnly?: boolean;
}
export class PostListing extends Component<PostListingProps, PostListingState> {
@@ -27,7 +26,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
iframeExpanded: false
}
- constructor(props, context) {
+ constructor(props: any, context: any) {
super(props, context);
this.state = this.emptyState;
@@ -52,7 +51,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
let post = this.props.post;
return (
<div class="listing">
- <div className="float-left small text-center">
+ <div className={`float-left small text-center ${this.props.viewOnly && 'no-click'}`}>
<div className={`pointer upvote ${post.my_vote == 1 ? 'text-info' : 'text-muted'}`} onClick={linkEvent(this, this.handlePostLike)}>▲</div>
<div>{post.score}</div>
<div className={`pointer downvote ${post.my_vote == -1 && 'text-danger'}`} onClick={linkEvent(this, this.handlePostDisLike)}>▼</div>
@@ -123,7 +122,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
return this.props.editable && UserService.Instance.loggedIn && this.props.post.creator_id == UserService.Instance.user.id;
}
- handlePostLike(i: PostListing, event) {
+ handlePostLike(i: PostListing) {
let form: CreatePostLikeForm = {
post_id: i.props.post.id,
@@ -132,7 +131,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
WebSocketService.Instance.likePost(form);
}
- handlePostDisLike(i: PostListing, event) {
+ handlePostDisLike(i: PostListing) {
let form: CreatePostLikeForm = {
post_id: i.props.post.id,
score: (i.props.post.my_vote == -1) ? 0 : -1
@@ -140,7 +139,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
WebSocketService.Instance.likePost(form);
}
- handleEditClick(i: PostListing, event) {
+ handleEditClick(i: PostListing) {
i.state.showEdit = true;
i.setState(i.state);
}
@@ -151,12 +150,12 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
}
// The actual editing is done in the recieve for post
- handleEditPost(post: Post) {
+ handleEditPost() {
this.state.showEdit = false;
this.setState(this.state);
}
- handleDeleteClick(i: PostListing, event) {
+ handleDeleteClick(i: PostListing) {
let deleteForm: PostFormI = {
body: '',
commun