@bbearai/react-native 0.5.3 → 0.5.5

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.mjs CHANGED
@@ -11713,6 +11713,8 @@ var BugBearClient = class {
11713
11713
  title: report.title || this.generateTitle(report),
11714
11714
  description: report.description,
11715
11715
  severity: report.severity,
11716
+ category: report.category,
11717
+ // Bug category (ui, performance, crash, etc.)
11716
11718
  failed_at_step: report.failedAtStep,
11717
11719
  voice_audio_url: report.voiceAudioUrl,
11718
11720
  voice_transcript: report.voiceTranscript,
@@ -13269,6 +13271,14 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
13269
13271
  initializeBugBear(newClient);
13270
13272
  }
13271
13273
  }, [enabled, config, initializeBugBear]);
13274
+ useEffect(() => {
13275
+ if (!client || !isTester || !isQAEnabled) return;
13276
+ const interval = setInterval(() => {
13277
+ refreshThreads();
13278
+ refreshIssueCounts();
13279
+ }, 3e4);
13280
+ return () => clearInterval(interval);
13281
+ }, [client, isTester, isQAEnabled, refreshThreads, refreshIssueCounts]);
13272
13282
  const currentAssignment = assignments.find(
13273
13283
  (a) => a.status === "in_progress"
13274
13284
  ) || assignments.find(
@@ -13320,15 +13330,15 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
13320
13330
  }
13321
13331
 
13322
13332
  // src/BugBearButton.tsx
