summaryrefslogtreecommitdiffstats
path: root/ui/src
diff options
context:
space:
mode:
authorDessalines <dessalines@users.noreply.github.com>2020-07-09 20:03:47 -0400
committerGitHub <noreply@github.com>2020-07-09 20:03:47 -0400
commit50e6d81d0b40e1d9caa0db83d20026adf3aef631 (patch)
tree78d3c0770ec4508dbc6c565372e93ddf8c577634 /ui/src
parent85c07e7154c82e5b387bb6a02aae70645cf1d8e0 (diff)
Redirect to login page for votes, comments, pages, etc. Fixes #849 (#926)
Diffstat (limited to 'ui/src')
-rw-r--r--ui/src/components/comment-form.tsx255
-rw-r--r--ui/src/components/create-community.tsx7
-rw-r--r--ui/src/components/create-post.tsx7
-rw-r--r--ui/src/components/create-private-message.tsx7
-rw-r--r--ui/src/components/post-listing.tsx9
5 files changed, 163 insertions, 122 deletions
diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx
index 32bc3786..a433dbd4 100644
--- a/ui/src/components/comment-form.tsx
+++ b/ui/src/components/comment-form.tsx
@@ -1,4 +1,5 @@
import { Component, linkEvent } from 'inferno';
+import { Link } from 'inferno-router';
import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators';
import { Prompt } from 'inferno-router';
@@ -25,6 +26,7 @@ import autosize from 'autosize';
import Tribute from 'tributejs/src/Tribute.js';
import emojiShortName from 'emoji-short-name';
import { i18n } from '../i18next';
+import { T } from 'inferno-i18next';
interface CommentFormProps {
postId?: number;
@@ -99,29 +101,31 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
componentDidMount() {
let textarea: any = document.getElementById(this.id);
- autosize(textarea);
- this.tribute.attach(textarea);
- textarea.addEventListener('tribute-replaced', () => {
- this.state.commentForm.content = textarea.value;
- this.setState(this.state);
- autosize.update(textarea);
- });
+ if (textarea) {
+ autosize(textarea);
+ this.tribute.attach(textarea);
+ textarea.addEventListener('tribute-replaced', () => {
+ this.state.commentForm.content = textarea.value;
+ this.setState(this.state);
+ autosize.update(textarea);
+ });
- // Quoting of selected text
- let selectedText = window.getSelection().toString();
- if (selectedText) {
- let quotedText =
- selectedText
- .split('\n')
- .map(t => `> ${t}`)
- .join('\n') + '\n\n';
- this.state.commentForm.content = quotedText;
- this.setState(this.state);
- // Not sure why this needs a delay
- setTimeout(() => autosize.update(textarea), 10);
- }
+ // Quoting of selected text
+ let selectedText = window.getSelection().toString();
+ if (selectedText) {
+ let quotedText =
+ selectedText
+ .split('\n')
+ .map(t => `> ${t}`)
+ .join('\n') + '\n\n';
+ this.state.commentForm.content = quotedText;
+ this.setState(this.state);
+ // Not sure why this needs a delay
+ setTimeout(() => autosize.update(textarea), 10);
+ }
- textarea.focus();
+ textarea.focus();
+ }
}
componentDidUpdate() {
@@ -144,115 +148,128 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
when={this.state.commentForm.content}
message={i18n.t('block_leaving')}
/>
- <form
- id={this.formId}
- onSubmit={linkEvent(this, this.handleCommentSubmit)}
- >
- <div class="form-group row">
- <div className={`col-sm-12`}>
- <textarea
- id={this.id}
- className={`form-control ${this.state.previewMode && 'd-none'}`}
- value={this.state.commentForm.content}
- onInput={linkEvent(this, this.handleCommentContentChange)}
- onPaste={linkEvent(this, this.handleImageUploadPaste)}
- required
- disabled={this.props.disabled}
- rows={2}
- maxLength={10000}
- />
- {this.state.previewMode && (
- <div
- className="card card-body md-div"
- dangerouslySetInnerHTML={mdToHtml(
- this.state.commentForm.content
- )}
+ {UserService.Instance.user ? (
+ <form
+ id={this.formId}
+ onSubmit={linkEvent(this, this.handleCommentSubmit)}
+ >
+ <div class="form-group row">
+ <div className={`col-sm-12`}>
+ <textarea
+ id={this.id}
+ className={`form-control ${
+ this.state.previewMode && 'd-none'
+ }`}
+ value={this.state.commentForm.content}
+ onInput={linkEvent(this, this.handleCommentContentChange)}
+ onPaste={linkEvent(this, this.handleImageUploadPaste)}
+ required
+ disabled={this.props.disabled}
+ rows={2}
+ maxLength={10000}
/>
- )}
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12">
- <button
- type="submit"
- class="btn btn-sm btn-secondary mr-2"
- disabled={this.props.disabled || this.state.loading}
- >
- {this.state.loading ? (
- <svg class="icon icon-spinner spin">
- <use xlinkHref="#icon-spinner"></use>
- </svg>
- ) : (
- <span>{this.state.buttonTitle}</span>
+ {this.state.previewMode && (
+ <div
+ className="card card-body md-div"
+ dangerouslySetInnerHTML={mdToHtml(
+ this.state.commentForm.content
+ )}
+ />
)}
- </button>
- {this.state.commentForm.content && (
- <button
- className={`btn btn-sm mr-2 btn-secondary ${
- this.state.previewMode && 'active'
- }`}
- onClick={linkEvent(this, this.handlePreviewToggle)}
- >
- {i18n.t('preview')}
- </button>
- )}
- {this.props.node && (
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-sm-12">
<button
- type="button"
+ type="submit"
class="btn btn-sm btn-secondary mr-2"
- onClick={linkEvent(this, this.handleReplyCancel)}
+ disabled={this.props.disabled || this.state.loading}
>
- {i18n.t('cancel')}
+ {this.state.loading ? (
+ <svg class="icon icon-spinner spin">
+ <use xlinkHref="#icon-spinner"></use>
+ </svg>
+ ) : (
+ <span>{this.state.buttonTitle}</span>
+ )}
</button>
- )}
- <a
- href={markdownHelpUrl}
- target="_blank"
- class="d-inline-block float-right text-muted font-weight-bold"
- title={i18n.t('formatting_help')}
- rel="noopener"
- >
- <svg class="icon icon-inline">
- <use xlinkHref="#icon-help-circle"></use>
- </svg>
- </a>
- <form class="d-inline-block mr-3 float-right text-muted font-weight-bold">
- <label
- htmlFor={`file-upload-${this.id}`}
- className={`${UserService.Instance.user && 'pointer'}`}
- data-tippy-content={i18n.t('upload_image')}
+ {this.state.commentForm.content && (
+ <button
+ className={`btn btn-sm mr-2 btn-secondary ${
+ this.state.previewMode && 'active'
+ }`}
+ onClick={linkEvent(this, this.handlePreviewToggle)}
+ >
+ {i18n.t('preview')}
+ </button>
+ )}
+ {this.props.node && (
+ <button
+ type="button"
+ class="btn btn-sm btn-secondary mr-2"
+ onClick={linkEvent(this, this.handleReplyCancel)}
+ >
+ {i18n.t('cancel')}
+ </button>
+ )}
+ <a
+ href={markdownHelpUrl}
+ target="_blank"
+ class="d-inline-block float-right text-muted font-weight-bold"
+ title={i18n.t('formatting_help')}
+ rel="noopener"
>
<svg class="icon icon-inline">
- <use xlinkHref="#icon-image"></use>
+ <use xlinkHref="#icon-help-circle"></use>
</svg>
- </label>
- <input
- id={`file-upload-${this.id}`}
- type="file"
- accept="image/*,video/*"
- name="file"
- class="d-none"
- disabled={!UserService.Instance.user}
- onChange={linkEvent(this, this.handleImageUpload)}
- />
- </form>
- {this.state.imageLoading && (
- <svg class="icon icon-spinner spin">
- <use xlinkHref="#icon-spinner"></use>
- </svg>
- )}
- <span
- onClick={linkEvent(this, this.handleEmojiPickerClick)}
- class="pointer unselectable d-inline-block mr-3 float-right text-muted font-weight-bold"
- data-tippy-content={i18n.t('emoji_picker')}
- >
- <svg class="icon icon-inline">
- <use xlinkHref="#icon-smile"></use>
- </svg>
- </span>
+ </a>
+ <form class="d-inline-block mr-3 float-right text-muted font-weight-bold">
+ <label
+ htmlFor={`file-upload-${this.id}`}
+ className={`${UserService.Instance.user && 'pointer'}`}
+ data-tippy-content={i18n.t('upload_image')}
+ >
+ <svg class="icon icon-inline">
+ <use xlinkHref="#icon-image"></use>
+ </svg>
+ </label>
+ <input
+ id={`file-upload-${this.id}`}
+ type="file"
+ accept="image/*,video/*"
+ name="file"
+ class="d-none"
+ disabled={!UserService.Instance.user}
+ onChange={linkEvent(this, this.handleImageUpload)}
+ />
+ </form>
+ {this.state.imageLoading && (
+ <svg class="icon icon-spinner spin">
+ <use xlinkHref="#icon-spinner"></use>
+ </svg>
+ )}
+ <span
+ onClick={linkEvent(this, this.handleEmojiPickerClick)}
+ class="pointer unselectable d-inline-block mr-3 float-right text-muted font-weight-bold"
+ data-tippy-content={i18n.t('emoji_picker')}
+ >
+ <svg class="icon icon-inline">
+ <use xlinkHref="#icon-smile"></use>
+ </svg>
+ </span>
+ </div>
</div>
+ </form>
+ ) : (
+ <div class="alert alert-warning" role="alert">
+ <svg class="icon icon-inline mr-2">
+ <use xlinkHref="#icon-alert-triangle"></use>
+ </svg>
+ <T i18nKey="must_login" class="d-inline">
+ #<Link to="/login">#</Link>
+ </T>
</div>
- </form>
+ )}
</div>
);
}
diff --git a/ui/src/components/create-community.tsx b/ui/src/components/create-community.tsx
index 86929894..3a5d943d 100644
--- a/ui/src/components/create-community.tsx
+++ b/ui/src/components/create-community.tsx
@@ -9,7 +9,7 @@ import {
GetSiteResponse,
} from '../interfaces';
import { toast, wsJsonToRes } from '../utils';
-import { WebSocketService } from '../services';
+import { WebSocketService, UserService } from '../services';
import { i18n } from '../i18next';
interface CreateCommunityState {
@@ -26,6 +26,11 @@ export class CreateCommunity extends Component<any, CreateCommunityState> {
this.handleCommunityCreate = this.handleCommunityCreate.bind(this);
this.state = this.emptyState;
+ if (!UserService.Instance.user) {
+ toast(i18n.t('not_logged_in'), 'danger');
+ this.context.router.history.push(`/login`);
+ }
+
this.subscription = WebSocketService.Instance.subject
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
.subscribe(
diff --git a/ui/src/components/create-post.tsx b/ui/src/components/create-post.tsx
index 348ba0cb..4554326d 100644
--- a/ui/src/components/create-post.tsx
+++ b/ui/src/components/create-post.tsx
@@ -3,7 +3,7 @@ import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators';
import { PostForm } from './post-form';
import { toast, wsJsonToRes } from '../utils';
-import { WebSocketService } from '../services';
+import { WebSocketService, UserService } from '../services';
import {
UserOperation,
PostFormParams,
@@ -41,6 +41,11 @@ export class CreatePost extends Component<any, CreatePostState> {
this.handlePostCreate = this.handlePostCreate.bind(this);
this.state = this.emptyState;
+ if (!UserService.Instance.user) {
+ toast(i18n.t('not_logged_in'), 'danger');
+ this.context.router.history.push(`/login`);
+ }
+
this.subscription = WebSocketService.Instance.subject
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
.subscribe(
diff --git a/ui/src/components/create-private-message.tsx b/ui/src/components/create-private-message.tsx
index 21ed04c7..c309cbe3 100644
--- a/ui/src/components/create-private-message.tsx
+++ b/ui/src/components/create-private-message.tsx
@@ -2,7 +2,7 @@ import { Component } from 'inferno';
import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators';
import { PrivateMessageForm } from './private-message-form';
-import { WebSocketService } from '../services';
+import { WebSocketService, UserService } from '../services';
import {
UserOperation,
WebSocketJsonResponse,
@@ -20,6 +20,11 @@ export class CreatePrivateMessage extends Component<any, any> {
this
);
+ if (!UserService.Instance.user) {
+ toast(i18n.t('not_logged_in'), 'danger');
+ this.context.router.history.push(`/login`);
+ }
+
this.subscription = WebSocketService.Instance.subject
.pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
.subscribe(
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx
index fa2a078e..418fe7b4 100644
--- a/ui/src/components/post-listing.tsx
+++ b/ui/src/components/post-listing.tsx
@@ -33,6 +33,7 @@ import {
setupTippy,
hostname,
previewLines,
+ toast,
} from '../utils';
import { i18n } from '../i18next';
@@ -1032,6 +1033,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
}
handlePostLike(i: PostListing) {
+ if (!UserService.Instance.user) {
+ this.context.router.history.push(`/login`);
+ }
+
let new_vote = i.state.my_vote == 1 ? 0 : 1;
if (i.state.my_vote == 1) {
@@ -1059,6 +1064,10 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
}
handlePostDisLike(i: PostListing) {
+ if (!UserService.Instance.user) {
+ this.context.router.history.push(`/login`);
+ }
+
let new_vote = i.state.my_vote == -1 ? 0 : -1;
if (i.state.my_vote == 1) {