Skip to content

Commit 97efa7b

Browse files
committed
work in progress - fix:switching between screens while model is generating
1 parent 3dfd1da commit 97efa7b

File tree

6 files changed

+71
-8
lines changed

6 files changed

+71
-8
lines changed

apps/llm/app/_layout.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { Drawer } from 'expo-router/drawer';
22
import ColorPalette from '../colors';
33
import React from 'react';
4+
import { LlmProvider, useLlmContext } from '../contexts/LlmContext';
45

5-
export default function _layout() {
6+
function DrawerWithScreens() {
7+
const { isGenerating } = useLlmContext();
68
return (
79
<Drawer
810
screenOptions={{
911
drawerActiveTintColor: ColorPalette.primary,
1012
drawerInactiveTintColor: '#888',
1113
headerTintColor: ColorPalette.primary,
1214
headerTitleStyle: { color: ColorPalette.primary },
15+
swipeEnabled: !isGenerating,
1316
}}
1417
>
1518
<Drawer.Screen
@@ -47,3 +50,11 @@ export default function _layout() {
4750
</Drawer>
4851
);
4952
}
53+
54+
export default function _layout() {
55+
return (
56+
<LlmProvider>
57+
<DrawerWithScreens />
58+
</LlmProvider>
59+
);
60+
}

apps/llm/app/llm/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import {
2121
import PauseIcon from '../../assets/icons/pause_icon.svg';
2222
import ColorPalette from '../../colors';
2323
import Messages from '../../components/Messages';
24+
import { useLlmContext } from '../../contexts/LlmContext';
2425

2526
export default function LLMScreen() {
27+
const { setIsGenerating } = useLlmContext();
2628
const [isTextInputFocused, setIsTextInputFocused] = useState(false);
2729
const [userInput, setUserInput] = useState('');
2830
const textInputRef = useRef<TextInput>(null);
@@ -33,6 +35,10 @@ export default function LLMScreen() {
3335
tokenizerConfigSource: LLAMA3_2_TOKENIZER_CONFIG,
3436
});
3537

38+
useEffect(() => {
39+
setIsGenerating(llm.isGenerating);
40+
}, [llm.isGenerating, setIsGenerating]);
41+
3642
useEffect(() => {
3743
if (llm.error) {
3844
console.log('LLM error:', llm.error);

apps/llm/app/llm_tool_calling/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ import Messages from '../../components/Messages';
2626
import * as Brightness from 'expo-brightness';
2727
import * as Calendar from 'expo-calendar';
2828
import { executeTool, TOOL_DEFINITIONS_PHONE } from '../../utils/tools';
29+
import { useLlmContext } from '../../contexts/LlmContext';
2930

3031
export default function LLMToolCallingScreen() {
32+
const { setIsGenerating } = useLlmContext();
3133
const [isTextInputFocused, setIsTextInputFocused] = useState(false);
3234
const [userInput, setUserInput] = useState('');
3335
const textInputRef = useRef<TextInput>(null);
@@ -38,6 +40,10 @@ export default function LLMToolCallingScreen() {
3840
tokenizerConfigSource: HAMMER2_1_TOKENIZER_CONFIG,
3941
});
4042

43+
useEffect(() => {
44+
setIsGenerating(llm.isGenerating);
45+
}, [llm.isGenerating, setIsGenerating]);
46+
4147
const { configure } = llm;
4248
useEffect(() => {
4349
configure({

apps/llm/app/voice_chat/index.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useRef, useState } from 'react';
1+
import { useRef, useState, useEffect } from 'react';
22
import {
33
Keyboard,
44
KeyboardAvoidingView,
@@ -27,7 +27,7 @@ import Messages from '../../components/Messages';
2727
import LiveAudioStream from 'react-native-live-audio-stream';
2828
import DeviceInfo from 'react-native-device-info';
2929
import { Buffer } from 'buffer';
30-
30+
import { useLlmContext } from '../../contexts/LlmContext';
3131
const audioStreamOptions = {
3232
sampleRate: 16000,
3333
channels: 1,
@@ -57,6 +57,7 @@ const float32ArrayFromPCMBinaryBuffer = (b64EncodedBuffer: string) => {
5757
};
5858

5959
export default function VoiceChatScreen() {
60+
const { setIsGenerating } = useLlmContext();
6061
const [isRecording, setIsRecording] = useState(false);
6162
const messageRecorded = useRef<boolean>(false);
6263

@@ -71,6 +72,10 @@ export default function VoiceChatScreen() {
7172
overlapSeconds: 1.2,
7273
});
7374

75+
useEffect(() => {
76+
setIsGenerating(llm.isGenerating || speechToText.isGenerating);
77+
}, [llm.isGenerating, speechToText.isGenerating, setIsGenerating]);
78+
7479
const onChunk = (data: string) => {
7580
const float32Chunk = float32ArrayFromPCMBinaryBuffer(data);
7681
speechToText.streamingTranscribe(

apps/llm/contexts/LlmContext.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React, {
2+
createContext,
3+
useState,
4+
useContext,
5+
Dispatch,
6+
SetStateAction,
7+
} from 'react';
8+
9+
type LlmContextType = {
10+
isGenerating: boolean;
11+
setIsGenerating: Dispatch<SetStateAction<boolean>>;
12+
};
13+
14+
export const LlmContext = createContext<LlmContextType>({
15+
isGenerating: false,
16+
setIsGenerating: () => {},
17+
});
18+
19+
export function useLlmContext() {
20+
const context = useContext(LlmContext);
21+
return context;
22+
}
23+
24+
import { ReactNode } from 'react';
25+
26+
export const LlmProvider = ({ children }: { children: ReactNode }) => {
27+
const [isGenerating, setIsGenerating] = useState(false);
28+
return (
29+
<LlmContext.Provider value={{ isGenerating, setIsGenerating }}>
30+
{children}
31+
</LlmContext.Provider>
32+
);
33+
};

yarn.lock

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3789,7 +3789,7 @@ __metadata:
37893789
languageName: node
37903790
linkType: hard
37913791

3792-
"@react-navigation/native@npm:^7.1.6":
3792+
"@react-navigation/native@npm:^7.1.10, @react-navigation/native@npm:^7.1.6":
37933793
version: 7.1.10
37943794
resolution: "@react-navigation/native@npm:7.1.10"
37953795
dependencies:
@@ -5735,6 +5735,7 @@ __metadata:
57355735
"@babel/core": "npm:^7.25.2"
57365736
"@react-native/metro-config": "npm:^0.76.3"
57375737
"@react-navigation/drawer": "npm:^7.4.1"
5738+
"@react-navigation/native": "npm:^7.1.10"
57385739
"@shopify/react-native-skia": "npm:v2.0.0-next.2"
57395740
"@types/react": "npm:~19.0.10"
57405741
expo: "npm:^53.0.0"
@@ -5746,7 +5747,8 @@ __metadata:
57465747
metro-config: "npm:^0.81.0"
57475748
react: "npm:19.0.0"
57485749
react-native: "npm:0.79.2"
5749-
react-native-executorch: "npm:0.4.2"
5750+
react-native-device-info: "npm:^14.0.4"
5751+
react-native-executorch: "workspace:*"
57505752
react-native-gesture-handler: "npm:~2.24.0"
57515753
react-native-image-picker: "npm:^7.2.2"
57525754
react-native-loading-spinner-overlay: "npm:^3.0.1"
@@ -5755,7 +5757,6 @@ __metadata:
57555757
react-native-screens: "npm:~4.11.1"
57565758
react-native-svg: "npm:15.11.2"
57575759
react-native-svg-transformer: "npm:^1.5.0"
5758-
react-native-wheel-scrollview-picker: "npm:^2.0.6"
57595760
peerDependencies:
57605761
react-native: "*"
57615762
languageName: unknown
@@ -9692,6 +9693,7 @@ __metadata:
96929693
"@babel/core": "npm:^7.25.2"
96939694
"@react-native/metro-config": "npm:^0.76.3"
96949695
"@react-navigation/drawer": "npm:^7.4.1"
9696+
"@react-navigation/native": "npm:^7.1.10"
96959697
"@types/react": "npm:~19.0.10"
96969698
expo: "npm:~53.0.8"
96979699
expo-brightness: "npm:~13.1.4"
@@ -9705,6 +9707,7 @@ __metadata:
97059707
react: "npm:19.0.0"
97069708
react-native: "npm:0.79.2"
97079709
react-native-audio-api: "npm:0.5.7"
9710+
react-native-device-info: "npm:^14.0.4"
97089711
react-native-executorch: "workspace:*"
97099712
react-native-gesture-handler: "npm:~2.24.0"
97109713
react-native-live-audio-stream: "npm:^1.1.1"
@@ -9715,7 +9718,6 @@ __metadata:
97159718
react-native-screens: "npm:~4.11.1"
97169719
react-native-svg: "npm:15.11.2"
97179720
react-native-svg-transformer: "npm:^1.5.0"
9718-
react-native-wheel-scrollview-picker: "npm:^2.0.6"
97199721
peerDependencies:
97209722
react-native: "*"
97219723
languageName: unknown
@@ -12328,7 +12330,7 @@ __metadata:
1232812330
languageName: unknown
1232912331
linkType: soft
1233012332

12331-
"react-native-executorch@npm:0.4.2, react-native-executorch@workspace:*, react-native-executorch@workspace:packages/react-native-executorch":
12333+
"react-native-executorch@workspace:*, react-native-executorch@workspace:packages/react-native-executorch":
1233212334
version: 0.0.0-use.local
1233312335
resolution: "react-native-executorch@workspace:packages/react-native-executorch"
1233412336
dependencies:

0 commit comments

Comments
 (0)