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 int VIEW_TYPE_LOADING = 1;
private final Context context; private final Context context;
private ArrayList<Download> parsedDownloads = new ArrayList<>(); private ArrayList<Download> parsedDownloads;
private final ArrayList<Boolean> downloadExpandableVisibility = new ArrayList<>(); private final ArrayList<Boolean> downloadExpandableVisibility = new ArrayList<>();
DownloadsAdapter(Context context, ArrayList<Download> parsedDownloads) { DownloadsAdapter(Context context, ArrayList<Download> parsedDownloads) {
@ -77,17 +77,14 @@ class DownloadsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
} }
if (download.getType() == Download.DownloadItemType.DOWNLOADS_CATEGORY) { if (download.getType() == Download.DownloadItemType.DOWNLOADS_CATEGORY) {
downloadViewHolder.downloadRow.setOnClickListener(new View.OnClickListener() { downloadViewHolder.downloadRow.setOnClickListener(view -> {
@Override Intent intent = new Intent(context, DownloadsActivity.class);
public void onClick(View view) { Bundle extras = new Bundle();
Intent intent = new Intent(context, DownloadsActivity.class); extras.putString(BUNDLE_DOWNLOADS_URL, download.getUrl());
Bundle extras = new Bundle(); extras.putString(BUNDLE_DOWNLOADS_TITLE, download.getTitle());
extras.putString(BUNDLE_DOWNLOADS_URL, download.getUrl()); intent.putExtras(extras);
extras.putString(BUNDLE_DOWNLOADS_TITLE, download.getTitle()); intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
intent.putExtras(extras); context.startActivity(intent);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}); });
if (downloadExpandableVisibility.get(downloadViewHolder.getAdapterPosition())) { if (downloadExpandableVisibility.get(downloadViewHolder.getAdapterPosition())) {
@ -97,20 +94,17 @@ class DownloadsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
downloadViewHolder.informationExpandable.setVisibility(View.GONE); downloadViewHolder.informationExpandable.setVisibility(View.GONE);
downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
} }
downloadViewHolder.informationExpandableBtn.setOnClickListener(new View.OnClickListener() { downloadViewHolder.informationExpandableBtn.setOnClickListener(view -> {
@Override final boolean visible = downloadExpandableVisibility.get(downloadViewHolder.
public void onClick(View view) { getAdapterPosition());
final boolean visible = downloadExpandableVisibility.get(downloadViewHolder. if (visible) {
getAdapterPosition()); downloadViewHolder.informationExpandable.setVisibility(View.GONE);
if (visible) { downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp);
downloadViewHolder.informationExpandable.setVisibility(View.GONE); } else {
downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_down_accent_24dp); downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE);
} else { downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
downloadViewHolder.informationExpandable.setVisibility(View.VISIBLE);
downloadViewHolder.informationExpandableBtn.setImageResource(R.drawable.ic_arrow_drop_up_accent_24dp);
}
downloadExpandableVisibility.set(downloadViewHolder.getAdapterPosition(), !visible);
} }
downloadExpandableVisibility.set(downloadViewHolder.getAdapterPosition(), !visible);
}); });
downloadViewHolder.title.setTypeface(Typeface.createFromAsset(context.getAssets() downloadViewHolder.title.setTypeface(Typeface.createFromAsset(context.getAssets()
, "fonts/fontawesome-webfont.ttf")); , "fonts/fontawesome-webfont.ttf"));
@ -124,15 +118,12 @@ class DownloadsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
downloadViewHolder.title.setText(tmp); downloadViewHolder.title.setText(tmp);
} }
} else { } else {
downloadViewHolder.downloadRow.setOnClickListener(new View.OnClickListener() { downloadViewHolder.downloadRow.setOnClickListener(view -> {
@Override try {
public void onClick(View view) { ((BaseActivity) context).downloadFile(new ThmmyFile(
try { new URL(download.getUrl()), download.getFileName(), null));
((BaseActivity) context).downloadFile(new ThmmyFile( } catch (MalformedURLException e) {
new URL(download.getUrl()), download.getFileName(), null)); e.printStackTrace();
} 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); recyclerView.setLayoutManager(layoutManager);
topicAdapter = new TopicAdapter(this, emojiKeyboard, topicItems); topicAdapter = new TopicAdapter(this, emojiKeyboard, topicItems);
recyclerView.setAdapter(topicAdapter); 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 = findViewById(R.id.topic_fab);
replyFAB.hide(); 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 //Make a toast to inform the user that the url was copied
Toast.makeText( Toast.makeText(
TopicActivity.this, TopicActivity.this,
TopicActivity.this.getString(R.string.url_copied_msg), TopicActivity.this.getString(R.string.link_copied_msg),
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
} }
//Something happened. Probably the device does not support this (report to Firebase) //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 @Override
public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions
, @NonNull int[] grantResults) { , @NonNull int[] grantResults) {
@ -760,13 +759,7 @@ public abstract class BaseActivity extends AppCompatActivity {
} }
} }
//Uses temp file - called after permission grant private void prepareDownload(@NonNull ThmmyFile thmmyFile) {
private void downloadFile() {
if (checkPerms())
prepareDownload(tempThmmyFile);
}
private void prepareDownload(ThmmyFile thmmyFile) {
String fileName = thmmyFile.getFilename(); String fileName = thmmyFile.getFilename();
if (FileUtils.fileNameExists(fileName)) if (FileUtils.fileNameExists(fileName))
openDownloadPrompt(thmmyFile); openDownloadPrompt(thmmyFile);
@ -774,7 +767,7 @@ public abstract class BaseActivity extends AppCompatActivity {
DownloadHelper.enqueueDownload(thmmyFile); 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); View view = getLayoutInflater().inflate(R.layout.download_prompt_dialog, null);
final BottomSheetDialog dialog = new BottomSheetDialog(this); final BottomSheetDialog dialog = new BottomSheetDialog(this);
dialog.setContentView(view); dialog.setContentView(view);

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

@ -1,5 +1,7 @@
package gr.thmmy.mthmmy.model; package gr.thmmy.mthmmy.model;
import android.webkit.URLUtil;
import java.net.URL; import java.net.URL;
public class ThmmyFile { public class ThmmyFile {
@ -8,27 +10,36 @@ public class ThmmyFile {
*/ */
private static final String TAG = "ThmmyFile"; private static final String TAG = "ThmmyFile";
private final URL fileUrl; 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. * 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 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) * @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.fileUrl = fileUrl;
this.filename = filename; if(fileName!=null)
this.fileName = fileName;
else
this.fileName = URLUtil.guessFileName(fileUrl.toString(), null, null);
this.fileInfo = fileInfo; this.fileInfo = fileInfo;
} }
public ThmmyFile(URL fileUrl) {
this.fileUrl = fileUrl;
this.fileName = URLUtil.guessFileName(fileUrl.toString(), null, null);
this.fileInfo = null;
}
public URL getFileUrl() { public URL getFileUrl() {
return fileUrl; return fileUrl;
} }
public String getFilename() { public String getFilename() {
return filename; return fileName;
} }
public String getFileInfo() { 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.os.Environment;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import java.io.File; import java.io.File;
import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.base.BaseApplication;
@ -34,7 +36,8 @@ public class DownloadHelper {
DownloadManager.Request request = new DownloadManager.Request(downloadURI); DownloadManager.Request request = new DownloadManager.Request(downloadURI);
Cookie thmmyCookie = BaseApplication.getInstance().getSessionManager().getThmmyCookie(); 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.setTitle(fileName);
request.setMimeType(getMimeType(fileName)); request.setMimeType(getMimeType(fileName));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
@ -49,6 +52,7 @@ public class DownloadHelper {
} }
} }
@NonNull
private static String renameFileIfExists(String originalFileName) { private static String renameFileIfExists(String originalFileName) {
final String dirPath = SAVE_DIR.getAbsolutePath(); final String dirPath = SAVE_DIR.getAbsolutePath();
File file = new File(dirPath, originalFileName); File file = new File(dirPath, originalFileName);
@ -68,7 +72,6 @@ public class DownloadHelper {
file = new File(dirPath, String.format(nameFormat, i)); file = new File(dirPath, String.format(nameFormat, i));
} }
return file.getName(); 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> { public abstract class ParseTask extends AsyncTask<String, Void, ParseTask.ResultCode> {
protected String url; protected String url;
protected enum ResultCode { public enum ResultCode {
SUCCESS, PARSING_ERROR, NETWORK_ERROR, OTHER_ERROR 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 screenWidth = BaseApplication.getInstance().getWidthInPixels();
private final static int screenHeight = BaseApplication.getInstance().getHeightInPixels(); 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); Dialog builder = new Dialog(context);
builder.requestWindowFeature(Window.FEATURE_NO_TITLE); builder.requestWindowFeature(Window.FEATURE_NO_TITLE);
builder.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); builder.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
@ -25,11 +25,20 @@ public class PhotoViewUtils {
PhotoView photoView = new PhotoView(context); PhotoView photoView = new PhotoView(context);
photoView.setLayoutParams(new ViewGroup.LayoutParams(screenWidth, screenHeight)); 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( builder.addContentView(photoView, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT)); ViewGroup.LayoutParams.MATCH_PARENT));
builder.show(); 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.webkit.WebView;
import android.widget.Toast; import android.widget.Toast;
import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.base.BaseApplication;
import gr.thmmy.mthmmy.utils.ui.ImageDownloadDialogBuilder;
import static android.content.Context.CLIPBOARD_SERVICE; import static android.content.Context.CLIPBOARD_SERVICE;
import static gr.thmmy.mthmmy.utils.ui.PhotoViewUtils.displayPhotoViewImage; import static gr.thmmy.mthmmy.utils.ui.PhotoViewUtils.displayPhotoViewImage;
@ -71,13 +73,21 @@ public class ReactiveWebView extends WebView {
private void setOnLongClickListener(){ private void setOnLongClickListener(){
this.setOnLongClickListener(v -> { this.setOnLongClickListener(v -> {
HitTestResult result = ReactiveWebView.this.getHitTestResult(); HitTestResult result = ReactiveWebView.this.getHitTestResult();
if(result.getType() == HitTestResult.SRC_ANCHOR_TYPE){ if(result.getType() == HitTestResult.SRC_ANCHOR_TYPE)
ClipboardManager clipboard = (ClipboardManager) BaseApplication.getInstance().getSystemService(CLIPBOARD_SERVICE); copyUrlToClipboard(result.getExtra());
ClipData clip = ClipData.newPlainText("ReactiveWebViewCopiedText", result.getExtra()); else if(result.getType() == WebView.HitTestResult.IMAGE_TYPE) {
clipboard.setPrimaryClip(clip); String imageURL = result.getExtra();
Toast.makeText(BaseApplication.getInstance().getApplicationContext(),"Link copied",Toast.LENGTH_SHORT).show(); ImageDownloadDialogBuilder builder = new ImageDownloadDialogBuilder(context,imageURL);
builder.show();
} }
return false; 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 --> <!-- New topic activity -->
<string name="new_topic_toolbar">New topic</string> <string name="new_topic_toolbar">New topic</string>
<string name="create_topic">Create 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> </resources>

Loading…
Cancel
Save