diff options
author | Dessalines <tyhou13@gmx.com> | 2019-08-03 13:26:20 -0700 |
---|---|---|
committer | Dessalines <tyhou13@gmx.com> | 2019-08-03 13:26:20 -0700 |
commit | 5a1e8aa645c9f0898e765b45c2f362308292db26 (patch) | |
tree | 67dc7b84232e1838327d0e95202b1fc58cf5d745 | |
parent | caf0af35392b7f044ed4603c4ac65e5c3e4604f8 (diff) |
Adding a debounce.
-rw-r--r-- | ui/src/components/post-form.tsx | 7 | ||||
-rw-r--r-- | ui/src/utils.ts | 42 |
2 files changed, 45 insertions, 4 deletions
diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx index 9b33c6e1..54b3ca44 100644 --- a/ui/src/components/post-form.tsx +++ b/ui/src/components/post-form.tsx @@ -4,7 +4,7 @@ import { Subscription } from "rxjs"; 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 { @@ -87,7 +87,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { <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> } @@ -96,7 +96,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { <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> @@ -166,7 +166,6 @@ export class PostForm extends Component<PostFormProps, PostFormState> { handlePostNameChange(i: PostForm, event: any) { i.state.postForm.name = event.target.value; - let form: SearchForm = { q: i.state.postForm.name, type_: SearchType[SearchType.Posts], diff --git a/ui/src/utils.ts b/ui/src/utils.ts index d0c7c89a..b9d9a389 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -117,3 +117,45 @@ export async function getPageTitle(url: string) { 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); + } +} |