Compare commits

..

No commits in common. "83d713c38c4364307831c324259bf744743d5535" and "9985e0517f9912e1ed57d2114f4380debc247e3f" have entirely different histories.

6 changed files with 22 additions and 43 deletions

View File

@ -1,6 +1,5 @@
import { HapticTab } from '@/components/HapticTab';
import { TabBarIcon } from '@/components/navigation/TabBarIcon';
import { requestNotificationPermission } from '@/components/owner/utils';
import TabBarBackground from '@/components/ui/TabBarBackground';
import { Colors } from '@/constants/Colors';
import { useColorScheme } from '@/hooks/useColorScheme';
@ -28,9 +27,9 @@ export default function TabLayout() {
const [token, setToken] = useState('');
const sendNotification = async (item: PollingData) => {
// 请求通知权限
const granted = await requestNotificationPermission();
if (!granted) {
console.log('用户拒绝了通知权限');
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') {
alert('请先允许通知权限');
return;
}

View File

@ -3,7 +3,6 @@ import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import { useEffect, useState } from 'react';
import { Button, Platform, Text, View } from 'react-native';
import { requestNotificationPermission } from '../owner/utils';
Notifications.setNotificationHandler({
handleNotification: async () => ({
@ -109,13 +108,13 @@ async function registerForPushNotificationsAsync() {
// 4. 如果尚未授予权限,则请求权限
if (existingStatus !== 'granted') {
const granted = await requestNotificationPermission();
finalStatus = granted ? Notifications.PermissionStatus.GRANTED : Notifications.PermissionStatus.DENIED;
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
// 5. 如果权限被拒绝,显示警告并返回
if (finalStatus !== 'granted') {
console.log('用户拒绝了通知权限');
alert('Failed to get push token for push notification!');
return;
}

View File

@ -1,9 +1,9 @@
import { requestLocationPermission, requestMediaLibraryPermission } from '@/components/owner/utils';
import { PermissionService } from '@/lib/PermissionService';
import { fetchApi } from '@/lib/server-api-util';
import { ConfirmUpload, defaultExifData, ExifData, FileStatus, ImagesPickerProps, UploadResult, UploadUrlResponse } from '@/types/upload';
import * as ImageManipulator from 'expo-image-manipulator';
import * as ImagePicker from 'expo-image-picker';
import { requestLocationPermission, requestMediaLibraryPermission } from '@/components/owner/utils';
import { PermissionService } from '@/lib/PermissionService';
import * as MediaLibrary from 'expo-media-library';
import React, { useEffect, useState } from 'react';
import { Button, Platform, TouchableOpacity, View } from 'react-native';
@ -115,7 +115,7 @@ export const ImagesPicker: React.FC<ImagesPickerProps> = ({
// 使用函数更新文件状态,确保每次更新都是原子的
const updateFileStatus = (updates: Partial<FileStatus>) => {
setCurrentFileStatus((original: FileStatus) => ({ ...original, ...updates } as FileStatus))
setCurrentFileStatus((original) => ({ ...original, ...updates }))
};
// 上传文件
const uploadFile = async (file: File, metadata: Record<string, any> = {}): Promise<ConfirmUpload> => {
@ -259,11 +259,9 @@ export const ImagesPicker: React.FC<ImagesPickerProps> = ({
originalUrl: undefined,
compressedUrl: '',
file: compressedFile,
exif: exifData,
exifData,
originalFile: {} as ConfirmUpload,
compressedFile: {} as ConfirmUpload,
thumbnail: '',
thumbnailFile: compressedFile,
};
try {
@ -287,8 +285,8 @@ export const ImagesPicker: React.FC<ImagesPickerProps> = ({
await new Promise(resolve => setTimeout(resolve, 300));
// 更新状态为成功
await updateFileStatus({ status: 'success', progress: 100, id: uploadResults.originalFile?.file_id });
// 调用上传完成回调 - 暂时注释,因为类型不匹配
// onUploadComplete?.(uploadResults);
// 调用上传完成回调
onUploadComplete?.(uploadResults);
} catch (error) {
updateFileStatus({ status: 'error', progress: 0, id: uploadResults.originalFile?.file_id });
throw error; // 重新抛出错误,让外层 catch 处理

View File

@ -129,9 +129,7 @@ const SettingModal = (props: { modalVisible: boolean, setModalVisible: (visible:
// 地理位置逆编码
const address = await reverseGeocode(location.coords.latitude, location.coords.longitude);
// 5. 更新位置状态
if (address) {
setCurrentLocation(address);
}
setCurrentLocation(address as Address);
return location;
} catch (error: any) {

View File

@ -2,13 +2,18 @@
import i18n from '@/i18n';
import { PermissionService } from '@/lib/PermissionService';
import { fetchApi } from '@/lib/server-api-util';
import { Address } from '@/types/user';
import * as ImagePicker from 'expo-image-picker';
import * as Location from 'expo-location';
import * as Notifications from 'expo-notifications';
import * as SecureStore from 'expo-secure-store';
import { Linking, Platform } from 'react-native';
interface Address {
id: number;
name: string;
// Add other address properties as needed
}
// 配置通知处理器
Notifications.setNotificationHandler({
handleNotification: async () => ({
@ -21,7 +26,7 @@ Notifications.setNotificationHandler({
});
// 逆编码
export const reverseGeocode = async (latitude: number, longitude: number): Promise<Address | undefined> => {
export const reverseGeocode = async (latitude: number, longitude: number) => {
try {
const addressResults = await fetchApi<Address[]>(`/area/gecoding?latitude=${latitude}&longitude=${longitude}`);
if (Object.keys(addressResults).length === 0) {
@ -37,7 +42,6 @@ export const reverseGeocode = async (latitude: number, longitude: number): Promi
return addressResults
} catch (error) {
console.log('逆地理编码失败:', error);
return undefined;
}
};
@ -132,13 +136,13 @@ export const checkMediaLibraryPermission = async (): Promise<{
status: ImagePicker.PermissionStatus;
}> => {
if (Platform.OS === 'web') {
return { hasPermission: true, canAskAgain: true, status: ImagePicker.PermissionStatus.GRANTED };
return { hasPermission: true, canAskAgain: true, status: 'granted' };
}
const { status, canAskAgain } = await ImagePicker.getMediaLibraryPermissionsAsync();
return {
hasPermission: status === ImagePicker.PermissionStatus.GRANTED,
hasPermission: status === 'granted',
canAskAgain,
status
};

View File

@ -1,19 +0,0 @@
// 重新导出 lib/background-uploader/types.ts 中的类型
export {
ExifData,
defaultExifData,
ImagesuploaderProps as ImagesPickerProps,
FileUploadItem,
ConfirmUpload,
UploadResult,
UploadUrlResponse,
} from '@/lib/background-uploader/types';
// 文件状态类型
export interface FileStatus {
file: File | null;
status: 'pending' | 'uploading' | 'success' | 'error';
progress: number;
error?: string;
id?: string;
}