]> Untitled Git - lemmy.git/commitdiff
Adding a debounce.
authorDessalines <tyhou13@gmx.com>
Sat, 3 Aug 2019 20:26:20 +0000 (13:26 -0700)
committerDessalines <tyhou13@gmx.com>
Sat, 3 Aug 2019 20:26:20 +0000 (13:26 -0700)
ui/src/components/post-form.tsx
ui/src/utils.ts

index 9b33c6e14c6ef9d5f6f52324dd8b49cf0cf53bae..54b3ca44004bcea88904c14d46584043b2dc80d9 100644 (file)
@@ -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],
index d0c7c89a61b6e3c491525f3fbdf95a45a1e3efe0..b9d9a38994d25262453ac71a266d42646af564f4 100644 (file)
@@ -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);
+  }
+}