1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Mobile: Fixed mobile build

This commit is contained in:
Laurent Cozic 2021-01-27 17:42:58 +00:00
parent 35597ce3c2
commit 12187b9da3
24 changed files with 1247 additions and 79 deletions

View File

@ -664,6 +664,9 @@ packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js.map
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.d.ts
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js.map
packages/app-desktop/utils/markupLanguageUtils.d.ts
packages/app-desktop/utils/markupLanguageUtils.js
packages/app-desktop/utils/markupLanguageUtils.js.map
packages/app-mobile/PluginAssetsLoader.d.ts
packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/PluginAssetsLoader.js.map
@ -712,6 +715,9 @@ packages/app-mobile/utils/ShareExtension.js.map
packages/app-mobile/utils/checkPermissions.d.ts
packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/checkPermissions.js.map
packages/app-mobile/utils/fs-driver-rn.d.ts
packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/fs-driver-rn.js.map
packages/app-mobile/utils/shareHandler.d.ts
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/shareHandler.js.map

6
.gitignore vendored
View File

@ -651,6 +651,9 @@ packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js.map
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.d.ts
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js.map
packages/app-desktop/utils/markupLanguageUtils.d.ts
packages/app-desktop/utils/markupLanguageUtils.js
packages/app-desktop/utils/markupLanguageUtils.js.map
packages/app-mobile/PluginAssetsLoader.d.ts
packages/app-mobile/PluginAssetsLoader.js
packages/app-mobile/PluginAssetsLoader.js.map
@ -699,6 +702,9 @@ packages/app-mobile/utils/ShareExtension.js.map
packages/app-mobile/utils/checkPermissions.d.ts
packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/checkPermissions.js.map
packages/app-mobile/utils/fs-driver-rn.d.ts
packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/fs-driver-rn.js.map
packages/app-mobile/utils/shareHandler.d.ts
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/shareHandler.js.map

1095
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,8 @@
"buildTranslations": "npm run tsc && node packages/tools/build-translation.js",
"buildTranslationsNoTsc": "node packages/tools/build-translation.js",
"buildWebsite": "npm run buildApiDoc && node ./packages/tools/build-website.js && npm run buildPluginDoc",
"circularDependencyCheck": "npx madge --warning --circular --extensions js ./",
"circularDependencyCheck": "madge --warning --circular --extensions js ./",
"dependencyTree": "madge",
"clean": "lerna clean -y && lerna run clean",
"generateDatabaseTypes": "node packages/tools/generate-database-types",
"linkChecker": "linkchecker https://joplinapp.org",
@ -60,6 +61,7 @@
"husky": "^3.0.2",
"lerna": "^3.22.1",
"lint-staged": "^9.2.1",
"madge": "^4.0.0",
"typedoc": "^0.17.8",
"typescript": "^4.0.5"
}

View File