13323
- import React16, { useState as useState11, useRef as useRef3 } from "react";
13333
+ import React17, { useState as useState12, useRef as useRef3 } from "react";
13324
13334
  import {
13325
- View as View15,
13326
- Text as Text15,
13335
+ View as View16,
13336
+ Text as Text16,
13327
13337
  Image as Image4,
13328
- TouchableOpacity as TouchableOpacity14,
13329
- Modal as Modal2,
13338
+ TouchableOpacity as TouchableOpacity15,
13339
+ Modal as Modal3,
13330
13340
  ScrollView as ScrollView3,
13331
- StyleSheet as StyleSheet16,
13341
+ StyleSheet as StyleSheet17,
13332
13342
  Dimensions as Dimensions2,
13333
13343
  KeyboardAvoidingView,
13334
13344
  Platform as Platform4,
@@ -14672,20 +14682,185 @@ var styles6 = StyleSheet7.create({
14672
14682
  });
14673
14683
 
14674
14684
  // src/widget/screens/ReportScreen.tsx
14675
- import React8, { useState as useState6, useRef as useRef2 } from "react";
14676
- import { View as View7, Text as Text7, TouchableOpacity as TouchableOpacity7, TextInput as TextInput3, StyleSheet as StyleSheet8 } from "react-native";
14685
+ import React9, { useState as useState7, useRef as useRef2, useEffect as useEffect5 } from "react";
14686
+ import { View as View8, Text as Text8, TouchableOpacity as TouchableOpacity8, TextInput as TextInput3, StyleSheet as StyleSheet9 } from "react-native";
14687
+
14688
+ // src/widget/CategoryPicker.tsx
14689
+ import React8, { useState as useState6 } from "react";
14690
+ import { View as View7, Text as Text7, TouchableOpacity as TouchableOpacity7, Modal as Modal2, StyleSheet as StyleSheet8 } from "react-native";
14691
+ var categoryOptions = [
14692
+ { value: "ui_ux", label: "UI/UX", icon: "\u{1F3A8}" },
14693
+ { value: "functional", label: "Functional", icon: "\u2699\uFE0F" },
14694
+ { value: "crash", label: "Crash", icon: "\u{1F4A5}" },
14695
+ { value: "security", label: "Security", icon: "\u{1F510}" },
14696
+ { value: "other", label: "Other", icon: "\u{1F4DD}" }
14697
+ ];
14698
+ function CategoryPicker({ value, onChange, optional = true }) {
14699
+ const [modalVisible, setModalVisible] = useState6(false);
14700
+ const selectedOption = value ? categoryOptions.find((o) => o.value === value) : null;
14701
+ const handleSelect = (category) => {
14702
+ onChange(category);
14703
+ setModalVisible(false);
14704
+ };
14705
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(
14706
+ TouchableOpacity7,
14707
+ {
14708
+ style: styles7.trigger,
14709
+ onPress: () => setModalVisible(true)
14710
+ },
14711
+ /* @__PURE__ */ React8.createElement(Text7, { style: selectedOption ? styles7.triggerTextSelected : styles7.triggerTextPlaceholder }, selectedOption ? `${selectedOption.icon} ${selectedOption.label}` : optional ? "Select category (optional)" : "Select category"),
14712
+ /* @__PURE__ */ React8.createElement(Text7, { style: styles7.chevron }, "\u25BC")
14713
+ ), /* @__PURE__ */ React8.createElement(
14714
+ Modal2,
14715
+ {
14716
+ visible: modalVisible,
14717
+ transparent: true,
14718
+ animationType: "fade",
14719
+ onRequestClose: () => setModalVisible(false)
14720
+ },
14721
+ /* @__PURE__ */ React8.createElement(
14722
+ TouchableOpacity7,
14723
+ {
14724
+ style: styles7.overlay,
14725
+ activeOpacity: 1,
14726
+ onPress: () => setModalVisible(false)
14727
+ },
14728
+ /* @__PURE__ */ React8.createElement(View7, { style: styles7.modal, onStartShouldSetResponder: () => true }, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.modalTitle }, "Select Category"), optional && /* @__PURE__ */ React8.createElement(
14729
+ TouchableOpacity7,
14730
+ {
14731
+ style: [styles7.option, !value && styles7.optionSelected],
14732
+ onPress: () => handleSelect(null)
14733
+ },
14734
+ /* @__PURE__ */ React8.createElement(Text7, { style: styles7.optionText }, "\u2014 None \u2014")
14735
+ ), categoryOptions.map(({ value: optValue, label, icon }) => /* @__PURE__ */ React8.createElement(
14736
+ TouchableOpacity7,
14737
+ {
14738
+ key: optValue,
14739
+ style: [styles7.option, value === optValue && styles7.optionSelected],
14740
+ onPress: () => handleSelect(optValue)
14741
+ },
14742
+ /* @__PURE__ */ React8.createElement(Text7, { style: styles7.optionIcon }, icon),
14743
+ /* @__PURE__ */ React8.createElement(Text7, { style: styles7.optionText }, label),
14744
+ value === optValue && /* @__PURE__ */ React8.createElement(Text7, { style: styles7.checkmark }, "\u2713")
14745
+ )), /* @__PURE__ */ React8.createElement(
14746
+ TouchableOpacity7,
14747
+ {
14748
+ style: styles7.cancelButton,
14749
+ onPress: () => setModalVisible(false)
14750
+ },
14751
+ /* @__PURE__ */ React8.createElement(Text7, { style: styles7.cancelText }, "Cancel")
14752
+ ))
14753
+ )
14754
+ ));
14755
+ }
14756
+ var styles7 = StyleSheet8.create({
14757
+ trigger: {
14758
+ flexDirection: "row",
14759
+ alignItems: "center",
14760
+ justifyContent: "space-between",
14761
+ backgroundColor: colors.card,
14762
+ borderWidth: 1,
14763
+ borderColor: colors.border,
14764
+ borderRadius: 8,
14765
+ paddingHorizontal: 12,
14766
+ paddingVertical: 10
14767
+ },
14768
+ triggerTextSelected: {
14769
+ fontSize: 14,
14770
+ color: colors.textPrimary
14771
+ },
14772
+ triggerTextPlaceholder: {
14773
+ fontSize: 14,
14774
+ color: colors.textMuted
14775
+ },
14776
+ chevron: {
14777
+ fontSize: 10,
14778
+ color: colors.textMuted
14779
+ },
14780
+ overlay: {
14781
+ flex: 1,
14782
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
14783
+ justifyContent: "center",
14784
+ alignItems: "center",
14785
+ padding: 24
14786
+ },
14787
+ modal: {
14788
+ width: "100%",
14789
+ maxWidth: 300,
14790
+ backgroundColor: colors.card,
14791
+ borderRadius: 16,
14792
+ padding: 8,
14793
+ borderWidth: 1,
14794
+ borderColor: colors.border
14795
+ },
14796
+ modalTitle: {
14797
+ fontSize: 16,
14798
+ fontWeight: "600",
14799
+ color: colors.textPrimary,
14800
+ textAlign: "center",
14801
+ paddingVertical: 12,
14802
+ borderBottomWidth: 1,
14803
+ borderBottomColor: colors.border,
14804
+ marginBottom: 4
14805
+ },
14806
+ option: {
14807
+ flexDirection: "row",
14808
+ alignItems: "center",
14809
+ paddingVertical: 14,
14810
+ paddingHorizontal: 16,
14811
+ borderRadius: 8
14812
+ },
14813
+ optionSelected: {
14814
+ backgroundColor: colors.blue + "20"
14815
+ },
14816
+ optionIcon: {
14817
+ fontSize: 18,
14818
+ marginRight: 12
14819
+ },
14820
+ optionText: {
14821
+ flex: 1,
14822
+ fontSize: 15,
14823
+ color: colors.textPrimary
14824
+ },
14825
+ checkmark: {
14826
+ fontSize: 16,
14827
+ color: colors.blue,
14828
+ fontWeight: "600"
14829
+ },
14830
+ cancelButton: {
14831
+ marginTop: 8,
14832
+ paddingVertical: 12,
14833
+ borderTopWidth: 1,
14834
+ borderTopColor: colors.border
14835
+ },
14836
+ cancelText: {
14837
+ fontSize: 15,
14838
+ color: colors.textMuted,
14839
+ textAlign: "center"
14840
+ }
14841
+ });
14842
+
14843
+ // src/widget/screens/ReportScreen.tsx
14677
14844
  function ReportScreen({ nav, prefill }) {
14678
14845
  const { client, getDeviceInfo, uploadImage, refreshAssignments } = useBugBear();
14679
- const [reportType, setReportType] = useState6(prefill?.type || "bug");
14680
- const [severity, setSeverity] = useState6("medium");
14681
- const [description, setDescription] = useState6("");
14682
- const [affectedScreen, setAffectedScreen] = useState6("");
14683
- const [submitting, setSubmitting] = useState6(false);
14684
- const [error, setError] = useState6(null);
14846
+ const [reportType, setReportType] = useState7(prefill?.type || "bug");
14847
+ const [severity, setSeverity] = useState7("medium");
14848
+ const [category, setCategory] = useState7(null);
14849
+ const [description, setDescription] = useState7("");
14850
+ const [affectedScreen, setAffectedScreen] = useState7("");
14851
+ const [submitting, setSubmitting] = useState7(false);
14852
+ const [error, setError] = useState7(null);
14685
14853
  const submittingRef = useRef2(false);
14686
14854
  const images = useImageAttachments(uploadImage, 5, "screenshots");
14687
14855
  const isRetestFailure = prefill?.type === "test_fail";
14688
14856
  const isBugType = reportType === "bug" || reportType === "test_fail";
14857
+ useEffect5(() => {
14858
+ if (reportType === "feedback" || reportType === "suggestion") {
14859
+ setCategory("other");
14860
+ } else {
14861
+ setCategory(null);
14862
+ }
14863
+ }, [reportType]);
14689
14864
  const handleSubmit = async () => {
14690
14865
  if (!client || !description.trim()) return;
14691
14866
  if (submittingRef.current) return;
@@ -14703,6 +14878,7 @@ function ReportScreen({ nav, prefill }) {
14703
14878
  type: reportType,
14704
14879
  description: description.trim(),
14705
14880
  severity: isBugType ? severity : void 0,
14881
+ category: category || void 0,
14706
14882
  assignmentId: prefill?.assignmentId,
14707
14883
  testCaseId: prefill?.testCaseId,
14708
14884
  appContext,
@@ -14727,23 +14903,23 @@ function ReportScreen({ nav, prefill }) {
14727
14903
  submittingRef.current = false;
14728
14904
  }
14729
14905
  };
14730
- return /* @__PURE__ */ React8.createElement(View7, null, isRetestFailure ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(View7, { style: styles7.retestBanner }, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.retestIcon }, "\u{1F504}"), /* @__PURE__ */ React8.createElement(View7, null, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.retestTitle }, "Bug Still Present"), /* @__PURE__ */ React8.createElement(Text7, { style: styles7.retestSubtitle }, "The fix did not resolve this issue"))), /* @__PURE__ */ React8.createElement(View7, { style: styles7.section }, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "Severity"), /* @__PURE__ */ React8.createElement(View7, { style: styles7.severityRow }, [
14906
+ return /* @__PURE__ */ React9.createElement(View8, null, isRetestFailure ? /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(View8, { style: styles8.retestBanner }, /* @__PURE__ */ React9.createElement(Text8, { style: styles8.retestIcon }, "\u{1F504}"), /* @__PURE__ */ React9.createElement(View8, null, /* @__PURE__ */ React9.createElement(Text8, { style: styles8.retestTitle }, "Bug Still Present"), /* @__PURE__ */ React9.createElement(Text8, { style: styles8.retestSubtitle }, "The fix did not resolve this issue"))), /* @__PURE__ */ React9.createElement(View8, { style: styles8.section }, /* @__PURE__ */ React9.createElement(Text8, { style: shared.label }, "Severity"), /* @__PURE__ */ React9.createElement(View8, { style: styles8.severityRow }, [
14731
14907
  { sev: "critical", color: "#ef4444" },
14732
14908
  { sev: "high", color: "#f97316" },
14733
14909
  { sev: "medium", color: "#eab308" },
14734
14910
  { sev: "low", color: "#6b7280" }
14735
- ].map(({ sev, color }) => /* @__PURE__ */ React8.createElement(
14736
- TouchableOpacity7,
14911
+ ].map(({ sev, color }) => /* @__PURE__ */ React9.createElement(
14912
+ TouchableOpacity8,
14737
14913
  {
14738
14914
  key: sev,
14739
- style: [styles7.sevButton, severity === sev && { backgroundColor: `${color}30`, borderColor: color }],
14915
+ style: [styles8.sevButton, severity === sev && { backgroundColor: `${color}30`, borderColor: color }],
14740
14916
  onPress: () => setSeverity(sev)
14741
14917
  },
14742
- /* @__PURE__ */ React8.createElement(Text7, { style: [styles7.sevText, severity === sev && { color }] }, sev)
14743
- )))), /* @__PURE__ */ React8.createElement(View7, { style: styles7.section }, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "What went wrong?"), /* @__PURE__ */ React8.createElement(
14918
+ /* @__PURE__ */ React9.createElement(Text8, { style: [styles8.sevText, severity === sev && { color }] }, sev)
14919
+ )))), /* @__PURE__ */ React9.createElement(View8, { style: styles8.section }, /* @__PURE__ */ React9.createElement(Text8, { style: shared.label }, "Category (optional)"), /* @__PURE__ */ React9.createElement(CategoryPicker, { value: category, onChange: setCategory, optional: true })), /* @__PURE__ */ React9.createElement(View8, { style: styles8.section }, /* @__PURE__ */ React9.createElement(Text8, { style: shared.label }, "What went wrong?"), /* @__PURE__ */ React9.createElement(
14744
14920
  TextInput3,
14745
14921
  {
14746
- style: styles7.descInput,
14922
+ style: styles8.descInput,
14747
14923
  value: description,
14748
14924
  onChangeText: setDescription,
14749
14925
  placeholder: "Describe what you observed. What still doesn't work?",
@@ -14752,7 +14928,7 @@ function ReportScreen({ nav, prefill }) {
14752
14928
  numberOfLines: 4,
14753
14929
  textAlignVertical: "top"
14754
14930
  }
14755
- )), /* @__PURE__ */ React8.createElement(
14931
+ )), /* @__PURE__ */ React9.createElement(
14756
14932
  ImagePickerButtons,
14757
14933
  {
14758
14934
  images: images.images,
@@ -14762,44 +14938,44 @@ function ReportScreen({ nav, prefill }) {
14762
14938
  onRemove: images.removeImage,
14763
14939
  label: "Attachments (optional)"
14764
14940
  }
14765
- ), error && /* @__PURE__ */ React8.createElement(View7, { style: styles7.errorBanner }, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.errorText }, error)), /* @__PURE__ */ React8.createElement(
14766
- TouchableOpacity7,
14941
+ ), error && /* @__PURE__ */ React9.createElement(View8, { style: styles8.errorBanner }, /* @__PURE__ */ React9.createElement(Text8, { style: styles8.errorText }, error)), /* @__PURE__ */ React9.createElement(
14942
+ TouchableOpacity8,
14767
14943
  {
14768
- style: [shared.primaryButton, styles7.retestSubmitButton, (!description.trim() || submitting || images.isUploading) && shared.primaryButtonDisabled, { marginTop: 20 }],
14944
+ style: [shared.primaryButton, styles8.retestSubmitButton, (!description.trim() || submitting || images.isUploading) && shared.primaryButtonDisabled, { marginTop: 20 }],
14769
14945
  onPress: handleSubmit,
14770
14946
  disabled: !description.trim() || submitting || images.isUploading
14771
14947
  },
14772
- /* @__PURE__ */ React8.createElement(Text7, { style: shared.primaryButtonText }, images.isUploading ? "Uploading images..." : submitting ? "Submitting..." : error ? "Retry" : "Submit Failed Retest")
14773
- )) : /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "What are you reporting?"), /* @__PURE__ */ React8.createElement(View7, { style: styles7.typeRow }, [
14948
+ /* @__PURE__ */ React9.createElement(Text8, { style: shared.primaryButtonText }, images.isUploading ? "Uploading images..." : submitting ? "Submitting..." : error ? "Retry" : "Submit Failed Retest")
14949
+ )) : /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(Text8, { style: shared.label }, "What are you reporting?"), /* @__PURE__ */ React9.createElement(View8, { style: styles8.typeRow }, [
14774
14950
  { type: "bug", label: "Bug", icon: "\u{1F41B}" },
14775
14951
  { type: "feedback", label: "Feedback", icon: "\u{1F4A1}" },
14776
14952
  { type: "suggestion", label: "Idea", icon: "\u2728" }
14777
- ].map(({ type, label, icon }) => /* @__PURE__ */ React8.createElement(
14778
- TouchableOpacity7,
14953
+ ].map(({ type, label, icon }) => /* @__PURE__ */ React9.createElement(
14954
+ TouchableOpacity8,
14779
14955
  {
14780
14956
  key: type,
14781
- style: [styles7.typeCard, reportType === type && styles7.typeCardActive],
14957
+ style: [styles8.typeCard, reportType === type && styles8.typeCardActive],
14782
14958
  onPress: () => setReportType(type)
14783
14959
  },
14784
- /* @__PURE__ */ React8.createElement(Text7, { style: styles7.typeIcon }, icon),
14785
- /* @__PURE__ */ React8.createElement(Text7, { style: [styles7.typeLabel, reportType === type && styles7.typeLabelActive] }, label)
14786
- ))), isBugType && /* @__PURE__ */ React8.createElement(View7, { style: styles7.section }, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "Severity"), /* @__PURE__ */ React8.createElement(View7, { style: styles7.severityRow }, [
14960
+ /* @__PURE__ */ React9.createElement(Text8, { style: styles8.typeIcon }, icon),
14961
+ /* @__PURE__ */ React9.createElement(Text8, { style: [styles8.typeLabel, reportType === type && styles8.typeLabelActive] }, label)
14962
+ ))), isBugType && /* @__PURE__ */ React9.createElement(View8, { style: styles8.section }, /* @__PURE__ */ React9.createElement(Text8, { style: shared.label }, "Severity"), /* @__PURE__ */ React9.createElement(View8, { style: styles8.severityRow }, [
14787
14963
  { sev: "critical", color: "#ef4444" },
14788
14964
  { sev: "high", color: "#f97316" },
14789
14965
  { sev: "medium", color: "#eab308" },
14790
14966
  { sev: "low", color: "#6b7280" }
14791
- ].map(({ sev, color }) => /* @__PURE__ */ React8.createElement(
14792
- TouchableOpacity7,
14967
+ ].map(({ sev, color }) => /* @__PURE__ */ React9.createElement(
14968
+ TouchableOpacity8,
14793
14969
  {
14794
14970
  key: sev,
14795
- style: [styles7.sevButton, severity === sev && { backgroundColor: `${color}30`, borderColor: color }],
14971
+ style: [styles8.sevButton, severity === sev && { backgroundColor: `${color}30`, borderColor: color }],
14796
14972
  onPress: () => setSeverity(sev)
14797
14973
  },
14798
- /* @__PURE__ */ React8.createElement(Text7, { style: [styles7.sevText, severity === sev && { color }] }, sev)
14799
- )))), /* @__PURE__ */ React8.createElement(View7, { style: styles7.section }, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "What happened?"), /* @__PURE__ */ React8.createElement(
14974
+ /* @__PURE__ */ React9.createElement(Text8, { style: [styles8.sevText, severity === sev && { color }] }, sev)
14975
+ )))), isBugType && /* @__PURE__ */ React9.createElement(View8, { style: styles8.section }, /* @__PURE__ */ React9.createElement(Text8, { style: shared.label }, "Category (optional)"), /* @__PURE__ */ React9.createElement(CategoryPicker, { value: category, onChange: setCategory, optional: true })), /* @__PURE__ */ React9.createElement(View8, { style: styles8.section }, /* @__PURE__ */ React9.createElement(Text8, { style: shared.label }, "What happened?"), /* @__PURE__ */ React9.createElement(
14800
14976
  TextInput3,
14801
14977
  {
14802
- style: styles7.descInput,
14978
+ style: styles8.descInput,
14803
14979
  value: description,
14804
14980
  onChangeText: setDescription,
14805
14981
  placeholder: "Describe the issue...",
@@ -14808,16 +14984,16 @@ function ReportScreen({ nav, prefill }) {
14808
14984
  numberOfLines: 4,
14809
14985
  textAlignVertical: "top"
14810
14986
  }
14811
- )), isBugType && /* @__PURE__ */ React8.createElement(View7, { style: styles7.section }, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "Which screen?"), /* @__PURE__ */ React8.createElement(
14987
+ )), isBugType && /* @__PURE__ */ React9.createElement(View8, { style: styles8.section }, /* @__PURE__ */ React9.createElement(Text8, { style: shared.label }, "Which screen?"), /* @__PURE__ */ React9.createElement(
14812
14988
  TextInput3,
14813
14989
  {
14814
- style: styles7.screenInput,
14990
+ style: styles8.screenInput,
14815
14991
  value: affectedScreen,
14816
14992
  onChangeText: setAffectedScreen,
14817
14993
  placeholder: "e.g. Reservations, Settings...",
14818
14994
  placeholderTextColor: colors.textMuted
14819
14995
  }
14820
- ), /* @__PURE__ */ React8.createElement(Text7, { style: styles7.screenHint }, "Which screen or area was the bug on? (optional)")), /* @__PURE__ */ React8.createElement(
14996
+ ), /* @__PURE__ */ React9.createElement(Text8, { style: styles8.screenHint }, "Which screen or area was the bug on? (optional)")), /* @__PURE__ */ React9.createElement(
14821
14997
  ImagePickerButtons,
14822
14998
  {
14823
14999
  images: images.images,
@@ -14827,17 +15003,17 @@ function ReportScreen({ nav, prefill }) {
14827
15003
  onRemove: images.removeImage,
14828
15004
  label: "Screenshots (optional)"
14829
15005
  }
14830
- ), error && /* @__PURE__ */ React8.createElement(View7, { style: styles7.errorBanner }, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.errorText }, error)), /* @__PURE__ */ React8.createElement(
14831
- TouchableOpacity7,
15006
+ ), error && /* @__PURE__ */ React9.createElement(View8, { style: styles8.errorBanner }, /* @__PURE__ */ React9.createElement(Text8, { style: styles8.errorText }, error)), /* @__PURE__ */ React9.createElement(
15007
+ TouchableOpacity8,
14832
15008
  {
14833
15009
  style: [shared.primaryButton, (!description.trim() || submitting || images.isUploading) && shared.primaryButtonDisabled, { marginTop: 20 }],
14834
15010
  onPress: handleSubmit,
14835
15011
  disabled: !description.trim() || submitting || images.isUploading
14836
15012
  },
14837
- /* @__PURE__ */ React8.createElement(Text7, { style: shared.primaryButtonText }, images.isUploading ? "Uploading images..." : submitting ? "Submitting..." : error ? "Retry" : "Submit Report")
15013
+ /* @__PURE__ */ React9.createElement(Text8, { style: shared.primaryButtonText }, images.isUploading ? "Uploading images..." : submitting ? "Submitting..." : error ? "Retry" : "Submit Report")
14838
15014
  )));
