[FIX] Fix filenames and servers url when downloading audio files (#4553)
This commit is contained in:
parent
5771dbd066
commit
d1e2c3fe6d
|
@ -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}</>;
|
||||||
},
|
},
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue