Fixes and improvements

This commit is contained in:
Thomas 2023-01-15 16:04:51 +01:00
parent 3ab25e3333
commit ce9d4c2cd3
8 changed files with 205 additions and 87 deletions

View File

@ -14,6 +14,8 @@ package app.fedilab.android.activities;
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.ui.fragment.media.FragmentMediaProfile.mediaAttachmentProfile;
import android.Manifest;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
@ -26,6 +28,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
@ -95,6 +98,7 @@ public class MediaActivity extends BaseTransparentActivity implements OnDownload
private ActivityMediaPagerBinding binding;
private FragmentMedia mCurrentFragment;
private Status status;
private boolean mediaFromProfile;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -105,14 +109,21 @@ public class MediaActivity extends BaseTransparentActivity implements OnDownload
binding = ActivityMediaPagerBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
fullscreen = false;
flags = getWindow().getDecorView().getSystemUiVisibility();
Bundle b = getIntent().getExtras();
if (b != null) {
mediaPosition = b.getInt(Helper.ARG_MEDIA_POSITION, 1);
attachments = (ArrayList<Attachment>) b.getSerializable(Helper.ARG_MEDIA_ARRAY);
mediaFromProfile = b.getBoolean(Helper.ARG_MEDIA_ARRAY_PROFILE, false);
status = (Status) b.getSerializable(Helper.ARG_STATUS);
}
Log.v(Helper.TAG, "mediaPosition: " + mediaPosition);
if (mediaFromProfile && mediaAttachmentProfile != null) {
attachments = new ArrayList<>();
attachments.addAll(mediaAttachmentProfile);
}
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
@ -130,10 +141,10 @@ public class MediaActivity extends BaseTransparentActivity implements OnDownload
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
String description = attachments.get(mediaPosition - 1).description;
handler = new Handler();
if (status != null) {
if (attachments.get(mediaPosition - 1).status != null) {
binding.originalMessage.setOnClickListener(v -> {
Intent intentContext = new Intent(MediaActivity.this, ContextActivity.class);
intentContext.putExtra(Helper.ARG_STATUS, status);
intentContext.putExtra(Helper.ARG_STATUS, attachments.get(mediaPosition - 1).status);
intentContext.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intentContext);
});
@ -171,6 +182,7 @@ public class MediaActivity extends BaseTransparentActivity implements OnDownload
}
public void onPageSelected(int position) {
mediaPosition = position;
String description = attachments.get(position).description;
if (handler != null) {
handler.removeCallbacksAndMessages(null);
@ -386,7 +398,7 @@ public class MediaActivity extends BaseTransparentActivity implements OnDownload
showSystemUI();
binding.mediaDescription.setVisibility(View.VISIBLE);
binding.translate.setVisibility(View.VISIBLE);
if (status != null) {
if (mediaFromProfile) {
binding.originalMessage.setVisibility(View.VISIBLE);
}
} else {

View File

@ -14,6 +14,8 @@ package app.fedilab.android.client.entities.api;
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import androidx.annotation.Nullable;
import com.google.gson.annotations.SerializedName;
import java.io.Serializable;
@ -52,7 +54,7 @@ public class Attachment implements Serializable {
public String peertubeId = null;
public String focus = null;
public String translation = null;
public transient Status status = null;
public static class Meta implements Serializable {
@SerializedName("focus")
@ -80,4 +82,15 @@ public class Attachment implements Serializable {
@SerializedName("aspect")
public float aspect;
}
@Override
public boolean equals(@Nullable Object obj) {
boolean same = false;
if (obj instanceof Attachment) {
same = this.id.equals(((Attachment) obj).id);
}
return same;
}
}

View File

@ -272,6 +272,7 @@ public class Helper {
public static final String ARG_CHECK_REMOTELY = "ARG_CHECK_REMOTELY";
public static final String ARG_USER_ID = "ARG_USER_ID";
public static final String ARG_MEDIA_ARRAY = "ARG_MEDIA_ARRAY";
public static final String ARG_MEDIA_ARRAY_PROFILE = "ARG_MEDIA_ARRAY_PROFILE";
public static final String ARG_VISIBILITY = "ARG_VISIBILITY";
public static final String ARG_SCHEDULED_DATE = "ARG_SCHEDULED_DATE";

View File

@ -56,6 +56,7 @@ import com.bumptech.glide.Glide;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
@ -370,64 +371,126 @@ public class SpannableHelper {
new Thread(() -> {
try {
String redirect = null;
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) finalUrlCheck.openConnection();
httpsURLConnection.setConnectTimeout(10 * 1000);
httpsURLConnection.setRequestProperty("http.keepAlive", "false");
//httpsURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpsURLConnection.setRequestMethod("HEAD");
httpsURLConnection.setInstanceFollowRedirects(false);
if (httpsURLConnection.getResponseCode() == 301 || httpsURLConnection.getResponseCode() == 302) {
Map<String, List<String>> map = httpsURLConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
if (entry.toString().toLowerCase().startsWith("location")) {
Matcher matcher = Patterns.WEB_URL.matcher(entry.toString());
if (matcher.find()) {
redirect = matcher.group(1);
if (finalUrl.startsWith("http://")) {
HttpURLConnection httpURLConnection = (HttpURLConnection) finalUrlCheck.openConnection();
httpURLConnection.setConnectTimeout(10 * 1000);
httpURLConnection.setRequestProperty("http.keepAlive", "false");
//httpsURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpURLConnection.setRequestMethod("HEAD");
httpURLConnection.setInstanceFollowRedirects(false);
if (httpURLConnection.getResponseCode() == 301 || httpURLConnection.getResponseCode() == 302) {
Map<String, List<String>> map = httpURLConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
if (entry.toString().toLowerCase().startsWith("location")) {
Matcher matcher = Patterns.WEB_URL.matcher(entry.toString());
if (matcher.find()) {
redirect = matcher.group(1);
}
}
}
}
}
httpsURLConnection.getInputStream().close();
if (redirect != null && redirect.compareTo(finalUrl) != 0) {
URL redirectURL = new URL(redirect);
String host = redirectURL.getHost();
String protocol = redirectURL.getProtocol();
if (protocol == null || host == null) {
redirect = null;
httpURLConnection.getInputStream().close();
if (redirect != null && redirect.compareTo(finalUrl) != 0) {
URL redirectURL = new URL(redirect);
String host = redirectURL.getHost();
String protocol = redirectURL.getProtocol();
if (protocol == null || host == null) {
redirect = null;
}
}
}
Handler mainHandler = new Handler(context.getMainLooper());
String finalRedirect = redirect;
Runnable myRunnable = () -> {
AlertDialog.Builder builder1 = new AlertDialog.Builder(view.getContext());
if (finalRedirect != null) {
builder1.setMessage(context.getString(R.string.redirect_detected, finalUrl, finalRedirect));
builder1.setNegativeButton(R.string.copy_link, (dialog, which) -> {
ClipboardManager clipboard1 = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip1 = ClipData.newPlainText(Helper.CLIP_BOARD, finalRedirect);
if (clipboard1 != null) {
clipboard1.setPrimaryClip(clip1);
Toasty.info(context, context.getString(R.string.clipboard_url), Toast.LENGTH_LONG).show();
}
dialog.dismiss();
});
builder1.setNeutralButton(R.string.share_link, (dialog, which) -> {
Intent sendIntent1 = new Intent(Intent.ACTION_SEND);
sendIntent1.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.shared_via));
sendIntent1.putExtra(Intent.EXTRA_TEXT, finalUrl);
sendIntent1.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent1, context.getString(R.string.share_with)));
dialog.dismiss();
});
} else {
builder1.setMessage(R.string.no_redirect);
}
builder1.setTitle(context.getString(R.string.check_redirect));
builder1.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss())
.show();
Handler mainHandler = new Handler(context.getMainLooper());
String finalRedirect = redirect;
Runnable myRunnable = () -> {
AlertDialog.Builder builder1 = new AlertDialog.Builder(view.getContext());
if (finalRedirect != null) {
builder1.setMessage(context.getString(R.string.redirect_detected, finalUrl, finalRedirect));
builder1.setNegativeButton(R.string.copy_link, (dialog, which) -> {
ClipboardManager clipboard1 = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip1 = ClipData.newPlainText(Helper.CLIP_BOARD, finalRedirect);
if (clipboard1 != null) {
clipboard1.setPrimaryClip(clip1);
Toasty.info(context, context.getString(R.string.clipboard_url), Toast.LENGTH_LONG).show();
}
dialog.dismiss();
});
builder1.setNeutralButton(R.string.share_link, (dialog, which) -> {
Intent sendIntent1 = new Intent(Intent.ACTION_SEND);
sendIntent1.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.shared_via));
sendIntent1.putExtra(Intent.EXTRA_TEXT, finalUrl);
sendIntent1.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent1, context.getString(R.string.share_with)));
dialog.dismiss();
});
} else {
builder1.setMessage(R.string.no_redirect);
}
builder1.setTitle(context.getString(R.string.check_redirect));
builder1.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss())
.show();
};
mainHandler.post(myRunnable);
} else {
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) finalUrlCheck.openConnection();
httpsURLConnection.setConnectTimeout(10 * 1000);
httpsURLConnection.setRequestProperty("http.keepAlive", "false");
//httpsURLConnection.setRequestProperty("User-Agent", USER_AGENT);
httpsURLConnection.setRequestMethod("HEAD");
httpsURLConnection.setInstanceFollowRedirects(false);
if (httpsURLConnection.getResponseCode() == 301 || httpsURLConnection.getResponseCode() == 302) {
Map<String, List<String>> map = httpsURLConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
if (entry.toString().toLowerCase().startsWith("location")) {
Matcher matcher = Patterns.WEB_URL.matcher(entry.toString());
if (matcher.find()) {
redirect = matcher.group(1);
}
}
}
}
httpsURLConnection.getInputStream().close();
if (redirect != null && redirect.compareTo(finalUrl) != 0) {
URL redirectURL = new URL(redirect);
String host = redirectURL.getHost();
String protocol = redirectURL.getProtocol();
if (protocol == null || host == null) {
redirect = null;
}
}
Handler mainHandler = new Handler(context.getMainLooper());
String finalRedirect = redirect;
Runnable myRunnable = () -> {
AlertDialog.Builder builder1 = new AlertDialog.Builder(view.getContext());
if (finalRedirect != null) {
builder1.setMessage(context.getString(R.string.redirect_detected, finalUrl, finalRedirect));
builder1.setNegativeButton(R.string.copy_link, (dialog, which) -> {
ClipboardManager clipboard1 = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip1 = ClipData.newPlainText(Helper.CLIP_BOARD, finalRedirect);
if (clipboard1 != null) {
clipboard1.setPrimaryClip(clip1);
Toasty.info(context, context.getString(R.string.clipboard_url), Toast.LENGTH_LONG).show();
}
dialog.dismiss();
});
builder1.setNeutralButton(R.string.share_link, (dialog, which) -> {
Intent sendIntent1 = new Intent(Intent.ACTION_SEND);
sendIntent1.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.shared_via));
sendIntent1.putExtra(Intent.EXTRA_TEXT, finalUrl);
sendIntent1.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent1, context.getString(R.string.share_with)));
dialog.dismiss();
});
} else {
builder1.setMessage(R.string.no_redirect);
}
builder1.setTitle(context.getString(R.string.check_redirect));
builder1.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss())
.show();
};
mainHandler.post(myRunnable);
}
};
mainHandler.post(myRunnable);
} catch (IOException e) {
e.printStackTrace();
}

