yaver-feedback-react-native 0.8.1 → 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.
- package/README.md +2 -2
- package/dist/AuthOverlay.js +1 -1
- package/dist/FeedbackModal.js +416 -214
- package/dist/P2PClient.d.ts +9 -3
- package/dist/P2PClient.js +23 -2
- package/dist/QuickActionIcon.js +16 -4
- package/dist/YaverFeedback.d.ts +5 -0
- package/dist/YaverFeedback.js +22 -0
- package/dist/__tests__/P2PClient.test.js +30 -0
- package/dist/__tests__/YaverFeedback.test.js +39 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +3 -4
- package/dist/preferences.d.ts +11 -0
- package/dist/preferences.js +82 -0
- package/package.json +6 -4
- package/src/AuthOverlay.tsx +1 -0
- package/src/FeedbackModal.tsx +485 -257
- package/src/P2PClient.ts +36 -3
- package/src/QuickActionIcon.tsx +25 -5
- package/src/YaverFeedback.ts +29 -0
- package/src/__tests__/P2PClient.test.ts +40 -0
- package/src/__tests__/YaverFeedback.test.ts +42 -0
- package/src/index.ts +3 -4
- package/src/preferences.ts +96 -0
package/dist/P2PClient.d.ts
CHANGED
|
@@ -4,6 +4,14 @@ export interface FeedbackEvent {
|
|
|
4
4
|
timestamp: string;
|
|
5
5
|
data: any;
|
|
6
6
|
}
|
|
7
|
+
export interface ReloadAck {
|
|
8
|
+
ok: boolean;
|
|
9
|
+
mode: 'dev' | 'bundle';
|
|
10
|
+
acknowledged: boolean;
|
|
11
|
+
message: string;
|
|
12
|
+
nativeChangesDetected?: boolean;
|
|
13
|
+
changeClass?: string;
|
|
14
|
+
}
|
|
7
15
|
/**
|
|
8
16
|
* Lightweight P2P HTTP client for communicating with a Yaver agent.
|
|
9
17
|
*
|
|
@@ -69,9 +77,7 @@ export declare class P2PClient {
|
|
|
69
77
|
projectName?: string;
|
|
70
78
|
bundleId?: string;
|
|
71
79
|
projectPath?: string;
|
|
72
|
-
}): Promise<
|
|
73
|
-
ok: boolean;
|
|
74
|
-
}>;
|
|
80
|
+
}): Promise<ReloadAck>;
|
|
75
81
|
/**
|
|
76
82
|
* Open a vibing session on the connected agent. Vibing is the Yaver
|
|
77
83
|
* interactive coding-agent flow — `/vibing/execute` creates a task with
|
package/dist/P2PClient.js
CHANGED
|
@@ -291,7 +291,18 @@ class P2PClient {
|
|
|
291
291
|
headers: { Authorization: `Bearer ${this.authToken}` },
|
|
292
292
|
});
|
|
293
293
|
if (primary.ok) {
|
|
294
|
-
|
|
294
|
+
const payload = await primary.json().catch(() => ({}));
|
|
295
|
+
const nativeChangesDetected = payload.nativeChangesDetected === true;
|
|
296
|
+
return {
|
|
297
|
+
ok: true,
|
|
298
|
+
mode: 'dev',
|
|
299
|
+
acknowledged: true,
|
|
300
|
+
nativeChangesDetected,
|
|
301
|
+
changeClass: typeof payload.changeClass === 'string' ? payload.changeClass : undefined,
|
|
302
|
+
message: nativeChangesDetected
|
|
303
|
+
? 'Reload accepted, but native changes need a rebuild.'
|
|
304
|
+
: 'Hot reload request accepted.',
|
|
305
|
+
};
|
|
295
306
|
}
|
|
296
307
|
// Dev mode failed — fall through to bundle rebuild below rather
|
|
297
308
|
// than surfacing the raw error, so the user never has to know
|
|
@@ -321,7 +332,17 @@ class P2PClient {
|
|
|
321
332
|
const text = await res.text().catch(() => '');
|
|
322
333
|
throw new Error(friendlyReloadError(res.status, text));
|
|
323
334
|
}
|
|
324
|
-
|
|
335
|
+
const payload = await res.json().catch(() => ({}));
|
|
336
|
+
return {
|
|
337
|
+
ok: true,
|
|
338
|
+
mode: 'bundle',
|
|
339
|
+
acknowledged: true,
|
|
340
|
+
changeClass: typeof payload.changeClass === 'string' ? payload.changeClass : undefined,
|
|
341
|
+
nativeChangesDetected: payload.nativeChangesDetected === true,
|
|
342
|
+
message: typeof payload.message === 'string' && payload.message.trim()
|
|
343
|
+
? payload.message
|
|
344
|
+
: 'Reload request acknowledged. Agent is rebuilding the bundle.',
|
|
345
|
+
};
|
|
325
346
|
}
|
|
326
347
|
/**
|
|
327
348
|
* Open a vibing session on the connected agent. Vibing is the Yaver
|
package/dist/QuickActionIcon.js
CHANGED
|
@@ -111,6 +111,7 @@ const QuickActionIcon = ({ color: colorProp, backgroundColor: backgroundColorPro
|
|
|
111
111
|
const dragStart = (0, react_1.useRef)(null);
|
|
112
112
|
const didDrag = (0, react_1.useRef)(false);
|
|
113
113
|
const [userDisabled, setUserDisabled] = (0, react_1.useState)(null);
|
|
114
|
+
const [colorPreset, setColorPreset] = (0, react_1.useState)(null);
|
|
114
115
|
const [shakenThisSession, setShakenThisSession] = (0, react_1.useState)(false);
|
|
115
116
|
const [menuOpen, setMenuOpen] = (0, react_1.useState)(false);
|
|
116
117
|
const [hostSuppressed] = (0, react_1.useState)(() => isRunningInsideYaverHost());
|
|
@@ -123,6 +124,10 @@ const QuickActionIcon = ({ color: colorProp, backgroundColor: backgroundColorPro
|
|
|
123
124
|
if (alive)
|
|
124
125
|
setUserDisabled(v);
|
|
125
126
|
});
|
|
127
|
+
(0, preferences_1.getQuickIconColorPreset)().then((v) => {
|
|
128
|
+
if (alive)
|
|
129
|
+
setColorPreset(v);
|
|
130
|
+
});
|
|
126
131
|
return () => {
|
|
127
132
|
alive = false;
|
|
128
133
|
};
|
|
@@ -146,9 +151,15 @@ const QuickActionIcon = ({ color: colorProp, backgroundColor: backgroundColorPro
|
|
|
146
151
|
void (0, preferences_1.setQuickIconDisabled)(true);
|
|
147
152
|
setMenuOpen(false);
|
|
148
153
|
});
|
|
154
|
+
const colorSub = react_native_1.DeviceEventEmitter.addListener('yaverFeedback:quickIconColorChange', (next) => {
|
|
155
|
+
const preset = next?.preset ?? null;
|
|
156
|
+
setColorPreset(preset);
|
|
157
|
+
void (0, preferences_1.setQuickIconColorPreset)(preset);
|
|
158
|
+
});
|
|
149
159
|
return () => {
|
|
150
160
|
showSub.remove();
|
|
151
161
|
hideSub.remove();
|
|
162
|
+
colorSub.remove();
|
|
152
163
|
};
|
|
153
164
|
}, []);
|
|
154
165
|
const panResponder = (0, react_1.useRef)(react_native_1.PanResponder.create({
|
|
@@ -204,6 +215,7 @@ const QuickActionIcon = ({ color: colorProp, backgroundColor: backgroundColorPro
|
|
|
204
215
|
return null;
|
|
205
216
|
if (!YaverFeedback_1.YaverFeedback.isEnabled())
|
|
206
217
|
return null;
|
|
218
|
+
const presetColors = colorPreset ? preferences_1.QUICK_ICON_COLOR_PRESETS[colorPreset] : null;
|
|
207
219
|
const visualSize = size;
|
|
208
220
|
const radius = visualSize / 2;
|
|
209
221
|
return (<react_native_1.Animated.View pointerEvents="box-none" style={[
|
|
@@ -232,16 +244,16 @@ const QuickActionIcon = ({ color: colorProp, backgroundColor: backgroundColorPro
|
|
|
232
244
|
width: visualSize,
|
|
233
245
|
height: visualSize,
|
|
234
246
|
borderRadius: radius,
|
|
235
|
-
backgroundColor,
|
|
236
|
-
borderColor,
|
|
237
|
-
shadowColor,
|
|
247
|
+
backgroundColor: presetColors?.backgroundColor ?? backgroundColor,
|
|
248
|
+
borderColor: presetColors?.borderColor ?? borderColor,
|
|
249
|
+
shadowColor: presetColors?.shadowColor ?? shadowColor,
|
|
238
250
|
opacity: pressed ? 0.85 : 1,
|
|
239
251
|
},
|
|
240
252
|
]}>
|
|
241
253
|
<react_native_1.Text style={[
|
|
242
254
|
styles.iconLabel,
|
|
243
255
|
{
|
|
244
|
-
color: foregroundColor,
|
|
256
|
+
color: presetColors?.foregroundColor ?? foregroundColor,
|
|
245
257
|
fontSize: Math.round(visualSize * 0.5),
|
|
246
258
|
},
|
|
247
259
|
]}>
|
package/dist/YaverFeedback.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FeedbackConfig, CapturedError } from './types';
|
|
2
2
|
import { P2PClient } from './P2PClient';
|
|
3
|
+
import { QuickIconColorPreset } from './preferences';
|
|
3
4
|
/**
|
|
4
5
|
* Main entry point for the Yaver Feedback SDK.
|
|
5
6
|
* Call `YaverFeedback.init()` once at app startup.
|
|
@@ -60,6 +61,8 @@ export declare class YaverFeedback {
|
|
|
60
61
|
* newly-selected machine.
|
|
61
62
|
*/
|
|
62
63
|
static setPreferredDevice(deviceId: string): Promise<void>;
|
|
64
|
+
/** Resolve the currently selected remote machine from the authenticated device list. */
|
|
65
|
+
static getSelectedRemoteDevice(): Promise<import("./auth").RemoteDevice | null>;
|
|
63
66
|
/**
|
|
64
67
|
* Sign out: clear cached token + device, tear down the P2P client. The
|
|
65
68
|
* SDK stays enabled; the next feedback trigger will re-prompt for login.
|
|
@@ -223,6 +226,8 @@ export declare class YaverFeedback {
|
|
|
223
226
|
* about the programmatic API.
|
|
224
227
|
*/
|
|
225
228
|
static isQuickIconHidden(): Promise<boolean>;
|
|
229
|
+
static setQuickIconColorPreset(preset: QuickIconColorPreset | null): Promise<void>;
|
|
230
|
+
static getQuickIconColorPreset(): Promise<QuickIconColorPreset | null>;
|
|
226
231
|
/** Clear the persisted "user hid the icon" flag. */
|
|
227
232
|
static resetQuickIconPreference(): Promise<void>;
|
|
228
233
|
/** Tear down the SDK (stop shake detector, clear state). */
|
package/dist/YaverFeedback.js
CHANGED
|
@@ -346,6 +346,15 @@ class YaverFeedback {
|
|
|
346
346
|
p2pClient = null;
|
|
347
347
|
await YaverFeedback.discoverAgent();
|
|
348
348
|
}
|
|
349
|
+
/** Resolve the currently selected remote machine from the authenticated device list. */
|
|
350
|
+
static async getSelectedRemoteDevice() {
|
|
351
|
+
if (!config?.authToken || !config.preferredDeviceId)
|
|
352
|
+
return null;
|
|
353
|
+
const preferredDeviceId = config.preferredDeviceId;
|
|
354
|
+
const devices = await (0, auth_1.listReachableDevices)(config.authToken);
|
|
355
|
+
const all = [...devices.owned, ...devices.shared];
|
|
356
|
+
return all.find((device) => device.deviceId === preferredDeviceId) ?? null;
|
|
357
|
+
}
|
|
349
358
|
/**
|
|
350
359
|
* Sign out: clear cached token + device, tear down the P2P client. The
|
|
351
360
|
* SDK stays enabled; the next feedback trigger will re-prompt for login.
|
|
@@ -809,6 +818,19 @@ class YaverFeedback {
|
|
|
809
818
|
static async isQuickIconHidden() {
|
|
810
819
|
return (0, preferences_1.getQuickIconDisabled)();
|
|
811
820
|
}
|
|
821
|
+
static async setQuickIconColorPreset(preset) {
|
|
822
|
+
await (0, preferences_1.setQuickIconColorPreset)(preset);
|
|
823
|
+
try {
|
|
824
|
+
const { DeviceEventEmitter } = require('react-native');
|
|
825
|
+
DeviceEventEmitter.emit('yaverFeedback:quickIconColorChange', { preset });
|
|
826
|
+
}
|
|
827
|
+
catch {
|
|
828
|
+
// emitter unavailable — preference is still persisted
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
static async getQuickIconColorPreset() {
|
|
832
|
+
return (0, preferences_1.getQuickIconColorPreset)();
|
|
833
|
+
}
|
|
812
834
|
/** Clear the persisted "user hid the icon" flag. */
|
|
813
835
|
static async resetQuickIconPreference() {
|
|
814
836
|
await YaverFeedback.setQuickIconVisible(true);
|
|
@@ -166,4 +166,34 @@ describe('P2PClient', () => {
|
|
|
166
166
|
expect(result).toEqual(builds);
|
|
167
167
|
});
|
|
168
168
|
});
|
|
169
|
+
describe('reloadApp()', () => {
|
|
170
|
+
it('returns an acknowledgement for dev reloads', async () => {
|
|
171
|
+
mockFetch.mockResolvedValue({
|
|
172
|
+
ok: true,
|
|
173
|
+
json: () => Promise.resolve({ ok: true, changeClass: 'js_only' }),
|
|
174
|
+
});
|
|
175
|
+
const client = new P2PClient_1.P2PClient('http://localhost:18080', 'tok');
|
|
176
|
+
const result = await client.reloadApp('dev');
|
|
177
|
+
expect(result).toEqual(expect.objectContaining({
|
|
178
|
+
ok: true,
|
|
179
|
+
mode: 'dev',
|
|
180
|
+
acknowledged: true,
|
|
181
|
+
message: 'Hot reload request accepted.',
|
|
182
|
+
}));
|
|
183
|
+
});
|
|
184
|
+
it('returns an acknowledgement for bundle reloads', async () => {
|
|
185
|
+
mockFetch.mockResolvedValue({
|
|
186
|
+
ok: true,
|
|
187
|
+
json: () => Promise.resolve({ ok: true }),
|
|
188
|
+
});
|
|
189
|
+
const client = new P2PClient_1.P2PClient('http://localhost:18080', 'tok');
|
|
190
|
+
const result = await client.reloadApp('bundle');
|
|
191
|
+
expect(result).toEqual(expect.objectContaining({
|
|
192
|
+
ok: true,
|
|
193
|
+
mode: 'bundle',
|
|
194
|
+
acknowledged: true,
|
|
195
|
+
message: 'Reload request acknowledged. Agent is rebuilding the bundle.',
|
|
196
|
+
}));
|
|
197
|
+
});
|
|
198
|
+
});
|
|
169
199
|
});
|
|
@@ -16,6 +16,33 @@ jest.mock('../Discovery', () => ({
|
|
|
16
16
|
discover: jest.fn(),
|
|
17
17
|
},
|
|
18
18
|
}));
|
|
19
|
+
jest.mock('../auth', () => ({
|
|
20
|
+
configureAuthEndpoints: jest.fn(),
|
|
21
|
+
setStrictNativeAuth: jest.fn(),
|
|
22
|
+
getToken: jest.fn(async () => null),
|
|
23
|
+
getSelectedDeviceId: jest.fn(async () => null),
|
|
24
|
+
clearToken: jest.fn(async () => { }),
|
|
25
|
+
clearSelectedDeviceId: jest.fn(async () => { }),
|
|
26
|
+
listReachableDevices: jest.fn(async () => ({
|
|
27
|
+
owned: [
|
|
28
|
+
{
|
|
29
|
+
deviceId: 'device-1',
|
|
30
|
+
name: 'Dev Mac',
|
|
31
|
+
platform: 'darwin',
|
|
32
|
+
isOnline: true,
|
|
33
|
+
needsAuth: false,
|
|
34
|
+
runnerDown: false,
|
|
35
|
+
lastHeartbeat: Date.now(),
|
|
36
|
+
isGuest: false,
|
|
37
|
+
accessScope: 'owner',
|
|
38
|
+
quicHost: '127.0.0.1',
|
|
39
|
+
quicPort: 18080,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
shared: [],
|
|
43
|
+
})),
|
|
44
|
+
DEFAULT_CONVEX_SITE_URL: 'https://example.convex.site',
|
|
45
|
+
}));
|
|
19
46
|
// Reset module-level state between tests by re-requiring
|
|
20
47
|
beforeEach(() => {
|
|
21
48
|
// YaverFeedback uses module-level variables (config, enabled, p2pClient).
|
|
@@ -106,6 +133,18 @@ describe('YaverFeedback', () => {
|
|
|
106
133
|
expect(cfg.agentUrl).toBe('http://10.0.0.1:18080');
|
|
107
134
|
});
|
|
108
135
|
});
|
|
136
|
+
describe('getSelectedRemoteDevice()', () => {
|
|
137
|
+
it('returns the selected device from the reachable device list', async () => {
|
|
138
|
+
YaverFeedback_1.YaverFeedback.init({
|
|
139
|
+
authToken: 'tok',
|
|
140
|
+
preferredDeviceId: 'device-1',
|
|
141
|
+
enabled: true,
|
|
142
|
+
});
|
|
143
|
+
const device = await YaverFeedback_1.YaverFeedback.getSelectedRemoteDevice();
|
|
144
|
+
expect(device?.deviceId).toBe('device-1');
|
|
145
|
+
expect(device?.name).toBe('Dev Mac');
|
|
146
|
+
});
|
|
147
|
+
});
|
|
109
148
|
describe('startReport()', () => {
|
|
110
149
|
it('does nothing when not enabled', async () => {
|
|
111
150
|
YaverFeedback_1.YaverFeedback.init({ authToken: 'tok', enabled: false });
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* yaver-feedback-react-native — Visual feedback SDK for Yaver.
|
|
3
3
|
*
|
|
4
|
-
* Shake-to-report surface with
|
|
4
|
+
* Shake-to-report surface with three launch actions:
|
|
5
5
|
* 1. Hot Reload — instant JS reload
|
|
6
6
|
* 2. Vibing — open a vibing session on the agent
|
|
7
|
-
* 3. Screenshot
|
|
8
|
-
*
|
|
9
|
-
* 4. Screen Recording — start, then stop + upload
|
|
7
|
+
* 3. Screenshot & Fix — capture the current screen and trigger
|
|
8
|
+
* the fix loop
|
|
10
9
|
*
|
|
11
10
|
* The small quick-access icon stays hidden until the first shake by
|
|
12
11
|
* default on mobile, then remains available unless the user hides it.
|
package/dist/index.js
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* yaver-feedback-react-native — Visual feedback SDK for Yaver.
|
|
4
4
|
*
|
|
5
|
-
* Shake-to-report surface with
|
|
5
|
+
* Shake-to-report surface with three launch actions:
|
|
6
6
|
* 1. Hot Reload — instant JS reload
|
|
7
7
|
* 2. Vibing — open a vibing session on the agent
|
|
8
|
-
* 3. Screenshot
|
|
9
|
-
*
|
|
10
|
-
* 4. Screen Recording — start, then stop + upload
|
|
8
|
+
* 3. Screenshot & Fix — capture the current screen and trigger
|
|
9
|
+
* the fix loop
|
|
11
10
|
*
|
|
12
11
|
* The small quick-access icon stays hidden until the first shake by
|
|
13
12
|
* default on mobile, then remains available unless the user hides it.
|
package/dist/preferences.d.ts
CHANGED
|
@@ -12,7 +12,18 @@
|
|
|
12
12
|
* still works (it just can't remember the disable beyond the
|
|
13
13
|
* in-memory session).
|
|
14
14
|
*/
|
|
15
|
+
export type QuickIconColorPreset = 'orange' | 'lime' | 'cyan' | 'pink' | 'yellow' | 'slate';
|
|
16
|
+
export declare const QUICK_ICON_COLOR_PRESETS: Record<QuickIconColorPreset, {
|
|
17
|
+
label: string;
|
|
18
|
+
backgroundColor: string;
|
|
19
|
+
foregroundColor: string;
|
|
20
|
+
borderColor: string;
|
|
21
|
+
shadowColor: string;
|
|
22
|
+
}>;
|
|
15
23
|
/** True if the user has long-pressed the icon and chosen "Hide". */
|
|
16
24
|
export declare function getQuickIconDisabled(): Promise<boolean>;
|
|
17
25
|
export declare function setQuickIconDisabled(disabled: boolean): Promise<void>;
|
|
18
26
|
export declare function clearQuickIconDisabled(): Promise<void>;
|
|
27
|
+
export declare function getQuickIconColorPreset(): Promise<QuickIconColorPreset | null>;
|
|
28
|
+
export declare function setQuickIconColorPreset(preset: QuickIconColorPreset | null): Promise<void>;
|
|
29
|
+
export declare function clearQuickIconColorPreset(): Promise<void>;
|
package/dist/preferences.js
CHANGED
|
@@ -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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yaver-feedback-react-native",
|
|
3
|
-
"version": "0.8.
|
|
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",
|
|
@@ -40,15 +40,17 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"jest": "^29.0.0",
|
|
44
43
|
"@types/jest": "^29.0.0",
|
|
44
|
+
"@types/react": "^19.2.2",
|
|
45
|
+
"jest": "^29.0.0",
|
|
45
46
|
"ts-jest": "^29.1.0",
|
|
46
47
|
"typescript": "^5.0.0"
|
|
47
48
|
},
|
|
48
49
|
"scripts": {
|
|
49
|
-
"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",
|
|
50
51
|
"prepublishOnly": "npm run build",
|
|
51
|
-
"test": "jest"
|
|
52
|
+
"test": "jest --runInBand",
|
|
53
|
+
"test:ci": "npm run build && npm test"
|
|
52
54
|
},
|
|
53
55
|
"jest": {
|
|
54
56
|
"preset": "ts-jest",
|
package/src/AuthOverlay.tsx
CHANGED