diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d41efe63..0bd9268e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -19,6 +19,17 @@
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true"
tools:ignore="AllowBackup,GoogleAppIndexingWarning,UnusedAttribute">
+
+
+
+
+
diff --git a/app/src/main/java/com/readrops/app/activities/ItemActivity.java b/app/src/main/java/com/readrops/app/activities/ItemActivity.java
index ed8ac4a3..65a1816e 100644
--- a/app/src/main/java/com/readrops/app/activities/ItemActivity.java
+++ b/app/src/main/java/com/readrops/app/activities/ItemActivity.java
@@ -3,20 +3,31 @@ package com.readrops.app.activities;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
+import android.util.Log;
+import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
+import androidx.core.app.ShareCompat;
import androidx.lifecycle.ViewModelProvider;
+import com.afollestad.materialdialogs.MaterialDialog;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.request.target.CustomTarget;
+import com.bumptech.glide.request.transition.Transition;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
@@ -37,6 +48,8 @@ import static com.readrops.app.utils.ReadropsKeys.WEB_URL;
public class ItemActivity extends AppCompatActivity {
+ private static final String TAG = ItemActivity.class.getSimpleName();
+
private ItemViewModel viewModel;
private TextView date;
private TextView title;
@@ -84,6 +97,8 @@ public class ItemActivity extends AppCompatActivity {
readTimeLayout = findViewById(R.id.activity_item_readtime_layout);
dateLayout = findViewById(R.id.activity_item_date_layout);
+ registerForContextMenu(webView);
+
if (imageUrl == null) {
getSupportActionBar().setDisplayShowTitleEnabled(false);
toolbarLayout.setTitleEnabled(false);
@@ -246,4 +261,58 @@ public class ItemActivity extends AppCompatActivity {
shareIntent.putExtra(Intent.EXTRA_TEXT, itemWithFeed.getItem().getTitle() + " - " + itemWithFeed.getItem().getLink());
startActivity(Intent.createChooser(shareIntent, getString(R.string.share_article)));
}
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ WebView.HitTestResult hitTestResult = webView.getHitTestResult();
+
+ if (hitTestResult.getType() == WebView.HitTestResult.IMAGE_TYPE ||
+ hitTestResult.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
+ new MaterialDialog.Builder(this)
+ .title(R.string.image_options)
+ .items(R.array.image_options)
+ .itemsCallback((dialog, itemView, position, text) -> {
+ if (position == 0)
+ shareImage(hitTestResult.getExtra());
+ else
+ downloadImage(hitTestResult.getExtra());
+ })
+ .show();
+ }
+ }
+
+ private void downloadImage(String url) {
+
+ }
+
+ private void shareImage(String url) {
+ GlideApp.with(this)
+ .asBitmap()
+ .diskCacheStrategy(DiskCacheStrategy.ALL)
+ .load(url)
+ .into(new CustomTarget() {
+ @Override
+ public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition super Bitmap> transition) {
+ try {
+ Uri uri = viewModel.saveImageInCache(resource);
+ Intent intent = ShareCompat.IntentBuilder.from(ItemActivity.this)
+ .setType("image/png")
+ .setStream(uri)
+ .setChooserTitle(R.string.share_image)
+ .createChooserIntent()
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ startActivity(intent);
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ }
+ }
+
+ @Override
+ public void onLoadCleared(@Nullable Drawable placeholder) {
+ // not useful
+ }
+ });
+
+ }
}
diff --git a/app/src/main/java/com/readrops/app/viewmodels/ItemViewModel.java b/app/src/main/java/com/readrops/app/viewmodels/ItemViewModel.java
index d79e2ccd..10585f37 100644
--- a/app/src/main/java/com/readrops/app/viewmodels/ItemViewModel.java
+++ b/app/src/main/java/com/readrops/app/viewmodels/ItemViewModel.java
@@ -1,14 +1,23 @@
package com.readrops.app.viewmodels;
import android.app.Application;
+import android.graphics.Bitmap;
+import android.net.Uri;
+
+import androidx.annotation.NonNull;
+import androidx.core.content.FileProvider;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
-import androidx.annotation.NonNull;
import com.readrops.app.database.Database;
import com.readrops.app.database.dao.ItemDao;
import com.readrops.app.database.pojo.ItemWithFeed;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
public class ItemViewModel extends AndroidViewModel {
private ItemDao itemDao;
@@ -23,4 +32,19 @@ public class ItemViewModel extends AndroidViewModel {
}
+ public Uri saveImageInCache(Bitmap bitmap) throws IOException {
+ File imagesFolder = new File(getApplication().getCacheDir().getAbsolutePath(), "images");
+
+ if (!imagesFolder.exists())
+ imagesFolder.mkdirs();
+
+ File image = new File(imagesFolder, "shared_image.png");
+ OutputStream stream = new FileOutputStream(image);
+ bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
+
+ stream.flush();
+ stream.close();
+
+ return FileProvider.getUriForFile(getApplication(), getApplication().getPackageName(), image);
+ }
}
diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml
index f5f3ec79..9af48fa0 100644
--- a/app/src/main/res/values-fr-rFR/strings.xml
+++ b/app/src/main/res/values-fr-rFR/strings.xml
@@ -103,5 +103,8 @@
Réessayer
Permissions
Ou
+ Options de l\'image
+ Télécharger l\'image
+ Partager l\'image
\ No newline at end of file
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index 8f06743e..6eb2a4e5 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -10,6 +10,11 @@
- @string/opml_export
+
+ - @string/share_image
+ - @string/download_image
+
+
- 20
- 50
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 74566f17..b12cc24f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -112,4 +112,7 @@
Try again
Permissions
Or
+ Image Options
+ Download image
+ Share image
diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml
new file mode 100644
index 00000000..2f2698e3
--- /dev/null
+++ b/app/src/main/res/xml/file_paths.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file