View File

@ -14,6 +14,8 @@ package app.fedilab.android.ui.drawer;
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.ui.fragment.media.FragmentMediaProfile.mediaAttachmentProfile;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@ -27,31 +29,26 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.activities.ContextActivity;
import app.fedilab.android.activities.MediaActivity;
import app.fedilab.android.client.entities.api.Attachment;
import app.fedilab.android.client.entities.api.Status;
import app.fedilab.android.databinding.DrawerMediaBinding;
import app.fedilab.android.helper.Helper;
public class ImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final List<Status> statuses;
private Context context;
public ImageAdapter(List<Status> statuses) {
this.statuses = statuses;
public ImageAdapter() {
}
public int getCount() {
return statuses.size();
return mediaAttachmentProfile.size();
}
public Status getItem(int position) {
return statuses.get(position);
public Attachment getItem(int position) {
return mediaAttachmentProfile.get(position);
}
@NonNull
@ -64,35 +61,40 @@ public class ImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
Status status = statuses.get(position);
Attachment attachment = mediaAttachmentProfile.get(position);
final ViewHolder holder = (ViewHolder) viewHolder;
if (Helper.isValidContextForGlide(context) && status.art_attachment != null) {
if (status.art_attachment.preview_url != null) {
Glide.with(context).load(status.art_attachment.preview_url).into(holder.binding.media);
} else if (status.art_attachment.url != null) {
Glide.with(context).load(status.art_attachment.url).into(holder.binding.media);
if (Helper.isValidContextForGlide(context) && attachment != null) {
if (attachment.preview_url != null) {
Glide.with(context).load(attachment.preview_url).into(holder.binding.media);
} else if (attachment.url != null) {
Glide.with(context).load(attachment.url).into(holder.binding.media);
}
}
holder.binding.media.setOnClickListener(v -> {
Intent mediaIntent = new Intent(context, MediaActivity.class);
Bundle b = new Bundle();
b.putInt(Helper.ARG_MEDIA_POSITION, 1);
ArrayList<Attachment> attachmentsTmp = new ArrayList<>();
attachmentsTmp.add(status.art_attachment);
b.putSerializable(Helper.ARG_STATUS, status);
b.putSerializable(Helper.ARG_MEDIA_ARRAY, new ArrayList<>(attachmentsTmp));
b.putInt(Helper.ARG_MEDIA_POSITION, position + 1);
b.putBoolean(Helper.ARG_MEDIA_ARRAY_PROFILE, true);
mediaIntent.putExtras(b);
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, holder.binding.media, status.media_attachments.get(0).url);
ActivityOptionsCompat options = null;
if (attachment != null) {
options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, holder.binding.media, attachment.url);
} else {
return;
}
// start the new activity
context.startActivity(mediaIntent, options.toBundle());
});
holder.binding.media.setOnLongClickListener(v -> {
Intent intentContext = new Intent(context, ContextActivity.class);
intentContext.putExtra(Helper.ARG_STATUS, status);
if (attachment != null) {
intentContext.putExtra(Helper.ARG_STATUS, attachment.status);
} else {
return false;
}
intentContext.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentContext);
return false;
@ -105,7 +107,7 @@ public class ImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
@Override
public int getItemCount() {
return statuses.size();
return mediaAttachmentProfile.size();
}

View File

@ -149,7 +149,7 @@ public class FragmentMedia extends Fragment {
binding.mediaPicture.setVisibility(View.VISIBLE);
final Handler handler = new Handler();
handler.postDelayed(() -> {
if (Helper.isValidContextForGlide(requireActivity()) && isAdded()) {
if (isAdded() && Helper.isValidContextForGlide(requireActivity())) {
Glide.with(requireActivity())
.asBitmap()
.dontTransform()

View File

@ -57,6 +57,8 @@ public class FragmentMediaProfile extends Fragment {
private ImageAdapter imageAdapter;
private boolean checkRemotely;
private String accountId;
public static List<Attachment> mediaAttachmentProfile;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -115,7 +117,7 @@ public class FragmentMediaProfile extends Fragment {
* @param statuses {@link Statuses}
*/
private void initializeStatusesCommonView(final Statuses statuses) {
mediaAttachmentProfile = new ArrayList<>();
flagLoading = false;
if (binding == null || !isAdded() || getActivity() == null) {
return;
@ -139,7 +141,7 @@ public class FragmentMediaProfile extends Fragment {
}
}
}
imageAdapter = new ImageAdapter(mediaStatuses);
imageAdapter = new ImageAdapter();
flagLoading = statuses.pagination.max_id == null;
binding.recyclerView.setVisibility(View.VISIBLE);
@ -179,7 +181,7 @@ public class FragmentMediaProfile extends Fragment {
}
}
});
fillWithMedia();
}
@ -223,5 +225,23 @@ public class FragmentMediaProfile extends Fragment {
} else {
flagLoading = true;
}
fillWithMedia();
}
public void fillWithMedia() {
if (mediaStatuses != null && mediaStatuses.size() > 0) {
for (Status status : mediaStatuses) {
if (status.media_attachments != null && status.media_attachments.size() > 0) {
for (Attachment attachment : status.media_attachments) {
attachment.status = status;
if (!mediaAttachmentProfile.contains(attachment)) {
mediaAttachmentProfile.add(attachment);
}
}
}
}
}
}
}

View File

@ -0,0 +1,7 @@
Changed:
- Allow to swipe media for profiles
Fixed:
- Fix crashes with pinch zoom
- Fix crash when checking redirection on http links
- Displaying options for media reset zoom