14839
15015
  }
14840
- var styles7 = StyleSheet8.create({
15016
+ var styles8 = StyleSheet9.create({
14841
15017
  typeRow: { flexDirection: "row", gap: 10, marginBottom: 20 },
14842
15018
  typeCard: { flex: 1, alignItems: "center", paddingVertical: 16, borderRadius: 12, backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border },
14843
15019
  typeCardActive: { borderColor: colors.blue, backgroundColor: "#172554" },
@@ -14861,16 +15037,16 @@ var styles7 = StyleSheet8.create({
14861
15037
  });
14862
15038
 
14863
15039
  // src/widget/screens/ReportSuccessScreen.tsx
14864
- import React9, { useEffect as useEffect5 } from "react";
14865
- import { View as View8, Text as Text8, StyleSheet as StyleSheet9 } from "react-native";
15040
+ import React10, { useEffect as useEffect6 } from "react";
15041
+ import { View as View9, Text as Text9, StyleSheet as StyleSheet10 } from "react-native";
14866
15042
  function ReportSuccessScreen({ nav }) {
14867
- useEffect5(() => {
15043
+ useEffect6(() => {
14868
15044
  const timer = setTimeout(() => nav.reset(), 2e3);
14869
15045
  return () => clearTimeout(timer);
14870
15046
  }, [nav]);
14871
- return /* @__PURE__ */ React9.createElement(View8, { style: styles8.container }, /* @__PURE__ */ React9.createElement(Text8, { style: styles8.emoji }, "\u{1F389}"), /* @__PURE__ */ React9.createElement(Text8, { style: styles8.title }, "Report submitted!"), /* @__PURE__ */ React9.createElement(Text8, { style: styles8.subtitle }, "Thank you for your feedback"));
15047
+ return /* @__PURE__ */ React10.createElement(View9, { style: styles9.container }, /* @__PURE__ */ React10.createElement(Text9, { style: styles9.emoji }, "\u{1F389}"), /* @__PURE__ */ React10.createElement(Text9, { style: styles9.title }, "Report submitted!"), /* @__PURE__ */ React10.createElement(Text9, { style: styles9.subtitle }, "Thank you for your feedback"));
14872
15048
  }
14873
- var styles8 = StyleSheet9.create({
15049
+ var styles9 = StyleSheet10.create({
14874
15050
  container: { alignItems: "center", paddingVertical: 60 },
14875
15051
  emoji: { fontSize: 48, marginBottom: 16 },
14876
15052
  title: { fontSize: 22, fontWeight: "700", color: colors.textPrimary, marginBottom: 6 },
@@ -14878,29 +15054,29 @@ var styles8 = StyleSheet9.create({
14878
15054
  });
14879
15055
 
14880
15056
  // src/widget/screens/MessageListScreen.tsx
14881
- import React10 from "react";
14882
- import { View as View9, Text as Text9, TouchableOpacity as TouchableOpacity8, StyleSheet as StyleSheet10 } from "react-native";
15057
+ import React11 from "react";
15058
+ import { View as View10, Text as Text10, TouchableOpacity as TouchableOpacity9, StyleSheet as StyleSheet11 } from "react-native";
14883
15059
  function MessageListScreen({ nav }) {
14884
15060
  const { threads, unreadCount, refreshThreads } = useBugBear();
14885
- return /* @__PURE__ */ React10.createElement(View9, null, /* @__PURE__ */ React10.createElement(
14886
- TouchableOpacity8,
15061
+ return /* @__PURE__ */ React11.createElement(View10, null, /* @__PURE__ */ React11.createElement(
15062
+ TouchableOpacity9,
14887
15063
  {
14888
- style: styles9.newMsgButton,
15064
+ style: styles10.newMsgButton,
14889
15065
  onPress: () => nav.push({ name: "COMPOSE_MESSAGE" })
14890
15066
  },
14891
- /* @__PURE__ */ React10.createElement(Text9, { style: styles9.newMsgText }, "\u2709\uFE0F New Message")
14892
- ), threads.length === 0 ? /* @__PURE__ */ React10.createElement(View9, { style: shared.emptyState }, /* @__PURE__ */ React10.createElement(Text9, { style: shared.emptyEmoji }, "\u{1F4AC}"), /* @__PURE__ */ React10.createElement(Text9, { style: shared.emptyTitle }, "No messages yet"), /* @__PURE__ */ React10.createElement(Text9, { style: shared.emptySubtitle }, "Start a conversation or wait for messages from admins")) : /* @__PURE__ */ React10.createElement(View9, null, threads.map((thread) => /* @__PURE__ */ React10.createElement(
14893
- TouchableOpacity8,
15067
+ /* @__PURE__ */ React11.createElement(Text10, { style: styles10.newMsgText }, "\u2709\uFE0F New Message")
15068
+ ), threads.length === 0 ? /* @__PURE__ */ React11.createElement(View10, { style: shared.emptyState }, /* @__PURE__ */ React11.createElement(Text10, { style: shared.emptyEmoji }, "\u{1F4AC}"), /* @__PURE__ */ React11.createElement(Text10, { style: shared.emptyTitle }, "No messages yet"), /* @__PURE__ */ React11.createElement(Text10, { style: shared.emptySubtitle }, "Start a conversation or wait for messages from admins")) : /* @__PURE__ */ React11.createElement(View10, null, threads.map((thread) => /* @__PURE__ */ React11.createElement(
15069
+ TouchableOpacity9,
14894
15070
  {
14895
15071
  key: thread.id,
14896
- style: [styles9.threadItem, thread.unreadCount > 0 && styles9.threadItemUnread],
15072
+ style: [styles10.threadItem, thread.unreadCount > 0 && styles10.threadItemUnread],
14897
15073
  onPress: () => nav.push({ name: "THREAD_DETAIL", thread })
14898
15074
  },
14899
- /* @__PURE__ */ React10.createElement(View9, { style: styles9.threadLeft }, /* @__PURE__ */ React10.createElement(Text9, { style: styles9.threadIcon }, getThreadTypeIcon(thread.threadType)), /* @__PURE__ */ React10.createElement(View9, { style: styles9.threadInfo }, /* @__PURE__ */ React10.createElement(View9, { style: styles9.threadTitleRow }, thread.isPinned && /* @__PURE__ */ React10.createElement(Text9, { style: styles9.pinIcon }, "\u{1F4CC}"), /* @__PURE__ */ React10.createElement(Text9, { style: styles9.threadSubject, numberOfLines: 1 }, thread.subject || "No subject")), thread.lastMessage && /* @__PURE__ */ React10.createElement(Text9, { style: styles9.threadPreview, numberOfLines: 1 }, thread.lastMessage.senderName, ": ", thread.lastMessage.content))),
14900
- /* @__PURE__ */ React10.createElement(View9, { style: styles9.threadRight }, /* @__PURE__ */ React10.createElement(Text9, { style: styles9.threadTime }, formatRelativeTime(thread.lastMessageAt)), thread.unreadCount > 0 && /* @__PURE__ */ React10.createElement(View9, { style: styles9.unreadBadge }, /* @__PURE__ */ React10.createElement(Text9, { style: styles9.unreadText }, thread.unreadCount)), thread.priority !== "normal" && /* @__PURE__ */ React10.createElement(View9, { style: [styles9.priorityDot, { backgroundColor: getPriorityColor(thread.priority) }] }))
14901
- ))), /* @__PURE__ */ React10.createElement(View9, { style: styles9.footer }, /* @__PURE__ */ React10.createElement(Text9, { style: styles9.footerText }, threads.length, " thread", threads.length !== 1 ? "s" : "", " \xB7 ", unreadCount, " unread"), /* @__PURE__ */ React10.createElement(TouchableOpacity8, { onPress: refreshThreads }, /* @__PURE__ */ React10.createElement(Text9, { style: styles9.refreshText }, "\u21BB Refresh"))));
15075
+ /* @__PURE__ */ React11.createElement(View10, { style: styles10.threadLeft }, /* @__PURE__ */ React11.createElement(Text10, { style: styles10.threadIcon }, getThreadTypeIcon(thread.threadType)), /* @__PURE__ */ React11.createElement(View10, { style: styles10.threadInfo }, /* @__PURE__ */ React11.createElement(View10, { style: styles10.threadTitleRow }, thread.isPinned && /* @__PURE__ */ React11.createElement(Text10, { style: styles10.pinIcon }, "\u{1F4CC}"), /* @__PURE__ */ React11.createElement(Text10, { style: styles10.threadSubject, numberOfLines: 1 }, thread.subject || "No subject")), thread.lastMessage && /* @__PURE__ */ React11.createElement(Text10, { style: styles10.threadPreview, numberOfLines: 1 }, thread.lastMessage.senderName, ": ", thread.lastMessage.content))),
15076
+ /* @__PURE__ */ React11.createElement(View10, { style: styles10.threadRight }, /* @__PURE__ */ React11.createElement(Text10, { style: styles10.threadTime }, formatRelativeTime(thread.lastMessageAt)), thread.unreadCount > 0 && /* @__PURE__ */ React11.createElement(View10, { style: styles10.unreadBadge }, /* @__PURE__ */ React11.createElement(Text10, { style: styles10.unreadText }, thread.unreadCount)), thread.priority !== "normal" && /* @__PURE__ */ React11.createElement(View10, { style: [styles10.priorityDot, { backgroundColor: getPriorityColor(thread.priority) }] }))
15077
+ ))), /* @__PURE__ */ React11.createElement(View10, { style: styles10.footer }, /* @__PURE__ */ React11.createElement(Text10, { style: styles10.footerText }, threads.length, " thread", threads.length !== 1 ? "s" : "", " \xB7 ", unreadCount, " unread"), /* @__PURE__ */ React11.createElement(TouchableOpacity9, { onPress: refreshThreads }, /* @__PURE__ */ React11.createElement(Text10, { style: styles10.refreshText }, "\u21BB Refresh"))));
14902
15078
  }
14903
- var styles9 = StyleSheet10.create({
15079
+ var styles10 = StyleSheet11.create({
14904
15080
  newMsgButton: { backgroundColor: colors.blue, paddingVertical: 12, borderRadius: 12, alignItems: "center", marginBottom: 16 },
14905
15081
  newMsgText: { fontSize: 15, fontWeight: "600", color: "#fff" },
14906
15082
  threadItem: { flexDirection: "row", justifyContent: "space-between", paddingVertical: 12, paddingHorizontal: 12, borderRadius: 10, marginBottom: 4, backgroundColor: colors.card },
@@ -14923,17 +15099,17 @@ var styles9 = StyleSheet10.create({
14923
15099
  });
14924
15100
 
14925
15101
  // src/widget/screens/ThreadDetailScreen.tsx
14926
- import React11, { useState as useState7, useEffect as useEffect6 } from "react";
14927
- import { View as View10, Text as Text10, TouchableOpacity as TouchableOpacity9, TextInput as TextInput4, StyleSheet as StyleSheet11, Image as Image2 } from "react-native";
15102
+ import React12, { useState as useState8, useEffect as useEffect7 } from "react";
15103
+ import { View as View11, Text as Text11, TouchableOpacity as TouchableOpacity10, TextInput as TextInput4, StyleSheet as StyleSheet12, Image as Image2 } from "react-native";
14928
15104
  function ThreadDetailScreen({ thread, nav }) {
14929
15105
  const { getThreadMessages, sendMessage, markAsRead, uploadImage } = useBugBear();
14930
- const [messages, setMessages] = useState7([]);
14931
- const [loading, setLoading] = useState7(true);
14932
- const [replyText, setReplyText] = useState7("");
14933
- const [sending, setSending] = useState7(false);
14934
- const [sendError, setSendError] = useState7(false);
15106
+ const [messages, setMessages] = useState8([]);
15107
+ const [loading, setLoading] = useState8(true);
15108
+ const [replyText, setReplyText] = useState8("");
15109
+ const [sending, setSending] = useState8(false);
15110
+ const [sendError, setSendError] = useState8(false);
14935
15111
  const replyImages = useImageAttachments(uploadImage, 3, "discussion-attachments");
14936
- useEffect6(() => {
15112
+ useEffect7(() => {
14937
15113
  (async () => {
14938
15114
  setLoading(true);
14939
15115
  const msgs = await getThreadMessages(thread.id);
@@ -14965,20 +15141,20 @@ function ThreadDetailScreen({ thread, nav }) {
14965
15141
  }
14966
15142
  setSending(false);
14967
15143
  };
14968
- return /* @__PURE__ */ React11.createElement(View10, { style: styles10.container }, /* @__PURE__ */ React11.createElement(View10, { style: styles10.header }, /* @__PURE__ */ React11.createElement(Text10, { style: styles10.headerIcon }, getThreadTypeIcon(thread.threadType)), /* @__PURE__ */ React11.createElement(Text10, { style: styles10.headerSubject, numberOfLines: 2 }, thread.subject || "No subject")), loading ? /* @__PURE__ */ React11.createElement(View10, { style: styles10.loadingContainer }, /* @__PURE__ */ React11.createElement(Text10, { style: styles10.loadingText }, "Loading messages...")) : /* @__PURE__ */ React11.createElement(View10, { style: styles10.messagesContainer }, messages.map((msg) => /* @__PURE__ */ React11.createElement(
14969
- View10,
15144
+ return /* @__PURE__ */ React12.createElement(View11, { style: styles11.container }, /* @__PURE__ */ React12.createElement(View11, { style: styles11.header }, /* @__PURE__ */ React12.createElement(Text11, { style: styles11.headerIcon }, getThreadTypeIcon(thread.threadType)), /* @__PURE__ */ React12.createElement(Text11, { style: styles11.headerSubject, numberOfLines: 2 }, thread.subject || "No subject")), loading ? /* @__PURE__ */ React12.createElement(View11, { style: styles11.loadingContainer }, /* @__PURE__ */ React12.createElement(Text11, { style: styles11.loadingText }, "Loading messages...")) : /* @__PURE__ */ React12.createElement(View11, { style: styles11.messagesContainer }, messages.map((msg) => /* @__PURE__ */ React12.createElement(
15145
+ View11,
14970
15146
  {
14971
15147
  key: msg.id,
14972
- style: [styles10.bubble, msg.senderType === "tester" ? styles10.bubbleTester : styles10.bubbleAdmin]
15148
+ style: [styles11.bubble, msg.senderType === "tester" ? styles11.bubbleTester : styles11.bubbleAdmin]
14973
15149
  },
14974
- /* @__PURE__ */ React11.createElement(Text10, { style: [styles10.sender, msg.senderType === "tester" && styles10.senderTester] }, msg.senderType === "tester" ? "You" : msg.senderName),
14975
- /* @__PURE__ */ React11.createElement(Text10, { style: [styles10.content, msg.senderType === "tester" && styles10.contentTester] }, msg.content),
14976
- msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ React11.createElement(View10, { style: styles10.attachments }, msg.attachments.filter((a) => a.type === "image").map((att, idx) => /* @__PURE__ */ React11.createElement(Image2, { key: idx, source: { uri: att.url }, style: styles10.attachmentImage, resizeMode: "cover" }))),
14977
- /* @__PURE__ */ React11.createElement(Text10, { style: [styles10.time, msg.senderType === "tester" && styles10.timeTester] }, formatMessageTime(msg.createdAt))
14978
- ))), sendError && /* @__PURE__ */ React11.createElement(View10, { style: styles10.errorBar }, /* @__PURE__ */ React11.createElement(Text10, { style: styles10.errorText }, "Failed to send. Tap Send to retry.")), replyImages.images.length > 0 && /* @__PURE__ */ React11.createElement(View10, { style: styles10.replyPreview }, /* @__PURE__ */ React11.createElement(ImagePreviewStrip, { images: replyImages.images, onRemove: replyImages.removeImage })), /* @__PURE__ */ React11.createElement(View10, { style: styles10.composer }, IMAGE_PICKER_AVAILABLE && /* @__PURE__ */ React11.createElement(TouchableOpacity9, { style: styles10.attachBtn, onPress: replyImages.pickFromGallery, disabled: replyImages.images.length >= 3 }, /* @__PURE__ */ React11.createElement(Text10, { style: styles10.attachBtnText }, "\u{1F4CE}")), /* @__PURE__ */ React11.createElement(
15150
+ /* @__PURE__ */ React12.createElement(Text11, { style: [styles11.sender, msg.senderType === "tester" && styles11.senderTester] }, msg.senderType === "tester" ? "You" : msg.senderName),
15151
+ /* @__PURE__ */ React12.createElement(Text11, { style: [styles11.content, msg.senderType === "tester" && styles11.contentTester] }, msg.content),
15152
+ msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ React12.createElement(View11, { style: styles11.attachments }, msg.attachments.filter((a) => a.type === "image").map((att, idx) => /* @__PURE__ */ React12.createElement(Image2, { key: idx, source: { uri: att.url }, style: styles11.attachmentImage, resizeMode: "cover" }))),
15153
+ /* @__PURE__ */ React12.createElement(Text11, { style: [styles11.time, msg.senderType === "tester" && styles11.timeTester] }, formatMessageTime(msg.createdAt))
15154
+ ))), sendError && /* @__PURE__ */ React12.createElement(View11, { style: styles11.errorBar }, /* @__PURE__ */ React12.createElement(Text11, { style: styles11.errorText }, "Failed to send. Tap Send to retry.")), replyImages.images.length > 0 && /* @__PURE__ */ React12.createElement(View11, { style: styles11.replyPreview }, /* @__PURE__ */ React12.createElement(ImagePreviewStrip, { images: replyImages.images, onRemove: replyImages.removeImage })), /* @__PURE__ */ React12.createElement(View11, { style: styles11.composer }, IMAGE_PICKER_AVAILABLE && /* @__PURE__ */ React12.createElement(TouchableOpacity10, { style: styles11.attachBtn, onPress: replyImages.pickFromGallery, disabled: replyImages.images.length >= 3 }, /* @__PURE__ */ React12.createElement(Text11, { style: styles11.attachBtnText }, "\u{1F4CE}")), /* @__PURE__ */ React12.createElement(
14979
15155
  TextInput4,
14980
15156
  {
14981
- style: styles10.replyInput,
15157
+ style: styles11.replyInput,
14982
15158
  value: replyText,
14983
15159
  onChangeText: setReplyText,
14984
15160
  placeholder: "Type a reply...",
@@ -14986,17 +15162,17 @@ function ThreadDetailScreen({ thread, nav }) {
14986
15162
  multiline: true,
14987
15163
  maxLength: 1e3
14988
15164
  }
14989
- ), /* @__PURE__ */ React11.createElement(
14990
- TouchableOpacity9,
15165
+ ), /* @__PURE__ */ React12.createElement(
15166
+ TouchableOpacity10,
14991
15167
  {
14992
- style: [styles10.sendBtn, (!replyText.trim() || sending || replyImages.isUploading) && styles10.sendBtnDisabled],
15168
+ style: [styles11.sendBtn, (!replyText.trim() || sending || replyImages.isUploading) && styles11.sendBtnDisabled],
14993
15169
  onPress: handleSend,
14994
15170
  disabled: !replyText.trim() || sending || replyImages.isUploading
14995
15171
  },
14996
- /* @__PURE__ */ React11.createElement(Text10, { style: styles10.sendBtnText }, sending ? "..." : "Send")
15172
+ /* @__PURE__ */ React12.createElement(Text11, { style: styles11.sendBtnText }, sending ? "..." : "Send")
14997
15173
  )));
14998
15174
  }
14999
- var styles10 = StyleSheet11.create({
15175
+ var styles11 = StyleSheet12.create({
15000
15176
  container: { flex: 1 },
15001
15177
  header: { flexDirection: "row", alignItems: "center", gap: 8, marginBottom: 16, paddingBottom: 12, borderBottomWidth: 1, borderBottomColor: colors.border },
15002
15178
  headerIcon: { fontSize: 20 },
@@ -15028,13 +15204,13 @@ var styles10 = StyleSheet11.create({
15028
15204
  });
15029
15205
 
15030
15206
  // src/widget/screens/ComposeMessageScreen.tsx
15031
- import React12, { useState as useState8 } from "react";
15032
- import { View as View11, Text as Text11, TextInput as TextInput5, TouchableOpacity as TouchableOpacity10, StyleSheet as StyleSheet12 } from "react-native";
15207
+ import React13, { useState as useState9 } from "react";
15208
+ import { View as View12, Text as Text12, TextInput as TextInput5, TouchableOpacity as TouchableOpacity11, StyleSheet as StyleSheet13 } from "react-native";
15033
15209
  function ComposeMessageScreen({ nav }) {
15034
15210
  const { createThread, uploadImage } = useBugBear();
15035
- const [subject, setSubject] = useState8("");
15036
- const [message, setMessage] = useState8("");
15037
- const [sending, setSending] = useState8(false);
15211
+ const [subject, setSubject] = useState9("");
15212
+ const [message, setMessage] = useState9("");
15213
+ const [sending, setSending] = useState9(false);
15038
15214
  const images = useImageAttachments(uploadImage, 3, "discussion-attachments");
15039
15215
  const handleSend = async () => {
15040
15216
  if (!subject.trim() || !message.trim()) return;
@@ -15050,20 +15226,20 @@ function ComposeMessageScreen({ nav }) {
15050
15226
  nav.pop();
15051
15227
  }
15052
15228
  };
15053
- return /* @__PURE__ */ React12.createElement(View11, null, /* @__PURE__ */ React12.createElement(View11, { style: styles11.header }, /* @__PURE__ */ React12.createElement(Text11, { style: styles11.title }, "New Message"), /* @__PURE__ */ React12.createElement(Text11, { style: styles11.subtitle }, "Send a message to the QA team")), /* @__PURE__ */ React12.createElement(View11, { style: styles11.form }, /* @__PURE__ */ React12.createElement(Text11, { style: shared.label }, "Subject"), /* @__PURE__ */ React12.createElement(
15229
+ return /* @__PURE__ */ React13.createElement(View12, null, /* @__PURE__ */ React13.createElement(View12, { style: styles12.header }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.title }, "New Message"), /* @__PURE__ */ React13.createElement(Text12, { style: styles12.subtitle }, "Send a message to the QA team")), /* @__PURE__ */ React13.createElement(View12, { style: styles12.form }, /* @__PURE__ */ React13.createElement(Text12, { style: shared.label }, "Subject"), /* @__PURE__ */ React13.createElement(
15054
15230
  TextInput5,
15055
15231
  {
15056
- style: styles11.subjectInput,
15232
+ style: styles12.subjectInput,
15057
15233
  value: subject,
15058
15234
  onChangeText: setSubject,
15059
15235
  placeholder: "What's this about?",
15060
15236
  placeholderTextColor: colors.textMuted,
15061
15237
  maxLength: 100
15062
15238
  }
15063
- ), /* @__PURE__ */ React12.createElement(Text11, { style: [shared.label, { marginTop: 16 }] }, "Message"), /* @__PURE__ */ React12.createElement(
15239
+ ), /* @__PURE__ */ React13.createElement(Text12, { style: [shared.label, { marginTop: 16 }] }, "Message"), /* @__PURE__ */ React13.createElement(
15064
15240
  TextInput5,
15065
15241
  {
15066
- style: styles11.messageInput,
15242
+ style: styles12.messageInput,
15067
15243
  value: message,
15068
15244
  onChangeText: setMessage,
15069
15245
  placeholder: "Write your message...",
@@ -15073,7 +15249,7 @@ function ComposeMessageScreen({ nav }) {
15073
15249
  textAlignVertical: "top",
15074
15250
  maxLength: 2e3
15075
15251
  }
15076
- ), /* @__PURE__ */ React12.createElement(
15252
+ ), /* @__PURE__ */ React13.createElement(
15077
15253
  ImagePickerButtons,
15078
15254
  {
15079
15255
  images: images.images,
@@ -15082,17 +15258,17 @@ function ComposeMessageScreen({ nav }) {
15082
15258
  onPickCamera: images.pickFromCamera,
15083
15259
  onRemove: images.removeImage
15084
15260
  }
15085
- ), /* @__PURE__ */ React12.createElement(
15086
- TouchableOpacity10,
15261
+ ), /* @__PURE__ */ React13.createElement(
15262
+ TouchableOpacity11,
15087
15263
  {
15088
15264
  style: [shared.primaryButton, (!subject.trim() || !message.trim() || sending || images.isUploading) && shared.primaryButtonDisabled, { marginTop: 20 }],
15089
15265
  onPress: handleSend,
15090
15266
  disabled: !subject.trim() || !message.trim() || sending || images.isUploading
15091
15267
  },
15092
- /* @__PURE__ */ React12.createElement(Text11, { style: shared.primaryButtonText }, images.isUploading ? "Uploading..." : sending ? "Sending..." : "Send Message")
15268
+ /* @__PURE__ */ React13.createElement(Text12, { style: shared.primaryButtonText }, images.isUploading ? "Uploading..." : sending ? "Sending..." : "Send Message")
15093
15269
  )));
15094
15270
  }
15095
- var styles11 = StyleSheet12.create({
15271
+ var styles12 = StyleSheet13.create({
15096
15272
  header: { marginBottom: 20 },
15097
15273
  title: { fontSize: 20, fontWeight: "600", color: colors.textPrimary, marginBottom: 4 },
15098
15274
  subtitle: { fontSize: 14, color: colors.textMuted },
@@ -15102,20 +15278,20 @@ var styles11 = StyleSheet12.create({
15102
15278
  });
15103
15279
 
15104
15280
  // src/widget/screens/ProfileScreen.tsx
15105
- import React13, { useState as useState9, useEffect as useEffect7 } from "react";
15106
- import { View as View12, Text as Text12, TouchableOpacity as TouchableOpacity11, TextInput as TextInput6, StyleSheet as StyleSheet13 } from "react-native";
15281
+ import React14, { useState as useState10, useEffect as useEffect8 } from "react";
15282
+ import { View as View13, Text as Text13, TouchableOpacity as TouchableOpacity12, TextInput as TextInput6, StyleSheet as StyleSheet14 } from "react-native";
15107
15283
  function ProfileScreen({ nav }) {
15108
15284
  const { testerInfo, assignments, updateTesterProfile, refreshTesterInfo } = useBugBear();
15109
- const [editing, setEditing] = useState9(false);
15110
- const [name, setName] = useState9(testerInfo?.name || "");
15111
- const [additionalEmails, setAdditionalEmails] = useState9(testerInfo?.additionalEmails || []);
15112
- const [newEmailInput, setNewEmailInput] = useState9("");
15113
- const [platforms, setPlatforms] = useState9(testerInfo?.platforms || []);
15114
- const [saving, setSaving] = useState9(false);
15115
- const [saved, setSaved] = useState9(false);
15116
- const [showDetails, setShowDetails] = useState9(false);
15285
+ const [editing, setEditing] = useState10(false);
15286
+ const [name, setName] = useState10(testerInfo?.name || "");
15287
+ const [additionalEmails, setAdditionalEmails] = useState10(testerInfo?.additionalEmails || []);
15288
+ const [newEmailInput, setNewEmailInput] = useState10("");
15289
+ const [platforms, setPlatforms] = useState10(testerInfo?.platforms || []);
15290
+ const [saving, setSaving] = useState10(false);
15291
+ const [saved, setSaved] = useState10(false);
15292
+ const [showDetails, setShowDetails] = useState10(false);
15117
15293
  const completedCount = assignments.filter((a) => a.status === "passed" || a.status === "failed").length;
15118
- useEffect7(() => {
15294
+ useEffect8(() => {
15119
15295
  if (testerInfo) {
15120
15296
  setName(testerInfo.name);
15121
15297
  setAdditionalEmails(testerInfo.additionalEmails || []);
@@ -15149,19 +15325,19 @@ function ProfileScreen({ nav }) {
15149
15325
  }
15150
15326
  };
15151
15327
  if (saved) {
15152
- return /* @__PURE__ */ React13.createElement(View12, { style: shared.emptyState }, /* @__PURE__ */ React13.createElement(Text12, { style: shared.emptyEmoji }, "\u2705"), /* @__PURE__ */ React13.createElement(Text12, { style: shared.emptyTitle }, "Profile saved!"));
15328
+ return /* @__PURE__ */ React14.createElement(View13, { style: shared.emptyState }, /* @__PURE__ */ React14.createElement(Text13, { style: shared.emptyEmoji }, "\u2705"), /* @__PURE__ */ React14.createElement(Text13, { style: shared.emptyTitle }, "Profile saved!"));
15153
15329
  }
15154
15330
  if (!testerInfo) {
15155
- return /* @__PURE__ */ React13.createElement(View12, { style: shared.emptyState }, /* @__PURE__ */ React13.createElement(Text12, { style: shared.emptyEmoji }, "\u{1F464}"), /* @__PURE__ */ React13.createElement(Text12, { style: shared.emptyTitle }, "No profile found"));
15331
+ return /* @__PURE__ */ React14.createElement(View13, { style: shared.emptyState }, /* @__PURE__ */ React14.createElement(Text13, { style: shared.emptyEmoji }, "\u{1F464}"), /* @__PURE__ */ React14.createElement(Text13, { style: shared.emptyTitle }, "No profile found"));
15156
15332
  }
15157
15333
  if (editing) {
15158
- return /* @__PURE__ */ React13.createElement(View12, null, /* @__PURE__ */ React13.createElement(View12, { style: styles12.editHeader }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.editTitle }, "Edit Profile"), /* @__PURE__ */ React13.createElement(TouchableOpacity11, { onPress: () => {
15334
+ return /* @__PURE__ */ React14.createElement(View13, null, /* @__PURE__ */ React14.createElement(View13, { style: styles13.editHeader }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.editTitle }, "Edit Profile"), /* @__PURE__ */ React14.createElement(TouchableOpacity12, { onPress: () => {
15159
15335
  setEditing(false);
15160
15336
  setNewEmailInput("");
15161
- } }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.cancelText }, "Cancel"))), /* @__PURE__ */ React13.createElement(View12, { style: styles12.field }, /* @__PURE__ */ React13.createElement(Text12, { style: shared.label }, "Name"), /* @__PURE__ */ React13.createElement(TextInput6, { style: styles12.input, value: name, onChangeText: setName, placeholder: "Your name", placeholderTextColor: colors.textMuted })), /* @__PURE__ */ React13.createElement(View12, { style: styles12.field }, /* @__PURE__ */ React13.createElement(Text12, { style: shared.label }, "Primary Email"), /* @__PURE__ */ React13.createElement(Text12, { style: styles12.emailFixed }, testerInfo.email)), /* @__PURE__ */ React13.createElement(View12, { style: styles12.field }, /* @__PURE__ */ React13.createElement(Text12, { style: shared.label }, "Additional Emails"), additionalEmails.map((email) => /* @__PURE__ */ React13.createElement(View12, { key: email, style: styles12.emailRow }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.emailText }, email), /* @__PURE__ */ React13.createElement(TouchableOpacity11, { onPress: () => setAdditionalEmails(additionalEmails.filter((e) => e !== email)) }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.removeEmail }, "\u2715")))), /* @__PURE__ */ React13.createElement(View12, { style: styles12.addEmailRow }, /* @__PURE__ */ React13.createElement(
15337
+ } }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.cancelText }, "Cancel"))), /* @__PURE__ */ React14.createElement(View13, { style: styles13.field }, /* @__PURE__ */ React14.createElement(Text13, { style: shared.label }, "Name"), /* @__PURE__ */ React14.createElement(TextInput6, { style: styles13.input, value: name, onChangeText: setName, placeholder: "Your name", placeholderTextColor: colors.textMuted })), /* @__PURE__ */ React14.createElement(View13, { style: styles13.field }, /* @__PURE__ */ React14.createElement(Text13, { style: shared.label }, "Primary Email"), /* @__PURE__ */ React14.createElement(Text13, { style: styles13.emailFixed }, testerInfo.email)), /* @__PURE__ */ React14.createElement(View13, { style: styles13.field }, /* @__PURE__ */ React14.createElement(Text13, { style: shared.label }, "Additional Emails"), additionalEmails.map((email) => /* @__PURE__ */ React14.createElement(View13, { key: email, style: styles13.emailRow }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.emailText }, email), /* @__PURE__ */ React14.createElement(TouchableOpacity12, { onPress: () => setAdditionalEmails(additionalEmails.filter((e) => e !== email)) }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.removeEmail }, "\u2715")))), /* @__PURE__ */ React14.createElement(View13, { style: styles13.addEmailRow }, /* @__PURE__ */ React14.createElement(
15162
15338
  TextInput6,
15163
15339
  {
15164
- style: [styles12.input, { flex: 1, marginRight: 8 }],
15340
+ style: [styles13.input, { flex: 1, marginRight: 8 }],
15165
15341
  value: newEmailInput,
15166
15342
  onChangeText: setNewEmailInput,
15167
15343
  placeholder: "Add email",
@@ -15169,26 +15345,26 @@ function ProfileScreen({ nav }) {
15169
15345
  keyboardType: "email-address",
15170
15346
  autoCapitalize: "none"
15171
15347
  }
15172
- ), /* @__PURE__ */ React13.createElement(TouchableOpacity11, { style: styles12.addButton, onPress: handleAddEmail }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.addButtonText }, "Add")))), /* @__PURE__ */ React13.createElement(View12, { style: styles12.field }, /* @__PURE__ */ React13.createElement(Text12, { style: shared.label }, "Testing Platforms"), /* @__PURE__ */ React13.createElement(View12, { style: styles12.platformRow }, [{ key: "ios", label: "\u{1F4F1} iOS" }, { key: "android", label: "\u{1F916} Android" }, { key: "web", label: "\u{1F310} Web" }].map(({ key, label }) => /* @__PURE__ */ React13.createElement(
15173
- TouchableOpacity11,
15348
+ ), /* @__PURE__ */ React14.createElement(TouchableOpacity12, { style: styles13.addButton, onPress: handleAddEmail }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.addButtonText }, "Add")))), /* @__PURE__ */ React14.createElement(View13, { style: styles13.field }, /* @__PURE__ */ React14.createElement(Text13, { style: shared.label }, "Testing Platforms"), /* @__PURE__ */ React14.createElement(View13, { style: styles13.platformRow }, [{ key: "ios", label: "\u{1F4F1} iOS" }, { key: "android", label: "\u{1F916} Android" }, { key: "web", label: "\u{1F310} Web" }].map(({ key, label }) => /* @__PURE__ */ React14.createElement(
15349
+ TouchableOpacity12,
15174
15350
  {
15175
15351
  key,
15176
- style: [styles12.platformBtn, platforms.includes(key) && styles12.platformBtnActive],
15352
+ style: [styles13.platformBtn, platforms.includes(key) && styles13.platformBtnActive],
15177
15353
  onPress: () => setPlatforms((prev) => prev.includes(key) ? prev.filter((p) => p !== key) : [...prev, key])
15178
15354
  },
15179
- /* @__PURE__ */ React13.createElement(Text12, { style: [styles12.platformText, platforms.includes(key) && styles12.platformTextActive] }, label)
15180
- )))), /* @__PURE__ */ React13.createElement(TouchableOpacity11, { style: [shared.primaryButton, { marginTop: 20 }], onPress: handleSave, disabled: saving }, /* @__PURE__ */ React13.createElement(Text12, { style: shared.primaryButtonText }, saving ? "Saving..." : "Save Profile")));
15355
+ /* @__PURE__ */ React14.createElement(Text13, { style: [styles13.platformText, platforms.includes(key) && styles13.platformTextActive] }, label)
15356
+ )))), /* @__PURE__ */ React14.createElement(TouchableOpacity12, { style: [shared.primaryButton, { marginTop: 20 }], onPress: handleSave, disabled: saving }, /* @__PURE__ */ React14.createElement(Text13, { style: shared.primaryButtonText }, saving ? "Saving..." : "Save Profile")));
15181
15357
  }
15182
- return /* @__PURE__ */ React13.createElement(View12, null, /* @__PURE__ */ React13.createElement(View12, { style: styles12.profileCard }, /* @__PURE__ */ React13.createElement(View12, { style: styles12.avatar }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.avatarText }, testerInfo.name.charAt(0).toUpperCase())), /* @__PURE__ */ React13.createElement(Text12, { style: styles12.profileName }, testerInfo.name), /* @__PURE__ */ React13.createElement(Text12, { style: styles12.profileEmail }, testerInfo.email)), /* @__PURE__ */ React13.createElement(View12, { style: styles12.statsRow }, /* @__PURE__ */ React13.createElement(View12, { style: styles12.statItem }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.statNumber }, completedCount), /* @__PURE__ */ React13.createElement(Text12, { style: styles12.statLabel }, "Completed")), /* @__PURE__ */ React13.createElement(View12, { style: styles12.statDivider }), /* @__PURE__ */ React13.createElement(View12, { style: styles12.statItem }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.statNumber }, assignments.length), /* @__PURE__ */ React13.createElement(Text12, { style: styles12.statLabel }, "Total Assigned"))), /* @__PURE__ */ React13.createElement(TouchableOpacity11, { onPress: () => setShowDetails(!showDetails), style: styles12.detailsToggle }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.detailsToggleText }, showDetails ? "\u25BC" : "\u25B6", " Details")), showDetails && /* @__PURE__ */ React13.createElement(View12, { style: styles12.detailsSection }, additionalEmails.length > 0 && /* @__PURE__ */ React13.createElement(View12, { style: styles12.detailBlock }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.detailLabel }, "Additional Emails"), additionalEmails.map((e) => /* @__PURE__ */ React13.createElement(Text12, { key: e, style: styles12.detailValue }, e))), platforms.length > 0 && /* @__PURE__ */ React13.createElement(View12, { style: styles12.detailBlock }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.detailLabel }, "Platforms"), /* @__PURE__ */ React13.createElement(View12, { style: styles12.platformTags }, platforms.map((p) => /* @__PURE__ */ React13.createElement(View12, { key: p, style: styles12.platformTag }, /* @__PURE__ */ React13.createElement(Text12, { style: styles12.platformTagText }, p === "ios" ? "\u{1F4F1} iOS" : p === "android" ? "\u{1F916} Android" : "\u{1F310} Web")))))), /* @__PURE__ */ React13.createElement(
15183
- TouchableOpacity11,
15358
+ return /* @__PURE__ */ React14.createElement(View13, null, /* @__PURE__ */ React14.createElement(View13, { style: styles13.profileCard }, /* @__PURE__ */ React14.createElement(View13, { style: styles13.avatar }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.avatarText }, testerInfo.name.charAt(0).toUpperCase())), /* @__PURE__ */ React14.createElement(Text13, { style: styles13.profileName }, testerInfo.name), /* @__PURE__ */ React14.createElement(Text13, { style: styles13.profileEmail }, testerInfo.email)), /* @__PURE__ */ React14.createElement(View13, { style: styles13.statsRow }, /* @__PURE__ */ React14.createElement(View13, { style: styles13.statItem }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.statNumber }, completedCount), /* @__PURE__ */ React14.createElement(Text13, { style: styles13.statLabel }, "Completed")), /* @__PURE__ */ React14.createElement(View13, { style: styles13.statDivider }), /* @__PURE__ */ React14.createElement(View13, { style: styles13.statItem }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.statNumber }, assignments.length), /* @__PURE__ */ React14.createElement(Text13, { style: styles13.statLabel }, "Total Assigned"))), /* @__PURE__ */ React14.createElement(TouchableOpacity12, { onPress: () => setShowDetails(!showDetails), style: styles13.detailsToggle }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.detailsToggleText }, showDetails ? "\u25BC" : "\u25B6", " Details")), showDetails && /* @__PURE__ */ React14.createElement(View13, { style: styles13.detailsSection }, additionalEmails.length > 0 && /* @__PURE__ */ React14.createElement(View13, { style: styles13.detailBlock }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.detailLabel }, "Additional Emails"), additionalEmails.map((e) => /* @__PURE__ */ React14.createElement(Text13, { key: e, style: styles13.detailValue }, e))), platforms.length > 0 && /* @__PURE__ */ React14.createElement(View13, { style: styles13.detailBlock }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.detailLabel }, "Platforms"), /* @__PURE__ */ React14.createElement(View13, { style: styles13.platformTags }, platforms.map((p) => /* @__PURE__ */ React14.createElement(View13, { key: p, style: styles13.platformTag }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.platformTagText }, p === "ios" ? "\u{1F4F1} iOS" : p === "android" ? "\u{1F916} Android" : "\u{1F310} Web")))))), /* @__PURE__ */ React14.createElement(
15359
+ TouchableOpacity12,
15184
15360
  {
15185
15361
  style: [shared.primaryButton, { marginTop: 20 }],
15186
15362
  onPress: () => setEditing(true)
15187
15363
  },
15188
- /* @__PURE__ */ React13.createElement(Text12, { style: shared.primaryButtonText }, "Edit Profile")
15364
+ /* @__PURE__ */ React14.createElement(Text13, { style: shared.primaryButtonText }, "Edit Profile")
15189
15365
  ));
