[FIX] Fix filenames and servers url when downloading audio files (#4553)

This commit is contained in:
Gleidson Daniel Silva 2022-09-23 17:21:11 -03:00 committed by Diego Mello
parent fed8a6f0f6
commit d867f939f6
5 changed files with 32 additions and 10 deletions

View File

@ -57,7 +57,7 @@ const AttachedActions = ({ attachment }: { attachment: IAttachment }) => {
}; };
const Attachments: React.FC<IMessageAttachments> = React.memo( const Attachments: React.FC<IMessageAttachments> = React.memo(
({ attachments, timeFormat, showAttachment, style, getCustomEmoji, isReply }: IMessageAttachments) => { ({ attachments, timeFormat, showAttachment, style, getCustomEmoji, isReply, id }: IMessageAttachments) => {
const { theme } = useTheme(); const { theme } = useTheme();
if (!attachments || attachments.length === 0) { if (!attachments || attachments.length === 0) {
@ -80,7 +80,15 @@ const Attachments: React.FC<IMessageAttachments> = React.memo(
if (file && file.audio_url) { if (file && file.audio_url) {
return ( return (
<Audio key={file.audio_url} file={file} getCustomEmoji={getCustomEmoji} isReply={isReply} style={style} theme={theme} /> <Audio
key={file.audio_url}
file={file}
getCustomEmoji={getCustomEmoji}
isReply={isReply}
style={style}
theme={theme}
messageId={id}
/>
); );
} }
@ -106,7 +114,7 @@ const Attachments: React.FC<IMessageAttachments> = React.memo(
); );
} }
return <Reply key={index} index={index} attachment={file} timeFormat={timeFormat} getCustomEmoji={getCustomEmoji} />; return <Reply key={index} index={index} attachment={file} timeFormat={timeFormat} getCustomEmoji={getCustomEmoji} messageId={id} />;
}); });
return <>{attachmentsElements}</>; return <>{attachmentsElements}</>;
}, },

View File

