diff --git a/__tests__/rntl/screens/DownloadManagerScreen.test.tsx b/__tests__/rntl/screens/DownloadManagerScreen.test.tsx index 85e593385..30a8723c6 100644 --- a/__tests__/rntl/screens/DownloadManagerScreen.test.tsx +++ b/__tests__/rntl/screens/DownloadManagerScreen.test.tsx @@ -390,6 +390,35 @@ describe('DownloadManagerScreen', () => { expect(getByText('3.0 MB/s')).toBeTruthy(); }); + // Regression: downloadSpeed is 0 on the first progress tick of every download. + // The guard used to be `item.downloadSpeed && ... && (...)`, which evaluates to + // the number 0 and renders a bare "0" text node outside a — a hard crash + // on the real RN renderer. With the `!!(...)` fix the speed row is simply hidden. + it('hides the speed row when downloadSpeed is 0', () => { + mockDownloadStoreDownloads = { + 'author/model-id/model-file.gguf': { + modelKey: 'author/model-id/model-file.gguf', + downloadId: 'dl-1', + modelId: 'author/model-id', + fileName: 'model-file.gguf', + quantization: 'Q4_K_M', + modelType: 'text', + status: 'running', + bytesDownloaded: 1024, + totalBytes: 4 * 1024 * 1024 * 1024, + combinedTotalBytes: 4 * 1024 * 1024 * 1024, + progress: 0.01, + downloadSpeed: 0, + createdAt: Date.now(), + lastProgressAt: Date.now(), + }, + }; + + const { getByText, queryByText } = render(); + expect(getByText('model-file.gguf')).toBeTruthy(); // renders without crashing + expect(queryByText(/\/s$/)).toBeNull(); // no speed row rendered at 0 B/s + }); + it('shows storage total when models exist', () => { setupSingleModelState({ modelOverrides: { fileSize: 1024 * 1024 * 1024 } }, 1024 * 1024 * 1024); diff --git a/src/screens/ChatScreen/ChatScreenComponents.tsx b/src/screens/ChatScreen/ChatScreenComponents.tsx index 71b9a2b6d..1728d5c94 100644 --- a/src/screens/ChatScreen/ChatScreenComponents.tsx +++ b/src/screens/ChatScreen/ChatScreenComponents.tsx @@ -66,6 +66,7 @@ export const NoModelScreen: React.FC<{ isLoading={isModelLoading} currentModelPath={llmService.getLoadedModelPath()} onSelectionComplete={() => setShowModelSelector(false)} + onAddServer={() => navigation.navigate('RemoteServers')} /> ); diff --git a/src/screens/DownloadManagerScreen/items.tsx b/src/screens/DownloadManagerScreen/items.tsx index ab487764e..ccfade437 100644 --- a/src/screens/DownloadManagerScreen/items.tsx +++ b/src/screens/DownloadManagerScreen/items.tsx @@ -122,7 +122,7 @@ export const ActiveDownloadCard: React.FC = ({ item, on {formatBytes(item.bytesDownloaded)} / {formatBytes(item.fileSize)} - {item.downloadSpeed && item.downloadSpeed > 0 && item.status === 'running' && ( + {!!(item.downloadSpeed && item.downloadSpeed > 0) && item.status === 'running' && ( {formatSpeed(item.downloadSpeed)} )}