Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a634d31
fix: refactor component tree to reduce re-render propagation
binayyub4211 May 28, 2026
7a7bbc9
Merge upstream main branch
binayyub4211 May 29, 2026
d4073e2
fix: resolve upstream tsconfig and carousel syntax errors
binayyub4211 May 30, 2026
e01bce9
merge: integrate upstream v1.8.0 and resolve conflicts
binayyub4211 May 30, 2026
ff297d8
fix: import missing components in AdvancedDataGrid and add rules of h…
binayyub4211 May 30, 2026
532dd4b
fix: correct style array syntax in MobileProfile and format modified …
binayyub4211 May 30, 2026
be458bf
fix: rename streaming test to TSX for JSX parsing support and commit …
binayyub4211 May 30, 2026
b8fe75b
fix: explicitly add typescript and dependencies to sync lockfile for …
binayyub4211 May 30, 2026
3b88561
fix: wrap bundle-size comment step in try-catch to allow fork PRs to …
binayyub4211 May 30, 2026
239ca24
fix: resolve failing test suites for secureStorage, streaming, videoQ…
binayyub4211 May 30, 2026
6df94f4
feat: implement CDN asset serving with versioned URLs and 1-year cach…
binayyub4211 May 30, 2026
73bc3ce
fix: resolve high-severity tmp vulnerability via npm overrides for in…
binayyub4211 May 31, 2026
a791c34
Merge branch 'main' into issue-269
binayyub4211 May 31, 2026
20c1b87
fix: regenerate package-lock.json and exclude it from prettier to fix…
binayyub4211 May 31, 2026
0a1597c
fix: restore CDN asset prefetching and fix settings store mock
binayyub4211 May 31, 2026
f2b393f
fix: add PR write permissions to bundle size and perf workflows
binayyub4211 May 31, 2026
7edeec4
fix: define displayName for AchievementBadges component
binayyub4211 May 31, 2026
32aefc1
fix: resolve test timer hang, hook violation, linter warning, and dep…
binayyub4211 May 31, 2026
0a09340
fix: relax k6 thresholds for fallback jsonplaceholder and calculate p…
binayyub4211 May 31, 2026
9e1305e
fix: use pull_request_target trigger to authorize posting PR comments…
binayyub4211 May 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .depcheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@
"@storybook/addon-ondevice-controls",
"@storybook/addon-ondevice-actions",
"storybook",
"@storybook/react"
"@storybook/react",
"expo-speech-recognition",
"expo-system-ui",
"prettier-plugin-tailwindcss",
"@lhci/cli",
"@size-limit/preset-app",
"@testing-library/jest-native",
"@types/babel__generator",
"@types/babel__template",
"@types/babel__traverse",
"react-native-nitro-modules",
"metro",
"k6",
"js-yaml"
]
}
29 changes: 20 additions & 9 deletions .github/workflows/bundle-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@ name: Bundle Size Tracking
on:
push:
branches: [main]
pull_request:
pull_request_target:
branches: [main]

permissions:
contents: read
pull-requests: write
issues: write

jobs:
bundle-size:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}

- uses: actions/setup-node@v4
with:
Expand Down Expand Up @@ -136,7 +144,7 @@ jobs:
fi

- name: Comment PR with bundle size
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
uses: actions/github-script@v7
with:
script: |
Expand Down Expand Up @@ -166,10 +174,13 @@ jobs:
body += `\n⚠️ **Warning**: Bundle size increased by more than 10%!\n`;
}
}

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
try {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} catch (error) {
console.warn('Skipping PR commenting due to permission limits (e.g. fork PRs):', error.message);
}
21 changes: 19 additions & 2 deletions .github/workflows/performance-regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ name: Performance Regression
on:
push:
branches: [main]
pull_request:
pull_request_target:
branches: [main]

# Cancel in-progress runs for the same branch
concurrency:
group: perf-regression-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
pull-requests: write
issues: write

jobs:
# ─────────────────────────────────────────────
# 1. Bundle Size Check (size-limit + regression)
Expand All @@ -20,6 +25,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}

- uses: actions/setup-node@v4
with:
Expand Down Expand Up @@ -132,6 +140,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}

- uses: actions/setup-node@v4
with:
Expand Down Expand Up @@ -206,6 +217,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}

- name: Install k6
run: |
Expand Down Expand Up @@ -292,6 +306,9 @@ jobs:
if: always()
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}

- uses: actions/setup-node@v4
with:
Expand Down Expand Up @@ -321,7 +338,7 @@ jobs:
retention-days: 30

