mobile: fix file and image upload

This commit is contained in:
ammarahm-ed
2023-07-13 09:55:02 +05:00
committed by Ammar Ahmed
parent 5854a3eef5
commit 4b68a083c5
11 changed files with 342 additions and 336 deletions

View File

@@ -51,6 +51,7 @@ export async function uploadFile(filename, data, cancelToken) {
uploadFilePath = appGroupPath;
}
DatabaseLogger.info(`Starting upload: ${filename}`);
let request = RNFetchBlob.config({
IOSBackgroundTask: !globalThis["IS_SHARE_EXTENSION"]
})
@@ -66,8 +67,11 @@ export async function uploadFile(filename, data, cancelToken) {
useAttachmentStore
.getState()
.setProgress(sent, total, filename, 0, "upload");
DatabaseLogger.info(`uploading file: ${sent}/${total}`);
DatabaseLogger.info(
`File upload progress: ${filename}, ${sent}/${total}`
);
});
cancelToken.cancel = request.cancel;
let response = await request;
@@ -90,7 +94,9 @@ export async function uploadFile(filename, data, cancelToken) {
} else {
const fileInfo = await RNFetchBlob.fs.stat(uploadFilePath);
throw new Error(
`${status}, ${text}, name: ${fileInfo.filename}, length: ${fileInfo}`
`${status}, ${text}, name: ${fileInfo.filename}, length: ${
fileInfo.size
}, info: ${JSON.stringify(response.info())}`
);
}

View File