@ -4,7 +4,7 @@ import { _ } from '@joplin/lib/locale';
const { themeStyle } = require('@joplin/lib/theme');
const DialogButtonRow = require('./DialogButtonRow.min');
const Countable = require('countable');
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils';
import markupLanguageUtils from '../utils/markupLanguageUtils';
interface NoteContentPropertiesDialogProps {
themeId: number;

View File

@ -25,7 +25,7 @@ import ToolbarButtonUtils from '@joplin/lib/services/commands/ToolbarButtonUtils
import { _ } from '@joplin/lib/locale';
import TagList from '../TagList';
import NoteTitleBar from './NoteTitle/NoteTitleBar';
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils';
import markupLanguageUtils from '../../utils/markupLanguageUtils';
import usePrevious from '../hooks/usePrevious';
import Setting from '@joplin/lib/models/Setting';
import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext';

View File

@ -1,7 +1,7 @@
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
import { useCallback, useMemo } from 'react';
import { ResourceInfos } from './types';
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils';
import markupLanguageUtils from '../../../utils/markupLanguageUtils';
import Setting from '@joplin/lib/models/Setting';
const { themeStyle } = require('@joplin/lib/theme');

View File

@ -15,7 +15,7 @@ const time = require('@joplin/lib/time').default;
const ReactTooltip = require('react-tooltip');
const { urlDecode, substrWithEllipsis } = require('@joplin/lib/string-utils');
const bridge = require('electron').remote.require('./bridge').default;
const markupLanguageUtils = require('@joplin/lib/markupLanguageUtils').default;
const markupLanguageUtils = require('../utils/markupLanguageUtils').default;
class NoteRevisionViewerComponent extends React.PureComponent {
constructor() {

View File

@ -16,7 +16,7 @@ const { ItemList } = require('../gui/ItemList.min');
const HelpButton = require('../gui/HelpButton.min');
const { surroundKeywords, nextWhitespaceIndex, removeDiacritics } = require('@joplin/lib/string-utils.js');
const { mergeOverlappingIntervals } = require('@joplin/lib/ArrayUtils.js');
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils';
import markupLanguageUtils from '../utils/markupLanguageUtils';
const PLUGIN_NAME = 'gotoAnything';

View File

@ -0,0 +1,18 @@
import { MarkupLanguageUtils as BaseMarkupLanguageUtils } from '@joplin/lib/markupLanguageUtils';
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
import { contentScriptsToRendererRules } from '@joplin/lib/services/plugins/utils/loadContentScripts';
class MarkupLanguageUtils extends BaseMarkupLanguageUtils {
public newMarkupToHtml(plugins: PluginStates, options: any = null) {
return super.newMarkupToHtml({
extraRendererRules: contentScriptsToRendererRules(plugins),
...options,
});
}
}
const markupLanguageUtils = new MarkupLanguageUtils();
export default markupLanguageUtils;

View File

@ -38,7 +38,7 @@ export default function useSource(noteBody: string, noteMarkupLanguage: number,
}, [themeId, paddingBottom]);
const markupToHtml = useMemo(() => {
return markupLanguageUtils.newMarkupToHtml({});
return markupLanguageUtils.newMarkupToHtml();
}, [isFirstRender]);
// To address https://github.com/laurent22/joplin/issues/433

View File

@ -30,7 +30,7 @@ import SyncTargetOneDrive from '@joplin/lib/SyncTargetOneDrive';
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar } = require('react-native');
const DropdownAlert = require('react-native-dropdownalert').default;
const AlarmServiceDriver = require('./services/AlarmServiceDriver');
const AlarmServiceDriver = require('./services/AlarmServiceDriver').default;
const SafeAreaView = require('./components/SafeAreaView');
const { connect, Provider } = require('react-redux');
const { BackButtonService } = require('./services/back-button.js');
@ -90,7 +90,7 @@ SyncTargetRegistry.addClass(SyncTargetFilesystem);
SyncTargetRegistry.addClass(SyncTargetAmazonS3);
SyncTargetRegistry.addClass(SyncTargetJoplinServer);
const FsDriverRN = require('./utils/fs-driver-rn.js').FsDriverRN;
import FsDriverRN from './utils/fs-driver-rn';
import DecryptionWorker from '@joplin/lib/services/DecryptionWorker';
import EncryptionService from '@joplin/lib/services/EncryptionService';
import MigrationService from '@joplin/lib/services/MigrationService';

View File

@ -1,40 +1,40 @@
const RNFS = require('react-native-fs');
const FsDriverBase = require('@joplin/lib/fs-driver-base').default;
import FsDriverBase from '@joplin/lib/fs-driver-base';
const RNFetchBlob = require('rn-fetch-blob').default;
const RNFS = require('react-native-fs');
const { Writable } = require('stream-browserify');
const { Buffer } = require('buffer');
class FsDriverRN extends FsDriverBase {
appendFileSync() {
export default class FsDriverRN extends FsDriverBase {
public appendFileSync() {
throw new Error('Not implemented');
}
// Encoding can be either "utf8" or "base64"
appendFile(path, content, encoding = 'base64') {
public appendFile(path: string, content: any, encoding = 'base64') {
return RNFS.appendFile(path, content, encoding);
}
// Encoding can be either "utf8" or "base64"
writeFile(path, content, encoding = 'base64') {
public writeFile(path: string, content: any, encoding = 'base64') {
// We need to use rn-fetch-blob here due to this bug:
// https://github.com/itinance/react-native-fs/issues/700
return RNFetchBlob.fs.writeFile(path, content, encoding);
}
// same as rm -rf
async remove(path) {
public async remove(path: string) {
return await this.unlink(path);
}
writeBinaryFile(path, content) {
public writeBinaryFile(path: string, content: any) {
const buffer = Buffer.from(content);
return RNFetchBlob.fs.writeStream(path, 'base64').then(stream => {
return RNFetchBlob.fs.writeStream(path, 'base64').then((stream: any) => {
const fileStream = new Writable({
write(chunk, encoding, callback) {
write(chunk: any, _encoding: any, callback: Function) {
this.stream.write(chunk.toString('base64'));
callback();
},
final(callback) {
final(callback: Function) {
this.stream.close();
callback();
},
@ -48,7 +48,7 @@ class FsDriverRN extends FsDriverBase {
}
// Returns a format compatible with Node.js format
rnfsStatToStd_(stat, path) {
private rnfsStatToStd_(stat: any, path: string) {
return {
birthtime: stat.ctime ? stat.ctime : stat.mtime, // Confusingly, "ctime" normally means "change time" but here it's used as "creation time". Also sometimes it is null
mtime: stat.mtime,
@ -58,7 +58,7 @@ class FsDriverRN extends FsDriverBase {
};
}
async readDirStats(path, options = null) {
public async readDirStats(path: string, options: any = null) {
if (!options) options = {};
if (!('recursive' in options)) options.recursive = false;
@ -69,7 +69,7 @@ class FsDriverRN extends FsDriverBase {
throw new Error(`Could not read directory: ${path}: ${error.message}`);
}
let output = [];
let output: any[] = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];
const relativePath = item.path.substr(path.length + 1);
@ -80,19 +80,19 @@ class FsDriverRN extends FsDriverBase {
return output;
}
async move(source, dest) {
public async move(source: string, dest: string) {
return RNFS.moveFile(source, dest);
}
async exists(path) {
public async exists(path: string) {
return RNFS.exists(path);
}
async mkdir(path) {
public async mkdir(path: string) {
return RNFS.mkdir(path);
}
async stat(path) {
public async stat(path: string) {
try {
const r = await RNFS.stat(path);
return this.rnfsStatToStd_(r, path);
@ -111,11 +111,11 @@ class FsDriverRN extends FsDriverBase {
// arguments but the function returns `false` and the timestamp is not set.
// Current setTimestamp is not really used so keep it that way, but careful if it
// becomes needed.
async setTimestamp() {
public async setTimestamp() {
// return RNFS.touch(path, timestampDate, timestampDate);
}
async open(path, mode) {
public async open(path: string, mode: number) {
// Note: RNFS.read() doesn't provide any way to know if the end of file has been reached.
// So instead we stat the file here and use stat.size to manually check for end of file.
// Bug: https://github.com/itinance/react-native-fs/issues/342
@ -128,17 +128,17 @@ class FsDriverRN extends FsDriverBase {
};
}
close() {
return null;
public close(): void {
// Nothing
}
readFile(path, encoding = 'utf8') {
public readFile(path: string, encoding = 'utf8') {
if (encoding === 'Buffer') throw new Error('Raw buffer output not supported for FsDriverRN.readFile');
return RNFS.readFile(path, encoding);
}
// Always overwrite destination
async copy(source, dest) {
public async copy(source: string, dest: string) {
let retry = false;
try {
await RNFS.copyFile(source, dest);
@ -151,7 +151,7 @@ class FsDriverRN extends FsDriverBase {
if (retry) await RNFS.copyFile(source, dest);
}
async unlink(path) {
public async unlink(path: string) {
try {
await RNFS.unlink(path);
} catch (error) {
@ -164,7 +164,7 @@ class FsDriverRN extends FsDriverBase {
}
}
async readFileChunk(handle, length, encoding = 'base64') {
public async readFileChunk(handle: any, length: number, encoding = 'base64') {
if (handle.offset + length > handle.stat.size) {
length = handle.stat.size - handle.offset;
}
@ -176,13 +176,15 @@ class FsDriverRN extends FsDriverBase {
return output ? output : null;
}
resolve(path) {
public resolve(path: string) {
throw new Error(`Not implemented: resolve(): ${path}`);
}
resolveRelativePathWithinDir(_baseDir, relativePath) {
public resolveRelativePathWithinDir(_baseDir: string, relativePath: string) {
throw new Error(`Not implemented: resolveRelativePathWithinDir(): ${relativePath}`);
}
}
module.exports.FsDriverRN = FsDriverRN;
public async md5File(path: string): Promise<string> {
throw new Error(`Not implemented: md5File(): ${path}`);
}
}

View File

@ -3,7 +3,7 @@ const { GeolocationReact } = require('./geolocation-react.js');
const PoorManIntervals = require('@joplin/lib/PoorManIntervals').default;
const RNFetchBlob = require('rn-fetch-blob').default;
const { generateSecureRandom } = require('react-native-securerandom');
const FsDriverRN = require('./fs-driver-rn.js').FsDriverRN;
const FsDriverRN = require('./fs-driver-rn').default;
const urlValidator = require('valid-url');
const { Buffer } = require('buffer');
const { Linking, Platform } = require('react-native');

View File

@ -118,4 +118,12 @@ export default class FsDriverBase {
};
}
public async tarExtract(_options: any) {
throw new Error('Not implemented');
}
public async tarCreate(_options: any, _filePaths: string[]) {
throw new Error('Not implemented');
}
}

View File

@ -1,7 +1,7 @@
import { resolve as nodeResolve } from 'path';
import FsDriverBase, { Stat } from './fs-driver-base';
import time from './time';
const md5File = require('md5-file/promise');
const fs = require('fs-extra');
export default class FsDriverNode extends FsDriverBase {
@ -206,4 +206,16 @@ export default class FsDriverNode extends FsDriverBase {
return resolvedPath;
}
public async md5File(path: string): Promise<string> {
return md5File(path);
}
public async tarExtract(options: any) {
await require('tar').extract(options);
}
public async tarCreate(options: any, filePaths: string[]) {
await require('tar').create(options, filePaths);
}
}

View File

@ -2,26 +2,24 @@ import markdownUtils from './markdownUtils';
import Setting from './models/Setting';
import shim from './shim';
import MarkupToHtml, { MarkupLanguage } from '@joplin/renderer/MarkupToHtml';
import { PluginStates } from './services/plugins/reducer';
import { contentScriptsToRendererRules } from './services/plugins/utils/loadContentScripts';
const htmlUtils = require('./htmlUtils');
import Resource from './models/Resource';
class MarkupLanguageUtils {
lib_(language: MarkupLanguage) {
export class MarkupLanguageUtils {
private lib_(language: MarkupLanguage) {
if (language === MarkupLanguage.Html) return htmlUtils;
if (language === MarkupLanguage.Markdown) return markdownUtils;
throw new Error(`Unsupported markup language: ${language}`);
}
extractImageUrls(language: MarkupLanguage, text: string) {
public extractImageUrls(language: MarkupLanguage, text: string) {
return this.lib_(language).extractImageUrls(text);
}
// Create a new MarkupToHtml instance while injecting options specific to Joplin
// desktop and mobile applications.
newMarkupToHtml(plugins: PluginStates, options: any = null) {
public newMarkupToHtml(options: any = null) {
const subValues = Setting.subValues('markdown.plugin', Setting.toPlainObject());
const pluginOptions: any = {};
for (const n in subValues) {
@ -33,7 +31,6 @@ class MarkupLanguageUtils {
pluginOptions: pluginOptions,
tempDir: Setting.value('tempDir'),
fsDriver: shim.fsDriver(),
extraRendererRules: contentScriptsToRendererRules(plugins),
}, options);
return new MarkupToHtml(options);

View File

@ -198,7 +198,7 @@ export default class InteropService {
if (moduleMetadata.isCustom) {
output = this.newModuleFromCustomFactory(moduleMetadata);
} else {
const ModuleClass = require(this.modulePath(moduleMetadata)).default;
const ModuleClass = shim.requireDynamic(this.modulePath(moduleMetadata)).default;
output = new ModuleClass();
}
@ -225,7 +225,7 @@ export default class InteropService {
output = this.newModuleFromCustomFactory(moduleMetadata);
} else {
const modulePath = this.modulePath(moduleMetadata);
const ModuleClass = require(modulePath).default;
const ModuleClass = shim.requireDynamic(modulePath).default;
output = new ModuleClass();
}
@ -248,7 +248,7 @@ export default class InteropService {
// if (moduleMetadata.isCustom) {
// output = this.newModuleFromCustomFactory(moduleMetadata);
// } else {
// const ModuleClass = require(modulePath).default;
// const ModuleClass = shim.requireDynamic(modulePath).default;
// output = new ModuleClass();
// }

View File

@ -7,6 +7,7 @@ import Note from '../../models/Note';
import Setting from '../../models/Setting';
import { MarkupToHtml } from '@joplin/renderer';
import { ResourceEntity } from '../database/types';
import { contentScriptsToRendererRules } from '../plugins/utils/loadContentScripts';
const { basename, friendlySafeFilename, rtrimSlashes } = require('../../path-utils');
const { themeStyle } = require('../../theme');
const { dirname } = require('../../path-utils');
@ -38,7 +39,9 @@ export default class InteropService_Exporter_Html extends InteropService_Exporte
this.resourceDir_ = this.destDir_ ? `${this.destDir_}/_resources` : null;
await shim.fsDriver().mkdir(this.destDir_);
this.markupToHtml_ = markupLanguageUtils.newMarkupToHtml(options.plugins);
this.markupToHtml_ = markupLanguageUtils.newMarkupToHtml({
extraRendererRules: contentScriptsToRendererRules(options.plugins),
});
this.style_ = themeStyle(Setting.THEME_LIGHT);
}

View File

@ -34,15 +34,12 @@ export default class InteropService_Exporter_Jex extends InteropService_Exporter
if (!filePaths.length) throw new Error(_('There is no data to export.'));
await require('tar').create(
{
strict: true,
portable: true,
file: this.destPath_,
cwd: this.tempDir_,
},
filePaths
);
await shim.fsDriver().tarCreate({
strict: true,
portable: true,
file: this.destPath_,
cwd: this.tempDir_,
}, filePaths);
await fs.remove(this.tempDir_);
}

View File

@ -3,6 +3,8 @@ import { ImportExportResult } from './types';
import InteropService_Importer_Base from './InteropService_Importer_Base';
import InteropService_Importer_Raw from './InteropService_Importer_Raw';
const { filename } = require('../../path-utils');
import shim from '../../shim';
const fs = require('fs-extra');
export default class InteropService_Importer_Jex extends InteropService_Importer_Base {
@ -10,7 +12,7 @@ export default class InteropService_Importer_Jex extends InteropService_Importer
const tempDir = await this.temporaryDirectory_(true);
try {
await require('tar').extract({
await shim.fsDriver().tarExtract({
strict: true,
portable: true,
file: this.sourcePath_,

View File

@ -11,7 +11,6 @@ import RepositoryApi from './RepositoryApi';
import produce from 'immer';
const compareVersions = require('compare-versions');
const uslug = require('uslug');
const md5File = require('md5-file/promise');
const logger = Logger.create('PluginService');
@ -183,7 +182,7 @@ export default class PluginService extends BaseService {
baseDir = rtrimSlashes(baseDir);
const fname = filename(path);
const hash = await md5File(path);
const hash = await shim.fsDriver().md5File(path);
const unpackDir = `${Setting.value('cacheDir')}/${fname}`;
const manifestFilePath = `${unpackDir}/manifest.json`;
@ -194,7 +193,7 @@ export default class PluginService extends BaseService {
await shim.fsDriver().remove(unpackDir);
await shim.fsDriver().mkdir(unpackDir);
await require('tar').extract({
await shim.fsDriver().tarExtract({
strict: true,
portable: true,
file: path,

View File

@ -4,7 +4,7 @@ import Joplin from './Joplin';
/**
* @ignore
*/
const builtinModules = require('builtin-modules');
// const builtinModules = require('builtin-modules');
/**
* @ignore
@ -12,7 +12,7 @@ const builtinModules = require('builtin-modules');
export default class Global {
private joplin_: Joplin;
private requireWhiteList_: string[] = null;
// private requireWhiteList_: string[] = null;
// private consoleWrapper_:any = null;
constructor(implementation: any, plugin: Plugin, store: any) {
@ -40,22 +40,22 @@ export default class Global {
return this.joplin_;
}
private requireWhiteList(): string[] {
if (!this.requireWhiteList_) {
this.requireWhiteList_ = builtinModules.slice();
this.requireWhiteList_.push('fs-extra');
}
return this.requireWhiteList_;
}
// private requireWhiteList(): string[] {
// if (!this.requireWhiteList_) {
// this.requireWhiteList_ = builtinModules.slice();
// this.requireWhiteList_.push('fs-extra');
// }
// return this.requireWhiteList_;
// }
// get console(): any {
// return this.consoleWrapper_;
// }
require(filePath: string): any {
if (!this.requireWhiteList().includes(filePath)) throw new Error(`Path not allowed: ${filePath}`);
return require(filePath);
}
// require(filePath: string): any {
// if (!this.requireWhiteList().includes(filePath)) throw new Error(`Path not allowed: ${filePath}`);
// return require(filePath);
// }
// To get webpack to work with Node module we need to set the parameter `target: "node"`, however
// when setting this, the code generated by webpack will try to access the `process` global variable,

View File

@ -1,3 +1,5 @@
'use strict';
const fs = require('fs-extra');
const shim = require('./shim').default;
const { GeolocationNode } = require('./geolocation-node.js');
@ -23,6 +25,15 @@ function fileExists(filePath) {
}
}
// https://github.com/sindresorhus/callsites/blob/main/index.js
function callsites() {
const _prepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = (_any, stack) => stack;
const stack = new Error().stack.slice(1);
Error.prepareStackTrace = _prepareStackTrace;
return stack;
}
const gunzipFile = function(source, destination) {
if (!fileExists(source)) {
throw new Error(`No such file: ${source}`);
@ -535,7 +546,17 @@ function shimInit(sharp = null, keytar = null, React = null) {
};
shim.requireDynamic = (path) => {
return require(path);
if (path.indexOf('.') === 0) {
const sites = callsites();
if (sites.length <= 1) throw new Error(`Cannot require file (1) ${path}`);
const filename = sites[1].getFileName();
if (!filename) throw new Error(`Cannot require file (2) ${path}`);
const fileDirName = require('path').dirname(filename);
return require(`${fileDirName}/${path}`);
} else {
return require(path);
}
};
}