15190
15366
  }
15191
- var styles12 = StyleSheet13.create({
15367
+ var styles13 = StyleSheet14.create({
15192
15368
  profileCard: { alignItems: "center", backgroundColor: colors.card, borderRadius: 16, padding: 24, marginBottom: 16 },
15193
15369
  avatar: { width: 64, height: 64, borderRadius: 32, backgroundColor: colors.blue, justifyContent: "center", alignItems: "center", marginBottom: 12 },
15194
15370
  avatarText: { fontSize: 28, fontWeight: "700", color: "#fff" },
@@ -15229,8 +15405,8 @@ var styles12 = StyleSheet13.create({
15229
15405
  });
15230
15406
 
15231
15407
  // src/widget/screens/IssueListScreen.tsx
15232
- import React14, { useState as useState10, useEffect as useEffect8 } from "react";
15233
- import { View as View13, Text as Text13, TouchableOpacity as TouchableOpacity12, StyleSheet as StyleSheet14, ActivityIndicator as ActivityIndicator2 } from "react-native";
15408
+ import React15, { useState as useState11, useEffect as useEffect9 } from "react";
15409
+ import { View as View14, Text as Text14, TouchableOpacity as TouchableOpacity13, StyleSheet as StyleSheet15, ActivityIndicator as ActivityIndicator2 } from "react-native";
15234
15410
  var CATEGORY_CONFIG = {
15235
15411
  open: { label: "Open Issues", accent: "#f97316", emptyIcon: "\u2705", emptyText: "No open issues" },
15236
15412
  done: { label: "Done", accent: "#22c55e", emptyIcon: "\u{1F389}", emptyText: "No completed issues yet" },
@@ -15244,10 +15420,10 @@ var SEVERITY_COLORS = {
15244
15420
  };
15245
15421
  function IssueListScreen({ nav, category }) {
15246
15422
  const { client } = useBugBear();
15247
- const [issues, setIssues] = useState10([]);
15248
- const [loading, setLoading] = useState10(true);
15423
+ const [issues, setIssues] = useState11([]);
15424
+ const [loading, setLoading] = useState11(true);
15249
15425
  const config = CATEGORY_CONFIG[category];
15250
- useEffect8(() => {
15426
+ useEffect9(() => {
15251
15427
  let cancelled = false;
15252
15428
  setLoading(true);
15253
15429
  (async () => {
@@ -15263,26 +15439,26 @@ function IssueListScreen({ nav, category }) {
15263
15439
  };
15264
15440
  }, [client, category]);
15265
15441
  if (loading) {
15266
- return /* @__PURE__ */ React14.createElement(View13, { style: styles13.emptyContainer }, /* @__PURE__ */ React14.createElement(ActivityIndicator2, { size: "small", color: colors.textMuted }), /* @__PURE__ */ React14.createElement(Text13, { style: styles13.emptyText }, "Loading..."));
15442
+ return /* @__PURE__ */ React15.createElement(View14, { style: styles14.emptyContainer }, /* @__PURE__ */ React15.createElement(ActivityIndicator2, { size: "small", color: colors.textMuted }), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.emptyText }, "Loading..."));
15267
15443
  }
15268
15444
  if (issues.length === 0) {
15269
- return /* @__PURE__ */ React14.createElement(View13, { style: styles13.emptyContainer }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.emptyIcon }, config.emptyIcon), /* @__PURE__ */ React14.createElement(Text13, { style: styles13.emptyText }, config.emptyText));
15445
+ return /* @__PURE__ */ React15.createElement(View14, { style: styles14.emptyContainer }, /* @__PURE__ */ React15.createElement(Text14, { style: styles14.emptyIcon }, config.emptyIcon), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.emptyText }, config.emptyText));
15270
15446
  }
15271
- return /* @__PURE__ */ React14.createElement(View13, null, issues.map((issue) => /* @__PURE__ */ React14.createElement(
15272
- TouchableOpacity12,
15447
+ return /* @__PURE__ */ React15.createElement(View14, null, issues.map((issue) => /* @__PURE__ */ React15.createElement(
15448
+ TouchableOpacity13,
15273
15449
  {
15274
15450
  key: issue.id,
15275
- style: styles13.issueCard,
15451
+ style: styles14.issueCard,
15276
15452
  onPress: () => nav.push({ name: "ISSUE_DETAIL", issue }),
15277
15453
  activeOpacity: 0.7
15278
15454
  },
15279
- /* @__PURE__ */ React14.createElement(View13, { style: styles13.topRow }, issue.severity && /* @__PURE__ */ React14.createElement(View13, { style: [styles13.severityDot, { backgroundColor: SEVERITY_COLORS[issue.severity] || colors.textDim }] }), /* @__PURE__ */ React14.createElement(Text13, { style: styles13.issueTitle, numberOfLines: 1 }, issue.title)),
15280
- /* @__PURE__ */ React14.createElement(View13, { style: styles13.bottomRow }, issue.route && /* @__PURE__ */ React14.createElement(Text13, { style: styles13.routeText, numberOfLines: 1 }, issue.route), /* @__PURE__ */ React14.createElement(Text13, { style: styles13.timeText }, formatRelativeTime(issue.updatedAt))),
15281
- category === "done" && issue.verifiedByName && /* @__PURE__ */ React14.createElement(View13, { style: styles13.verifiedBadge }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.verifiedBadgeText }, "\u2714", " Verified by ", issue.verifiedByName)),
15282
- category === "reopened" && issue.originalBugTitle && /* @__PURE__ */ React14.createElement(View13, { style: styles13.reopenedBadge }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.reopenedBadgeText, numberOfLines: 1 }, "\u{1F504}", " Retest of: ", issue.originalBugTitle))
15455
+ /* @__PURE__ */ React15.createElement(View14, { style: styles14.topRow }, issue.severity && /* @__PURE__ */ React15.createElement(View14, { style: [styles14.severityDot, { backgroundColor: SEVERITY_COLORS[issue.severity] || colors.textDim }] }), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.issueTitle, numberOfLines: 1 }, issue.title)),
15456
+ /* @__PURE__ */ React15.createElement(View14, { style: styles14.bottomRow }, issue.route && /* @__PURE__ */ React15.createElement(Text14, { style: styles14.routeText, numberOfLines: 1 }, issue.route), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.timeText }, formatRelativeTime(issue.updatedAt))),
15457
+ category === "done" && issue.verifiedByName && /* @__PURE__ */ React15.createElement(View14, { style: styles14.verifiedBadge }, /* @__PURE__ */ React15.createElement(Text14, { style: styles14.verifiedBadgeText }, "\u2714", " Verified by ", issue.verifiedByName)),
15458
+ category === "reopened" && issue.originalBugTitle && /* @__PURE__ */ React15.createElement(View14, { style: styles14.reopenedBadge }, /* @__PURE__ */ React15.createElement(Text14, { style: styles14.reopenedBadgeText, numberOfLines: 1 }, "\u{1F504}", " Retest of: ", issue.originalBugTitle))
15283
15459
  )));
