From 959e7f411c0e2b6fd498eebcfbd19638d4d3ba94 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 26 Jan 2021 14:54:33 +0200 Subject: [PATCH 1/3] Upload Photo: bottom sheet with the progress bar Uplaod progress dialog Upload complete dialog --- .../layout/bottom_sheet_with_progress_bar.xml | 49 +++++ OsmAnd/res/values/strings.xml | 5 +- ...UploadPhotoWithProgressBarBottomSheet.java | 111 ++++++++++ .../plus/mapcontextmenu/MenuBuilder.java | 157 +++----------- .../mapcontextmenu/UploadPhotosAsyncTask.java | 203 ++++++++++++++++++ 5 files changed, 393 insertions(+), 132 deletions(-) create mode 100644 OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml create mode 100644 OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoWithProgressBarBottomSheet.java create mode 100644 OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java diff --git a/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml b/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml new file mode 100644 index 0000000000..fd1f27bbae --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml @@ -0,0 +1,49 @@ + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 79d3a211b4..4b4b94826e 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,7 +11,10 @@ Thx - Hardy --> - + Uploaded %1$s of %2$d + Uploading %1$s of %2$d + Upload completed + Uploading Copy to favorites Copy to map markers Delete waypoints diff --git a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoWithProgressBarBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoWithProgressBarBottomSheet.java new file mode 100644 index 0000000000..73e09845a3 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoWithProgressBarBottomSheet.java @@ -0,0 +1,111 @@ +package net.osmand.plus.dialogs; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; + +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; +import net.osmand.plus.widgets.TextViewEx; + +public class UploadPhotoWithProgressBarBottomSheet extends MenuBottomSheetDialogFragment { + + public static final String TAG = UploadPhotoWithProgressBarBottomSheet.class.getSimpleName(); + + private ProgressBar progressBar; + private TextView uploadedPhotosCounter; + private TextViewEx uploadedPhotosTitle; + private int maxProgress; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + Context context = requireContext(); + LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); + View view = inflater.inflate(R.layout.bottom_sheet_with_progress_bar, null); + + progressBar = view.findViewById(R.id.progress_bar); + progressBar.setMax(maxProgress); + uploadedPhotosCounter = view.findViewById(R.id.description); + + uploadedPhotosTitle = view.findViewById(R.id.title); + + BaseBottomSheetItem descriptionItem = new BottomSheetItemWithDescription.Builder() + .setDescription(getString(R.string.uploading_count, progressBar.getProgress(), maxProgress)) + .setTitle(getString(R.string.upload_photo)) + .setCustomView(view) + .create(); + items.add(descriptionItem); + + int padding = getResources().getDimensionPixelSize(R.dimen.content_padding_small); + items.add(new DividerSpaceItem(requireContext(), padding)); + } + + public void onProgressUpdate(int progress) { + progressBar.setProgress(progress); + uploadedPhotosCounter.setText((getString(R.string.uploading_count, progressBar.getProgress(), maxProgress))); + } + + public void onUploadingFinished() { + TextViewEx dismissButtonText = dismissButton.findViewById(R.id.button_text); + setDismissButtonTextId(R.string.shared_string_close); + dismissButtonText.setText(R.string.shared_string_close); + uploadedPhotosTitle.setText(R.string.upload_photo_completed); + uploadedPhotosCounter.setText((getString(R.string.uploaded_count, progressBar.getProgress(), maxProgress))); + } + + @Override + protected boolean useVerticalButtons() { + return true; + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_cancel; + } + + @Override + protected DialogButtonType getRightBottomButtonType() { + return DialogButtonType.PRIMARY; + } + + @Override + public int getSecondDividerHeight() { + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin); + } + + @Override + protected void onRightBottomButtonClick() { + dismiss(); + } + + @Nullable + public MapActivity getMapActivity() { + Activity activity = getActivity(); + if (activity instanceof MapActivity) { + return (MapActivity) activity; + } + return null; + } + + public static UploadPhotoWithProgressBarBottomSheet showInstance(@NonNull FragmentManager fragmentManager, int maxProgress) { + UploadPhotoWithProgressBarBottomSheet fragment = new UploadPhotoWithProgressBarBottomSheet(); + fragment.maxProgress = maxProgress; + fragment.setRetainInstance(true); + fragmentManager.beginTransaction().add(fragment, TAG).commitAllowingStateLoss(); + return fragment; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index 3890046fac..98198d65f3 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -1,22 +1,19 @@ package net.osmand.plus.mapcontextmenu; import android.app.Activity; +import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.res.ColorStateList; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Color; -import android.graphics.Matrix; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.net.Uri; import android.os.AsyncTask; -import android.os.Handler; -import android.os.Looper; +import android.os.Build; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; @@ -46,7 +43,6 @@ import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiType; -import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; @@ -54,6 +50,7 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.Version; import net.osmand.plus.activities.ActivityResultListener; +import net.osmand.plus.activities.ActivityResultListener.OnActivityResultListener; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard; @@ -80,12 +77,7 @@ import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; -import org.openplacereviews.opendb.util.exception.FailedVerificationException; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -99,7 +91,6 @@ import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCa public class MenuBuilder { private static final int PICK_IMAGE = 1231; - private static final int MAX_IMAGE_LENGTH = 2048; private static final Log LOG = PlatformUtil.getLog(MenuBuilder.class); public static final float SHADOW_HEIGHT_TOP_DP = 17f; public static final int TITLE_LIMIT = 60; @@ -425,7 +416,7 @@ public class MenuBuilder { if (false) { AddPhotosBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager()); } else { - registerResultListener(view); + registerResultListener(); final String baseUrl = OPRConstants.getBaseUrl(app); final String name = app.getSettings().OPR_USERNAME.get(); final String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); @@ -443,6 +434,9 @@ public class MenuBuilder { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); + if (Build.VERSION.SDK_INT > 18) { + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + } mapActivity.startActivityForResult(Intent.createChooser(intent, mapActivity.getString(R.string.select_picture)), PICK_IMAGE); } @@ -472,132 +466,33 @@ public class MenuBuilder { false, null, false); } - private void registerResultListener(final View view) { - mapActivity.registerActivityResultListener(new ActivityResultListener(PICK_IMAGE, new ActivityResultListener. - OnActivityResultListener() { + private void registerResultListener() { + mapActivity.registerActivityResultListener(new ActivityResultListener(PICK_IMAGE, new OnActivityResultListener() { @Override public void onResult(int resultCode, Intent resultData) { if (resultData != null) { - handleSelectedImage(view, resultData.getData()); + List imagesUri = new ArrayList<>(); + Uri data = resultData.getData(); + if (data != null) { + imagesUri.add(data); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + ClipData clipData = resultData.getClipData(); + if (clipData != null) { + for (int i = 0; i < clipData.getItemCount(); i++) { + Uri uri = resultData.getClipData().getItemAt(i).getUri(); + if (uri != null) { + imagesUri.add(uri); + } + } + } + } + execute(new UploadPhotosAsyncTask(mapActivity, imagesUri, getLatLon(), placeId, getAdditionalCardParams(), imageCardListener)); } } })); } - private void handleSelectedImage(final View view, final Uri uri) { - Thread t = new Thread(new Runnable() { - @Override - public void run() { - InputStream inputStream = null; - try { - inputStream = app.getContentResolver().openInputStream(uri); - if (inputStream != null) { - uploadImageToPlace(inputStream); - } - } catch (Exception e) { - LOG.error(e); - String str = app.getString(R.string.cannot_upload_image); - showToastMessage(str); - } finally { - Algorithms.closeStream(inputStream); - } - } - }); - t.start(); - } - - private void uploadImageToPlace(InputStream image) { - InputStream serverData = new ByteArrayInputStream(compressImageToJpeg(image)); - final String baseUrl = OPRConstants.getBaseUrl(app); - // all these should be constant - String url = baseUrl + "api/ipfs/image"; - String response = NetworkUtils.sendPostDataRequest(url, "file", "compressed.jpeg", serverData); - if (response != null) { - int res = 0; - try { - StringBuilder error = new StringBuilder(); - String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); - String username = app.getSettings().OPR_USERNAME.get(); - res = openDBAPI.uploadImage( - placeId, - baseUrl, - privateKey, - username, - response, error); - if (res != 200) { - showToastMessage(error.toString()); - } else { - //ok, continue - } - } catch (FailedVerificationException e) { - LOG.error(e); - checkTokenAndShowScreen(); - } - if (res != 200) { - //image was uploaded but not added to blockchain - checkTokenAndShowScreen(); - } else { - String str = app.getString(R.string.successfully_uploaded_pattern, 1, 1); - showToastMessage(str); - //refresh the image - execute(new GetImageCardsTask(mapActivity, getLatLon(), getAdditionalCardParams(), imageCardListener)); - } - } else { - checkTokenAndShowScreen(); - } - } - - private void showToastMessage(final String str) { - new Handler(Looper.getMainLooper()).post(new Runnable() { - @Override - public void run() { - Toast.makeText(mapActivity.getBaseContext(), str, Toast.LENGTH_LONG).show(); - } - }); - } - - //This method runs on non main thread - private void checkTokenAndShowScreen() { - final String baseUrl = OPRConstants.getBaseUrl(app); - final String name = app.getSettings().OPR_USERNAME.get(); - final String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); - if (openDBAPI.checkPrivateKeyValid(baseUrl, name, privateKey)) { - String str = app.getString(R.string.cannot_upload_image); - showToastMessage(str); - } else { - app.runInUIThread(new Runnable() { - @Override - public void run() { - OprStartFragment.showInstance(mapActivity.getSupportFragmentManager()); - } - }); - } - } - - private byte[] compressImageToJpeg(InputStream image) { - BufferedInputStream bufferedInputStream = new BufferedInputStream(image); - Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - int h = bmp.getHeight(); - int w = bmp.getWidth(); - boolean scale = false; - while (w > MAX_IMAGE_LENGTH || h > MAX_IMAGE_LENGTH) { - w = w / 2; - h = h / 2; - scale = true; - } - if (scale) { - Matrix matrix = new Matrix(); - matrix.postScale(w, h); - Bitmap resizedBitmap = Bitmap.createBitmap( - bmp, 0, 0, w, h, matrix, false); - bmp.recycle(); - bmp = resizedBitmap; - } - bmp.compress(Bitmap.CompressFormat.JPEG, 90, os); - return os.toByteArray(); - } - private void startLoadingImages() { if (onlinePhotoCardsRow == null) { return; diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java new file mode 100644 index 0000000000..ce59999a11 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java @@ -0,0 +1,203 @@ +package net.osmand.plus.mapcontextmenu; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +import android.net.Uri; +import android.os.AsyncTask; + +import androidx.fragment.app.FragmentActivity; + +import net.osmand.AndroidUtils; +import net.osmand.PlatformUtil; +import net.osmand.data.LatLon; +import net.osmand.osm.io.NetworkUtils; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.dialogs.UploadPhotoWithProgressBarBottomSheet; +import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask; +import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener; +import net.osmand.plus.openplacereviews.OPRConstants; +import net.osmand.plus.openplacereviews.OprStartFragment; +import net.osmand.plus.osmedit.opr.OpenDBAPI; +import net.osmand.util.Algorithms; + +import org.apache.commons.logging.Log; +import org.openplacereviews.opendb.util.exception.FailedVerificationException; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.lang.ref.WeakReference; +import java.util.List; +import java.util.Map; + +public class UploadPhotosAsyncTask extends AsyncTask { + + private static final Log LOG = PlatformUtil.getLog(UploadPhotosAsyncTask.class); + + private static final int MAX_IMAGE_LENGTH = 2048; + + private final OsmandApplication app; + private final WeakReference activityRef; + private UploadPhotoWithProgressBarBottomSheet progress; + + private final OpenDBAPI openDBAPI = new OpenDBAPI(); + private final LatLon latLon; + private final List data; + private final String[] placeId; + private final Map params; + private final GetImageCardsListener imageCardListener; + + public UploadPhotosAsyncTask(MapActivity activity, List data, LatLon latLon, String[] placeId, + Map params, GetImageCardsListener imageCardListener) { + app = (OsmandApplication) activity.getApplicationContext(); + activityRef = new WeakReference<>(activity); + this.data = data; + this.latLon = latLon; + this.params = params; + this.placeId = placeId; + this.imageCardListener = imageCardListener; + } + + @Override + protected void onPreExecute() { + FragmentActivity activity = activityRef.get(); + if (AndroidUtils.isActivityNotDestroyed(activity)) { + progress = UploadPhotoWithProgressBarBottomSheet.showInstance(activity.getSupportFragmentManager(), data.size()); + } + } + + protected Void doInBackground(Void... uris) { + for (int i = 0; i < data.size(); i++) { + if (isCancelled()) { + break; + } + Uri uri = data.get(i); + handleSelectedImage(uri); + publishProgress(i); + } + return null; + } + + @Override + protected void onProgressUpdate(Integer... values) { + if (progress != null) { + progress.onProgressUpdate(values[0]); + } + } + + @Override + protected void onPostExecute(Void aVoid) { + if (progress != null) { + progress.onUploadingFinished(); + } + } + + private void handleSelectedImage(final Uri uri) { + InputStream inputStream = null; + try { + inputStream = app.getContentResolver().openInputStream(uri); + if (inputStream != null) { + uploadImageToPlace(inputStream); + } + } catch (Exception e) { + LOG.error(e); + app.showToastMessage(R.string.cannot_upload_image); + } finally { + Algorithms.closeStream(inputStream); + } + } + + private void uploadImageToPlace(InputStream image) { + InputStream serverData = new ByteArrayInputStream(compressImageToJpeg(image)); + final String baseUrl = OPRConstants.getBaseUrl(app); + // all these should be constant + String url = baseUrl + "api/ipfs/image"; + String response = NetworkUtils.sendPostDataRequest(url, "file", "compressed.jpeg", serverData); + if (response != null) { + int res = 0; + try { + StringBuilder error = new StringBuilder(); + String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); + String username = app.getSettings().OPR_USERNAME.get(); + res = openDBAPI.uploadImage( + placeId, + baseUrl, + privateKey, + username, + response, error); + if (res != 200) { + app.showToastMessage(error.toString()); + } else { + //ok, continue + } + } catch (FailedVerificationException e) { + LOG.error(e); + checkTokenAndShowScreen(); + } + if (res != 200) { + //image was uploaded but not added to blockchain + checkTokenAndShowScreen(); + } else { + String str = app.getString(R.string.successfully_uploaded_pattern, 1, 1); + app.showToastMessage(str); + //refresh the image + + MapActivity activity = activityRef.get(); + if (activity != null) { + MenuBuilder.execute(new GetImageCardsTask(activity, latLon, params, imageCardListener)); + } + } + } else { + checkTokenAndShowScreen(); + } + } + + //This method runs on non main thread + private void checkTokenAndShowScreen() { + final String baseUrl = OPRConstants.getBaseUrl(app); + final String name = app.getSettings().OPR_USERNAME.get(); + final String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); + if (openDBAPI.checkPrivateKeyValid(baseUrl, name, privateKey)) { + String str = app.getString(R.string.cannot_upload_image); + app.showToastMessage(str); + } else { + app.runInUIThread(new Runnable() { + @Override + public void run() { + MapActivity activity = activityRef.get(); + if (activity != null) { + OprStartFragment.showInstance(activity.getSupportFragmentManager()); + } + } + }); + } + } + + private byte[] compressImageToJpeg(InputStream image) { + BufferedInputStream bufferedInputStream = new BufferedInputStream(image); + Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + int h = bmp.getHeight(); + int w = bmp.getWidth(); + boolean scale = false; + while (w > MAX_IMAGE_LENGTH || h > MAX_IMAGE_LENGTH) { + w = w / 2; + h = h / 2; + scale = true; + } + if (scale) { + Matrix matrix = new Matrix(); + matrix.postScale(w, h); + Bitmap resizedBitmap = Bitmap.createBitmap( + bmp, 0, 0, w, h, matrix, false); + bmp.recycle(); + bmp = resizedBitmap; + } + bmp.compress(Bitmap.CompressFormat.JPEG, 90, os); + return os.toByteArray(); + } +} \ No newline at end of file From 829c1ae9989f59a49ab49629595e9b45986845f0 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 27 Jan 2021 18:21:36 +0200 Subject: [PATCH 2/3] Request review --- .../layout/bottom_sheet_with_progress_bar.xml | 1 - OsmAnd/res/values/strings.xml | 4 +- .../UploadPhotoProgressBottomSheet.java | 118 ++++++++++++++++++ ...UploadPhotoWithProgressBarBottomSheet.java | 111 ---------------- .../plus/mapcontextmenu/MenuBuilder.java | 6 - .../mapcontextmenu/UploadPhotosAsyncTask.java | 53 +++++--- 6 files changed, 155 insertions(+), 138 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java delete mode 100644 OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoWithProgressBarBottomSheet.java diff --git a/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml b/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml index fd1f27bbae..66583734bf 100644 --- a/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml +++ b/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml @@ -4,7 +4,6 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/selectableItemBackground" android:minHeight="@dimen/bottom_sheet_selected_item_title_height" android:orientation="vertical" android:paddingStart="@dimen/content_padding" diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 4b4b94826e..17f80d6b39 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,8 +11,8 @@ Thx - Hardy --> - Uploaded %1$s of %2$d - Uploading %1$s of %2$d + Uploaded %1$d of %2$d + Uploading %1$d of %2$d Upload completed Uploading Copy to favorites diff --git a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java new file mode 100644 index 0000000000..d5b618310b --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java @@ -0,0 +1,118 @@ +package net.osmand.plus.dialogs; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnDismissListener; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; +import net.osmand.plus.mapcontextmenu.UploadPhotosAsyncTask.UploadPhotosListener; + +public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragment implements UploadPhotosListener { + + public static final String TAG = UploadPhotoProgressBottomSheet.class.getSimpleName(); + + private ProgressBar progressBar; + private TextView uploadedPhotosTitle; + private TextView uploadedPhotosCounter; + + private OnDismissListener onDismissListener; + + private int progress; + private int maxProgress; + String descriptionProgress; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + Context context = requireContext(); + LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); + View view = inflater.inflate(R.layout.bottom_sheet_with_progress_bar, null); + + uploadedPhotosTitle = view.findViewById(R.id.title); + uploadedPhotosCounter = view.findViewById(R.id.description); + progressBar = view.findViewById(R.id.progress_bar); + progressBar.setMax(maxProgress); + String titleProgress = getString(progress == maxProgress? R.string.upload_photo_completed: R.string.upload_photo); + if (progress == maxProgress) { + descriptionProgress = getString(R.string.uploaded_count, progress, maxProgress); + } else { + descriptionProgress = getString(R.string.uploading_count, progress, maxProgress); + } + + BaseBottomSheetItem descriptionItem = new BottomSheetItemWithDescription.Builder() + .setDescription(descriptionProgress) + .setTitle(titleProgress) + .setCustomView(view) + .create(); + items.add(descriptionItem); + + updateProgress(progress); + + int padding = getResources().getDimensionPixelSize(R.dimen.content_padding_small); + items.add(new DividerSpaceItem(context, padding)); + } + + public void setMaxProgress(int maxProgress) { + this.maxProgress = maxProgress; + } + + public void setOnDismissListener(OnDismissListener onDismissListener) { + this.onDismissListener = onDismissListener; + } + + private void updateProgress(int progress) { + progressBar.setProgress(progress); + uploadedPhotosCounter.setText((getString(R.string.uploading_count, progress, maxProgress))); + uploadedPhotosTitle.setText(progress == maxProgress ? R.string.upload_photo_completed : R.string.upload_photo); + } + + @Override + public void uploadPhotosProgressUpdate(int progress) { + this.progress = progress; + updateProgress(progress); + } + + @Override + public void uploadPhotosFinished() { + updateProgress(maxProgress); + if (progress == maxProgress) { + uploadedPhotosCounter.setText((getString(R.string.uploaded_count, progress, maxProgress))); + setDismissButtonTextId(R.string.shared_string_close); + UiUtilities.setupDialogButton(nightMode, dismissButton, getDismissButtonType(), getDismissButtonTextId()); + } + } + + @Override + public void onDismiss(@NonNull DialogInterface dialog) { + super.onDismiss(dialog); + FragmentActivity activity = getActivity(); + if (onDismissListener != null && activity != null && !activity.isChangingConfigurations()) { + onDismissListener.onDismiss(dialog); + } + } + + public static UploadPhotosListener showInstance(@NonNull FragmentManager fragmentManager, int maxProgress, OnDismissListener listener) { + UploadPhotoProgressBottomSheet fragment = new UploadPhotoProgressBottomSheet(); + fragment.setRetainInstance(true); + fragment.setMaxProgress(maxProgress); + fragment.setOnDismissListener(listener); + fragmentManager.beginTransaction() + .add(fragment, UploadPhotoProgressBottomSheet.TAG) + .commitAllowingStateLoss(); + + return fragment; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoWithProgressBarBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoWithProgressBarBottomSheet.java deleted file mode 100644 index 73e09845a3..0000000000 --- a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoWithProgressBarBottomSheet.java +++ /dev/null @@ -1,111 +0,0 @@ -package net.osmand.plus.dialogs; - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.ProgressBar; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentManager; - -import net.osmand.plus.R; -import net.osmand.plus.UiUtilities; -import net.osmand.plus.UiUtilities.DialogButtonType; -import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.base.MenuBottomSheetDialogFragment; -import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; -import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; -import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; -import net.osmand.plus.widgets.TextViewEx; - -public class UploadPhotoWithProgressBarBottomSheet extends MenuBottomSheetDialogFragment { - - public static final String TAG = UploadPhotoWithProgressBarBottomSheet.class.getSimpleName(); - - private ProgressBar progressBar; - private TextView uploadedPhotosCounter; - private TextViewEx uploadedPhotosTitle; - private int maxProgress; - - @Override - public void createMenuItems(Bundle savedInstanceState) { - Context context = requireContext(); - LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); - View view = inflater.inflate(R.layout.bottom_sheet_with_progress_bar, null); - - progressBar = view.findViewById(R.id.progress_bar); - progressBar.setMax(maxProgress); - uploadedPhotosCounter = view.findViewById(R.id.description); - - uploadedPhotosTitle = view.findViewById(R.id.title); - - BaseBottomSheetItem descriptionItem = new BottomSheetItemWithDescription.Builder() - .setDescription(getString(R.string.uploading_count, progressBar.getProgress(), maxProgress)) - .setTitle(getString(R.string.upload_photo)) - .setCustomView(view) - .create(); - items.add(descriptionItem); - - int padding = getResources().getDimensionPixelSize(R.dimen.content_padding_small); - items.add(new DividerSpaceItem(requireContext(), padding)); - } - - public void onProgressUpdate(int progress) { - progressBar.setProgress(progress); - uploadedPhotosCounter.setText((getString(R.string.uploading_count, progressBar.getProgress(), maxProgress))); - } - - public void onUploadingFinished() { - TextViewEx dismissButtonText = dismissButton.findViewById(R.id.button_text); - setDismissButtonTextId(R.string.shared_string_close); - dismissButtonText.setText(R.string.shared_string_close); - uploadedPhotosTitle.setText(R.string.upload_photo_completed); - uploadedPhotosCounter.setText((getString(R.string.uploaded_count, progressBar.getProgress(), maxProgress))); - } - - @Override - protected boolean useVerticalButtons() { - return true; - } - - @Override - protected int getDismissButtonTextId() { - return R.string.shared_string_cancel; - } - - @Override - protected DialogButtonType getRightBottomButtonType() { - return DialogButtonType.PRIMARY; - } - - @Override - public int getSecondDividerHeight() { - return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin); - } - - @Override - protected void onRightBottomButtonClick() { - dismiss(); - } - - @Nullable - public MapActivity getMapActivity() { - Activity activity = getActivity(); - if (activity instanceof MapActivity) { - return (MapActivity) activity; - } - return null; - } - - public static UploadPhotoWithProgressBarBottomSheet showInstance(@NonNull FragmentManager fragmentManager, int maxProgress) { - UploadPhotoWithProgressBarBottomSheet fragment = new UploadPhotoWithProgressBarBottomSheet(); - fragment.maxProgress = maxProgress; - fragment.setRetainInstance(true); - fragmentManager.beginTransaction().add(fragment, TAG).commitAllowingStateLoss(); - return fragment; - } -} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index 98198d65f3..183e41a84f 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -36,7 +36,6 @@ import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; import net.osmand.AndroidUtils; -import net.osmand.PlatformUtil; import net.osmand.data.Amenity; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; @@ -76,8 +75,6 @@ import net.osmand.plus.widgets.tools.ClickableSpanTouchListener; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; -import org.apache.commons.logging.Log; - import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -91,7 +88,6 @@ import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCa public class MenuBuilder { private static final int PICK_IMAGE = 1231; - private static final Log LOG = PlatformUtil.getLog(MenuBuilder.class); public static final float SHADOW_HEIGHT_TOP_DP = 17f; public static final int TITLE_LIMIT = 60; protected static final String[] arrowChars = new String[] {"=>", " - "}; @@ -124,7 +120,6 @@ public class MenuBuilder { private String preferredMapLang; private String preferredMapAppLang; private boolean transliterateNames; - private View view; private View photoButton; private final OpenDBAPI openDBAPI = new OpenDBAPI(); @@ -261,7 +256,6 @@ public class MenuBuilder { } public void build(View view) { - this.view = view; firstRow = true; hidden = false; buildTopInternal(view); diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java index ce59999a11..30932e8b42 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/UploadPhotosAsyncTask.java @@ -1,5 +1,7 @@ package net.osmand.plus.mapcontextmenu; +import android.content.DialogInterface; +import android.content.DialogInterface.OnDismissListener; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; @@ -7,6 +9,7 @@ import android.net.Uri; import android.os.AsyncTask; import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; @@ -15,7 +18,7 @@ import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.dialogs.UploadPhotoWithProgressBarBottomSheet; +import net.osmand.plus.dialogs.UploadPhotoProgressBottomSheet; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener; import net.osmand.plus.openplacereviews.OPRConstants; @@ -42,7 +45,7 @@ public class UploadPhotosAsyncTask extends AsyncTask { private final OsmandApplication app; private final WeakReference activityRef; - private UploadPhotoWithProgressBarBottomSheet progress; + private UploadPhotosListener listener; private final OpenDBAPI openDBAPI = new OpenDBAPI(); private final LatLon latLon; @@ -66,7 +69,20 @@ public class UploadPhotosAsyncTask extends AsyncTask { protected void onPreExecute() { FragmentActivity activity = activityRef.get(); if (AndroidUtils.isActivityNotDestroyed(activity)) { - progress = UploadPhotoWithProgressBarBottomSheet.showInstance(activity.getSupportFragmentManager(), data.size()); + FragmentManager manager = activity.getSupportFragmentManager(); + listener = UploadPhotoProgressBottomSheet.showInstance(manager, data.size(), new OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + cancel(false); + } + }); + } + } + + @Override + protected void onProgressUpdate(Integer... values) { + if (listener != null) { + listener.uploadPhotosProgressUpdate(values[0]); } } @@ -77,22 +93,15 @@ public class UploadPhotosAsyncTask extends AsyncTask { } Uri uri = data.get(i); handleSelectedImage(uri); - publishProgress(i); + publishProgress(i + 1); } return null; } - @Override - protected void onProgressUpdate(Integer... values) { - if (progress != null) { - progress.onProgressUpdate(values[0]); - } - } - @Override protected void onPostExecute(Void aVoid) { - if (progress != null) { - progress.onUploadingFinished(); + if (listener != null) { + listener.uploadPhotosFinished(); } } @@ -158,12 +167,11 @@ public class UploadPhotosAsyncTask extends AsyncTask { //This method runs on non main thread private void checkTokenAndShowScreen() { - final String baseUrl = OPRConstants.getBaseUrl(app); - final String name = app.getSettings().OPR_USERNAME.get(); - final String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); + String baseUrl = OPRConstants.getBaseUrl(app); + String name = app.getSettings().OPR_USERNAME.get(); + String privateKey = app.getSettings().OPR_ACCESS_TOKEN.get(); if (openDBAPI.checkPrivateKeyValid(baseUrl, name, privateKey)) { - String str = app.getString(R.string.cannot_upload_image); - app.showToastMessage(str); + app.showToastMessage(R.string.cannot_upload_image); } else { app.runInUIThread(new Runnable() { @Override @@ -200,4 +208,13 @@ public class UploadPhotosAsyncTask extends AsyncTask { bmp.compress(Bitmap.CompressFormat.JPEG, 90, os); return os.toByteArray(); } + + + public interface UploadPhotosListener { + + void uploadPhotosProgressUpdate(int progress); + + void uploadPhotosFinished(); + + } } \ No newline at end of file From 7ff2b92dfb6f8c69a245c441a896df3733d1cce0 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 27 Jan 2021 18:41:50 +0200 Subject: [PATCH 3/3] Global variable, code styling --- .../layout/bottom_sheet_with_progress_bar.xml | 82 +++++++++---------- .../UploadPhotoProgressBottomSheet.java | 2 +- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml b/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml index 66583734bf..258489706b 100644 --- a/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml +++ b/OsmAnd/res/layout/bottom_sheet_with_progress_bar.xml @@ -1,48 +1,48 @@ + xmlns:osmand="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="@dimen/bottom_sheet_selected_item_title_height" + android:orientation="vertical" + android:paddingStart="@dimen/content_padding" + android:paddingLeft="@dimen/content_padding" + android:paddingTop="@dimen/measurement_tool_menu_title_padding_top" + android:paddingEnd="@dimen/content_padding" + android:paddingRight="@dimen/content_padding" + android:paddingBottom="@dimen/content_padding_small"> - + - + - + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java index d5b618310b..f1c37a55ee 100644 --- a/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/dialogs/UploadPhotoProgressBottomSheet.java @@ -33,7 +33,6 @@ public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragmen private int progress; private int maxProgress; - String descriptionProgress; @Override public void createMenuItems(Bundle savedInstanceState) { @@ -46,6 +45,7 @@ public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragmen progressBar = view.findViewById(R.id.progress_bar); progressBar.setMax(maxProgress); String titleProgress = getString(progress == maxProgress? R.string.upload_photo_completed: R.string.upload_photo); + String descriptionProgress; if (progress == maxProgress) { descriptionProgress = getString(R.string.uploaded_count, progress, maxProgress); } else {