Browse Source

Add ability to download images/ copy their links

pull/70/head
Ezerous 5 years ago
parent
commit
2fa356d16e
No known key found for this signature in database GPG Key ID: 262B2954BBA319E3
  1. 59
      app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java
  2. 4
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  3. 11
      app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java
  4. 21
      app/src/main/java/gr/thmmy/mthmmy/model/ThmmyFile.java
  5. 7
      app/src/main/java/gr/thmmy/mthmmy/services/DownloadHelper.java
  6. 2
      app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseTask.java
  7. 66
      app/src/main/java/gr/thmmy/mthmmy/utils/ui/ImageDownloadDialogBuilder.java
  8. 13
      app/src/main/java/gr/thmmy/mthmmy/utils/ui/PhotoViewUtils.java
  9. 20
      app/src/main/java/gr/thmmy/mthmmy/views/ReactiveWebView.java
  10. 2
      app/src/main/res/values/strings.xml

59
app/src/main/java/gr/thmmy/mthmmy/activities/downloads/DownloadsAdapter.java

@ -34,7 +34,7 @@ class DownloadsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_LOADING = 1;
private final Context context;
private ArrayList<Download> parsedDownloads = new ArrayList<>();
private ArrayList<Download> parsedDownloads;
private final ArrayList<Boolean> downloadExpandableVisibility = new ArrayList<>();
DownloadsAdapter(Context context, ArrayList<Download> parsedDownloads) {
@ -77,17 +77,14 @@ class DownloadsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
}
if (download.getType() == Download.DownloadItemType.DOWNLOADS_CATEGORY) {
downloadViewHolder.downloadRow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context, DownloadsActivity.class);
Bundle extras = new Bundle();
extras.putString(BUNDLE_DOWNLOADS_URL, download.getUrl());
extras.putString(BUNDLE_DOWNLOADS_TITLE, download.getTitle());
intent.putExtras(extras);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
downloadViewHolder.downloadRow.setOnClickListener(view -> {
Intent intent = new Intent(context, DownloadsActivity.class);
Bundle extras = new Bundle();
extras.putString(BUNDLE_DOWNLOADS_URL, download.getUrl());
extras.putString(BUNDLE_DOWNLOADS_TITLE, download.getTitle());
intent.putExtras(extras);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
});
if (downloadExpandableVisibility.get(downloadViewHolder.getAdapterPosition())) {
@ -97,20 +94,17 @@ class DownloadsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
downloadViewHolder.informationExpandable.setVisibility(View.GONE);
downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
}
downloadViewHolder.informationExpandableBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final boolean visible = downloadExpandableVisibility.get(downloadViewHolder.
getAdapterPosition());
if (visible) {
downloadViewHolder.informationExpandable.setVisibility(View.GONE);
downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
} else {
downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE);
downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
}
downloadExpandableVisibility.set(downloadViewHolder.getAdapterPosition(), !visible);
downloadViewHolder.informationExpandableBtn.setOnClickListener(view -> {
final boolean visible = downloadExpandableVisibility.get(downloadViewHolder.
getAdapterPosition());
if (visible) {
downloadViewHolder.informationExpandable.setVisibility(View.GONE);
downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
} else {
downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE);
downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
}
downloadExpandableVisibility.set(downloadViewHolder.getAdapterPosition(), !visible);
});
downloadViewHolder.title.setTypeface(Typeface.createFromAsset(context.getAssets()
, "fonts/fontawesome-webfont.ttf"));
@ -124,15 +118,12 @@ class DownloadsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
downloadViewHolder.title.setText(tmp);
}
} else {
downloadViewHolder.downloadRow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
((BaseActivity) context).downloadFile(new ThmmyFile(
new URL(download.getUrl()), download.getFileName(), null));
} catch (MalformedURLException e) {
e.printStackTrace();
}
downloadViewHolder.downloadRow.setOnClickListener(view -> {
try {
((BaseActivity) context).downloadFile(new ThmmyFile(
new URL(download.getUrl()), download.getFileName(), null));
} catch (MalformedURLException e) {
e.printStackTrace();
}
});

4
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java

@ -187,7 +187,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
recyclerView.setLayoutManager(layoutManager);
topicAdapter = new TopicAdapter(this, emojiKeyboard, topicItems);
recyclerView.setAdapter(topicAdapter);
recyclerView.setItemViewCacheSize(15); //Every page has maximum 15 posts
recyclerView.setItemViewCacheSize(17); //Every page has maximum 15 posts + Poll + EditorView
replyFAB = findViewById(R.id.topic_fab);
replyFAB.hide();
@ -814,7 +814,7 @@ public class TopicActivity extends BaseActivity implements TopicAdapter.OnPostFo
//Make a toast to inform the user that the url was copied
Toast.makeText(
TopicActivity.this,
TopicActivity.this.getString(R.string.url_copied_msg),
TopicActivity.this.getString(R.string.link_copied_msg),
Toast.LENGTH_SHORT).show();
}
//Something happened. Probably the device does not support this (report to Firebase)