@@ -17,15 +17,14 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { formatBytes } from "@notesnook/common";
import React from "react";
import { TouchableOpacity, View } from "react-native";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { db } from "../../common/database";
import { useAttachmentProgress } from "../../hooks/use-attachment-progress";
import { useThemeStore } from "../../stores/use-theme-store";
import { formatBytes } from "@notesnook/common";
import { SIZE } from "../../utils/size";
import SheetProvider from "../sheet-provider";
import { IconButton } from "../ui/icon-button";
import { ProgressCircleComponent } from "../ui/svg/lazy";
import Paragraph from "../ui/typography/paragraph";
@@ -41,7 +40,8 @@ export const AttachmentItem = ({
encryption,
setAttachments,
pressable = true,
hideWhenNotDownloading
hideWhenNotDownloading,
context
}) => {
const colors = useThemeStore((state) => state.colors);
const [currentProgress, setCurrentProgress] = useAttachmentProgress(
@@ -51,7 +51,7 @@ export const AttachmentItem = ({
const onPress = () => {
if (!pressable) return;
Actions.present(attachment, setAttachments, attachment.metadata.hash);
Actions.present(attachment, setAttachments, context);
};
return hideWhenNotDownloading &&
@@ -70,7 +70,6 @@ export const AttachmentItem = ({
}}
type="grayBg"
>
<SheetProvider context={attachment.metadata.hash} />
<View
style={{
flexShrink: 1,

View File

@@ -82,7 +82,11 @@ export const AttachmentDialog = ({ note }) => {
};
const renderItem = ({ item }) => (
<AttachmentItem setAttachments={setAttachments} attachment={item} />
<AttachmentItem
setAttachments={setAttachments}
attachment={item}
context="attachments-list"
/>
);
const onCheck = async () => {

View File

@@ -26,7 +26,6 @@
"zustand": "^3.6.0",
"fflate": "^0.7.3",
"timeago.js": "4.0.2",
"react-native-blob-util": "0.17.3",
"react-native-swiper-flatlist": "3.2.2",
"@streetwriters/showdown": "^3.0.1-alpha.2",
"react-native-keyboard-aware-scroll-view": "^0.9.5",

View File

@@ -18,47 +18,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import Sodium from "@ammarahmed/react-native-sodium";
import React from "react";
import { Platform, View } from "react-native";
import { isImage } from "@notesnook/core/utils/filename";
import { Platform } from "react-native";
import RNFetchBlob from "react-native-blob-util";
import DocumentPicker from "react-native-document-picker";
import { launchCamera, launchImageLibrary } from "react-native-image-picker";
import RNFetchBlob from "react-native-blob-util";
import { db } from "../../../common/database";
import { compressToBase64 } from "../../../common/filesystem/compress";
import { AttachmentItem } from "../../../components/attachments/attachment-item";
import {
ToastEvent,
eSendEvent,
presentSheet,
ToastEvent
presentSheet
} from "../../../services/event-manager";
import PremiumService from "../../../services/premium";
import { FILE_SIZE_LIMIT, IMAGE_SIZE_LIMIT } from "../../../utils/constants";
import { eCloseSheet } from "../../../utils/events";
import { editorController, editorState } from "./utils";
import { isImage } from "@notesnook/core/utils/filename";
import { FILE_SIZE_LIMIT, IMAGE_SIZE_LIMIT } from "../../../utils/constants";
const showEncryptionSheet = (file) => {
presentSheet({
title: "Encrypting attachment",
paragraph: "Please wait while we encrypt file for upload",
icon: "attachment",
component: (
<View
style={{
paddingHorizontal: 12
}}
>
<AttachmentItem
attachment={{
metadata: {
filename: file.name
},
length: file.size
}}
encryption
/>
</View>
)
paragraph: `Please wait while we encrypt ${file.name} file for upload`,
icon: "attachment"
});
};

View File

@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import Clipboard from "@react-native-clipboard/clipboard";
import { LogMessage } from "@notesnook/logger";
import { format, LogLevel, logManager } from "@notesnook/core/logger";
import React, { useEffect, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { FlatList, Platform, TouchableOpacity, View } from "react-native";
import * as ScopedStorage from "react-native-scoped-storage";
import RNFetchBlob from "react-native-blob-util";
@@ -55,6 +55,8 @@ import { sanitizeFilename } from "@notesnook/common";
export default function DebugLogs() {
const colors = useThemeStore((state) => state.colors);
const { seconds, start } = useTimer("debug_logs_timer");
const listRef = useRef<FlatList>(null);
const currentOffset = useRef(0);
const [logs, setLogs] = useState<
{
key: string;
@@ -229,6 +231,7 @@ export default function DebugLogs() {
{currentLog && (
<FlatList
ref={listRef}
ListHeaderComponent={
<View
style={{

View File

@@ -299,7 +299,7 @@ PODS:
- React-Core
- react-native-begin-background-task (0.1.0):
- React
- react-native-blob-util (0.17.3):
- react-native-blob-util (0.18.3):
- React-Core
- react-native-config (1.5.1):
- react-native-config/App (= 1.5.1)
@@ -862,7 +862,7 @@ SPEC CHECKSUMS:
react-native-actions-shortcuts: 5d9cf0c9c308333dfcc1e05c3f9afa8c428e2533
react-native-background-actions: 2c251c986f23347f9c1722f05fd296938f60edb1
react-native-begin-background-task: 3b889e07458afc5822a7277cf9cbc7cd077e39ee
react-native-blob-util: 99f4d79189252f597fe0d810c57a3733b1b1dea6
react-native-blob-util: 2d36383bb52c15c5451be81cb7ddf22bc34a12a6
react-native-config: 86038147314e2e6d10ea9972022aa171e6b1d4d8
react-native-date-picker: 93e43b3084cea595b4d68b1405d6d99849663bd6
react-native-document-picker: ec07866a30707f23660c0f3ae591d669d3e89096

View File

@@ -5,9 +5,14 @@
"main": "index.js",
"license": "GPL-3.0-or-later",
"dependencies": {
"@ammarahmed/notifee-react-native": "7.4.4",
"@ammarahmed/react-native-share-extension": "^2.5.5",
"@ammarahmed/react-native-sodium": "1.4.1",
"@bam.tech/react-native-image-resizer": "3.0.5",
"@callstack/repack": "^3.2.0",
"@react-native-clipboard/clipboard": "^1.9.0",
"@react-native-community/checkbox": "^0.5.8",
"@react-native-community/datetimepicker": "6.6.0",
"@react-native-community/netinfo": "^9.3.7",
"@react-native-community/toolbar-android": "^0.2.1",
"@react-native-masked-view/masked-view": "^0.2.6",
@@ -15,12 +20,16 @@
"@react-navigation/native": "^6.0.10",
"@react-navigation/native-stack": "6.6.2",
"@sayem314/react-native-keep-awake": "^1.0.4",
"@shopify/flash-list": "1.4.0",
"react": "18.2.0",
"react-native": "0.72.0",
"react-native-actions-shortcuts": "^1.0.1",
"react-native-background-actions": "^2.6.6",
"react-native-begin-background-task": "https://github.com/blockfirm/react-native-begin-background-task.git",
"react-native-blob-util": "^0.18.3",
"react-native-bootsplash": "4.1.4",
"react-native-config": "^1.4.6",
"react-native-date-picker": "4.2.6",
"react-native-device-info": "^8.4.1",
"react-native-document-picker": "^7.1.1",
"react-native-eventsource": "github:ammarahm-ed/react-native-eventsource",
@@ -29,12 +38,18 @@
"react-native-fingerprint-scanner": "https://github.com/ammarahm-ed/react-native-fingerprint-scanner.git",
"react-native-gesture-handler": "^2.12.0",
"react-native-get-random-values": "^1.7.0",
"react-native-gzip": "1.0.0",
"react-native-html-to-pdf-lite": "^0.9.1",
"react-native-iap": "7.5.6",
"react-native-image-picker": "4.1.2",
"react-native-in-app-review": "4.3.3",
"react-native-keychain": "4.0.5",
"react-native-mmkv-storage": "^0.9.1",
"react-native-modal-datetime-picker": "14.0.0",
"react-native-navigation-bar-color": "2.0.2",
"react-native-notification-sounds": "0.5.5",
"react-native-orientation": "https://github.com/yamill/react-native-orientation.git",
"react-native-pdf": "6.6.2",
"react-native-privacy-snapshot": "https://github.com/standardnotes/react-native-privacy-snapshot.git",
"react-native-reanimated": "3.3.0",
"react-native-safe-area-context": "^4.3.1",
@@ -42,72 +57,57 @@
"react-native-screens": "^3.13.1",
"react-native-securerandom": "^1.0.1",
"react-native-share": "^7.2.0",
"@ammarahmed/react-native-sodium": "1.4.1",
"react-native-svg": "^12.3.0",
"react-native-swiper-flatlist": "3.2.2",
"react-native-tooltips": "^1.0.3",
"react-native-webview": "^11.14.1",
"react-native-gzip":"1.0.0",
"@shopify/flash-list":"1.4.0",
"@ammarahmed/notifee-react-native": "7.4.4",
"react-native-modal-datetime-picker":"14.0.0",
"@react-native-community/datetimepicker":"6.6.0",
"react-native-date-picker": "4.2.6",
"react-native-notification-sounds": "0.5.5",
"@bam.tech/react-native-image-resizer": "3.0.5",
"react-native-navigation-bar-color": "2.0.2",
"react-native-actions-shortcuts": "^1.0.1",
"react-native-zip-archive": "6.0.9",
"react-native-vector-icons": "9.2.0",
"react-native-pdf": "6.6.2",
"react-native-blob-util": "0.17.3",
"@ammarahmed/react-native-share-extension": "^2.5.5",
"react-native-in-app-review": "4.3.3",
"react-native-swiper-flatlist": "3.2.2"
"react-native-webview": "^11.14.1",
"react-native-zip-archive": "6.0.9"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.16.5",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/eslint-config": "^0.72.2",
"@react-native/metro-config": "^0.72.6",
"@tsconfig/react-native": "^3.0.2",
"@types/html-to-text": "^8.0.1",
"@types/jest": "^29.2.1",
"@types/metro-config": "^0.76.3",
"@types/react": "^18.0.24",
"@babel/eslint-parser": "^7.16.5",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5",
"@types/html-to-text": "^8.0.1",
"@types/react-native": "^0.69.1",
"@types/react-native-vector-icons": "^6.4.10",
"@types/react-test-renderer": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.14.0",
"@typescript-eslint/parser": "^5.14.0",
"babel-jest": "^29.2.1",
"babel-loader": "^8.2.5",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-transform-remove-console": "6.9.4",
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@types/jest": "^29.2.1",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.2.1",
"eslint": "^8.19.0",
"jest": "^29.2.1",
"metro-react-native-babel-preset": "0.76.5",
"prettier": "^2.4.1",
"react-test-renderer": "18.2.0",
"typescript": "4.8.4",
"detox": "^19.9.1",
"eslint": "^8.19.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-native": "^4.0.0",
"eslint-plugin-unused-imports": "^2.0.0",
"react-native-actions-shortcuts": "^1.0.1",
"expect": "^28.1.3",
"jest": "^29.2.1",
"jest-circus": "^28.1.3",
"jest-image-snapshot": "^5.1.0",
"metro-react-native-babel-preset": "0.76.5",
"pixelmatch": "^5.3.0",
"prettier": "^2.4.1",
"react-native-actions-shortcuts": "^1.0.1",
"react-native-bundle-visualizer": "^3.1.1",
"react-native-cli-bump-version": "^1.3.0",
"react-refresh": "0.14.0",
"react-test-renderer": "18.2.0",
"terser-webpack-plugin": "^5.3.5",
"ts-jest": "^28.0.7",
"webpack": "^5.74.0",
"react-refresh": "0.14.0"
"typescript": "4.8.4",
"webpack": "^5.74.0"
}
}

View File

@@ -97,6 +97,7 @@ module.exports = (env) => {
"deepmerge": path.join(__dirname, "../node_modules/deepmerge"),
"@selderee/plugin-htmlparser2": path.join(__dirname, "../node_modules/@selderee/plugin-htmlparser2"),
"peberminta": path.join(__dirname, "../node_modules/peberminta"),
"react-native-blob-util": path.join(__dirname, "../node_modules/react-native-blob-util")
},
},
/**
@@ -223,7 +224,7 @@ module.exports = (env) => {
: [
"react-native-reanimated/plugin",
`@babel/plugin-transform-named-capturing-groups-regex`,
"transform-remove-console",
//"transform-remove-console",
],
},
},

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,136 @@
diff --git a/node_modules/react-native-blob-util/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java b/node_modules/react-native-blob-util/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java
index 9aee829..87124b3 100644
--- a/node_modules/react-native-blob-util/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java
+++ b/node_modules/react-native-blob-util/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java
@@ -634,7 +634,9 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
*/
private void done(Response resp) {
boolean isBlobResp = isBlobResponse(resp);
- emitStateEvent(getResponseInfo(resp, isBlobResp));
+ WritableMap map = getResponseInfo(resp,isBlobResp);
+ emitStateEvent(getResponseInfo(resp,isBlobResp));
+
switch (responseType) {
case KeepInMemory:
try {
@@ -652,7 +654,7 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
ins.close();
os.flush();
os.close();
- invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, dest);
+ invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, dest, map);
}
// response data directly pass to JS context as string.
else {
@@ -674,11 +676,11 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
invoke_callback("Error from file transformer:" + e.getLocalizedMessage(), null);
return;
}
- invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, this.destPath);
+ invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, this.destPath,map);
return;
}
if (responseFormat == ResponseFormat.BASE64) {
- invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP));
+ invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP),map);
return;
}
try {
@@ -688,21 +690,21 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
decoder.decode(ByteBuffer.wrap(b));
// If the data contains invalid characters the following lines will be skipped.
String utf8 = new String(b, charSet);
- invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_UTF8, utf8);
+ invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_UTF8, utf8,map);
}
// This usually means the data contains invalid unicode characters but still valid data,
// it's binary data, so send it as a normal string
catch (CharacterCodingException ignored) {
if (responseFormat == ResponseFormat.UTF8) {
String utf8 = new String(b);
- invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_UTF8, utf8);
+ invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_UTF8, utf8,map);
} else {
- invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP));
+ invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP),map);
}
}
}
} catch (IOException e) {
- invoke_callback("ReactNativeBlobUtil failed to encode response data to BASE64 string.", null);
+ invoke_callback("ReactNativeBlobUtil failed to encode response data to BASE64 string.", null,map);
}
break;
case FileStorage:
@@ -742,18 +744,18 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
}
if (ReactNativeBlobUtilFileResp != null && !ReactNativeBlobUtilFileResp.isDownloadComplete()) {
- invoke_callback("Download interrupted.", null);
+ invoke_callback("Download interrupted.", null,map);
} else {
this.destPath = this.destPath.replace("?append=true", "");
- invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, this.destPath);
+ invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, this.destPath,map);
}
break;
default:
try {
- invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_UTF8, new String(resp.body().bytes(), "UTF-8"));
+ invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_UTF8, new String(resp.body().bytes(), "UTF-8"),map);
} catch (IOException e) {
- invoke_callback("ReactNativeBlobUtil failed to encode response data to UTF8 string.", null);
+ invoke_callback("ReactNativeBlobUtil failed to encode response data to UTF8 string.", null,map);
}
break;
}
diff --git a/node_modules/react-native-blob-util/fetch.js b/node_modules/react-native-blob-util/fetch.js
index 97e5263..45c086c 100644
--- a/node_modules/react-native-blob-util/fetch.js
+++ b/node_modules/react-native-blob-util/fetch.js
@@ -244,7 +244,7 @@ export function fetch(...args: any): Promise {
* dose the response data presents.
* @param data {string} Response data or its reference.
*/
- req(options, taskId, method, url, headers || {}, body, (err, rawType, data) => {
+ req(options, taskId, method, url, headers || {}, body, (err, rawType, data, responseInfo) => {
// task done, remove event listeners
subscription.remove();
@@ -270,6 +270,9 @@ export function fetch(...args: any): Promise {
fs.session(options.session).add(data);
}
respInfo.rnfbEncode = rawType;
+ if (respInfo.status === undefined || respInfo.status === null) {
+ respInfo.status = responseInfo?.status
+ }
resolve(new FetchBlobResponse(taskId, respInfo, data));
}
diff --git a/node_modules/react-native-blob-util/ios/ReactNativeBlobUtilRequest.mm b/node_modules/react-native-blob-util/ios/ReactNativeBlobUtilRequest.mm
index d4e468a..25b8d81 100644
--- a/node_modules/react-native-blob-util/ios/ReactNativeBlobUtilRequest.mm
+++ b/node_modules/react-native-blob-util/ios/ReactNativeBlobUtilRequest.mm
@@ -438,13 +438,20 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCom
}
}
+ NSHTTPURLResponse *response = (NSHTTPURLResponse *) [task response];
+
callback(@[
errMsg ?: [NSNull null],
rnfbRespType ?: @"",
- respStr ?: [NSNull null]
+ respStr ?: [NSNull null],
+ @{
+ @"status": [NSNumber numberWithInteger:[response statusCode]]
+ }
]);
+
+
respData = nil;
receivedBytes = 0;
[session finishTasksAndInvalidate];