Skip to content

Commit

Permalink
[v0.0.6] Refactor chat UI, support multiple github tokens (#57)
Browse files Browse the repository at this point in the history
* bump versions to 006

* start chat bar

* bar

* Add expandable TextInput and icons to ChatBar; introduce state for toggling visibility.

* Add KeyboardAvoidingView to ChatBar for better keyboard handling on iOS and Android.

* Add collapse function and TouchableWithoutFeedback to ChatBar for keyboard dismiss.

* Add TouchableWithoutFeedback and Keyboard to Chat.tsx to dismiss keyboard on touch outside.

* Refactor ChatBar to use Keyboard event listener for collapsing, and remove unused imports.

* Refactor ChatBar to use useEffect for handling keyboard events based on platform.

* Refactor ChatBar to include typography from theme for enhanced styling.

* Add initial input height state to ChatBar for dynamic sizing.

* Refactor ChatBar.tsx: Remove unused 'inputHeight' state and 'EmitterSubscription' import, streamline keyboard event handling.

* Refactor ChatBar to use consistent keyboard event names across platforms.

* Add input height state management to ChatBar component.

* Update initial height in ChatBar from 0 to 24 for better UI layout.

* Refactor ChatBar to handle keyboard events based on OS type in ChatBar.tsx.

* try it

* hm

* Refactor ChatBar to use local state for expansion and height management.

* Refactor ChatBar component to enhance readability and maintainability.

* Refactor ChatBar.tsx to improve readability and maintainability by organizing imports and adjusting component structure.

* Refactor ChatBar.tsx to remove unused Keyboard import, enhancing code clarity.

* Refactor ChatBar to manage state and layout with custom hooks for improved readability and maintainability.

* Refactor ChatBar to use improved state management with hooks.

* Refactor ChatBar to use useMemo for height calculation to optimize performance.

* chatbar

* Refactor ChatBar to manage state and layout more effectively, enhancing UI responsiveness and maintenance.

* Refactor ChatBar component to improve readability and maintenance by consolidating state management and updating useEffect dependencies.

* comment

* nice

* nice

* gorgeous

* Refactor ChatBar.tsx: Add useRef and Animated, remove FontAwesome, and manage text state for improved animation and input handling.

* Added FontAwesome to imports and updated icons in ChatBar.tsx for enhanced UI options.

* Refactor ChatBar.tsx by removing unused imports to optimize bundle size.

* No changes detected in ChatBar.tsx; commit unnecessary.

* No changes detected in ChatBar.tsx; commit skipped.

* Refactor ChatBar.tsx to import colors and typography directly from theme directories for cleaner code and better maintainability.

* No changes detected between old and new content in ChatBar.tsx.

* No changes detected in ChatBar.tsx; commit aborted.

* Refactor ChatBar.tsx: Remove unused imports and state, add text state management.

* spellcheckfalse

* Refactor ChatBar.tsx to consolidate theme imports from a single source.

* Refactor ChatBar to remove unused imports and streamline state management.

* Refactor ChatBar component to centralize theming imports and clean up code structure for clarity and maintenance.

* Refactor ChatBar.tsx to improve readability and maintainability by organizing imports and updating useState usage.

* padding unfuck

* Refactor ChatBar.tsx to clean up imports and improve readability. No functional changes.

* Refactor Chat.tsx to improve readability and maintainability by removing unused imports and streamlining component structure.

* chat tsx cleanup

* initial overlay

* isLoading

* hmm

* Add KeyboardAvoidingView and Platform imports to ChatOverlay.tsx for improved keyboard handling on mobile devices.

* useChat refactor

* format

* No changes made to styles.ts; commit message unnecessary.

* Refactor ChatOverlay.tsx: Reorder imports, update MessageContent and styles paths to use '@/onyx' alias.

* Add TouchableWithoutFeedback and Keyboard to imports in ChatOverlay to dismiss keyboard on tap outside input.

* hierarchy

* Refactor Chat component layout for better structure in Chat.tsx, adding nested View for ChatOverlay.

* Refactor ChatOverlay.tsx: Remove KeyboardAvoidingView and Platform imports, add isLoading and optional error props.

* Refactor ChatBar.tsx to optimize imports and improve readability.

* Add keyboard dismiss on touch outside in Chat.tsx to enhance UX.

* Refactor ChatOverlay.tsx by removing unused imports and cleaning up the interface.

* Refactor Chat.tsx to nest TouchableWithoutFeedback inside a new View for improved layout control.

* Refactor ChatBar.tsx to enhance readability and maintainability.

* Refactor: Streamline imports in ChatOverlay.tsx by removing unused modules.

* Enhance keyboard usability in Chat component by implementing KeyboardAvoidingView for better platform-specific behavior.

* Remove KeyboardAvoidingView import and usage from ChatBar.tsx for simplification.

* pull in ignite theme shaz

* screen hm

* theme hmm

* closer

* before hmph

* hm

* hm

* Wrapped Chat component in DismissKeyboardView for enhanced usability.

* Add console log to DismissKeyboardView on press for debugging.

* Refactor Chat component to dismiss keyboard on press using Pressable from react-native.

* Refactor Chat component for better overlay touch handling by nesting Pressable inside View.

* Remove zIndex style from Pressable in Chat component for cleaner layout management.

* maybe good

* hierarchy

* shh

* axe dupe markdown

* hmm

* hm

* Refactor ChatActions.ts to include new interface definitions for improved type safety and modularity.

* Refactor ChatStore.ts: Remove withGroqActions import and expand MessageModel with new fields.

* axe chatactions

* chatstore

* Refactored RootStore.ts to organize imports and enhance code readability.

* Refactor: Removed redundant import in ChatStore.ts for clarity and maintenance.

* axe chatactions

* old

* axe old onyx

* shh

* hierarchy

* axe local models for now

* sidebar colors

* axe groq chat

* shh

* colors

* colors

* padding

* shh

* connect text chat

* axe old tool/gemini impl

* shh

* shh

* shh

* Create file app/hooks/useKeyboard.ts

* Refactor ChatBar.tsx: Remove useEffect, add useKeyboard hook for better keyboard management.

* Refactor Chat.tsx to use custom `useKeyboard` hook for keyboard state management.

* Refactor `useKeyboard` hook to include `useRef` for managing TextInput focus and add `TextInput` import in `useKeyboard.ts`.

* Refactor ChatBar component for better readability and maintenance.

* Refactor useKeyboard: Rename inputRef to globalInputRef, refactor ref to localRef for clarity.

* Added useEffect import in ChatBar.tsx for future feature enhancements.

* Refactor `useKeyboard` to improve readability and initialization logic.

* Refactor ChatBar to use updated typography and icons from theme, enhancing UI consistency.

* Refactor `useKeyboard.ts` to remove unused `isKeyboardOpening` state variable.

* cleanup

* nice

* add i18n and shh docs

* axe old docs

* hierarchy

* expo localization

* ignite images

* hierarchy hide imagses

* demo icons too

* header noice. i18n stuff

* keyboarddismisser and delete old

* Added useState to manage drawer state in Chat component.

* Refactor ChatDrawerContainer.tsx: remove unused imports and components, add platform check for Android.

* Refactor Chat component to accept drawer state via props for better state management.

* Refactor ChatDrawerContainer to improve code readability and maintenance.

* nice

* disallow empty msgs

* console shh

* hierarchy

* ignore i18n in hierarchy script for now

* Create file app/hooks/useVoiceRecording.ts

* Added useVoiceRecording hook to ChatBar for voice message functionality.

* Refactor ChatBar.tsx: Add useRef and useEffect hooks, replace View with Animated for smoother animations.

* hierarchy

* toolinvo colorsdark

* shh

* navigator refactor

* tsignore that

* set up settings screen in navigator

* settings header

* styles

* secondary bg

* autoimage and shh

* test hello

* hierarchy

* Create file app/screens/SettingsScreen/coder/GithubTokenSection.tsx

* Create file app/screens/SettingsScreen/coder/ToolsSection.tsx

* Create file app/screens/SettingsScreen/coder/RepoFormSection.tsx

* Create file app/screens/SettingsScreen/coder/RepoListSection.tsx

* Refactor RepoSettings.tsx to improve structure and modularity by extracting components like GithubTokenSection, RepoFormSection, and RepoListSection.

* Wrapped ToolsSection component with observer for reactive updates.

* Wrap GithubTokenSection with observer for reactive updates in MobX.

* Wrap RepoListSection with observer for MobX state reactivity.

* Added GithubTokenModel to CoderStore.ts for handling GitHub authentication tokens.

* Refactor GithubTokenSection to manage token visibility and editing state, add TouchableOpacity for improved UX.

* Create file docs/coder-settings.md

* hierarchy

* No changes detected between old and new content.

* Updated `coder-settings.md` to include additional information on managing GitHub PATs in Onyx Coder settings.

* No changes detected in CoderStore.ts, commit unnecessary.

* do i still have this token

* Create file app/components/ThinkingAnimation.tsx

* Refactor ChatOverlay.tsx: Removed unused imports, added ThinkingAnimation component, and updated props to enhance loading state management.

* Refactor ChatBar.tsx: Remove useEffect import, add ThinkingAnimation component import to enhance UI animations.

* shh

* Refactor ChatBar.tsx to update imports, removing ThinkingAnimation and adjusting typography path for better modularization.

* Refactor ChatBar.tsx by removing unused imports and organizing code structure for better readability and maintenance.

* Refactor ChatBar.tsx to import `colorsDark` directly for improved code clarity.

* Refactor ChatBar.tsx to use updated hooks and theme paths for better modularity and maintenance.

* Refactor ChatBar.tsx to improve code readability and maintainability.

* Refactor ChatBar.tsx to update imports and clean up unused dependencies.

* Refactor ChatBar.tsx to optimize imports and improve code readability.

* Create file docs/chatbar.md

* Refactor ChatBar.tsx to remove unused imports and organize code for better readability.

* Update chatbar.md to clarify behavior during voice recording; specify send button appearance and component state.

* Refactor ChatBar.tsx to use updated theme path for consistent styling.

* Update chatbar.md to fix typos and improve clarity in the Voice Recording section.

* Refactor `ChatBar.tsx` to use `colorsDark` from theme, enhancing UI consistency.

* Refactor ChatBar.tsx to import colors from "@/theme" directly, enhancing code maintainability and readability.

* Refactor ChatBar component to use relative imports for improved modularity and easier maintenance.

* Update chatbar.md to specify UI dimensions and icon alignment for Mic and Send buttons in the Voice Recording section.

* Refactor ChatBar.tsx to improve readability and maintainability without altering functionality.

* Refactor ChatBar.tsx to clarify imports and consolidate related logic for better readability and maintenance.

* format

* shh

* extract polyfills

* init

* No changes detected in `useStores.ts`, commit message unnecessary.

* shh

* nice

* handle legacy token

* githubtokens hm

* shh

* hierarchy

* No changes detected in CoderStore.ts, commit unnecessary.

* Refactor `styles.ts` to enhance code readability and maintainability; no changes in functionality.

* Refactor CoderStore.ts to improve code organization and readability, no functional changes.

* move that up

* Refactor Chat.tsx to use MobX `observer` for reactive state management.

* hm

* Replace ScrollView with KeyboardAwareScrollView in Chat.tsx for better keyboard handling.

* Refactor ChatOverlay.tsx to remove unused KeyboardAwareScrollView import and add ChatOverlayProps interface.

* remove keyboarddismiser

* Refactor Chat.tsx: Removed unused imports and components, streamlined file structure for better readability and maintainability.

* Refactor ChatBar.tsx: Remove unused imports and update typography import path.

* Refactor Chat.tsx to improve code readability and maintainability.

* Refactor ChatDrawerContainer to use specific safe area insets.

* Refactor Chat.tsx to improve readability and maintainability.

* No changes detected in `CoderStore.ts`. Commit discarded.

* nice
  • Loading branch information
AtlantisPleb authored Dec 30, 2024
1 parent 4a195d4 commit e6c4d1f
Show file tree
Hide file tree
Showing 186 changed files with 7,771 additions and 5,139 deletions.
3 changes: 2 additions & 1 deletion app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ module.exports = ({ config }: ConfigContext): Partial<ExpoConfig> => {
...config,
plugins: [
...existingPlugins,
'expo-sqlite'
'expo-localization',
'expo-sqlite',
],
extra: {
...config.extra,
Expand Down
2 changes: 1 addition & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Onyx",
"slug": "onyx",
"scheme": "onyx",
"version": "0.0.5",
"version": "0.0.6",
"orientation": "portrait",
"userInterfaceStyle": "automatic",
"icon": "./assets/images/app-icon-all.png",
Expand Down
57 changes: 20 additions & 37 deletions app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,41 @@ if (__DEV__) {

import "react-native-gesture-handler"
import "@/utils/ignore-warnings"
import "@/utils/crypto-polyfill"
import "text-encoding-polyfill"
import { Buffer } from "buffer"
import "@/utils/polyfills"
import { useFonts } from "expo-font"
import { StatusBar } from "expo-status-bar"
import * as React from "react"
import { ActivityIndicator, Alert, AppRegistry, View, ViewStyle } from "react-native"
import { ActivityIndicator, AppRegistry, View } from "react-native"
import { KeyboardProvider } from "react-native-keyboard-controller"
import { initialWindowMetrics, SafeAreaProvider } from "react-native-safe-area-context"
import { Canvas } from "@/canvas"
import { customFontsToLoad } from "@/theme/typography"
import { Chat } from "./chat/Chat"
import Config from "./config"
import { useAutoUpdate } from "./hooks/useAutoUpdate"
import { useInitialRootStore } from "./models"
import { OnyxLayout } from "./onyx/OnyxLayout"
import { AppNavigator, useNavigationPersistence } from "./navigators"
import { ErrorBoundary } from "./screens/ErrorScreen/ErrorBoundary"

global.Buffer = Buffer
import * as storage from "./utils/storage"

interface AppProps {
hideSplashScreen: () => Promise<void>
}

function AppContents(props: AppProps) {
export const NAVIGATION_PERSISTENCE_KEY = "NAVIGATION_STATE"

function App(props: AppProps) {
useAutoUpdate()
const { hideSplashScreen } = props
const {
initialNavigationState,
onNavigationStateChange,
isRestored: isNavigationStateRestored,
} = useNavigationPersistence(storage, NAVIGATION_PERSISTENCE_KEY)
const [loaded] = useFonts(customFontsToLoad)
const { rehydrated } = useInitialRootStore(() => {
// This runs after the root store has been initialized and rehydrated.
setTimeout(hideSplashScreen, 500)
})

if (!loaded || !rehydrated) {
if (!loaded || !rehydrated || !isNavigationStateRestored) {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<ActivityIndicator size="large" color="#fff" />
Expand All @@ -47,36 +49,17 @@ function AppContents(props: AppProps) {
return (
<SafeAreaProvider initialMetrics={initialWindowMetrics}>
<ErrorBoundary catchErrors={Config.catchErrors}>
<View style={$container}>
<StatusBar style="light" />
<View style={$canvasContainer}>
<Canvas />
</View>
<Chat />
</View>
<KeyboardProvider>
<AppNavigator
initialState={initialNavigationState}
onStateChange={onNavigationStateChange}
/>
</KeyboardProvider>
</ErrorBoundary>
</SafeAreaProvider>
)
}

function App(props: AppProps) {
return <AppContents {...props} />
}

const $container: ViewStyle = {
flex: 1,
backgroundColor: "#000",
}

const $canvasContainer: ViewStyle = {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: 0,
}

AppRegistry.registerComponent("main", () => App)

export default App
84 changes: 37 additions & 47 deletions app/chat/Chat.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,43 @@
import { useState } from "react"
import { Dimensions, TouchableOpacity, View } from "react-native"
import { Drawer } from "react-native-drawer-layout"
import { OnyxLayout } from "@/onyx/OnyxLayout"
import { useSafeAreaInsetsStyle } from "@/utils/useSafeAreaInsetsStyle"
import { Feather } from "@expo/vector-icons"
import { ChatDrawerContent } from "./ChatDrawerContent"
import { observer } from "mobx-react-lite"
import { Platform, View } from "react-native"
import { KeyboardAwareScrollView } from "react-native-keyboard-controller"
import { Header } from "@/components"
import { useChat } from "@/hooks/useChat"
import { navigate } from "@/navigators"
import { ChatBar } from "./ChatBar"
import { ChatOverlay } from "./ChatOverlay"

export const Chat = () => {
const [open, setOpen] = useState(false)
const $drawerInsets = useSafeAreaInsetsStyle(["top"])
interface ChatProps {
drawerOpen: boolean
setDrawerOpen: (open: boolean) => void
}

export const Chat = observer(({ drawerOpen, setDrawerOpen }: ChatProps) => {
const { handleSendMessage, isLoading, messages } = useChat()

return (
<Drawer
open={open}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
drawerType="slide"
renderDrawerContent={() => (
<ChatDrawerContent drawerInsets={$drawerInsets} setOpen={setOpen} />
)}
>
<View style={$drawerInsets}>
<TouchableOpacity
onPress={() => setOpen((prevOpen) => !prevOpen)}
style={{
position: "absolute",
top: 55,
left: 15,
zIndex: 900,
backgroundColor: "rgba(32, 32, 32, 0.8)",
padding: 8,
borderRadius: 4,
}}
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<Header
title="Onyx Chat"
leftIcon="menu"
onLeftPress={() => setDrawerOpen(!drawerOpen)}
rightIcon="settings"
onRightPress={() => navigate("Settings")}
/>
<KeyboardAwareScrollView
style={{ flex: 1 }}
contentContainerStyle={{ flexGrow: 1 }}
keyboardShouldPersistTaps="handled"
enabled={true}
disableScrollOnKeyboardHide={false}
>
<Feather name="menu" size={24} color="white" />
</TouchableOpacity>
<View
style={{
position: "absolute",
top: 0,
right: 0,
left: 0,
bottom: 0,
height: Dimensions.get("window").height,
}}
>
<OnyxLayout />
</View>
<View style={{ flex: 1 }}>
<ChatOverlay messages={messages} isLoading={isLoading} />
<ChatBar handleSendMessage={handleSendMessage} />
</View>
</KeyboardAwareScrollView>
</View>
</Drawer>
</View>
)
}
})
159 changes: 159 additions & 0 deletions app/chat/ChatBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { useRef, useState } from "react"
import { Keyboard, Pressable, TextInput, View } from "react-native"
import { ThinkingAnimation } from "@/components/ThinkingAnimation"
import { useKeyboard } from "@/hooks/useKeyboard"
import { useVoiceRecording } from "@/hooks/useVoiceRecording"
import { colorsDark as colors } from "@/theme"
import { AntDesign, FontAwesome } from "@expo/vector-icons"
import { typography } from "../theme/typography"

interface ChatBarProps {
handleSendMessage: (message: string) => void
}

export const ChatBar = ({ handleSendMessage }: ChatBarProps) => {
const [height, setHeight] = useState(24)
const [text, setText] = useState("")
const sendImmediatelyRef = useRef(false)
const { isOpened: expanded, show, ref } = useKeyboard()
const { isRecording, isProcessing, startRecording, stopRecording } = useVoiceRecording(
(transcription) => {
const trimmedTranscription = transcription.trim()
if (sendImmediatelyRef.current) {
// Send all accumulated text plus new transcription
const existingText = text.trim()
const fullMessage = existingText
? `${existingText} ${trimmedTranscription}`
: trimmedTranscription
handleSendMessage(fullMessage)
setText("")
sendImmediatelyRef.current = false
} else {
setText((prev) => {
if (!prev.trim()) return trimmedTranscription
return `${prev.trim()} ${trimmedTranscription}`
})
}
},
)

const updateSize = (event) => {
const newHeight = Math.min(event.nativeEvent.contentSize.height, 240)
setHeight(newHeight)
}

const handleMicPress = async (e) => {
e.stopPropagation()
if (isRecording) {
sendImmediatelyRef.current = false
await stopRecording()
} else {
await startRecording()
}
}

const handleSendPress = async (e) => {
e.stopPropagation()
if (isRecording) {
sendImmediatelyRef.current = true
await stopRecording()
} else if (text.trim()) {
handleSendMessage(text)
setText("")
Keyboard.dismiss()
}
}

const handleBarPress = () => {
if (!expanded) {
show()
}
}

return (
<View
style={{
borderRadius: 10,
marginHorizontal: 10,
backgroundColor: colors.backgroundSecondary,
paddingVertical: 8,
paddingHorizontal: 8,
minHeight: 50,
zIndex: 4,
}}
>
<Pressable
onPress={handleBarPress}
style={{
flexDirection: "row",
alignItems: "flex-end",
minHeight: 34,
}}
>
<Pressable
onPress={handleMicPress}
style={{
marginRight: 16,
backgroundColor: isRecording ? "white" : "transparent",
borderRadius: 36,
width: 36,
height: 36,
alignItems: "center",
justifyContent: "center",
}}
disabled={isProcessing}
>
<FontAwesome name="microphone" size={20} color={isRecording ? "black" : "#666"} />
</Pressable>

<View style={{ flex: 1, minHeight: 34 }}>
<TextInput
ref={ref}
spellCheck={false}
multiline
style={{
color: "white",
fontSize: 16,
fontFamily: typography.primary.normal,
opacity: expanded ? 1 : 0.8,
minHeight: 34,
maxHeight: 240,
}}
editable={!isRecording}
onContentSizeChange={updateSize}
placeholder={isRecording ? "Recording..." : "Message"}
placeholderTextColor="#666"
onChangeText={setText}
value={text}
onPressIn={handleBarPress}
/>
{isProcessing && (
<View style={{ position: "absolute", right: 0, bottom: 9 }}>
<ThinkingAnimation size={16} />
</View>
)}
</View>

<Pressable
onPress={handleSendPress}
style={{
backgroundColor: text.trim() || isRecording ? "white" : "transparent",
borderRadius: 28,
width: 28,
height: 28,
marginLeft: 12,
alignItems: "center",
justifyContent: "center",
marginBottom: 4,
}}
>
<AntDesign
name="arrowup"
size={20}
color={text.trim() || isRecording ? "black" : "#666"}
/>
</Pressable>
</Pressable>
</View>
)
}
Loading

0 comments on commit e6c4d1f

Please sign in to comment.