diff options
author | Dessalines <tyhou13@gmx.com> | 2020-07-11 19:12:56 -0400 |
---|---|---|
committer | Dessalines <tyhou13@gmx.com> | 2020-07-11 19:12:56 -0400 |
commit | 60288b2d060ba930fe6cae22c4824d88fe7a00c9 (patch) | |
tree | 8fed01325853240c69f3688ee621be29bedfd382 /ui | |
parent | 1710844a1bc6a4f46eceaa12f2fb428cb794c694 (diff) | |
parent | 1b9f2fa5f7f7831f59b24cb36a5607a769a0d92e (diff) |
Merge branch 'master' into jmarthernandez-remove-karma-from-search
Diffstat (limited to 'ui')
52 files changed, 1696 insertions, 852 deletions
diff --git a/ui/assets/css/choices.min.css b/ui/assets/css/choices.min.css new file mode 100644 index 00000000..19adabab --- /dev/null +++ b/ui/assets/css/choices.min.css @@ -0,0 +1 @@ +.choices{position:relative;margin-bottom:24px;font-size:16px}.choices:focus{outline:0}.choices:last-child{margin-bottom:0}.choices.is-disabled .choices__inner,.choices.is-disabled .choices__input{background-color:#eaeaea;cursor:not-allowed;-webkit-user-select:none;-ms-user-select:none;user-select:none}.choices.is-disabled .choices__item{cursor:not-allowed}.choices [hidden]{display:none!important}.choices[data-type*=select-one]{cursor:pointer}.choices[data-type*=select-one] .choices__inner{padding-bottom:7.5px}.choices[data-type*=select-one] .choices__input{display:block;width:100%;padding:10px;border-bottom:1px solid #ddd;background-color:#fff;margin:0}.choices[data-type*=select-one] .choices__button{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==);padding:0;background-size:8px;position:absolute;top:50%;right:0;margin-top:-10px;margin-right:25px;height:20px;width:20px;border-radius:10em;opacity:.5}.choices[data-type*=select-one] .choices__button:focus,.choices[data-type*=select-one] .choices__button:hover{opacity:1}.choices[data-type*=select-one] .choices__button:focus{box-shadow:0 0 0 2px #00bcd4}.choices[data-type*=select-one] .choices__item[data-value=''] .choices__button{display:none}.choices[data-type*=select-one]:after{content:'';height:0;width:0;border-style:solid;border-color:#333 transparent transparent;border-width:5px;position:absolute;right:11.5px;top:50%;margin-top:-2.5px;pointer-events:none}.choices[data-type*=select-one].is-open:after{border-color:transparent transparent #333;margin-top:-7.5px}.choices[data-type*=select-one][dir=rtl]:after{left:11.5px;right:auto}.choices[data-type*=select-one][dir=rtl] .choices__button{right:auto;left:0;margin-left:25px;margin-right:0}.choices[data-type*=select-multiple] .choices__inner,.choices[data-type*=text] .choices__inner{cursor:text}.choices[data-type*=select-multiple] .choices__button,.choices[data-type*=text] .choices__button{position:relative;display:inline-block;margin:0 -4px 0 8px;padding-left:16px;border-left:1px solid #008fa1;background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==);background-size:8px;width:8px;line-height:1;opacity:.75;border-radius:0}.choices[data-type*=select-multiple] .choices__button:focus,.choices[data-type*=select-multiple] .choices__button:hover,.choices[data-type*=text] .choices__button:focus,.choices[data-type*=text] .choices__button:hover{opacity:1}.choices__inner{display:inline-block;vertical-align:top;width:100%;background-color:#f9f9f9;padding:7.5px 7.5px 3.75px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;min-height:44px;overflow:hidden}.is-focused .choices__inner,.is-open .choices__inner{border-color:#b7b7b7}.is-open .choices__inner{border-radius:2.5px 2.5px 0 0}.is-flipped.is-open .choices__inner{border-radius:0 0 2.5px 2.5px}.choices__list{margin:0;padding-left:0;list-style:none}.choices__list--single{display:inline-block;padding:4px 16px 4px 4px;width:100%}[dir=rtl] .choices__list--single{padding-right:4px;padding-left:16px}.choices__list--single .choices__item{width:100%}.choices__list--multiple{display:inline}.choices__list--multiple .choices__item{display:inline-block;vertical-align:middle;border-radius:20px;padding:4px 10px;font-size:12px;font-weight:500;margin-right:3.75px;margin-bottom:3.75px;background-color:#00bcd4;border:1px solid #00a5bb;color:#fff;word-break:break-all;box-sizing:border-box}.choices__list--multiple .choices__item[data-deletable]{padding-right:5px}[dir=rtl] .choices__list--multiple .choices__item{margin-right:0;margin-left:3.75px}.choices__list--multiple .choices__item.is-highlighted{background-color:#00a5bb;border:1px solid #008fa1}.is-disabled .choices__list--multiple .choices__item{background-color:#aaa;border:1px solid #919191}.choices__list--dropdown{visibility:hidden;z-index:1;position:absolute;width:100%;background-color:#fff;border:1px solid #ddd;top:100%;margin-top:-1px;border-bottom-left-radius:2.5px;border-bottom-right-radius:2.5px;overflow:hidden;word-break:break-all;will-change:visibility}.choices__list--dropdown.is-active{visibility:visible}.is-open .choices__list--dropdown{border-color:#b7b7b7}.is-flipped .choices__list--dropdown{top:auto;bottom:100%;margin-top:0;margin-bottom:-1px;border-radius:.25rem .25rem 0 0}.choices__list--dropdown .choices__list{position:relative;max-height:300px;overflow:auto;-webkit-overflow-scrolling:touch;will-change:scroll-position}.choices__list--dropdown .choices__item{position:relative;padding:10px;font-size:14px}[dir=rtl] .choices__list--dropdown .choices__item{text-align:right}@media (min-width:640px){.choices__list--dropdown .choices__item--selectable{padding-right:100px}.choices__list--dropdown .choices__item--selectable:after{content:attr(data-select-text);font-size:12px;opacity:0;position:absolute;right:10px;top:50%;transform:translateY(-50%)}[dir=rtl] .choices__list--dropdown .choices__item--selectable{text-align:right;padding-left:100px;padding-right:10px}[dir=rtl] .choices__list--dropdown .choices__item--selectable:after{right:auto;left:10px}}.choices__list--dropdown .choices__item--selectable.is-highlighted{background-color:#f2f2f2}.choices__list--dropdown .choices__item--selectable.is-highlighted:after{opacity:.5}.choices__item{cursor:default}.choices__item--selectable{cursor:pointer}.choices__item--disabled{cursor:not-allowed;-webkit-user-select:none;-ms-user-select:none;user-select:none;opacity:.5}.choices__heading{font-weight:600;font-size:12px;padding:10px;border-bottom:1px solid #f7f7f7;color:gray}.choices__button{text-indent:-9999px;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;background-color:transparent;background-repeat:no-repeat;background-position:center;cursor:pointer}.choices__button:focus,.choices__input:focus{outline:0}.choices__input{display:inline-block;vertical-align:baseline;background-color:#f9f9f9;font-size:14px;margin-bottom:5px;border:0;border-radius:0;max-width:100%;padding:4px 0 4px 2px}[dir=rtl] .choices__input{padding-right:2px;padding-left:0}.choices__placeholder{opacity:.5}
\ No newline at end of file diff --git a/ui/assets/css/main.css b/ui/assets/css/main.css index c1f004d7..9f744fb1 100644 --- a/ui/assets/css/main.css +++ b/ui/assets/css/main.css @@ -249,3 +249,25 @@ pre { white-space: pre-wrap; word-break: keep-all; } + +.form-control.search-input { + float: right !important; + transition: width 0.2s ease-out 0s !important; +} + +.show-input { + width: 13em !important; + +} +.hide-input { + background: transparent !important; + width: 0px !important; + padding: 0 !important; + } + +br.big { + display: block; + content: ""; + margin-top: 1rem; +} + diff --git a/ui/assets/css/selectr.min.css b/ui/assets/css/selectr.min.css deleted file mode 100644 index 78bab83f..00000000 --- a/ui/assets/css/selectr.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*!
- * Selectr 2.4.13
- * http://mobius.ovh/docs/selectr
- *
- * Released under the MIT license
- */
-.selectr-container li,.selectr-option,.selectr-tag{list-style:none}.selectr-container{position:relative}.selectr-hidden{position:absolute;overflow:hidden;clip:rect(0,0,0,0);width:1px;height:1px;margin:-1px;padding:0;border:0}.selectr-visible{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:11}.selectr-desktop.multiple .selectr-visible{display:none}.selectr-desktop.multiple.native-open .selectr-visible{top:100%;min-height:200px!important;height:auto;opacity:1;display:block}.selectr-container.multiple.selectr-mobile .selectr-selected{z-index:0}.selectr-selected{position:relative;z-index:1;box-sizing:border-box;width:100%;padding:7px 28px 7px 14px;cursor:pointer;border:1px solid #999;border-radius:3px;}.selectr-selected::before{position:absolute;top:50%;right:10px;width:0;height:0;content:'';-o-transform:rotate(0) translate3d(0,-50%,0);-ms-transform:rotate(0) translate3d(0,-50%,0);-moz-transform:rotate(0) translate3d(0,-50%,0);-webkit-transform:rotate(0) translate3d(0,-50%,0);transform:rotate(0) translate3d(0,-50%,0);border-width:4px 4px 0;border-style:solid;border-color:#6c7a86 transparent transparent}.selectr-container.native-open .selectr-selected::before,.selectr-container.open .selectr-selected::before{border-width:0 4px 4px;border-style:solid;border-color:transparent transparent #6c7a86}.selectr-label{display:none;overflow:hidden;width:100%;white-space:nowrap;text-overflow:ellipsis}.selectr-placeholder{color:#6c7a86}.selectr-tags{margin:0;padding:0;white-space:normal}.has-selected .selectr-tags{margin:0 0 -2px}.selectr-tag{position:relative;float:left;padding:2px 25px 2px 8px;margin:0 2px 2px 0;cursor:default;color:#fff;border:none;border-radius:10px;background:#acb7bf}.selectr-container.multiple.has-selected .selectr-selected{padding:5px 28px 5px 5px}.selectr-options-container{position:absolute;z-index:10000;top:calc(100% - 1px);left:0;display:none;box-sizing:border-box;width:100%;border-width:0 1px 1px;border-style:solid;border-color:transparent #999 #999;border-radius:0 0 3px 3px;}.selectr-container.open .selectr-options-container{display:block}.selectr-input-container{position:relative;display:none}.selectr-clear,.selectr-input-clear,.selectr-tag-remove{position:absolute;top:50%;right:22px;width:20px;height:20px;padding:0;cursor:pointer;-o-transform:translate3d(0,-50%,0);-ms-transform:translate3d(0,-50%,0);-moz-transform:translate3d(0,-50%,0);-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0);border:none;background-color:transparent;z-index:11}.selectr-clear,.selectr-input-clear{display:none}.selectr-container.has-selected .selectr-clear,.selectr-input-container.active,.selectr-input-container.active .selectr-clear,.selectr-input-container.active .selectr-input-clear{display:block}.selectr-selected .selectr-tag-remove{right:2px}.selectr-clear::after,.selectr-clear::before,.selectr-input-clear::after,.selectr-input-clear::before,.selectr-tag-remove::after,.selectr-tag-remove::before{position:absolute;top:5px;left:9px;width:2px;height:10px;content:' ';background-color:#6c7a86}.selectr-tag-remove::after,.selectr-tag-remove::before{top:4px;width:3px;height:12px;}.selectr-clear:before,.selectr-input-clear::before,.selectr-tag-remove::before{-o-transform:rotate(45deg);-ms-transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg)}.selectr-clear:after,.selectr-input-clear::after,.selectr-tag-remove::after{-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.selectr-input{top:5px;left:5px;box-sizing:border-box;width:calc(100% - 30px);margin:10px 15px;padding:7px 30px 7px 9px;border:1px solid #999;border-radius:3px}.selectr-notice{display:none;box-sizing:border-box;width:100%;padding:8px 16px;border-top:1px solid #999;border-radius:0 0 3px 3px;}.input-tag,.taggable .selectr-label{width:auto}.selectr-container.notice .selectr-notice{display:block}.selectr-container.notice .selectr-selected{border-radius:3px 3px 0 0}.selectr-options{position:relative;top:calc(100% + 2px);display:none;overflow-x:auto;overflow-y:scroll;max-height:200px;margin:0;padding:0}.selectr-container.notice .selectr-options-container,.selectr-container.open .selectr-input-container,.selectr-container.open .selectr-options{display:block}.selectr-option{position:relative;display:block;padding:5px 20px;cursor:pointer;font-weight:400}.has-selected .selectr-placeholder,.selectr-empty,.selectr-option.excluded{display:none}.selectr-options.optgroups>.selectr-option{padding-left:25px}.selectr-optgroup{font-weight:700;padding:0}.selectr-optgroup--label{font-weight:700;margin-top:10px;padding:5px 15px}.selectr-match{text-decoration:underline}.selectr-option.selected{background-color:#ddd}.selectr-option.active{color:#fff;background-color:#5897fb}.selectr-option.disabled{opacity:.4}.selectr-container.open .selectr-selected{border-color:#999 #999 transparent;border-radius:3px 3px 0 0}.selectr-container.open .selectr-selected::after{-o-transform:rotate(180deg) translate3d(0,50%,0);-ms-transform:rotate(180deg) translate3d(0,50%,0);-moz-transform:rotate(180deg) translate3d(0,50%,0);-webkit-transform:rotate(180deg) translate3d(0,50%,0);transform:rotate(180deg) translate3d(0,50%,0)}.selectr-disabled{opacity:.6}.has-selected .selectr-label{display:block}.taggable .selectr-selected{padding:4px 28px 4px 4px}.taggable .selectr-selected::after{display:table;content:" ";clear:both}.taggable .selectr-tags{float:left;display:block}.taggable .selectr-placeholder{display:none}.input-tag{float:left;min-width:90px}.selectr-tag-input{border:none;padding:3px 10px;width:100%;font-family:inherit;font-weight:inherit;font-size:inherit}.selectr-input-container.loading::after{position:absolute;top:50%;right:20px;width:20px;height:20px;content:'';-o-transform:translate3d(0,-50%,0);-ms-transform:translate3d(0,-50%,0);-moz-transform:translate3d(0,-50%,0);-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0);-o-transform-origin:50% 0 0;-ms-transform-origin:50% 0 0;-moz-transform-origin:50% 0 0;-webkit-transform-origin:50% 0 0;transform-origin:50% 0 0;-moz-animation:.5s linear 0s normal forwards infinite running spin;-webkit-animation:.5s linear 0s normal forwards infinite running spin;animation:.5s linear 0s normal forwards infinite running spin;border-width:3px;border-style:solid;border-color:#aaa #ddd #ddd;border-radius:50%}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0) translate3d(0,-50%,0);transform:rotate(0) translate3d(0,-50%,0)}100%{-webkit-transform:rotate(360deg) translate3d(0,-50%,0);transform:rotate(360deg) translate3d(0,-50%,0)}}@keyframes spin{0%{-webkit-transform:rotate(0) translate3d(0,-50%,0);transform:rotate(0) translate3d(0,-50%,0)}100%{-webkit-transform:rotate(360deg) translate3d(0,-50%,0);transform:rotate(360deg) translate3d(0,-50%,0)}}.selectr-container.open.inverted .selectr-selected{border-color:transparent #999 #999;border-radius:0 0 3px 3px}.selectr-container.inverted .selectr-options-container{border-width:1px 1px 0;border-color:#999 #999 transparent;border-radius:3px 3px 0 0;top:auto;bottom:calc(100% - 1px)}.selectr-container ::-webkit-input-placeholder{color:#6c7a86;opacity:1}.selectr-container ::-moz-placeholder{color:#6c7a86;opacity:1}.selectr-container :-ms-input-placeholder{color:#6c7a86;opacity:1}.selectr-container ::placeholder{color:#6c7a86;opacity:1}
@@ -6,12 +6,10 @@ const { WebIndexPlugin, QuantumPlugin, } = require('fuse-box'); -// const transformInferno = require('../../dist').default const transformInferno = require('ts-transform-inferno').default; const transformClasscat = require('ts-transform-classcat').default; let fuse, app; let isProduction = false; -// var setVersion = require('./set_version.js').setVersion; Sparky.task('config', _ => { fuse = new FuseBox({ @@ -45,18 +43,18 @@ Sparky.task('config', _ => { }); app = fuse.bundle('app').instructions('>index.tsx'); }); -// Sparky.task('version', _ => setVersion()); Sparky.task('clean', _ => Sparky.src('dist/').clean('dist/')); Sparky.task('env', _ => (isProduction = true)); Sparky.task('copy-assets', () => Sparky.src('assets/**/**.*').dest(isProduction ? 'dist/' : 'dist/static') ); Sparky.task('dev', ['clean', 'config', 'copy-assets'], _ => { - fuse.dev(); + fuse.dev({ + fallback: 'index.html', + }); app.hmr().watch(); return fuse.run(); }); Sparky.task('prod', ['clean', 'env', 'config', 'copy-assets'], _ => { - // fuse.dev({ reload: true }); // remove after demo return fuse.run(); }); diff --git a/ui/package.json b/ui/package.json index 0101ce13..1bd07e86 100644 --- a/ui/package.json +++ b/ui/package.json @@ -15,7 +15,6 @@ }, "keywords": [], "dependencies": { - "@joeattardi/emoji-button": "^2.12.1", "@types/autosize": "^3.0.6", "@types/js-cookie": "^2.2.6", "@types/jwt-decode": "^2.2.1", @@ -24,6 +23,7 @@ "@types/node": "^13.11.1", "autosize": "^4.0.2", "bootswatch": "^4.3.1", + "choices.js": "^9.0.1", "classcat": "^4.0.2", "dotenv": "^8.2.0", "emoji-short-name": "^1.0.0", @@ -37,7 +37,6 @@ "markdown-it": "^10.0.0", "markdown-it-container": "^2.0.0", "markdown-it-emoji": "^1.4.0", - "mobius1-selectr": "^2.4.13", "moment": "^2.24.0", "node-fetch": "^2.6.0", "prettier": "^2.0.4", @@ -47,7 +46,6 @@ "tippy.js": "^6.1.1", "toastify-js": "^1.7.0", "tributejs": "^5.1.3", - "twemoji": "^12.1.2", "ws": "^7.2.3" }, "devDependencies": { @@ -72,7 +70,7 @@ "engineStrict": true, "husky": { "hooks": { - "pre-commit": "cargo clippy --manifest-path ../server/Cargo.toml --all-targets --all-features -- -D warnings && lint-staged" + "pre-commit": "cargo clippy --manifest-path ../server/Cargo.toml --all-targets --workspace -- -D warnings && lint-staged" } }, "lint-staged": { diff --git a/ui/src/components/cake-day.tsx b/ui/src/components/cake-day.tsx new file mode 100644 index 00000000..f28be33c --- /dev/null +++ b/ui/src/components/cake-day.tsx @@ -0,0 +1,25 @@ +import { Component } from 'inferno'; +import { i18n } from '../i18next'; + +interface CakeDayProps { + creatorName: string; +} + +export class CakeDay extends Component<CakeDayProps, any> { + render() { + return ( + <div + className={`mx-2 d-inline-block unselectable pointer`} + data-tippy-content={this.cakeDayTippy()} + > + <svg class="icon icon-inline"> + <use xlinkHref="#icon-cake"></use> + </svg> + </div> + ); + } + + cakeDayTippy(): string { + return i18n.t('cake_day_info', { creator_name: this.props.creatorName }); + } +} diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx index 61ee3d77..04720cbb 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'; @@ -17,7 +18,6 @@ import { toast, setupTribute, wsJsonToRes, - emojiPicker, pictrsDeleteToast, } from '../utils'; import { WebSocketService, UserService } from '../services'; @@ -25,6 +25,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; @@ -72,7 +73,6 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { super(props, context); this.tribute = setupTribute(); - this.setupEmojiPicker(); this.state = this.emptyState; @@ -98,18 +98,45 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { } componentDidMount() { - var 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); - }); + let textarea: any = document.getElementById(this.id); + 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); + } + + textarea.focus(); + } + } + + componentDidUpdate() { + if (this.state.commentForm.content) { + window.onbeforeunload = () => true; + } else { + window.onbeforeunload = undefined; + } } componentWillUnmount() { this.subscription.unsubscribe(); + window.onbeforeunload = null; } render() { @@ -119,133 +146,123 @@ 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)} |