preface

Because to complete the clipboard history function, after consulting the electron clipboard document. No clipboard change hook event was found, so I decided to implement one myself.

Electron has an API for reading clipboard content that encapsulates the listener timer method. The specific logic is as follows:

Use timer to constantly judge whether the content is the same, such as different. Execute the clipboard change callback

Write a clipboard observer class that instantiates incoming message/picture change callbacks for listening, and needs to support incoming custom listening intervals because frequent fetching of clipboard content can be a performance burden.

The returned instance should support methods to pause and continue listening.

Write clipboard observer classes

First define the interface for the constructor parameters

import { clipboard, NativeImage } from 'electron';

interface Options {
  // Interval for the timer to obtain content judgmentduration? :number;
  // Text change callbacktextChange? :(text: string, beforeText: string) = > void;
  // Image change callbackimageChange? :(image: NativeImage, beforeImage: NativeImage) = > void;
}
Copy the code

Next, you define the class and write the logic and exposed APIS that handle parameter passing in the constructor

class ClipboardObserver {
  / / timer
  timer: NodeJS.Timeout;
  // Text before change (used to compare newly acquired clipboard text)
  beforeText: string;
  // Change the image to go (to compare the newly acquired clipboard image)
  beforeImage: NativeImage;

  duration = 500;
  textChange: (text: string, beforeText: string) = > void;
  imageChange: (image: NativeImage, beforeImage: NativeImage) = > void;

  constructor(options: Options) {
    // Get the incoming configuration and save it to the properties
    const { duration, textChange, imageChange } = options;

    this.duration = duration;
    this.textChange = textChange;
    this.imageChange = imageChange;

    // Determine the incoming callback and start the timer by default
    if (this.textChange || this.imageChange) {
      this.start(); }}/** * start */
  start(): void {
    // Record the current contents of the clipboard
    this.setClipboardDefaultValue();
    // Set the timer
    this.setTimer();
  }

  /** * pause */
  stop(): void {
    // Clear the timer
    this.setTimer(); }}Copy the code

ClearTimer is responsible for calling clearInterval to clear the timer, and setClipboardDefaultValue is responsible for setting the last change recorded in the instance.

class ClipboardObserver {.../**
   * 清除定时器
   */
  clearTimer(): void {
    clearInterval(this.timer);
  }

  /** * Sets the clipboard default contents */
  setClipboardDefaultValue(): void {
    if (this.textChange) {
      // The electron clipboard reads the text method
      this.beforeText = clipboard.readText();
    }
    if (this.imageChange) {
      // The electron clipboard reads the image method
      this.beforeImage = clipboard.readImage(); }}}Copy the code

SetTimer is responsible for comparing the core logic, setting the timer, and determining whether the content has changed during each timer callback. If the content changes, perform the content change callback.

class ClipboardObserver {.../** * Set timer */
  setTimer(): void {
    // Set the timer
    this.timer = setInterval(() = > {
      if (this.textChange) {
        const text = clipboard.readText();
        // Determine if the content is different from the last read
        if (this.isDiffText(this.beforeText, text)) {
          // Perform the change callback
          this.textChange(text, this.beforeText);
          // Record the contents
          this.beforeText = text; }}if (this.imageChange) {
        const image = clipboard.readImage();
        // Determine if the content is different from the last read
        if (this.isDiffImage(this.beforeImage, image)) {
          // Perform the change callback
          this.imageChange(image, this.beforeImage);
          // Record the contents
          this.beforeImage = image; }}},this.duration);
  }

  /** * Determine if the content is inconsistent *@param beforeText
   * @param afterText
   * @returns* /
  isDiffText(beforeText: string.afterText: string) :boolean {
    returnafterText && beforeText ! == afterText; }/** * Determine if the image is inconsistent *@param beforeImage
   * @param afterImage
   * @returns* /
  isDiffImage(beforeImage: NativeImage, afterImage: NativeImage): boolean {
    returnafterImage && ! afterImage.isEmpty() && beforeImage.toDataURL() ! == afterImage.toDataURL(); }}Copy the code

Finished work

At this point, the logic for the Clipboard observer class is complete. We can eat this in our code

const clipboardObserver = new ClipboardObserver({
  textChange: (text: string, beforeText: string) = > {
    // Handle the logic of text changes
  },
  imageChange: (image: Electron.NativeImage, beforeText: Electron.NativeImage) = > {
    // Handle image change logic}});// It can also be paused
clipboardObserver.stop();

// You can start again
clipboardObserver.start();
Copy the code

The project has been open-source to the electron- Clipboard-Observer. You can copy code to your project for use

You can also install the autoelectron-Clipboard-Observer in your project.

NPM install electric-clipboard-observer or YARN add electric-clipboard-observerCopy the code

use

import ClipboardObserver from "electron-clipboard-observer"

const clipboardObserver = new ClipboardObserver({
    textChange() {},
    imageChange(){}})Copy the code

The project address

Code warehouse

npm