11
app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java

@ -735,7 +735,6 @@ public abstract class BaseActivity extends AppCompatActivity {
}
}
@Override
public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions
, @NonNull int[] grantResults) {
@ -760,13 +759,7 @@ public abstract class BaseActivity extends AppCompatActivity {
}
}
//Uses temp file - called after permission grant
private void downloadFile() {
if (checkPerms())
prepareDownload(tempThmmyFile);
}
private void prepareDownload(ThmmyFile thmmyFile) {
private void prepareDownload(@NonNull ThmmyFile thmmyFile) {
String fileName = thmmyFile.getFilename();
if (FileUtils.fileNameExists(fileName))
openDownloadPrompt(thmmyFile);
@ -774,7 +767,7 @@ public abstract class BaseActivity extends AppCompatActivity {
DownloadHelper.enqueueDownload(thmmyFile);
}
private void openDownloadPrompt(final ThmmyFile thmmyFile) {
private void openDownloadPrompt(@NonNull final ThmmyFile thmmyFile) {
View view = getLayoutInflater().inflate(R.layout.download_prompt_dialog, null);
final BottomSheetDialog dialog = new BottomSheetDialog(this);
dialog.setContentView(view);

21
app/src/main/java/gr/thmmy/mthmmy/model/ThmmyFile.java

@ -1,5 +1,7 @@
package gr.thmmy.mthmmy.model;
import android.webkit.URLUtil;
import java.net.URL;
public class ThmmyFile {
@ -8,27 +10,36 @@ public class ThmmyFile {
*/
private static final String TAG = "ThmmyFile";
private final URL fileUrl;
private final String filename, fileInfo;
private final String fileName, fileInfo;
/**
* This constructor only creates a ThmmyFile object and <b>does not download</b> the file.
*
* @param fileUrl {@link URL} object with file's url
* @param filename {@link String} with desired file name
* @param fileName {@link String} with desired file name
* @param fileInfo {@link String} with any extra information (like number of downloads)
*/
public ThmmyFile(URL fileUrl, String filename, String fileInfo) {
public ThmmyFile(URL fileUrl, String fileName, String fileInfo) {
this.fileUrl = fileUrl;
this.filename = filename;
if(fileName!=null)
this.fileName = fileName;
else
this.fileName = URLUtil.guessFileName(fileUrl.toString(), null, null);
this.fileInfo = fileInfo;
}
public ThmmyFile(URL fileUrl) {
this.fileUrl = fileUrl;
this.fileName = URLUtil.guessFileName(fileUrl.toString(), null, null);
this.fileInfo = null;
}
public URL getFileUrl() {
return fileUrl;
}
public String getFilename() {
return filename;
return fileName;
}
public String getFileInfo() {

7
app/src/main/java/gr/thmmy/mthmmy/services/DownloadHelper.java

@ -6,6 +6,8 @@ import android.net.Uri;
import android.os.Environment;
import android.widget.Toast;
import androidx.annotation.NonNull;
import java.io.File;
import gr.thmmy.mthmmy.base.BaseApplication;
@ -34,7 +36,8 @@ public class DownloadHelper {
DownloadManager.Request request = new DownloadManager.Request(downloadURI);
Cookie thmmyCookie = BaseApplication.getInstance().getSessionManager().getThmmyCookie();
request.addRequestHeader("Cookie", thmmyCookie.name() + "=" + thmmyCookie.value());
if(thmmyCookie!=null)
request.addRequestHeader("Cookie", thmmyCookie.name() + "=" + thmmyCookie.value());
request.setTitle(fileName);
request.setMimeType(getMimeType(fileName));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
@ -49,6 +52,7 @@ public class DownloadHelper {
}
}
@NonNull
private static String renameFileIfExists(String originalFileName) {
final String dirPath = SAVE_DIR.getAbsolutePath();
File file = new File(dirPath, originalFileName);
@ -68,7 +72,6 @@ public class DownloadHelper {
file = new File(dirPath, String.format(nameFormat, i));
}
return file.getName();
}
}

2
app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseTask.java

@ -21,7 +21,7 @@ import timber.log.Timber;
*/
public abstract class ParseTask extends AsyncTask<String, Void, ParseTask.ResultCode> {
protected String url;
protected enum ResultCode {
public enum ResultCode {
SUCCESS, PARSING_ERROR, NETWORK_ERROR, OTHER_ERROR
}

66
app/src/main/java/gr/thmmy/mthmmy/utils/ui/ImageDownloadDialogBuilder.java

@ -0,0 +1,66 @@
package gr.thmmy.mthmmy.utils.ui;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import java.net.MalformedURLException;
import java.net.URL;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.model.ThmmyFile;
import timber.log.Timber;
import static android.content.Context.CLIPBOARD_SERVICE;
public class ImageDownloadDialogBuilder extends AlertDialog.Builder{
private static final String[] colors = {"Copy image location", "Save Image"};
private Context context;
private String imageURL;
public ImageDownloadDialogBuilder(@NonNull Context context, String imageURL) {
super(context);
this.context = context;
this.imageURL = imageURL;
setItems(colors, (dialog, which) -> {
if(which == 0)
copyUrlToClipboard();
else {
try {
getBaseActivity().downloadFile(new ThmmyFile(new URL(imageURL)));
} catch (MalformedURLException e) {
Timber.e(e, "Exception downloading image (MalformedURLException)");
} catch (NullPointerException e) {
Timber.e(e, "Exception downloading image (NullPointerException)");
}
}
});
}
private void copyUrlToClipboard(){
ClipboardManager clipboard = (ClipboardManager) BaseApplication.getInstance().getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("ReactiveWebViewCopiedText", imageURL);
clipboard.setPrimaryClip(clip);
Toast.makeText(BaseApplication.getInstance().getApplicationContext(),context.getString(R.string.link_copied_msg),Toast.LENGTH_SHORT).show();
}
private BaseActivity getBaseActivity() {
Context baseActivityContext = context;
while (baseActivityContext instanceof ContextWrapper) {
if (context instanceof BaseActivity) {
return (BaseActivity) context;
}
baseActivityContext = ((ContextWrapper)context).getBaseContext();
}
return null;
}
}

13
app/src/main/java/gr/thmmy/mthmmy/utils/ui/PhotoViewUtils.java

@ -15,7 +15,7 @@ public class PhotoViewUtils {
private final static int screenWidth = BaseApplication.getInstance().getWidthInPixels();
private final static int screenHeight = BaseApplication.getInstance().getHeightInPixels();
public static void displayPhotoViewImage(Context context, String url) {
public static void displayPhotoViewImage(Context context, String imageURL) {
Dialog builder = new Dialog(context);
builder.requestWindowFeature(Window.FEATURE_NO_TITLE);
builder.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
@ -25,11 +25,20 @@ public class PhotoViewUtils {
PhotoView photoView = new PhotoView(context);
photoView.setLayoutParams(new ViewGroup.LayoutParams(screenWidth, screenHeight));
Glide.with(context).load(url).fitCenter().into(photoView);
Glide.with(context)
.load(imageURL)
.fitCenter()
.into(photoView);
builder.addContentView(photoView, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
builder.show();
photoView.setOnLongClickListener(v -> {
ImageDownloadDialogBuilder imageDownloadDialogBuilder = new ImageDownloadDialogBuilder(context, imageURL);
imageDownloadDialogBuilder.show();
return false;
});
}
}

20
app/src/main/java/gr/thmmy/mthmmy/views/ReactiveWebView.java

@ -8,7 +8,9 @@ import android.view.MotionEvent;
import android.webkit.WebView;
import android.widget.Toast;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.utils.ui.ImageDownloadDialogBuilder;
import static android.content.Context.CLIPBOARD_SERVICE;
import static gr.thmmy.mthmmy.utils.ui.PhotoViewUtils.displayPhotoViewImage;
@ -71,13 +73,21 @@ public class ReactiveWebView extends WebView {
private void setOnLongClickListener(){
this.setOnLongClickListener(v -> {
HitTestResult result = ReactiveWebView.this.getHitTestResult();
if(result.getType() == HitTestResult.SRC_ANCHOR_TYPE){
ClipboardManager clipboard = (ClipboardManager) BaseApplication.getInstance().getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("ReactiveWebViewCopiedText", result.getExtra());
clipboard.setPrimaryClip(clip);
Toast.makeText(BaseApplication.getInstance().getApplicationContext(),"Link copied",Toast.LENGTH_SHORT).show();
if(result.getType() == HitTestResult.SRC_ANCHOR_TYPE)
copyUrlToClipboard(result.getExtra());
else if(result.getType() == WebView.HitTestResult.IMAGE_TYPE) {
String imageURL = result.getExtra();
ImageDownloadDialogBuilder builder = new ImageDownloadDialogBuilder(context,imageURL);
builder.show();
}
return false;
});
}
private void copyUrlToClipboard(String urlToCopy){
ClipboardManager clipboard = (ClipboardManager) BaseApplication.getInstance().getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("ReactiveWebViewCopiedText", urlToCopy);
clipboard.setPrimaryClip(clip);
Toast.makeText(BaseApplication.getInstance().getApplicationContext(),context.getString(R.string.link_copied_msg),Toast.LENGTH_SHORT).show();
}
}

2
app/src/main/res/values/strings.xml

@ -233,5 +233,5 @@
<!-- New topic activity -->
<string name="new_topic_toolbar">New topic</string>
<string name="create_topic">Create topic</string>
<string name="url_copied_msg">URL copied</string>
<string name="link_copied_msg">Link copied</string>
</resources>

Loading…
Cancel
Save