2025-07-31 14:11:49 +08:00

129 lines
4.0 KiB
TypeScript

import { fetchApi } from "@/lib/server-api-util";
import { Message } from "@/types/ask";
import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';
import { TFunction } from "i18next";
import { useCallback } from "react";
import { Alert } from 'react-native';
// 实现一个函数,从两个数组中轮流插入新数组
export const mergeArrays = (arr1: any[], arr2: any[]) => {
const result: any[] = [];
const maxLength = Math.max(arr1.length, arr2.length);
for (let i = 0; i < maxLength; i++) {
if (i < arr1.length) result.push(arr1[i]);
if (i < arr2.length) result.push(arr2[i]);
}
return result;
};
// 创建新对话并获取消息
export const createNewConversation = useCallback(async (user_text: string) => {
const data = await fetchApi<string>("/chat/new", {
method: "POST",
});
return data
}, []);
// 获取对话信息
export const getConversation = async ({
session_id,
user_text,
material_ids
}: {
session_id: string,
user_text: string,
material_ids: string[]
}): Promise<Message | undefined> => {
// 获取对话信息必须要有对话id
if (!session_id) return undefined;
try {
const response = await fetchApi<Message>(`/chat`, {
method: "POST",
body: JSON.stringify({
session_id,
user_text,
material_ids
})
});
return response;
} catch (error) {
// console.error('Error in getConversation:', error);
return undefined;
}
};
// 图片 视频 保存到本地
export const saveMediaToGallery = async (mediaUrl: string, t: TFunction) => {
// 声明 fileUri 变量以便在 finally 块中使用
let fileUri: string | null = null;
try {
// 首先请求权限
const { status } = await MediaLibrary.requestPermissionsAsync();
if (status !== 'granted') {
Alert.alert('需要相册权限', '请允许应用访问相册以保存媒体文件');
return false;
}
// 获取文件扩展名
const fileExtension = mediaUrl.split('.').pop()?.toLowerCase() || 'mp4';
const isVideo = ['mp4', 'mov', 'avi', 'mkv'].includes(fileExtension);
const fileName = `temp_${Date.now()}.${fileExtension}`;
fileUri = `${FileSystem.documentDirectory}${fileName}`;
// 下载文件
console.log('开始下载文件:', mediaUrl);
const downloadResumable = FileSystem.createDownloadResumable(
mediaUrl,
fileUri,
{},
(downloadProgress) => {
const progress = downloadProgress.totalBytesWritten / (downloadProgress.totalBytesExpectedToWrite || 1);
console.log(`下载进度: ${Math.round(progress * 100)}%`);
}
);
const downloadResult = await downloadResumable.downloadAsync();
if (!downloadResult) {
throw new Error('下载失败: 下载被取消或发生错误');
}
const { uri } = downloadResult;
console.log('文件下载完成,准备保存到相册:', uri);
// 保存到相册
const asset = await MediaLibrary.createAssetAsync(uri);
await MediaLibrary.createAlbumAsync(
'Memowake',
asset,
false
);
Alert.alert(
'保存成功',
isVideo ? '视频已保存到相册' : '图片已保存到相册'
);
return true;
} catch (error) {
console.error('保存失败:', error);
Alert.alert(
'保存失败',
error instanceof Error ? error.message : '保存媒体文件时出错,请重试'
);
return false;
} finally {
// 清理临时文件
try {
if (fileUri) {
await FileSystem.deleteAsync(fileUri, { idempotent: true }).catch(console.warn);
}
} catch (cleanupError) {
console.warn('清理临时文件时出错:', cleanupError);
}
}
};