yaver-feedback-react-native 0.8.0 → 0.8.2

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.
@@ -14,9 +14,13 @@
14
14
  * in-memory session).
15
15
  */
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.QUICK_ICON_COLOR_PRESETS = void 0;
17
18
  exports.getQuickIconDisabled = getQuickIconDisabled;
18
19
  exports.setQuickIconDisabled = setQuickIconDisabled;
19
20
  exports.clearQuickIconDisabled = clearQuickIconDisabled;
21
+ exports.getQuickIconColorPreset = getQuickIconColorPreset;
22
+ exports.setQuickIconColorPreset = setQuickIconColorPreset;
23
+ exports.clearQuickIconColorPreset = clearQuickIconColorPreset;
20
24
  let AsyncStorage = null;
21
25
  try {
22
26
  AsyncStorage = require('@react-native-async-storage/async-storage').default;
@@ -25,6 +29,51 @@ catch {
25
29
  // not installed — degrade gracefully
26
30
  }
27
31
  const QUICK_ICON_DISABLED_KEY = 'yaver_feedback_quickicon_disabled';
32
+ const QUICK_ICON_COLOR_KEY = 'yaver_feedback_quickicon_color';
33
+ exports.QUICK_ICON_COLOR_PRESETS = {
34
+ orange: {
35
+ label: 'Orange',
36
+ backgroundColor: '#ff6b2c',
37
+ foregroundColor: '#111111',
38
+ borderColor: 'rgba(255,255,255,0.92)',
39
+ shadowColor: '#000000',
40
+ },
41
+ lime: {
42
+ label: 'Lime',
43
+ backgroundColor: '#a3e635',
44
+ foregroundColor: '#111111',
45
+ borderColor: 'rgba(255,255,255,0.85)',
46
+ shadowColor: '#365314',
47
+ },
48
+ cyan: {
49
+ label: 'Cyan',
50
+ backgroundColor: '#22d3ee',
51
+ foregroundColor: '#082f49',
52
+ borderColor: 'rgba(255,255,255,0.82)',
53
+ shadowColor: '#083344',
54
+ },
55
+ pink: {
56
+ label: 'Pink',
57
+ backgroundColor: '#fb7185',
58
+ foregroundColor: '#fff1f2',
59
+ borderColor: 'rgba(255,255,255,0.78)',
60
+ shadowColor: '#4c0519',
61
+ },
62
+ yellow: {
63
+ label: 'Yellow',
64
+ backgroundColor: '#facc15',
65
+ foregroundColor: '#1c1917',
66
+ borderColor: 'rgba(255,255,255,0.88)',
67
+ shadowColor: '#713f12',
68
+ },
69
+ slate: {
70
+ label: 'Slate',
71
+ backgroundColor: '#475569',
72
+ foregroundColor: '#f8fafc',
73
+ borderColor: 'rgba(255,255,255,0.68)',
74
+ shadowColor: '#020617',
75
+ },
76
+ };
28
77
  /** True if the user has long-pressed the icon and chosen "Hide". */
29
78
  async function getQuickIconDisabled() {
30
79
  if (!AsyncStorage)
@@ -55,3 +104,36 @@ async function setQuickIconDisabled(disabled) {
55
104
  async function clearQuickIconDisabled() {
56
105
  await setQuickIconDisabled(false);
57
106
  }
107
+ async function getQuickIconColorPreset() {
108
+ if (!AsyncStorage)
109
+ return null;
110
+ try {
111
+ const v = await AsyncStorage.getItem(QUICK_ICON_COLOR_KEY);
112
+ if (!v)
113
+ return null;
114
+ if (Object.prototype.hasOwnProperty.call(exports.QUICK_ICON_COLOR_PRESETS, v)) {
115
+ return v;
116
+ }
117
+ return null;
118
+ }
119
+ catch {
120
+ return null;
121
+ }
122
+ }
123
+ async function setQuickIconColorPreset(preset) {
124
+ if (!AsyncStorage)
125
+ return;
126
+ try {
127
+ if (!preset) {
128
+ await AsyncStorage.removeItem(QUICK_ICON_COLOR_KEY);
129
+ return;
130
+ }
131
+ await AsyncStorage.setItem(QUICK_ICON_COLOR_KEY, preset);
132
+ }
133
+ catch {
134
+ // best-effort
135
+ }
136
+ }
137
+ async function clearQuickIconColorPreset() {
138
+ await setQuickIconColorPreset(null);
139
+ }
package/dist/types.d.ts CHANGED
@@ -48,7 +48,7 @@ export interface FeedbackConfig {
48
48
  * Single tap → open the feedback modal; long-press → menu with
49
49
  * "Hide icon" (persisted across launches via AsyncStorage).
50
50
  *
51
- * - `'auto'` (default) → `'always'` on iOS/Android, `'off'` on web.
51
+ * - `'auto'` (default) → `'after-shake'` on iOS/Android, `'off'` on web.
52
52
  * - `'always'` → visible from app launch.
53
53
  * - `'after-shake'` → hidden until the first shake this session.
54
54
  * - `'off'` → never rendered. Shake still works.
@@ -59,11 +59,34 @@ export interface FeedbackConfig {
59
59
  */
60
60
  quickIcon?: 'auto' | 'always' | 'after-shake' | 'off';
61
61
  /**
62
- * Background color for the quick-action icon. Default: '#6366f1'
63
- * (indigo). Pick something distinctive so the icon never visually
64
- * collides with your own FAB.
62
+ * Deprecated alias for `quickIconBackgroundColor`.
63
+ *
64
+ * Background color for the quick-action icon. The SDK now defaults
65
+ * to a high-visibility safety orange so the icon reads as a utility
66
+ * affordance instead of blending into the common blue/indigo FAB
67
+ * palette many mobile apps already use.
65
68
  */
66
69
  quickIconColor?: string;
70
+ /**
71
+ * Background color for the quick-action icon.
72
+ * Default: '#ff6b2c' (safety orange).
73
+ */
74
+ quickIconBackgroundColor?: string;
75
+ /**
76
+ * Foreground/text color for the quick-action icon label.
77
+ * Default: '#111111'.
78
+ */
79
+ quickIconForegroundColor?: string;
80
+ /**
81
+ * Border color for the quick-action icon.
82
+ * Default: 'rgba(255,255,255,0.92)'.
83
+ */
84
+ quickIconBorderColor?: string;
85
+ /**
86
+ * Shadow color for the quick-action icon.
87
+ * Default: '#000000'.
88
+ */
89
+ quickIconShadowColor?: string;
67
90
  /**
68
91
  * Initial position of the quick-action icon, in pixels from the
69
92
  * top-left. Default: near the top-right corner of the screen. The
@@ -191,6 +214,8 @@ export interface FeedbackBundle {
191
214
  metadata: FeedbackMetadata;
192
215
  /** Screen-recording file path, when produced by the "Start Recording" action. */
193
216
  video?: string;
217
+ /** Optional audio attachment path. */
218
+ audio?: string;
194
219
  screenshots: string[];
195
220
  /** Captured errors with stack traces, attached via attachError / wrapErrorHandler. */
196
221
  errors?: CapturedError[];
package/dist/upload.d.ts CHANGED
@@ -6,6 +6,7 @@ import { FeedbackBundle } from './types';
6
6
  * - `metadata` (JSON string)
7
7
  * - `screenshot_0`, `screenshot_1`, ... (image files)
8
8
  * - `video` (video file, if present)
9
+ * - `audio` (audio file, if present)
9
10
  *
10
11
  * Returns the parsed agent response — typically `{ ok, id, reportId }`.
11
12
  * Callers can inspect `.id` / `.reportId` to drive a follow-up
package/dist/upload.js CHANGED
@@ -9,6 +9,7 @@ const react_native_1 = require("react-native");
9
9
  * - `metadata` (JSON string)
10
10
  * - `screenshot_0`, `screenshot_1`, ... (image files)
11
11
  * - `video` (video file, if present)
12
+ * - `audio` (audio file, if present)
12
13
  *
13
14
  * Returns the parsed agent response — typically `{ ok, id, reportId }`.
14
15
  * Callers can inspect `.id` / `.reportId` to drive a follow-up
@@ -35,6 +36,13 @@ async function uploadFeedback(agentUrl, authToken, bundle) {
35
36
  name: 'screen_recording.mp4',
36
37
  });
37
38
  }
39
+ if (bundle.audio) {
40
+ formData.append('audio', {
41
+ uri: react_native_1.Platform.OS === 'android' ? `file://${bundle.audio}` : bundle.audio,
42
+ type: 'audio/m4a',
43
+ name: 'voice_note.m4a',
44
+ });
45
+ }
38
46
  const url = agentUrl.replace(/\/$/, '') + '/feedback';
39
47
  const response = await fetch(url, {
40
48
  method: 'POST',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yaver-feedback-react-native",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Visual feedback SDK for Yaver — bug reports, screen recording, voice annotations, and local-first developer workflows",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,7 +22,8 @@
22
22
  "react-native": ">=0.70.0",
23
23
  "@react-native-async-storage/async-storage": ">=1.17.0",
24
24
  "expo-web-browser": ">=12.0.0",
25
- "expo-apple-authentication": ">=6.0.0"
25
+ "expo-apple-authentication": ">=6.0.0",
26
+ "expo-document-picker": ">=13.0.0"
26
27
  },
27
28
  "peerDependenciesMeta": {
28
29
  "@expo/config-plugins": {
@@ -33,18 +34,23 @@
33
34
  },
34
35
  "expo-apple-authentication": {
35
36
  "optional": true
37
+ },
38
+ "expo-document-picker": {
39
+ "optional": true
36
40
  }
37
41
  },
38
42
  "devDependencies": {
39
- "jest": "^29.0.0",
40
43
  "@types/jest": "^29.0.0",
44
+ "@types/react": "^19.2.2",
45
+ "jest": "^29.0.0",
41
46
  "ts-jest": "^29.1.0",
42
47
  "typescript": "^5.0.0"
43
48
  },
44
49
  "scripts": {
45
- "build": "rm -rf dist && (tsc || true) && test -f dist/index.js",
50
+ "build": "rm -rf dist && (tsc -p tsconfig.json || true) && test -f dist/index.js",
46
51
  "prepublishOnly": "npm run build",
47
- "test": "jest"
52
+ "test": "jest --runInBand",
53
+ "test:ci": "npm run build && npm test"
48
54
  },
49
55
  "jest": {
50
56
  "preset": "ts-jest",
@@ -87,6 +87,7 @@ export const AuthOverlay: React.FC = () => {
87
87
  {token && (
88
88
  <YaverMachinePickerScreen
89
89
  token={token}
90
+ currentDeviceId={YaverFeedback.getConfig()?.preferredDeviceId}
90
91
  onPick={handleDevicePicked}
91
92
  onCancel={() => setPickerVisible(false)}
92
93
  />