-
Notifications
You must be signed in to change notification settings - Fork 780
Open
Labels
Description
🪲 Description
cleaned all gradle
🪲 Please post your code:
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useIsFocused } from '@react-navigation/native';
import axios from 'axios';
import moment from 'moment';
import React, { useEffect, useState } from 'react';
import {
ActivityIndicator,
Alert,
Image,
PermissionsAndroid,
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import Config from 'react-native-config';
import DeviceInfo from 'react-native-device-info';
import GetLocation from 'react-native-get-location';
import { check, PERMISSIONS, request, RESULTS } from 'react-native-permissions';
import Sound from 'react-native-sound';
import {
Camera,
useCameraDevice,
useCameraPermission,
useCodeScanner,
} from 'react-native-vision-camera';
const API_URL = __DEV__ ? Config.API_URL_DEV : Config.API_URL_PROD;
export default function QRScreen({ navigation }) {
const [name, setName] = useState('');
const [staffId, setStaffId] = useState('');
const [deviceId, setDeviceId] = useState('');
const [deviceName, setDeviceName] = useState('');
const [appelletionName, setAppelletionName] = useState('');
const [email, setEmail] = useState('');
const [company, setCompany] = useState('');
const [companyId, setCompanyId] = useState('');
const [picture, setPicture] = useState('');
const [token, setToken] = useState('');
const [modalVisible, setModalVisible] = useState(false);
const [response, setResponse] = useState(null);
const { hasPermission, requestPermission } = useCameraPermission();
const [latestScannedData, setLatestScannedData] = useState(null);
const [location, setLocation] = useState({ latitude: 0, longitude: 0 });
const [qrLocation, setQrLocation] = useState({
latitude: 0,
longitude: 0,
location_device_no: '',
location_name: '',
location_token: '',
location_date: '',
});
const [errorMessage, setErrorMessage] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [locationStatus, setLocationStatus] = useState('waiting'); // 'waiting', 'searching', 'found', 'error'
const [locationRetryCount, setLocationRetryCount] = useState(0);
const [lastEntryInfo, setlastEntryInfo] = useState(null);
const [isScanning, setIsScanning] = useState(false);
const isFocused = useIsFocused();
const device = useCameraDevice('back');
Sound.setCategory('Playback', true);
const beep = new Sound(
Platform.OS === 'ios'
? 'beep.mp3'
: require('../../assets/sounds/beep.mp3'),
Sound.MAIN_BUNDLE,
error => {
if (error) {
console.log('failed to load the sound', error);
return;
}
},
);
console.log('location', location, latestScannedData);
// Helper function to validate coordinates
const isValidCoordinate = coord => {
return (
typeof coord === 'number' && !isNaN(coord) && Math.abs(coord) > 0.00001
);
};
// Check if location services are enabled
const checkLocationServicesEnabled = async () => {
try {
if (Platform.OS === 'ios') {
const result = await check(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
return result === RESULTS.GRANTED;
} else {
const result = await check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION);
return result === RESULTS.GRANTED;
}
} catch (error) {
console.error('Location services check failed:', error);
return false;
}
};
useEffect(() => {
// Request camera permission
requestPermission();
// Fetch user data from AsyncStorage
const fetchGlobalData = async () => {
try {
const globalData = await AsyncStorage.getItem('globalData');
const parsedData = globalData ? JSON.parse(globalData) : null;
setName(parsedData?.user?.staff_name);
setStaffId(parsedData?.user?.id);
setAppelletionName(parsedData?.user?.appellation_name);
setEmail(parsedData?.user?.email);
setCompany(parsedData?.user?.company);
setCompanyId(parsedData?.user?.company_id);
setPicture(parsedData?.user?.staff_picture);
setToken(parsedData?.access_token);
//son giriş-çıkış bilgisi
const response = await axios.get(
`${API_URL}/${parsedData?.user?.company}${parsedData?.user?.id}`,
{
headers: {
Authorization: `Bearer ${parsedData?.access_token}`,
'Content-Type': 'application/json',
},
},
);
setlastEntryInfo(response.data.data);
console.log('son haererk --->', response.data.data);
} catch (error) {
console.error('Error fetching global data:', error);
}
};
// Fetch device information
const fetchDeviceInfo = async () => {
try {
const name = await DeviceInfo.getDeviceName();
const id = await DeviceInfo.getUniqueId();
console.log('Device Unique ID:', id);
console.log('Device Name:', name);
setDeviceId(id);
setDeviceName(name);
} catch (error) {
console.error('Error fetching device info:', error);
}
};
// Start location acquisition early
const preloadLocation = async () => {
setLocationStatus('searching');
const enabled = await checkLocationServicesEnabled();
if (!enabled) {
setLocationStatus('error');
setErrorMessage(
'Konum servisleri etkin değil. Lütfen konum servislerini açın.',
);
return;
}
const locationData = await getLocation();
if (locationData) {
setLocationStatus('found');
} else {
setLocationStatus('error');
}
};
fetchGlobalData();
fetchDeviceInfo();
preloadLocation();
// Clean up function
return () => {
beep.release();
};
}, []);
// Effect to retry getting location if focused and we have an error
useEffect(() => {
if (isFocused && locationStatus === 'error' && locationRetryCount < 3) {
const timer = setTimeout(() => {
setLocationRetryCount(prev => prev + 1);
setLocationStatus('searching');
getLocation().then(loc => {
if (loc) setLocationStatus('found');
else setLocationStatus('error');
});
}, 3000); // Retry after 3 seconds
return () => clearTimeout(timer);
}
}, [isFocused, locationStatus, locationRetryCount]);
const requestLocationPermission = async () => {
try {
if (Platform.OS === 'android') {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
} else if (Platform.OS === 'ios') {
const result = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
return result === RESULTS.GRANTED;
}
} catch (error) {
console.error('İzin kontrol hatası:', error);
return false;
}
};
const getLocation = async () => {
const hasPermission = await requestLocationPermission();
if (!hasPermission) {
setErrorMessage(
'Konum izni verilmedi. Giriş/çıkış yapmak için konum iznine ihtiyaç vardır.',
);
Alert.alert(
'İzin Gerekli',
'Konum izni verilmedi. Uygulamayı kullanmak için konum izni vermeniz gerekmektedir.',
);
return null;
}
try {
// Show loading indicator
setIsLoading(true);
const location = await GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 20000, // Longer timeout for better accuracy
});
// Check for valid location with more robust validation
if (
!location ||
!isValidCoordinate(location.latitude) ||
!isValidCoordinate(location.longitude)
) {
setErrorMessage(
'Geçerli konum bilgisi alınamadı. Lütfen tekrar deneyin.',
);
Alert.alert(
'Konum Hatası',
'Geçerli konum bilgisi alınamadı. GPS sinyalinizi kontrol edin ve tekrar deneyin.',
);
return null;
}
console.log(
`Location acquired: ${location.latitude}, ${location.longitude}`,
);
setLocation(location);
setErrorMessage(''); // Clear any previous error
return location;
} catch (error) {
let errorMsg = 'Konum bilgisi alınamadı.';
// Provide more specific error messages
if (error.code === 'CANCELLED') {
errorMsg = 'Konum isteği iptal edildi.';
} else if (error.code === 'UNAVAILABLE') {
errorMsg =
'Konum servisi kullanılamıyor. GPS açık olduğundan emin olun.';
} else if (error.code === 'TIMEOUT') {
errorMsg = 'Konum alınamadı. Zaman aşımı oluştu.';
} else if (error.code === 'UNAUTHORIZED') {
errorMsg = 'Konum izni verilmedi.';
}
setErrorMessage(errorMsg);
//Alert.alert('Konum Alınamadı', errorMsg);
console.warn('Location error:', error);
return null;
} finally {
setIsLoading(false);
}
};
const codeScanner = useCodeScanner({
codeTypes: ['qr', 'ean-13'],
onCodeScanned: codes => {
if (isScanning) return; // Yeni bir tarama yapılmasını engelle
setIsScanning(true); // Tarama başlatıldı
try {
// Update the state with the latest scanned data
const returnValue = JSON.parse(String(codes[0].value));
setQrLocation(returnValue);
beep.play(success => {
if (!success) {
console.log('Playback failed due to audio decoding errors');
}
});
setLatestScannedData(returnValue);
// If we haven't got location yet, try again now
if (locationStatus !== 'found') {
setLocationStatus('searching');
getLocation().then(loc => {
if (loc) setLocationStatus('found');
else setLocationStatus('error');
});
}
} catch (error) {
Alert.alert(
'Hata',
'Geçersiz QR kod formatı. Lütfen geçerli bir QR kod okutun.',
);
console.log('QR kod formatı hatalı:', error);
return;
} finally {
// 2 saniye sonra tekrar taramaya izin ver
setTimeout(() => {
setIsScanning(false);
}, 2000);
}
},
});
if (device == null) {
return (
<View style={styles.centeredContainer}>
<Text>
Kamera bulunamadı. Lütfen cihazınızın kamera erişimine izin
verdiğinizden emin olun.
</Text>
</View>
);
}
const onPressSendEntryInfo = async entryType => {
if (locationStatus !== 'found') {
// If we don't have a valid location, try to get one now
setLocationStatus('searching');
const locationData = await getLocation();
if (
locationData &&
isValidCoordinate(locationData.latitude) &&
isValidCoordinate(locationData.longitude)
) {
setLocationStatus('found');
sendEntryInformation(entryType);
} else {
setLocationStatus('error');
Alert.alert(
'Konum Hatası',
'Konum bilgisi alınamadı. Giriş/çıkış yapabilmek için konum bilgisine ihtiyaç vardır.',
[
{
text: 'Tekrar Dene',
onPress: () => onPressSendEntryInfo(entryType),
},
{
text: 'İptal',
},
],
);
}
} else {
// We already have a valid location
sendEntryInformation(entryType);
}
};
const sendEntryInformation = async entryType => {
try {
setIsLoading(true);
const now = new Date();
const currentDate = now.toISOString().split('T')[0]; // YYYY-MM-DD formatında
const currentTime = now.toTimeString().split(' ')[0]; // HH:mm:ss formatında
const data = {
staff_id: staffId,
email: email,
phone_device_id: deviceId || 'DeviceId yok',
phone_device_name: deviceName || 'DeviceName yok',
phone_device_mac: 'phone_device_mac',
phone_latitude: location.latitude,
phone_longitude: location.longitude,
location_latitude: qrLocation.latitude,
location_longitude: qrLocation.longitude,
location_device_no: qrLocation.location_device_no,
location_name: qrLocation.location_name,
location_token: qrLocation.location_token,
location_date: qrLocation.location_date,
entry_date: currentDate,
entry_time: currentTime,
entry_type: entryType === 1 ? 'Giriş' : 'Çıkış',
company_id: companyId || 1,
};
console.log('Sending entry data:', data);
const response = await axios.post(
`${API_URL}/${company}/mobile/control`,
data,
{
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
},
);
const result = response.data;
if (result.status) {
console.log('Server response:', result);
setResponse(result.message);
beep.play(success => {
if (!success) {
console.log('Playback failed due to audio decoding errors');
}
});
navigation.navigate('EntryResult', { response: result.message });
} else {
Alert.alert(
'Hata',
result.message || 'İşlem sırasında bir hata oluştu.',
);
}
} catch (error) {
console.error('API request error:', error);
const errorMessage =
error.response?.data?.message || 'Sunucu ile iletişim kurulamadı.';
Alert.alert('Hata', errorMessage);
} finally {
setIsLoading(false);
}
};
return (
<View style={styles.container}>
<View style={styles.headerContainer}>
<Text style={styles.headerText}>Giriş Çıkış İşlemleriniz</Text>
</View>
<View style={styles.profileContainer}>
<Text style={styles.profileName}>{name}</Text>
<Text style={styles.profileTitle}>{appelletionName}</Text>
</View>
<View style={styles.cameraContainer}>
<View style={styles.camera_wrapper}>
<Camera
style={styles.camera}
codeScanner={codeScanner}
device={device}
isActive={isFocused}
/>
</View>
</View>
{/* Location status indicator */}
<View style={styles.locationStatusContainer}>
{locationStatus === 'waiting' && (
<Text style={styles.locationStatusText}>Konum bekleniyor...</Text>
)}
{locationStatus === 'searching' && (
<View style={styles.locationSearchingContainer}>
<ActivityIndicator size="small" color="#24A0D9" />
<Text style={styles.locationStatusText}>Konum aranıyor...</Text>
</View>
)}
{locationStatus === 'found' && (
<Text style={styles.locationStatusSuccess}>Konum bulundu ✓</Text>
)}
{locationStatus === 'error' && (
<View>
<Text style={styles.locationStatusError}>Konum hatası!</Text>
<TouchableOpacity
style={styles.retryButton}
onPress={() => {
setLocationStatus('searching');
getLocation().then(loc => {
if (loc) setLocationStatus('found');
else setLocationStatus('error');
});
}}
>
<Text style={styles.retryButtonText}>Konumu Yeniden Al</Text>
</TouchableOpacity>
</View>
)}
{errorMessage ? (
<Text style={styles.errorText}>{errorMessage}</Text>
) : null}
{!latestScannedData && locationStatus == 'found' && (
<View style={styles.scanInstructionContainer}>
<Text style={styles.scanInstructionText}>
Lütfen QR Kodu Okutun
</Text>
</View>
)}
</View>
</View>
);
}Is your issue with...
- iOS
- [ X] Android
- Windows
Are you using...
- [ X] React Native CLI (e.g.
react-native run-android) - Expo
- Other: (please specify)
Which versions are you using?
- React Native Sound: 0.13.0
- React Native:0.82.0
- iOS: iphone 17 pro
- Android: api level 36
- Windows:
Does the problem occur on...
- [ X] Simulator
- [ X] Device
If your problem is happening on a device, which device?
- Device: mate 10 pro