mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-21 09:38:01 +02:00
161 lines
5.1 KiB
TypeScript
161 lines
5.1 KiB
TypeScript
import { Linking, Platform } from 'react-native';
|
|
import injectedJs from './injectedJs';
|
|
import PoorManIntervals from '@joplin/lib/PoorManIntervals';
|
|
import makeShowMessageBox from '../makeShowMessageBox';
|
|
import { Buffer } from 'buffer';
|
|
import { basename, fileExtension } from '@joplin/utils/path';
|
|
import uuid from '@joplin/lib/uuid';
|
|
import * as mimeUtils from '@joplin/lib/mime-utils';
|
|
import Resource from '@joplin/lib/models/Resource';
|
|
import { getLocales } from 'react-native-localize';
|
|
import type Setting from '@joplin/lib/models/Setting';
|
|
import shim from '@joplin/lib/shim';
|
|
import { closestSupportedLocale, defaultLocale, setLocale } from '@joplin/lib/locale';
|
|
|
|
const shimInitShared = () => {
|
|
shim.sjclModule = require('@joplin/lib/vendor/sjcl-rn.js');
|
|
|
|
shim.stringByteLength = function(string) {
|
|
return Buffer.byteLength(string, 'utf-8');
|
|
};
|
|
|
|
shim.Buffer = Buffer;
|
|
|
|
shim.stringByteLength = function(string) {
|
|
return Buffer.byteLength(string, 'utf-8');
|
|
};
|
|
|
|
shim.fetch = async function(url, options = null) {
|
|
// The native fetch() throws an uncatchable error that crashes the
|
|
// app if calling it with an invalid URL such as '//.resource' or
|
|
// "http://ocloud. de" so detect if the URL is valid beforehand and
|
|
// throw a catchable error. Bug:
|
|
// https://github.com/facebook/react-native/issues/7436
|
|
let validatedUrl = '';
|
|
try { // Check if the url is valid
|
|
validatedUrl = new URL(url).href;
|
|
} catch (error) { // If the url is not valid, a TypeError will be thrown
|
|
throw new Error(`Not a valid URL: ${url}`);
|
|
}
|
|
|
|
return shim.fetchWithRetry(() => {
|
|
// If the request has a body and it's not a GET call, and it
|
|
// doesn't have a Content-Type header we display a warning,
|
|
// because it could trigger a "Network request failed" error.
|
|
// https://github.com/facebook/react-native/issues/30176
|
|
if (options?.body && options?.method && options.method !== 'GET' && !options?.headers?.['Content-Type']) {
|
|
console.warn('Done a non-GET fetch call without a Content-Type header. It may make the request fail.', url, options);
|
|
}
|
|
|
|
// Among React Native `fetch()` many bugs, one of them is that
|
|
// it will truncate strings when they contain binary data.
|
|
// Browser fetch() or Node fetch() work fine but as always RN's
|
|
// one doesn't. There's no obvious way to fix this so we'll
|
|
// have to wait if it's eventually fixed upstream. See here for
|
|
// more info:
|
|
// https://github.com/laurent22/joplin/issues/3986#issuecomment-718019688
|
|
|
|
return fetch(validatedUrl, options);
|
|
}, options);
|
|
};
|
|
|
|
shim.openUrl = url => {
|
|
return Linking.openURL(url);
|
|
};
|
|
|
|
shim.showMessageBox = makeShowMessageBox(null);
|
|
|
|
shim.waitForFrame = () => {
|
|
return new Promise<void>((resolve) => {
|
|
requestAnimationFrame(() => {
|
|
resolve();
|
|
});
|
|
});
|
|
};
|
|
|
|
shim.mobilePlatform = () => {
|
|
return Platform.OS;
|
|
};
|
|
|
|
shim.injectedJs = function(name) {
|
|
if (!(name in injectedJs)) throw new Error(`Cannot find injectedJs file (add it to "injectedJs" object): ${name}`);
|
|
return injectedJs[name as keyof typeof injectedJs];
|
|
};
|
|
|
|
shim.setTimeout = (fn, interval) => {
|
|
return PoorManIntervals.setTimeout(fn, interval);
|
|
};
|
|
|
|
shim.setInterval = (fn, interval) => {
|
|
return PoorManIntervals.setInterval(fn, interval);
|
|
};
|
|
|
|
shim.clearTimeout = (id) => {
|
|
return PoorManIntervals.clearTimeout(id);
|
|
};
|
|
|
|
shim.clearInterval = (id) => {
|
|
return PoorManIntervals.clearInterval(id);
|
|
};
|
|
|
|
// NOTE: This is a limited version of createResourceFromPath - unlike the Node version, it
|
|
// only really works with images. It does not resize the image either.
|
|
shim.createResourceFromPath = async function(filePath, defaultProps = undefined) {
|
|
defaultProps = defaultProps ? defaultProps : {};
|
|
const resourceId = defaultProps.id ? defaultProps.id : uuid.create();
|
|
|
|
const ext = fileExtension(filePath);
|
|
let mimeType = mimeUtils.fromFileExtension(ext);
|
|
if (!mimeType) mimeType = 'image/jpeg';
|
|
|
|
let resource = Resource.new();
|
|
resource.id = resourceId;
|
|
resource.mime = mimeType;
|
|
resource.title = basename(filePath);
|
|
resource.file_extension = ext;
|
|
|
|
const targetPath = Resource.fullPath(resource);
|
|
await shim.fsDriver().copy(filePath, targetPath);
|
|
|
|
if (defaultProps) {
|
|
resource = { ...resource, ...defaultProps };
|
|
}
|
|
|
|
const itDoes = await shim.fsDriver().waitTillExists(targetPath);
|
|
if (!itDoes) throw new Error(`Resource file was not created: ${targetPath}`);
|
|
|
|
const fileStat = await shim.fsDriver().stat(targetPath);
|
|
resource.size = fileStat.size;
|
|
|
|
resource = await Resource.save(resource, { isNew: true });
|
|
|
|
return resource;
|
|
};
|
|
|
|
shim.detectAndSetLocale = (settings: typeof Setting) => {
|
|
// [
|
|
// {
|
|
// "countryCode": "US",
|
|
// "isRTL": false,
|
|
// "languageCode": "fr",
|
|
// "languageTag": "fr-US"
|
|
// },
|
|
// {
|
|
// "countryCode": "US",
|
|
// "isRTL": false,
|
|
// "languageCode": "en",
|
|
// "languageTag": "en-US"
|
|
// }
|
|
// ]
|
|
|
|
const locales = getLocales();
|
|
let locale = locales.length ? locales[0].languageTag : defaultLocale();
|
|
locale = closestSupportedLocale(locale);
|
|
settings.setValue('locale', locale);
|
|
setLocale(locale);
|
|
return locale;
|
|
};
|
|
};
|
|
|
|
export default shimInitShared;
|