Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions android/src/main/java/com/typerich/TypeRichTextInputView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class TypeRichTextInputView : AppCompatEditText {
private var lineHeightPx: Int? = null
private var isSettingTextFromJS = false
private var isInitialized = false
private var disableImagePasting = false

constructor(context: Context) : super(context) {
prepareComponent()
Expand Down Expand Up @@ -140,23 +141,34 @@ class TypeRichTextInputView : AppCompatEditText {
override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
val ic = super.onCreateInputConnection(outAttrs) ?: return null

EditorInfoCompat.setContentMimeTypes(
outAttrs,
arrayOf("image/png", "image/jpg", "image/jpeg", "image/gif", "image/webp")
)
if (!disableImagePasting) {
EditorInfoCompat.setContentMimeTypes(
outAttrs,
arrayOf("image/png", "image/jpg", "image/jpeg", "image/gif", "image/webp")
)

return InputConnectionCompat.createWrapper(ic, outAttrs, onCommitContent)
}

return InputConnectionCompat.createWrapper(ic, outAttrs, onCommitContent)
return ic
}

private val onCommitContent = InputConnectionCompat.OnCommitContentListener { info, flags, _ ->
try {
// request permission if needed
if ((flags and InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
val hasPermission =
(flags and InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0

if (hasPermission) {
try {
info.requestPermission()
} catch (ex: Exception) {
// permission failed
} catch (_: Exception) {}
}

if (disableImagePasting) {
if (hasPermission) {
try { info.releasePermission() } catch (_: Exception) {}
}
return@OnCommitContentListener false
}

val uri = info.contentUri
Expand Down Expand Up @@ -189,7 +201,7 @@ class TypeRichTextInputView : AppCompatEditText {
}
}

// paste handler
// context menu paste handler
override fun onTextContextMenuItem(id: Int): Boolean {
if (id == android.R.id.paste || id == android.R.id.pasteAsPlainText) {
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
Expand All @@ -198,6 +210,12 @@ class TypeRichTextInputView : AppCompatEditText {
val clip = clipboard.primaryClip ?: return super.onTextContextMenuItem(id)
val item = clip.getItemAt(0)

if (disableImagePasting) {
if (item.uri != null || item.intent?.data != null) {
return true
}
}

// uri
item.uri?.let { uri ->
val source = EnumPasteSource.CLIPBOARD.value
Expand Down Expand Up @@ -577,6 +595,10 @@ class TypeRichTextInputView : AppCompatEditText {
}
}

fun setDisableImagePasting(disabled: Boolean){
this.disableImagePasting = disabled
}

override fun isLayoutRequested(): Boolean {
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ class TypeRichTextInputViewManager :
view?.setLineHeightReact(lineHeight)
}

@ReactProp(name = "disableImagePasting")
override fun setDisableImagePasting(view: TypeRichTextInputView?, value: Boolean) {
view?.setDisableImagePasting(value)
}

override fun onAfterUpdateTransaction(view: TypeRichTextInputView) {
super.onAfterUpdateTransaction(view)
view.afterUpdateTransaction()
Expand Down
1 change: 1 addition & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export default function App() {
fontWeight={'200'}
fontSize={24}
color="indigo"
disableImagePasting={false}
/>
</View>
<TextInput
Expand Down
1 change: 1 addition & 0 deletions ios/TypeRichTextInputView.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)invalidateTextLayoutFromCommand;
- (void)updatePlaceholderVisibilityFromCommand;
- (void)dispatchSelectionChangeIfNeeded;
- (BOOL)isDisableImagePasting;

@end
NS_ASSUME_NONNULL_END
13 changes: 13 additions & 0 deletions ios/TypeRichTextInputView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

#pragma mark - Implementation

@implementation TypeRichTextInputView {

Check warning on line 35 in ios/TypeRichTextInputView.mm

View workflow job for this annotation

GitHub Actions / build-ios

class 'TypeRichTextInputView' does not conform to protocol 'RCTTypeRichTextInputViewViewProtocol' [-Wprotocol]

Check warning on line 35 in ios/TypeRichTextInputView.mm

View workflow job for this annotation

GitHub Actions / build-ios

class 'TypeRichTextInputView' does not conform to protocol 'RCTTypeRichTextInputViewViewProtocol' [-Wprotocol]
/// Native text input
UITextView *_textView;

Expand All @@ -52,6 +52,9 @@
/// Commands to call from js side
TypeRichTextInputCommands *_commandHandler;
// BOOL _isHandlingUserInput;

/// Disabling Image Pasing
BOOL _disableImagePasting;
}

#pragma mark - Fabric registration
Expand Down Expand Up @@ -124,6 +127,8 @@
_textView.font = defaultFont;
_placeholderLabel.font = defaultFont;

_disableImagePasting = NO;

// Add textView as subview (not contentView)
[self addSubview:_textView];

Expand Down Expand Up @@ -301,6 +306,11 @@
);
}

// disableImagePasting
if (!oldPropsPtr || newProps.disableImagePasting != oldPropsPtr->disableImagePasting) {
_disableImagePasting = newProps.disableImagePasting;
}

#pragma mark - Style Props

// Text color
Expand Down Expand Up @@ -436,7 +446,7 @@
}

// Apply to existing text
NSMutableAttributedString *attributedText =

Check warning on line 449 in ios/TypeRichTextInputView.mm

View workflow job for this annotation

GitHub Actions / build-ios

unused variable 'attributedText' [-Wunused-variable]

Check warning on line 449 in ios/TypeRichTextInputView.mm

View workflow job for this annotation

GitHub Actions / build-ios

unused variable 'attributedText' [-Wunused-variable]
[[NSMutableAttributedString alloc]
initWithString:_textView.text ?: @""
attributes:attributes];
Expand Down Expand Up @@ -815,4 +825,7 @@
// return _isHandlingUserInput;
//}

- (BOOL)isDisableImagePasting{
return _disableImagePasting;
}
@end
25 changes: 23 additions & 2 deletions ios/inputTextView/TypeRichUITextView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@ @implementation TypeRichUITextView
- (void)paste:(id)sender {
UIPasteboard *pb = UIPasteboard.generalPasteboard;

if (pb.hasImages) {
if ([self.owner isDisableImagePasting] &&
pb.hasImages &&
!pb.hasStrings) {
return;
}

if (
![self.owner isDisableImagePasting]
&& pb.hasImages
) {

UIImage *image = pb.image;
if (!image) {
[super paste:sender];
Expand Down Expand Up @@ -53,7 +63,11 @@ - (void)paste:(id)sender {

- (BOOL)canPasteItemProviders:(NSArray<NSItemProvider *> *)itemProviders {
for (NSItemProvider *provider in itemProviders) {
if ([provider hasItemConformingToTypeIdentifier:@"public.text"] ||
if ([provider hasItemConformingToTypeIdentifier:@"public.text"]) {
return YES;
}

if (![self.owner isDisableImagePasting] &&
[provider hasItemConformingToTypeIdentifier:@"public.image"]) {
return YES;
}
Expand All @@ -65,6 +79,13 @@ - (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if (action == @selector(paste:)) {
UIPasteboard *pb = UIPasteboard.generalPasteboard;

if (
[self.owner isDisableImagePasting] &&
pb.hasImages &&
!pb.hasStrings) {
return NO;
}

// Allow paste if there is text OR image
if (pb.hasStrings || pb.hasImages) {
return YES;
Expand Down
6 changes: 2 additions & 4 deletions src/TypeRichTextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function normalizeEvent<T>(event: MaybeNativeEvent<T>): T {
return event as T;
}

// Public facing props (same as NativeProps but events normalized)
// normalised events
export interface TypeRichTextInputProps
extends Omit<
TypeRichTextInputNativeProps,
Expand All @@ -38,7 +38,6 @@ export interface TypeRichTextInputProps
| 'onInputBlur'
| 'onPasteImage'
> {
// JS-friendly callbacks
onFocus?: () => void;
onBlur?: () => void;
onChangeText?: (value: string) => void;
Expand Down Expand Up @@ -67,8 +66,7 @@ export interface TypeRichTextInputRef {
* - Fabric-based rendering
* - custom ShadowNode on Android
*
* iOS support is currently unavailable and renders a `View` comp as fallback
* we are planning to add support for ios too soon
* iOS support is currently in Beta Stage and
*/
const TypeRichTextInput = forwardRef(
(props: TypeRichTextInputProps, ref: Ref<TypeRichTextInputRef>) => {
Expand Down
2 changes: 1 addition & 1 deletion src/TypeRichTextInputNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export interface TypeRichTextInputNativeProps extends ViewProps {
keyboardAppearance?: WithDefault<'default' | 'light' | 'dark', 'default'>; // ios only

// Todo
// disableImagePasting?: boolean
disableImagePasting?: boolean;

// event callbacks
onInputFocus?: DirectEventHandler<null>;
Expand Down
Loading