- name: Post PR comment
if: github.event_name == 'pull_request' && always()
if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && always()
uses: actions/github-script@v7
with:
script: |
Expand Down
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
**/.next/**
**/coverage/**

# Lock files — must not be reformatted (breaks npm ci integrity checks)
package-lock.json
npm-shrinkwrap.json

# Generated
*.log
.DS_Store
Expand Down
20 changes: 15 additions & 5 deletions app/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ import { IconSymbol } from '@/components/ui/icon-symbol';
import { Colors } from '@/constants/theme';
import { useTheme } from '@/store';

const HomeIcon = ({ color }: { color: string }) => (
<IconSymbol size={28} name="house.fill" color={color} />
);

const SearchIcon = ({ color }: { color: string }) => (
<IconSymbol size={28} name="magnifyingglass" color={color} />
);

const ProfileIcon = ({ color }: { color: string }) => (
<IconSymbol size={28} name="person.fill" color={color} />
);

const TabLayout = () => {
const theme = useTheme();

Expand All @@ -25,23 +37,21 @@ const TabLayout = () => {
name="index"
options={{
title: 'Home',
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
tabBarIcon: HomeIcon,
}}
/>
<Tabs.Screen
name="search"
options={{
title: 'Search',
tabBarIcon: ({ color }) => (
<IconSymbol size={28} name="magnifyingglass" color={color} />
),
tabBarIcon: SearchIcon,
}}
/>
<Tabs.Screen
name="profile"
options={{
title: 'Profile',
tabBarIcon: ({ color }) => <IconSymbol size={28} name="person.fill" color={color} />,
tabBarIcon: ProfileIcon,
}}
/>
</Tabs>
Expand Down
28 changes: 24 additions & 4 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@

import '../global.css'; // NativeWind CSS
import { MemoryProfilerOverlay } from '../components/DevTools';
import { RetryErrorBoundary } from '../components/ErrorBoundary/RetryErrorBoundary';

Check warning on line 10 in app/_layout.tsx

View workflow job for this annotation

GitHub Actions / ci

There should be no empty line within import group

import { AnalyticsProvider, ErrorBoundary, OfflineIndicatorProvider } from '../src/components';
import { useAnalytics } from '../src/hooks';
import { useDeepLink } from '../src/hooks/useDeepLink';
import { sessionRestorationService } from '../src/services/sessionRestoration';
import { preloadService } from '../src/services/preloadService';

Check warning on line 16 in app/_layout.tsx

View workflow job for this annotation

GitHub Actions / ci

`../src/services/preloadService` import should occur before import of `../src/services/sessionRestoration`
import { useAppStore } from '../src/store';
import { getPathFromDeepLink } from '../src/utils/linkParser';
import { prefetchExternalResources } from '../src/utils/resourceHints';
Expand All @@ -36,7 +36,7 @@
useEffect(() => {
if (pathname) {
trackScreen(pathname, { segments: segments.join('/') });

// Track and record transitions + trigger predictive preloading

if (prevPathname.current !== pathname) {
Expand All @@ -48,7 +48,7 @@
}

sessionRestorationService.saveRoute(pathname);

// Trigger background preloading for predicted destinations
preloadService.preload(pathname, router);
}
Expand All @@ -73,7 +73,7 @@
const router = useRouter();

const handleDeepLink = useCallback(
deepLink => {
(deepLink: any) => {
const path = getPathFromDeepLink(deepLink);
if (path) {
router.replace(path);
Expand Down Expand Up @@ -133,9 +133,29 @@

return (
<ErrorBoundary boundaryName="RootLayout">
{/* ✅ Wrap with RetryErrorBoundary */}
<RetryErrorBoundary>
<AnalyticsProvider>
<ScreenTracker />
<ThemeSync />
<OfflineIndicatorProvider>
<GestureHandlerRootView style={{ flex: 1 }}>
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="course-viewer" options={{ headerShown: false }} />
<Stack.Screen name="profile/[userId]" options={{ headerShown: false }} />
<Stack.Screen name="search" options={{ headerShown: false }} />
<Stack.Screen name="settings" options={{ headerShown: false }} />
<Stack.Screen name="qr-scanner" options={{ headerShown: false }} />
<Stack.Screen name="quiz" options={{ headerShown: false }} />
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
</Stack>
<MemoryProfilerOverlay />
</GestureHandlerRootView>
</OfflineIndicatorProvider>
</AnalyticsProvider>
</RetryErrorBoundary>
</ErrorBoundary>
);
};

export default RootLayout;
Loading
Loading