@codebymanan/react-native-photo-editor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/PhotoEditor.podspec +23 -0
- package/README.md +200 -0
- package/android/build.gradle +65 -0
- package/android/src/main/AndroidManifest.xml +14 -0
- package/android/src/main/assets/beyond_wonderland.ttf +0 -0
- package/android/src/main/assets/emojione-android.ttf +0 -0
- package/android/src/main/assets/filters/auto_fix.png +0 -0
- package/android/src/main/assets/filters/b_n_w.png +0 -0
- package/android/src/main/assets/filters/brightness.png +0 -0
- package/android/src/main/assets/filters/contrast.png +0 -0
- package/android/src/main/assets/filters/cross_process.png +0 -0
- package/android/src/main/assets/filters/documentary.png +0 -0
- package/android/src/main/assets/filters/dual_tone.png +0 -0
- package/android/src/main/assets/filters/fill_light.png +0 -0
- package/android/src/main/assets/filters/fish_eye.png +0 -0
- package/android/src/main/assets/filters/flip_horizental.png +0 -0
- package/android/src/main/assets/filters/flip_vertical.png +0 -0
- package/android/src/main/assets/filters/grain.png +0 -0
- package/android/src/main/assets/filters/gray_scale.png +0 -0
- package/android/src/main/assets/filters/lomish.png +0 -0
- package/android/src/main/assets/filters/negative.png +0 -0
- package/android/src/main/assets/filters/original.jpg +0 -0
- package/android/src/main/assets/filters/posterize.png +0 -0
- package/android/src/main/assets/filters/rotate.png +0 -0
- package/android/src/main/assets/filters/saturate.png +0 -0
- package/android/src/main/assets/filters/sepia.png +0 -0
- package/android/src/main/assets/filters/sharpen.png +0 -0
- package/android/src/main/assets/filters/temprature.png +0 -0
- package/android/src/main/assets/filters/tint.png +0 -0
- package/android/src/main/assets/filters/vignette.png +0 -0
- package/android/src/main/java/com/photoeditor/PhotoEditorModule.kt +130 -0
- package/android/src/main/java/com/photoeditor/PhotoEditorPackage.kt +31 -0
- package/android/src/main/java/com/photoeditor/editor/ColorPickerAdapter.kt +100 -0
- package/android/src/main/java/com/photoeditor/editor/EditImageActivity.kt +407 -0
- package/android/src/main/java/com/photoeditor/editor/EditorLocale.kt +41 -0
- package/android/src/main/java/com/photoeditor/editor/EditorStrings.kt +46 -0
- package/android/src/main/java/com/photoeditor/editor/EmojiBSFragment.kt +121 -0
- package/android/src/main/java/com/photoeditor/editor/PropertiesBSFragment.kt +76 -0
- package/android/src/main/java/com/photoeditor/editor/ShapeBSFragment.kt +112 -0
- package/android/src/main/java/com/photoeditor/editor/StickerBSFragment.kt +130 -0
- package/android/src/main/java/com/photoeditor/editor/TextEditorDialogFragment.kt +133 -0
- package/android/src/main/java/com/photoeditor/editor/base/BaseActivity.kt +67 -0
- package/android/src/main/java/com/photoeditor/editor/base/BaseFragment.kt +10 -0
- package/android/src/main/java/com/photoeditor/editor/filters/FilterListener.kt +7 -0
- package/android/src/main/java/com/photoeditor/editor/filters/FilterViewAdapter.kt +105 -0
- package/android/src/main/java/com/photoeditor/editor/tools/EditingToolsAdapter.kt +70 -0
- package/android/src/main/java/com/photoeditor/editor/tools/ToolType.kt +10 -0
- package/android/src/main/res/drawable/pe_blank_image.jpg +0 -0
- package/android/src/main/res/drawable/pe_ic_brush.xml +9 -0
- package/android/src/main/res/drawable/pe_ic_close.xml +9 -0
- package/android/src/main/res/drawable/pe_ic_eraser.xml +4 -0
- package/android/src/main/res/drawable/pe_ic_insert_emoticon.xml +9 -0
- package/android/src/main/res/drawable/pe_ic_oval.xml +9 -0
- package/android/src/main/res/drawable/pe_ic_photo_filter.xml +5 -0
- package/android/src/main/res/drawable/pe_ic_rectangle.xml +9 -0
- package/android/src/main/res/drawable/pe_ic_redo.xml +10 -0
- package/android/src/main/res/drawable/pe_ic_redo_disabled.xml +10 -0
- package/android/src/main/res/drawable/pe_ic_save.xml +9 -0
- package/android/src/main/res/drawable/pe_ic_sticker.xml +9 -0
- package/android/src/main/res/drawable/pe_ic_text.xml +9 -0
- package/android/src/main/res/drawable/pe_ic_undo.xml +10 -0
- package/android/src/main/res/drawable/pe_ic_undo_disabled.xml +10 -0
- package/android/src/main/res/drawable/pe_original.jpg +0 -0
- package/android/src/main/res/drawable/pe_redo.xml +6 -0
- package/android/src/main/res/drawable/pe_rounded_border_text_view.xml +14 -0
- package/android/src/main/res/drawable/pe_undo.xml +6 -0
- package/android/src/main/res/font/pe_roboto_medium.xml +7 -0
- package/android/src/main/res/layout/pe_activity_edit_image.xml +111 -0
- package/android/src/main/res/layout/pe_add_text_dialog.xml +56 -0
- package/android/src/main/res/layout/pe_color_picker_item_list.xml +15 -0
- package/android/src/main/res/layout/pe_fragment_bottom_properties_dialog.xml +77 -0
- package/android/src/main/res/layout/pe_fragment_bottom_shapes_dialog.xml +135 -0
- package/android/src/main/res/layout/pe_fragment_bottom_sticker_emoji_dialog.xml +62 -0
- package/android/src/main/res/layout/pe_row_editing_tools.xml +34 -0
- package/android/src/main/res/layout/pe_row_emoji.xml +17 -0
- package/android/src/main/res/layout/pe_row_filter_view.xml +35 -0
- package/android/src/main/res/layout/pe_row_sticker.xml +23 -0
- package/android/src/main/res/values/colors.xml +22 -0
- package/android/src/main/res/values/dimens.xml +7 -0
- package/android/src/main/res/values/font_certs.xml +17 -0
- package/android/src/main/res/values/preloaded_fonts.xml +6 -0
- package/android/src/main/res/values/strings.xml +462 -0
- package/android/src/main/res/values/styles.xml +28 -0
- package/ios/PhotoEditor.h +5 -0
- package/ios/PhotoEditor.mm +58 -0
- package/ios/PhotoEditorManager.swift +164 -0
- package/lib/module/NativePhotoEditor.js +5 -0
- package/lib/module/NativePhotoEditor.js.map +1 -0
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/open.js +6 -0
- package/lib/module/open.js.map +1 -0
- package/lib/module/open.native.js +7 -0
- package/lib/module/open.native.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativePhotoEditor.d.ts +14 -0
- package/lib/typescript/src/NativePhotoEditor.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/open.d.ts +3 -0
- package/lib/typescript/src/open.d.ts.map +1 -0
- package/lib/typescript/src/open.native.d.ts +3 -0
- package/lib/typescript/src/open.native.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +39 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +128 -0
- package/src/NativePhotoEditor.ts +12 -0
- package/src/index.tsx +2 -0
- package/src/open.native.tsx +6 -0
- package/src/open.tsx +7 -0
- package/src/types.ts +36 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#import "PhotoEditor.h"
|
|
2
|
+
|
|
3
|
+
#if __has_include("PhotoEditor/PhotoEditor-Swift.h")
|
|
4
|
+
#import "PhotoEditor/PhotoEditor-Swift.h"
|
|
5
|
+
#else
|
|
6
|
+
#import "PhotoEditor-Swift.h"
|
|
7
|
+
#endif
|
|
8
|
+
|
|
9
|
+
@implementation PhotoEditor
|
|
10
|
+
|
|
11
|
+
- (void)open:(JS::NativePhotoEditor::SpecOpenOptions &)options
|
|
12
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
13
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
14
|
+
{
|
|
15
|
+
NSString *path = options.path();
|
|
16
|
+
if (path.length == 0) {
|
|
17
|
+
reject(@"E_INVALID_OPTIONS", @"Missing required option: path", nil);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
NSMutableArray<NSString *> *stickers = [NSMutableArray new];
|
|
22
|
+
if (options.stickers().has_value()) {
|
|
23
|
+
auto vector = options.stickers().value();
|
|
24
|
+
for (size_t i = 0; i < vector.size(); i++) {
|
|
25
|
+
[stickers addObject:vector[i]];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Codegen hands dictionaries back untyped, so check before casting.
|
|
30
|
+
id rawTranslations = options.translations();
|
|
31
|
+
NSDictionary *translations = [rawTranslations isKindOfClass:[NSDictionary class]]
|
|
32
|
+
? (NSDictionary *)rawTranslations
|
|
33
|
+
: nil;
|
|
34
|
+
|
|
35
|
+
[PhotoEditorManager open:path
|
|
36
|
+
stickers:stickers
|
|
37
|
+
language:options.language()
|
|
38
|
+
translations:translations
|
|
39
|
+
resolve:^(NSString *outputPath) {
|
|
40
|
+
resolve(outputPath);
|
|
41
|
+
}
|
|
42
|
+
reject:^(NSString *code, NSString *message) {
|
|
43
|
+
reject(code, message, nil);
|
|
44
|
+
}];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
48
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
49
|
+
{
|
|
50
|
+
return std::make_shared<facebook::react::NativePhotoEditorSpecJSI>(params);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
+ (NSString *)moduleName
|
|
54
|
+
{
|
|
55
|
+
return @"PhotoEditor";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@end
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import UIKit
|
|
2
|
+
import ZLImageEditor
|
|
3
|
+
|
|
4
|
+
@objc(PhotoEditorManager)
|
|
5
|
+
public class PhotoEditorManager: NSObject {
|
|
6
|
+
|
|
7
|
+
@objc public static func open(
|
|
8
|
+
_ path: String,
|
|
9
|
+
stickers: [String],
|
|
10
|
+
language: String?,
|
|
11
|
+
translations: [String: Any]?,
|
|
12
|
+
resolve: @escaping (String) -> Void,
|
|
13
|
+
reject: @escaping (String, String) -> Void
|
|
14
|
+
) {
|
|
15
|
+
loadImage(path) { image in
|
|
16
|
+
DispatchQueue.main.async {
|
|
17
|
+
guard let image else {
|
|
18
|
+
reject("E_FAILED", "Could not load image: \(path)")
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
guard let presenter = topViewController() else {
|
|
22
|
+
reject("E_NO_ACTIVITY", "No view controller available to present the editor")
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
ZLImageEditorUIConfiguration.default()
|
|
27
|
+
.languageType(languageType(for: language))
|
|
28
|
+
.customLanguageConfig(customLanguage(from: translations))
|
|
29
|
+
|
|
30
|
+
ZLImageEditorConfiguration.default()
|
|
31
|
+
.editImageTools([.draw, .clip, .textSticker, .mosaic, .filter, .adjust])
|
|
32
|
+
.adjustTools([.brightness, .contrast, .saturation])
|
|
33
|
+
|
|
34
|
+
let editor = ZLEditImageViewController(image: image)
|
|
35
|
+
editor.modalPresentationStyle = .fullScreen
|
|
36
|
+
editor.editFinishBlock = { resImage, _ in
|
|
37
|
+
saveImage(resImage, resolve: resolve, reject: reject)
|
|
38
|
+
}
|
|
39
|
+
editor.cancelBlock = {
|
|
40
|
+
reject("E_CANCELLED", "User cancelled image editing")
|
|
41
|
+
}
|
|
42
|
+
presenter.present(editor, animated: true)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// The editor exposes exactly these nine strings for overriding, so this is
|
|
48
|
+
/// the whole of what `translations` can reach on iOS. Keys are the same ones
|
|
49
|
+
/// Android uses, which is what lets one map drive both platforms.
|
|
50
|
+
private static let overridableKeys: [String: ZLLocalLanguageKey] = [
|
|
51
|
+
"pe_label_cancel": .cancel,
|
|
52
|
+
"pe_label_done": .done,
|
|
53
|
+
"pe_label_save": .editFinish,
|
|
54
|
+
"pe_label_undo": .revert,
|
|
55
|
+
"pe_filter_brightness": .brightness,
|
|
56
|
+
"pe_filter_contrast": .contrast,
|
|
57
|
+
"pe_filter_saturate": .saturation,
|
|
58
|
+
"pe_msg_drag_to_remove": .textStickerRemoveTips,
|
|
59
|
+
"pe_msg_saving": .hudProcessing,
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
/// Always returns a dictionary, empty included: the configuration is a shared
|
|
63
|
+
/// singleton, so anything left unassigned would outlive the call that set it.
|
|
64
|
+
private static func customLanguage(from translations: [String: Any]?) -> [ZLLocalLanguageKey: String] {
|
|
65
|
+
guard let translations else { return [:] }
|
|
66
|
+
|
|
67
|
+
return overridableKeys.reduce(into: [:]) { config, entry in
|
|
68
|
+
// Non-string values are dropped rather than coerced, so a mistyped entry
|
|
69
|
+
// falls back to the built-in string.
|
|
70
|
+
if let value = translations[entry.key] as? String, !value.isEmpty {
|
|
71
|
+
config[entry.value] = value
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// Maps a BCP-47 tag onto the languages the editor ships.
|
|
77
|
+
///
|
|
78
|
+
/// A missing tag means "follow the device". An unrecognised tag falls back to
|
|
79
|
+
/// English rather than to the device language: the caller explicitly asked not
|
|
80
|
+
/// to use the device setting, so quietly reverting to it would be the one
|
|
81
|
+
/// answer we know they did not want.
|
|
82
|
+
private static func languageType(for tag: String?) -> ZLImageEditorLanguageType {
|
|
83
|
+
guard let tag = tag?.lowercased(), !tag.isEmpty else { return .system }
|
|
84
|
+
|
|
85
|
+
// Tolerate the Java-style "pt_BR" spelling as well as BCP-47's "pt-BR".
|
|
86
|
+
let subtags = tag.split(whereSeparator: { $0 == "-" || $0 == "_" }).map(String.init)
|
|
87
|
+
|
|
88
|
+
// Chinese needs the script or region, not just the language, to pick a bundle.
|
|
89
|
+
if subtags.first == "zh" {
|
|
90
|
+
let traditional = subtags.dropFirst().contains { ["hant", "tw", "hk", "mo"].contains($0) }
|
|
91
|
+
return traditional ? .chineseTraditional : .chineseSimplified
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
switch subtags.first ?? tag {
|
|
95
|
+
case "en": return .english
|
|
96
|
+
case "ja": return .japanese
|
|
97
|
+
case "fr": return .french
|
|
98
|
+
case "de": return .german
|
|
99
|
+
case "ru": return .russian
|
|
100
|
+
case "vi": return .vietnamese
|
|
101
|
+
case "ko": return .korean
|
|
102
|
+
case "ms": return .malay
|
|
103
|
+
case "it": return .italian
|
|
104
|
+
case "id", "in": return .indonesian
|
|
105
|
+
case "pt": return .portuguese
|
|
106
|
+
case "es": return .spanish
|
|
107
|
+
case "tr": return .turkish
|
|
108
|
+
case "ar": return .arabic
|
|
109
|
+
case "uk": return .ukrainian
|
|
110
|
+
case "nl": return .dutch
|
|
111
|
+
default: return .english
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private static func loadImage(_ path: String, completion: @escaping (UIImage?) -> Void) {
|
|
116
|
+
if path.hasPrefix("http://") || path.hasPrefix("https://") {
|
|
117
|
+
guard let url = URL(string: path) else {
|
|
118
|
+
completion(nil)
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
URLSession.shared.dataTask(with: url) { data, _, _ in
|
|
122
|
+
completion(data.flatMap(UIImage.init(data:)))
|
|
123
|
+
}.resume()
|
|
124
|
+
} else {
|
|
125
|
+
let filePath = path.hasPrefix("file://") ? String(path.dropFirst(7)) : path
|
|
126
|
+
completion(UIImage(contentsOfFile: filePath))
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private static func saveImage(
|
|
131
|
+
_ image: UIImage,
|
|
132
|
+
resolve: @escaping (String) -> Void,
|
|
133
|
+
reject: @escaping (String, String) -> Void
|
|
134
|
+
) {
|
|
135
|
+
let outputDir = (NSTemporaryDirectory() as NSString).appendingPathComponent("photo_editor")
|
|
136
|
+
do {
|
|
137
|
+
try FileManager.default.createDirectory(
|
|
138
|
+
atPath: outputDir, withIntermediateDirectories: true)
|
|
139
|
+
let outputPath = (outputDir as NSString)
|
|
140
|
+
.appendingPathComponent("\(Int(Date().timeIntervalSince1970 * 1000)).png")
|
|
141
|
+
guard let data = image.pngData() else {
|
|
142
|
+
reject("E_FAILED", "Could not encode edited image")
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
try data.write(to: URL(fileURLWithPath: outputPath))
|
|
146
|
+
resolve(outputPath)
|
|
147
|
+
} catch {
|
|
148
|
+
reject("E_FAILED", "Failed to save image: \(error.localizedDescription)")
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private static func topViewController() -> UIViewController? {
|
|
153
|
+
let keyWindow = UIApplication.shared.connectedScenes
|
|
154
|
+
.compactMap { $0 as? UIWindowScene }
|
|
155
|
+
.flatMap { $0.windows }
|
|
156
|
+
.first { $0.isKeyWindow }
|
|
157
|
+
|
|
158
|
+
var top = keyWindow?.rootViewController
|
|
159
|
+
while let presented = top?.presentedViewController {
|
|
160
|
+
top = presented
|
|
161
|
+
}
|
|
162
|
+
return top
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativePhotoEditor.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;AAWpE,eAAeA,mBAAmB,CAACC,YAAY,CAAO,aAAa,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["open"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,IAAI,QAAQ,QAAQ","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["open","_options","Error"],"sourceRoot":"../../src","sources":["open.tsx"],"mappings":";;AAEA,OAAO,SAASA,IAAIA,CAACC,QAA4B,EAAmB;EAClE,MAAM,IAAIC,KAAK,CACb,iFACF,CAAC;AACH","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["PhotoEditor","open","options"],"sourceRoot":"../../src","sources":["open.native.tsx"],"mappings":";;AAAA,OAAOA,WAAW,MAAM,wBAAqB;AAG7C,OAAO,SAASC,IAAIA,CAACC,OAA2B,EAAmB;EACjE,OAAOF,WAAW,CAACC,IAAI,CAACC,OAAO,CAAC;AAClC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type TurboModule } from 'react-native';
|
|
2
|
+
export interface Spec extends TurboModule {
|
|
3
|
+
open(options: {
|
|
4
|
+
path: string;
|
|
5
|
+
stickers?: string[];
|
|
6
|
+
language?: string;
|
|
7
|
+
translations?: {
|
|
8
|
+
[key: string]: string;
|
|
9
|
+
};
|
|
10
|
+
}): Promise<string>;
|
|
11
|
+
}
|
|
12
|
+
declare const _default: Spec;
|
|
13
|
+
export default _default;
|
|
14
|
+
//# sourceMappingURL=NativePhotoEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativePhotoEditor.d.ts","sourceRoot":"","sources":["../../../src/NativePhotoEditor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;KAC1C,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrB;;AAED,wBAAqE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../src/open.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAS,CAAC;AAElD,wBAAgB,IAAI,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAIlE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.native.d.ts","sourceRoot":"","sources":["../../../src/open.native.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAS,CAAC;AAElD,wBAAgB,IAAI,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface PhotoEditorOptions {
|
|
2
|
+
/**
|
|
3
|
+
* The image to edit. Accepts a local file path, `file://` or `content://`
|
|
4
|
+
* URI, or a remote `http(s)` URL.
|
|
5
|
+
*/
|
|
6
|
+
path: string;
|
|
7
|
+
/**
|
|
8
|
+
* Optional list of sticker image URLs shown in the sticker picker.
|
|
9
|
+
*/
|
|
10
|
+
stickers?: string[];
|
|
11
|
+
/**
|
|
12
|
+
* BCP-47 language tag (`'fr'`, `'pt-BR'`, `'zh-Hans'`) for the editor UI.
|
|
13
|
+
*
|
|
14
|
+
* Defaults to the device language. Set this only when your app has its own
|
|
15
|
+
* language picker and needs the editor to follow it rather than the device.
|
|
16
|
+
*
|
|
17
|
+
* On Android the tag selects a `values-<lang>` resource folder, so it can be
|
|
18
|
+
* any language your app provides strings for. On iOS it maps onto the
|
|
19
|
+
* languages the underlying editor ships; unsupported tags fall back to
|
|
20
|
+
* English.
|
|
21
|
+
*/
|
|
22
|
+
language?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Per-key string overrides, keyed by the editor's string names
|
|
25
|
+
* (`pe_label_save`, `pe_filter_contrast`, ...). See the README for the list.
|
|
26
|
+
*
|
|
27
|
+
* Use this when your strings live in JS rather than in native resources, or
|
|
28
|
+
* to reach a language iOS does not ship. Keys you leave out keep their
|
|
29
|
+
* built-in value, and on Android anything you have already put in a
|
|
30
|
+
* `values-<lang>` folder still applies underneath.
|
|
31
|
+
*
|
|
32
|
+
* Android honours every key. iOS honours the nine the underlying editor
|
|
33
|
+
* exposes; the rest are ignored there.
|
|
34
|
+
*/
|
|
35
|
+
translations?: {
|
|
36
|
+
[key: string]: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC1C"}
|
package/package.json
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codebymanan/react-native-photo-editor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A React Native photo editor plugin wrapping native editors for Android and iOS",
|
|
5
|
+
"main": "./lib/module/index.js",
|
|
6
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"react-native-photo-editor-source": "./src/index.tsx",
|
|
10
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
11
|
+
"default": "./lib/module/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"src",
|
|
17
|
+
"lib",
|
|
18
|
+
"android",
|
|
19
|
+
"ios",
|
|
20
|
+
"cpp",
|
|
21
|
+
"*.podspec",
|
|
22
|
+
"react-native.config.js",
|
|
23
|
+
"!ios/build",
|
|
24
|
+
"!android/build",
|
|
25
|
+
"!android/gradle",
|
|
26
|
+
"!android/gradlew",
|
|
27
|
+
"!android/gradlew.bat",
|
|
28
|
+
"!android/local.properties",
|
|
29
|
+
"!**/__tests__",
|
|
30
|
+
"!**/__fixtures__",
|
|
31
|
+
"!**/__mocks__",
|
|
32
|
+
"!**/.*"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"example": "yarn workspace react-native-photo-editor-example",
|
|
36
|
+
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
37
|
+
"prepare": "bob build",
|
|
38
|
+
"typecheck": "tsc",
|
|
39
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\""
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"react-native",
|
|
43
|
+
"ios",
|
|
44
|
+
"android"
|
|
45
|
+
],
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/codebymanan/react-native-photo-editor.git"
|
|
49
|
+
},
|
|
50
|
+
"author": "Abdul Manan <abdulmanancoder@gmail.com> (https://github.com/codebymanan)",
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/codebymanan/react-native-photo-editor/issues"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/codebymanan/react-native-photo-editor#readme",
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"registry": "https://registry.npmjs.org/",
|
|
58
|
+
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@eslint/compat": "^2.1.0",
|
|
62
|
+
"@eslint/eslintrc": "^3.3.5",
|
|
63
|
+
"@eslint/js": "^10.0.1",
|
|
64
|
+
"@react-native/babel-preset": "0.85.0",
|
|
65
|
+
"@react-native/eslint-config": "0.85.0",
|
|
66
|
+
"@types/react": "^19.2.0",
|
|
67
|
+
"del-cli": "^7.0.0",
|
|
68
|
+
"eslint": "^9.39.4",
|
|
69
|
+
"eslint-config-prettier": "^10.1.8",
|
|
70
|
+
"eslint-plugin-ft-flow": "^3.0.11",
|
|
71
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
72
|
+
"prettier": "^3.8.3",
|
|
73
|
+
"react": "19.2.3",
|
|
74
|
+
"react-native": "0.85.0",
|
|
75
|
+
"react-native-builder-bob": "^0.43.0",
|
|
76
|
+
"turbo": "^2.9.16",
|
|
77
|
+
"typescript": "^6.0.3"
|
|
78
|
+
},
|
|
79
|
+
"peerDependencies": {
|
|
80
|
+
"react": "*",
|
|
81
|
+
"react-native": "*"
|
|
82
|
+
},
|
|
83
|
+
"workspaces": [
|
|
84
|
+
"example"
|
|
85
|
+
],
|
|
86
|
+
"packageManager": "yarn@4.11.0",
|
|
87
|
+
"react-native-builder-bob": {
|
|
88
|
+
"source": "src",
|
|
89
|
+
"output": "lib",
|
|
90
|
+
"targets": [
|
|
91
|
+
[
|
|
92
|
+
"module",
|
|
93
|
+
{
|
|
94
|
+
"esm": true
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
[
|
|
98
|
+
"typescript",
|
|
99
|
+
{
|
|
100
|
+
"project": "tsconfig.build.json"
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
"codegenConfig": {
|
|
106
|
+
"name": "PhotoEditorSpec",
|
|
107
|
+
"type": "modules",
|
|
108
|
+
"jsSrcsDir": "src",
|
|
109
|
+
"android": {
|
|
110
|
+
"javaPackageName": "com.photoeditor"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"prettier": {
|
|
114
|
+
"quoteProps": "consistent",
|
|
115
|
+
"singleQuote": true,
|
|
116
|
+
"tabWidth": 2,
|
|
117
|
+
"trailingComma": "es5",
|
|
118
|
+
"useTabs": false
|
|
119
|
+
},
|
|
120
|
+
"create-react-native-library": {
|
|
121
|
+
"type": "turbo-module",
|
|
122
|
+
"languages": "kotlin-objc",
|
|
123
|
+
"tools": [
|
|
124
|
+
"eslint"
|
|
125
|
+
],
|
|
126
|
+
"version": "0.63.0"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TurboModuleRegistry, type TurboModule } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export interface Spec extends TurboModule {
|
|
4
|
+
open(options: {
|
|
5
|
+
path: string;
|
|
6
|
+
stickers?: string[];
|
|
7
|
+
language?: string;
|
|
8
|
+
translations?: { [key: string]: string };
|
|
9
|
+
}): Promise<string>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('PhotoEditor');
|
package/src/index.tsx
ADDED
package/src/open.tsx
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface PhotoEditorOptions {
|
|
2
|
+
/**
|
|
3
|
+
* The image to edit. Accepts a local file path, `file://` or `content://`
|
|
4
|
+
* URI, or a remote `http(s)` URL.
|
|
5
|
+
*/
|
|
6
|
+
path: string;
|
|
7
|
+
/**
|
|
8
|
+
* Optional list of sticker image URLs shown in the sticker picker.
|
|
9
|
+
*/
|
|
10
|
+
stickers?: string[];
|
|
11
|
+
/**
|
|
12
|
+
* BCP-47 language tag (`'fr'`, `'pt-BR'`, `'zh-Hans'`) for the editor UI.
|
|
13
|
+
*
|
|
14
|
+
* Defaults to the device language. Set this only when your app has its own
|
|
15
|
+
* language picker and needs the editor to follow it rather than the device.
|
|
16
|
+
*
|
|
17
|
+
* On Android the tag selects a `values-<lang>` resource folder, so it can be
|
|
18
|
+
* any language your app provides strings for. On iOS it maps onto the
|
|
19
|
+
* languages the underlying editor ships; unsupported tags fall back to
|
|
20
|
+
* English.
|
|
21
|
+
*/
|
|
22
|
+
language?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Per-key string overrides, keyed by the editor's string names
|
|
25
|
+
* (`pe_label_save`, `pe_filter_contrast`, ...). See the README for the list.
|
|
26
|
+
*
|
|
27
|
+
* Use this when your strings live in JS rather than in native resources, or
|
|
28
|
+
* to reach a language iOS does not ship. Keys you leave out keep their
|
|
29
|
+
* built-in value, and on Android anything you have already put in a
|
|
30
|
+
* `values-<lang>` folder still applies underneath.
|
|
31
|
+
*
|
|
32
|
+
* Android honours every key. iOS honours the nine the underlying editor
|
|
33
|
+
* exposes; the rest are ignored there.
|
|
34
|
+
*/
|
|
35
|
+
translations?: { [key: string]: string };
|
|
36
|
+
}
|