mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-23 19:31:33 +00:00
Add image loading indicator.
This commit is contained in:
parent
4672e9b783
commit
3444c70313
4 changed files with 46 additions and 9 deletions
22
ui/src/components/comment-form.tsx
vendored
22
ui/src/components/comment-form.tsx
vendored
|
@ -1,7 +1,7 @@
|
|||
import { Component, linkEvent } from 'inferno';
|
||||
import { CommentNode as CommentNodeI, CommentForm as CommentFormI, SearchForm, SearchType, SortType, UserOperation, SearchResponse } from '../interfaces';
|
||||
import { Subscription } from "rxjs";
|
||||
import { capitalizeFirstLetter, mentionDropdownFetchLimit, msgOp, mdToHtml, randomStr, imageUploadUrl, markdownHelpUrl } from '../utils';
|
||||
import { capitalizeFirstLetter, mentionDropdownFetchLimit, msgOp, mdToHtml, randomStr, markdownHelpUrl } from '../utils';
|
||||
import { WebSocketService, UserService } from '../services';
|
||||
import * as autosize from 'autosize';
|
||||
import { i18n } from '../i18next';
|
||||
|
@ -21,6 +21,7 @@ interface CommentFormState {
|
|||
commentForm: CommentFormI;
|
||||
buttonTitle: string;
|
||||
previewMode: boolean;
|
||||
imageLoading: boolean;
|
||||
}
|
||||
|
||||
export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
||||
|
@ -38,6 +39,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
|||
},
|
||||
buttonTitle: !this.props.node ? capitalizeFirstLetter(i18n.t('post')) : this.props.edit ? capitalizeFirstLetter(i18n.t('edit')) : capitalizeFirstLetter(i18n.t('reply')),
|
||||
previewMode: false,
|
||||
imageLoading: false,
|
||||
}
|
||||
|
||||
constructor(props: any, context: any) {
|
||||
|
@ -134,12 +136,15 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
|||
{this.state.commentForm.content &&
|
||||
<button className={`btn btn-sm mr-2 btn-secondary ${this.state.previewMode && 'active'}`} onClick={linkEvent(this, this.handlePreviewToggle)}><T i18nKey="preview">#</T></button>
|
||||
}
|
||||
{this.props.node && <button type="button" class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.handleReplyCancel)}><T i18nKey="cancel">#</T></button>}
|
||||
{this.props.node && <button type="button" class="btn btn-sm btn-secondary mr-2" onClick={linkEvent(this, this.handleReplyCancel)}><T i18nKey="cancel">#</T></button>}
|
||||
<a href={markdownHelpUrl} target="_blank" class="d-inline-block float-right text-muted small font-weight-bold"><T i18nKey="formatting_help">#</T></a>
|
||||
<form class="d-inline-block mr-2 float-right text-muted small font-weight-bold">
|
||||
<label htmlFor={`file-upload-${this.id}`} class="pointer"><T i18nKey="upload_image">#</T></label>
|
||||
<input id={`file-upload-${this.id}`} type="file" name="file" class="d-none" onChange={linkEvent(this, this.handleImageUpload)} />
|
||||
<input id={`file-upload-${this.id}`} type="file" accept="image/*,video/*" name="file" class="d-none" onChange={linkEvent(this, this.handleImageUpload)} />
|
||||
</form>
|
||||
{this.state.imageLoading &&
|
||||
<svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -187,6 +192,10 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
|||
const imageUploadUrl = `/pictshare/api/upload.php`;
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
i.state.imageLoading = true;
|
||||
i.setState(i.state);
|
||||
|
||||
fetch(imageUploadUrl, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
|
@ -198,9 +207,14 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
|||
let content = i.state.commentForm.content;
|
||||
content = (content) ? `${content} ${markdown}` : markdown;
|
||||
i.state.commentForm.content = content;
|
||||
i.state.imageLoading = false;
|
||||
i.setState(i.state);
|
||||
})
|
||||
.catch((error) => alert(error));
|
||||
.catch((error) => {
|
||||
i.state.imageLoading = false;
|
||||
i.setState(i.state);
|
||||
alert(error);
|
||||
})
|
||||
}
|
||||
|
||||
userSearch(text: string, cb: any) {
|
||||
|
|
21
ui/src/components/post-form.tsx
vendored
21
ui/src/components/post-form.tsx
vendored
|
@ -4,7 +4,7 @@ import { Subscription } from "rxjs";
|
|||
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||
import { PostForm as PostFormI, PostFormParams, Post, PostResponse, UserOperation, Community, ListCommunitiesResponse, ListCommunitiesForm, SortType, SearchForm, SearchType, SearchResponse } from '../interfaces';
|
||||
import { WebSocketService, UserService } from '../services';
|
||||
import { msgOp, getPageTitle, debounce, validURL, capitalizeFirstLetter, imageUploadUrl, markdownHelpUrl, mdToHtml } from '../utils';
|
||||
import { msgOp, getPageTitle, debounce, validURL, capitalizeFirstLetter, markdownHelpUrl, mdToHtml } from '../utils';
|
||||
import * as autosize from 'autosize';
|
||||
import { i18n } from '../i18next';
|
||||
import { T } from 'inferno-i18next';
|
||||
|
@ -21,6 +21,7 @@ interface PostFormState {
|
|||
postForm: PostFormI;
|
||||
communities: Array<Community>;
|
||||
loading: boolean;
|
||||
imageLoading: boolean;
|
||||
previewMode: boolean;
|
||||
suggestedTitle: string;
|
||||
suggestedPosts: Array<Post>;
|
||||
|
@ -40,6 +41,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
},
|
||||
communities: [],
|
||||
loading: false,
|
||||
imageLoading: false,
|
||||
previewMode: false,
|
||||
suggestedTitle: undefined,
|
||||
suggestedPosts: [],
|
||||
|
@ -111,8 +113,11 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
}
|
||||
<form>
|
||||
<label htmlFor="file-upload" class="pointer d-inline-block mr-2 float-right text-muted small font-weight-bold"><T i18nKey="upload_image">#</T></label>
|
||||
<input id="file-upload" type="file" name="file" class="d-none" onChange={linkEvent(this, this.handleImageUpload)} />
|
||||
<input id="file-upload" type="file" accept="image/*,video/*" name="file" class="d-none" onChange={linkEvent(this, this.handleImageUpload)} />
|
||||
</form>
|
||||
{this.state.imageLoading &&
|
||||
<svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg>
|
||||
}
|
||||
{this.state.crossPosts.length > 0 &&
|
||||
<>
|
||||
<div class="my-1 text-muted small font-weight-bold"><T i18nKey="cross_posts">#</T></div>
|
||||
|
@ -275,6 +280,10 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
const imageUploadUrl = `/pictshare/api/upload.php`;
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
i.state.imageLoading = true;
|
||||
i.setState(i.state);
|
||||
|
||||
fetch(imageUploadUrl, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
|
@ -285,11 +294,15 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
|||
if (res.filetype == 'mp4') {
|
||||
url += '/raw';
|
||||
}
|
||||
|
||||
i.state.postForm.url = url;
|
||||
i.state.imageLoading = false;
|
||||
i.setState(i.state);
|
||||
})
|
||||
.catch((error) => alert(error));
|
||||
.catch((error) => {
|
||||
i.state.imageLoading = false;
|
||||
i.setState(i.state);
|
||||
alert(error);
|
||||
})
|
||||
}
|
||||
|
||||
parseMessage(msg: any) {
|
||||
|
|
1
ui/src/utils.ts
vendored
1
ui/src/utils.ts
vendored
|
@ -15,7 +15,6 @@ import * as twemoji from 'twemoji';
|
|||
import * as emojiShortName from 'emoji-short-name';
|
||||
|
||||
export const repoUrl = 'https://github.com/dessalines/lemmy';
|
||||
export const imageUploadUrl = 'https://postimages.org/';
|
||||
export const markdownHelpUrl = 'https://commonmark.org/help/';
|
||||
|
||||
export const fetchLimit: number = 20;
|
||||
|
|
11
ui/tmp
vendored
Normal file
11
ui/tmp
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
lang | done | missing
|
||||
--- | --- | ---
|
||||
de | 86% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,settings,banned,subscribed,expires,recent_comments,nsfw,show_nsfw,crypto,monero,joined,by,to,transfer_community,transfer_site,are_you_sure,yes,no
|
||||
eo | 95% | number_of_communities,preview,upload_image,formatting_help,banned,are_you_sure,yes,no
|
||||
es | 95% | number_of_communities,preview,upload_image,formatting_help,banned,are_you_sure,yes,no
|
||||
fr | 100% |
|
||||
nl | 98% | preview,upload_image,formatting_help,banned
|
||||
ru | 91% | cross_posts,cross_post,number_of_communities,preview,upload_image,formatting_help,banned,recent_comments,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no
|
||||
sv | 98% | preview,upload_image,formatting_help,banned
|
||||
zh | 89% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,formatting_help,settings,banned,recent_comments,nsfw,show_nsfw,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no
|
||||
|
Loading…
Reference in a new issue