VUE

useClipboardMonitor Composable

Reactive clipboard monitoring with content change detection and permission checks

Vue3ComposablesClipboardMonitoringReactive

Code

import { ref, onMounted, onUnmounted } from 'vue';

export function useClipboardMonitor(
  interval = 1000,
  stopOnChange = false
) {
  const clipboardContent = ref<string | null>(null);
  const isMonitoring = ref(false);
  const hasPermission = ref(false);
  const error = ref<Error | null>(null);
  let intervalId: ReturnType<typeof setInterval> | null = null;

  // Check clipboard permission
  const checkPermission = __TOKEN_34__ () => {
    try {
      __TOKEN_36__ (!navigator.permissions || !navigator.clipboard) {
        hasPermission.value = false;
        error.value = new Error('Clipboard API not supported');
        return false;
      }

      const permission = await navigator.permissions.query({
        name: 'clipboard-read' as PermissionName
      });

      hasPermission.value = permission.state === 'granted';
      __TOKEN_41__ (permission.state === 'prompt') {
        // Request permission by reading clipboard
        await readClipboard();
      }
      return hasPermission.value;
    } __TOKEN_44__ (e) {
      error.value = e instanceof Error ? e : new Error('Failed to check permission');
      hasPermission.value = false;
      return false;
    }
  };

  // Read clipboard content
  const readClipboard = __TOKEN_49__ () => {
    try {
      const content = await navigator.clipboard.readText();
      // Check if content changed
      __TOKEN_53__ (content !== clipboardContent.value) {
        clipboardContent.value = content;
        __TOKEN_54__ (stopOnChange) {
          stopMonitoring();
        }
      }
      error.value = null;
      return content;
    } __TOKEN_56__ (e) {
      error.value = e instanceof Error ? e : new Error('Failed to read clipboard');
      return null;
    }
  };

  // Start monitoring
  const startMonitoring = __TOKEN_61__ () => {
    __TOKEN_62__ (isMonitoring.value) return;

    const permissionGranted = await checkPermission();
    __TOKEN_66__ (!permissionGranted) return;

    isMonitoring.value = true;
    // Initial read
    await readClipboard();
    // Set up interval
    intervalId = setInterval(readClipboard, interval);
  };

  // Stop monitoring
  const stopMonitoring = () => {
    isMonitoring.value = false;
    __TOKEN_70__ (intervalId) {
      clearInterval(intervalId);
      intervalId = null;
    }
  };

  // Toggle monitoring
  const toggleMonitoring = __TOKEN_72__ () => {
    __TOKEN_73__ (isMonitoring.value) {
      stopMonitoring();
    } else {
      await startMonitoring();
    }
  };

  // Cleanup
  onUnmounted(() => {
    stopMonitoring();
  });

  return {
    clipboardContent,
    isMonitoring,
    hasPermission,
    error,
    startMonitoring,
    stopMonitoring,
    toggleMonitoring,
    readClipboard
  };
}

// Usage example
// const { clipboardContent, startMonitoring } = useClipboardMonitor(500);
// startMonitoring();
// watch(clipboardContent, (content) => {
//   if (content) console.log('Clipboard changed:', content);
// });