mirror of
https://github.com/EthanShoeDev/fressh.git
synced 2026-01-11 06:12:51 +00:00
Good changes
This commit is contained in:
@@ -31,7 +31,7 @@ export default function TabsShellDetail() {
|
||||
// TODO: This is gross. It would be much better to switch
|
||||
// after the navigation animation completes.
|
||||
setReady(true);
|
||||
}, 50);
|
||||
}, 16);
|
||||
});
|
||||
|
||||
return () => {
|
||||
@@ -45,9 +45,19 @@ export default function TabsShellDetail() {
|
||||
}
|
||||
|
||||
function RouteSkeleton() {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<View>
|
||||
<Text>Loading</Text>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: theme.colors.background,
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: theme.colors.textPrimary, fontSize: 20 }}>
|
||||
Loading
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -81,7 +91,7 @@ function ShellDetail() {
|
||||
useEffect(() => {
|
||||
if (shell && connection) return;
|
||||
console.log('shell or connection not found, replacing route with /shell');
|
||||
router.replace('/shell');
|
||||
router.back();
|
||||
}, [connection, router, shell]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -111,6 +121,7 @@ function ShellDetail() {
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
edges={['left', 'right']}
|
||||
onLayout={(e) => {
|
||||
const { y, height } = e.nativeEvent.layout;
|
||||
const extra = computeBottomExtra(y, height);
|
||||
@@ -120,9 +131,10 @@ function ShellDetail() {
|
||||
flex: 1,
|
||||
justifyContent: 'flex-start',
|
||||
backgroundColor: theme.colors.background,
|
||||
padding: 0,
|
||||
paddingBottom:
|
||||
4 + insets.bottom + (bottomExtra || estimatedTabBarHeight),
|
||||
paddingTop: 2,
|
||||
paddingLeft: 8,
|
||||
paddingRight: 8,
|
||||
paddingBottom: insets.bottom + (bottomExtra || estimatedTabBarHeight),
|
||||
}}
|
||||
>
|
||||
<Stack.Screen
|
||||
@@ -149,6 +161,10 @@ function ShellDetail() {
|
||||
<XtermJsWebView
|
||||
ref={xtermRef}
|
||||
style={{ flex: 1 }}
|
||||
webViewOptions={{
|
||||
// Prevent iOS from adding automatic top inset inside WebView
|
||||
contentInsetAdjustmentBehavior: 'never',
|
||||
}}
|
||||
logger={{
|
||||
log: console.log,
|
||||
// debug: console.log,
|
||||
|
||||
@@ -35,6 +35,7 @@ function ShellContent() {
|
||||
const connections = useSshStore(
|
||||
useShallow((s) => Object.values(s.connections)),
|
||||
);
|
||||
console.log('DEBUG list view connections', connections.length);
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RnRussh } from '@fressh/react-native-uniffi-russh';
|
||||
import { RnRussh, SshError_Tags } from '@fressh/react-native-uniffi-russh';
|
||||
import { queryOptions } from '@tanstack/react-query';
|
||||
import * as Crypto from 'expo-crypto';
|
||||
import * as SecureStore from 'expo-secure-store';
|
||||
@@ -82,9 +82,9 @@ function makeBetterSecureStore<
|
||||
const unsafedRootManifest: unknown = rawRootManifestString
|
||||
? JSON.parse(rawRootManifestString)
|
||||
: {
|
||||
manifestVersion: rootManifestVersion,
|
||||
manifestChunksIds: [],
|
||||
};
|
||||
manifestVersion: rootManifestVersion,
|
||||
manifestChunksIds: [],
|
||||
};
|
||||
const rootManifest = rootManifestSchema.parse(unsafedRootManifest);
|
||||
const manifestChunks = await Promise.all(
|
||||
rootManifest.manifestChunksIds.map(async (manifestChunkId) => {
|
||||
@@ -330,8 +330,15 @@ async function upsertPrivateKey(params: {
|
||||
metadata: StrictOmit<KeyMetadata, 'createdAtMs'>;
|
||||
value: string;
|
||||
}) {
|
||||
const validKey = RnRussh.validatePrivateKey(params.value);
|
||||
if (!validKey) throw new Error('Invalid private key');
|
||||
const validateKeyResult = RnRussh.validatePrivateKey(params.value);
|
||||
if (!validateKeyResult.valid) {
|
||||
console.log('Invalid private key', validateKeyResult.error);
|
||||
if (validateKeyResult.error.tag === SshError_Tags.RusshKeys) {
|
||||
console.log('Invalid private key inner', validateKeyResult.error.inner);
|
||||
console.log('Invalid private key content', params.value);
|
||||
}
|
||||
throw new Error('Invalid private key', { cause: validateKeyResult.error });
|
||||
}
|
||||
const keyId = params.keyId ?? `key_${Crypto.randomUUID()}`;
|
||||
log(`${params.keyId ? 'Upserting' : 'Creating'} private key ${keyId}`);
|
||||
// Preserve createdAtMs if the entry already exists
|
||||
|
||||
@@ -19,6 +19,7 @@ export const useSshStore = create<SshRegistryStore>((set) => ({
|
||||
...args,
|
||||
onDisconnected: (connectionId) => {
|
||||
args.onDisconnected?.(connectionId);
|
||||
console.log('DEBUG connection disconnected', connectionId);
|
||||
set((s) => {
|
||||
const { [connectionId]: _omit, ...rest } = s.connections;
|
||||
return { connections: rest };
|
||||
@@ -32,6 +33,7 @@ export const useSshStore = create<SshRegistryStore>((set) => ({
|
||||
onClosed: (channelId) => {
|
||||
args.onClosed?.(channelId);
|
||||
const storeKey = `${connection.connectionId}-${channelId}` as const;
|
||||
console.log('DEBUG shell closed', storeKey);
|
||||
set((s) => {
|
||||
const { [storeKey]: _omit, ...rest } = s.shells;
|
||||
return { shells: rest };
|
||||
|
||||
Reference in New Issue
Block a user