mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
fix: address review findings (#6710)
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -44,6 +44,7 @@ import {
|
||||
import type { RpcSuccess } from '../../../src/transport/types'
|
||||
import { StatusDot } from '../../../src/components/StatusDot'
|
||||
import { NewWorktreeModalController } from '../../../src/components/NewWorktreeModalController'
|
||||
import { NewWorkspaceFab, FAB_SIZE } from '../../../src/components/NewWorkspaceFab'
|
||||
import { MobileRepoIcon } from '../../../src/components/MobileRepoIcon'
|
||||
import { WorktreeListRow } from '../../../src/components/WorktreeListRow'
|
||||
import { useNow } from '../../../src/hooks/use-now'
|
||||
@@ -1099,17 +1100,6 @@ export function HostScreen({
|
||||
/>
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
style={styles.newButton}
|
||||
onPress={openNewWorktreeModal}
|
||||
disabled={connState !== 'connected'}
|
||||
>
|
||||
<Plus
|
||||
size={16}
|
||||
color={connState === 'connected' ? colors.textPrimary : colors.textMuted}
|
||||
/>
|
||||
</Pressable>
|
||||
|
||||
<Pressable style={styles.searchToggle} onPress={() => setShowSearch((s) => !s)}>
|
||||
{showSearch ? (
|
||||
<X size={16} color={colors.textSecondary} />
|
||||
@@ -1187,7 +1177,9 @@ export function HostScreen({
|
||||
// above the Samsung 3-button nav / iOS home indicator.
|
||||
contentContainerStyle={[
|
||||
styles.list,
|
||||
{ paddingBottom: spacing.lg + insets.bottom },
|
||||
// Phone shows a floating "+" button bottom-right; reserve room so the
|
||||
// last row stays tappable above it. Embedded sidebars keep the toolbar +.
|
||||
{ paddingBottom: (embedded ? spacing.lg : FAB_SIZE + spacing.xl) + insets.bottom },
|
||||
isWideLayout &&
|
||||
!embedded && { maxWidth: contentMaxWidth, width: '100%', alignSelf: 'center' }
|
||||
]}
|
||||
@@ -1245,6 +1237,11 @@ export function HostScreen({
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Floating "new workspace" button — phone only; embedded sidebars keep the toolbar +. */}
|
||||
{!embedded && (
|
||||
<NewWorkspaceFab onPress={openNewWorktreeModal} disabled={connState !== 'connected'} />
|
||||
)}
|
||||
|
||||
<PickerModal
|
||||
visible={showSortPicker}
|
||||
title="Sort By"
|
||||
@@ -1610,9 +1607,6 @@ const styles = StyleSheet.create({
|
||||
toolbarIconDisabled: {
|
||||
opacity: 0.6
|
||||
},
|
||||
newButton: {
|
||||
padding: spacing.xs
|
||||
},
|
||||
searchToggle: {
|
||||
padding: spacing.xs
|
||||
},
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { Pressable, StyleSheet } from 'react-native'
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
import { Plus } from 'lucide-react-native'
|
||||
import { colors, spacing } from '../theme/mobile-theme'
|
||||
|
||||
// Diameter of the phone "new workspace" floating action button. Exported so the
|
||||
// worktree list can reserve matching bottom padding and keep the last row tappable.
|
||||
export const FAB_SIZE = 48
|
||||
|
||||
type NewWorkspaceFabProps = {
|
||||
onPress: () => void
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
// Phone-only floating "+" for creating a workspace. Absolutely positioned so it
|
||||
// never intercepts list row taps, and lifted above the home indicator.
|
||||
export function NewWorkspaceFab({ onPress, disabled }: NewWorkspaceFabProps): React.JSX.Element {
|
||||
const insets = useSafeAreaInsets()
|
||||
return (
|
||||
<Pressable
|
||||
style={({ pressed }) => [
|
||||
styles.fab,
|
||||
{ bottom: spacing.xl + insets.bottom },
|
||||
pressed && styles.fabPressed,
|
||||
disabled && styles.fabDisabled
|
||||
]}
|
||||
onPress={onPress}
|
||||
disabled={disabled}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="New workspace"
|
||||
hitSlop={8}
|
||||
>
|
||||
<Plus size={24} color={colors.bgBase} strokeWidth={2.75} />
|
||||
</Pressable>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
fab: {
|
||||
position: 'absolute',
|
||||
right: spacing.lg,
|
||||
width: FAB_SIZE,
|
||||
height: FAB_SIZE,
|
||||
borderRadius: FAB_SIZE / 2,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
// Crisp near-white surface + dark icon: high contrast against the dark canvas
|
||||
// reads as the primary action while staying monochrome (STYLEGUIDE: color is
|
||||
// for state). Tight shadow avoids the muddy halo that made it look disabled.
|
||||
backgroundColor: colors.surfaceBright,
|
||||
shadowColor: '#000',
|
||||
shadowOpacity: 0.25,
|
||||
shadowRadius: 4,
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
elevation: 4
|
||||
},
|
||||
fabPressed: {
|
||||
backgroundColor: colors.textPrimary
|
||||
},
|
||||
fabDisabled: {
|
||||
opacity: 0.5
|
||||
}
|
||||
})
|
||||
@@ -12,6 +12,11 @@ export const colors = {
|
||||
textSecondary: '#888888',
|
||||
textMuted: '#555555',
|
||||
|
||||
// Crisp near-white surface for the single primary action on a screen (the
|
||||
// worktree FAB). Brighter than textPrimary so it reads as a solid button, not
|
||||
// disabled chrome, while staying monochrome (STYLEGUIDE: color is for state).
|
||||
surfaceBright: '#f5f5f5',
|
||||
|
||||
accentBlue: '#3b82f6',
|
||||
|
||||
statusGreen: '#22c55e',
|
||||
|
||||
Reference in New Issue
Block a user