mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Resize images
This commit is contained in:
parent
19266206f4
commit
303af9004d
@ -14,6 +14,8 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.0.3\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
|
||||
msgid "No notebook selected."
|
||||
msgstr "Aucun carnet n'est sélectionné."
|
||||
@ -577,7 +579,7 @@ msgstr ""
|
||||
"(+)."
|
||||
|
||||
msgid "Welcome"
|
||||
msgstr "Bienvenu"
|
||||
msgstr "Bienvenue"
|
||||
|
||||
#~ msgid "NAME"
|
||||
#~ msgstr "NOM"
|
||||
|
@ -137,6 +137,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-image-resizer')
|
||||
compile project(':react-native-fs')
|
||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||
compile "com.android.support:appcompat-v7:23.0.1"
|
||||
@ -144,6 +145,7 @@ dependencies {
|
||||
compile project(':react-native-sqlite-storage')
|
||||
compile project(':react-native-fetch-blob')
|
||||
compile project(':react-native-document-picker')
|
||||
compile project(':react-native-image-resizer')
|
||||
}
|
||||
|
||||
// Run this once to be able to run the application with BUCK
|
||||
|
@ -11,6 +11,7 @@ import com.facebook.soloader.SoLoader;
|
||||
import org.pgsqlite.SQLitePluginPackage;
|
||||
import com.RNFetchBlob.RNFetchBlobPackage;
|
||||
import com.reactnativedocumentpicker.ReactNativeDocumentPicker;
|
||||
import fr.bamlab.rnimageresizer.ImageResizerPackage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -30,7 +31,8 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
new MainReactPackage(),
|
||||
new RNFSPackage(),
|
||||
new RNFetchBlobPackage(),
|
||||
new ReactNativeDocumentPicker()
|
||||
new ReactNativeDocumentPicker(),
|
||||
new ImageResizerPackage()
|
||||
);
|
||||
}
|
||||
};
|
@ -1,4 +1,6 @@
|
||||
rootProject.name = 'Joplin'
|
||||
include ':react-native-image-resizer'
|
||||
project(':react-native-image-resizer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-resizer/android')
|
||||
include ':react-native-fs'
|
||||
project(':react-native-fs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fs/android')
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
||||
EA51DDC9EBFC469F8214B3AD /* libRNFS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8E646D13B9444DE81EC441D /* libRNFS.a */; };
|
||||
628436ED66784ABE86A775AE /* libRCTImageResizer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B8E2583D2B6447DB35F295C /* libRCTImageResizer.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -257,6 +258,8 @@
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
|
||||
8C2AA97067234408AD5BFD90 /* RNFS.xcodeproj */ = {isa = PBXFileReference; name = "RNFS.xcodeproj"; path = "../node_modules/react-native-fs/RNFS.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
|
||||
A8E646D13B9444DE81EC441D /* libRNFS.a */ = {isa = PBXFileReference; name = "libRNFS.a"; path = "libRNFS.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
|
||||
8FB22B82988847ED8E7C0976 /* RCTImageResizer.xcodeproj */ = {isa = PBXFileReference; name = "RCTImageResizer.xcodeproj"; path = "../node_modules/react-native-image-resizer/ios/RCTImageResizer.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
|
||||
9B8E2583D2B6447DB35F295C /* libRCTImageResizer.a */ = {isa = PBXFileReference; name = "libRCTImageResizer.a"; path = "libRCTImageResizer.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -284,6 +287,7 @@
|
||||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
|
||||
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
|
||||
EA51DDC9EBFC469F8214B3AD /* libRNFS.a in Frameworks */,
|
||||
628436ED66784ABE86A775AE /* libRCTImageResizer.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -451,6 +455,7 @@
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
|
||||
8C2AA97067234408AD5BFD90 /* RNFS.xcodeproj */,
|
||||
8FB22B82988847ED8E7C0976 /* RCTImageResizer.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@ -979,10 +984,12 @@
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)\..\node_modules\react-native-image-resizer\ios\RCTImageResizer",
|
||||
);
|
||||
};
|
||||
name = Debug;
|
||||
@ -1004,10 +1011,12 @@
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)\..\node_modules\react-native-image-resizer\ios\RCTImageResizer",
|
||||
);
|
||||
};
|
||||
name = Release;
|
||||
@ -1030,6 +1039,7 @@
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)\..\node_modules\react-native-image-resizer\ios\RCTImageResizer",
|
||||
);
|
||||
};
|
||||
name = Debug;
|
||||
@ -1051,6 +1061,7 @@
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)\..\node_modules\react-native-image-resizer\ios\RCTImageResizer",
|
||||
);
|
||||
};
|
||||
name = Release;
|
||||
@ -1081,10 +1092,12 @@
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)\..\node_modules\react-native-image-resizer\ios\RCTImageResizer",
|
||||
);
|
||||
};
|
||||
name = Debug;
|
||||
@ -1115,10 +1128,12 @@
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/react-native-fs/**",
|
||||
"$(SRCROOT)\..\node_modules\react-native-image-resizer\ios\RCTImageResizer",
|
||||
);
|
||||
};
|
||||
name = Release;
|
||||
@ -1144,6 +1159,7 @@
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
};
|
||||
name = Debug;
|
||||
@ -1169,6 +1185,7 @@
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
};
|
||||
name = Release;
|
||||
|
@ -129,7 +129,7 @@ class NoteBodyViewer extends Component {
|
||||
const mime = r.mime.toLowerCase();
|
||||
if (mime == 'image/png' || mime == 'image/jpg' || mime == 'image/jpeg' || mime == 'image/gif') {
|
||||
const src = 'data:' + r.mime + ';base64,' + r.base64;
|
||||
let output = '<img title="' + htmlentities(title) + '" src="' + htmlentities(src) + '"/>';
|
||||
let output = '<img title="' + htmlentities(title) + '" src="' + src + '"/>';
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { BackHandler, View, Button, TextInput, WebView, Text, StyleSheet, Linking } from 'react-native';
|
||||
import { BackHandler, View, Button, TextInput, WebView, Text, StyleSheet, Linking, Image } from 'react-native';
|
||||
import { connect } from 'react-redux'
|
||||
import { uuid } from 'lib/uuid.js';
|
||||
import { Log } from 'lib/log.js'
|
||||
@ -22,7 +22,7 @@ import DialogBox from 'react-native-dialogbox';
|
||||
import { NoteBodyViewer } from 'lib/components/note-body-viewer.js';
|
||||
import RNFetchBlob from 'react-native-fetch-blob';
|
||||
import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker';
|
||||
|
||||
import ImageResizer from 'react-native-image-resizer';
|
||||
|
||||
class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
@ -100,6 +100,11 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
paddingTop: theme.marginTop,
|
||||
paddingBottom: theme.marginBottom,
|
||||
},
|
||||
metadata: {
|
||||
paddingLeft: globalStyle.marginLeft,
|
||||
paddingRight: globalStyle.marginRight,
|
||||
color: theme.color,
|
||||
},
|
||||
};
|
||||
|
||||
styles.titleContainer = {
|
||||
@ -264,9 +269,22 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
});
|
||||
}
|
||||
|
||||
async imageDimensions(uri) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Image.getSize(uri, (width, height) => {
|
||||
resolve({ width: width, height: height });
|
||||
}, (error) => { reject(error) });
|
||||
});
|
||||
}
|
||||
|
||||
async attachFile_onPress() {
|
||||
const res = await this.pickDocument();
|
||||
|
||||
const localFilePath = res.uri;
|
||||
|
||||
reg.logger().info('Got file: ' + localFilePath);
|
||||
reg.logger().info('Got type: ' + res.type);
|
||||
|
||||
// res.uri,
|
||||
// res.type, // mime type
|
||||
// res.fileName,
|
||||
@ -277,16 +295,42 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
resource.mime = res.type;
|
||||
resource.title = res.fileName ? res.fileName : _('Untitled');
|
||||
|
||||
const targetPath = Resource.fullPath(resource);
|
||||
RNFetchBlob.fs.cp(res.uri, targetPath);
|
||||
let targetPath = Resource.fullPath(resource);
|
||||
|
||||
if (res.type == 'image/jpeg' || res.type == 'image/jpg' || res.type == 'image/png') {
|
||||
const maxSize = 1920;
|
||||
|
||||
let dimensions = await this.imageDimensions(localFilePath);
|
||||
|
||||
reg.logger().info('Original dimensions ', dimensions);
|
||||
if (dimensions.width > maxSize || dimensions.height > maxSize) {
|
||||
dimensions.width = maxSize;
|
||||
dimensions.height = maxSize;
|
||||
}
|
||||
reg.logger().info('New dimensions ', dimensions);
|
||||
|
||||
const format = res.type == 'image/png' ? 'PNG' : 'JPEG';
|
||||
reg.logger().info('Resizing image ' + localFilePath);
|
||||
const resizedImagePath = await ImageResizer.createResizedImage(localFilePath, dimensions.width, dimensions.height, format, 85);
|
||||
reg.logger().info('Resized image ', resizedImagePath);
|
||||
RNFetchBlob.fs.cp(resizedImagePath, targetPath); // mv doesn't work ("source path does not exist") so need to do cp and unlink
|
||||
|
||||
try {
|
||||
RNFetchBlob.fs.unlink(resizedImagePath);
|
||||
} catch (error) {
|
||||
reg.logger().info('Error when unlinking cached file: ', error);
|
||||
}
|
||||
} else {
|
||||
RNFetchBlob.fs.cp(localFilePath, targetPath);
|
||||
}
|
||||
|
||||
await Resource.save(resource, { isNew: true });
|
||||
|
||||
const resourceTag = Resource.markdownTag(resource);
|
||||
|
||||
const newNote = Object.assign({}, this.state.note);
|
||||
newNote.body += "\n" + resourceTag;
|
||||
this.setState({ note: newNote });
|
||||
const newNote = Object.assign({}, this.state.note);
|
||||
newNote.body += "\n" + resourceTag;
|
||||
this.setState({ note: newNote });
|
||||
}
|
||||
|
||||
toggleIsTodo_onPress() {
|
||||
@ -467,7 +511,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
{ titleComp }
|
||||
{ bodyComponent }
|
||||
{ actionButtonComp }
|
||||
{ this.state.showNoteMetadata && <Text style={{ paddingLeft: globalStyle.marginLeft, paddingRight: globalStyle.marginRight, }}>{this.state.noteMetadata}</Text> }
|
||||
{ this.state.showNoteMetadata && <Text style={this.styles().metadata}>{this.state.noteMetadata}</Text> }
|
||||
<DialogBox ref={dialogbox => { this.dialogbox = dialogbox }}/>
|
||||
</View>
|
||||
);
|
||||
|
16
ReactNativeClient/lib/markdown-utils.js
Normal file
16
ReactNativeClient/lib/markdown-utils.js
Normal file
@ -0,0 +1,16 @@
|
||||
const markdownUtils = {
|
||||
|
||||
// Not really escaping because that's not supported by marked.js
|
||||
escapeLinkText(text) {
|
||||
return text.replace(/(\[|\]|\(|\))/g, '_');
|
||||
},
|
||||
|
||||
escapeLinkUrl(url) {
|
||||
url = url.replace(/\(/g, '%28');
|
||||
url = url.replace(/\)/g, '%29');
|
||||
return url;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export { markdownUtils };
|
@ -4,6 +4,7 @@ import { Setting } from 'lib/models/setting.js';
|
||||
import { mime } from 'lib/mime-utils.js';
|
||||
import { filename } from 'lib/path-utils.js';
|
||||
import { FsDriverDummy } from 'lib/fs-driver-dummy.js';
|
||||
import { markdownUtils } from 'lib/markdown-utils.js';
|
||||
import lodash from 'lodash';
|
||||
|
||||
class Resource extends BaseItem {
|
||||
@ -44,11 +45,11 @@ class Resource extends BaseItem {
|
||||
let lines = [];
|
||||
if (Resource.isSupportedImageMimeType(resource.mime)) {
|
||||
lines.push("![");
|
||||
lines.push(tagAlt);
|
||||
lines.push(markdownUtils.escapeLinkText(tagAlt));
|
||||
lines.push("](:/" + resource.id + ")");
|
||||
} else {
|
||||
lines.push("[");
|
||||
lines.push(tagAlt);
|
||||
lines.push(markdownUtils.escapeLinkText(tagAlt));
|
||||
lines.push("](:/" + resource.id + ")");
|
||||
}
|
||||
return lines.join('');
|
||||
|
@ -56,7 +56,7 @@ class Synchronizer {
|
||||
if (report.updateRemote) lines.push(_('Updated remote items: %d.', report.updateRemote));
|
||||
if (report.deleteLocal) lines.push(_('Deleted local items: %d.', report.deleteLocal));
|
||||
if (report.deleteRemote) lines.push(_('Deleted remote items: %d.', report.deleteRemote));
|
||||
if (!report.completedTime && report.state) lines.push(_('State: %s.', report.state.replace(/_/g, ' ')));
|
||||
if (!report.completedTime && report.state) lines.push(_('State: "%s".', report.state));
|
||||
if (report.errors && report.errors.length) lines.push(_('Last error: %s (stacktrace in log).', report.errors[report.errors.length-1].message));
|
||||
if (report.cancelling && !report.completedTime) lines.push(_('Cancelling...'));
|
||||
if (report.completedTime) lines.push(_('Completed: %s', time.unixMsToLocalDateTime(report.completedTime)));
|
||||
|
@ -20,6 +20,7 @@
|
||||
"react-native-document-picker": "^2.0.0",
|
||||
"react-native-fetch-blob": "^0.10.6",
|
||||
"react-native-fs": "^2.3.3",
|
||||
"react-native-image-resizer": "^0.1.1",
|
||||
"react-native-popup-menu": "^0.7.4",
|
||||
"react-native-side-menu": "^0.20.1",
|
||||
"react-native-sqlite-storage": "3.3.*",
|
||||
|
Loading…
Reference in New Issue
Block a user