Merge branch 'l10n_develop_new' of framagit.org:tom79/fedilab into l10n_develop_new

This commit is contained in:
Thomas 2020-05-07 17:02:27 +02:00
commit e0c2d58612
47 changed files with 460 additions and 540 deletions

View File

@ -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

View File

@ -0,0 +1,4 @@
Added:
- Simple click on reactions to add them
Fixed:
- Recent crashes (connection, when scrolling)

View File

@ -0,0 +1,2 @@
Fixed:
- Fix last remaining issues

View File

@ -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) {

View File

@ -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()) {

View File

@ -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);

View File

@ -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);

View File

@ -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)) {

View File

@ -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) {

View File

@ -316,7 +316,7 @@ public class SlideMediaActivity extends BaseActivity implements OnDownloadInterf
public void togglePlaying(View v) {
if (mCurrentFragment != null) {
mCurrentFragment.togglePlaying(v);
mCurrentFragment.togglePlaying();
}
}

View File

@ -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;

View File

@ -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;

View File

@ -369,9 +369,9 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
List<app.fedilab.android.client.Entities.Status> 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<>();

View File

@ -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<Status>
*/
private static List<Status> parseStatuses(Context context, filterFor action, JSONArray jsonArray) {
private static List<Status> parseStatuses(Context context, JSONArray jsonArray) {
List<Status> 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<Attachment> attachments = new ArrayList<>();
//Retrieves attachments
if (resobj.has("media_attachments")) {
@ -807,41 +811,46 @@ public class API {
status.setMedia_attachments(attachments);
//Retrieves mentions
List<Mention> 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<Tag> 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<Emojis> 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<IdentityProof> parseIdentityProof(Context context, JSONArray jsonArray) {
private List<IdentityProof> parseIdentityProof(JSONArray jsonArray) {
List<IdentityProof> 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<Status> tmp_status = parseStatuses(context, null, new JSONArray(response));
List<Status> 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<Account> parseAccountResponsePeertube(Context context, String instance, JSONArray jsonArray) {
private List<Account> parseAccountResponsePeertube(String instance, JSONArray jsonArray) {
List<Account> 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,

View File

@ -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<Context> 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;
}
}

View File

@ -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 <http://www.gnu.org/licenses>. */
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;
}
}

View File

@ -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);

View File

@ -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<Context> 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<Context> 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<Context> 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<Context> contextWeakReference, Poll poll) {
Context context = contextWeakReference.get();
if ((context instanceof Activity && ((Activity) context).isFinishing()) || poll == null || poll.getOptionsList() == null)
return;
final List<Emojis> 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<Context> contextWeakReference, Status status) {
Context context = contextWeakReference.get();
if (context instanceof Activity && ((Activity) context).isFinishing())
return;
if (status.getAccount() == null)

View File

@ -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<Account>
*/
private static List<Account> parseGroups(Context context, JSONArray jsonArray) {
private static List<Account> parseGroups(JSONArray jsonArray) {
List<Account> 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++;
}

View File

@ -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<String> 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<Integer, String> 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<String, String> 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<Account> parseAccountResponsePeertube(Context context, JSONArray jsonArray) {
private List<Account> parseAccountResponsePeertube(JSONArray jsonArray) {
List<Account> 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++;
}

View File

@ -15,6 +15,8 @@ package app.fedilab.android.drawers;
* see <http://www.gnu.org/licenses>. */
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<Reaction> reactions;
private RetrieveFeedsAsyncTask.Type type;
private String statusId;
ReactionAdapter(List<Reaction> reactions) {
ReactionAdapter(List<Reaction> 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;

View File

@ -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;

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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();
}

View File

@ -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<Bitmap>() {
@Override
public void onResourceReady(@NonNull final Bitmap resource, Transition<? super Bitmap> 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<? super Bitmap> 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

View File

@ -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<Bitmap>() {
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> 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<? super Drawable> 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<Drawable>() {
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<Drawable>() {
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> 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<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, Transition<? super Drawable> 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<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, Transition<? super Drawable> 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<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, Transition<? super Drawable> transition) {
if (!activity.isFinishing() && isAttached) {
try {
Glide.with(activity)
.asDrawable()
.load(urlHeader)
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, Transition<? super Drawable> 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<String> list
*/
public static List restoreArrayFromString(String serializedArray) {
public static List<String> 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;

View File

@ -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<Peertube>
*/
public List<Peertube> 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<Peertube>
*/
public List<Peertube> 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();

View File

@ -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 <http://www.gnu.org/licenses>. */
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());
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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 + "");

View File

@ -51,7 +51,7 @@
android:layout_height="match_parent"
android:gravity="center" />
<WebView
<app.fedilab.android.webview.CustomWebview
android:id="@+id/webview_video"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -37,7 +37,7 @@
android:layout_height="0dp"
android:layout_weight="1">
<WebView
<app.fedilab.android.webview.CustomWebview
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -31,7 +31,7 @@
android:layout_height="10dp"
android:padding="2dp"/>
<WebView
<app.fedilab.android.webview.CustomWebview
android:id="@+id/webviewConnect"
android:layout_width="match_parent"
android:layout_height="0dp"

View File

@ -35,7 +35,6 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_weight="1"
android:orientation="vertical">

View File

@ -557,7 +557,7 @@
</RelativeLayout>
<WebView
<app.fedilab.android.webview.CustomWebview
android:id="@+id/status_cardview_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -481,7 +481,7 @@
/>
</RelativeLayout>
<WebView
<app.fedilab.android.webview.CustomWebview
android:id="@+id/status_cardview_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -432,7 +432,7 @@
/>
</RelativeLayout>
<WebView
<app.fedilab.android.webview.CustomWebview
android:id="@+id/status_cardview_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -414,7 +414,7 @@
</RelativeLayout>
<WebView
<app.fedilab.android.webview.CustomWebview
android:id="@+id/status_cardview_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -37,7 +37,7 @@
android:layout_height="match_parent"
android:layout_centerInParent="true">
<WebView
<app.fedilab.android.webview.CustomWebview
android:id="@+id/webview_video"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -83,7 +83,7 @@
<string name="no_emoji">L\'app non raccoglie emoji personalizzate per il momento.</string>
<string name="live_notif">Notifiche in tempo reale</string>
<string name="logout_confirmation">Sei sicuro di volerti disconnettere?</string>
<string name="logout_account_confirmation">Are you sure you want to logout @%1$s@%2$s?</string>
<string name="logout_account_confirmation">Sei sicuro di volerti disconnettere @%1$s@%2$s?</string>
<!-- Status -->
<string name="no_status">Nessun toot da mostrare</string>
<string name="no_stories">Nessuna storia da mostrare</string>
@ -1117,5 +1117,5 @@
<string name="action_announcements">Annunci</string>
<string name="no_announcements">Nessun annuncio!</string>
<string name="add_reaction">Aggiungi una reazione</string>
<string name="set_custom_tabs_indication">Use your favourite browser inside the app. Uncheck this feature to open links externally.</string>
<string name="set_custom_tabs_indication">Usa il tuo browser preferito all\'interno dell\'app. Deseleziona questa funzione per aprire i link esternamente.</string>
</resources>

View File

@ -83,7 +83,7 @@
<string name="no_emoji">アプリはしばらくの間カスタム絵文字を収集していません。</string>
<string name="live_notif">ライブ通知</string>
<string name="logout_confirmation">本当にログアウトしますか?</string>
<string name="logout_account_confirmation">Are you sure you want to logout @%1$s@%2$s?</string>
<string name="logout_account_confirmation">\@%1$s@%2$sからログアウトしますか</string>
<!-- Status -->
<string name="no_status">トゥートがありません</string>
<string name="no_stories">表示するストーリーがありません</string>
@ -1100,5 +1100,5 @@
<string name="action_announcements">お知らせ</string>
<string name="no_announcements">お知らせはありません!</string>
<string name="add_reaction">リアクションを追加</string>
<string name="set_custom_tabs_indication">Use your favourite browser inside the app. Uncheck this feature to open links externally.</string>
<string name="set_custom_tabs_indication">アプリ内でお気に入りのブラウザを使用します。リンクを外部アプリで開きたい場合はこのチェックを外してください。</string>
</resources>

View File

@ -100,7 +100,6 @@
<string name="pin_add">Pin this toot?</string>
<string name="pin_remove">Unpin this toot?</string>
<string name="more_action_1">Mute</string>
<string name="more_action_2">Block</string>
<string name="more_action_3">Report</string>

View File

@ -116,6 +116,7 @@
</style>
<style name="Dialog" parent="Cyanea.AlertDialog.Theme.Light">
<item name="iconColorMenu">@color/black</item>
<item name="iconColor">@color/black</item>
<item name="textColor">@color/black</item>
<item name="android:textColor">@color/black</item>
@ -125,6 +126,7 @@
</style>
<style name="DialogDark" parent="Cyanea.AlertDialog.Theme.Dark">
<item name="iconColorMenu">@color/dark_icon_theme</item>
<item name="iconColor">@color/dark_icon_theme</item>
<item name="android:textColor">@color/dark_text</item>
<item name="buttonBarButtonStyle">@style/DialogButton</item>
@ -133,6 +135,7 @@
</style>
<style name="DialogBlack" parent="Cyanea.AlertDialog.Theme.Dark">
<item name="iconColorMenu">@color/black_icon_theme</item>
<item name="iconColor">@color/black_icon_theme</item>
<item name="android:textColor">@color/dark_text</item>
<item name="buttonBarButtonStyle">@style/DialogButton</item>
@ -140,7 +143,7 @@
<item name="android:windowBackground">@color/cyanea_primary_reference</item>
</style>
<style name="TransparentLight" parent="Theme.Cyanea.Light">black_icon_theme
<style name="TransparentLight" parent="Theme.Cyanea.Light">
<item name="iconColor">@color/black</item>
<item name="iconColorMenu">@color/black</item>
<item name="android:windowBackground">@android:color/transparent</item>

View File

@ -0,0 +1,4 @@
Added:
- Simple click on reactions to add them
Fixed:
- Recent crashes (connection, when scrolling)

View File

@ -0,0 +1,2 @@
Fixed:
- Fix last remaining issues