import { retryWhen, delay, take } from 'rxjs/operators';
import { PostForm as PostFormI, Post, PostResponse, UserOperation, Community, ListCommunitiesResponse, ListCommunitiesForm, SortType, SearchForm, SearchType, SearchResponse } from '../interfaces';
import { WebSocketService, UserService } from '../services';
-import { msgOp, getPageTitle } from '../utils';
+import { msgOp, getPageTitle, debounce } from '../utils';
import * as autosize from 'autosize';
interface PostFormProps {
<div class="form-group row">
<label class="col-sm-2 col-form-label">URL</label>
<div class="col-sm-10">
- <input type="url" class="form-control" value={this.state.postForm.url} onInput={linkEvent(this, this.handlePostUrlChange)} />
+ <input type="url" class="form-control" value={this.state.postForm.url} onInput={linkEvent(this, debounce(this.handlePostUrlChange))} />
{this.state.suggestedTitle &&
<div class="mt-1 text-muted small font-weight-bold pointer" onClick={linkEvent(this, this.copySuggestedTitle)}>copy suggested title: {this.state.suggestedTitle}</div>
}
<div class="form-group row">
<label class="col-sm-2 col-form-label">Title</label>
<div class="col-sm-10">
- <textarea value={this.state.postForm.name} onInput={linkEvent(this, this.handlePostNameChange)} class="form-control" required rows={2} minLength={3} maxLength={100} />
+ <textarea value={this.state.postForm.name} onInput={linkEvent(this, debounce(this.handlePostNameChange))} class="form-control" required rows={2} minLength={3} maxLength={100} />
{this.state.suggestedPosts.length > 0 &&
<>
<div class="my-1 text-muted small font-weight-bold">These posts might be related</div>
handlePostNameChange(i: PostForm, event: any) {
i.state.postForm.name = event.target.value;
-
let form: SearchForm = {
q: i.state.postForm.name,
type_: SearchType[SearchType.Posts],
return data;
}
+export function debounce(func: any, wait: number = 500, immediate: boolean = false) {
+ // 'private' variable for instance
+ // The returned function will be able to reference this due to closure.
+ // Each call to the returned function will share this common timer.
+ let timeout: number;
+
+ // Calling debounce returns a new anonymous function
+ return function() {
+ // reference the context and args for the setTimeout function
+ var context = this,
+ args = arguments;
+
+ // Should the function be called now? If immediate is true
+ // and not already in a timeout then the answer is: Yes
+ var callNow = immediate && !timeout;
+
+ // This is the basic debounce behaviour where you can call this
+ // function several times, but it will only execute once
+ // [before or after imposing a delay].
+ // Each time the returned function is called, the timer starts over.
+ clearTimeout(timeout);
+
+ // Set the new timeout
+ timeout = setTimeout(function() {
+
+ // Inside the timeout function, clear the timeout variable
+ // which will let the next execution run when in 'immediate' mode
+ timeout = null;
+
+ // Check if the function already ran with the immediate flag
+ if (!immediate) {
+ // Call the original function with apply
+ // apply lets you define the 'this' object as well as the arguments
+ // (both captured before setTimeout)
+ func.apply(context, args);
+ }
+ }, wait);
+
+ // Immediate mode and no wait timer? Execute the function..
+ if (callNow) func.apply(context, args);
+ }
+}