15284
15460
  }
15285
- var styles13 = StyleSheet14.create({
15461
+ var styles14 = StyleSheet15.create({
15286
15462
  emptyContainer: {
15287
15463
  alignItems: "center",
15288
15464
  paddingVertical: 40
@@ -15373,8 +15549,8 @@ var styles13 = StyleSheet14.create({
15373
15549
  });
15374
15550
 
15375
15551
  // src/widget/screens/IssueDetailScreen.tsx
15376
- import React15 from "react";
15377
- import { View as View14, Text as Text14, Image as Image3, StyleSheet as StyleSheet15, Linking as Linking2, TouchableOpacity as TouchableOpacity13 } from "react-native";
15552
+ import React16 from "react";
15553
+ import { View as View15, Text as Text15, Image as Image3, StyleSheet as StyleSheet16, Linking as Linking2, TouchableOpacity as TouchableOpacity14 } from "react-native";
15378
15554
  var STATUS_LABELS = {
15379
15555
  new: { label: "New", bg: "#1e3a5f", color: "#60a5fa" },
15380
15556
  triaging: { label: "Triaging", bg: "#1e3a5f", color: "#60a5fa" },
@@ -15398,9 +15574,9 @@ var SEVERITY_CONFIG = {
15398
15574
  function IssueDetailScreen({ nav, issue }) {
15399
15575
  const statusConfig = STATUS_LABELS[issue.status] || { label: issue.status, bg: "#27272a", color: "#a1a1aa" };
15400
15576
  const severityConfig = issue.severity ? SEVERITY_CONFIG[issue.severity] : null;
15401
- return /* @__PURE__ */ React15.createElement(View14, null, /* @__PURE__ */ React15.createElement(View14, { style: styles14.badgeRow }, /* @__PURE__ */ React15.createElement(View14, { style: [styles14.badge, { backgroundColor: statusConfig.bg }] }, /* @__PURE__ */ React15.createElement(Text14, { style: [styles14.badgeText, { color: statusConfig.color }] }, statusConfig.label)), severityConfig && /* @__PURE__ */ React15.createElement(View14, { style: [styles14.badge, { backgroundColor: severityConfig.bg }] }, /* @__PURE__ */ React15.createElement(Text14, { style: [styles14.badgeText, { color: severityConfig.color }] }, severityConfig.label))), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.title }, issue.title), issue.route && /* @__PURE__ */ React15.createElement(Text14, { style: styles14.route }, issue.route), issue.description && /* @__PURE__ */ React15.createElement(View14, { style: styles14.descriptionCard }, /* @__PURE__ */ React15.createElement(Text14, { style: styles14.descriptionText }, issue.description)), issue.verifiedByName && /* @__PURE__ */ React15.createElement(View14, { style: styles14.verifiedCard }, /* @__PURE__ */ React15.createElement(View14, { style: styles14.verifiedHeader }, /* @__PURE__ */ React15.createElement(Text14, { style: styles14.verifiedIcon }, "\u2705"), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.verifiedTitle }, "Retesting Proof")), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.verifiedBody }, "Verified by ", issue.verifiedByName, issue.verifiedAt && ` on ${new Date(issue.verifiedAt).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" })}`)), issue.originalBugTitle && /* @__PURE__ */ React15.createElement(View14, { style: styles14.originalBugCard }, /* @__PURE__ */ React15.createElement(View14, { style: styles14.originalBugHeader }, /* @__PURE__ */ React15.createElement(Text14, { style: styles14.originalBugIcon }, "\u{1F504}"), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.originalBugTitle }, "Original Bug")), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.originalBugBody }, "Retest of: ", issue.originalBugTitle)), issue.screenshotUrls && issue.screenshotUrls.length > 0 && /* @__PURE__ */ React15.createElement(View14, { style: styles14.screenshotSection }, /* @__PURE__ */ React15.createElement(Text14, { style: styles14.screenshotLabel }, "Screenshots (", issue.screenshotUrls.length, ")"), /* @__PURE__ */ React15.createElement(View14, { style: styles14.screenshotRow }, issue.screenshotUrls.map((url, i) => /* @__PURE__ */ React15.createElement(TouchableOpacity13, { key: i, onPress: () => Linking2.openURL(url), activeOpacity: 0.7 }, /* @__PURE__ */ React15.createElement(Image3, { source: { uri: url }, style: styles14.screenshotThumb }))))), /* @__PURE__ */ React15.createElement(View14, { style: styles14.metaSection }, issue.reporterName && /* @__PURE__ */ React15.createElement(Text14, { style: styles14.metaText }, "Reported by ", issue.reporterName), /* @__PURE__ */ React15.createElement(Text14, { style: styles14.metaTextSmall }, "Created ", formatRelativeTime(issue.createdAt), " ", "\xB7", " Updated ", formatRelativeTime(issue.updatedAt))));
15577
+ return /* @__PURE__ */ React16.createElement(View15, null, /* @__PURE__ */ React16.createElement(View15, { style: styles15.badgeRow }, /* @__PURE__ */ React16.createElement(View15, { style: [styles15.badge, { backgroundColor: statusConfig.bg }] }, /* @__PURE__ */ React16.createElement(Text15, { style: [styles15.badgeText, { color: statusConfig.color }] }, statusConfig.label)), severityConfig && /* @__PURE__ */ React16.createElement(View15, { style: [styles15.badge, { backgroundColor: severityConfig.bg }] }, /* @__PURE__ */ React16.createElement(Text15, { style: [styles15.badgeText, { color: severityConfig.color }] }, severityConfig.label))), /* @__PURE__ */ React16.createElement(Text15, { style: styles15.title }, issue.title), issue.route && /* @__PURE__ */ React16.createElement(Text15, { style: styles15.route }, issue.route), issue.description && /* @__PURE__ */ React16.createElement(View15, { style: styles15.descriptionCard }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.descriptionText }, issue.description)), issue.verifiedByName && /* @__PURE__ */ React16.createElement(View15, { style: styles15.verifiedCard }, /* @__PURE__ */ React16.createElement(View15, { style: styles15.verifiedHeader }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.verifiedIcon }, "\u2705"), /* @__PURE__ */ React16.createElement(Text15, { style: styles15.verifiedTitle }, "Retesting Proof")), /* @__PURE__ */ React16.createElement(Text15, { style: styles15.verifiedBody }, "Verified by ", issue.verifiedByName, issue.verifiedAt && ` on ${new Date(issue.verifiedAt).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" })}`)), issue.originalBugTitle && /* @__PURE__ */ React16.createElement(View15, { style: styles15.originalBugCard }, /* @__PURE__ */ React16.createElement(View15, { style: styles15.originalBugHeader }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.originalBugIcon }, "\u{1F504}"), /* @__PURE__ */ React16.createElement(Text15, { style: styles15.originalBugTitle }, "Original Bug")), /* @__PURE__ */ React16.createElement(Text15, { style: styles15.originalBugBody }, "Retest of: ", issue.originalBugTitle)), issue.screenshotUrls && issue.screenshotUrls.length > 0 && /* @__PURE__ */ React16.createElement(View15, { style: styles15.screenshotSection }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.screenshotLabel }, "Screenshots (", issue.screenshotUrls.length, ")"), /* @__PURE__ */ React16.createElement(View15, { style: styles15.screenshotRow }, issue.screenshotUrls.map((url, i) => /* @__PURE__ */ React16.createElement(TouchableOpacity14, { key: i, onPress: () => Linking2.openURL(url), activeOpacity: 0.7 }, /* @__PURE__ */ React16.createElement(Image3, { source: { uri: url }, style: styles15.screenshotThumb }))))), /* @__PURE__ */ React16.createElement(View15, { style: styles15.metaSection }, issue.reporterName && /* @__PURE__ */ React16.createElement(Text15, { style: styles15.metaText }, "Reported by ", issue.reporterName), /* @__PURE__ */ React16.createElement(Text15, { style: styles15.metaTextSmall }, "Created ", formatRelativeTime(issue.createdAt), " ", "\xB7", " Updated ", formatRelativeTime(issue.updatedAt))));
15402
15578
  }
