App: [$250] [Image] Implement the ability to copy images to the clipboard

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Coming from https://github.com/Expensify/App/issues/3313

Action Performed:

Right-click or long-press on an image in a chat.

Expected Result:

  1. A context menu appears, displaying a single option: Copy image to clipboard
  2. Clicking on this option should copy the image to the clipboard, where it can be pasted somewhere else.

Note: the solution implemented must be an offline-first solution. Meaning the user should be able to copy the image to their clipboard, whether or not they have internet connection.

Actual Result:

  1. The normal context menu appears.
  2. Clicking on Copy to clipboard copies the HTML image tag to the clipboard, not the binary image itself.

Workaround:

Screenshot the image? Also you can click on it and download it.

Platform:

  • Web
  • iOS
  • Android
  • Desktop App
  • Mobile Web

Version Number: 1.0.85-3 Logs: https://stackoverflow.com/c/expensify/questions/4856 Notes/Photos/Videos: Any additional supporting documentation Expensify/Expensify Issue URL:

Upwork job: https://www.upwork.com/jobs/~012fd9a807faaf42aa View all open jobs on Upwork

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01b3973ec74ce159e9
  • Upwork Job ID: 1782953316490067968
  • Last Price Increase: 2024-05-01

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 129 (121 by maintainers)

Most upvoted comments

Ya I think this should hold on caching, looks like we’re close so it should only hold another week!

Still on HOLD, reassigning to @Beamanator

After we have added functionality to add images offline in NewDot. We will need to make attachment offline.

For that, there is a issue https://github.com/Expensify/App/issues/6527

Thanks @parasharrajat I’ve removed the help wanted label and marked this as on hold for now.

@roryabraham Correct, we need to make images offline first so that we can refer to them in the file system. I think https://github.com/Expensify/react-native-onyx/pull/102 will enable us to do that easily so I think we should hold this issue till that time. Until we store the images in APP storage (file system) there is no way to get them without the internet. Currently, they are only located via a URL so first have a feature to make them offline, and then we can easily use the path as a URL and add a copy feature. IMO, this feature can’t be offline until we have offline images. Thus I think we should hold this.

@puneetlath Let’s hire @MTN718 for this job on Upwork!

Hired!

Okay, I’ll review as soon as I can.

Thanks. Oh, and please try to do most of your testing with a test account instead of Concierge. I believe test messages sent to Concierge may clutter our customer support channels.

Oh yeah, and we’ve forked react-native-clipboard: https://github.com/Expensify/Clipboard

In my implementation, input parameter is Image URL but in current PR, not. And in my view, that’s not complete solution.

In the meantime, I’ll create an internal issue to create an Expensify/clipboard fork.

Yes as you can see implemented web and ios already. let me implement android and show you result soon.

One Notice: Image url should be png file. clipboard support only image/png type. can’t save jpg file to clipboard So we should be discuss about convert image jpg to png from server or frontend.

It seems you should use data URLs shema with base64, which will work with a variety of mediatype, probably all attachment types accepted by the backend API. We should use the same approach (share the same function) for retriveing the url of the attachment to a base64 data url, so that it is possible to copy or share the base64 data. Here it is a good example on how to do this: (that would be your fetch(embeddedImages[0].src))

.fetch('GET', fileUrl)
    .then(resp => {
      filePath = resp.path();
      return resp.readFile('base64');
    })
    .then(async base64Data => {
      base64Data = `data:${type};base64,` + base64Data;

the full example is here: https://react-native-share.github.io/react-native-share/docs/share-remote-file

Also react-native-web uses the same Clipboard component from react-native which is deprecated (https://reactnative.dev/docs/clipboard), so I would recommend using only https://github.com/react-native-clipboard/clipboard for that (rename src/libs/Clipboard/index.native.js to src/libs/Clipboard/index.js)

@parasharrajat https://github.com/Expensify/App/issues/1294 is slightly different – I believe that’s about adding New Expensify as an option in native share menus, not about exposing native share menus from within New Expensify