mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
Update files
This commit is contained in:
@@ -14,7 +14,7 @@ import { ScrollView, type ScrollView as ScrollViewType } from "react-native-gest
|
||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import * as Linking from "expo-linking";
|
||||
import { ChevronDown, ChevronRight, GitBranch, MoreVertical, RotateCcw } from "lucide-react-native";
|
||||
import { ChevronDown, ChevronRight, GitBranch, MoreVertical } from "lucide-react-native";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { useSessionStore } from "@/stores/session-store";
|
||||
import {
|
||||
@@ -32,7 +32,6 @@ import { getNowMs, isPerfLoggingEnabled, perfLog } from "@/utils/perf";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuHint,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
@@ -121,6 +120,7 @@ function HighlightedText({ tokens, lineType }: HighlightedTextProps) {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
interface DiffFileSectionProps {
|
||||
file: ParsedDiffFile;
|
||||
isExpanded: boolean;
|
||||
@@ -824,67 +824,12 @@ export function GitDiffPane({ serverId, agentId }: GitDiffPaneProps) {
|
||||
<Text style={styles.branchLabel} testID="changes-branch" numberOfLines={1}>
|
||||
{branchLabel}
|
||||
</Text>
|
||||
{isStatusFetching && (
|
||||
<ActivityIndicator size="small" color={theme.colors.foregroundMuted} />
|
||||
)}
|
||||
{isStatusFetching && (
|
||||
<ActivityIndicator size="small" color={theme.colors.foregroundMuted} />
|
||||
)}
|
||||
</View>
|
||||
{isGit ? (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
testID="changes-view-selector"
|
||||
style={styles.viewSelector}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Change diff view"
|
||||
>
|
||||
<Text style={styles.viewSelectorText}>
|
||||
{diffMode === "uncommitted" ? "Working" : "Base"}
|
||||
</Text>
|
||||
<ChevronDown size={14} color={theme.colors.foregroundMuted} />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" width={180} testID="changes-view-menu">
|
||||
<DropdownMenuItem
|
||||
testID="changes-mode-uncommitted"
|
||||
selected={diffMode === "uncommitted"}
|
||||
onSelect={() => setDiffMode("uncommitted")}
|
||||
>
|
||||
Working
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
testID="changes-mode-base"
|
||||
selected={diffMode === "base"}
|
||||
onSelect={() => setDiffMode("base")}
|
||||
>
|
||||
Base
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
{isGit ? (
|
||||
<View style={styles.toolbarRow} testID="changes-toolbar">
|
||||
<View style={styles.toolbarLeft}>
|
||||
{canShowCommit ? (
|
||||
<Pressable
|
||||
testID="changes-action-commit"
|
||||
style={[
|
||||
styles.secondaryActionButton,
|
||||
commitDisabled && styles.secondaryActionButtonDisabled,
|
||||
]}
|
||||
onPress={() => commitMutation.mutate()}
|
||||
disabled={commitDisabled}
|
||||
>
|
||||
{commitMutation.isPending ? (
|
||||
<ActivityIndicator size="small" color={theme.colors.foreground} />
|
||||
) : (
|
||||
<Text style={styles.secondaryActionText}>Commit…</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
) : (
|
||||
<View style={styles.toolbarLeftSpacer} />
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.toolbarRight}>
|
||||
<View style={styles.headerRight}>
|
||||
{canShowShip ? (
|
||||
<View style={styles.shipSplitButton}>
|
||||
<Pressable
|
||||
@@ -917,14 +862,9 @@ export function GitDiffPane({ serverId, agentId }: GitDiffPaneProps) {
|
||||
{shipPrimaryPending ? (
|
||||
<ActivityIndicator size="small" color={theme.colors.foreground} />
|
||||
) : (
|
||||
<>
|
||||
<Text style={styles.shipPrimaryText}>
|
||||
{resolvedShipPrimary === "merge" ? "Merge" : prActionLabel}
|
||||
</Text>
|
||||
<Text style={styles.shipSecondaryText} numberOfLines={1}>
|
||||
into {baseRefLabel}
|
||||
</Text>
|
||||
</>
|
||||
<Text style={styles.shipPrimaryText}>
|
||||
{resolvedShipPrimary === "merge" ? "Merge branch" : prActionLabel}
|
||||
</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
<DropdownMenu>
|
||||
@@ -940,19 +880,15 @@ export function GitDiffPane({ serverId, agentId }: GitDiffPaneProps) {
|
||||
<DropdownMenuItem
|
||||
testID="changes-ship-merge"
|
||||
disabled={mergeDisabled}
|
||||
description={mergeDisabled && hasUncommittedChanges ? "Requires clean working tree" : undefined}
|
||||
onSelect={() => {
|
||||
void persistShipDefault("merge");
|
||||
mergeMutation.mutate();
|
||||
}}
|
||||
>
|
||||
Merge into {baseRefLabel}
|
||||
Merge branch
|
||||
</DropdownMenuItem>
|
||||
{mergeDisabled && hasUncommittedChanges ? (
|
||||
<DropdownMenuHint>Requires a clean working tree.</DropdownMenuHint>
|
||||
) : null}
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
<DropdownMenuItem
|
||||
testID={hasPullRequest ? "changes-ship-open-pr" : "changes-ship-create-pr"}
|
||||
disabled={prDisabled}
|
||||
@@ -965,7 +901,7 @@ export function GitDiffPane({ serverId, agentId }: GitDiffPaneProps) {
|
||||
prMutation.mutate();
|
||||
}}
|
||||
>
|
||||
{hasPullRequest ? "Open PR" : `Create PR into ${baseRefLabel}`}
|
||||
{hasPullRequest ? "Open PR" : "Create PR"}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
@@ -982,35 +918,56 @@ export function GitDiffPane({ serverId, agentId }: GitDiffPaneProps) {
|
||||
<MoreVertical size={16} color={theme.colors.foregroundMuted} />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" width={220} testID="changes-overflow-content">
|
||||
<DropdownMenuItem
|
||||
testID="changes-menu-refresh"
|
||||
leading={<RotateCcw size={16} color={theme.colors.foreground} />}
|
||||
onSelect={handleRefresh}
|
||||
>
|
||||
Refresh
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
{canShowShip ? (
|
||||
<>
|
||||
{resolvedShipPrimary === "merge" ? (
|
||||
<DropdownMenuItem
|
||||
testID={hasPullRequest ? "changes-menu-open-pr" : "changes-menu-create-pr"}
|
||||
disabled={prDisabled}
|
||||
onSelect={() => {
|
||||
void persistShipDefault("pr");
|
||||
if (hasPullRequest && prStatus?.url) {
|
||||
void Linking.openURL(prStatus.url);
|
||||
return;
|
||||
}
|
||||
prMutation.mutate();
|
||||
}}
|
||||
>
|
||||
{hasPullRequest ? "Open PR" : "Create PR"}
|
||||
</DropdownMenuItem>
|
||||
) : (
|
||||
<DropdownMenuItem
|
||||
testID="changes-menu-merge"
|
||||
disabled={mergeDisabled}
|
||||
description={mergeDisabled && hasUncommittedChanges ? "Requires clean working tree" : undefined}
|
||||
onSelect={() => {
|
||||
void persistShipDefault("merge");
|
||||
mergeMutation.mutate();
|
||||
}}
|
||||
>
|
||||
Merge branch
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
) : null}
|
||||
<DropdownMenuItem
|
||||
testID="changes-menu-merge-from-base"
|
||||
disabled={mergeFromBaseDisabled}
|
||||
description={mergeFromBaseDisabled && hasUncommittedChanges ? "Requires clean working tree" : undefined}
|
||||
onSelect={() => mergeFromBaseMutation.mutate()}
|
||||
>
|
||||
Merge from {baseRefLabel}
|
||||
</DropdownMenuItem>
|
||||
{mergeFromBaseDisabled && hasUncommittedChanges ? (
|
||||
<DropdownMenuHint>Requires a clean working tree.</DropdownMenuHint>
|
||||
) : null}
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
testID="changes-menu-push"
|
||||
disabled={pushDisabled}
|
||||
description={pushDisabled && !(gitStatus?.hasRemote ?? false) ? "No remote configured" : undefined}
|
||||
onSelect={() => pushMutation.mutate()}
|
||||
>
|
||||
Push branch
|
||||
</DropdownMenuItem>
|
||||
{pushDisabled && !(gitStatus?.hasRemote ?? false) ? (
|
||||
<DropdownMenuHint>Remote 'origin' is not configured.</DropdownMenuHint>
|
||||
) : null}
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
testID="changes-menu-archive"
|
||||
@@ -1023,6 +980,63 @@ export function GitDiffPane({ serverId, agentId }: GitDiffPaneProps) {
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
{isGit ? (
|
||||
<View style={styles.toolbarRow} testID="changes-toolbar">
|
||||
<View style={styles.toolbarLeft}>
|
||||
{canShowCommit ? (
|
||||
<Pressable
|
||||
testID="changes-action-commit"
|
||||
style={[
|
||||
styles.secondaryActionButton,
|
||||
commitDisabled && styles.secondaryActionButtonDisabled,
|
||||
]}
|
||||
onPress={() => commitMutation.mutate()}
|
||||
disabled={commitDisabled}
|
||||
>
|
||||
{commitMutation.isPending ? (
|
||||
<ActivityIndicator size={12} color={theme.colors.foreground} style={styles.buttonSpinner} />
|
||||
) : (
|
||||
<Text style={styles.secondaryActionText}>Commit</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
) : (
|
||||
<View style={styles.toolbarLeftSpacer} />
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.toolbarRight}>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
testID="changes-view-selector"
|
||||
style={styles.viewSelector}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Change diff view"
|
||||
>
|
||||
<Text style={styles.viewSelectorText}>
|
||||
{diffMode === "uncommitted" ? "Working" : "Base"}
|
||||
</Text>
|
||||
<ChevronDown size={14} color={theme.colors.foregroundMuted} />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" width={180} testID="changes-view-menu">
|
||||
<DropdownMenuItem
|
||||
testID="changes-mode-uncommitted"
|
||||
selected={diffMode === "uncommitted"}
|
||||
onSelect={() => setDiffMode("uncommitted")}
|
||||
>
|
||||
Working
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
testID="changes-mode-base"
|
||||
selected={diffMode === "base"}
|
||||
onSelect={() => setDiffMode("base")}
|
||||
>
|
||||
Base
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</View>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -1076,6 +1090,12 @@ const styles = StyleSheet.create((theme) => ({
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
},
|
||||
headerRight: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: theme.spacing[1],
|
||||
flexShrink: 0,
|
||||
},
|
||||
branchLabel: {
|
||||
fontSize: theme.fontSize.sm,
|
||||
color: theme.colors.foreground,
|
||||
@@ -1104,7 +1124,9 @@ const styles = StyleSheet.create((theme) => ({
|
||||
gap: theme.spacing[2],
|
||||
paddingHorizontal: theme.spacing[3],
|
||||
paddingTop: theme.spacing[2],
|
||||
paddingBottom: theme.spacing[1],
|
||||
paddingBottom: theme.spacing[3],
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: theme.colors.border,
|
||||
},
|
||||
toolbarLeft: {
|
||||
flex: 1,
|
||||
@@ -1136,6 +1158,9 @@ const styles = StyleSheet.create((theme) => ({
|
||||
color: theme.colors.foreground,
|
||||
fontWeight: theme.fontWeight.medium,
|
||||
},
|
||||
buttonSpinner: {
|
||||
height: theme.fontSize.xs * 1.4,
|
||||
},
|
||||
shipSplitButton: {
|
||||
flexDirection: "row",
|
||||
alignItems: "stretch",
|
||||
@@ -1148,7 +1173,7 @@ const styles = StyleSheet.create((theme) => ({
|
||||
shipPrimaryButton: {
|
||||
paddingHorizontal: theme.spacing[3],
|
||||
paddingVertical: theme.spacing[2],
|
||||
minWidth: 140,
|
||||
justifyContent: "center",
|
||||
},
|
||||
shipPrimaryButtonDisabled: {
|
||||
opacity: 0.6,
|
||||
@@ -1158,11 +1183,6 @@ const styles = StyleSheet.create((theme) => ({
|
||||
color: theme.colors.foreground,
|
||||
fontWeight: theme.fontWeight.medium,
|
||||
},
|
||||
shipSecondaryText: {
|
||||
marginTop: 2,
|
||||
fontSize: theme.fontSize.xs,
|
||||
color: theme.colors.foregroundMuted,
|
||||
},
|
||||
shipCaretButton: {
|
||||
width: 36,
|
||||
alignItems: "center",
|
||||
@@ -1373,16 +1393,14 @@ const styles = StyleSheet.create((theme) => ({
|
||||
color: theme.colors.palette.red[500],
|
||||
},
|
||||
additions: {
|
||||
fontSize: theme.fontSize.sm,
|
||||
fontSize: theme.fontSize.xs,
|
||||
fontWeight: theme.fontWeight.normal,
|
||||
color: theme.colors.palette.green[400],
|
||||
fontFamily: Fonts.mono,
|
||||
},
|
||||
deletions: {
|
||||
fontSize: theme.fontSize.sm,
|
||||
fontSize: theme.fontSize.xs,
|
||||
fontWeight: theme.fontWeight.normal,
|
||||
color: theme.colors.palette.red[500],
|
||||
fontFamily: Fonts.mono,
|
||||
},
|
||||
diffContent: {
|
||||
borderTopWidth: theme.borderWidth[1],
|
||||
|
||||
@@ -485,11 +485,13 @@ export async function getCheckoutDiff(
|
||||
throw new Error(`Base ref mismatch: expected ${baseRef}, got ${compare.baseRef}`);
|
||||
} else {
|
||||
const normalizedBaseRef = normalizeLocalBranchRefName(baseRef);
|
||||
const { stdout } = await execAsync(`git diff ${normalizedBaseRef}...HEAD`, {
|
||||
// Diff base ref against working tree (includes uncommitted changes)
|
||||
const { stdout: trackedDiff } = await execAsync(`git diff ${normalizedBaseRef}`, {
|
||||
cwd,
|
||||
env: READ_ONLY_GIT_ENV,
|
||||
});
|
||||
diff = stdout;
|
||||
const untrackedDiff = await getUntrackedDiff(cwd);
|
||||
diff = trackedDiff + untrackedDiff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ DAEMON_PORT=$(get-port 6767 6768 6769 6770 6771 6772 6773)
|
||||
METRO_PORT=$(get-port 8081 8082 8083 8084 8085 8086 8087)
|
||||
|
||||
# Use a temporary PASEO_HOME to avoid conflicts between dev instances
|
||||
export PASEO_HOME=$(mktemp -d "${TMPDIR:-/tmp}/paseo-dev.XXXXXX")
|
||||
trap "rm -rf '$PASEO_HOME'" EXIT
|
||||
# export PASEO_HOME=$(mktemp -d "${TMPDIR:-/tmp}/paseo-dev.XXXXXX")
|
||||
# trap "rm -rf '$PASEO_HOME'" EXIT
|
||||
|
||||
# Build CORS origins for this Expo instance
|
||||
CORS_ORIGINS="http://localhost:${METRO_PORT},http://127.0.0.1:${METRO_PORT}"
|
||||
@@ -24,7 +24,7 @@ echo " Paseo Dev"
|
||||
echo "══════════════════════════════════════════════════════"
|
||||
echo " Daemon: http://localhost:${DAEMON_PORT}"
|
||||
echo " Metro: http://localhost:${METRO_PORT}"
|
||||
echo " Home: ${PASEO_HOME}"
|
||||
# echo " Home: ${PASEO_HOME}"
|
||||
echo "══════════════════════════════════════════════════════"
|
||||
|
||||
# Export for child processes (overrides .env values)
|
||||
|
||||
Reference in New Issue
Block a user