15403
- var styles14 = StyleSheet15.create({
15579
+ var styles15 = StyleSheet16.create({
15404
15580
  badgeRow: {
15405
15581
  flexDirection: "row",
15406
15582
  gap: 8,
@@ -15544,7 +15720,7 @@ function BugBearButton({
15544
15720
  }) {
15545
15721
  const { shouldShowWidget, testerInfo, isLoading, unreadCount, assignments } = useBugBear();
15546
15722
  const { currentScreen, canGoBack, push, pop, replace, reset } = useNavigation();
15547
- const [modalVisible, setModalVisible] = useState11(false);
15723
+ const [modalVisible, setModalVisible] = useState12(false);
15548
15724
  const getInitialPosition = () => {
15549
15725
  const buttonSize = 56;
15550
15726
  const margin = 16;
@@ -15660,77 +15836,77 @@ function BugBearButton({
15660
15836
  const renderScreen = () => {
15661
15837
  switch (currentScreen.name) {
15662
15838
  case "HOME":
15663
- return /* @__PURE__ */ React16.createElement(HomeScreen, { nav });
15839
+ return /* @__PURE__ */ React17.createElement(HomeScreen, { nav });
15664
15840
  case "TEST_DETAIL":
15665
- return /* @__PURE__ */ React16.createElement(TestDetailScreen, { testId: currentScreen.testId, nav });
15841
+ return /* @__PURE__ */ React17.createElement(TestDetailScreen, { testId: currentScreen.testId, nav });
15666
15842
  case "TEST_LIST":
15667
- return /* @__PURE__ */ React16.createElement(TestListScreen, { nav });
15843
+ return /* @__PURE__ */ React17.createElement(TestListScreen, { nav });
15668
15844
  case "TEST_FEEDBACK":
15669
- return /* @__PURE__ */ React16.createElement(TestFeedbackScreen, { status: currentScreen.status, assignmentId: currentScreen.assignmentId, nav });
15845
+ return /* @__PURE__ */ React17.createElement(TestFeedbackScreen, { status: currentScreen.status, assignmentId: currentScreen.assignmentId, nav });
15670
15846
  case "REPORT":
15671
- return /* @__PURE__ */ React16.createElement(ReportScreen, { nav, prefill: currentScreen.prefill });
15847
+ return /* @__PURE__ */ React17.createElement(ReportScreen, { nav, prefill: currentScreen.prefill });
15672
15848
  case "REPORT_SUCCESS":
15673
- return /* @__PURE__ */ React16.createElement(ReportSuccessScreen, { nav });
15849
+ return /* @__PURE__ */ React17.createElement(ReportSuccessScreen, { nav });
15674
15850
  case "MESSAGE_LIST":
15675
- return /* @__PURE__ */ React16.createElement(MessageListScreen, { nav });
15851
+ return /* @__PURE__ */ React17.createElement(MessageListScreen, { nav });
15676
15852
  case "THREAD_DETAIL":
15677
- return /* @__PURE__ */ React16.createElement(ThreadDetailScreen, { thread: currentScreen.thread, nav });
15853
+ return /* @__PURE__ */ React17.createElement(ThreadDetailScreen, { thread: currentScreen.thread, nav });
15678
15854
  case "COMPOSE_MESSAGE":
15679
- return /* @__PURE__ */ React16.createElement(ComposeMessageScreen, { nav });
15855
+ return /* @__PURE__ */ React17.createElement(ComposeMessageScreen, { nav });
15680
15856
  case "ISSUE_LIST":
15681
- return /* @__PURE__ */ React16.createElement(IssueListScreen, { nav, category: currentScreen.category });
15857
+ return /* @__PURE__ */ React17.createElement(IssueListScreen, { nav, category: currentScreen.category });
15682
15858
  case "ISSUE_DETAIL":
15683
- return /* @__PURE__ */ React16.createElement(IssueDetailScreen, { nav, issue: currentScreen.issue });
15859
+ return /* @__PURE__ */ React17.createElement(IssueDetailScreen, { nav, issue: currentScreen.issue });
15684
15860
  case "PROFILE":
15685
- return /* @__PURE__ */ React16.createElement(ProfileScreen, { nav });
15861
+ return /* @__PURE__ */ React17.createElement(ProfileScreen, { nav });
15686
15862
  default:
15687
- return /* @__PURE__ */ React16.createElement(HomeScreen, { nav });
15863
+ return /* @__PURE__ */ React17.createElement(HomeScreen, { nav });
15688
15864
  }
15689
15865
  };
15690
- return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(
15866
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(
15691
15867
  Animated.View,
15692
15868
  {
15693
- style: [styles15.fabContainer, { transform: pan.getTranslateTransform() }, buttonStyle],
15869
+ style: [styles16.fabContainer, { transform: pan.getTranslateTransform() }, buttonStyle],
15694
15870
  ...panResponder.panHandlers
15695
15871
  },
15696
- /* @__PURE__ */ React16.createElement(
15697
- TouchableOpacity14,
15872
+ /* @__PURE__ */ React17.createElement(
15873
+ TouchableOpacity15,
15698
15874
  {
15699
- style: styles15.fab,
15875
+ style: styles16.fab,
15700
15876
  onPress: () => setModalVisible(true),
15701
15877
  activeOpacity: draggable ? 1 : 0.7
15702
15878
  },
15703
- /* @__PURE__ */ React16.createElement(Image4, { source: { uri: BUGBEAR_LOGO_BASE64 }, style: styles15.fabIcon }),
15704
- badgeCount > 0 && /* @__PURE__ */ React16.createElement(View15, { style: styles15.badge }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.badgeText }, badgeCount > 9 ? "9+" : badgeCount))
15879
+ /* @__PURE__ */ React17.createElement(Image4, { source: { uri: BUGBEAR_LOGO_BASE64 }, style: styles16.fabIcon }),
15880
+ badgeCount > 0 && /* @__PURE__ */ React17.createElement(View16, { style: styles16.badge }, /* @__PURE__ */ React17.createElement(Text16, { style: styles16.badgeText }, badgeCount > 9 ? "9+" : badgeCount))
15705
15881
  )
15706
- ), /* @__PURE__ */ React16.createElement(
15707
- Modal2,
15882
+ ), /* @__PURE__ */ React17.createElement(
15883
+ Modal3,
15708
15884
  {
15709
15885
  visible: modalVisible,
15710
15886
  animationType: "slide",
15711
15887
  transparent: true,
15712
15888
  onRequestClose: handleClose
15713
15889
  },
15714
- /* @__PURE__ */ React16.createElement(
15890
+ /* @__PURE__ */ React17.createElement(
15715
15891
  KeyboardAvoidingView,
15716
15892
  {
15717
15893
  behavior: Platform4.OS === "ios" ? "padding" : "height",
15718
- style: styles15.modalOverlay
15894
+ style: styles16.modalOverlay
15719
15895
  },
15720
- /* @__PURE__ */ React16.createElement(View15, { style: styles15.modalContainer }, /* @__PURE__ */ React16.createElement(View15, { style: styles15.header }, /* @__PURE__ */ React16.createElement(View15, { style: styles15.headerLeft }, canGoBack ? /* @__PURE__ */ React16.createElement(View15, { style: styles15.headerNavRow }, /* @__PURE__ */ React16.createElement(TouchableOpacity14, { onPress: () => nav.pop(), style: styles15.backButton }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.backText }, "\u2190 Back")), /* @__PURE__ */ React16.createElement(TouchableOpacity14, { onPress: () => nav.reset(), style: styles15.homeButton }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.homeText }, "\u{1F3E0}"))) : /* @__PURE__ */ React16.createElement(View15, { style: styles15.headerTitleRow }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.headerTitle }, "BugBear"), testerInfo && /* @__PURE__ */ React16.createElement(TouchableOpacity14, { onPress: () => push({ name: "PROFILE" }) }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.headerName }, testerInfo.name, " \u270E")))), getHeaderTitle() ? /* @__PURE__ */ React16.createElement(Text15, { style: styles15.headerScreenTitle, numberOfLines: 1 }, getHeaderTitle()) : null, /* @__PURE__ */ React16.createElement(TouchableOpacity14, { onPress: handleClose, style: styles15.closeButton }, /* @__PURE__ */ React16.createElement(Text15, { style: styles15.closeText }, "\u2715"))), /* @__PURE__ */ React16.createElement(
15896
+ /* @__PURE__ */ React17.createElement(View16, { style: styles16.modalContainer }, /* @__PURE__ */ React17.createElement(View16, { style: styles16.header }, /* @__PURE__ */ React17.createElement(View16, { style: styles16.headerLeft }, canGoBack ? /* @__PURE__ */ React17.createElement(View16, { style: styles16.headerNavRow }, /* @__PURE__ */ React17.createElement(TouchableOpacity15, { onPress: () => nav.pop(), style: styles16.backButton }, /* @__PURE__ */ React17.createElement(Text16, { style: styles16.backText }, "\u2190 Back")), /* @__PURE__ */ React17.createElement(TouchableOpacity15, { onPress: () => nav.reset(), style: styles16.homeButton }, /* @__PURE__ */ React17.createElement(Text16, { style: styles16.homeText }, "\u{1F3E0}"))) : /* @__PURE__ */ React17.createElement(View16, { style: styles16.headerTitleRow }, /* @__PURE__ */ React17.createElement(Text16, { style: styles16.headerTitle }, "BugBear"), testerInfo && /* @__PURE__ */ React17.createElement(TouchableOpacity15, { onPress: () => push({ name: "PROFILE" }) }, /* @__PURE__ */ React17.createElement(Text16, { style: styles16.headerName }, testerInfo.name, " \u270E")))), getHeaderTitle() ? /* @__PURE__ */ React17.createElement(Text16, { style: styles16.headerScreenTitle, numberOfLines: 1 }, getHeaderTitle()) : null, /* @__PURE__ */ React17.createElement(TouchableOpacity15, { onPress: handleClose, style: styles16.closeButton }, /* @__PURE__ */ React17.createElement(Text16, { style: styles16.closeText }, "\u2715"))), /* @__PURE__ */ React17.createElement(
15721
15897
  ScrollView3,
15722
15898
  {
15723
- style: styles15.content,
15724
- contentContainerStyle: styles15.contentContainer,
15899
+ style: styles16.content,
15900
+ contentContainerStyle: styles16.contentContainer,
15725
15901
  keyboardShouldPersistTaps: "handled",
15726
15902
  showsVerticalScrollIndicator: false
15727
15903
  },
15728
- isLoading ? /* @__PURE__ */ React16.createElement(View15, { style: styles15.loadingContainer }, /* @__PURE__ */ React16.createElement(ActivityIndicator3, { size: "large", color: colors.blue }), /* @__PURE__ */ React16.createElement(Text15, { style: styles15.loadingText }, "Loading...")) : renderScreen()
15904
+ isLoading ? /* @__PURE__ */ React17.createElement(View16, { style: styles16.loadingContainer }, /* @__PURE__ */ React17.createElement(ActivityIndicator3, { size: "large", color: colors.blue }), /* @__PURE__ */ React17.createElement(Text16, { style: styles16.loadingText }, "Loading...")) : renderScreen()
15729
15905
  ))
15730
15906
  )
15731
15907
  ));
15732
15908
  }
15733
- var styles15 = StyleSheet16.create({
15909
+ var styles16 = StyleSheet17.create({
15734
15910
  // FAB
15735
15911
  fabContainer: {
15736
15912
  position: "absolute",
@@ -15872,8 +16048,8 @@ var styles15 = StyleSheet16.create({
15872
16048
  });
15873
16049
 
15874
16050
  // src/BugBearErrorBoundary.tsx
15875
- import React17, { Component } from "react";
15876
- import { View as View16, Text as Text16, TouchableOpacity as TouchableOpacity15, StyleSheet as StyleSheet17 } from "react-native";
16051
+ import React18, { Component } from "react";
16052
+ import { View as View17, Text as Text17, TouchableOpacity as TouchableOpacity16, StyleSheet as StyleSheet18 } from "react-native";
15877
16053
  var BugBearErrorBoundary = class extends Component {
15878
16054
  constructor(props) {
15879
16055
  super(props);
@@ -15918,7 +16094,7 @@ var BugBearErrorBoundary = class extends Component {
15918
16094
  if (fallback) {
15919
16095
  return fallback;
15920
16096
  }
15921
- return /* @__PURE__ */ React17.createElement(View16, { style: styles16.container }, /* @__PURE__ */ React17.createElement(Text16, { style: styles16.title }, "Something went wrong"), /* @__PURE__ */ React17.createElement(Text16, { style: styles16.message }, error.message), /* @__PURE__ */ React17.createElement(TouchableOpacity15, { style: styles16.button, onPress: this.reset }, /* @__PURE__ */ React17.createElement(Text16, { style: styles16.buttonText }, "Try Again")), /* @__PURE__ */ React17.createElement(Text16, { style: styles16.caption }, "The error has been captured by BugBear"));
16097
+ return /* @__PURE__ */ React18.createElement(View17, { style: styles17.container }, /* @__PURE__ */ React18.createElement(Text17, { style: styles17.title }, "Something went wrong"), /* @__PURE__ */ React18.createElement(Text17, { style: styles17.message }, error.message), /* @__PURE__ */ React18.createElement(TouchableOpacity16, { style: styles17.button, onPress: this.reset }, /* @__PURE__ */ React18.createElement(Text17, { style: styles17.buttonText }, "Try Again")), /* @__PURE__ */ React18.createElement(Text17, { style: styles17.caption }, "The error has been captured by BugBear"));
15922
16098
  }
15923
16099
  return children;
15924
16100
  }
@@ -15929,7 +16105,7 @@ function useErrorContext() {
15929
16105
  getEnhancedContext: () => contextCapture.getEnhancedContext()
15930
16106
  };
15931
16107
  }
15932
- var styles16 = StyleSheet17.create({
16108
+ var styles17 = StyleSheet18.create({
15933
16109
  container: {
15934
16110
  padding: 20,
15935
16111
  margin: 20,