-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some linting #51
Some linting #51
Conversation
WalkthroughThe changes shift the project from a Hugo‐based static generator to an Expo/Node.js-based application architecture. New GitHub Actions workflows for linting, testing, and deployments have been added while deployment configurations (Firebase, Netlify, Wrangler) now reference Expo and Node.js. The application is rebranded from “chat” to “Orbiting” with expanded web and PWA support. Tests, contexts, components, and utilities have been updated or newly introduced, and many legacy Hugo files and configurations have been removed. Changes
Sequence Diagram(s)sequenceDiagram
participant B as Browser
participant I as Index Component
participant R as registerServiceWorker
B->>I: Window load event
I->>R: Import and call registerServiceWorker
R->>B: Attempt to register /sw.js
B-->>R: Registration result (success/failure)
R-->>I: Log outcome
sequenceDiagram
participant B as Browser
participant A as InstallPWA Component
participant U as User
B->>A: Trigger beforeinstallprompt event
A->>A: Prevent default and store prompt event
A->>U: Display "Install App" button
U->>A: Click button to install
A->>B: Invoke prompt() method on stored event
B-->>A: Return user choice
A->>A: Process installation result
Poem
✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
✅ Deploy Preview for orbit-ing ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caution
Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.
Actionable comments posted: 42
🔭 Outside diff range comments (8)
packages/chat/app/components/BigTextDisplay.tsx (1)
49-70
: 🧹 Nitpick (assertive)Edge case in calculateAndSetFontSize.
When text is shorter (e.g. 1–2 chars), resetting font size to max is logical. Consider verifying with test cases for boundary text lengths.
packages/chat/app/settings.tsx (1)
200-275
: 🧹 Nitpick (assertive)Style definitions are coherent.
The consistent usage of Paper theme colors ensures a unified look & feel. The naming is intuitive, though consider grouping advanced styling in separate files as the component grows.
packages/chat/app/__tests__/HomeScreen.test.tsx (2)
1-118
:⚠️ Potential issueFix the react-native-shake package linking issue.
The pipeline is failing due to an unlinked package. This needs to be addressed before merging.
#!/bin/bash # Install and link the package npm install react-native-shake cd ios && pod install && cd ..🧰 Tools
🪛 GitHub Actions: Expo Tests
[error] 8-8: The package 'react-native-shake' doesn't seem to be linked. Make sure: - You have run 'pod install' - You rebuilt the app after installing the package - You are not using Expo Go.
52-70
: 🧹 Nitpick (assertive)Add test coverage for font size edge cases.
Consider adding tests for:
- Maximum font size limit
- Minimum font size limit
- Font size calculation with special characters
packages/chat/app/context/TextContext.tsx (1)
19-19
: 🧹 Nitpick (assertive)Make autosave delay configurable.
Consider moving AUTOSAVE_DELAY to environment configuration.
.github/workflows/expo-test.yml (1)
1-31
: 🧹 Nitpick (assertive)Fix YAML formatting issues.
The workflow logic is correct, but there are formatting inconsistencies.
- branches: [ main ] + branches: [main] - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - + - +🧰 Tools
🪛 YAMLlint (1.35.1)
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
[error] 5-5: too many spaces inside brackets
(brackets)
[error] 5-5: too many spaces inside brackets
(brackets)
[error] 7-7: too many spaces inside brackets
(brackets)
[error] 7-7: too many spaces inside brackets
(brackets)
[error] 17-17: wrong indentation: expected 6 but found 4
(indentation)
[error] 18-18: trailing spaces
(trailing-spaces)
[error] 28-28: trailing spaces
(trailing-spaces)
packages/chat/app/__tests__/storage.test.ts (1)
1-7
:⚠️ Potential issueFix AsyncStorage setup in test environment.
The pipeline is failing due to AsyncStorage not being properly initialized in the test environment.
Add a mock for AsyncStorage in your test setup:
+jest.mock('@react-native-async-storage/async-storage', () => ({ + clear: jest.fn(), + getItem: jest.fn(), + setItem: jest.fn(), +}));🧰 Tools
🪛 GitHub Actions: Expo Tests
[error] 1-1: [@RNC/AsyncStorage]: NativeModule: AsyncStorage is null. To fix this issue try these steps: • Uninstall, rebuild and restart the app. • Run the packager with
--reset-cache
flag. • If you are using CocoaPods on iOS, runpod install
in theios
directory, then rebuild and re-run the app.packages/chat/README.md (1)
1-62
: 🧹 Nitpick (assertive)Fix markdown formatting issues.
The README has several formatting issues:
- Add language identifier to code blocks
- Remove trailing spaces
- Add blank lines around code blocks
-``` +```bash app/ ├─ __tests__/🧰 Tools
🪛 LanguageTool
[style] ~58-~58: The phrase ‘feel free to’ is used quite frequently. Consider using a less frequent alternative to set your writing apart from others and make it sound more professional.
Context: ...sx ├─ help.tsx └─ settings.tsx ``` Feel free to contribute! Open issues for bugs or fea...(FEEL_FREE_TO_STYLE_ME)
[style] ~61-~61: Using many exclamation marks might seem excessive (in this case: 4 exclamation marks for a text that’s 1893 characters long)
Context: ...t with your enhancements! Happy coding! 🎉(EN_EXCESSIVE_EXCLAMATION)
🪛 markdownlint-cli2 (0.17.2)
5-5: Trailing spaces
Expected: 0 or 2; Actual: 1(MD009, no-trailing-spaces)
14-14: Fenced code blocks should be surrounded by blank lines
null(MD031, blanks-around-fences)
16-16: Fenced code blocks should be surrounded by blank lines
null(MD031, blanks-around-fences)
32-32: Trailing spaces
Expected: 0 or 2; Actual: 1(MD009, no-trailing-spaces)
46-46: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
59-59: Trailing spaces
Expected: 0 or 2; Actual: 1(MD009, no-trailing-spaces)
🛑 Comments failed to post (42)
packages/chat/app/_layout.tsx (2)
43-49: 🧹 Nitpick (assertive)
Top-level error boundary is a good practice.
Wrapping the app in anErrorBoundary
ensures errors are caught globally. Consider integrating a remote error-tracking tool like Sentry if you need production-level monitoring.
11-29: 🧹 Nitpick (assertive)
Consider removing the extra fragment.
Wrapping<WelcomeModal />
and<Stack />
inside<>...</>
isn't strictly needed. This is a minor code simplification suggestion.- <> <WelcomeModal /> <Stack - </>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.function AppContent() { const { currentTheme } = useSettings(); return ( <PaperProvider theme={currentTheme}> <TextProvider> <WelcomeModal /> <Stack screenOptions={{ headerShown: false, contentStyle: { flex: 1 } }} /> </TextProvider> </PaperProvider> ); }
packages/chat/app/components/ErrorBoundary.tsx (2)
14-42: 🧹 Nitpick (assertive)
Error boundary is correctly implemented.
Storing errors in state and logging is standard. Consider optionally integrating a remote logging service.
44-73: 🧹 Nitpick (assertive)
Friendly fallback UI.
Displaying a “Try Again” button is user-friendly. Ensure sensitive error messages are not exposed in production.packages/chat/app/utils/storageUtils.ts (4)
33-37: 🧹 Nitpick (assertive)
Rename for clarity if desired.
The interface provides clean structure for pagination and search options. You might consider a more explicit name like
MessagesQueryOptions
to better convey its purpose.
49-49: 🧹 Nitpick (assertive)
Consider type-checking after JSON parse.
let messages = jsonValue ? JSON.parse(jsonValue) : [];
could benefit from basic type validation, especially if user data might become corrupted.
51-57: 🧹 Nitpick (assertive)
Potential performance strain with large datasets.
Filtering all messages on each call can be costly for large storage. If performance becomes an issue, consider indexing or a more efficient query mechanism.
39-45: 💡 Verification agent
🧩 Analysis chain
Ensure old calls are updated to new signature.
Switching to an object parameter is a great improvement. However, verify all call sites that previously used
(page, pageSize)
are updated to use the new options object.
🏁 Script executed:
#!/bin/bash # Checking for references to old function signature usage rg --context 3 "getMessages\(.*[0-9]+.*\,.*[0-9]+"Length of output: 175
Let's run this script to verify whether there are still any call sites using the old API signature.
🏁 Script executed:
#!/bin/bash # Searching for references to old function signature usage (numeric parameters) in the codebase rg --context 3 "getMessages\s*\(\s*\d+\s*,\s*\d+"Length of output: 598
Update call sites for getMessages signature
- The legacy call using numeric parameters exists in
packages/chat/app/context/TextContext.tsx
(e.g.,await getMessages(0, 1)
), which still needs to be updated to use the new options object.packages/chat/app/components/BigTextDisplay.tsx (3)
28-31: 🧹 Nitpick (assertive)
Fallback logic clarity.
Using
propMaxFontSize ?? (startingFontSize / 2.4)
is neat. Ensure the ratio (2.4 here) is documented or explained to avoid confusion.
99-129: 🧹 Nitpick (assertive)
Keyboard handlers need type definitions.
handleKeyboardShow(e: any)
handles an event object. Consider a typed approach or validatinge.endCoordinates?.height
to reduce runtime errors.
179-192: 🧹 Nitpick (assertive)
Dimension change logic is well designed.
Double-check quickly that it’s not triggered too frequently on some Android devices with ephemeral orientation changes. Debounce usage might handle that already.
packages/chat/app/settings.tsx (1)
186-194: 🧹 Nitpick (assertive)
Reset button clarity.
Distinguishing it with a bold color properly signals its destructive action. Confirm there's no need for a secondary confirmation.
packages/chat/app/history.tsx (1)
143-147: 🧹 Nitpick (assertive)
Refactor string concatenation to template literals.
Use template literals for readability and consistency.- "Yesterday " + - date.toLocaleTimeString(undefined, { - hour: "2-digit", - minute: "2-digit", - }) + `Yesterday ${date.toLocaleTimeString(undefined, { + hour: "2-digit", + minute: "2-digit", + })}`📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.`Yesterday ${date.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit", })}`
🧰 Tools
🪛 Biome (1.9.4)
[error] 143-147: Template literals are preferred over string concatenation.
Unsafe fix: Use a template literal.
(lint/style/useTemplate)
packages/chat/app/utils/registerServiceWorker.ts (1)
5-8: 🧹 Nitpick (assertive)
Enhance error handling and logging.
Consider using a proper logging service for production and improving error handling.
- console.log('SW registered:', registration); + // Use a proper logging service + if (process.env.NODE_ENV !== 'production') { + console.log('SW registered:', registration); + }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.// Use a proper logging service if (process.env.NODE_ENV !== 'production') { console.log('SW registered:', registration); } } catch (error) { console.log('SW registration failed:', error); }
packages/chat/app/index.tsx (1)
6-17: 🧹 Nitpick (assertive)
Consider optimizing service worker initialization.
The implementation works but could be more efficient.
useEffect(() => { if (Platform.OS === 'web' && typeof window !== 'undefined') { - const initServiceWorker = () => { - import('./utils/registerServiceWorker') - .then(({ registerServiceWorker }) => registerServiceWorker()) - .catch(error => console.error('Failed to load SW registration:', error)); - }; + const initServiceWorker = async () => { + try { + const { registerServiceWorker } = await import('./utils/registerServiceWorker'); + await registerServiceWorker(); + } catch (error) { + // Handle error appropriately + } + }; window.addEventListener('load', initServiceWorker); return () => window.removeEventListener('load', initServiceWorker); } }, []);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.useEffect(() => { if (Platform.OS === 'web' && typeof window !== 'undefined') { const initServiceWorker = async () => { try { const { registerServiceWorker } = await import('./utils/registerServiceWorker'); await registerServiceWorker(); } catch (error) { // Handle error appropriately } }; window.addEventListener('load', initServiceWorker); return () => window.removeEventListener('load', initServiceWorker); } }, []);
packages/chat/app/utils/settingsStorage.ts (2)
14-20: 🧹 Nitpick (assertive)
Add type safety to settings object.
Consider using a more specific type than
Record<string, unknown>
.+interface Settings { + version: number; + // Add other settings properties +} -export async function saveSettings(settings: Record<string, unknown>): Promise<void> { +export async function saveSettings(settings: Settings): Promise<void> {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.interface Settings { version: number; // Add other settings properties } export async function saveSettings(settings: Settings): Promise<void> { try { await AsyncStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(settings)); } catch (error) { throw new Error(`Failed to save settings: ${error}`); } }
5-12: 🧹 Nitpick (assertive)
Add validation and versioning to settings.
Consider adding schema validation and versioning for better maintainability.
+const SETTINGS_VERSION = 1; + export async function loadSettings(): Promise<Record<string, unknown> | null> { try { const settingsJson = await AsyncStorage.getItem(SETTINGS_STORAGE_KEY); - return settingsJson ? JSON.parse(settingsJson) : null; + if (!settingsJson) return null; + const settings = JSON.parse(settingsJson); + if (settings.version !== SETTINGS_VERSION) { + // Handle migration + } + return settings; } catch (error) { throw new Error(`Failed to load settings: ${error}`); }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.const SETTINGS_VERSION = 1; export async function loadSettings(): Promise<Record<string, unknown> | null> { try { const settingsJson = await AsyncStorage.getItem(SETTINGS_STORAGE_KEY); if (!settingsJson) return null; const settings = JSON.parse(settingsJson); if (settings.version !== SETTINGS_VERSION) { // Handle migration } return settings; } catch (error) { throw new Error(`Failed to load settings: ${error}`); } }
packages/chat/app/components/InstallPWA.tsx (2)
41-44: 🧹 Nitpick (assertive)
Enhance error handling with user feedback.
Consider providing user feedback when installation fails.
} catch (error) { console.error('Installation failed:', error); + // Consider showing a user-friendly error message + Alert.alert('Installation failed', 'Please try again later'); }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.} catch (error) { console.error('Installation failed:', error); // Consider showing a user-friendly error message Alert.alert('Installation failed', 'Please try again later'); } setDeferredPrompt(null);
15-29: 🧹 Nitpick (assertive)
Consider moving platform check to component level.
Move the platform check to the component level to avoid unnecessary effect setup.
export function InstallPWA() { + if (Platform.OS !== 'web') return null; + const [deferredPrompt, setDeferredPrompt] = useState<BeforeInstallPromptEvent | null>(null); const [isInstallable, setIsInstallable] = useState(false); useEffect(() => { - if (Platform.OS !== 'web') return; - const handleBeforeInstallPrompt = (e: Event) => {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.export function InstallPWA() { if (Platform.OS !== 'web') return null; const [deferredPrompt, setDeferredPrompt] = useState<BeforeInstallPromptEvent | null>(null); const [isInstallable, setIsInstallable] = useState(false); useEffect(() => { const handleBeforeInstallPrompt = (e: Event) => { e.preventDefault(); setDeferredPrompt(e as BeforeInstallPromptEvent); setIsInstallable(true); }; window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt); return () => { window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt); }; }, []); // ...rest of the component's implementation }
packages/chat/app/components/BottomBar.tsx (1)
18-26: 🧹 Nitpick (assertive)
Move styles outside component.
StyleSheet.create is being called on every render. Move it outside the component.
+const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + justifyContent: 'space-around', + alignItems: 'center', + height: 60, + }, +}); export default function BottomBar({ onClearPress, onHistoryPress }: BottomBarProps) { const theme = useTheme(); const { width } = useWindowDimensions(); - - const styles = StyleSheet.create({ - container: { - flexDirection: 'row', - justifyContent: 'space-around', - alignItems: 'center', - height: 60, - backgroundColor: theme.colors.background, - }, - }); + + const containerStyle = [styles.container, { backgroundColor: theme.colors.background }];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.// Moved outside the component to avoid recreating the static styles on every render. const styles = StyleSheet.create({ container: { flexDirection: 'row', justifyContent: 'space-around', alignItems: 'center', height: 60, }, }); export default function BottomBar({ onClearPress, onHistoryPress }: BottomBarProps) { const theme = useTheme(); const { width } = useWindowDimensions(); // Merge the static style with the dynamic backgroundColor based on the theme. const containerStyle = [styles.container, { backgroundColor: theme.colors.background }]; // ...rest of the component logic }
packages/chat/app/__tests__/HistoryScreen.test.tsx (1)
7-13: 🧹 Nitpick (assertive)
Simplify Alert mock.
The Alert mock can be simplified using jest.fn().
jest.mock('react-native', () => ({ ...jest.requireActual('react-native'), - Alert: { - ...jest.requireActual('react-native').Alert, - alert: jest.fn() - } + Alert: { alert: jest.fn() } }));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.jest.mock('react-native', () => ({ ...jest.requireActual('react-native'), Alert: { alert: jest.fn() } }));
🧰 Tools
🪛 GitHub Actions: Expo Tests
[error] 7-7: Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'SettingsManager' could not be found. Verify that a module by this name is registered in the native binary.
packages/chat/app/__tests__/accessibility.test.tsx (1)
46-56: 🧹 Nitpick (assertive)
Add cleanup for AccessibilityInfo mock.
Restore the original AccessibilityInfo.announceForAccessibility after test.
describe('Screen reader announcements', () => { it('announces errors', () => { const mockAnnounce = jest.spyOn(AccessibilityInfo, 'announceForAccessibility'); + + afterEach(() => { + mockAnnounce.mockRestore(); + }); + const { rerender } = render(<HomeScreen />); // Simulate an error rerender(<HomeScreen error="Test error" />); expect(mockAnnounce).toHaveBeenCalledWith('Test error'); }); });Committable suggestion skipped: line range outside the PR's diff.
packages/chat/app/+html.tsx (2)
26-26: 🛠️ Refactor suggestion
Move service worker registration to a separate file.
Using
dangerouslySetInnerHTML
poses security risks. Consider moving the service worker registration code to a separate file.- <script dangerouslySetInnerHTML={{ __html: sw }} /> + <script src="/js/register-sw.js" defer />Also applies to: 41-51
🧰 Tools
🪛 Biome (1.9.4)
[error] 26-26: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
18-21: 🧹 Nitpick (assertive)
Use self-closing tag for script element.
- <script - src="https://tinylytics.app/embed/ezMr4h65sCPevsfzK4ed.js" - defer - ></script> + <script + src="https://tinylytics.app/embed/ezMr4h65sCPevsfzK4ed.js" + defer + />📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.<script src="https://tinylytics.app/embed/ezMr4h65sCPevsfzK4ed.js" defer />
🧰 Tools
🪛 Biome (1.9.4)
[error] 18-21: JSX elements without children should be marked as self-closing. In JSX, it is valid for any element to be self-closing.
Unsafe fix: Use a SelfClosingElement instead
(lint/style/useSelfClosingElements)
packages/chat/app/context/SettingsContext.tsx (2)
7-7: 🧹 Nitpick (assertive)
Consider using enum for theme types.
Using an enum would provide better type safety and autocompletion.
-export type ThemeType = 'classic' | 'ocean' | 'forest' | 'sunset' | 'mono' | 'neon' | 'contrast' | 'candy' | 'mint'; +export enum ThemeType { + Classic = 'classic', + Ocean = 'ocean', + Forest = 'forest', + Sunset = 'sunset', + Mono = 'mono', + Neon = 'neon', + Contrast = 'contrast', + Candy = 'candy', + Mint = 'mint' +}Also applies to: 33-33
55-59: 🛠️ Refactor suggestion
Add error handling for settings update.
The
updateSettings
function should handle potential storage failures.const updateSettings = async (newSettings: Partial<Settings>) => { const updatedSettings = { ...settings, ...newSettings }; setSettings(updatedSettings); - await saveSettings(updatedSettings); + try { + await saveSettings(updatedSettings); + } catch (err) { + console.error('Failed to save settings:', err); + setSettings(settings); // Revert on failure + } };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.const updateSettings = async (newSettings: Partial<Settings>) => { const updatedSettings = { ...settings, ...newSettings }; setSettings(updatedSettings); try { await saveSettings(updatedSettings); } catch (err) { console.error('Failed to save settings:', err); setSettings(settings); // Revert on failure } };
packages/chat/app/about.tsx (2)
12-14: 🛠️ Refactor suggestion
Use encodeURIComponent for Wikipedia URLs.
Ensure URLs are properly encoded to handle special characters in names.
- Linking.openURL(`https://en.wikipedia.org/wiki/${name}`).catch((err) => + Linking.openURL(`https://en.wikipedia.org/wiki/${encodeURIComponent(name)}`).catch((err) =>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.Linking.openURL(`https://en.wikipedia.org/wiki/${encodeURIComponent(name)}`).catch((err) => console.error("Failed to open Wikipedia:", err), );
18-18: 🧹 Nitpick (assertive)
Move email address to configuration.
Hardcoded email addresses make maintenance difficult.
+const FEEDBACK_EMAIL = process.env.FEEDBACK_EMAIL || 'feedback@orbiting.com'; const handleEmailPress = () => { - Linking.openURL("mailto:feedback@orbiting.com"); + Linking.openURL(`mailto:${FEEDBACK_EMAIL}`); };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.const FEEDBACK_EMAIL = process.env.FEEDBACK_EMAIL || 'feedback@orbiting.com'; const handleEmailPress = () => { Linking.openURL(`mailto:${FEEDBACK_EMAIL}`); };
packages/chat/app/components/PageLayout.tsx (1)
16-21: 🧹 Nitpick (assertive)
Enhance error display with retry option.
Add a retry button and improve error message presentation.
return ( <View style={styles.errorContainer}> - <Text>Something went wrong</Text> - <Text>{this.state.error?.message}</Text> + <Text variant="headlineSmall">Oops! Something went wrong</Text> + <Text style={styles.errorMessage}>{this.state.error?.message}</Text> + <Button onPress={() => this.setState({ hasError: false })}> + Try Again + </Button> </View> );📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.return ( <View style={styles.errorContainer}> <Text variant="headlineSmall">Oops! Something went wrong</Text> <Text style={styles.errorMessage}>{this.state.error?.message}</Text> <Button onPress={() => this.setState({ hasError: false })}> Try Again </Button> </View> );
packages/chat/app/components/WelcomeModal.tsx (3)
34-36: 🛠️ Refactor suggestion
Move email address to configuration.
Hardcoded email should be moved to a configuration file.
90-90: 🛠️ Refactor suggestion
Remove type assertions using proper typing.
The
as any
assertions can be replaced with proper types.-contentContainerStyle={styles.modalContainer as any} +contentContainerStyle={styles.modalContainer}Also applies to: 91-91, 92-92
13-25: 🧹 Nitpick (assertive)
Improve cookie handling with error boundaries.
Consider using a try-catch wrapper utility for cookie operations.
+const getCookie = (name: string) => { + try { + return Cookies.get(name); + } catch (error) { + console.error(`Cookie error: ${error}`); + return null; + } +}; useEffect(() => { if (Platform.OS === "web") { - try { - const hasSeenWelcome = Cookies.get(WELCOME_COOKIE); - if (!hasSeenWelcome) { - setVisible(true); - } - } catch (error) { - console.error("Failed to check welcome cookie:", error); - setVisible(true); - } + const hasSeenWelcome = getCookie(WELCOME_COOKIE); + if (!hasSeenWelcome) { + setVisible(true); + } } }, []);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.const getCookie = (name: string) => { try { return Cookies.get(name); } catch (error) { console.error(`Cookie error: ${error}`); return null; } }; useEffect(() => { if (Platform.OS === "web") { const hasSeenWelcome = getCookie(WELCOME_COOKIE); if (!hasSeenWelcome) { setVisible(true); } } }, []);
packages/chat/app/components/HomeScreen.tsx (2)
70-87: 🧹 Nitpick (assertive)
Optimize shake gesture handling.
Consider debouncing the shake handler to prevent rapid consecutive triggers.
74-84: 🧹 Nitpick (assertive)
Extract animation duration constants.
Move magic numbers to named constants.
+const FLASH_IN_DURATION = 100; +const FLASH_OUT_DURATION = 900; Animated.sequence([ Animated.timing(flashAnim, { toValue: 1, - duration: 100, + duration: FLASH_IN_DURATION, useNativeDriver: false, }), Animated.timing(flashAnim, { toValue: 0, - duration: 900, + duration: FLASH_OUT_DURATION, useNativeDriver: false, }) ])📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.+const FLASH_IN_DURATION = 100; +const FLASH_OUT_DURATION = 900; Animated.sequence([ Animated.timing(flashAnim, { toValue: 1, duration: FLASH_IN_DURATION, useNativeDriver: false, }), Animated.timing(flashAnim, { toValue: 0, duration: FLASH_OUT_DURATION, useNativeDriver: false, })
packages/chat/app/context/TextContext.tsx (1)
67-72: 🧹 Nitpick (assertive)
Centralize error messages.
Move error messages to a separate constants file for better maintenance.
+// errorMessages.ts +export const ERROR_MESSAGES = { + AUTOSAVE_FAILED: 'Autosave failed:', + TEXT_UPDATE_FAILED: 'Failed to update text:', + CLEAR_TEXT_FAILED: 'Failed to clear text:', +};Committable suggestion skipped: line range outside the PR's diff.
packages/chat/app/themes/index.ts (2)
338-399: 🛠️ Refactor suggestion
Adjust neon theme colors for better readability.
Green text (#00cc00) on white background might be difficult to read.
- onBackground: '#00cc00', + onBackground: '#008000', - onSurface: '#00cc00', + onSurface: '#008000',📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.light: { colors: { primary: '#00e600', onPrimary: '#000000', primaryContainer: '#e6ffe6', onPrimaryContainer: '#003300', secondary: '#e600e6', onSecondary: '#000000', secondaryContainer: '#ffe6ff', onSecondaryContainer: '#330033', background: '#ffffff', onBackground: '#008000', surface: '#ffffff', onSurface: '#008000', surfaceVariant: '#e6ffe6', onSurfaceVariant: '#003300', outline: '#00ff00', elevation: { level0: 'transparent', level1: '#e6ffe6', level2: '#ccffcc', level3: '#b3ffb3', level4: '#99ff99', level5: '#80ff80', } }, custom: { tabBar: '#e6ffe6', tabBarActive: '#00ff00', } }, dark: { colors: { primary: '#00e600', onPrimary: '#000000', primaryContainer: '#001a00', onPrimaryContainer: '#00ff00', secondary: '#e600e6', onSecondary: '#000000', secondaryContainer: '#1a001a', onSecondaryContainer: '#ff00ff', background: '#000000', onBackground: '#00ff00', surface: '#000000', onSurface: '#00ff00', surfaceVariant: '#001a00', onSurfaceVariant: '#00ff00', outline: '#00ff00', elevation: { level0: 'transparent', level1: '#001a00', level2: '#003300', level3: '#004d00', level4: '#006600', level5: '#008000', } }, custom: { tabBar: '#001a00', tabBarActive: '#00ff00', } }
4-14: 💡 Verification agent
🧩 Analysis chain
Verify color contrast ratios for accessibility.
Some theme combinations might not meet WCAG contrast requirements.
🌐 Web query:
What are the minimum color contrast requirements for WCAG 2.1 Level AA compliance?
💡 Result:
WCAG 2.1 Level AA compliance requires specific color contrast ratios to ensure accessibility for users with visual impairments:
Normal Text Contrast
- Minimum 4.5:1 contrast ratio between text/background colors[1][2][5][7]
- Applies to standard-sized text (under 18pt regular or 14pt bold)[4][7]
- Includes images containing text[1][5]
Large Text Contrast
- Minimum 3:1 contrast ratio for:
- Text ≥18pt regular
- Text ≥14pt bold[1][2][4][5]
Additional Requirements in WCAG 2.1
- Non-text elements like UI components/icons require 3:1 contrast[1][2]
- Applies to:
- Form input borders
- Graphical objects essential to understanding content[1][2]
Exceptions
- Logos/brand names[1][5]
- Decorative/inactive UI elements[1][2]
- Text in images containing significant other visual content[1]
Ratios must be precise – no rounding up (e.g., 4.47:1 fails)[1]. Tools like WebAIM's Contrast Checker[4] or Accessible Web's tool[8] can verify compliance using hex color codes.
These standards help ensure content remains readable for users with low vision or color deficiencies while maintaining design flexibility[5][7].
Citations:
- 1: https://webaim.org/articles/contrast/
- 2: https://www.washington.edu/accesstech/checklist/contrast/
- 3: https://www.levelaccess.com/blog/ada-compliance-levels/
- 4: https://webaim.org/resources/contrastchecker/
- 5: https://altitudemarketing.com/blog/color-contrast-web-design/
- 6: https://docs.sourcepoint.com/hc/en-us/articles/4408054975891-WCAG-2-1-compliancy-custom-message
- 7: https://www.a11y-collective.com/glossary/colour-contrast/
- 8: https://accessibleweb.com/color-contrast-checker/
- 9: https://www.digitala11y.com/understanding-sc-1-4-3-contrast-minimum/
- 10: https://www.accessibleresources.com/post/understanding-wcag-2-1-a-aa-and-aaa-guidelines-for-color-contrast
Accessibility Contrast Issues in Theme Definitions
- Neon Theme: The combination of
#00ff00
(primary) and#ff00ff
(secondary) has an estimated contrast ratio around 2.3:1—well below the WCAG 2.1 Level AA minimum of 4.5:1 for normal text.- Candy Theme: The pairing of
#ff1493
and#9932cc
results in an estimated ratio near 1.6:1, which is far insufficient.- Classic Theme: The
#000000
/#666666
combo yields roughly 3.66:1, below the required threshold.- Sunset, Forest, Ocean, and Mint Themes: Preliminary calculations indicate these themes also offer contrast ratios between approximately 2.7:1 and 3.3:1—again falling short of the 4.5:1 guideline.
In contrast, the Mono (
#000000
/#ffffff
) and Contrast (#ffff00
/#000000
) themes already exceed the minimum contrast ratio. Consider revisiting the color choices for the other themes to achieve at least a 4.5:1 ratio for normal text (or use them only where large text is applied, which requires a minimum of 3:1).wrangler.toml (1)
14-15: 💡 Verification agent
🧩 Analysis chain
Verify Node.js LTS compatibility.
Check if Node.js 20 is the current LTS version.
🌐 Web query:
What is the current LTS version of Node.js?
💡 Result:
The current Long Term Support (LTS) version of Node.js as of February 2025 is Node.js v22.x (codename "Jod")[1][3][4][7]. This version transitioned to Active LTS status on October 29, 2024[1][7], and will receive critical updates through its support lifecycle:
Support Phase Timeline Active LTS Until October 2025[1][8] Maintenance LTS Until April 2027[1][7][8] Key details:
- Replaces Node.js v20.x (now in maintenance mode)[1]
- Introduces features like a built-in WebSocket client[1]
- Default version for major platforms like Netlify since February 2025[3]
- Recommended for production environments due to extended security patches and stability guarantees[1][8]
The next LTS release will be Node.js v24.x, scheduled for October 2025[7]. Developers should prioritize upgrading to v22.x for applications requiring long-term stability and security updates.
Citations:
- 1: https://nodesource.com/blog/Node.js-v22-Long-Term-Support-LTS
- 2: https://www.nearform.com/digital-community/node-js-release-schedule-explained/
- 3: https://answers.netlify.com/t/builds-functions-plugins-default-node-js-version-upgrade-to-22/135981
- 4: https://nodejs.org/en
- 5: https://nodejs.org/en/about/previous-releases
- 6: https://endoflife.date/nodejs
- 7: https://github.com/nodejs/Release
- 8: https://www.herodevs.com/blog-posts/node-js-end-of-life-dates-you-should-be-aware-of
- 9: https://community.auth0.com/t/node-js-22-or-20-for-running-actions/153963
- 10: https://www.herodevs.com/blog-posts/node-js-18-end-of-life-what-it-means-and-how-to-prepare
Action: Update Node.js version for LTS compatibility.
- The current LTS as of February 2025 is Node.js v22.x.
- Change
NODE_VERSION
inwrangler.toml
(lines 14-15) from"20"
to"22"
..github/workflows/firebase-hosting-pull-request.yml (1)
16-16: 🛠️ Refactor suggestion
Update actions/setup-node to v4.
The current version is outdated.
- uses: actions/setup-node@v3 + uses: actions/setup-node@v4📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.uses: actions/setup-node@v4
🧰 Tools
🪛 actionlint (1.7.4)
16-16: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
.github/workflows/firebase-hosting-merge.yml (2)
18-18:
⚠️ Potential issueUpdate setup-node action version.
The current version is outdated.
-uses: actions/setup-node@v3 +uses: actions/setup-node@v4📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.uses: actions/setup-node@v4
🧰 Tools
🪛 actionlint (1.7.4)
18-18: the runner of "actions/setup-node@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
21-21:
⚠️ Potential issueUpdate Node.js version to a stable release.
Node.js v22 is not yet released. Use a stable LTS version.
-node-version: "22" +node-version: "20"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.node-version: "20"
packages/chat/package.json (1)
85-91: 🧹 Nitpick (assertive)
Consider using TypeScript ESLint.
Since you're using TypeScript, add @typescript-eslint for better type checking.
"devDependencies": { + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", "eslint": "^8.57.0", "eslint-config-expo": "~8.0.1" }
Summary by CodeRabbit
New Features
Enhancements