useScan.ts 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import { tryOnBeforeMount, tryOnUnmounted, useDebounceFn } from '@vueuse/core';
  2. import type { BridgeEventMap } from '../../../@types/bridge';
  3. export type ScanData = NonNullable<BridgeEventMap['scan']['detail']['data']>;
  4. export const scanKey = Symbol() as InjectionKey<() => Promise<void>>;
  5. export function useScan(fn: (data: ScanData) => void) {
  6. const callback = useDebounceFn(fn, 300)
  7. let onCleanup = () => {};
  8. tryOnBeforeMount(async () => {
  9. if (window.bridge) {
  10. onCleanup = window.bridge.addEventListener('scan', (event) => {
  11. event.stopPropagation();
  12. event.preventDefault();
  13. if (event.detail.code !== 0 || !event.detail.data?.code) return;
  14. callback(event.detail.data);
  15. });
  16. } else if (window.platform) {
  17. const update = (event: CustomEvent) => {
  18. event.stopPropagation();
  19. event.preventDefault();
  20. if (!event.detail?.code) return;
  21. callback({ code: event.detail.code, state: 0, type: -1 });
  22. };
  23. platform.addEventListener('scan', update);
  24. onCleanup = () => platform.removeEventListener('scan', update);
  25. }
  26. });
  27. tryOnUnmounted(() => onCleanup?.());
  28. const scanValue = ref('');
  29. async function scan(code?: string) {
  30. if (code != null) return callback({ code, state: 0, type: -1 });
  31. try {
  32. const data = await Bridge.scan();
  33. if (data?.code) callback(data);
  34. } catch (e) {}
  35. }
  36. return { scanValue, scan };
  37. }