@feugene/granularity-media 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -6
- package/dist/chunks/config-DfJkKtIh.js +27 -0
- package/dist/chunks/{en-C-Wc5fTB.js → en-BugobSAO.js} +12 -4
- package/dist/chunks/{es-BUPtE9_0.js → es-B7iA-ExH.js} +12 -4
- package/dist/chunks/ru-DSjpFh8N.js +4 -0
- package/dist/chunks/{ru-BqNILj54.js → ru-DpiW6Vax.js} +12 -4
- package/dist/chunks/useCameraStream-CPdm3r90.js +86 -0
- package/dist/components/GrCameraCapture/chunks/GrCameraCapture-t-uFTD9s.js +134 -0
- package/dist/components/GrCameraCapture/index.js +4 -3
- package/dist/components/GrCodeScanner/chunks/GrCodeScanner-BX147Gct.js +162 -0
- package/dist/components/GrCodeScanner/index.js +3 -0
- package/dist/granular-provider.js +13 -11
- package/dist/i18n/all.js +1 -1
- package/dist/i18n/index.js +4 -4
- package/dist/index.js +8 -5
- package/dist/resolver.js +5 -1
- package/dist/types/componentNames.d.ts +1 -1
- package/dist/types/components/GrCameraCapture/GrCameraCapture.vue.d.ts +3 -5
- package/dist/types/components/GrCodeScanner/GrCodeScanner.vue.d.ts +121 -0
- package/dist/types/components/GrCodeScanner/__tests__/GrCodeScanner.test.d.ts +1 -0
- package/dist/types/components/GrCodeScanner/__tests__/codeDetection.test.d.ts +1 -0
- package/dist/types/components/GrCodeScanner/codeDetection.d.ts +42 -0
- package/dist/types/components/GrCodeScanner/config.d.ts +5 -0
- package/dist/types/components/GrCodeScanner/defaults.d.ts +16 -0
- package/dist/types/components/GrCodeScanner/grCodeScannerStyles.d.ts +19 -0
- package/dist/types/components/GrCodeScanner/index.d.ts +9 -0
- package/dist/types/granular-provider/shared.d.ts +1 -0
- package/dist/types/i18n/index.d.ts +21 -0
- package/dist/types/i18n/messages/en.d.ts +14 -0
- package/dist/types/i18n/messages/es.d.ts +14 -0
- package/dist/types/i18n/messages/ru.d.ts +14 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/internal/useCameraStream.d.ts +30 -0
- package/package.json +5 -1
- package/dist/chunks/ru-DN_wJDkP.js +0 -4
- package/dist/components/GrCameraCapture/chunks/GrCameraCapture-CoSuBEfS.js +0 -182
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# `@feugene/granularity-media`
|
|
2
2
|
|
|
3
|
-
Работа с изображением и камерой для `@feugene/granularity`.
|
|
4
|
-
стоят рядом по сценарию: `GrCameraCapture` снимает кадр камерой,
|
|
5
|
-
|
|
6
|
-
`Blob
|
|
3
|
+
Работа с изображением и камерой для `@feugene/granularity`. Три компонента, и они
|
|
4
|
+
стоят рядом по сценарию: `GrCameraCapture` снимает кадр камерой, `GrImageCrop`
|
|
5
|
+
выбирает кадр из уже существующей картинки, `GrCodeScanner` читает камерой QR и
|
|
6
|
+
штрихкоды. Первые два отдают готовый `Blob`, третий — содержимое кода.
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
9
|
yarn add @feugene/granularity-media
|
|
@@ -95,9 +95,26 @@ presetGranularNode({
|
|
|
95
95
|
Превью фронтальной камеры зеркальное, снимок — нет: иначе текст на визитке или в
|
|
96
96
|
документе уехал бы в зазеркалье.
|
|
97
97
|
|
|
98
|
+
## Чтение кодов
|
|
99
|
+
|
|
100
|
+
```vue
|
|
101
|
+
<GrCodeScanner :formats="['qr_code']" @detect="codes => open(codes[0].value)" />
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Декодера пакет не несёт. Нативный `BarcodeDetector` есть в Chrome и Edge, а
|
|
105
|
+
Safari и Firefox закрываются детектором, который передаёт приложение
|
|
106
|
+
(`:detector`): встроить библиотеку значило бы навязать самую тяжёлую
|
|
107
|
+
зависимость и тем, кто взял один кроп. Готовый рецепт на `@zxing/browser` — на
|
|
108
|
+
странице компонента.
|
|
109
|
+
|
|
110
|
+
Один код в кадре даёт одно событие: камера отдаёт десятки кадров в секунду, и
|
|
111
|
+
без фильтра приложение оформило бы двадцать заказов вместо одного. Режим
|
|
112
|
+
приёмки, где сканируют одинаковые упаковки подряд, включается `continuous`.
|
|
113
|
+
|
|
98
114
|
## Документация
|
|
99
115
|
|
|
100
116
|
- [`docs/components.md`](./docs/components.md) — состав пакета;
|
|
101
|
-
- [`docs/components/GrImageCrop.md`](./docs/components/GrImageCrop.md)
|
|
102
|
-
[`docs/components/GrCameraCapture.md`](./docs/components/GrCameraCapture.md)
|
|
117
|
+
- [`docs/components/GrImageCrop.md`](./docs/components/GrImageCrop.md),
|
|
118
|
+
[`docs/components/GrCameraCapture.md`](./docs/components/GrCameraCapture.md) и
|
|
119
|
+
[`docs/components/GrCodeScanner.md`](./docs/components/GrCodeScanner.md) — страницы компонентов;
|
|
103
120
|
- [`docs/keyboard.md`](./docs/keyboard.md), [`docs/ssr.md`](./docs/ssr.md) — сквозные правила пакета.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { t as e } from "./classTokens-bAzTjLuQ.js";
|
|
2
|
+
import { defineGranularComponent as t } from "@feugene/unocss-preset-granular/contract";
|
|
3
|
+
//#region src/components/GrCodeScanner/grCodeScannerStyles.ts
|
|
4
|
+
var n = "grid gap-2", r = "relative w-full overflow-hidden rounded-[var(--gr-radius-md)] border border-[var(--gr-brd)] bg-[var(--gr-muted)]", i = "h-full w-full object-contain", a = "pointer-events-none absolute inset-[15%] rounded-[var(--gr-radius-md)] border-2 border-[var(--gr-code-scanner-reticle,var(--gr-primary))]", o = "absolute inset-0 grid place-content-center gap-3 p-4 text-center transition-opacity duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]", s = "text-[var(--gr-muted-fg)]", c = "flex flex-wrap items-center gap-2", l = {
|
|
5
|
+
xs: "text-[length:var(--gr-control-text-xs)] leading-[var(--gr-control-leading-xs)]",
|
|
6
|
+
sm: "text-[length:var(--gr-control-text-sm)] leading-[var(--gr-control-leading-sm)]",
|
|
7
|
+
md: "text-[length:var(--gr-control-text-md)] leading-[var(--gr-control-leading-md)]",
|
|
8
|
+
lg: "text-[length:var(--gr-control-text-lg)] leading-[var(--gr-control-leading-lg)]"
|
|
9
|
+
}, u = [
|
|
10
|
+
...e(n),
|
|
11
|
+
...e(r),
|
|
12
|
+
...e(i),
|
|
13
|
+
...e(a),
|
|
14
|
+
...e(o),
|
|
15
|
+
...e(s),
|
|
16
|
+
...e(c),
|
|
17
|
+
...Object.values(l).flatMap(e)
|
|
18
|
+
], d = t(import.meta.url, {
|
|
19
|
+
name: "GrCodeScanner",
|
|
20
|
+
safelist: u,
|
|
21
|
+
dependencies: [{
|
|
22
|
+
provider: "@feugene/granularity",
|
|
23
|
+
components: ["GrButton"]
|
|
24
|
+
}]
|
|
25
|
+
});
|
|
26
|
+
//#endregion
|
|
27
|
+
export { a, o as c, u as i, s as l, c as n, n as o, r, l as s, d as t, i as u };
|
|
@@ -2,8 +2,9 @@ import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
|
|
|
2
2
|
//#region src/i18n/locales/en.json
|
|
3
3
|
var t = /* @__PURE__ */ e({
|
|
4
4
|
camera: () => r,
|
|
5
|
-
default: () =>
|
|
6
|
-
imageCrop: () => n
|
|
5
|
+
default: () => a,
|
|
6
|
+
imageCrop: () => n,
|
|
7
|
+
scanner: () => i
|
|
7
8
|
}), n = {
|
|
8
9
|
label: "Image crop",
|
|
9
10
|
frame: "Frame: arrow keys move the image, plus and minus zoom",
|
|
@@ -25,8 +26,15 @@ var t = /* @__PURE__ */ e({
|
|
|
25
26
|
live: "Camera is on",
|
|
26
27
|
captured: "Photo taken"
|
|
27
28
|
}, i = {
|
|
29
|
+
label: "Code scanner",
|
|
30
|
+
start: "Start scanning",
|
|
31
|
+
stop: "Stop",
|
|
32
|
+
unsupported: "This browser cannot read codes. Pass a `detector` to enable it.",
|
|
33
|
+
detected: "Code recognised"
|
|
34
|
+
}, a = {
|
|
28
35
|
imageCrop: n,
|
|
29
|
-
camera: r
|
|
36
|
+
camera: r,
|
|
37
|
+
scanner: i
|
|
30
38
|
};
|
|
31
39
|
//#endregion
|
|
32
|
-
export { t as n,
|
|
40
|
+
export { t as n, a as t };
|
|
@@ -2,8 +2,9 @@ import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
|
|
|
2
2
|
//#region src/i18n/locales/es.json
|
|
3
3
|
var t = /* @__PURE__ */ e({
|
|
4
4
|
camera: () => r,
|
|
5
|
-
default: () =>
|
|
6
|
-
imageCrop: () => n
|
|
5
|
+
default: () => a,
|
|
6
|
+
imageCrop: () => n,
|
|
7
|
+
scanner: () => i
|
|
7
8
|
}), n = {
|
|
8
9
|
label: "Recorte de imagen",
|
|
9
10
|
frame: "Marco: las flechas mueven la imagen, más y menos ajustan el zoom",
|
|
@@ -25,8 +26,15 @@ var t = /* @__PURE__ */ e({
|
|
|
25
26
|
live: "Cámara encendida",
|
|
26
27
|
captured: "Foto tomada"
|
|
27
28
|
}, i = {
|
|
29
|
+
label: "Escáner de códigos",
|
|
30
|
+
start: "Iniciar escaneo",
|
|
31
|
+
stop: "Detener",
|
|
32
|
+
unsupported: "Este navegador no puede leer códigos. Pasa un `detector` para habilitarlos.",
|
|
33
|
+
detected: "Código reconocido"
|
|
34
|
+
}, a = {
|
|
28
35
|
imageCrop: n,
|
|
29
|
-
camera: r
|
|
36
|
+
camera: r,
|
|
37
|
+
scanner: i
|
|
30
38
|
};
|
|
31
39
|
//#endregion
|
|
32
|
-
export { t as n,
|
|
40
|
+
export { t as n, a as t };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
//#region src/i18n/messages/const.ts
|
|
2
|
+
var e = "grMedia", t = { en: { [e]: async () => import("./en-BugobSAO.js").then((e) => e.n) } }, n = { es: { [e]: async () => import("./es-B7iA-ExH.js").then((e) => e.n) } }, r = { ru: { [e]: async () => import("./ru-DpiW6Vax.js").then((e) => e.n) } };
|
|
3
|
+
//#endregion
|
|
4
|
+
export { e as i, n, t as r, r as t };
|
|
@@ -2,8 +2,9 @@ import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
|
|
|
2
2
|
//#region src/i18n/locales/ru.json
|
|
3
3
|
var t = /* @__PURE__ */ e({
|
|
4
4
|
camera: () => r,
|
|
5
|
-
default: () =>
|
|
6
|
-
imageCrop: () => n
|
|
5
|
+
default: () => a,
|
|
6
|
+
imageCrop: () => n,
|
|
7
|
+
scanner: () => i
|
|
7
8
|
}), n = {
|
|
8
9
|
label: "Кадрирование изображения",
|
|
9
10
|
frame: "Кадр: стрелки двигают изображение, плюс и минус меняют увеличение",
|
|
@@ -25,8 +26,15 @@ var t = /* @__PURE__ */ e({
|
|
|
25
26
|
live: "Камера включена",
|
|
26
27
|
captured: "Снимок сделан"
|
|
27
28
|
}, i = {
|
|
29
|
+
label: "Сканер кодов",
|
|
30
|
+
start: "Начать сканирование",
|
|
31
|
+
stop: "Остановить",
|
|
32
|
+
unsupported: "Этот браузер не умеет читать коды. Передайте `detector`, чтобы включить их.",
|
|
33
|
+
detected: "Код распознан"
|
|
34
|
+
}, a = {
|
|
28
35
|
imageCrop: n,
|
|
29
|
-
camera: r
|
|
36
|
+
camera: r,
|
|
37
|
+
scanner: i
|
|
30
38
|
};
|
|
31
39
|
//#endregion
|
|
32
|
-
export { t as n,
|
|
40
|
+
export { t as n, a as t };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { computed as e, onBeforeUnmount as t, ref as n, shallowRef as r } from "vue";
|
|
2
|
+
import { useAnnouncer as i } from "@feugene/granularity/composables/useAnnouncer";
|
|
3
|
+
import { useGranularityTranslations as a } from "@feugene/granularity/composables/useGranularityTranslations";
|
|
4
|
+
//#region src/components/GrCameraCapture/cameraState.ts
|
|
5
|
+
function o(e) {
|
|
6
|
+
switch (e instanceof Error ? e.name : "") {
|
|
7
|
+
case "NotAllowedError":
|
|
8
|
+
case "SecurityError":
|
|
9
|
+
case "PermissionDeniedError": return "denied";
|
|
10
|
+
case "NotFoundError":
|
|
11
|
+
case "DevicesNotFoundError":
|
|
12
|
+
case "OverconstrainedError": return "missing";
|
|
13
|
+
case "NotReadableError":
|
|
14
|
+
case "TrackStartError":
|
|
15
|
+
case "AbortError": return "busy";
|
|
16
|
+
default: return "error";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function s(e) {
|
|
20
|
+
return typeof e?.mediaDevices?.getUserMedia == "function";
|
|
21
|
+
}
|
|
22
|
+
function c(e, t) {
|
|
23
|
+
return t ?? e === "user";
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/internal/useCameraStream.ts
|
|
27
|
+
function l(c) {
|
|
28
|
+
let { t: l } = a(), { announce: u } = i(), d = r(null), f = n("idle"), p = n(null), m = e(() => f.value === "live"), h = e(() => p.value ?? 4 / 3), g = e(() => {
|
|
29
|
+
switch (f.value) {
|
|
30
|
+
case "starting": return l("grMedia.camera.starting", "Requesting camera access…");
|
|
31
|
+
case "denied": return l("grMedia.camera.denied", "Camera access is blocked. Allow it in the browser settings for this site.");
|
|
32
|
+
case "missing": return l("grMedia.camera.missing", "No camera found on this device.");
|
|
33
|
+
case "busy": return l("grMedia.camera.busy", "The camera is busy in another application.");
|
|
34
|
+
case "insecure": return l("grMedia.camera.insecure", "The camera works only over HTTPS.");
|
|
35
|
+
case "error": return l("grMedia.camera.error", "The camera could not be started.");
|
|
36
|
+
default: return l("grMedia.camera.idle", "The camera is off.");
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
function _(e) {
|
|
40
|
+
f.value !== e && (f.value = e, c.onStatus?.(e));
|
|
41
|
+
}
|
|
42
|
+
function v() {
|
|
43
|
+
let e = c.video.value;
|
|
44
|
+
!e || e.videoWidth <= 0 || e.videoHeight <= 0 || (p.value = e.videoWidth / e.videoHeight);
|
|
45
|
+
}
|
|
46
|
+
function y() {
|
|
47
|
+
d.value?.getTracks().forEach((e) => e.stop()), d.value = null, p.value = null, c.video.value && (c.video.value.srcObject = null);
|
|
48
|
+
}
|
|
49
|
+
async function b() {
|
|
50
|
+
if (!(c.disabled() || f.value === "starting" || f.value === "live")) {
|
|
51
|
+
if (!s(navigator)) {
|
|
52
|
+
_("insecure");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
_("starting");
|
|
56
|
+
try {
|
|
57
|
+
let e = c.aspectRatio?.(), t = await navigator.mediaDevices.getUserMedia({
|
|
58
|
+
video: {
|
|
59
|
+
...c.deviceId() ? { deviceId: { exact: c.deviceId() } } : { facingMode: c.facing() },
|
|
60
|
+
...e ? { aspectRatio: e } : {}
|
|
61
|
+
},
|
|
62
|
+
audio: !1
|
|
63
|
+
});
|
|
64
|
+
d.value = t;
|
|
65
|
+
let n = c.video.value;
|
|
66
|
+
n && (n.srcObject = t, n.addEventListener("loadedmetadata", v, { once: !0 }), await n.play().catch(() => void 0), v()), _("live"), c.onStart?.(), u(l("grMedia.camera.live", "Camera is on"));
|
|
67
|
+
} catch (e) {
|
|
68
|
+
y(), _(o(e)), u(g.value, { politeness: "assertive" });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function x() {
|
|
73
|
+
d.value && (y(), _("idle"), c.onStop?.());
|
|
74
|
+
}
|
|
75
|
+
return t(y), {
|
|
76
|
+
status: f,
|
|
77
|
+
streamRatio: p,
|
|
78
|
+
frameRatio: h,
|
|
79
|
+
isLive: m,
|
|
80
|
+
message: g,
|
|
81
|
+
start: b,
|
|
82
|
+
stop: x
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { c as i, o as n, s as r, l as t };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { t as e } from "../../../chunks/outputSize-D2FU4CbB.js";
|
|
2
|
+
import { i as t, t as n } from "../../../chunks/useCameraStream-CPdm3r90.js";
|
|
3
|
+
import { a as r, c as i, l as a, n as o, o as s, r as c, s as l, u } from "../../../chunks/config-DHLlFslI.js";
|
|
4
|
+
import { computed as d, createBlock as f, createCommentVNode as p, createElementBlock as m, createElementVNode as h, createTextVNode as g, createVNode as _, defineComponent as v, normalizeClass as y, normalizeStyle as b, onMounted as x, openBlock as S, ref as C, renderSlot as w, toDisplayString as T, unref as E, withCtx as D } from "vue";
|
|
5
|
+
import O from "@feugene/granularity/components/GrButton";
|
|
6
|
+
import { useAnnouncer as k } from "@feugene/granularity/composables/useAnnouncer";
|
|
7
|
+
import { useGrComponentSize as A } from "@feugene/granularity/composables/useGrComponentConfig";
|
|
8
|
+
import { useGranularityTranslations as j } from "@feugene/granularity/composables/useGranularityTranslations";
|
|
9
|
+
//#region src/components/GrCameraCapture/GrCameraCapture.vue?vue&type=script&setup=true&lang.ts
|
|
10
|
+
var M = ["aria-label"], N = /* @__PURE__ */ v({
|
|
11
|
+
__name: "GrCameraCapture",
|
|
12
|
+
props: {
|
|
13
|
+
facing: { default: "user" },
|
|
14
|
+
deviceId: { default: void 0 },
|
|
15
|
+
aspectRatio: { default: void 0 },
|
|
16
|
+
autoStart: {
|
|
17
|
+
type: Boolean,
|
|
18
|
+
default: !1
|
|
19
|
+
},
|
|
20
|
+
mirror: {
|
|
21
|
+
type: Boolean,
|
|
22
|
+
default: void 0
|
|
23
|
+
},
|
|
24
|
+
output: { default: void 0 },
|
|
25
|
+
size: { default: void 0 },
|
|
26
|
+
disabled: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: !1
|
|
29
|
+
},
|
|
30
|
+
ariaLabel: { default: void 0 }
|
|
31
|
+
},
|
|
32
|
+
emits: [
|
|
33
|
+
"capture",
|
|
34
|
+
"start",
|
|
35
|
+
"stop",
|
|
36
|
+
"statusChange"
|
|
37
|
+
],
|
|
38
|
+
setup(v, { expose: N, emit: P }) {
|
|
39
|
+
let F = v, I = P, { t: L } = j(), { announce: R } = k(), z = A(() => F.size, { component: "GrCameraCapture" }), B = C(null), { frameRatio: V, isLive: H, message: U, start: W, status: G, stop: K } = n({
|
|
40
|
+
video: B,
|
|
41
|
+
disabled: () => F.disabled,
|
|
42
|
+
facing: () => F.facing,
|
|
43
|
+
deviceId: () => F.deviceId,
|
|
44
|
+
aspectRatio: () => F.aspectRatio,
|
|
45
|
+
onStatus: (e) => I("statusChange", e),
|
|
46
|
+
onStart: () => I("start"),
|
|
47
|
+
onStop: () => I("stop")
|
|
48
|
+
}), q = d(() => t(F.facing, F.mirror));
|
|
49
|
+
async function J() {
|
|
50
|
+
let t = B.value;
|
|
51
|
+
if (!t || !H.value) return null;
|
|
52
|
+
let n = {
|
|
53
|
+
sx: 0,
|
|
54
|
+
sy: 0,
|
|
55
|
+
sw: t.videoWidth,
|
|
56
|
+
sh: t.videoHeight
|
|
57
|
+
};
|
|
58
|
+
if (n.sw <= 0) return null;
|
|
59
|
+
let r = document.createElement("canvas"), i = e(n, F.output);
|
|
60
|
+
r.width = i.width, r.height = i.height;
|
|
61
|
+
let a = r.getContext("2d");
|
|
62
|
+
if (!a) return null;
|
|
63
|
+
a.drawImage(t, n.sx, n.sy, n.sw, n.sh, 0, 0, r.width, r.height);
|
|
64
|
+
let o = await new Promise((e) => {
|
|
65
|
+
r.toBlob(e, F.output?.type ?? "image/jpeg", F.output?.quality ?? .92);
|
|
66
|
+
});
|
|
67
|
+
return o && (I("capture", o), R(L("grMedia.camera.captured", "Photo taken"))), o;
|
|
68
|
+
}
|
|
69
|
+
return x(() => {
|
|
70
|
+
F.autoStart && W();
|
|
71
|
+
}), N({
|
|
72
|
+
start: W,
|
|
73
|
+
stop: K,
|
|
74
|
+
capture: J,
|
|
75
|
+
status: G
|
|
76
|
+
}), (e, t) => (S(), m("div", {
|
|
77
|
+
class: y(E(s)),
|
|
78
|
+
role: "group",
|
|
79
|
+
"aria-label": v.ariaLabel ?? E(L)("grMedia.camera.label", "Camera")
|
|
80
|
+
}, [h("div", {
|
|
81
|
+
class: y(E(c)),
|
|
82
|
+
style: b({ aspectRatio: String(E(V)) })
|
|
83
|
+
}, [h("video", {
|
|
84
|
+
ref_key: "videoEl",
|
|
85
|
+
ref: B,
|
|
86
|
+
class: y([E(u), q.value ? E(r) : ""]),
|
|
87
|
+
playsinline: "",
|
|
88
|
+
muted: "",
|
|
89
|
+
autoplay: ""
|
|
90
|
+
}, null, 2), E(H) ? p("", !0) : (S(), m("div", {
|
|
91
|
+
key: 0,
|
|
92
|
+
class: y(E(i))
|
|
93
|
+
}, [h("p", { class: y([E(a), E(l)[E(z)]]) }, T(E(U)), 3), E(G) !== "starting" && E(G) !== "insecure" && E(G) !== "missing" ? (S(), f(E(O), {
|
|
94
|
+
key: 0,
|
|
95
|
+
size: E(z),
|
|
96
|
+
disabled: v.disabled,
|
|
97
|
+
onClick: E(W)
|
|
98
|
+
}, {
|
|
99
|
+
default: D(() => [g(T(E(G) === "idle" ? E(L)("grMedia.camera.start", "Turn on camera") : E(L)("grMedia.camera.retry", "Try again")), 1)]),
|
|
100
|
+
_: 1
|
|
101
|
+
}, 8, [
|
|
102
|
+
"size",
|
|
103
|
+
"disabled",
|
|
104
|
+
"onClick"
|
|
105
|
+
])) : p("", !0)], 2))], 6), h("div", { class: y(E(o)) }, [w(e.$slots, "controls", {
|
|
106
|
+
status: E(G),
|
|
107
|
+
start: E(W),
|
|
108
|
+
stop: E(K),
|
|
109
|
+
capture: J
|
|
110
|
+
}, () => [_(E(O), {
|
|
111
|
+
size: E(z),
|
|
112
|
+
disabled: v.disabled || !E(H),
|
|
113
|
+
onClick: J
|
|
114
|
+
}, {
|
|
115
|
+
default: D(() => [g(T(E(L)("grMedia.camera.capture", "Take photo")), 1)]),
|
|
116
|
+
_: 1
|
|
117
|
+
}, 8, ["size", "disabled"]), E(H) ? (S(), f(E(O), {
|
|
118
|
+
key: 0,
|
|
119
|
+
variant: "outline",
|
|
120
|
+
size: E(z),
|
|
121
|
+
disabled: v.disabled,
|
|
122
|
+
onClick: E(K)
|
|
123
|
+
}, {
|
|
124
|
+
default: D(() => [g(T(E(L)("grMedia.camera.stop", "Turn off")), 1)]),
|
|
125
|
+
_: 1
|
|
126
|
+
}, 8, [
|
|
127
|
+
"size",
|
|
128
|
+
"disabled",
|
|
129
|
+
"onClick"
|
|
130
|
+
])) : p("", !0)])], 2)], 10, M));
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
//#endregion
|
|
134
|
+
export { N as t };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { i as e, n as t, r as n
|
|
2
|
-
import { i, t as
|
|
3
|
-
|
|
1
|
+
import { i as e, n as t, r as n } from "../../chunks/useCameraStream-CPdm3r90.js";
|
|
2
|
+
import { i as r, t as i } from "../../chunks/config-DHLlFslI.js";
|
|
3
|
+
import { t as a } from "./chunks/GrCameraCapture-t-uFTD9s.js";
|
|
4
|
+
export { a as GrCameraCapture, a as default, t as cameraStatusFromError, n as cameraSupported, i as grCameraCaptureConfig, r as grCameraCaptureSafelist, e as shouldMirrorPreview };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { t as e } from "../../../chunks/useCameraStream-CPdm3r90.js";
|
|
2
|
+
import { a as t, c as n, l as r, n as ee, o as i, r as a, s as o, u as te } from "../../../chunks/config-DfJkKtIh.js";
|
|
3
|
+
import { computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createTextVNode as f, defineComponent as p, normalizeClass as m, normalizeStyle as h, onBeforeUnmount as g, onMounted as ne, openBlock as _, ref as v, renderSlot as y, shallowRef as b, toDisplayString as x, unref as S, withCtx as C } from "vue";
|
|
4
|
+
import w from "@feugene/granularity/components/GrButton";
|
|
5
|
+
import { useAnnouncer as T } from "@feugene/granularity/composables/useAnnouncer";
|
|
6
|
+
import { useGrComponentSize as E } from "@feugene/granularity/composables/useGrComponentConfig";
|
|
7
|
+
import { useGranularityTranslations as D } from "@feugene/granularity/composables/useGranularityTranslations";
|
|
8
|
+
//#region src/components/GrCodeScanner/codeDetection.ts
|
|
9
|
+
function O(e = globalThis) {
|
|
10
|
+
return typeof e.BarcodeDetector == "function";
|
|
11
|
+
}
|
|
12
|
+
function k(e, t = globalThis) {
|
|
13
|
+
if (!O(t)) return null;
|
|
14
|
+
let n = t.BarcodeDetector, r = new n(e ? { formats: [...e] } : void 0);
|
|
15
|
+
return async (e) => (await r.detect(e)).map((e) => ({
|
|
16
|
+
value: e.rawValue,
|
|
17
|
+
format: e.format
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
function A(e, t, n) {
|
|
21
|
+
if (n) return [...t];
|
|
22
|
+
let r = new Set(e.map((e) => `${e.format}:${e.value}`));
|
|
23
|
+
return t.filter((e) => !r.has(`${e.format}:${e.value}`));
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/components/GrCodeScanner/GrCodeScanner.vue?vue&type=script&setup=true&lang.ts
|
|
27
|
+
var j = ["aria-label"], M = /* @__PURE__ */ p({
|
|
28
|
+
__name: "GrCodeScanner",
|
|
29
|
+
props: {
|
|
30
|
+
facing: { default: "environment" },
|
|
31
|
+
deviceId: { default: void 0 },
|
|
32
|
+
autoStart: {
|
|
33
|
+
type: Boolean,
|
|
34
|
+
default: !1
|
|
35
|
+
},
|
|
36
|
+
formats: { default: void 0 },
|
|
37
|
+
detector: {
|
|
38
|
+
type: Function,
|
|
39
|
+
default: void 0
|
|
40
|
+
},
|
|
41
|
+
interval: { default: 250 },
|
|
42
|
+
continuous: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: !1
|
|
45
|
+
},
|
|
46
|
+
size: { default: void 0 },
|
|
47
|
+
disabled: {
|
|
48
|
+
type: Boolean,
|
|
49
|
+
default: !1
|
|
50
|
+
},
|
|
51
|
+
ariaLabel: { default: void 0 }
|
|
52
|
+
},
|
|
53
|
+
emits: [
|
|
54
|
+
"detect",
|
|
55
|
+
"start",
|
|
56
|
+
"stop",
|
|
57
|
+
"statusChange"
|
|
58
|
+
],
|
|
59
|
+
setup(p, { expose: M, emit: re }) {
|
|
60
|
+
let N = p, P = re, { t: F } = D(), { announce: I } = T(), L = E(() => N.size, { component: "GrCodeScanner" }), R = v(null), z = b(null), B = b([]), { frameRatio: V, isLive: H, message: U, start: W, status: G, stop: K } = e({
|
|
61
|
+
video: R,
|
|
62
|
+
disabled: () => N.disabled,
|
|
63
|
+
facing: () => N.facing,
|
|
64
|
+
deviceId: () => N.deviceId,
|
|
65
|
+
onStatus: (e) => P("statusChange", e),
|
|
66
|
+
onStart: () => {
|
|
67
|
+
B.value = [], ae(), P("start");
|
|
68
|
+
},
|
|
69
|
+
onStop: () => P("stop")
|
|
70
|
+
}), q = s(() => !N.detector && !O()), J = s(() => q.value ? F("grMedia.scanner.unsupported", "This browser cannot read codes. Pass a `detector` to enable it.") : U.value);
|
|
71
|
+
function Y() {
|
|
72
|
+
return N.detector ?? k(N.formats);
|
|
73
|
+
}
|
|
74
|
+
let X = null, Z = !1;
|
|
75
|
+
async function ie() {
|
|
76
|
+
let e = R.value;
|
|
77
|
+
if (!(!e || !H.value || N.disabled) && (z.value ??= Y(), z.value)) try {
|
|
78
|
+
let t = await z.value(e), n = A(B.value, t, N.continuous);
|
|
79
|
+
B.value = t, n.length > 0 && (P("detect", n), I(F("grMedia.scanner.detected", "Code recognised")));
|
|
80
|
+
} catch {}
|
|
81
|
+
}
|
|
82
|
+
function ae() {
|
|
83
|
+
if (Z) return;
|
|
84
|
+
Z = !0;
|
|
85
|
+
let e = async () => {
|
|
86
|
+
if (Z) {
|
|
87
|
+
if (await ie(), !Z || !H.value) {
|
|
88
|
+
X = null, Z = !1;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
X = setTimeout(() => void e(), N.interval);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
X = setTimeout(() => void e(), N.interval);
|
|
95
|
+
}
|
|
96
|
+
function Q() {
|
|
97
|
+
Z = !1, X !== null && (clearTimeout(X), X = null);
|
|
98
|
+
}
|
|
99
|
+
ne(() => {
|
|
100
|
+
N.autoStart && W();
|
|
101
|
+
}), g(Q);
|
|
102
|
+
function $() {
|
|
103
|
+
Q(), K();
|
|
104
|
+
}
|
|
105
|
+
return M({
|
|
106
|
+
start: W,
|
|
107
|
+
stop: $,
|
|
108
|
+
status: G
|
|
109
|
+
}), (e, s) => (_(), u("div", {
|
|
110
|
+
class: m(S(i)),
|
|
111
|
+
role: "group",
|
|
112
|
+
"aria-label": p.ariaLabel ?? S(F)("grMedia.scanner.label", "Code scanner")
|
|
113
|
+
}, [d("div", {
|
|
114
|
+
class: m(S(a)),
|
|
115
|
+
style: h({ aspectRatio: String(S(V)) })
|
|
116
|
+
}, [
|
|
117
|
+
d("video", {
|
|
118
|
+
ref_key: "videoEl",
|
|
119
|
+
ref: R,
|
|
120
|
+
class: m(S(te)),
|
|
121
|
+
playsinline: "",
|
|
122
|
+
muted: "",
|
|
123
|
+
autoplay: ""
|
|
124
|
+
}, null, 2),
|
|
125
|
+
S(H) && !q.value ? (_(), u("div", {
|
|
126
|
+
key: 0,
|
|
127
|
+
class: m(S(t))
|
|
128
|
+
}, null, 2)) : l("", !0),
|
|
129
|
+
!S(H) || q.value ? (_(), u("div", {
|
|
130
|
+
key: 1,
|
|
131
|
+
class: m(S(n))
|
|
132
|
+
}, [d("p", { class: m([S(r), S(o)[S(L)]]) }, x(J.value), 3), !q.value && S(G) !== "starting" && S(G) !== "insecure" && S(G) !== "missing" ? (_(), c(S(w), {
|
|
133
|
+
key: 0,
|
|
134
|
+
size: S(L),
|
|
135
|
+
disabled: p.disabled,
|
|
136
|
+
onClick: S(W)
|
|
137
|
+
}, {
|
|
138
|
+
default: C(() => [f(x(S(G) === "idle" ? S(F)("grMedia.scanner.start", "Start scanning") : S(F)("grMedia.camera.retry", "Try again")), 1)]),
|
|
139
|
+
_: 1
|
|
140
|
+
}, 8, [
|
|
141
|
+
"size",
|
|
142
|
+
"disabled",
|
|
143
|
+
"onClick"
|
|
144
|
+
])) : l("", !0)], 2)) : l("", !0)
|
|
145
|
+
], 6), d("div", { class: m(S(ee)) }, [y(e.$slots, "controls", {
|
|
146
|
+
status: S(G),
|
|
147
|
+
start: S(W),
|
|
148
|
+
stop: $
|
|
149
|
+
}, () => [S(H) ? (_(), c(S(w), {
|
|
150
|
+
key: 0,
|
|
151
|
+
variant: "outline",
|
|
152
|
+
size: S(L),
|
|
153
|
+
disabled: p.disabled,
|
|
154
|
+
onClick: $
|
|
155
|
+
}, {
|
|
156
|
+
default: C(() => [f(x(S(F)("grMedia.scanner.stop", "Stop")), 1)]),
|
|
157
|
+
_: 1
|
|
158
|
+
}, 8, ["size", "disabled"])) : l("", !0)])], 2)], 10, j));
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
//#endregion
|
|
162
|
+
export { O as i, k as n, A as r, M as t };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { i as e, n as t, r as n, t as r } from "./chunks/GrCodeScanner-BX147Gct.js";
|
|
2
|
+
import { i, t as a } from "../../chunks/config-DfJkKtIh.js";
|
|
3
|
+
export { r as GrCodeScanner, r as default, t as createNativeDetector, n as freshCodes, a as grCodeScannerConfig, i as grCodeScannerSafelist, e as nativeDetectorSupported };
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { t as e } from "./chunks/config-DHLlFslI.js";
|
|
2
|
-
import { t } from "./chunks/config-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { t } from "./chunks/config-DfJkKtIh.js";
|
|
3
|
+
import { t as n } from "./chunks/config-Be_Mh801.js";
|
|
4
|
+
import { defineGranularProvider as r, resolvePackageBaseUrl as i } from "@feugene/unocss-preset-granular/contract";
|
|
5
|
+
import { granularityProvider as a } from "@feugene/granularity/granular-provider";
|
|
5
6
|
//#region src/granular-provider/shared.ts
|
|
6
|
-
var
|
|
7
|
+
var o = "@feugene/granularity-media", s = {
|
|
7
8
|
GrCameraCapture: e,
|
|
8
|
-
|
|
9
|
+
GrCodeScanner: t,
|
|
10
|
+
GrImageCrop: n
|
|
9
11
|
};
|
|
10
|
-
function
|
|
11
|
-
return
|
|
12
|
-
id:
|
|
12
|
+
function c(e, t) {
|
|
13
|
+
return r({
|
|
14
|
+
id: o,
|
|
13
15
|
contractVersion: 1,
|
|
14
16
|
packageBaseUrl: t,
|
|
15
|
-
components: Object.values(
|
|
17
|
+
components: Object.values(s),
|
|
16
18
|
dependencies: [e]
|
|
17
19
|
});
|
|
18
20
|
}
|
|
19
|
-
var
|
|
21
|
+
var l = c(a, i(import.meta.url, 0));
|
|
20
22
|
//#endregion
|
|
21
|
-
export {
|
|
23
|
+
export { o as GRANULARITY_MEDIA_PROVIDER_ID, c as createGranularityMediaProvider, l as default, l as granularityMediaProvider, s as granularityMediaComponentConfigs };
|
package/dist/i18n/all.js
CHANGED
package/dist/i18n/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as e } from "../chunks/en-
|
|
2
|
-
import { t } from "../chunks/es-
|
|
3
|
-
import { t as n } from "../chunks/ru-
|
|
4
|
-
import { i as r, n as i, r as a, t as o } from "../chunks/ru-
|
|
1
|
+
import { t as e } from "../chunks/en-BugobSAO.js";
|
|
2
|
+
import { t } from "../chunks/es-B7iA-ExH.js";
|
|
3
|
+
import { t as n } from "../chunks/ru-DpiW6Vax.js";
|
|
4
|
+
import { i as r, n as i, r as a, t as o } from "../chunks/ru-DSjpFh8N.js";
|
|
5
5
|
//#region src/i18n/index.ts
|
|
6
6
|
var s = {
|
|
7
7
|
en: e,
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { i as e, n as t, r as n
|
|
2
|
-
import { i, t as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { i as e, n as t, r as n } from "./chunks/useCameraStream-CPdm3r90.js";
|
|
2
|
+
import { i as r, t as i } from "./chunks/config-DHLlFslI.js";
|
|
3
|
+
import { t as a } from "./components/GrCameraCapture/chunks/GrCameraCapture-t-uFTD9s.js";
|
|
4
|
+
import { i as o, n as s, r as c, t as l } from "./components/GrCodeScanner/chunks/GrCodeScanner-BX147Gct.js";
|
|
5
|
+
import { i as u, t as d } from "./chunks/config-DfJkKtIh.js";
|
|
6
|
+
import { a as f, i as p, n as m, o as h, r as g, s as _, t as v } from "./components/GrImageCrop/chunks/GrImageCrop-g1StRUis.js";
|
|
7
|
+
import { a as y, t as b } from "./chunks/config-Be_Mh801.js";
|
|
8
|
+
export { a as GrCameraCapture, l as GrCodeScanner, v as GrImageCrop, t as cameraStatusFromError, n as cameraSupported, m as clampOffset, g as coverScale, s as createNativeDetector, p as cropRect, f as displaySize, c as freshCodes, i as grCameraCaptureConfig, r as grCameraCaptureSafelist, d as grCodeScannerConfig, u as grCodeScannerSafelist, b as grImageCropConfig, y as grImageCropSafelist, o as nativeDetectorSupported, h as offsetBounds, e as shouldMirrorPreview, _ as viewportFor };
|
package/dist/resolver.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { createGranularResolver as e } from "@feugene/unplugin-granularity";
|
|
2
2
|
//#region src/componentNames.ts
|
|
3
|
-
var t = [
|
|
3
|
+
var t = [
|
|
4
|
+
"GrCameraCapture",
|
|
5
|
+
"GrCodeScanner",
|
|
6
|
+
"GrImageCrop"
|
|
7
|
+
], n = "@feugene/granularity-media";
|
|
4
8
|
function r() {
|
|
5
9
|
return e({
|
|
6
10
|
packageName: n,
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Список генерируется `yarn generate:registry` — руками не писать.
|
|
10
10
|
*/
|
|
11
|
-
export declare const GRANULARITY_MEDIA_COMPONENTS: readonly ["GrCameraCapture", "GrImageCrop"];
|
|
11
|
+
export declare const GRANULARITY_MEDIA_COMPONENTS: readonly ["GrCameraCapture", "GrCodeScanner", "GrImageCrop"];
|
|
12
12
|
export type GranularityMediaComponentName = typeof GRANULARITY_MEDIA_COMPONENTS[number];
|