ci: add iOS OTA publishing and refactor gesture handling
Some checks failed
Frontend CI / ota-android (push) Successful in 1m10s
Frontend CI / ota-ios (push) Successful in 1m8s
Frontend CI / build-and-push-web (push) Successful in 6m1s
Frontend CI / build-android-apk (push) Has been cancelled

- Add `ota-ios` job to GitHub Actions workflow to support iOS OTA updates
- Refactor `ScheduleScreen` to use `GestureDetector` and `Gesture` from `react-native-gesture-handler` instead of `PanGestureHandler`
- Update `TradeCard` styles and layout spacing in `HomeScreen` and `MarketView`
- Refactor `MarketView` to use updated responsive spacing values
This commit is contained in:
2026-05-05 17:46:31 +08:00
parent c0ebebe3da
commit f5f9c3a619
5 changed files with 112 additions and 47 deletions

View File

@@ -18,8 +18,8 @@ import {
ActivityIndicator,
Platform,
} from 'react-native';
import { PanGestureHandler, State } from 'react-native-gesture-handler';
import type { PanGestureHandlerStateChangeEvent } from 'react-native-gesture-handler';
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
import { runOnJS } from 'react-native-reanimated';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { blurActiveElement } from '../../infrastructure/platform';
@@ -305,20 +305,23 @@ export const ScheduleScreen: React.FC = () => {
[courses]
);
const handleWeekSwipe = useCallback(
({ nativeEvent }: PanGestureHandlerStateChangeEvent) => {
if (nativeEvent.oldState !== State.ACTIVE && nativeEvent.oldState !== State.BEGAN) return;
const { translationX, translationY } = nativeEvent;
if (Math.abs(translationX) < SWIPE_THRESHOLD) return;
if (Math.abs(translationX) <= Math.abs(translationY) * 0.8) return;
const goNextWeek = useCallback(() => setCurrentWeek(prev => Math.min(prev + 1, weeks.length)), [weeks.length]);
const goPrevWeek = useCallback(() => setCurrentWeek(prev => Math.max(prev - 1, 1)), [weeks.length]);
if (translationX < 0) {
setCurrentWeek(prev => Math.min(prev + 1, weeks.length));
} else {
setCurrentWeek(prev => Math.max(prev - 1, 1));
}
},
[weeks.length]
const weekSwipeGesture = useMemo(() =>
Gesture.Pan()
.activeOffsetX([-8, 8])
.failOffsetY([-80, 80])
.onEnd((e) => {
if (Math.abs(e.translationX) < SWIPE_THRESHOLD) return;
if (Math.abs(e.translationX) <= Math.abs(e.translationY) * 0.8) return;
if (e.translationX < 0) {
runOnJS(goNextWeek)();
} else {
runOnJS(goPrevWeek)();
}
}),
[goNextWeek, goPrevWeek]
);
const webTouchStartRef = useRef<{ x: number; y: number; time: number } | null>(null);
@@ -797,11 +800,7 @@ export const ScheduleScreen: React.FC = () => {
</ScrollView>
</View>
) : (
<PanGestureHandler
activeOffsetX={[-8, 8]}
failOffsetY={[-80, 80]}
onHandlerStateChange={handleWeekSwipe}
>
<GestureDetector gesture={weekSwipeGesture}>
<View style={styles.scheduleBodyGestureLayer}>
<ScrollView
style={styles.scheduleBody}
@@ -809,21 +808,14 @@ export const ScheduleScreen: React.FC = () => {
contentContainerStyle={styles.scheduleBodyContent}
>
{renderTimeColumn()}
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
nestedScrollEnabled
contentContainerStyle={{ flexGrow: 1 }}
>
<View style={styles.daysContainer}>
{VISIBLE_DAY_VALUES.map((dayOfWeek, index) =>
renderDayColumn(dayOfWeek, index, index === VISIBLE_DAY_VALUES.length - 1)
)}
</View>
</ScrollView>
<View style={styles.daysContainer}>
{VISIBLE_DAY_VALUES.map((dayOfWeek, index) =>
renderDayColumn(dayOfWeek, index, index === VISIBLE_DAY_VALUES.length - 1)
)}
</View>
</ScrollView>
</View>
</PanGestureHandler>
</GestureDetector>
)
);
};