@innspel/react-native 0.1.0 → 0.2.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/dist/index.cjs CHANGED
@@ -20,9 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ InnspelPrivate: () => InnspelPrivate,
23
24
  InnspelProvider: () => InnspelProvider,
24
25
  byggTema: () => byggTema,
25
26
  createMemoryStorage: () => createMemoryStorage,
27
+ createScreenshotAdapter: () => createScreenshotAdapter,
26
28
  createStorage: () => createStorage,
27
29
  darkTokens: () => t,
28
30
  light: () => light,
@@ -37,10 +39,53 @@ __export(index_exports, {
37
39
  module.exports = __toCommonJS(index_exports);
38
40
 
39
41
  // src/InnspelProvider.tsx
40
- var import_react9 = require("react");
42
+ var import_react11 = require("react");
43
+ var import_react_native10 = require("react-native");
41
44
 
42
- // src/tema.ts
45
+ // src/skjermbilde.ts
43
46
  var import_react = require("react");
47
+ var import_react_native = require("react-native");
48
+ function createScreenshotAdapter(captureRef) {
49
+ return {
50
+ async capture(ref, options) {
51
+ const uri = await captureRef(ref, { format: options.format, quality: options.quality, result: "tmpfile" });
52
+ const { width, height } = await new Promise(
53
+ (resolve, reject) => import_react_native.Image.getSize(uri, (w, h) => resolve({ width: w, height: h }), reject)
54
+ );
55
+ return { uri, width, height };
56
+ },
57
+ measure(ref) {
58
+ return new Promise((resolve) => {
59
+ const view = ref.current;
60
+ if (!view) return resolve(null);
61
+ view.measureInWindow((x, y, width, height) => resolve({ x, y, width, height }));
62
+ });
63
+ },
64
+ async read(uri) {
65
+ const res = await fetch(uri);
66
+ return res.blob();
67
+ }
68
+ };
69
+ }
70
+ function createPrivateRegistry() {
71
+ const alle = /* @__PURE__ */ new Set();
72
+ return {
73
+ register(ref) {
74
+ alle.add(ref);
75
+ return () => {
76
+ alle.delete(ref);
77
+ };
78
+ },
79
+ refs: () => [...alle]
80
+ };
81
+ }
82
+ var SkjermbildeContext = (0, import_react.createContext)(null);
83
+ function useSkjermbilde() {
84
+ return (0, import_react.useContext)(SkjermbildeContext);
85
+ }
86
+
87
+ // src/tema.ts
88
+ var import_react2 = require("react");
44
89
 
45
90
  // src/generated/tokens.ts
46
91
  var t = {
@@ -215,7 +260,9 @@ var screenRules = {
215
260
  brushFill: "#E5007D",
216
261
  autoMaskFill: "#101114",
217
262
  autoMaskStroke: "#E5007D",
218
- previewBackdrop: "#000000"
263
+ previewBackdrop: "#000000",
264
+ brushWidth: 28,
265
+ textBlurRadius: 24
219
266
  };
220
267
 
221
268
  // src/tema.ts
@@ -228,24 +275,24 @@ function byggTema(vertens, palett = "dark") {
228
275
  color: { ...bunn.color, ...vertens.color }
229
276
  };
230
277
  }
231
- var TemaContext = (0, import_react.createContext)(t);
278
+ var TemaContext = (0, import_react2.createContext)(t);
232
279
  var TemaProvider = TemaContext.Provider;
233
280
  function useTema() {
234
- return (0, import_react.useContext)(TemaContext);
281
+ return (0, import_react2.useContext)(TemaContext);
235
282
  }
236
283
 
237
284
  // src/widget/Widget.tsx
238
- var import_core = require("@innspel/core");
239
- var import_react8 = require("react");
240
- var import_react_native7 = require("react-native");
285
+ var import_core2 = require("@innspel/core");
286
+ var import_react10 = require("react");
287
+ var import_react_native9 = require("react-native");
241
288
 
242
289
  // src/widget/Felt.tsx
243
- var import_react3 = require("react");
244
- var import_react_native2 = require("react-native");
290
+ var import_react4 = require("react");
291
+ var import_react_native3 = require("react-native");
245
292
 
246
293
  // src/widget/primitiver.tsx
247
- var import_react2 = require("react");
248
- var import_react_native = require("react-native");
294
+ var import_react3 = require("react");
295
+ var import_react_native2 = require("react-native");
249
296
  var import_jsx_runtime = require("react/jsx-runtime");
250
297
  function Btn({
251
298
  label,
@@ -263,9 +310,9 @@ function Btn({
263
310
  const bakgrunn = variant === "primary" ? c.actionPrimary : variant === "secondary" ? c.surfaceRaised : "transparent";
264
311
  const tekstfarge = variant === "primary" ? c.onActionPrimary : variant === "danger" ? c.danger : c.actionSecondaryText;
265
312
  const kant = variant === "ghost" ? "transparent" : variant === "primary" ? c.actionPrimary : c.actionSecondaryBorder;
266
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: grow ? { flex: 1 } : void 0, children: [
313
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: grow ? { flex: 1 } : void 0, children: [
267
314
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
268
- import_react_native.Pressable,
315
+ import_react_native2.Pressable,
269
316
  {
270
317
  testID,
271
318
  accessibilityRole: "button",
@@ -287,9 +334,9 @@ function Btn({
287
334
  opacity: disabled ? 0.6 : 1
288
335
  },
289
336
  children: [
290
- ikon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.body }, children: ikon }) : null,
337
+ ikon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.body }, children: ikon }) : null,
291
338
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
292
- import_react_native.Text,
339
+ import_react_native2.Text,
293
340
  {
294
341
  style: {
295
342
  color: disabled ? c.textDisabled : tekstfarge,
@@ -307,9 +354,9 @@ function Btn({
307
354
  }
308
355
  function H({ children, sub }) {
309
356
  const tema = useTema();
310
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: { gap: tema.space.xs }, children: [
357
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: { gap: tema.space.xs }, children: [
311
358
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
312
- import_react_native.Text,
359
+ import_react_native2.Text,
313
360
  {
314
361
  accessibilityRole: "header",
315
362
  style: {
@@ -322,7 +369,7 @@ function H({ children, sub }) {
322
369
  }
323
370
  ),
324
371
  sub ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
325
- import_react_native.Text,
372
+ import_react_native2.Text,
326
373
  {
327
374
  style: {
328
375
  color: tema.color.textSecondary,
@@ -337,7 +384,7 @@ function H({ children, sub }) {
337
384
  function Hint({ children }) {
338
385
  const tema = useTema();
339
386
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
340
- import_react_native.Text,
387
+ import_react_native2.Text,
341
388
  {
342
389
  style: {
343
390
  color: tema.color.textMuted,
@@ -355,7 +402,7 @@ function Card({
355
402
  }) {
356
403
  const tema = useTema();
357
404
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
358
- import_react_native.View,
405
+ import_react_native2.View,
359
406
  {
360
407
  style: [
361
408
  {
@@ -380,7 +427,7 @@ function StatusPill({
380
427
  }) {
381
428
  const tema = useTema();
382
429
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
383
- import_react_native.View,
430
+ import_react_native2.View,
384
431
  {
385
432
  style: {
386
433
  flexDirection: "row",
@@ -393,8 +440,8 @@ function StatusPill({
393
440
  backgroundColor: tema.color[`${farge}Bg`]
394
441
  },
395
442
  children: [
396
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.small }, children: ikon }),
397
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { style: { color: tema.color[farge], fontSize: tema.font.small, fontWeight: tema.weight.medium }, children: etikett })
443
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.small }, children: ikon }),
444
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: { color: tema.color[farge], fontSize: tema.font.small, fontWeight: tema.weight.medium }, children: etikett })
398
445
  ]
399
446
  }
400
447
  );
@@ -407,7 +454,7 @@ function Banner({
407
454
  }) {
408
455
  const tema = useTema();
409
456
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
410
- import_react_native.View,
457
+ import_react_native2.View,
411
458
  {
412
459
  style: {
413
460
  flexDirection: "row",
@@ -417,9 +464,9 @@ function Banner({
417
464
  padding: tema.space.md
418
465
  },
419
466
  children: [
420
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.body }, children: ikon }),
467
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.body }, children: ikon }),
421
468
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
422
- import_react_native.Text,
469
+ import_react_native2.Text,
423
470
  {
424
471
  accessibilityRole: "alert",
425
472
  accessibilityLiveRegion: live ? "polite" : "none",
@@ -474,6 +521,27 @@ var tekst = {
474
521
  kontekstAldri: "Aldri: navn, e-post, telefon, posisjon eller det som st\xE5r p\xE5 skjermen.",
475
522
  lenketTil: (tittel) => `Lenket til: \xAB${tittel}\xBB`,
476
523
  fjernLenke: "Fjern lenken til den kjente feilen",
524
+ // 2f — skjermbilde (K4, DD-39, DD-40, DD-42)
525
+ leggVedSkjermbilde: "Legg ved skjermbilde",
526
+ leggVedHint: "Bildet tas f\xF8rst n\xE5r du trykker \u2014 du ser det f\xF8r det sendes.",
527
+ skjermbildeTittel: "Se over bildet",
528
+ skjermbildeUnder: "Bildet ble tatt da du trykket. Det du maskerer, ser vi aldri.",
529
+ maskering: "Maskering",
530
+ maskerFelt: "Masker felt",
531
+ tegnOver: "Tegn over",
532
+ maskerAllTekst: "Masker all tekst",
533
+ maskertAvAppen: "Maskert av appen",
534
+ maskertAvAppenHint: "Registrert privat view. Penselen kan ikke oppheve den.",
535
+ dittStrok: "\u25B2 ditt str\xF8k \u2014 maskert (kan angres med ett trykk)",
536
+ allTekstHint: "Hele bildet er gjort uskarpt s\xE5 tekst ikke kan leses. Layouten er synlig.",
537
+ fjernBildet: "Fjern bildet",
538
+ leggVedOgFortsett: "Legg ved og fortsett",
539
+ leggVedHintDD42: "Teksten sendes f\xF8rst; bildet lastes opp for seg.",
540
+ skjermbildeLagtVed: "Skjermbilde lagt ved \u2014 maskert",
541
+ fjernSkjermbilde: "Fjern skjermbildet",
542
+ sendHintMedBilde: "Teksten sendes f\xF8rst; bildet lastes opp for seg.",
543
+ skjermbildeFeilet: "kunne ikke ta skjermbilde. Du kan sende uten.",
544
+ skjermbildeA11y: (auto, egne, uskarpt) => `Forh\xE5ndsvisning av skjermbildet. ${auto ? `${auto} felt maskert av appen og kan ikke avmaskeres. ` : ""}${egne ? `${egne} felt maskert av deg. ` : ""}${uskarpt ? "All tekst er gjort uskarp. " : ""}Trykk for \xE5 maskere et felt, dra for \xE5 tegne over.`,
477
545
  // DD-46 — mønstervarsel. Aldri stille redaksjon.
478
546
  monsterSpm: {
479
547
  email: "Dette ser ut som en e-postadresse. Vil du fjerne den?",
@@ -493,10 +561,17 @@ var tekst = {
493
561
  kvitteringJaOgsa: "Du f\xE5r beskjed n\xE5r den er rettet.",
494
562
  saksnummer: (nr) => `Saksnummer ${nr} \u2014 vis dette hvis du sp\xF8r support.`,
495
563
  tilbakeTilAppen: "Tilbake til appen",
564
+ /** DD-42: saken er sendt, bildet kom ikke med — aldri en blokkert innsending. */
565
+ kvitteringVedleggFeilet: "Sendt \u2014 skjermbildet kunne ikke legges ved",
566
+ tekstenErLagret: "Teksten din er lagret.",
567
+ vedleggFeiletBanner: "Bildet ble ikke lastet opp. Saken er sendt uten det \u2014 vil du, kan du sende et nytt innspill med bilde.",
568
+ saksnummerUtenVedlegg: (nr) => `Saksnummer ${nr} \xB7 uten vedlegg`,
496
569
  // 2i — tilstander
497
570
  offlineTittel: "Ingen nett",
498
571
  offlineBanner: "Ingen nett. Lagres og sendes automatisk \u2014 du ser det under \xABMine innspill\xBB til det er sendt.",
499
572
  offlineLagre: "Lagre \u2014 sendes automatisk",
573
+ /** DD-41: et skjermbilde køes aldri. */
574
+ offlineUtenBilde: "Skjermbilde kan ikke legges ved uten nett. Teksten sendes; bildet ble ikke lagret.",
500
575
  sendefeilBanner: (arsak) => `Kunne ikke sende: ${arsak} Teksten din er beholdt.`,
501
576
  provIgjen: "Pr\xF8v igjen",
502
577
  // 2j — mine innspill
@@ -542,17 +617,20 @@ function Felt({
542
617
  onFjernLenke,
543
618
  funn,
544
619
  onSend,
545
- sender
620
+ sender,
621
+ onSkjermbilde,
622
+ harVedlegg,
623
+ onFjernVedlegg
546
624
  }) {
547
625
  const tema = useTema();
548
- const [apen, setApen] = (0, import_react3.useState)(false);
549
- const [beholdt, setBeholdt] = (0, import_react3.useState)([]);
626
+ const [apen, setApen] = (0, import_react4.useState)(false);
627
+ const [beholdt, setBeholdt] = (0, import_react4.useState)([]);
550
628
  const brukt = verdi.length;
551
629
  const forKort = brukt < minTextLength;
552
630
  const full = brukt >= textMaxLength;
553
631
  const visTeller = brukt >= textMaxLength * 0.8;
554
632
  const uavklart = funn.find((f) => !beholdt.includes(f.match));
555
- const linjer = (0, import_react3.useMemo)(() => {
633
+ const linjer = (0, import_react4.useMemo)(() => {
556
634
  const etiketter = {
557
635
  screen: "Skjerm",
558
636
  appVersion: "Appversjon",
@@ -566,9 +644,9 @@ function Felt({
566
644
  return verdi2 && !fjernedeFelter.includes(felt) ? { felt, etikett, verdi: verdi2 } : null;
567
645
  }).filter((x) => x !== null);
568
646
  }, [kontekst, fjernedeFelter]);
569
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: { flex: 1, gap: tema.space.md }, children: [
647
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: { flex: 1, gap: tema.space.md }, children: [
570
648
  lenketTil ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
571
- import_react_native2.View,
649
+ import_react_native3.View,
572
650
  {
573
651
  style: {
574
652
  flexDirection: "row",
@@ -582,23 +660,23 @@ function Felt({
582
660
  paddingRight: tema.space.xs
583
661
  },
584
662
  children: [
585
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: { flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }, children: tekst.lenketTil(lenketTil.title) }),
663
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: { flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }, children: tekst.lenketTil(lenketTil.title) }),
586
664
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
587
- import_react_native2.Pressable,
665
+ import_react_native3.Pressable,
588
666
  {
589
667
  testID: "fjern-lenke",
590
668
  accessibilityRole: "button",
591
669
  accessibilityLabel: tekst.fjernLenke,
592
670
  onPress: onFjernLenke,
593
671
  style: { minWidth: tema.touch, minHeight: tema.touch, alignItems: "center", justifyContent: "center" },
594
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: "\u2715" })
672
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: "\u2715" })
595
673
  }
596
674
  )
597
675
  ]
598
676
  }
599
677
  ) : null,
600
678
  uavklart ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
601
- import_react_native2.View,
679
+ import_react_native3.View,
602
680
  {
603
681
  style: {
604
682
  gap: tema.space.sm,
@@ -608,7 +686,7 @@ function Felt({
608
686
  },
609
687
  children: [
610
688
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
611
- import_react_native2.Text,
689
+ import_react_native3.Text,
612
690
  {
613
691
  accessibilityRole: "alert",
614
692
  accessibilityLiveRegion: "polite",
@@ -621,7 +699,7 @@ function Felt({
621
699
  children: tekst.monsterSpm[uavklart.kind]
622
700
  }
623
701
  ),
624
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
702
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
625
703
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
626
704
  Btn,
627
705
  {
@@ -649,7 +727,7 @@ function Felt({
649
727
  ) : null,
650
728
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(H, { children: spor === "onske" ? tekst.feltLabelOnske : tekst.feltLabelFeil }),
651
729
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
652
- import_react_native2.TextInput,
730
+ import_react_native3.TextInput,
653
731
  {
654
732
  testID: "innspill-tekst",
655
733
  accessibilityLabel: spor === "onske" ? tekst.feltLabelOnske : tekst.feltLabelFeil,
@@ -675,7 +753,7 @@ function Felt({
675
753
  }
676
754
  ),
677
755
  visTeller ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
678
- import_react_native2.Text,
756
+ import_react_native3.Text,
679
757
  {
680
758
  testID: "teller",
681
759
  accessibilityLiveRegion: full ? "assertive" : "polite",
@@ -692,9 +770,51 @@ function Felt({
692
770
  ]
693
771
  }
694
772
  ) : null,
695
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: { borderTopWidth: tema.hairline, borderTopColor: tema.color.border, paddingTop: tema.space.sm }, children: [
773
+ harVedlegg ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
774
+ import_react_native3.View,
775
+ {
776
+ testID: "vedlegg-chip",
777
+ style: {
778
+ flexDirection: "row",
779
+ alignItems: "center",
780
+ gap: tema.space.sm,
781
+ minHeight: tema.touch,
782
+ borderWidth: tema.hairline,
783
+ borderColor: tema.color.borderInteractive,
784
+ borderRadius: tema.radius.pill,
785
+ paddingLeft: tema.space.md,
786
+ paddingRight: tema.space.xs
787
+ },
788
+ children: [
789
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.small }, children: "\u{1F4F7}" }),
790
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: { flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }, children: tekst.skjermbildeLagtVed }),
791
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
792
+ import_react_native3.Pressable,
793
+ {
794
+ testID: "fjern-vedlegg",
795
+ accessibilityRole: "button",
796
+ accessibilityLabel: tekst.fjernSkjermbilde,
797
+ onPress: onFjernVedlegg,
798
+ style: { minWidth: tema.touch, minHeight: tema.touch, alignItems: "center", justifyContent: "center" },
799
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: "\u2715" })
800
+ }
801
+ )
802
+ ]
803
+ }
804
+ ) : onSkjermbilde ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
805
+ Btn,
806
+ {
807
+ variant: "secondary",
808
+ testID: "legg-ved-skjermbilde",
809
+ ikon: "\u{1F4F7}",
810
+ label: tekst.leggVedSkjermbilde,
811
+ hint: tekst.leggVedHint,
812
+ onPress: onSkjermbilde
813
+ }
814
+ ) : null,
815
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: { borderTopWidth: tema.hairline, borderTopColor: tema.color.border, paddingTop: tema.space.sm }, children: [
696
816
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
697
- import_react_native2.Pressable,
817
+ import_react_native3.Pressable,
698
818
  {
699
819
  testID: "kontekst-bryter",
700
820
  accessibilityRole: "button",
@@ -702,7 +822,7 @@ function Felt({
702
822
  accessibilityLabel: `${tekst.kontekstLinje}${apen ? "" : tekst.kontekstVis}`,
703
823
  onPress: () => setApen((a) => !a),
704
824
  style: { minHeight: tema.touch, justifyContent: "center" },
705
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: [
825
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: [
706
826
  apen ? "\u25B4" : "\u25BE",
707
827
  " ",
708
828
  tekst.kontekstLinje,
@@ -710,9 +830,9 @@ function Felt({
710
830
  ] })
711
831
  }
712
832
  ),
713
- apen ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { children: [
833
+ apen ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { children: [
714
834
  linjer.map((l) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
715
- import_react_native2.View,
835
+ import_react_native3.View,
716
836
  {
717
837
  style: {
718
838
  flexDirection: "row",
@@ -723,17 +843,17 @@ function Felt({
723
843
  borderBottomColor: tema.color.border
724
844
  },
725
845
  children: [
726
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: { color: tema.color.textMuted, fontSize: tema.font.small, minWidth: tema.touch * 2 }, children: l.etikett }),
727
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: { flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }, children: l.verdi }),
846
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: { color: tema.color.textMuted, fontSize: tema.font.small, minWidth: tema.touch * 2 }, children: l.etikett }),
847
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: { flex: 1, color: tema.color.textPrimary, fontSize: tema.font.small }, children: l.verdi }),
728
848
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
729
- import_react_native2.Pressable,
849
+ import_react_native3.Pressable,
730
850
  {
731
851
  testID: `fjern-${l.felt}`,
732
852
  accessibilityRole: "button",
733
853
  accessibilityLabel: `${tekst.kontekstFjern} ${l.etikett.toLowerCase()} fra innsendingen`,
734
854
  onPress: () => onFjernKontekst(l.felt),
735
855
  style: { minWidth: tema.touch, minHeight: tema.touch, alignItems: "center", justifyContent: "center" },
736
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: [
856
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: [
737
857
  "\u2715 ",
738
858
  tekst.kontekstFjern
739
859
  ] })
@@ -743,16 +863,16 @@ function Felt({
743
863
  },
744
864
  l.felt
745
865
  )),
746
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: { paddingTop: tema.space.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Hint, { children: tekst.kontekstAldri }) })
866
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: { paddingTop: tema.space.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Hint, { children: tekst.kontekstAldri }) })
747
867
  ] }) : null
748
868
  ] }),
749
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: { flex: 1, justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
869
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: { flex: 1, justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
750
870
  Btn,
751
871
  {
752
872
  testID: "send",
753
873
  label: spor === "onske" && !forKort ? tekst.nesteOnske : tekst.send,
754
874
  disabled: forKort || sender,
755
- hint: forKort ? tekst.forKort(minTextLength) : void 0,
875
+ hint: forKort ? tekst.forKort(minTextLength) : harVedlegg ? tekst.sendHintMedBilde : void 0,
756
876
  onPress: onSend
757
877
  }
758
878
  ) })
@@ -760,13 +880,13 @@ function Felt({
760
880
  }
761
881
 
762
882
  // src/widget/Valg.tsx
763
- var import_react4 = require("react");
764
- var import_react_native3 = require("react-native");
883
+ var import_react5 = require("react");
884
+ var import_react_native4 = require("react-native");
765
885
  var import_jsx_runtime3 = require("react/jsx-runtime");
766
886
  function Valg({ onVelg }) {
767
887
  const tema = useTema();
768
888
  const flate = (spor, ikon, label, under) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
769
- import_react_native3.Pressable,
889
+ import_react_native4.Pressable,
770
890
  {
771
891
  testID: `spor-${spor}`,
772
892
  accessibilityRole: "button",
@@ -785,9 +905,9 @@ function Valg({ onVelg }) {
785
905
  padding: tema.space.md
786
906
  },
787
907
  children: [
788
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.h1 }, children: ikon }),
908
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native4.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.h1 }, children: ikon }),
789
909
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
790
- import_react_native3.Text,
910
+ import_react_native4.Text,
791
911
  {
792
912
  style: {
793
913
  color: tema.color.textPrimary,
@@ -798,13 +918,13 @@ function Valg({ onVelg }) {
798
918
  children: label
799
919
  }
800
920
  ),
801
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.Text, { style: { color: tema.color.textMuted, fontSize: tema.font.small, textAlign: "center" }, children: under })
921
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native4.Text, { style: { color: tema.color.textMuted, fontSize: tema.font.small, textAlign: "center" }, children: under })
802
922
  ]
803
923
  }
804
924
  );
805
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: { flex: 1, gap: tema.space.lg }, children: [
925
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: { flex: 1, gap: tema.space.lg }, children: [
806
926
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(H, { sub: tekst.valgUnder, children: tekst.valgTittel }),
807
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: { flex: 1, justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: { flexDirection: "row", gap: tema.space.md }, children: [
927
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native4.View, { style: { flex: 1, justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: { flexDirection: "row", gap: tema.space.md }, children: [
808
928
  flate("feil", "\u{1F41E}", tekst.sporFeil, tekst.sporFeilUnder),
809
929
  flate("onske", "\u{1F4A1}", tekst.sporOnske, tekst.sporOnskeUnder)
810
930
  ] }) })
@@ -812,8 +932,8 @@ function Valg({ onVelg }) {
812
932
  }
813
933
 
814
934
  // src/widget/KjenteFeil.tsx
815
- var import_react5 = require("react");
816
- var import_react_native4 = require("react-native");
935
+ var import_react6 = require("react");
936
+ var import_react_native5 = require("react-native");
817
937
  var import_jsx_runtime4 = require("react/jsx-runtime");
818
938
  function KjenteFeil({
819
939
  kort,
@@ -825,19 +945,19 @@ function KjenteFeil({
825
945
  }) {
826
946
  const tema = useTema();
827
947
  if (laster) {
828
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: { flex: 1, gap: tema.space.md }, children: [
948
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.View, { style: { flex: 1, gap: tema.space.md }, children: [
829
949
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(H, { sub: spor === "onske" ? tekst.kjenteFeilUnderOnske : tekst.kjenteFeilUnderFeil, children: spor === "onske" ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil }),
830
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.ActivityIndicator, { accessibilityLabel: "Sjekker kjente feil", color: tema.color.textSecondary })
950
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native5.ActivityIndicator, { accessibilityLabel: "Sjekker kjente feil", color: tema.color.textSecondary })
831
951
  ] });
832
952
  }
833
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: { flex: 1, gap: tema.space.md }, children: [
953
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.View, { style: { flex: 1, gap: tema.space.md }, children: [
834
954
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(H, { sub: spor === "onske" ? tekst.kjenteFeilUnderOnske : tekst.kjenteFeilUnderFeil, children: spor === "onske" ? tekst.kjenteFeilTittelOnske : tekst.kjenteFeilTittelFeil }),
835
955
  kort.map((k) => {
836
956
  const versjon = k.fixedIn ? k.status === "fikset" ? tekst.rettetI(k.fixedIn) : tekst.rettesI(k.fixedIn) : void 0;
837
957
  const kontekst = versjon ? `${k.title}. ${versjon}` : k.title;
838
958
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Card, { children: [
839
959
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
840
- import_react_native4.Text,
960
+ import_react_native5.Text,
841
961
  {
842
962
  style: {
843
963
  color: tema.color.textPrimary,
@@ -849,7 +969,7 @@ function KjenteFeil({
849
969
  }
850
970
  ),
851
971
  k.workaround ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
852
- import_react_native4.Text,
972
+ import_react_native5.Text,
853
973
  {
854
974
  style: {
855
975
  color: tema.color.textSecondary,
@@ -871,7 +991,7 @@ function KjenteFeil({
871
991
  farge: k.status === "fikset" ? "success" : "info"
872
992
  }
873
993
  ) : null,
874
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
994
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.View, { style: { flexDirection: "row", gap: tema.space.sm }, children: [
875
995
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
876
996
  Btn,
877
997
  {
@@ -901,12 +1021,13 @@ function KjenteFeil({
901
1021
  }
902
1022
 
903
1023
  // src/widget/Kvittering.tsx
904
- var import_react6 = require("react");
905
- var import_react_native5 = require("react-native");
1024
+ var import_react7 = require("react");
1025
+ var import_react_native6 = require("react-native");
906
1026
  var import_jsx_runtime5 = require("react/jsx-runtime");
907
1027
  function Kvittering({
908
1028
  art,
909
1029
  saksnummer,
1030
+ vedlegg,
910
1031
  onLukk
911
1032
  }) {
912
1033
  const tema = useTema();
@@ -918,10 +1039,12 @@ function Kvittering({
918
1039
  // (DD-41 presiserer DD-07). Den lover bare at det sendes.
919
1040
  k\u00F8: { h: tekst.offlineTittel, p: tekst.offlineBanner }
920
1041
  }[art];
921
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: { flex: 1, justifyContent: "center", gap: tema.space.lg }, children: [
922
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: { alignItems: "center", gap: tema.space.md }, children: [
1042
+ const overskrift = vedlegg === "feilet" ? tekst.kvitteringVedleggFeilet : innhold.h;
1043
+ const brodtekst = vedlegg === "feilet" ? `${tekst.tekstenErLagret} ${innhold.p}` : innhold.p;
1044
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native6.View, { style: { flex: 1, justifyContent: "center", gap: tema.space.lg }, children: [
1045
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native6.View, { style: { alignItems: "center", gap: tema.space.md }, children: [
923
1046
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
924
- import_react_native5.Text,
1047
+ import_react_native6.Text,
925
1048
  {
926
1049
  accessibilityElementsHidden: true,
927
1050
  importantForAccessibility: "no",
@@ -929,9 +1052,11 @@ function Kvittering({
929
1052
  children: art === "k\xF8" ? "\u21C5" : "\u2713"
930
1053
  }
931
1054
  ),
932
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(H, { children: innhold.h }),
1055
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(H, { children: overskrift }),
1056
+ vedlegg === "feilet" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Banner, { ikon: "\u26A0", tone: "warning", children: tekst.vedleggFeiletBanner }) : null,
1057
+ vedlegg === "forkastet" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Banner, { ikon: "\u{1F4F7}", tone: "info", children: tekst.offlineUtenBilde }) : null,
933
1058
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
934
- import_react_native5.Text,
1059
+ import_react_native6.Text,
935
1060
  {
936
1061
  testID: "kvittering-tekst",
937
1062
  accessibilityRole: "alert",
@@ -942,18 +1067,18 @@ function Kvittering({
942
1067
  lineHeight: tema.lineHeight.body,
943
1068
  textAlign: "center"
944
1069
  },
945
- children: innhold.p
1070
+ children: brodtekst
946
1071
  }
947
1072
  ),
948
- saksnummer ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Hint, { children: tekst.saksnummer(saksnummer) }) : null
1073
+ saksnummer ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Hint, { children: vedlegg === "feilet" ? tekst.saksnummerUtenVedlegg(saksnummer) : tekst.saksnummer(saksnummer) }) : null
949
1074
  ] }),
950
1075
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Btn, { testID: "tilbake-til-appen", label: tekst.tilbakeTilAppen, onPress: onLukk })
951
1076
  ] });
952
1077
  }
953
1078
 
954
1079
  // src/widget/MineInnspill.tsx
955
- var import_react7 = require("react");
956
- var import_react_native6 = require("react-native");
1080
+ var import_react8 = require("react");
1081
+ var import_react_native7 = require("react-native");
957
1082
 
958
1083
  // src/widget/status.ts
959
1084
  var IKON = {
@@ -1018,9 +1143,9 @@ function MineInnspill({
1018
1143
  onNytt
1019
1144
  }) {
1020
1145
  const tema = useTema();
1021
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native6.View, { style: { flex: 1, gap: tema.space.md }, children: [
1146
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native7.View, { style: { flex: 1, gap: tema.space.md }, children: [
1022
1147
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(H, { sub: tekst.mineUnder, children: tekst.mineTittel }),
1023
- laster ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native6.ActivityIndicator, { accessibilityLabel: "Henter innspillene dine", color: tema.color.textSecondary }) : rader.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Hint, { children: tekst.mineTom }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native6.ScrollView, { style: { flex: 1 }, contentContainerStyle: { gap: tema.space.sm }, children: rader.map((rad) => {
1148
+ laster ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native7.ActivityIndicator, { accessibilityLabel: "Henter innspillene dine", color: tema.color.textSecondary }) : rader.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Hint, { children: tekst.mineTom }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native7.ScrollView, { style: { flex: 1 }, contentContainerStyle: { gap: tema.space.sm }, children: rader.map((rad) => {
1024
1149
  const venter = rad.pending === true;
1025
1150
  const v = venter ? venterVisning : statusVisning(rad.status, rad.type, rad.deadlineAt);
1026
1151
  const nokkel = venter ? rad.clientRef : rad.id;
@@ -1033,7 +1158,7 @@ function MineInnspill({
1033
1158
  rad.type === "onske" ? "\xF8nske" : "feil"
1034
1159
  ] }),
1035
1160
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1036
- import_react_native6.Text,
1161
+ import_react_native7.Text,
1037
1162
  {
1038
1163
  style: {
1039
1164
  color: tema.color.textPrimary,
@@ -1043,12 +1168,12 @@ function MineInnspill({
1043
1168
  children: rad.text
1044
1169
  }
1045
1170
  ),
1046
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native6.View, { style: { gap: tema.space.xs }, children: [
1171
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native7.View, { style: { gap: tema.space.xs }, children: [
1047
1172
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StatusPill, { ikon: v.ikon, etikett: v.etikett, farge: v.farge }),
1048
1173
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Hint, { children: v.lofte })
1049
1174
  ] }),
1050
1175
  svar ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1051
- import_react_native6.View,
1176
+ import_react_native7.View,
1052
1177
  {
1053
1178
  style: {
1054
1179
  borderLeftWidth: tema.hairline * 2,
@@ -1057,9 +1182,9 @@ function MineInnspill({
1057
1182
  gap: tema.space.xs
1058
1183
  },
1059
1184
  children: [
1060
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native6.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: tenantName ? tekst.svarFra(tenantName) : tekst.svarFraGenerisk }),
1185
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native7.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, children: tenantName ? tekst.svarFra(tenantName) : tekst.svarFraGenerisk }),
1061
1186
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1062
- import_react_native6.Text,
1187
+ import_react_native7.Text,
1063
1188
  {
1064
1189
  style: {
1065
1190
  color: tema.color.textPrimary,
@@ -1078,8 +1203,209 @@ function MineInnspill({
1078
1203
  ] });
1079
1204
  }
1080
1205
 
1081
- // src/widget/Widget.tsx
1206
+ // src/widget/Skjermbilde.tsx
1207
+ var import_core = require("@innspel/core");
1208
+ var import_react9 = require("react");
1209
+ var import_react_native8 = require("react-native");
1082
1210
  var import_jsx_runtime7 = require("react/jsx-runtime");
1211
+ function Skjermbilde({
1212
+ bilde,
1213
+ automaskerRot,
1214
+ rotStorrelse,
1215
+ previewRef,
1216
+ komponerer,
1217
+ onFjern,
1218
+ onLeggVed
1219
+ }) {
1220
+ const tema = useTema();
1221
+ const [verktoy, setVerktoy] = (0, import_react9.useState)("pensel");
1222
+ const [allTekst, setAllTekst] = (0, import_react9.useState)(false);
1223
+ const [egne, setEgne] = (0, import_react9.useState)([]);
1224
+ const [ramme, setRamme] = (0, import_react9.useState)(null);
1225
+ const strok = (0, import_react9.useRef)([]);
1226
+ const visning = (0, import_react9.useMemo)(() => {
1227
+ if (!ramme) return null;
1228
+ const s = Math.min(ramme.width / bilde.width, ramme.height / bilde.height);
1229
+ return { width: Math.floor(bilde.width * s), height: Math.floor(bilde.height * s) };
1230
+ }, [ramme, bilde.width, bilde.height]);
1231
+ const automasker = (0, import_react9.useMemo)(
1232
+ () => visning ? automaskerRot.map((r) => (0, import_core.skaler)(r, rotStorrelse, visning)) : [],
1233
+ [automaskerRot, rotStorrelse, visning]
1234
+ );
1235
+ const onLayout = (0, import_react9.useCallback)((e) => {
1236
+ const { width, height } = e.nativeEvent.layout;
1237
+ setRamme({ width, height });
1238
+ }, []);
1239
+ const punkt = (e) => ({ x: e.nativeEvent.locationX, y: e.nativeEvent.locationY });
1240
+ const onGrant = (e) => {
1241
+ if (!visning) return;
1242
+ const p = punkt(e);
1243
+ const treff = egne.findIndex((r) => (0, import_core.treffer)(p, r));
1244
+ if (treff >= 0) {
1245
+ setEgne((x) => x.filter((_, i) => i !== treff));
1246
+ return;
1247
+ }
1248
+ if (verktoy === "felt") {
1249
+ const r = (0, import_core.trykkTilRekt)(p, { width: tema.touch * 4, height: tema.touch }, visning);
1250
+ if (r) setEgne((x) => [...x, r]);
1251
+ return;
1252
+ }
1253
+ strok.current = [p];
1254
+ };
1255
+ const onMove = (e) => {
1256
+ if (verktoy !== "pensel" || strok.current.length === 0) return;
1257
+ strok.current.push(punkt(e));
1258
+ };
1259
+ const onRelease = () => {
1260
+ if (verktoy !== "pensel" || !visning || strok.current.length === 0) return;
1261
+ const rekter = (0, import_core.strokTilRekter)(strok.current, screenRules.brushWidth, visning);
1262
+ strok.current = [];
1263
+ if (rekter.length) setEgne((x) => [...x, ...rekter]);
1264
+ };
1265
+ const knapp = (id, ikon, label) => {
1266
+ const valgt = id === "allTekst" ? allTekst : verktoy === id && !allTekst;
1267
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1268
+ import_react_native8.Pressable,
1269
+ {
1270
+ testID: `verktoy-${id}`,
1271
+ accessibilityRole: "button",
1272
+ accessibilityLabel: label,
1273
+ accessibilityState: { selected: valgt },
1274
+ onPress: () => id === "allTekst" ? setAllTekst((a) => !a) : setVerktoy(id),
1275
+ style: {
1276
+ flex: 1,
1277
+ minHeight: tema.touch,
1278
+ alignItems: "center",
1279
+ justifyContent: "center",
1280
+ gap: tema.space.xs,
1281
+ padding: tema.space.xs,
1282
+ borderRadius: tema.radius.md,
1283
+ borderWidth: tema.hairline,
1284
+ borderColor: tema.color.actionSecondaryBorder,
1285
+ borderBottomWidth: valgt ? tema.hairline * 2 : tema.hairline,
1286
+ borderBottomColor: valgt ? tema.color.textPrimary : tema.color.actionSecondaryBorder,
1287
+ backgroundColor: valgt ? tema.color.surfaceRaised : "transparent"
1288
+ },
1289
+ children: [
1290
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native8.Text, { accessibilityElementsHidden: true, importantForAccessibility: "no", style: { fontSize: tema.font.body }, children: ikon }),
1291
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1292
+ import_react_native8.Text,
1293
+ {
1294
+ style: {
1295
+ color: tema.color.textPrimary,
1296
+ fontSize: tema.font.small,
1297
+ fontWeight: valgt ? tema.weight.semibold : tema.weight.regular
1298
+ },
1299
+ children: label
1300
+ }
1301
+ )
1302
+ ]
1303
+ },
1304
+ id
1305
+ );
1306
+ };
1307
+ const a11y = tekst.skjermbildeA11y(automasker.length, egne.length, allTekst);
1308
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { style: { flex: 1, gap: tema.space.md }, children: [
1309
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(H, { sub: tekst.skjermbildeUnder, children: tekst.skjermbildeTittel }),
1310
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { accessibilityRole: "toolbar", accessibilityLabel: tekst.maskering, style: { flexDirection: "row", gap: tema.space.sm }, children: [
1311
+ knapp("felt", "\u25A3", tekst.maskerFelt),
1312
+ knapp("pensel", "\u270E", tekst.tegnOver),
1313
+ knapp("allTekst", "\u25A6", tekst.maskerAllTekst)
1314
+ ] }),
1315
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1316
+ import_react_native8.View,
1317
+ {
1318
+ testID: "skjermbilde-ramme",
1319
+ onLayout,
1320
+ style: {
1321
+ flex: 1,
1322
+ minHeight: tema.touch * 5,
1323
+ alignItems: "center",
1324
+ justifyContent: "center",
1325
+ backgroundColor: screenRules.previewBackdrop,
1326
+ borderRadius: tema.radius.md,
1327
+ overflow: "hidden"
1328
+ },
1329
+ children: visning ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1330
+ import_react_native8.View,
1331
+ {
1332
+ ref: previewRef,
1333
+ collapsable: false,
1334
+ testID: "forhandsvisning",
1335
+ accessibilityRole: "image",
1336
+ accessibilityLabel: a11y,
1337
+ onStartShouldSetResponder: () => !komponerer,
1338
+ onMoveShouldSetResponder: () => !komponerer,
1339
+ onResponderGrant: onGrant,
1340
+ onResponderMove: onMove,
1341
+ onResponderRelease: onRelease,
1342
+ onResponderTerminate: onRelease,
1343
+ style: { width: visning.width, height: visning.height, backgroundColor: screenRules.previewBackdrop },
1344
+ children: [
1345
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1346
+ import_react_native8.Image,
1347
+ {
1348
+ testID: "skjermbilde-bilde",
1349
+ source: { uri: bilde.uri },
1350
+ blurRadius: allTekst ? screenRules.textBlurRadius : 0,
1351
+ style: { width: visning.width, height: visning.height },
1352
+ accessibilityIgnoresInvertColors: true
1353
+ }
1354
+ ),
1355
+ automasker.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1356
+ import_react_native8.View,
1357
+ {
1358
+ testID: `automask-${i}`,
1359
+ pointerEvents: "none",
1360
+ style: {
1361
+ position: "absolute",
1362
+ left: r.x,
1363
+ top: r.y,
1364
+ width: r.width,
1365
+ height: r.height,
1366
+ backgroundColor: screenRules.autoMaskFill,
1367
+ borderWidth: tema.hairline * 2,
1368
+ borderColor: screenRules.autoMaskStroke,
1369
+ alignItems: "center",
1370
+ justifyContent: "center"
1371
+ },
1372
+ children: !komponerer ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.small }, numberOfLines: 1, children: [
1373
+ "\u{1F512} ",
1374
+ tekst.maskertAvAppen
1375
+ ] }) : null
1376
+ },
1377
+ `auto-${i}`
1378
+ )),
1379
+ egne.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1380
+ import_react_native8.View,
1381
+ {
1382
+ testID: `maske-${i}`,
1383
+ pointerEvents: "none",
1384
+ style: { position: "absolute", left: r.x, top: r.y, width: r.width, height: r.height, backgroundColor: screenRules.brushFill }
1385
+ },
1386
+ `egen-${i}`
1387
+ ))
1388
+ ]
1389
+ }
1390
+ ) : null
1391
+ }
1392
+ ),
1393
+ automasker.length ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Hint, { children: [
1394
+ "\u{1F512} ",
1395
+ tekst.maskertAvAppenHint
1396
+ ] }) : null,
1397
+ egne.length ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Hint, { children: tekst.dittStrok }) : null,
1398
+ allTekst ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Hint, { children: tekst.allTekstHint }) : null,
1399
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { style: { gap: tema.space.sm }, children: [
1400
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { variant: "danger", testID: "fjern-bildet", ikon: "\u{1F5D1}", label: tekst.fjernBildet, onPress: onFjern, disabled: komponerer }),
1401
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { testID: "legg-ved", label: tekst.leggVedOgFortsett, onPress: onLeggVed, disabled: komponerer || !visning, hint: tekst.leggVedHintDD42 })
1402
+ ] })
1403
+ ] });
1404
+ }
1405
+
1406
+ // src/widget/Widget.tsx
1407
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1408
+ var FANGST = { format: "jpg", quality: 0.85 };
1083
1409
  function Widget({
1084
1410
  client,
1085
1411
  synlig,
@@ -1088,20 +1414,28 @@ function Widget({
1088
1414
  tenantName
1089
1415
  }) {
1090
1416
  const tema = useTema();
1091
- const [steg, setSteg] = (0, import_react8.useState)("valg");
1092
- const [spor, setSpor] = (0, import_react8.useState)("feil");
1093
- const [verdi, setVerdi] = (0, import_react8.useState)("");
1094
- const [kort, setKort] = (0, import_react8.useState)([]);
1095
- const [lasterKort, setLasterKort] = (0, import_react8.useState)(false);
1096
- const [lenketTil, setLenketTil] = (0, import_react8.useState)();
1097
- const [funn, setFunn] = (0, import_react8.useState)([]);
1098
- const [fjernede, setFjernede] = (0, import_react8.useState)([]);
1099
- const [sender, setSender] = (0, import_react8.useState)(false);
1100
- const [feil, setFeil] = (0, import_react8.useState)();
1101
- const [kvittering, setKvittering] = (0, import_react8.useState)();
1102
- const [mine, setMine] = (0, import_react8.useState)([]);
1103
- const [lasterMine, setLasterMine] = (0, import_react8.useState)(false);
1104
- const nullstill = (0, import_react8.useCallback)(() => {
1417
+ const skjermbilde = useSkjermbilde();
1418
+ const previewRef = (0, import_react10.useRef)(null);
1419
+ const [steg, setSteg] = (0, import_react10.useState)("valg");
1420
+ const [spor, setSpor] = (0, import_react10.useState)("feil");
1421
+ const [verdi, setVerdi] = (0, import_react10.useState)("");
1422
+ const [kort, setKort] = (0, import_react10.useState)([]);
1423
+ const [lasterKort, setLasterKort] = (0, import_react10.useState)(false);
1424
+ const [lenketTil, setLenketTil] = (0, import_react10.useState)();
1425
+ const [funn, setFunn] = (0, import_react10.useState)([]);
1426
+ const [fjernede, setFjernede] = (0, import_react10.useState)([]);
1427
+ const [sender, setSender] = (0, import_react10.useState)(false);
1428
+ const [feil, setFeil] = (0, import_react10.useState)();
1429
+ const [kvittering, setKvittering] = (0, import_react10.useState)();
1430
+ const [mine, setMine] = (0, import_react10.useState)([]);
1431
+ const [lasterMine, setLasterMine] = (0, import_react10.useState)(false);
1432
+ const [bilde, setBilde] = (0, import_react10.useState)();
1433
+ const [automasker, setAutomasker] = (0, import_react10.useState)([]);
1434
+ const [rotStorrelse, setRotStorrelse] = (0, import_react10.useState)({ width: 1, height: 1 });
1435
+ const [komponerer, setKomponerer] = (0, import_react10.useState)(false);
1436
+ const [vedlegg, setVedlegg] = (0, import_react10.useState)();
1437
+ const skjermbildeMulig = client.settings.screenshotsEnabled && skjermbilde?.adapter != null;
1438
+ const nullstill = (0, import_react10.useCallback)(() => {
1105
1439
  setSteg("valg");
1106
1440
  setSpor("feil");
1107
1441
  setVerdi("");
@@ -1111,18 +1445,22 @@ function Widget({
1111
1445
  setFjernede([]);
1112
1446
  setFeil(void 0);
1113
1447
  setKvittering(void 0);
1448
+ setBilde(void 0);
1449
+ setAutomasker([]);
1450
+ setVedlegg(void 0);
1451
+ setKomponerer(false);
1114
1452
  }, []);
1115
- const lukk = (0, import_react8.useCallback)(() => {
1453
+ const lukk = (0, import_react10.useCallback)(() => {
1116
1454
  onLukk();
1117
1455
  nullstill();
1118
1456
  }, [onLukk, nullstill]);
1119
- (0, import_react8.useEffect)(() => {
1457
+ (0, import_react10.useEffect)(() => {
1120
1458
  if (!synlig) return;
1121
1459
  client.track({ name: "widget_opened" });
1122
1460
  void client.queue.flush().catch(() => void 0);
1123
1461
  if (apneOpsjoner?.track) velgSpor(apneOpsjoner.track);
1124
1462
  }, [synlig]);
1125
- const hentKort = (0, import_react8.useCallback)(async () => {
1463
+ const hentKort = (0, import_react10.useCallback)(async () => {
1126
1464
  setLasterKort(true);
1127
1465
  try {
1128
1466
  const q = apneOpsjoner?.screen ? { screen: apneOpsjoner.screen } : {};
@@ -1131,7 +1469,7 @@ function Widget({
1131
1469
  setLasterKort(false);
1132
1470
  }
1133
1471
  }, [client, apneOpsjoner?.screen]);
1134
- const velgSpor = (0, import_react8.useCallback)(
1472
+ const velgSpor = (0, import_react10.useCallback)(
1135
1473
  async (valgt) => {
1136
1474
  setSpor(valgt);
1137
1475
  client.track({ name: "track_selected", type: valgt });
@@ -1144,17 +1482,62 @@ function Widget({
1144
1482
  },
1145
1483
  [client, hentKort]
1146
1484
  );
1147
- (0, import_react8.useEffect)(() => {
1485
+ (0, import_react10.useEffect)(() => {
1148
1486
  if (steg === "kjenteFeil" && !lasterKort && kort.length === 0) setSteg("felt");
1149
1487
  }, [steg, lasterKort, kort.length]);
1150
- const endreTekst = (0, import_react8.useCallback)(
1488
+ const endreTekst = (0, import_react10.useCallback)(
1151
1489
  (v) => {
1152
1490
  setVerdi(v);
1153
1491
  setFunn(client.scanText(v));
1154
1492
  },
1155
1493
  [client]
1156
1494
  );
1157
- const send = (0, import_react8.useCallback)(async () => {
1495
+ const taSkjermbilde = (0, import_react10.useCallback)(async () => {
1496
+ if (!skjermbilde?.adapter) return;
1497
+ const { adapter, rootRef, privat } = skjermbilde;
1498
+ setFeil(void 0);
1499
+ try {
1500
+ const fangst = await adapter.capture(rootRef, FANGST);
1501
+ const rot = await adapter.measure(rootRef);
1502
+ const private_ = await Promise.all(privat.refs().map((r) => adapter.measure(r)));
1503
+ if (rot) {
1504
+ setRotStorrelse({ width: rot.width, height: rot.height });
1505
+ setAutomasker(
1506
+ private_.filter((r) => r !== null).map((r) => ({ x: r.x - rot.x, y: r.y - rot.y, width: r.width, height: r.height }))
1507
+ );
1508
+ } else {
1509
+ setRotStorrelse({ width: fangst.width, height: fangst.height });
1510
+ setAutomasker([]);
1511
+ }
1512
+ setBilde(fangst);
1513
+ setSteg("skjermbilde");
1514
+ } catch {
1515
+ setFeil(tekst.skjermbildeFeilet);
1516
+ }
1517
+ }, [skjermbilde]);
1518
+ const leggVedBilde = (0, import_react10.useCallback)(async () => {
1519
+ if (!skjermbilde?.adapter) return;
1520
+ setKomponerer(true);
1521
+ try {
1522
+ const komposit = await skjermbilde.adapter.capture(previewRef, FANGST);
1523
+ const body = await skjermbilde.adapter.read(komposit.uri);
1524
+ setVedlegg({ mime: "image/jpeg", body, width: komposit.width, height: komposit.height });
1525
+ setBilde(void 0);
1526
+ setSteg("felt");
1527
+ } catch {
1528
+ setFeil(tekst.skjermbildeFeilet);
1529
+ setSteg("felt");
1530
+ } finally {
1531
+ setKomponerer(false);
1532
+ }
1533
+ }, [skjermbilde]);
1534
+ const fjernBilde = (0, import_react10.useCallback)(() => {
1535
+ setBilde(void 0);
1536
+ setAutomasker([]);
1537
+ setVedlegg(void 0);
1538
+ setSteg("felt");
1539
+ }, []);
1540
+ const send = (0, import_react10.useCallback)(async () => {
1158
1541
  if (spor === "onske" && steg === "felt" && kort.length === 0 && !lasterKort) {
1159
1542
  setSteg("kjenteFeil");
1160
1543
  await hentKort();
@@ -1166,24 +1549,29 @@ function Widget({
1166
1549
  const res = await client.capture({
1167
1550
  type: spor,
1168
1551
  text: verdi,
1552
+ ...vedlegg ? { attachment: vedlegg } : {},
1169
1553
  ...spor === "feil" && lenketTil ? { relatedKnownIssueId: lenketTil.id } : {},
1170
1554
  ...fjernede.length ? { context: fjernetKontekst(client, fjernede) } : {}
1171
1555
  });
1172
1556
  if (res.status === "queued") {
1173
- setKvittering({ art: "k\xF8" });
1557
+ setKvittering({ art: "k\xF8", ...res.attachment ? { vedlegg: "forkastet" } : {} });
1174
1558
  } else {
1175
- setKvittering({ art: spor, nr: res.submission.id });
1559
+ setKvittering({
1560
+ art: spor,
1561
+ nr: res.submission.id,
1562
+ ...res.attachment?.status === "failed" ? { vedlegg: "feilet" } : {}
1563
+ });
1176
1564
  }
1177
1565
  setSteg("kvittering");
1178
1566
  } catch (e) {
1179
- if (e instanceof import_core.InnspelQueueFullError) setFeil(e.userMessage);
1180
- else if (e instanceof import_core.InnspelApiError) setFeil(e.message);
1567
+ if (e instanceof import_core2.InnspelQueueFullError) setFeil(e.userMessage);
1568
+ else if (e instanceof import_core2.InnspelApiError) setFeil(e.message);
1181
1569
  else setFeil("tjeneren svarte ikke.");
1182
1570
  } finally {
1183
1571
  setSender(false);
1184
1572
  }
1185
- }, [client, spor, steg, verdi, lenketTil, fjernede, kort.length, lasterKort, hentKort]);
1186
- const jaOgsa = (0, import_react8.useCallback)(
1573
+ }, [client, spor, steg, verdi, vedlegg, lenketTil, fjernede, kort.length, lasterKort, hentKort]);
1574
+ const jaOgsa = (0, import_react10.useCallback)(
1187
1575
  async (k) => {
1188
1576
  setSender(true);
1189
1577
  try {
@@ -1191,14 +1579,14 @@ function Widget({
1191
1579
  setKvittering({ art: "jaOgsa", nr: res.id });
1192
1580
  setSteg("kvittering");
1193
1581
  } catch (e) {
1194
- setFeil(e instanceof import_core.InnspelApiError ? e.message : "tjeneren svarte ikke.");
1582
+ setFeil(e instanceof import_core2.InnspelApiError ? e.message : "tjeneren svarte ikke.");
1195
1583
  } finally {
1196
1584
  setSender(false);
1197
1585
  }
1198
1586
  },
1199
1587
  [client]
1200
1588
  );
1201
- const visMine = (0, import_react8.useCallback)(async () => {
1589
+ const visMine = (0, import_react10.useCallback)(async () => {
1202
1590
  setSteg("mine");
1203
1591
  setLasterMine(true);
1204
1592
  try {
@@ -1209,16 +1597,16 @@ function Widget({
1209
1597
  setLasterMine(false);
1210
1598
  }
1211
1599
  }, [client]);
1212
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1213
- import_react_native7.Modal,
1600
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1601
+ import_react_native9.Modal,
1214
1602
  {
1215
1603
  visible: synlig,
1216
1604
  transparent: true,
1217
1605
  animationType: "slide",
1218
1606
  onRequestClose: lukk,
1219
1607
  accessibilityViewIsModal: true,
1220
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native7.View, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1221
- import_react_native7.View,
1608
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.View, { style: { flex: 1, backgroundColor: tema.color.scrim, justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1609
+ import_react_native9.View,
1222
1610
  {
1223
1611
  testID: "innspel-widget",
1224
1612
  accessibilityViewIsModal: true,
@@ -1233,26 +1621,26 @@ function Widget({
1233
1621
  minHeight: "60%"
1234
1622
  },
1235
1623
  children: [
1236
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native7.View, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "center" }, children: [
1237
- steg !== "valg" && steg !== "kvittering" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { variant: "ghost", testID: "tilbake", ikon: "\u2190", label: tekst.tilbake, onPress: nullstill }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native7.View, {}),
1238
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1239
- import_react_native7.Pressable,
1624
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native9.View, { style: { flexDirection: "row", justifyContent: "space-between", alignItems: "center" }, children: [
1625
+ steg === "skjermbilde" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { variant: "ghost", testID: "tilbake", ikon: "\u2190", label: tekst.tilbake, onPress: fjernBilde }) : steg !== "valg" && steg !== "kvittering" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { variant: "ghost", testID: "tilbake", ikon: "\u2190", label: tekst.tilbake, onPress: nullstill }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.View, {}),
1626
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1627
+ import_react_native9.Pressable,
1240
1628
  {
1241
1629
  testID: "lukk",
1242
1630
  accessibilityRole: "button",
1243
1631
  accessibilityLabel: tekst.lukk,
1244
1632
  onPress: lukk,
1245
1633
  style: { minWidth: tema.touch, minHeight: tema.touch, alignItems: "center", justifyContent: "center" },
1246
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native7.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.body }, children: "\u2715" })
1634
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.Text, { style: { color: tema.color.textSecondary, fontSize: tema.font.body }, children: "\u2715" })
1247
1635
  }
1248
1636
  )
1249
1637
  ] }),
1250
- feil ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Banner, { live: true, ikon: "\u26A0", tone: "danger", children: tekst.sendefeilBanner(feil) }) : null,
1251
- steg === "valg" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1252
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Valg, { onVelg: velgSpor }),
1253
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { variant: "ghost", testID: "mine-innspill", ikon: "\u{1F4CB}", label: tekst.mineTittel, onPress: visMine })
1638
+ feil ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Banner, { live: true, ikon: "\u26A0", tone: "danger", children: tekst.sendefeilBanner(feil) }) : null,
1639
+ steg === "valg" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1640
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Valg, { onVelg: velgSpor }),
1641
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { variant: "ghost", testID: "mine-innspill", ikon: "\u{1F4CB}", label: tekst.mineTittel, onPress: visMine })
1254
1642
  ] }) : null,
1255
- steg === "kjenteFeil" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1643
+ steg === "kjenteFeil" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1256
1644
  KjenteFeil,
1257
1645
  {
1258
1646
  kort,
@@ -1266,7 +1654,7 @@ function Widget({
1266
1654
  onNei: () => spor === "onske" ? void send() : setSteg("felt")
1267
1655
  }
1268
1656
  ) : null,
1269
- steg === "felt" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1657
+ steg === "felt" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1270
1658
  Felt,
1271
1659
  {
1272
1660
  spor,
@@ -1280,11 +1668,34 @@ function Widget({
1280
1668
  ...lenketTil ? { lenketTil, onFjernLenke: () => setLenketTil(void 0) } : {},
1281
1669
  funn,
1282
1670
  onSend: send,
1283
- sender
1671
+ sender,
1672
+ ...skjermbildeMulig ? { onSkjermbilde: taSkjermbilde } : {},
1673
+ harVedlegg: vedlegg !== void 0,
1674
+ onFjernVedlegg: fjernBilde
1675
+ }
1676
+ ) : null,
1677
+ steg === "skjermbilde" && bilde ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1678
+ Skjermbilde,
1679
+ {
1680
+ bilde,
1681
+ automaskerRot: automasker,
1682
+ rotStorrelse,
1683
+ previewRef,
1684
+ komponerer,
1685
+ onFjern: fjernBilde,
1686
+ onLeggVed: leggVedBilde
1284
1687
  }
1285
1688
  ) : null,
1286
- steg === "kvittering" && kvittering ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Kvittering, { art: kvittering.art, ...kvittering.nr ? { saksnummer: kvittering.nr } : {}, onLukk: lukk }) : null,
1287
- steg === "mine" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1689
+ steg === "kvittering" && kvittering ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1690
+ Kvittering,
1691
+ {
1692
+ art: kvittering.art,
1693
+ ...kvittering.nr ? { saksnummer: kvittering.nr } : {},
1694
+ ...kvittering.vedlegg ? { vedlegg: kvittering.vedlegg } : {},
1695
+ onLukk: lukk
1696
+ }
1697
+ ) : null,
1698
+ steg === "mine" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1288
1699
  MineInnspill,
1289
1700
  {
1290
1701
  rader: mine,
@@ -1308,35 +1719,42 @@ function fjernetKontekst(client, fjernede) {
1308
1719
  }
1309
1720
 
1310
1721
  // src/InnspelProvider.tsx
1311
- var import_jsx_runtime8 = require("react/jsx-runtime");
1312
- var Kontekst = (0, import_react9.createContext)(null);
1722
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1723
+ var Kontekst = (0, import_react11.createContext)(null);
1313
1724
  function InnspelProvider({
1314
1725
  client,
1315
1726
  children,
1316
1727
  theme,
1317
1728
  colorScheme = "dark",
1318
- tenantName
1729
+ tenantName,
1730
+ screenshot
1319
1731
  }) {
1320
- const [synlig, setSynlig] = (0, import_react9.useState)(false);
1321
- const [apneOpsjoner, setApneOpsjoner] = (0, import_react9.useState)();
1322
- const registrert = (0, import_react9.useRef)(false);
1323
- const open = (0, import_react9.useCallback)(
1732
+ const [synlig, setSynlig] = (0, import_react11.useState)(false);
1733
+ const [apneOpsjoner, setApneOpsjoner] = (0, import_react11.useState)();
1734
+ const registrert = (0, import_react11.useRef)(false);
1735
+ const rootRef = (0, import_react11.useRef)(null);
1736
+ const privat = (0, import_react11.useMemo)(createPrivateRegistry, []);
1737
+ const open = (0, import_react11.useCallback)(
1324
1738
  async (options) => {
1325
1739
  setApneOpsjoner(options);
1326
1740
  setSynlig(true);
1327
1741
  },
1328
1742
  []
1329
1743
  );
1330
- const close = (0, import_react9.useCallback)(() => setSynlig(false), []);
1744
+ const close = (0, import_react11.useCallback)(() => setSynlig(false), []);
1331
1745
  if (!registrert.current) {
1332
1746
  client.registerPresenter({ open });
1333
1747
  registrert.current = true;
1334
1748
  }
1335
- const tema = (0, import_react9.useMemo)(() => byggTema(theme, colorScheme), [theme, colorScheme]);
1336
- const verdi = (0, import_react9.useMemo)(() => ({ client, open, close }), [client, open, close]);
1337
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Kontekst.Provider, { value: verdi, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(TemaProvider, { value: tema, children: [
1338
- children,
1339
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1749
+ const tema = (0, import_react11.useMemo)(() => byggTema(theme, colorScheme), [theme, colorScheme]);
1750
+ const verdi = (0, import_react11.useMemo)(() => ({ client, open, close }), [client, open, close]);
1751
+ const skjermbilde = (0, import_react11.useMemo)(
1752
+ () => ({ adapter: screenshot ?? null, rootRef, privat }),
1753
+ [screenshot, privat]
1754
+ );
1755
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Kontekst.Provider, { value: verdi, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SkjermbildeContext.Provider, { value: skjermbilde, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(TemaProvider, { value: tema, children: [
1756
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { ref: rootRef, collapsable: false, style: { flex: 1 }, testID: "innspel-rot", children }),
1757
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1340
1758
  Widget,
1341
1759
  {
1342
1760
  client,
@@ -1346,10 +1764,10 @@ function InnspelProvider({
1346
1764
  onLukk: close
1347
1765
  }
1348
1766
  )
1349
- ] }) });
1767
+ ] }) }) });
1350
1768
  }
1351
1769
  function useInnspel() {
1352
- const k = (0, import_react9.useContext)(Kontekst);
1770
+ const k = (0, import_react11.useContext)(Kontekst);
1353
1771
  if (!k) {
1354
1772
  throw new Error(
1355
1773
  "[innspel] useInnspel() ble kalt utenfor <InnspelProvider>. Pakk appen din i den \u2014 se README.md."
@@ -1358,6 +1776,21 @@ function useInnspel() {
1358
1776
  return k;
1359
1777
  }
1360
1778
 
1779
+ // src/InnspelPrivate.tsx
1780
+ var import_react12 = require("react");
1781
+ var import_react_native11 = require("react-native");
1782
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1783
+ function InnspelPrivate({ children, style }) {
1784
+ const ref = (0, import_react12.useRef)(null);
1785
+ const kontekst = useSkjermbilde();
1786
+ const registrer = kontekst?.privat.register;
1787
+ (0, import_react12.useEffect)(() => {
1788
+ if (!registrer) return;
1789
+ return registrer(ref);
1790
+ }, [registrer]);
1791
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native11.View, { ref, collapsable: false, style, testID: "innspel-privat", children });
1792
+ }
1793
+
1361
1794
  // src/lagring.ts
1362
1795
  function createStorage(pakke) {
1363
1796
  return {
@@ -1380,9 +1813,11 @@ function createMemoryStorage() {
1380
1813
  }
1381
1814
  // Annotate the CommonJS export names for ESM import in node:
1382
1815
  0 && (module.exports = {
1816
+ InnspelPrivate,
1383
1817
  InnspelProvider,
1384
1818
  byggTema,
1385
1819
  createMemoryStorage,
1820
+ createScreenshotAdapter,
1386
1821
  createStorage,
1387
1822
  darkTokens,
1388
1823
  light,