Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RNMobile] Adds Clipboard Link Suggestion to Image block and Buttons block #35972

Merged
merged 15 commits into from
Nov 22, 2021
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
2 changes: 1 addition & 1 deletion packages/block-library/src/button/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ function ButtonEdit( props ) {
label: __( 'Button Link URL' ),
placeholder: __( 'Add URL' ),
autoFocus: true,
autoFill: true,
autoFill: false,
ttahmouch marked this conversation as resolved.
Show resolved Hide resolved
},
openInNewTab: {
label: __( 'Open in new tab' ),
Expand Down
2 changes: 1 addition & 1 deletion packages/block-library/src/image/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function LinkSettings( {
url: {
valueMask,
autoFocus: false,
autoFill: true,
autoFill: false,
ttahmouch marked this conversation as resolved.
Show resolved Hide resolved
},
openInNewTab: {
label: __( 'Open in new tab' ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ import { usePreferredColorSchemeStyle } from '@wordpress/compose';
import Cell from './cell';
import cellStyles from './styles.scss';
import suggestionStyles from './link-suggestion-styles.scss';
import { posts, pages, empty } from '../gridicons';
import { posts, pages, empty, clipboard } from '../gridicons';

const icons = {
URL: globe,
clipboard,
post: posts,
page: pages,
};

const getSummaryForType = ( type ) => {
switch ( type ) {
case 'clipboard':
return __( 'From clipboard' );
case 'mailto':
return __( 'Add this email link' );
case 'tel':
Expand All @@ -36,7 +39,7 @@ const getSummaryForType = ( type ) => {
};

// we use some Cell styles here with a column flex-direction
function LinkSuggestionItemCell( { suggestion, onLinkPicked } ) {
function LinkSuggestionItemCell( { suggestion, onLinkPicked, ...props } ) {
ttahmouch marked this conversation as resolved.
Show resolved Hide resolved
const { title: contentTitle, url, type, isDirectEntry } = suggestion;
const title = isDirectEntry ? url : contentTitle;
const summary = isDirectEntry ? getSummaryForType( type ) : url;
Expand All @@ -58,6 +61,7 @@ function LinkSuggestionItemCell( { suggestion, onLinkPicked } ) {

return (
<Cell
{ ...props }
ttahmouch marked this conversation as resolved.
Show resolved Hide resolved
icon={ icons[ type ] || empty }
onPress={ pickLink }
separatorType={ 'none' }
Expand Down
6 changes: 3 additions & 3 deletions packages/components/src/mobile/gridicons/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const fromPathData24x24 = ( pathData ) => (
</SVG>
);

export const clipboard = fromPathData24x24(
'M16 18H8v-2h8v2zm0-6H8v2h8v-2zm2-9h-2v2h2v15H6V5h2V3H6a2 2 0 00-2 2v15a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2zm-4 2V4a2 2 0 10-4 0v1a2 2 0 00-2 2v1h8V7a2 2 0 00-2-2z'
ttahmouch marked this conversation as resolved.
Show resolved Hide resolved
);
export const posts = fromPathData24x24(
'M16 19H3v-2h13v2zm5-10H3v2h18V9zM3 5v2h11V5H3zm14 0v2h4V5h-4zm-6 8v2h10v-2H11zm-8 0v2h5v-2H3z'
);
Expand All @@ -21,15 +24,12 @@ export const refresh = fromPathData24x24(
export const noticeOutline = fromPathData24x24(
'M12 4c4.41 0 8 3.59 8 8s-3.59 8-8 8-8-3.59-8-8 3.59-8 8-8m0-2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm1 13h-2v2h2v-2zm-2-2h2l.5-6h-3l.5 6z'
);

export const empty = (
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" />
);

export const search = fromPathData24x24(
'M21,19l-5.154-5.154C16.574,12.742,17,11.421,17,10c0-3.866-3.134-7-7-7s-7,3.134-7,7c0,3.866,3.134,7,7,7 c1.421,0,2.742-0.426,3.846-1.154L19,21L21,19z M5,10c0-2.757,2.243-5,5-5s5,2.243,5,5s-2.243,5-5,5S5,12.757,5,10z'
);

export default {
empty,
posts,
Expand Down
48 changes: 41 additions & 7 deletions packages/components/src/mobile/link-picker/index.native.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
/**
* External dependencies
*/
import { SafeAreaView, TouchableOpacity, View } from 'react-native';
import { Clipboard, SafeAreaView, TouchableOpacity, View } from 'react-native';
ttahmouch marked this conversation as resolved.
Show resolved Hide resolved
import { lowerCase, startsWith } from 'lodash';

/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useEffect, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { BottomSheet, Icon } from '@wordpress/components';
import { getProtocol, prependHTTP } from '@wordpress/url';
import { getProtocol, isURL, prependHTTP } from '@wordpress/url';
ttahmouch marked this conversation as resolved.
Show resolved Hide resolved
import { link, cancelCircleFilled } from '@wordpress/icons';
import { usePreferredColorSchemeStyle } from '@wordpress/compose';

Expand Down Expand Up @@ -47,12 +47,20 @@ export const createDirectEntry = ( value ) => {
};
};

const getURLFromClipboard = async () => {
const text = await Clipboard.getString();
return !! text && isURL( text ) ? text : '';
};

export const LinkPicker = ( {
value: initialValue,
onLinkPicked,
onCancel: cancel,
} ) => {
const [ value, setValue ] = useState( initialValue );
const [ { value, clipboardUrl }, setValue ] = useState( {
ttahmouch marked this conversation as resolved.
Show resolved Hide resolved
value: initialValue,
clipboardUrl: '',
} );
const directEntry = createDirectEntry( value );

// the title of a direct entry is displayed as the raw input value, but if we
Expand All @@ -66,7 +74,7 @@ export const LinkPicker = ( {
};

const clear = () => {
setValue( '' );
setValue( { value: '', clipboardUrl } );
};

const omniCellStyle = usePreferredColorSchemeStyle(
Expand All @@ -79,6 +87,14 @@ export const LinkPicker = ( {
styles.iconDark
);

useEffect( () => {
getURLFromClipboard()
.then( ( url ) => setValue( { value, clipboardUrl: url } ) )
.catch( () => setValue( { value, clipboardUrl: '' } ) );
Comment on lines +91 to +93
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to avoid React errors regarding setting state on an unmounted component, we may want to avoid updating the state with a clean up function for the Hook. WDYT?

useEffect(() => {
  let isCurrent = true;
  getURLFromClipboard()
    .then((url) => {
      if (isCurrent) {
        setValue({ value, clipboardUrl: url });
      }
    })
    .catch(() => {
      if (isCurrent) {
        setValue({ value, clipboardUrl: "" });
      }
    });
  return () => {
    isCurrent = false;
  };
}, []);

}, [] );

// TODO: Localize the accessibility label.
// TODO: Decide on if `LinkSuggestionItemCell` with `isDirectEntry` makes sense.
return (
<SafeAreaView style={ styles.safeArea }>
<NavBar>
Expand All @@ -96,7 +112,9 @@ export const LinkPicker = ( {
autoCapitalize="none"
autoCorrect={ false }
keyboardType="url"
onChangeValue={ setValue }
onChangeValue={ ( newValue ) => {
setValue( { value: newValue, clipboardUrl } );
} }
onSubmit={ onSubmit }
/* eslint-disable-next-line jsx-a11y/no-autofocus */
autoFocus
Expand All @@ -115,6 +133,22 @@ export const LinkPicker = ( {
</TouchableOpacity>
) }
</BottomSheet.Cell>
{ !! clipboardUrl && clipboardUrl !== value && (
<BottomSheet.LinkSuggestionItemCell
ttahmouch marked this conversation as resolved.
Show resolved Hide resolved
accessible
accessibilityLabel={ sprintf(
/* translators: Copy URL from the clipboard, https://sample.url */
__( 'Copy URL from the clipboard, %s' ),
clipboardUrl
) }
suggestion={ {
type: 'clipboard',
url: clipboardUrl,
isDirectEntry: true,
} }
onLinkPicked={ pickLink }
/>
) }
{ !! value && (
<LinkPickerResults
query={ value }
Expand Down
Loading