@ -36,6 +36,7 @@ interface IMessageAudioProps {
theme: TSupportedThemes; theme: TSupportedThemes;
getCustomEmoji: TGetCustomEmoji; getCustomEmoji: TGetCustomEmoji;
scale?: number; scale?: number;
messageId: string;
} }
interface IMessageAudioState { interface IMessageAudioState {
@ -128,7 +129,7 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
} }
async componentDidMount() { async componentDidMount() {
const { file } = this.props; const { file, messageId } = this.props;
const { baseUrl, user } = this.context; const { baseUrl, user } = this.context;
let url = file.audio_url; let url = file.audio_url;
@ -139,7 +140,7 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
this.setState({ loading: true }); this.setState({ loading: true });
try { try {
if (url) { if (url) {
const audio = await downloadAudioFile(`${url}?rc_uid=${user.id}&rc_token=${user.token}`, url); const audio = await downloadAudioFile(`${url}?rc_uid=${user.id}&rc_token=${user.token}`, url, messageId);
await this.sound.loadAsync({ uri: audio }); await this.sound.loadAsync({ uri: audio });
} }
} catch { } catch {

View File

@ -90,6 +90,7 @@ interface IMessageReply {
timeFormat?: string; timeFormat?: string;
index: number; index: number;
getCustomEmoji: TGetCustomEmoji; getCustomEmoji: TGetCustomEmoji;
messageId: string;
} }
const Title = React.memo( const Title = React.memo(
@ -201,7 +202,7 @@ const Fields = React.memo(
); );
const Reply = React.memo( const Reply = React.memo(
({ attachment, timeFormat, index, getCustomEmoji }: IMessageReply) => { ({ attachment, timeFormat, index, getCustomEmoji, messageId }: IMessageReply) => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { theme } = useTheme(); const { theme } = useTheme();
const { baseUrl, user, jumpToMessage } = useContext(MessageContext); const { baseUrl, user, jumpToMessage } = useContext(MessageContext);
@ -256,6 +257,7 @@ const Reply = React.memo(
timeFormat={timeFormat} timeFormat={timeFormat}
style={[{ color: themes[theme].auxiliaryTintColor, fontSize: 14, marginBottom: 8 }]} style={[{ color: themes[theme].auxiliaryTintColor, fontSize: 14, marginBottom: 8 }]}
isReply isReply
id={messageId}
/> />
<UrlImage image={attachment.thumb_url} /> <UrlImage image={attachment.thumb_url} />
<Description attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} /> <Description attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />

View File

@ -14,6 +14,7 @@ export interface IMessageAttachments {
isReply?: boolean; isReply?: boolean;
showAttachment?: (file: IAttachment) => void; showAttachment?: (file: IAttachment) => void;
getCustomEmoji: TGetCustomEmoji; getCustomEmoji: TGetCustomEmoji;
id: string;
} }
export interface IMessageAvatar { export interface IMessageAvatar {

View File

@ -1,8 +1,17 @@
import * as FileSystem from 'expo-file-system'; import * as FileSystem from 'expo-file-system';
import { sanitizeLikeString } from '../database/utils';
import { store } from '../store/auxStore'; import { store } from '../store/auxStore';
import log from './helpers/log'; import log from './helpers/log';
const sanitizeString = (value: string) => sanitizeLikeString(value.substring(value.lastIndexOf('/') + 1));
const parseFilename = (value: string) => {
const extension = value.substring(value.lastIndexOf('.') + 1);
const filename = sanitizeString(value.substring(value.lastIndexOf('/') + 1).split('.')[0]);
return `${filename}.${extension}`;
};
const ensureDirAsync = async (dir: string, intermediates = true): Promise<void> => { const ensureDirAsync = async (dir: string, intermediates = true): Promise<void> => {
const info = await FileSystem.getInfoAsync(dir); const info = await FileSystem.getInfoAsync(dir);
if (info.exists && info.isDirectory) { if (info.exists && info.isDirectory) {
@ -12,13 +21,14 @@ const ensureDirAsync = async (dir: string, intermediates = true): Promise<void>
return ensureDirAsync(dir, intermediates); return ensureDirAsync(dir, intermediates);
}; };
export const downloadAudioFile = async (url: string, fileUrl: string): Promise<string> => { export const downloadAudioFile = async (url: string, fileUrl: string, messageId: string): Promise<string> => {
let path = ''; let path = '';
try { try {
const serverUrl = store.getState().server.server; const serverUrl = store.getState().server.server;
const serverUrlParsed = serverUrl.substring(serverUrl.lastIndexOf('/') + 1); const serverUrlParsed = sanitizeString(serverUrl);
const folderPath = `${FileSystem.documentDirectory}audios/${serverUrlParsed}`; const folderPath = `${FileSystem.documentDirectory}audios/${serverUrlParsed}`;
const filePath = `${folderPath}/${fileUrl.substring(fileUrl.lastIndexOf('/') + 1)}`; const filename = `${messageId}_${parseFilename(fileUrl)}`;
const filePath = `${folderPath}/${filename}`;
await ensureDirAsync(folderPath); await ensureDirAsync(folderPath);
const file = await FileSystem.getInfoAsync(filePath); const file = await FileSystem.getInfoAsync(filePath);
if (!file.exists) { if (!file.exists) {
@ -35,7 +45,7 @@ export const downloadAudioFile = async (url: string, fileUrl: string): Promise<s
export const deleteAllAudioFiles = async (serverUrl: string): Promise<void> => { export const deleteAllAudioFiles = async (serverUrl: string): Promise<void> => {
try { try {
const serverUrlParsed = serverUrl.substring(serverUrl.lastIndexOf('/') + 1); const serverUrlParsed = sanitizeString(serverUrl);
const path = `${FileSystem.documentDirectory}audios/${serverUrlParsed}`; const path = `${FileSystem.documentDirectory}audios/${serverUrlParsed}`;
await FileSystem.deleteAsync(path); await FileSystem.deleteAsync(path);
} catch (error) { } catch (error) {