diff --git a/app/build.gradle b/app/build.gradle index 6e554190e..fa54ae20b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,12 +2,12 @@ apply plugin: 'com.android.application' android { compileSdkVersion 29 - buildToolsVersion "29.0.2" + buildToolsVersion "29.0.3" defaultConfig { minSdkVersion 19 targetSdkVersion 29 - versionCode 363 - versionName "2.35.0" + versionCode 365 + versionName "2.35.2" multiDexEnabled true renderscriptTargetApi 28 as int renderscriptSupportModeEnabled true diff --git a/app/src/main/assets/changelogs/364.txt b/app/src/main/assets/changelogs/364.txt new file mode 100644 index 000000000..260dbe5d1 --- /dev/null +++ b/app/src/main/assets/changelogs/364.txt @@ -0,0 +1,4 @@ +Added: +- Simple click on reactions to add them +Fixed: +- Recent crashes (connection, when scrolling) \ No newline at end of file diff --git a/app/src/main/assets/changelogs/365.txt b/app/src/main/assets/changelogs/365.txt new file mode 100644 index 000000000..ae66cb3ec --- /dev/null +++ b/app/src/main/assets/changelogs/365.txt @@ -0,0 +1,2 @@ +Fixed: +- Fix last remaining issues \ No newline at end of file diff --git a/app/src/main/java/app/fedilab/android/activities/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/activities/BaseMainActivity.java index 1fd81f6fb..072c50441 100644 --- a/app/src/main/java/app/fedilab/android/activities/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/BaseMainActivity.java @@ -179,6 +179,7 @@ public abstract class BaseMainActivity extends BaseActivity public static String regex_home, regex_local, regex_public; public static boolean show_boosts, show_replies, show_art_nsfw; public static iconLauncher mLauncher = iconLauncher.BUBBLES; + public static boolean isAttached = false; private static boolean notificationChecked = false; private final int PICK_IMPORT = 5556; private FloatingActionButton toot, delete_all, add_new; @@ -2374,6 +2375,18 @@ public abstract class BaseMainActivity extends BaseActivity } } + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + isAttached = true; + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + isAttached = false; + } + public enum iconLauncher { BUBBLES, FEDIVERSE, @@ -2521,6 +2534,7 @@ public abstract class BaseMainActivity extends BaseActivity } } + @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { if (mPageReferenceMap != null) { diff --git a/app/src/main/java/app/fedilab/android/activities/EditProfileActivity.java b/app/src/main/java/app/fedilab/android/activities/EditProfileActivity.java index 48449b116..0e18a3e79 100644 --- a/app/src/main/java/app/fedilab/android/activities/EditProfileActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/EditProfileActivity.java @@ -16,6 +16,7 @@ package app.fedilab.android.activities; import android.Manifest; +import android.annotation.SuppressLint; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -185,6 +186,7 @@ public class EditProfileActivity extends BaseActivity implements OnRetrieveAccou } + @SuppressLint("CutPasteId") @Override public void onRetrieveAccount(Account account, Error error) { if (error != null) { @@ -312,36 +314,33 @@ public class EditProfileActivity extends BaseActivity implements OnRetrieveAccou Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT); getIntent.setType("image/*"); - Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); - pickIntent.setType("image/*"); + Intent pickIntent = new Intent(Intent.ACTION_PICK); + pickIntent.setDataAndType(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*"); Intent chooserIntent = Intent.createChooser(getIntent, getString(R.string.toot_select_image)); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent}); startActivityForResult(chooserIntent, PICK_IMAGE_HEADER); }); - set_change_profile_picture.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + set_change_profile_picture.setOnClickListener(v -> { - if (ContextCompat.checkSelfPermission(EditProfileActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != - PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(EditProfileActivity.this, - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, - MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE_PICTURE); - return; - } - - Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT); - getIntent.setType("image/*"); - - Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); - pickIntent.setType("image/*"); - - Intent chooserIntent = Intent.createChooser(getIntent, getString(R.string.toot_select_image)); - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent}); - startActivityForResult(chooserIntent, PICK_IMAGE_PROFILE); + if (ContextCompat.checkSelfPermission(EditProfileActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != + PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(EditProfileActivity.this, + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE_PICTURE); + return; } + + Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT); + getIntent.setType("image/*"); + + Intent pickIntent = new Intent(Intent.ACTION_PICK); + pickIntent.setDataAndType(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); + + Intent chooserIntent = Intent.createChooser(getIntent, getString(R.string.toot_select_image)); + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent}); + startActivityForResult(chooserIntent, PICK_IMAGE_PROFILE); }); if (!EditProfileActivity.this.isFinishing()) { diff --git a/app/src/main/java/app/fedilab/android/activities/LoginActivity.java b/app/src/main/java/app/fedilab/android/activities/LoginActivity.java index 79c2178e4..692f0c430 100644 --- a/app/src/main/java/app/fedilab/android/activities/LoginActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/LoginActivity.java @@ -589,8 +589,7 @@ public class LoginActivity extends BaseActivity { String refresh_token = null; if (resobj.has("refresh_token")) refresh_token = resobj.getString("refresh_token"); - SharedPreferences sharedpreferences1 = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); - SharedPreferences.Editor editor = sharedpreferences1.edit(); + SharedPreferences.Editor editor = sharedpreferences.edit(); editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token); editor.apply(); //Update the account with the token; @@ -601,10 +600,9 @@ public class LoginActivity extends BaseActivity { } else { try { resobj = new JSONObject(response); - Account account = GNUAPI.parseAccountResponse(LoginActivity.this, resobj); + Account account = GNUAPI.parseAccountResponse(resobj); account.setToken(basicAuth); - SharedPreferences sharedpreferences1 = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); - SharedPreferences.Editor editor = sharedpreferences1.edit(); + SharedPreferences.Editor editor = sharedpreferences.edit(); editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, basicAuth); account.setInstance(instance); diff --git a/app/src/main/java/app/fedilab/android/activities/PeertubeActivity.java b/app/src/main/java/app/fedilab/android/activities/PeertubeActivity.java index ade75a356..c188ecc4e 100644 --- a/app/src/main/java/app/fedilab/android/activities/PeertubeActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/PeertubeActivity.java @@ -40,7 +40,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; -import android.webkit.WebView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.FrameLayout; @@ -106,6 +105,7 @@ import app.fedilab.android.interfaces.OnRetrievePeertubeInterface; import app.fedilab.android.sqlite.AccountDAO; import app.fedilab.android.sqlite.PeertubeFavoritesDAO; import app.fedilab.android.sqlite.Sqlite; +import app.fedilab.android.webview.CustomWebview; import app.fedilab.android.webview.MastalabWebChromeClient; import app.fedilab.android.webview.MastalabWebViewClient; import es.dmoral.toasty.Toasty; @@ -183,7 +183,7 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube peertube_description = findViewById(R.id.peertube_description); peertube_title = findViewById(R.id.peertube_title); peertube_information_container = findViewById(R.id.peertube_information_container); - WebView webview_video = findViewById(R.id.webview_video); + CustomWebview webview_video = findViewById(R.id.webview_video); playerView = findViewById(R.id.media_video); write_comment_container = findViewById(R.id.write_comment_container); ImageView my_pp = findViewById(R.id.my_pp); diff --git a/app/src/main/java/app/fedilab/android/activities/PhotoEditorActivity.java b/app/src/main/java/app/fedilab/android/activities/PhotoEditorActivity.java index 1903ae21f..97809e4d2 100644 --- a/app/src/main/java/app/fedilab/android/activities/PhotoEditorActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/PhotoEditorActivity.java @@ -56,6 +56,7 @@ import app.fedilab.android.imageeditor.filters.FilterListener; import app.fedilab.android.imageeditor.filters.FilterViewAdapter; import app.fedilab.android.imageeditor.tools.EditingToolsAdapter; import app.fedilab.android.imageeditor.tools.ToolType; +import es.dmoral.toasty.Toasty; import ja.burhanrashid52.photoeditor.OnPhotoEditorListener; import ja.burhanrashid52.photoeditor.PhotoEditor; import ja.burhanrashid52.photoeditor.PhotoEditorView; @@ -163,8 +164,11 @@ public class PhotoEditorActivity extends BaseActivity implements OnPhotoEditorLi mPhotoEditor.setOnPhotoEditorListener(this); //Set Image Dynamically - mPhotoEditorView.getSource().setImageURI(uri); - + try { + mPhotoEditorView.getSource().setImageURI(uri); + } catch (Exception e) { + Toasty.error(PhotoEditorActivity.this, getString(R.string.error)).show(); + } if (uri != null) { try (InputStream inputStream = getContentResolver().openInputStream(uri)) { diff --git a/app/src/main/java/app/fedilab/android/activities/ShowConversationActivity.java b/app/src/main/java/app/fedilab/android/activities/ShowConversationActivity.java index f21dde88e..253ecc828 100644 --- a/app/src/main/java/app/fedilab/android/activities/ShowConversationActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ShowConversationActivity.java @@ -36,6 +36,7 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; @@ -109,11 +110,11 @@ public class ShowConversationActivity extends BaseActivity implements OnRetrieve loader.setVisibility(View.VISIBLE); detailsStatus.setFocused(true); //Some spannable - Status.fillSpan(ShowConversationActivity.this, detailsStatus); + Status.fillSpan(new WeakReference<>(ShowConversationActivity.this), detailsStatus); if (detailsStatus.getPoll() != null) { - Status.makeEmojiPoll(ShowConversationActivity.this, detailsStatus.getPoll()); + Status.makeEmojiPoll(new WeakReference<>(ShowConversationActivity.this), detailsStatus.getPoll()); } - Account.makeAccountNameEmoji(ShowConversationActivity.this, detailsStatus.getAccount()); + Account.makeAccountNameEmoji(new WeakReference<>(ShowConversationActivity.this), detailsStatus.getAccount()); if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) { diff --git a/app/src/main/java/app/fedilab/android/activities/SlideMediaActivity.java b/app/src/main/java/app/fedilab/android/activities/SlideMediaActivity.java index 67bff8706..695456f1a 100644 --- a/app/src/main/java/app/fedilab/android/activities/SlideMediaActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/SlideMediaActivity.java @@ -316,7 +316,7 @@ public class SlideMediaActivity extends BaseActivity implements OnDownloadInterf public void togglePlaying(View v) { if (mCurrentFragment != null) { - mCurrentFragment.togglePlaying(v); + mCurrentFragment.togglePlaying(); } } diff --git a/app/src/main/java/app/fedilab/android/activities/WebviewActivity.java b/app/src/main/java/app/fedilab/android/activities/WebviewActivity.java index 3cceba0e2..181b39523 100644 --- a/app/src/main/java/app/fedilab/android/activities/WebviewActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/WebviewActivity.java @@ -34,7 +34,6 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; -import android.webkit.WebView; import android.widget.ArrayAdapter; import android.widget.FrameLayout; import android.widget.Toast; @@ -56,6 +55,7 @@ import app.fedilab.android.helper.CountDrawable; import app.fedilab.android.helper.Helper; import app.fedilab.android.sqlite.DomainBlockDAO; import app.fedilab.android.sqlite.Sqlite; +import app.fedilab.android.webview.CustomWebview; import app.fedilab.android.webview.MastalabWebChromeClient; import app.fedilab.android.webview.MastalabWebViewClient; import es.dmoral.toasty.Toasty; @@ -72,7 +72,7 @@ public class WebviewActivity extends BaseActivity { private String url; private String peertubeLinkToFetch; private boolean peertubeLink; - private WebView webView; + private CustomWebview webView; private Menu defaultMenu; private MastalabWebViewClient mastalabWebViewClient; diff --git a/app/src/main/java/app/fedilab/android/activities/WebviewConnectActivity.java b/app/src/main/java/app/fedilab/android/activities/WebviewConnectActivity.java index 3ad019585..c920816e1 100644 --- a/app/src/main/java/app/fedilab/android/activities/WebviewConnectActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/WebviewConnectActivity.java @@ -51,6 +51,7 @@ import app.fedilab.android.R; import app.fedilab.android.asynctasks.UpdateAccountInfoAsyncTask; import app.fedilab.android.client.HttpsConnection; import app.fedilab.android.helper.Helper; +import app.fedilab.android.webview.CustomWebview; import es.dmoral.toasty.Toasty; /** @@ -60,7 +61,7 @@ import es.dmoral.toasty.Toasty; public class WebviewConnectActivity extends BaseActivity { - private WebView webView; + private CustomWebview webView; private AlertDialog alert; private String clientId, clientSecret; private String instance; diff --git a/app/src/main/java/app/fedilab/android/asynctasks/RetrieveFeedsAsyncTask.java b/app/src/main/java/app/fedilab/android/asynctasks/RetrieveFeedsAsyncTask.java index ae776c9ca..64aa69f1c 100644 --- a/app/src/main/java/app/fedilab/android/asynctasks/RetrieveFeedsAsyncTask.java +++ b/app/src/main/java/app/fedilab/android/asynctasks/RetrieveFeedsAsyncTask.java @@ -369,9 +369,9 @@ public class RetrieveFeedsAsyncTask extends AsyncTask { List statuses = new StatusCacheDAO(contextReference.get(), db).getAllStatus(StatusCacheDAO.BOOKMARK_CACHE); if (statuses != null) { for (app.fedilab.android.client.Entities.Status status : statuses) { - app.fedilab.android.client.Entities.Status.fillSpan(contextReference.get(), status); - app.fedilab.android.client.Entities.Status.makeEmojiPoll(contextReference.get(), status.getReblog() != null ? status.getReblog().getPoll() : status.getPoll()); - Account.makeAccountNameEmoji(contextReference.get(), status.getReblog() != null ? status.getReblog().getAccount() : status.getAccount()); + app.fedilab.android.client.Entities.Status.fillSpan(contextReference, status); + app.fedilab.android.client.Entities.Status.makeEmojiPoll(contextReference, status.getReblog() != null ? status.getReblog().getPoll() : status.getPoll()); + Account.makeAccountNameEmoji(contextReference, status.getReblog() != null ? status.getReblog().getAccount() : status.getAccount()); } } else { statuses = new ArrayList<>(); diff --git a/app/src/main/java/app/fedilab/android/client/API.java b/app/src/main/java/app/fedilab/android/client/API.java index 9d48bac3a..43007d129 100644 --- a/app/src/main/java/app/fedilab/android/client/API.java +++ b/app/src/main/java/app/fedilab/android/client/API.java @@ -36,6 +36,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringReader; import java.io.UnsupportedEncodingException; +import java.lang.ref.WeakReference; import java.net.URLEncoder; import java.net.UnknownHostException; import java.security.KeyManagementException; @@ -297,7 +298,7 @@ public class API { * @param resobj JSONObject * @return Peertube */ - public static Peertube parsePeertube(Context context, String instance, JSONObject resobj) { + public static Peertube parsePeertube(String instance, JSONObject resobj) { Peertube peertube = new Peertube(); try { peertube.setId(resobj.get("id").toString()); @@ -332,7 +333,7 @@ public class API { * @param resobj JSONObject * @return Peertube */ - private static Peertube parseSinglePeertube(Context context, String instance, JSONObject resobj) { + private static Peertube parseSinglePeertube(String instance, JSONObject resobj) { Peertube peertube = new Peertube(); try { peertube.setId(resobj.get("id").toString()); @@ -502,7 +503,7 @@ public class API { * @param jsonArray JSONArray * @return List */ - private static List parseStatuses(Context context, filterFor action, JSONArray jsonArray) { + private static List parseStatuses(Context context, JSONArray jsonArray) { List statuses = new ArrayList<>(); try { @@ -672,7 +673,7 @@ public class API { } catch (JSONException | ParseException e) { e.printStackTrace(); } - Status.fillSpan(context, announcement); + Status.fillSpan(new WeakReference<>(context), announcement); return announcement; } @@ -717,7 +718,7 @@ public class API { } catch (JSONException | ParseException e) { e.printStackTrace(); } - Status.makeEmojiPoll(context, poll); + Status.makeEmojiPoll(new WeakReference<>(context), poll); return poll; } @@ -754,7 +755,9 @@ public class API { } else { status.setSensitive(false); } - status.setSpoiler_text(resobj.get("spoiler_text").toString()); + if (resobj.has("spoiler_text")) { + status.setSpoiler_text(resobj.get("spoiler_text").toString()); + } try { status.setVisibility(resobj.get("visibility").toString()); } catch (Exception e) { @@ -775,8 +778,9 @@ public class API { } status.setReactions(reactions); - - status.setUrl(resobj.get("url").toString()); + if (resobj.has("url")) { + status.setUrl(resobj.get("url").toString()); + } ArrayList attachments = new ArrayList<>(); //Retrieves attachments if (resobj.has("media_attachments")) { @@ -807,41 +811,46 @@ public class API { status.setMedia_attachments(attachments); //Retrieves mentions List mentions = new ArrayList<>(); - JSONArray arrayMention = resobj.getJSONArray("mentions"); - for (int j = 0; j < arrayMention.length(); j++) { - JSONObject menObj = arrayMention.getJSONObject(j); - Mention mention = new Mention(); - mention.setId(menObj.get("id").toString()); - mention.setUrl(menObj.get("url").toString()); - mention.setAcct(menObj.get("acct").toString()); - mention.setUsername(menObj.get("username").toString()); - mentions.add(mention); + if (resobj.has("mentions")) { + JSONArray arrayMention = resobj.getJSONArray("mentions"); + for (int j = 0; j < arrayMention.length(); j++) { + JSONObject menObj = arrayMention.getJSONObject(j); + Mention mention = new Mention(); + mention.setId(menObj.get("id").toString()); + mention.setUrl(menObj.get("url").toString()); + mention.setAcct(menObj.get("acct").toString()); + mention.setUsername(menObj.get("username").toString()); + mentions.add(mention); + } } status.setMentions(mentions); //Retrieves tags List tags = new ArrayList<>(); - JSONArray arrayTag = resobj.getJSONArray("tags"); - for (int j = 0; j < arrayTag.length(); j++) { - JSONObject tagObj = arrayTag.getJSONObject(j); - Tag tag = new Tag(); - tag.setName(tagObj.get("name").toString()); - tag.setUrl(tagObj.get("url").toString()); - tags.add(tag); + if (resobj.has("tags")) { + JSONArray arrayTag = resobj.getJSONArray("tags"); + for (int j = 0; j < arrayTag.length(); j++) { + JSONObject tagObj = arrayTag.getJSONObject(j); + Tag tag = new Tag(); + tag.setName(tagObj.get("name").toString()); + tag.setUrl(tagObj.get("url").toString()); + tags.add(tag); + } } status.setTags(tags); //Retrieves emjis List emojiList = new ArrayList<>(); - try { - JSONArray emojisTag = resobj.getJSONArray("emojis"); - for (int j = 0; j < emojisTag.length(); j++) { - JSONObject emojisObj = emojisTag.getJSONObject(j); - Emojis emojis = parseEmojis(emojisObj); - emojiList.add(emojis); + if (resobj.has("emojis")) { + try { + JSONArray emojisTag = resobj.getJSONArray("emojis"); + for (int j = 0; j < emojisTag.length(); j++) { + JSONObject emojisObj = emojisTag.getJSONObject(j); + Emojis emojis = parseEmojis(emojisObj); + emojiList.add(emojis); + } + } catch (Exception ignored) { } - status.setEmojis(emojiList); - } catch (Exception e) { - status.setEmojis(new ArrayList<>()); } + status.setEmojis(emojiList); //Retrieve Application Application application = new Application(); try { @@ -905,7 +914,7 @@ public class API { e.printStackTrace(); } status.setViewType(context); - Status.fillSpan(context, status); + Status.fillSpan(new WeakReference<>(context), status); return status; } @@ -1090,7 +1099,7 @@ public class API { } catch (ParseException e) { e.printStackTrace(); } - Status.fillSpan(context, status); + Status.fillSpan(new WeakReference<>(context), status); return status; } @@ -1258,7 +1267,7 @@ public class API { if (!resobj.isNull("action_taken_by_account")) { report.setAction_taken_by_account(parseAccountAdminResponse(context, resobj.getJSONObject("action_taken_by_account"))); } - report.setStatuses(parseStatuses(context, null, resobj.getJSONArray("statuses"))); + report.setStatuses(parseStatuses(context, resobj.getJSONArray("statuses"))); } catch (Exception e) { e.printStackTrace(); } @@ -1482,7 +1491,7 @@ public class API { e.printStackTrace(); } try { - Account.makeAccountNameEmoji(context, account); + Account.makeAccountNameEmoji(new WeakReference<>(context), account); } catch (Exception e) { e.printStackTrace(); } @@ -1614,10 +1623,11 @@ public class API { notification.setType(resobj.get("type").toString()); notification.setCreated_at(Helper.mstStringToDate(resobj.get("created_at").toString())); notification.setAccount(parseAccountResponse(context, resobj.getJSONObject("account"))); - try { - notification.setStatus(parseStatuses(context, resobj.getJSONObject("status"))); - } catch (Exception ignored) { - ignored.printStackTrace(); + if (resobj.has("status")) { + try { + notification.setStatus(parseStatuses(context, resobj.getJSONObject("status"))); + } catch (Exception ignored) { + } } notification.setCreated_at(Helper.mstStringToDate(resobj.get("created_at").toString())); } catch (JSONException ignored) { @@ -1761,7 +1771,7 @@ public class API { if (xpp.getName().compareTo("item") == 0) { if (status != null) { status.setAccount(account); - Status.fillSpan(context, status); + Status.fillSpan(new WeakReference<>(context), status); statuses.add(status); } account = null; @@ -1776,14 +1786,14 @@ public class API { return statuses; } - private List parseIdentityProof(Context context, JSONArray jsonArray) { + private List parseIdentityProof(JSONArray jsonArray) { List identityProofs = new ArrayList<>(); try { int i = 0; while (i < jsonArray.length()) { JSONObject resobj = jsonArray.getJSONObject(i); - IdentityProof identityProof = parseIdentityProof(context, resobj); + IdentityProof identityProof = parseIdentityProof(resobj); i++; identityProofs.add(identityProof); } @@ -1794,7 +1804,7 @@ public class API { return identityProofs; } - private IdentityProof parseIdentityProof(Context context, JSONObject jsonObject) { + private IdentityProof parseIdentityProof(JSONObject jsonObject) { IdentityProof identityProof = new IdentityProof(); try { identityProof.setProfile_url(jsonObject.getString("profile_url")); @@ -2748,7 +2758,7 @@ public class API { try { HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); String response = httpsConnection.get(getAbsoluteUrl(String.format("/accounts/%s/statuses", accountId)), 10, params, prefKeyOauthTokenT); - statuses = parseStatuses(context, filterFor.STATUSES_ACCOUNT, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); } catch (HttpsConnection.HttpsConnectionException e) { @@ -2903,7 +2913,7 @@ public class API { String response = httpsConnection.get(getAbsoluteUr2l(String.format("/status/%s/replies", statusId)), 10, params, prefKeyOauthTokenT); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - statuses = parseStatuses(context, null, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException e) { @@ -3009,7 +3019,7 @@ public class API { String response = httpsConnection.get(getAbsoluteUrl("/timelines/direct"), 10, params, prefKeyOauthTokenT); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - statuses = parseStatuses(context, null, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException e) { @@ -3114,7 +3124,7 @@ public class API { if (since_id == null) { statuses = parseStatusesForCache(context, new JSONArray(response)); } else { - statuses = parseStatuses(context, filterFor.HOME, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } } catch (UnknownHostException e) { if (since_id == null) { @@ -3143,7 +3153,7 @@ public class API { HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); String response = httpsConnection.get(getAbsoluteUrl(String.format("/accounts/%s/identity_proofs", userId)), 10, null, prefKeyOauthTokenT); - identityProofs = parseIdentityProof(context, new JSONArray(response)); + identityProofs = parseIdentityProof(new JSONArray(response)); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException e) { e.printStackTrace(); } catch (HttpsConnection.HttpsConnectionException e) { @@ -3204,7 +3214,7 @@ public class API { String response = httpsConnection.get(getAbsoluteUrlRemote(remoteInstance, "/timelines/public/"), 10, params, prefKeyOauthTokenT); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - statuses = parseStatuses(context, filterFor.PUBLIC, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException | HttpsConnection.HttpsConnectionException e) { e.printStackTrace(); } @@ -3224,7 +3234,7 @@ public class API { HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); String response = httpsConnection.get(String.format("https://" + instance + "/api/v1/accounts/%s/video-channels", name), 10, null, null); JSONArray jsonArray = new JSONObject(response).getJSONArray("data"); - accounts = parseAccountResponsePeertube(context, instance, jsonArray); + accounts = parseAccountResponsePeertube(instance, jsonArray); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); e.printStackTrace(); @@ -3307,7 +3317,7 @@ public class API { HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); String response = httpsConnection.get(String.format("https://" + instance + "/api/v1/videos/%s", videoId), 10, null, null); JSONObject jsonObject = new JSONObject(response); - peertube = parseSinglePeertube(context, instance, jsonObject); + peertube = parseSinglePeertube(instance, jsonObject); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); e.printStackTrace(); @@ -3553,7 +3563,7 @@ public class API { String response = httpsConnection.get(url, 10, params, prefKeyOauthTokenT); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - statuses = parseStatuses(context, local ? filterFor.LOCAL : filterFor.PUBLIC, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); e.printStackTrace(); @@ -3585,7 +3595,7 @@ public class API { String response = httpsConnection.get("https://toot.fedilab.app/api/v1/timelines/tag/fedilab", 10, params, prefKeyOauthTokenT); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - List tmp_status = parseStatuses(context, null, new JSONArray(response)); + List tmp_status = parseStatuses(context, new JSONArray(response)); if (tmp_status.size() > 0) { for (Status status : tmp_status) { if (status.getAccount().getAcct().equals("fedilab")) { @@ -3641,7 +3651,7 @@ public class API { String response = httpsConnection.get(url, 10, params, prefKeyOauthTokenT); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - statuses = parseStatuses(context, null, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException e) { @@ -3821,7 +3831,7 @@ public class API { response = httpsConnection.get(getAbsoluteUrlRemote(instance, String.format("/timelines/tag/%s", query)), 10, params, null); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - statuses = parseStatuses(context, null, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); e.printStackTrace(); @@ -4048,7 +4058,7 @@ public class API { String response = httpsConnection.get(getAbsoluteUrl("/favourites"), 10, params, prefKeyOauthTokenT); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - statuses = parseStatuses(context, null, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException e) { @@ -4098,7 +4108,7 @@ public class API { String response = httpsConnection.get(getAbsoluteUrl("/bookmarks"), 10, params, prefKeyOauthTokenT); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - statuses = parseStatuses(context, null, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException e) { @@ -4553,7 +4563,9 @@ public class API { Status alreadyCached = new TimelineCacheDAO(context, db).getSingle(status.getId()); Account account = new AccountDAO(context, db).getAccountByToken(prefKeyOauthTokenT); if (alreadyCached != null) { - new TimelineCacheDAO(context, db).update(status.getId(), response, account.getId(), account.getInstance()); + poll = parsePoll(context, new JSONObject(response)); + status.setPoll(poll); + new TimelineCacheDAO(context, db).update(status.getId(), Helper.statusToStringStorage(status), account.getId(), account.getInstance()); } LocalBroadcastManager.getInstance(context).sendBroadcast(intentBC); return poll; @@ -4592,6 +4604,7 @@ public class API { jsonObject.addProperty("sensitive", Boolean.toString(status.isSensitive())); if (status.getSpoiler_text() != null) jsonObject.addProperty("spoiler_text", status.getSpoiler_text()); + if (status.getPoll() != null) { JsonObject poll = new JsonObject(); JsonArray options = new JsonArray(); @@ -5240,7 +5253,7 @@ public class API { String response = httpsConnection.get(getAbsoluteUrl(String.format("/timelines/list/%s", list_id)), 10, params, prefKeyOauthTokenT); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); - statuses = parseStatuses(context, null, new JSONArray(response)); + statuses = parseStatuses(context, new JSONArray(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); e.printStackTrace(); @@ -5470,7 +5483,7 @@ public class API { Results results = new Results(); try { results.setAccounts(parseAccountResponse(resobj.getJSONArray("accounts"))); - results.setStatuses(parseStatuses(context, null, resobj.getJSONArray("statuses"))); + results.setStatuses(parseStatuses(context, resobj.getJSONArray("statuses"))); results.setTrends(parseTrends(resobj.getJSONArray("hashtags"))); results.setHashtags(parseTags(resobj.getJSONArray("hashtags"))); } catch (JSONException e) { @@ -5556,7 +5569,7 @@ public class API { int i = 0; while (i < jsonArray.length()) { JSONObject resobj = jsonArray.getJSONObject(i); - Peertube peertube = parsePeertube(context, instance, resobj); + Peertube peertube = parsePeertube(instance, resobj); i++; peertubes.add(peertube); } @@ -5901,7 +5914,7 @@ public class API { return lists; } - private List parseAccountResponsePeertube(Context context, String instance, JSONArray jsonArray) { + private List parseAccountResponsePeertube(String instance, JSONArray jsonArray) { List accounts = new ArrayList<>(); try { int i = 0; @@ -6061,8 +6074,8 @@ public class API { app.fedilab.android.client.Entities.Context context = new app.fedilab.android.client.Entities.Context(); try { - context.setAncestors(parseStatuses(this.context, null, jsonObject.getJSONArray("ancestors"))); - context.setDescendants(parseStatuses(this.context, null, jsonObject.getJSONArray("descendants"))); + context.setAncestors(parseStatuses(this.context, jsonObject.getJSONArray("ancestors"))); + context.setDescendants(parseStatuses(this.context, jsonObject.getJSONArray("descendants"))); } catch (JSONException e) { setDefaultError(e); } @@ -6155,13 +6168,6 @@ public class API { return "https://communitywiki.org/trunk/api/v1" + action; } - enum filterFor { - STATUSES_ACCOUNT, - HOME, - LOCAL, - PUBLIC - } - public enum searchType { TAGS, STATUSES, diff --git a/app/src/main/java/app/fedilab/android/client/Entities/Account.java b/app/src/main/java/app/fedilab/android/client/Entities/Account.java index 06b8eb6e0..0a6f3e98e 100644 --- a/app/src/main/java/app/fedilab/android/client/Entities/Account.java +++ b/app/src/main/java/app/fedilab/android/client/Entities/Account.java @@ -47,6 +47,7 @@ import com.bumptech.glide.request.transition.Transition; import org.jetbrains.annotations.NotNull; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; @@ -199,7 +200,8 @@ public class Account implements Parcelable { this.invited_by_account_id = in.readString(); } - public static void makeAccountNameEmoji(final Context context, Account account) { + public static void makeAccountNameEmoji(final WeakReference contextWeakReference, Account account) { + Context context = contextWeakReference.get(); if ((context instanceof Activity && ((Activity) context).isFinishing()) || account.getDisplay_name() == null) return; @@ -225,13 +227,16 @@ public class Account implements Parcelable { //emojis can be used several times so we have to loop for (int startPosition = -1; (startPosition = displayNameSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) { final int endPosition = startPosition + targetedEmoji.length(); - if (endPosition <= displayNameSpan.toString().length() && endPosition >= startPosition) { - resource.setBounds(0, 0, (int) Helper.convertDpToPixel(20, context), (int) Helper.convertDpToPixel(20, context)); - resource.setVisible(true, true); - ImageSpan imageSpan = new ImageSpan(resource); - displayNameSpan.setSpan( - imageSpan, startPosition, - endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + if (resource != null && endPosition <= displayNameSpan.toString().length() && endPosition >= startPosition) { + try { + resource.setBounds(0, 0, (int) Helper.convertDpToPixel(20, context), (int) Helper.convertDpToPixel(20, context)); + resource.setVisible(true, true); + ImageSpan imageSpan = new ImageSpan(resource); + displayNameSpan.setSpan( + imageSpan, startPosition, + endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + } catch (Exception ignored) { + } return; } } diff --git a/app/src/main/java/app/fedilab/android/client/Entities/BlockedDomains.java b/app/src/main/java/app/fedilab/android/client/Entities/BlockedDomains.java deleted file mode 100644 index e6c1a4c01..000000000 --- a/app/src/main/java/app/fedilab/android/client/Entities/BlockedDomains.java +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright 2019 Thomas Schneider - * - * This file is a part of Fedilab - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Fedilab; if not, - * see . */ -package app.fedilab.android.client.Entities; - -public class BlockedDomains { - - private int id; - private String domain; - - public String getDomain() { - return domain; - } - - public void setDomain(String domain) { - this.domain = domain; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } -} diff --git a/app/src/main/java/app/fedilab/android/client/Entities/ManageTimelines.java b/app/src/main/java/app/fedilab/android/client/Entities/ManageTimelines.java index 663c11c08..fb2ec3b98 100644 --- a/app/src/main/java/app/fedilab/android/client/Entities/ManageTimelines.java +++ b/app/src/main/java/app/fedilab/android/client/Entities/ManageTimelines.java @@ -571,7 +571,7 @@ public class ManageTimelines { } popup.setOnDismissListener(menu12 -> { - if (displayStatusFragment != null && displayStatusFragment.getUserVisibleHint()) + if (displayStatusFragment != null && displayStatusFragment.isVisible()) displayStatusFragment.refreshFilter(); }); int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); diff --git a/app/src/main/java/app/fedilab/android/client/Entities/Status.java b/app/src/main/java/app/fedilab/android/client/Entities/Status.java index cee832d47..dbaf113d1 100644 --- a/app/src/main/java/app/fedilab/android/client/Entities/Status.java +++ b/app/src/main/java/app/fedilab/android/client/Entities/Status.java @@ -59,6 +59,7 @@ import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; +import java.lang.ref.WeakReference; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; @@ -263,15 +264,15 @@ public class Status implements Parcelable { } - public static void fillSpan(Context context, Status status) { - Status.transform(context, status); - Status.makeEmojis(context, status); - Status.makeImage(context, status); + public static void fillSpan(WeakReference contextWeakReference, Status status) { + Status.transform(contextWeakReference, status); + Status.makeEmojis(contextWeakReference, status); + Status.makeImage(contextWeakReference, status); } - private static void transform(Context context, Status status) { - + private static void transform(WeakReference contextWeakReference, Status status) { + Context context = contextWeakReference.get(); if (status == null) return; SpannableString spannableStringContent, spannableStringCW; @@ -849,8 +850,8 @@ public class Status implements Parcelable { status.setContentSpanTranslated(contentSpanTranslated); } - private static void makeEmojis(final Context context, Status status) { - + private static void makeEmojis(final WeakReference contextWeakReference, Status status) { + Context context = contextWeakReference.get(); if (context instanceof Activity && ((Activity) context).isFinishing()) return; if (status.getReblog() != null && status.getReblog().getEmojis() == null) @@ -890,14 +891,17 @@ public class Status implements Parcelable { //emojis can be used several times so we have to loop for (int startPosition = -1; (startPosition = contentSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) { final int endPosition = startPosition + targetedEmoji.length(); - if (endPosition <= contentSpan.toString().length() && endPosition >= startPosition) { + if (resource != null && endPosition <= contentSpan.toString().length() && endPosition >= startPosition) { ImageSpan imageSpan; - resource.setBounds(0, 0, (int) Helper.convertDpToPixel(20, context), (int) Helper.convertDpToPixel(20, context)); - resource.setVisible(true, true); - imageSpan = new ImageSpan(resource); - contentSpan.setSpan( - imageSpan, startPosition, - endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + try { + resource.setBounds(0, 0, (int) Helper.convertDpToPixel(20, context), (int) Helper.convertDpToPixel(20, context)); + resource.setVisible(true, true); + imageSpan = new ImageSpan(resource); + contentSpan.setSpan( + imageSpan, startPosition, + endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + } catch (Exception ignored) { + } } } } @@ -928,7 +932,8 @@ public class Status implements Parcelable { } } - public static void makeEmojiPoll(final Context context, Poll poll) { + public static void makeEmojiPoll(final WeakReference contextWeakReference, Poll poll) { + Context context = contextWeakReference.get(); if ((context instanceof Activity && ((Activity) context).isFinishing()) || poll == null || poll.getOptionsList() == null) return; final List emojis = poll.getEmojis(); @@ -988,8 +993,8 @@ public class Status implements Parcelable { } } - private static void makeImage(final Context context, Status status) { - + private static void makeImage(final WeakReference contextWeakReference, Status status) { + Context context = contextWeakReference.get(); if (context instanceof Activity && ((Activity) context).isFinishing()) return; if (status.getAccount() == null) diff --git a/app/src/main/java/app/fedilab/android/client/GNUAPI.java b/app/src/main/java/app/fedilab/android/client/GNUAPI.java index 66c2f8c17..648d23ce8 100644 --- a/app/src/main/java/app/fedilab/android/client/GNUAPI.java +++ b/app/src/main/java/app/fedilab/android/client/GNUAPI.java @@ -28,6 +28,7 @@ import org.json.JSONObject; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.lang.ref.WeakReference; import java.net.URLEncoder; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -133,7 +134,7 @@ public class GNUAPI { * @param jsonArray JSONArray * @return List */ - private static List parseGroups(Context context, JSONArray jsonArray) { + private static List parseGroups(JSONArray jsonArray) { List groups = new ArrayList<>(); try { @@ -141,7 +142,7 @@ public class GNUAPI { while (i < jsonArray.length()) { JSONObject resobj = jsonArray.getJSONObject(i); - Account group = parseGroups(context, resobj); + Account group = parseGroups(resobj); i++; groups.add(group); } @@ -158,7 +159,7 @@ public class GNUAPI { * @param resobj JSONObject * @return Account */ - private static Account parseGroups(Context context, JSONObject resobj) { + private static Account parseGroups(JSONObject resobj) { Account group = new Account(); try { group.setId(resobj.get("id").toString()); @@ -293,9 +294,9 @@ public class GNUAPI { } status.setApplication(application); if (resobj.has("user")) - status.setAccount(parseAccountResponse(context, resobj.getJSONObject("user"))); + status.setAccount(parseAccountResponse(resobj.getJSONObject("user"))); else if (resobj.has("sender")) - status.setAccount(parseAccountResponse(context, resobj.getJSONObject("sender"))); + status.setAccount(parseAccountResponse(resobj.getJSONObject("sender"))); if (resobj.has("statusnet_html")) status.setContent(context, resobj.get("statusnet_html").toString()); else if (resobj.has("text")) @@ -346,7 +347,7 @@ public class GNUAPI { e.printStackTrace(); } status.setViewType(context); - Status.fillSpan(context, status); + Status.fillSpan(new WeakReference<>(context), status); return status; } @@ -357,7 +358,7 @@ public class GNUAPI { * @param resobj JSONObject * @return Account */ - public static Account parseAccountResponse(Context context, JSONObject resobj) { + public static Account parseAccountResponse(JSONObject resobj) { Account account = new Account(); try { @@ -553,7 +554,7 @@ public class GNUAPI { } try { String response = new HttpsConnection(context, this.instance).get(getAbsoluteUrl("/account/verify_credentials.json"), 60, null, prefKeyOauthTokenT); - account = parseAccountResponse(context, new JSONObject(response)); + account = parseAccountResponse(new JSONObject(response)); if (social != null) { account.setSocial(social.toUpperCase()); } @@ -579,7 +580,7 @@ public class GNUAPI { params.put("user_id", accountId); try { String response = new HttpsConnection(context, this.instance).get(getAbsoluteUrl("/users/show.json"), 60, params, prefKeyOauthTokenT); - account = parseAccountResponse(context, new JSONObject(response)); + account = parseAccountResponse(new JSONObject(response)); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); e.printStackTrace(); @@ -619,7 +620,7 @@ public class GNUAPI { try { HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); String response = httpsConnection.get(getAbsoluteUrl("/statusnet/groups/list.json"), 60, params, prefKeyOauthTokenT); - accounts = parseGroups(context, new JSONArray(response)); + accounts = parseGroups(new JSONArray(response)); if (accounts.size() > 0) { apiResponse.setSince_id(accounts.get(0).getId()); apiResponse.setMax_id(accounts.get(accounts.size() - 1).getId()); @@ -1771,7 +1772,7 @@ public class GNUAPI { Notification notification = new Notification(); notification.setType(stringType); notification.setId(st.getId()); - Status.fillSpan(context, st); + Status.fillSpan(new WeakReference<>(context), st); notification.setStatus(st); notification.setAccount(st.getAccount()); notifications.add(notification); @@ -1934,7 +1935,7 @@ public class GNUAPI { int i = 0; while (i < jsonArray.length()) { JSONObject resobj = jsonArray.getJSONObject(i); - Account account = parseAccountResponse(context, resobj); + Account account = parseAccountResponse(resobj); accounts.add(account); i++; } diff --git a/app/src/main/java/app/fedilab/android/client/PeertubeAPI.java b/app/src/main/java/app/fedilab/android/client/PeertubeAPI.java index c82216d2f..188aac831 100644 --- a/app/src/main/java/app/fedilab/android/client/PeertubeAPI.java +++ b/app/src/main/java/app/fedilab/android/client/PeertubeAPI.java @@ -125,7 +125,7 @@ public class PeertubeAPI { * @param resobj JSONObject * @return Peertube */ - private static PeertubeNotification parsePeertubeNotifications(Context context, JSONObject resobj) { + private static PeertubeNotification parsePeertubeNotifications(JSONObject resobj) { PeertubeNotification peertubeNotification = new PeertubeNotification(); try { peertubeNotification.setId(resobj.get("id").toString()); @@ -230,7 +230,7 @@ public class PeertubeAPI { * @param resobj JSONObject * @return Peertube */ - private static Peertube parsePeertube(Context context, JSONObject resobj) { + private static Peertube parsePeertube(JSONObject resobj) { Peertube peertube = new Peertube(); if (resobj.has("video")) { try { @@ -248,9 +248,9 @@ public class PeertubeAPI { peertube.setEmbedPath(resobj.get("embedPath").toString()); peertube.setPreviewPath(resobj.get("previewPath").toString()); peertube.setThumbnailPath(resobj.get("thumbnailPath").toString()); - peertube.setAccount(parseAccountResponsePeertube(context, resobj.getJSONObject("account"))); + peertube.setAccount(parseAccountResponsePeertube(resobj.getJSONObject("account"))); try { - peertube.setChannel(parseAccountResponsePeertube(context, resobj.getJSONObject("channel"))); + peertube.setChannel(parseAccountResponsePeertube(resobj.getJSONObject("channel"))); } catch (Exception ignored) { } peertube.setView(Integer.parseInt(resobj.get("views").toString())); @@ -298,7 +298,7 @@ public class PeertubeAPI { * @param resobj JSONObject * @return Peertube */ - private static Peertube parseSinglePeertube(Context context, String instance, JSONObject resobj) { + private static Peertube parseSinglePeertube(String instance, JSONObject resobj) { Peertube peertube = new Peertube(); try { peertube.setId(resobj.get("id").toString()); @@ -316,7 +316,7 @@ public class PeertubeAPI { peertube.setCommentsEnabled(Boolean.parseBoolean(resobj.get("commentsEnabled").toString())); peertube.setDislike(Integer.parseInt(resobj.get("dislikes").toString())); peertube.setDuration(Integer.parseInt(resobj.get("duration").toString())); - peertube.setAccount(parseAccountResponsePeertube(context, resobj.getJSONObject("account"))); + peertube.setAccount(parseAccountResponsePeertube(resobj.getJSONObject("account"))); List tags = new ArrayList<>(); try { JSONArray tagsA = resobj.getJSONArray("tags"); @@ -328,7 +328,7 @@ public class PeertubeAPI { } catch (Exception ignored) { } try { - peertube.setChannel(parseAccountResponsePeertube(context, resobj.getJSONObject("channel"))); + peertube.setChannel(parseAccountResponsePeertube(resobj.getJSONObject("channel"))); } catch (Exception ignored) { } peertube.setSensitive(Boolean.parseBoolean(resobj.get("nsfw").toString())); @@ -404,7 +404,7 @@ public class PeertubeAPI { playlist.setLocal(resobj.getBoolean("isLocal")); playlist.setVideoChannelId(resobj.getString("videoChannel")); playlist.setThumbnailPath(resobj.getString("thumbnailPath")); - playlist.setOwnerAccount(parseAccountResponsePeertube(context, resobj.getJSONObject("ownerAccount"))); + playlist.setOwnerAccount(parseAccountResponsePeertube(resobj.getJSONObject("ownerAccount"))); playlist.setVideosLength(resobj.getInt("videosLength")); try { LinkedHashMap type = new LinkedHashMap<>(); @@ -430,7 +430,7 @@ public class PeertubeAPI { * @param accountObject JSONObject * @return Account */ - private static Account parseAccountResponsePeertube(Context context, JSONObject accountObject) { + private static Account parseAccountResponsePeertube(JSONObject accountObject) { Account account = new Account(); try { account.setId(accountObject.get("id").toString()); @@ -463,8 +463,10 @@ public class PeertubeAPI { if (accountObject.has("avatar") && !accountObject.isNull("avatar")) { account.setAvatar(accountObject.getJSONObject("avatar").get("path").toString()); account.setAvatar_static(accountObject.getJSONObject("avatar").get("path").toString()); - } else + } else { account.setAvatar("null"); + account.setAvatar_static("null"); + } account.setHeader("null"); account.setHeader_static("null"); @@ -655,7 +657,7 @@ public class PeertubeAPI { try { String response = new HttpsConnection(context, this.instance).get(getAbsoluteUrl("/users/me"), 60, null, prefKeyOauthTokenT); JSONObject accountObject = new JSONObject(response).getJSONObject("account"); - account = parseAccountResponsePeertube(context, accountObject); + account = parseAccountResponsePeertube( accountObject); if (social != null) { account.setSocial(social.toUpperCase()); } @@ -686,7 +688,7 @@ public class PeertubeAPI { try { response = new HttpsConnection(context, this.instance).get(getAbsoluteUrl("/users/me"), 60, null, targetedAccount.getToken()); JSONObject accountObject = new JSONObject(response).getJSONObject("account"); - account = parseAccountResponsePeertube(context, accountObject); + account = parseAccountResponsePeertube(accountObject); if (social != null) { account.setSocial(social.toUpperCase()); } @@ -780,7 +782,7 @@ public class PeertubeAPI { account = new Account(); try { String response = new HttpsConnection(context, this.instance).get(getAbsoluteUrl(String.format("/accounts/%s", accountId)), 60, null, prefKeyOauthTokenT); - account = parseAccountResponsePeertube(context, new JSONObject(response)); + account = parseAccountResponsePeertube(new JSONObject(response)); } catch (HttpsConnection.HttpsConnectionException e) { e.printStackTrace(); setError(e.getStatusCode(), e); @@ -1057,9 +1059,9 @@ public class PeertubeAPI { try { return getTL("/users/me/subscriptions/videos", "-publishedAt", null, max_id, null, null); } catch (HttpsConnection.HttpsConnectionException e) { - if (e.getStatusCode() == 401 || e.getStatusCode() == 403) { - SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); - Account targetedAccount = new AccountDAO(context, db).getAccountByToken(prefKeyOauthTokenT); + SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + Account targetedAccount = new AccountDAO(context, db).getAccountByToken(prefKeyOauthTokenT); + if (targetedAccount != null && (e.getStatusCode() == 401 || e.getStatusCode() == 403)) { HashMap values = refreshToken(targetedAccount.getClient_id(), targetedAccount.getClient_secret(), targetedAccount.getRefresh_token()); SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); if (values.containsKey("access_token") && values.get("access_token") != null) { @@ -1238,7 +1240,7 @@ public class PeertubeAPI { HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); String response = httpsConnection.get(getAbsoluteUrl(String.format("/accounts/%s/video-channels", name)), 60, null, null); JSONArray jsonArray = new JSONObject(response).getJSONArray("data"); - accounts = parseAccountResponsePeertube(context, jsonArray); + accounts = parseAccountResponsePeertube(jsonArray); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException e) { @@ -1260,7 +1262,7 @@ public class PeertubeAPI { HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); String response = httpsConnection.get(String.format("https://" + instance + "/api/v1/videos/%s", videoId), 60, null, token); JSONObject jsonObject = new JSONObject(response); - peertube = parseSinglePeertube(context, instance, jsonObject); + peertube = parseSinglePeertube(instance, jsonObject); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException | IOException | KeyManagementException | JSONException e) { @@ -1564,7 +1566,7 @@ public class PeertubeAPI { int i = 0; while (i < jsonArray.length()) { JSONObject resobj = jsonArray.getJSONObject(i); - PeertubeNotification peertubeNotification = parsePeertubeNotifications(context, resobj); + PeertubeNotification peertubeNotification = parsePeertubeNotifications(resobj); i++; peertubeNotifications.add(peertubeNotification); } @@ -1636,7 +1638,7 @@ public class PeertubeAPI { int i = 0; while (i < jsonArray.length()) { JSONObject resobj = jsonArray.getJSONObject(i); - Peertube peertube = parsePeertube(context, resobj); + Peertube peertube = parsePeertube(resobj); i++; peertubes.add(peertube); } @@ -1689,13 +1691,13 @@ public class PeertubeAPI { return playlists; } - private List parseAccountResponsePeertube(Context context, JSONArray jsonArray) { + private List parseAccountResponsePeertube(JSONArray jsonArray) { List accounts = new ArrayList<>(); try { int i = 0; while (i < jsonArray.length()) { JSONObject resobj = jsonArray.getJSONObject(i); - Account account = parseAccountResponsePeertube(context, resobj); + Account account = parseAccountResponsePeertube(resobj); accounts.add(account); i++; } diff --git a/app/src/main/java/app/fedilab/android/drawers/ReactionAdapter.java b/app/src/main/java/app/fedilab/android/drawers/ReactionAdapter.java index 5aa0e6d2c..5ce6500be 100644 --- a/app/src/main/java/app/fedilab/android/drawers/ReactionAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/ReactionAdapter.java @@ -15,6 +15,8 @@ package app.fedilab.android.drawers; * see . */ +import android.content.Context; +import android.os.AsyncTask; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -31,23 +33,32 @@ import java.util.ArrayList; import java.util.List; import app.fedilab.android.R; +import app.fedilab.android.asynctasks.PostActionAsyncTask; +import app.fedilab.android.asynctasks.RetrieveFeedsAsyncTask; +import app.fedilab.android.client.API; +import app.fedilab.android.client.Entities.Error; import app.fedilab.android.client.Entities.Reaction; import app.fedilab.android.helper.Helper; +import app.fedilab.android.interfaces.OnPostActionInterface; /** * Created by Thomas on 10/03/2020. * Adapter for reactions on messages */ -public class ReactionAdapter extends RecyclerView.Adapter { +public class ReactionAdapter extends RecyclerView.Adapter implements OnPostActionInterface { private List reactions; + private RetrieveFeedsAsyncTask.Type type; + private String statusId; - ReactionAdapter(List reactions) { + ReactionAdapter(List reactions, RetrieveFeedsAsyncTask.Type type, String statusId) { this.reactions = reactions; if (reactions == null) { this.reactions = new ArrayList<>(); } + this.type = type; + this.statusId = statusId; } @NonNull @@ -61,7 +72,7 @@ public class ReactionAdapter extends RecyclerView.Adapter { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { final Reaction reaction = reactions.get(viewHolder.getAdapterPosition()); ViewHolder holder = (ViewHolder) viewHolder; - + Context context = viewHolder.itemView.getContext(); holder.reaction_count.setText(String.valueOf(reaction.getCount())); if (reaction.isMe()) { holder.reaction_container.setBackgroundResource(R.drawable.reaction_voted); @@ -92,6 +103,23 @@ public class ReactionAdapter extends RecyclerView.Adapter { holder.reaction_name.setVisibility(View.VISIBLE); holder.reaction_emoji.setVisibility(View.GONE); } + + holder.reaction_container.setOnClickListener(v -> { + String emojiStr = reaction.getName(); + API.StatusAction statusAction; + if (type == RetrieveFeedsAsyncTask.Type.ANNOUNCEMENTS) { + statusAction = reaction.isMe() ? API.StatusAction.REMOVE_REACTION : API.StatusAction.ADD_REACTION; + } else { + statusAction = reaction.isMe() ? API.StatusAction.REMOVE_PLEROMA_REACTION : API.StatusAction.ADD_PLEROMA_REACTION; + } + reaction.setMe(!reaction.isMe()); + if (reaction.isMe()) { + reaction.setCount(reaction.getCount() + 1); + } else { + reaction.setCount(reaction.getCount() - 1); + } + new PostActionAsyncTask(context, statusAction, this.statusId, null, emojiStr, ReactionAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }); } @Override @@ -104,6 +132,11 @@ public class ReactionAdapter extends RecyclerView.Adapter { return reactions.size(); } + @Override + public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) { + notifyDataSetChanged(); + } + static class ViewHolder extends RecyclerView.ViewHolder { TextView reaction_name, reaction_count; diff --git a/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java b/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java index 940633362..5b010d902 100644 --- a/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java @@ -182,6 +182,7 @@ import app.fedilab.android.sqlite.StatusStoredDAO; import app.fedilab.android.sqlite.TempMuteDAO; import app.fedilab.android.sqlite.TimelineCacheDAO; import app.fedilab.android.sqlite.TimelinesDAO; +import app.fedilab.android.webview.CustomWebview; import es.dmoral.toasty.Toasty; import jp.wasabeef.glide.transformations.BlurTransformation; @@ -1014,7 +1015,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct holder.status_action_container.setVisibility(View.GONE); } holder.status_reactions.setVisibility(View.VISIBLE); - ReactionAdapter reactionAdapter = new ReactionAdapter(status.getReactions()); + ReactionAdapter reactionAdapter = new ReactionAdapter(status.getReactions(), type, status.getId()); holder.reactions_view.setAdapter(reactionAdapter); LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false); @@ -4071,7 +4072,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct ImageView status_cardview_image; TextView status_cardview_title, status_cardview_content, status_cardview_url; FrameLayout status_cardview_video; - WebView status_cardview_webview; + CustomWebview status_cardview_webview; ImageView hide_preview, hide_preview_h; TextView status_toot_app; RelativeLayout webview_preview; diff --git a/app/src/main/java/app/fedilab/android/fragments/DisplayNotificationsFragment.java b/app/src/main/java/app/fedilab/android/fragments/DisplayNotificationsFragment.java index e27cbd5c6..228159ab6 100644 --- a/app/src/main/java/app/fedilab/android/fragments/DisplayNotificationsFragment.java +++ b/app/src/main/java/app/fedilab/android/fragments/DisplayNotificationsFragment.java @@ -252,12 +252,12 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve swipeRefreshLayout.setEnabled(true); if (context == null) return; - if (getUserVisibleHint()) { + if (isVisible()) { NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); assert mNotificationManager != null; mNotificationManager.cancelAll(); } - if (getUserVisibleHint() && notifications != null && notifications.size() > 0) { + if (isVisible() && notifications != null && notifications.size() > 0) { retrieveMissingNotifications(notifications.get(0).getId()); updateNotificationLastId(notifications.get(0).getId()); } diff --git a/app/src/main/java/app/fedilab/android/fragments/DisplayStatusFragment.java b/app/src/main/java/app/fedilab/android/fragments/DisplayStatusFragment.java index 6d67373c7..5c8859b55 100644 --- a/app/src/main/java/app/fedilab/android/fragments/DisplayStatusFragment.java +++ b/app/src/main/java/app/fedilab/android/fragments/DisplayStatusFragment.java @@ -179,9 +179,9 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter timelineId = bundle.getInt("timelineId"); currentfilter = bundle.getString("currentfilter", null); } - if (ischannel) + if (ischannel) { type = RetrieveFeedsAsyncTask.Type.CHANNEL; - + } assert context != null; SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); @@ -766,13 +766,13 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter swipeRefreshLayout.setEnabled(true); boolean liveNotifications = sharedpreferences.getBoolean(Helper.SET_LIVE_NOTIFICATIONS, true); if (type == RetrieveFeedsAsyncTask.Type.HOME || type == RetrieveFeedsAsyncTask.Type.PF_HOME) { - if (getUserVisibleHint()) { + if (this.isVisible()) { if (statuses != null && statuses.size() > 0 && asyncTask.getStatus() != AsyncTask.Status.RUNNING) { retrieveMissingToots(statuses.get(0).getId()); } } } else if (type == RetrieveFeedsAsyncTask.Type.PUBLIC) { - if (getUserVisibleHint()) { + if (isVisible()) { SharedPreferences.Editor editor = sharedpreferences.edit(); editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_FEDERATED + userId + instance, true); editor.apply(); @@ -788,7 +788,7 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter } } else if (type == RetrieveFeedsAsyncTask.Type.LOCAL) { - if (getUserVisibleHint()) { + if (isVisible()) { SharedPreferences.Editor editor = sharedpreferences.edit(); editor.putBoolean(Helper.SHOULD_CONTINUE_STREAMING_LOCAL + userId + instance, true); editor.apply(); @@ -803,17 +803,17 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter retrieveMissingToots(statuses.get(0).getId()); } } else if (type == RetrieveFeedsAsyncTask.Type.DIRECT || type == RetrieveFeedsAsyncTask.Type.GNU_DM) { - if (getUserVisibleHint()) { + if (isVisible()) { if (statuses != null && statuses.size() > 0) retrieveMissingToots(statuses.get(0).getId()); } } else if (type == RetrieveFeedsAsyncTask.Type.CONVERSATION) { - if (getUserVisibleHint()) { + if (isVisible()) { if (statuses != null && statuses.size() > 0) retrieveMissingToots(statuses.get(0).getId()); } } else if (type == RetrieveFeedsAsyncTask.Type.TAG) { - if (getUserVisibleHint()) { + if (isVisible()) { if (statuses != null && statuses.size() > 0) retrieveMissingToots(statuses.get(0).getId()); } diff --git a/app/src/main/java/app/fedilab/android/fragments/DisplayStoriesFragment.java b/app/src/main/java/app/fedilab/android/fragments/DisplayStoriesFragment.java index 856f421d9..9e993448d 100644 --- a/app/src/main/java/app/fedilab/android/fragments/DisplayStoriesFragment.java +++ b/app/src/main/java/app/fedilab/android/fragments/DisplayStoriesFragment.java @@ -103,7 +103,7 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie mLayoutManager = new LinearLayoutManager(context); lv_stories.setLayoutManager(mLayoutManager); lv_stories.addOnScrollListener(new RecyclerView.OnScrollListener() { - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) { if (dy > 0) { int visibleItemCount = mLayoutManager.getChildCount(); int totalItemCount = mLayoutManager.getItemCount(); @@ -122,17 +122,11 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie }); - swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - flag_loading = true; - swiped = true; - String sinceId = null; - if (pixelFedStories != null && pixelFedStories.size() > 0) - sinceId = pixelFedStories.get(0).getId(); - if (context != null) - asyncTask = new RetrieveStoriesAsyncTask(context, null, type, DisplayStoriesFragment.this).execute(); - } + swipeRefreshLayout.setOnRefreshListener(() -> { + flag_loading = true; + swiped = true; + if (context != null) + asyncTask = new RetrieveStoriesAsyncTask(context, null, type, DisplayStoriesFragment.this).execute(); }); SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); @@ -159,12 +153,9 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie if (context != null) asyncTask = new RetrieveStoriesAsyncTask(context, max_id, type, DisplayStoriesFragment.this).execute(); else - new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { - @Override - public void run() { - if (context != null) - asyncTask = new RetrieveStoriesAsyncTask(context, max_id, type, DisplayStoriesFragment.this).execute(); - } + new Handler(Looper.getMainLooper()).postDelayed(() -> { + if (context != null) + asyncTask = new RetrieveStoriesAsyncTask(context, max_id, type, DisplayStoriesFragment.this).execute(); }, 500); return rootView; } @@ -253,7 +244,7 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie swipeRefreshLayout.setEnabled(true); if (context == null) return; - if (getUserVisibleHint() && pixelFedStories != null && pixelFedStories.size() > 0) { + if (isVisible() && pixelFedStories != null && pixelFedStories.size() > 0) { retrieveMissingNotifications(pixelFedStories.get(0).getId()); } } @@ -274,7 +265,7 @@ public class DisplayStoriesFragment extends Fragment implements OnRetrieveStorie * * @param sinceId String */ - void retrieveMissingNotifications(String sinceId) { + private void retrieveMissingNotifications(String sinceId) { asyncTask = new RetrieveStoriesAsyncTask(context, null, type, DisplayStoriesFragment.this).execute(); } diff --git a/app/src/main/java/app/fedilab/android/fragments/MediaSliderFragment.java b/app/src/main/java/app/fedilab/android/fragments/MediaSliderFragment.java index cdb7f0461..0fed7f5e4 100644 --- a/app/src/main/java/app/fedilab/android/fragments/MediaSliderFragment.java +++ b/app/src/main/java/app/fedilab/android/fragments/MediaSliderFragment.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Bitmap; -import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.media.MediaPlayer; import android.net.Uri; @@ -31,7 +30,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; -import android.webkit.WebView; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; @@ -49,7 +47,6 @@ import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; import com.cleveroad.audiovisualization.DbmHandler; import com.cleveroad.audiovisualization.GLAudioVisualizationView; -import com.github.chrisbanes.photoview.OnMatrixChangedListener; import com.github.chrisbanes.photoview.PhotoView; import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.Player; @@ -74,6 +71,7 @@ import app.fedilab.android.activities.SlideMediaActivity; import app.fedilab.android.client.Entities.Attachment; import app.fedilab.android.client.TLSSocketFactory; import app.fedilab.android.helper.Helper; +import app.fedilab.android.webview.CustomWebview; import app.fedilab.android.webview.MastalabWebChromeClient; import app.fedilab.android.webview.MastalabWebViewClient; @@ -147,19 +145,16 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl } url = attachment.getUrl(); - imageView.setOnMatrixChangeListener(new OnMatrixChangedListener() { - @Override - public void onMatrixChanged(RectF rect) { - canSwipe = (imageView.getScale() == 1); + imageView.setOnMatrixChangeListener(rect -> { + canSwipe = (imageView.getScale() == 1); - if (!canSwipe) { - if (!((SlideMediaActivity) context).getFullScreen()) { - ((SlideMediaActivity) context).setFullscreen(true); - } - ((SlideMediaActivity) context).enableSliding(false); - } else { - ((SlideMediaActivity) context).enableSliding(true); + if (!canSwipe) { + if (!((SlideMediaActivity) context).getFullScreen()) { + ((SlideMediaActivity) context).setFullscreen(true); } + ((SlideMediaActivity) context).enableSliding(false); + } else { + ((SlideMediaActivity) context).enableSliding(true); } }); ProgressBar pbar_inf = rootView.findViewById(R.id.pbar_inf); @@ -189,7 +184,7 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl new CustomTarget() { @Override public void onResourceReady(@NonNull final Bitmap resource, Transition transition) { - Bitmap imageCompressed = Helper.compressImageIfNeeded(context, resource); + Bitmap imageCompressed = Helper.compressImageIfNeeded(resource); imageView.setImageBitmap(imageCompressed); Glide.with(context) .asBitmap() @@ -198,18 +193,15 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl @Override public void onResourceReady(@NonNull final Bitmap resource, Transition transition) { loader.setVisibility(View.GONE); - Bitmap imageCompressed = Helper.compressImageIfNeeded(context, resource); + Bitmap imageCompressed = Helper.compressImageIfNeeded(resource); if (imageView.getScale() < 1.1) { imageView.setImageBitmap(imageCompressed); } else { message_ready.setVisibility(View.VISIBLE); } - message_ready.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - imageView.setImageBitmap(imageCompressed); - message_ready.setVisibility(View.GONE); - } + message_ready.setOnClickListener(view -> { + imageView.setImageBitmap(imageCompressed); + message_ready.setVisibility(View.GONE); }); } @@ -258,7 +250,7 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl break; case "web": loader.setVisibility(View.GONE); - WebView webview_video = Helper.initializeWebview((Activity) context, R.id.webview_video, null); + CustomWebview webview_video = Helper.initializeWebview((Activity) context, R.id.webview_video, null); webview_video.setVisibility(View.VISIBLE); FrameLayout webview_container = rootView.findViewById(R.id.main_media_frame); final ViewGroup videoLayout = rootView.findViewById(R.id.videoLayout); @@ -340,12 +332,7 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl } } - visualizerView.post(new Runnable() { - @Override - public void run() { - playeraudio.setOnCompletionListener(MediaSliderFragment.this); - } - }); + visualizerView.post(() -> playeraudio.setOnCompletionListener(MediaSliderFragment.this)); timerView.setText("00:00:00"); playView.setVisibility(View.VISIBLE); @@ -390,12 +377,9 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl } private void updateTimer() { - ((Activity) context).runOnUiThread(new Runnable() { - @Override - public void run() { - playerSecondsElapsed++; - timerView.setText(formatSeconds(playerSecondsElapsed)); - } + ((Activity) context).runOnUiThread(() -> { + playerSecondsElapsed++; + timerView.setText(formatSeconds(playerSecondsElapsed)); }); } @@ -415,7 +399,7 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl } } - public void togglePlaying(View v) { + public void togglePlaying() { HANDLER.postDelayed(() -> { if (isPlaying()) { @@ -493,9 +477,6 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl } } - public boolean canSwipe() { - return canSwipe; - } @Override diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index 1816699de..7f79bcdec 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -35,13 +35,10 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; -import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; -import android.graphics.PorterDuffXfermode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.media.AudioAttributes; @@ -74,15 +71,12 @@ import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.view.View; -import android.view.ViewTreeObserver; import android.view.WindowManager; import android.webkit.CookieManager; import android.webkit.MimeTypeMap; import android.webkit.URLUtil; import android.webkit.WebChromeClient; import android.webkit.WebSettings; -import android.webkit.WebView; -import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageButton; @@ -116,8 +110,8 @@ import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; import com.google.android.material.navigation.NavigationView; import com.google.android.material.tabs.TabLayout; -import com.google.common.reflect.TypeToken; import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import com.iceteck.silicompressorr.SiliCompressor; import com.oguzdev.circularfloatingactionmenu.library.FloatingActionButton; import com.oguzdev.circularfloatingactionmenu.library.FloatingActionMenu; @@ -157,8 +151,6 @@ import java.net.PasswordAuthentication; import java.net.Proxy; import java.net.URISyntaxException; import java.nio.channels.FileChannel; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.Security; import java.text.DateFormat; import java.text.ParseException; @@ -221,6 +213,7 @@ import app.fedilab.android.sqlite.MainMenuDAO; import app.fedilab.android.sqlite.Sqlite; import app.fedilab.android.sqlite.StatusCacheDAO; import app.fedilab.android.sqlite.TimelineCacheDAO; +import app.fedilab.android.webview.CustomWebview; import app.fedilab.android.webview.ProxyHelper; import es.dmoral.toasty.Toasty; import info.guardianproject.netcipher.client.StrongBuilder; @@ -232,6 +225,7 @@ import okhttp3.TlsVersion; import static android.content.Context.DOWNLOAD_SERVICE; import static app.fedilab.android.activities.BaseMainActivity.filters; +import static app.fedilab.android.activities.BaseMainActivity.isAttached; import static app.fedilab.android.activities.BaseMainActivity.mutedAccount; import static app.fedilab.android.activities.BaseMainActivity.regex_home; import static app.fedilab.android.activities.BaseMainActivity.regex_local; @@ -647,6 +641,9 @@ public class Helper { editor.putString(Helper.PREF_INSTANCE, null); editor.putString(Helper.ID, null); editor.apply(); + Intent loginActivity = new Intent(activity, LoginActivity.class); + activity.startActivity(loginActivity); + activity.finish(); } else { editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, newAccount.getToken()); editor.putString(Helper.PREF_KEY_ID, newAccount.getId()); @@ -1297,8 +1294,6 @@ public class Helper { final ImageView arrow = navigationView.getHeaderView(0).findViewById(R.id.owner_accounts); if (currrentUserId == null) return; - - final SharedPreferences sharedpreferences = activity.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); if (!menuAccountsOpened) { arrow.setImageResource(R.drawable.ic_arrow_drop_up); SQLiteDatabase db = Sqlite.getInstance(activity.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); @@ -1308,7 +1303,6 @@ public class Helper { navigationView.inflateMenu(R.menu.menu_accounts); Menu mainMenu = navigationView.getMenu(); SubMenu currentSubmenu = null; - boolean disableGif = sharedpreferences.getBoolean(SET_DISABLE_GIF, false); if (accounts != null) for (final Account account : accounts) { @@ -1327,14 +1321,12 @@ public class Helper { } if (!url.equals("null")) Glide.with(navigationView.getContext()) - .asBitmap() + .asDrawable() .load(account.getAvatar()) - .into(new CustomTarget() { + .into(new CustomTarget() { @Override - public void onResourceReady(@NonNull Bitmap resource, Transition transition) { - Drawable drawable = new BitmapDrawable(activity.getResources(), resource); - item.setIcon(drawable); - item.getIcon().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY); + public void onResourceReady(@NonNull Drawable resource, Transition transition) { + item.setIcon(resource); } @Override @@ -1535,6 +1527,7 @@ public class Helper { * @param activity Activity * @param userID String - the new user id */ + @SuppressLint("ApplySharedPref") public static void changeUser(Activity activity, String userID, String instance, boolean notificationIntent) { final SharedPreferences sharedpreferences = activity.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); @@ -1696,6 +1689,7 @@ public class Helper { * @param account Account - new account in use * @param headerLayout View - the menu header */ + @SuppressLint("ApplySharedPref") public static void updateHeaderAccountInfo(Activity activity, final Account account, final View headerLayout) { @@ -1788,38 +1782,41 @@ public class Helper { if (!accountChoice.getAvatar().startsWith("http")) accountChoice.setAvatar("https://" + accountChoice.getInstance() + accountChoice.getAvatar()); ImageView itemIconAcc = new ImageView(activity); - if( !activity.isFinishing()) { - Glide.with(activity) - .asDrawable() - .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(270))) - .load(!disableGif ? accountChoice.getAvatar() : accountChoice.getAvatar_static()) - .listener(new RequestListener() { + if (!activity.isFinishing() && isAttached) { + try { + Glide.with(activity) + .asDrawable() + .apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(270))) + .load(!disableGif ? accountChoice.getAvatar() : accountChoice.getAvatar_static()) + .listener(new RequestListener() { - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - return false; - } + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + return false; + } - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) - itemIconAcc.setImageResource(R.drawable.missing); - else if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) - itemIconAcc.setImageResource(R.drawable.missing_peertube); - return false; - } - }) - .into(new CustomTarget() { - @Override - public void onResourceReady(@NonNull Drawable resource, Transition transition) { - itemIconAcc.setImageDrawable(resource); - } + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) + itemIconAcc.setImageResource(R.drawable.missing); + else if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) + itemIconAcc.setImageResource(R.drawable.missing_peertube); + return false; + } + }) + .into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Drawable resource, Transition transition) { + itemIconAcc.setImageDrawable(resource); + } - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { - } - }); + } + }); + } catch (Exception ignored) { + } } if (accounts.size() > 2) { @@ -1917,7 +1914,7 @@ public class Helper { activity.startActivity(myIntent); activity.finish(); //User is logged out to get a new token } else { - Account.makeAccountNameEmoji(activity, account); + Account.makeAccountNameEmoji(new WeakReference<>(activity), account); username.setText(String.format("@%s", account.getUsername() + "@" + account.getInstance())); displayedName.setText(account.getDisplayNameSpan(), TextView.BufferType.SPANNABLE); loadGiF(activity, account, profilePicture); @@ -1927,27 +1924,32 @@ public class Helper { } if (!urlHeader.contains("missing.png")) { ImageView backgroundImage = headerLayout.findViewById(R.id.back_ground_image); - Glide.with(activity) - .asDrawable() - .load(urlHeader) - .into(new CustomTarget() { - @Override - public void onResourceReady(@NonNull Drawable resource, Transition transition) { + if (!activity.isFinishing() && isAttached) { + try { + Glide.with(activity) + .asDrawable() + .load(urlHeader) + .into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Drawable resource, Transition transition) { - backgroundImage.setImageDrawable(resource); - if (theme == THEME_LIGHT) { - backgroundImage.setImageAlpha(80); - } else { - backgroundImage.setImageAlpha(60); - } + backgroundImage.setImageDrawable(resource); + if (theme == THEME_LIGHT) { + backgroundImage.setImageAlpha(80); + } else { + backgroundImage.setImageAlpha(60); + } - } + } - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { - } - }); + } + }); + } catch (Exception ignored) { + } + } } } profilePicture.setOnClickListener(null); @@ -2191,9 +2193,9 @@ public class Helper { return spannableString; } - public static WebView initializeWebview(Activity activity, int webviewId, View rootView) { + public static CustomWebview initializeWebview(Activity activity, int webviewId, View rootView) { - WebView webView; + CustomWebview webView; if (rootView == null) { webView = activity.findViewById(webviewId); } else { @@ -2241,30 +2243,6 @@ public class Helper { return webView; } - public static String md5(final String s) { - final String MD5 = "MD5"; - try { - // Create MD5 Hash - MessageDigest digest = java.security.MessageDigest - .getInstance(MD5); - digest.update(s.getBytes()); - byte[] messageDigest = digest.digest(); - - // Create Hex String - StringBuilder hexString = new StringBuilder(); - for (byte aMessageDigest : messageDigest) { - StringBuilder h = new StringBuilder(Integer.toHexString(0xFF & aMessageDigest)); - while (h.length() < 2) - h.insert(0, "0"); - hexString.append(h); - } - return hexString.toString(); - - } catch (NoSuchAlgorithmException ignored) { - } - return ""; - } - /** * change color of a drawable * @@ -2328,23 +2306,6 @@ public class Helper { imageButton.setColorFilter(color); } - /** - * change color of a drawable - * - * @param button int the button - * @param hexaColor example 0xffff00 - */ - public static void changeButtonTextColor(Context context, Button button, int hexaColor) { - if (button == null) - return; - int color; - try { - color = context.getResources().getColor(hexaColor); - } catch (Resources.NotFoundException e) { - color = hexaColor; - } - button.setTextColor(color); - } /** * Returns the current locale of the device @@ -2438,6 +2399,7 @@ public class Helper { Date dateEndD = formatter.parse(dateEnd); Date currentDateD = formatter.parse(currentDate); boolean canNotify = false; + assert currentDateD != null; if (currentDateD.before(dateEndD) && currentDateD.after(dateIniD) && notification == Helper.ACTION_ACTIVE) canNotify = true; else if (currentDateD.after(dateEndD) && currentDateD.before(dateIniD) && notification == Helper.ACTION_SILENT) @@ -2538,20 +2500,6 @@ public class Helper { } } - /** - * Unserialized a Locale - * - * @param serializedLocale String serialized locale - * @return Locale - */ - public static Locale restoreLocaleFromString(String serializedLocale) { - Gson gson = new Gson(); - try { - return gson.fromJson(serializedLocale, Locale.class); - } catch (Exception e) { - return null; - } - } /** * Serialized a Locale class @@ -2649,7 +2597,7 @@ public class Helper { * @param serializedArray String serialized array * @return List list */ - public static List restoreArrayFromString(String serializedArray) { + public static List restoreArrayFromString(String serializedArray) { Gson gson = new Gson(); try { return gson.fromJson(serializedArray, List.class); @@ -2946,49 +2894,6 @@ public class Helper { tableLayout.setVisibility(View.VISIBLE); } - /** - * Get a bitmap from a view - * - * @param view The view to convert - * @return Bitmap - */ - public static Bitmap convertTootIntoBitmap(Context context, String name, View view) { - - if (view.getWidth() == 0 || view.getHeight() == 0) { - Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show(); - return null; - } - Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth() + (int) Helper.convertDpToPixel(10, context), view.getHeight() + (int) Helper.convertDpToPixel(30, context), Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(returnedBitmap); - canvas.drawBitmap(returnedBitmap, view.getWidth() + (int) Helper.convertDpToPixel(10, context), 0, null); - Drawable bgDrawable = view.getBackground(); - if (bgDrawable != null) - bgDrawable.draw(canvas); - else { - final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); - if (theme == Helper.THEME_DARK) { - canvas.drawColor(ContextCompat.getColor(context, R.color.mastodonC1)); - - } else if (theme == Helper.THEME_BLACK) { - canvas.drawColor(ContextCompat.getColor(context, R.color.black)); - } else { - canvas.drawColor(Color.WHITE); - } - } - - view.draw(canvas); - Paint paint = new Paint(); - int mastodonC4 = ContextCompat.getColor(context, R.color.mastodonC4); - paint.setColor(mastodonC4); - paint.setStrokeWidth(12); - paint.setTextSize((int) Helper.convertDpToPixel(14, context)); - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); - canvas.drawText(name + " - #Fedilab", 0, view.getHeight() + (int) Helper.convertDpToPixel(15, context), paint); - - return returnedBitmap; - } - @SuppressLint("DefaultLocale") public static String withSuffix(long count) { if (count < 1000) return "" + count; @@ -3008,26 +2913,6 @@ public class Helper { "kMGTPE".charAt(exp - 1)); } - public static Bitmap addBorder(Bitmap resource, Context context) { - int w = resource.getWidth(); - int h = resource.getHeight(); - int radius = Math.min(h / 2, w / 2); - Bitmap output = Bitmap.createBitmap(w + 8, h + 8, Bitmap.Config.ARGB_8888); - Paint p = new Paint(); - p.setAntiAlias(true); - Canvas c = new Canvas(output); - c.drawARGB(0, 0, 0, 0); - p.setStyle(Paint.Style.FILL); - c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p); - p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); - c.drawBitmap(resource, 4, 4, p); - p.setXfermode(null); - p.setStyle(Paint.Style.STROKE); - p.setColor(ContextCompat.getColor(context, R.color.white)); - p.setStrokeWidth(3); - c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p); - return output; - } public static String secondsToString(int pTime) { @@ -3430,7 +3315,7 @@ public class Helper { } @SuppressLint("Recycle") - public static String getRealPathFromURI(Context context, Uri uri) throws URISyntaxException { + public static String getRealPathFromURI(Context context, Uri uri) { String selection = null; String[] selectionArgs = null; // Uri is different in versions after KITKAT (Android 4.4), we need to @@ -3529,7 +3414,7 @@ public class Helper { } } - public static Bitmap compressImageIfNeeded(Context context, Bitmap bmToCompress) { + public static Bitmap compressImageIfNeeded(Bitmap bmToCompress) { int size = bmToCompress.getByteCount(); double resizeby = 33554432; //4Mo @@ -3748,16 +3633,10 @@ public class Helper { } - private static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener) { - v.getViewTreeObserver().removeOnGlobalLayoutListener(listener); - } - public static int languageSpinnerPosition(Context context) { SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE); String defaultLocaleString = sharedpreferences.getString(Helper.SET_DEFAULT_LOCALE_NEW, "NOT_DEFINED"); switch (defaultLocaleString) { - case "NOT_DEFINED": - return 0; case "en": return 1; case "fr": @@ -4084,13 +3963,6 @@ public class Helper { } } - public static Uri getImageUri(Context inContext, Bitmap inImage) { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes); - String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null); - return Uri.parse(path); - } - public static void initNetCipher(Context context) { Context appContext = context.getApplicationContext(); @@ -4394,28 +4266,6 @@ public class Helper { } - public static Bitmap drawableToBitmap(Drawable drawable) { - Bitmap bitmap; - - if (drawable instanceof BitmapDrawable) { - BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; - if (bitmapDrawable.getBitmap() != null) { - return bitmapDrawable.getBitmap(); - } - } - - if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) { - bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - } else { - bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); - } - - Canvas canvas = new Canvas(bitmap); - drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); - drawable.draw(canvas); - return bitmap; - } - public static void startStreaming(Context context) { int liveNotifications = Helper.liveNotifType(context); Intent streamingIntent = null; diff --git a/app/src/main/java/app/fedilab/android/sqlite/PeertubeFavoritesDAO.java b/app/src/main/java/app/fedilab/android/sqlite/PeertubeFavoritesDAO.java index d90f99042..5c409cd46 100644 --- a/app/src/main/java/app/fedilab/android/sqlite/PeertubeFavoritesDAO.java +++ b/app/src/main/java/app/fedilab/android/sqlite/PeertubeFavoritesDAO.java @@ -16,7 +16,6 @@ package app.fedilab.android.sqlite; import android.content.ContentValues; import android.content.Context; -import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; @@ -98,7 +97,6 @@ public class PeertubeFavoritesDAO { * @return stored peertube List */ public List getAllPeertube() { - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); try { Cursor c = db.query(Sqlite.TABLE_PEERTUBE_FAVOURITES, null, null, null, null, null, Sqlite.COL_DATE + " DESC"); return cursorToListPeertube(c); @@ -113,7 +111,6 @@ public class PeertubeFavoritesDAO { * @return stored peertube List */ public List getSinglePeertube(Peertube peertube) { - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); try { Cursor c = db.query(Sqlite.TABLE_PEERTUBE_FAVOURITES, null, Sqlite.COL_UUID + " = \"" + peertube.getUuid() + "\" AND " + Sqlite.COL_INSTANCE + " = \"" + peertube.getInstance() + "\"", null, null, null, Sqlite.COL_DATE + " DESC"); return cursorToListPeertube(c); @@ -137,7 +134,7 @@ public class PeertubeFavoritesDAO { while (c.moveToNext()) { //Restore cached status try { - Peertube peertube = API.parsePeertube(context, c.getString(c.getColumnIndex(Sqlite.COL_INSTANCE)), new JSONObject(c.getString(c.getColumnIndex(Sqlite.COL_CACHE)))); + Peertube peertube = API.parsePeertube(c.getString(c.getColumnIndex(Sqlite.COL_INSTANCE)), new JSONObject(c.getString(c.getColumnIndex(Sqlite.COL_CACHE)))); peertubes.add(peertube); } catch (JSONException e) { e.printStackTrace(); diff --git a/app/src/main/java/app/fedilab/android/webview/CustomWebview.java b/app/src/main/java/app/fedilab/android/webview/CustomWebview.java new file mode 100644 index 000000000..298979279 --- /dev/null +++ b/app/src/main/java/app/fedilab/android/webview/CustomWebview.java @@ -0,0 +1,58 @@ +package app.fedilab.android.webview; +/* Copyright 2019 Thomas Schneider + * + * This file is a part of Fedilab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Fedilab; if not, + * see . */ + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.util.AttributeSet; +import android.webkit.WebView; + + +/** + * Created by Thomas on 14/10/2019. + * CustomWebview + */ + +public class CustomWebview extends WebView { + + + public CustomWebview(Context context) { + super(getFixedContext(context)); + } + + public CustomWebview(Context context, AttributeSet attrs) { + super(getFixedContext(context), attrs); + } + + public CustomWebview(Context context, AttributeSet attrs, int defStyleAttr) { + super(getFixedContext(context), attrs, defStyleAttr); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public CustomWebview(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(getFixedContext(context), attrs, defStyleAttr, defStyleRes); + } + + @SuppressWarnings("deprecation") + public CustomWebview(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) { + super(getFixedContext(context), attrs, defStyleAttr, privateBrowsing); + } + + public static Context getFixedContext(Context context) { + return context.createConfigurationContext(new Configuration()); + } +} diff --git a/app/src/main/java/app/fedilab/android/webview/MastalabWebChromeClient.java b/app/src/main/java/app/fedilab/android/webview/MastalabWebChromeClient.java index b66395c35..dd30053ff 100644 --- a/app/src/main/java/app/fedilab/android/webview/MastalabWebChromeClient.java +++ b/app/src/main/java/app/fedilab/android/webview/MastalabWebChromeClient.java @@ -46,7 +46,7 @@ public class MastalabWebChromeClient extends WebChromeClient implements MediaPla private ToggledFullscreenCallback toggledFullscreenCallback; - private WebView webView; + private CustomWebview webView; private View activityNonVideoView; private ViewGroup activityVideoView; private ProgressBar pbar; @@ -54,7 +54,7 @@ public class MastalabWebChromeClient extends WebChromeClient implements MediaPla private Activity activity; - public MastalabWebChromeClient(Activity activity, WebView webView, FrameLayout activityNonVideoView, ViewGroup activityVideoView) { + public MastalabWebChromeClient(Activity activity, CustomWebview webView, FrameLayout activityNonVideoView, ViewGroup activityVideoView) { this.activity = activity; this.isVideoFullscreen = false; this.webView = webView; diff --git a/app/src/main/java/app/fedilab/android/webview/MastalabWebViewClient.java b/app/src/main/java/app/fedilab/android/webview/MastalabWebViewClient.java index 0412fb845..28709948a 100644 --- a/app/src/main/java/app/fedilab/android/webview/MastalabWebViewClient.java +++ b/app/src/main/java/app/fedilab/android/webview/MastalabWebViewClient.java @@ -101,9 +101,7 @@ public class MastalabWebViewClient extends WebViewClient { return new WebResourceResponse("text/plain", "utf-8", nothing); } - } catch (URISyntaxException ignored) { - ignored.printStackTrace(); - } + } catch (URISyntaxException ignored) {} } } return super.shouldInterceptRequest(view, url); diff --git a/app/src/main/java/app/fedilab/android/webview/ProxyHelper.java b/app/src/main/java/app/fedilab/android/webview/ProxyHelper.java index 5ebdf9132..cac5ae7dd 100644 --- a/app/src/main/java/app/fedilab/android/webview/ProxyHelper.java +++ b/app/src/main/java/app/fedilab/android/webview/ProxyHelper.java @@ -19,7 +19,6 @@ import android.content.Context; import android.content.Intent; import android.net.Proxy; import android.util.ArrayMap; -import android.webkit.WebView; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -29,14 +28,14 @@ import java.lang.reflect.Method; public class ProxyHelper { - public static void setProxy(Context context, WebView webview, String host, int port, String applicationClassName) { + public static void setProxy(Context context, CustomWebview webview, String host, int port, String applicationClassName) { setProxyKKPlus(context, webview, host, port, applicationClassName); } @SuppressWarnings("all") - private static boolean setProxyICS(WebView webview, String host, int port) { + private static boolean setProxyICS(CustomWebview webview, String host, int port) { try { Class jwcjb = Class.forName("android.webkit.JWebCoreJavaBridge"); Class params[] = new Class[1]; @@ -73,7 +72,7 @@ public class ProxyHelper { * Set Proxy for Android 4.1 - 4.3. */ @SuppressWarnings("all") - private static boolean setProxyJB(WebView webview, String host, int port) { + private static boolean setProxyJB(CustomWebview webview, String host, int port) { try { Class wvcClass = Class.forName("android.webkit.WebViewClassic"); @@ -116,7 +115,7 @@ public class ProxyHelper { // from https://stackoverflow.com/questions/19979578/android-webview-set-proxy-programatically-kitkat @SuppressLint("NewApi") @SuppressWarnings("all") - private static void setProxyKKPlus(Context appContext, WebView webView, String host, int port, String applicationClassName) { + private static void setProxyKKPlus(Context appContext, CustomWebview webView, String host, int port, String applicationClassName) { System.setProperty("http.proxyHost", host); System.setProperty("http.proxyPort", port + ""); diff --git a/app/src/main/res/layout/activity_peertube.xml b/app/src/main/res/layout/activity_peertube.xml index e5e849fed..de23889d0 100644 --- a/app/src/main/res/layout/activity_peertube.xml +++ b/app/src/main/res/layout/activity_peertube.xml @@ -51,7 +51,7 @@ android:layout_height="match_parent" android:gravity="center" /> - - - diff --git a/app/src/main/res/layout/drawer_status.xml b/app/src/main/res/layout/drawer_status.xml index 21f855648..8eda48cbb 100644 --- a/app/src/main/res/layout/drawer_status.xml +++ b/app/src/main/res/layout/drawer_status.xml @@ -557,7 +557,7 @@ - - - - - L\'app non raccoglie emoji personalizzate per il momento. Notifiche in tempo reale Sei sicuro di volerti disconnettere? - Are you sure you want to logout @%1$s@%2$s? + Sei sicuro di volerti disconnettere @%1$s@%2$s? Nessun toot da mostrare Nessuna storia da mostrare @@ -1117,5 +1117,5 @@ Annunci Nessun annuncio! Aggiungi una reazione - Use your favourite browser inside the app. Uncheck this feature to open links externally. + Usa il tuo browser preferito all\'interno dell\'app. Deseleziona questa funzione per aprire i link esternamente. diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 13b3c09e2..1499a081f 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -83,7 +83,7 @@ アプリはしばらくの間カスタム絵文字を収集していません。 ライブ通知 本当にログアウトしますか? - Are you sure you want to logout @%1$s@%2$s? + \@%1$s@%2$sからログアウトしますか? トゥートがありません 表示するストーリーがありません @@ -1100,5 +1100,5 @@ お知らせ お知らせはありません! リアクションを追加 - Use your favourite browser inside the app. Uncheck this feature to open links externally. + アプリ内でお気に入りのブラウザを使用します。リンクを外部アプリで開きたい場合はこのチェックを外してください。 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 000a0b10e..b0a84b134 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -100,7 +100,6 @@ Pin this toot? Unpin this toot? - Mute Block Report diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 7113d8640..ed4f7064e 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -116,6 +116,7 @@ -