Skip to content

Commit f462147

Browse files
aapelivclaude
andcommitted
mobile: dev tool ergonomics — clipboard share link, devtool start script, ASC app id
Replaces the dev-settings "Share via QR" block with a collapsible "Share via link" row that copies the deep link to the clipboard (adds expo-clipboard). Adds a start:devtool script that runs expo start with the couchers-devtool scheme so the QR opens the Dev Tool app, and fills in the devtool iOS ascAppId for auto-submit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 831770d commit f462147

4 files changed

Lines changed: 61 additions & 16 deletions

File tree

app/mobile/app/dev-settings.tsx

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as Clipboard from "expo-clipboard";
12
import Constants from "expo-constants";
23
import { router, useLocalSearchParams } from "expo-router";
34
import { useEffect, useState } from "react";
@@ -50,6 +51,8 @@ export default function DevSettingsScreen() {
5051
const [apiBaseUrl, setApiBaseUrl] = useState(paramApi ?? getApiBaseUrl());
5152
const [webBaseUrl, setWebBaseUrl] = useState(paramWeb ?? getWebBaseUrl());
5253
const [history, setHistory] = useState<UrlOverrides[]>([]);
54+
const [linkExpanded, setLinkExpanded] = useState(false);
55+
const [copied, setCopied] = useState(false);
5356

5457
// Apply incoming deep-link params (e.g. a scanned QR opening the app while
5558
// this screen is already mounted).
@@ -72,6 +75,7 @@ export default function DevSettingsScreen() {
7275
: theme.palette.text.secondary,
7376
border: isDark ? theme.dark.grey[100] : theme.palette.grey[200],
7477
inputBackground: isDark ? theme.dark.background.default : "#fff",
78+
muted: isDark ? theme.dark.grey[100] : theme.palette.grey[50],
7579
primary: isDark ? theme.dark.primary.main : theme.palette.primary.main,
7680
};
7781

@@ -145,6 +149,13 @@ export default function DevSettingsScreen() {
145149
clearUrlHistory().then(() => setHistory([]));
146150
};
147151

152+
const handleCopyLink = async () => {
153+
if (!shareLink) return;
154+
await Clipboard.setStringAsync(shareLink);
155+
setCopied(true);
156+
setTimeout(() => setCopied(false), 1500);
157+
};
158+
148159
return (
149160
<SafeAreaView
150161
style={[styles.container, { backgroundColor: colors.background }]}
@@ -266,22 +277,35 @@ export default function DevSettingsScreen() {
266277

267278
{shareLink && (
268279
<View style={styles.shareSection}>
269-
<Text style={[styles.sectionTitle, { color: colors.text }]}>
270-
Share via QR
271-
</Text>
272-
<Text style={[styles.hint, { color: colors.textSecondary }]}>
273-
Make a QR of this link and scan it with a phone camera to open
274-
another device with these URLs filled in.
275-
</Text>
276-
<Text
277-
selectable
278-
style={[
279-
styles.link,
280-
{ color: colors.text, borderColor: colors.border },
281-
]}
280+
<Pressable
281+
onPress={() => setLinkExpanded((v) => !v)}
282+
style={styles.shareHeader}
282283
>
283-
{shareLink}
284-
</Text>
284+
<Text style={[styles.shareTitle, { color: colors.textSecondary }]}>
285+
{linkExpanded ? "▾" : "▸"} Share via link
286+
</Text>
287+
</Pressable>
288+
{linkExpanded && (
289+
<>
290+
<Pressable onPress={handleCopyLink}>
291+
<Text
292+
style={[
293+
styles.link,
294+
{
295+
color: colors.text,
296+
borderColor: colors.border,
297+
backgroundColor: colors.muted,
298+
},
299+
]}
300+
>
301+
{shareLink}
302+
</Text>
303+
</Pressable>
304+
<Text style={[styles.hint, { color: colors.textSecondary }]}>
305+
{copied ? "Copied to clipboard" : "Tap the link to copy it"}
306+
</Text>
307+
</>
308+
)}
285309
</View>
286310
)}
287311
</ScrollView>
@@ -467,6 +491,13 @@ const styles = StyleSheet.create({
467491
shareSection: {
468492
marginTop: 24,
469493
},
494+
shareHeader: {
495+
paddingVertical: 8,
496+
},
497+
shareTitle: {
498+
fontSize: 14,
499+
fontWeight: "600",
500+
},
470501
link: {
471502
fontSize: 13,
472503
fontFamily: Platform.OS === "ios" ? "Courier" : "monospace",

app/mobile/eas.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
},
6969
"devtool": {
7070
"ios": {
71-
"ascAppId": "REPLACE_WITH_DEVTOOL_ASC_APP_ID"
71+
"ascAppId": "6772371797"
7272
},
7373
"android": {
7474
"track": "internal",

app/mobile/package-lock.json

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/mobile/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"version": "1.1.19",
55
"scripts": {
66
"start": "expo start",
7+
"start:devtool": "APP_VARIANT=devtool expo start --dev-client --scheme couchers-devtool",
78
"start:localhost": "expo start --localhost",
89
"build:protos": "bash ./ci-build-protos.sh",
910
"eas-build-pre-install": "npm run build:protos",
@@ -36,6 +37,7 @@
3637
"@react-navigation/native": "^7.1.6",
3738
"expo": "~54.0.34",
3839
"expo-build-properties": "^1.0.10",
40+
"expo-clipboard": "~8.0.8",
3941
"expo-constants": "~18.0.11",
4042
"expo-dev-client": "~6.0.21",
4143
"expo-device": "~8.0.10",

0 commit comments

Comments
 (0)