Merge branch 'develop'

This commit is contained in:
Thomas 2020-07-08 13:54:17 +02:00
commit 89899557df
99 changed files with 2904 additions and 1695 deletions

View File

@ -6,8 +6,8 @@ android {
defaultConfig {
minSdkVersion 19
targetSdkVersion 29
versionCode 372
versionName "2.35.8"
versionCode 374
versionName "2.36.0"
multiDexEnabled true
renderscriptTargetApi 28 as int
renderscriptSupportModeEnabled true
@ -117,6 +117,7 @@ dependencies {
implementation "info.guardianproject.netcipher:netcipher:2.0.0-alpha1"
implementation "info.guardianproject.netcipher:netcipher-okhttp3:2.0.0-alpha1"
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.github.adrielcafe:AndroidAudioRecorder:0.3.0'
implementation 'yogesh.firzen:MukkiyaSevaigal:1.0.6'
implementation 'com.iceteck.silicompressorr:silicompressor:2.2.2'

View File

@ -69,6 +69,11 @@
android:name="app.fedilab.android.services.BackupNotificationInDataBaseService"
android:exported="false" />
<receiver android:name=".services.UpgradeReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
<receiver
android:name="app.fedilab.android.services.RestartLiveNotificationReceiver"
android:exported="false">
@ -527,5 +532,6 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>

View File

@ -0,0 +1,18 @@
Added:
- Select text for media description
changed:
- Increase media description length to 1500 chars
- More details about accounts in notifications
- Media management in timelines
- Allow cross-account replies on followed instances
Fixed:
- Remove extra spaces at the bottom of messages
- Some issue with custom emoji
- Fix issue with "Your toots/notifications"
- Fix issue with CW and Pixelfed
- Fix some media not loaded in profiles
- Scheduled toots from server side have an incorrect date
- Incorrect feeds when checking instance admin account
- Some crashes

View File

@ -0,0 +1,19 @@
Added:
- Select text for media description
changed:
- Increase media description length to 1500 chars
- More details about accounts in notifications
- Media management in timelines
- Allow cross-account replies on followed instances
Fixed:
- Crash when adding media
- Remove extra spaces at the bottom of messages
- Some issue with custom emoji
- Fix issue with "Your toots/notifications"
- Fix issue with CW and Pixelfed
- Fix some media not loaded in profiles
- Scheduled toots from server side have an incorrect date
- Incorrect feeds when checking instance admin account
- Some crashes

View File

@ -5,9 +5,11 @@ import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.View;
import android.view.Window;
import android.widget.Toast;
import androidx.annotation.NonNull;
@ -67,6 +69,9 @@ public class BaseActivity extends CyaneaAppCompatActivity {
.build());
}*/
canShowActionMode = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
}
super.onCreate(savedInstanceState);
}

View File

@ -986,8 +986,8 @@ public abstract class BaseMainActivity extends BaseActivity
SeekBar set_icon_size = popup_quick_settings.findViewById(R.id.set_icon_size);
final TextView set_text_size_value = popup_quick_settings.findViewById(R.id.set_text_size_value);
final TextView set_icon_size_value = popup_quick_settings.findViewById(R.id.set_icon_size_value);
set_text_size_value.setText(String.format("%s%%", String.valueOf(textSize)));
set_icon_size_value.setText(String.format("%s%%", String.valueOf(iconSize)));
set_text_size_value.setText(String.format("%s%%", textSize));
set_icon_size_value.setText(String.format("%s%%", iconSize));
set_text_size.setMax(20);
set_icon_size.setMax(20);
@ -1008,7 +1008,7 @@ public abstract class BaseMainActivity extends BaseActivity
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int value = 80 + progress * 5;
set_text_size_value.setText(String.format("%s%%", String.valueOf(value)));
set_text_size_value.setText(String.format("%s%%", value));
SharedPreferences.Editor editor = sharedpreferences1.edit();
editor.putInt(Helper.SET_TEXT_SIZE, value);
editor.apply();
@ -1026,7 +1026,7 @@ public abstract class BaseMainActivity extends BaseActivity
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int value = 80 + progress * 5;
set_icon_size_value.setText(String.format("%s%%", String.valueOf(value)));
set_icon_size_value.setText(String.format("%s%%", value));
SharedPreferences.Editor editor = sharedpreferences1.edit();
editor.putInt(Helper.SET_ICON_SIZE, value);
editor.apply();
@ -1503,9 +1503,9 @@ public abstract class BaseMainActivity extends BaseActivity
}
} else if (type.startsWith("image/") || type.startsWith("video/")) {
Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (!TootActivity.active) {
Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (imageUri != null) {
Bundle b = new Bundle();
b.putParcelable("sharedUri", imageUri);
@ -1513,7 +1513,6 @@ public abstract class BaseMainActivity extends BaseActivity
CrossActions.doCrossShare(BaseMainActivity.this, b);
}
} else {
Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (imageUri != null) {
intent = new Intent(BaseMainActivity.this, TootActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
@ -2381,7 +2380,13 @@ public abstract class BaseMainActivity extends BaseActivity
}
}
final NavigationView navigationView = findViewById(R.id.nav_view);
if (navigationView == null) {
return;
}
MenuItem item = navigationView.getMenu().findItem(R.id.nav_announcements);
if (item == null || item.getActionView() == null) {
return;
}
TextView actionView = item.getActionView().findViewById(R.id.counter);
if (actionView != null) {
if (unread > 0) {

View File

@ -122,7 +122,7 @@ public class InstanceProfileActivity extends BaseActivity {
finish();
return;
}
if (instanceNodeInfo.getThumbnail() != null && !instanceNodeInfo.getThumbnail().equals("null"))
if (instanceNodeInfo.getThumbnail() != null && !instanceNodeInfo.getThumbnail().equals("null") && Helper.isValidContextForGlide(InstanceProfileActivity.this))
Glide.with(InstanceProfileActivity.this)
.asBitmap()
.load(instanceNodeInfo.getThumbnail())
@ -149,7 +149,7 @@ public class InstanceProfileActivity extends BaseActivity {
accounts.add(instanceNodeInfo.getStaffAccount());
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
AccountsListAdapter accountsListAdapter = new AccountsListAdapter(RetrieveAccountsAsyncTask.Type.FOLLOWERS, userId, accounts);
AccountsListAdapter accountsListAdapter = new AccountsListAdapter(RetrieveAccountsAsyncTask.Type.FOLLOWERS, userId, true, accounts);
lv_accounts.setAdapter(accountsListAdapter);
final LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(InstanceProfileActivity.this);

View File

@ -175,7 +175,7 @@ public class OwnerChartsActivity extends BaseActivity implements OnRetrieveChart
dateEnd = new StatusCacheDAO(OwnerChartsActivity.this, db).getGreaterDate(StatusCacheDAO.ARCHIVE_CACHE);
if( dateIni == null){
if (dateIni == null) {
dateIni = new Date();
dateEnd = new Date();
}
@ -417,7 +417,7 @@ public class OwnerChartsActivity extends BaseActivity implements OnRetrieveChart
@Override
public MPPointF getOffset() {
if (mOffset == null) {
mOffset = new MPPointF(-((float)getWidth() / 2), -getHeight());
mOffset = new MPPointF(-((float) getWidth() / 2), -getHeight());
}
return mOffset;
}

View File

@ -15,6 +15,7 @@
package app.fedilab.android.activities;
import android.annotation.SuppressLint;
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.SharedPreferences;
@ -260,27 +261,26 @@ public class OwnerNotificationChartsActivity extends BaseActivity implements OnR
List<Entry> boostsEntry = new ArrayList<>();
Iterator it = charts.getReblogs().entrySet().iterator();
Iterator<Map.Entry<Long, Integer>> it = charts.getReblogs().entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
boostsEntry.add(new Entry((long) pair.getKey(), (int) pair.getValue()));
Map.Entry<Long, Integer> pair = it.next();
boostsEntry.add(new Entry(pair.getKey(), pair.getValue()));
it.remove();
}
List<Entry> favEntry = new ArrayList<>();
it = charts.getFavourites().entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
favEntry.add(new Entry((long) pair.getKey(), (int) pair.getValue()));
Map.Entry<Long, Integer> pair = it.next();
favEntry.add(new Entry(pair.getKey(), pair.getValue()));
it.remove();
}
List<Entry> mentionEntry = new ArrayList<>();
it = charts.getMentions().entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
mentionEntry.add(new Entry((long) pair.getKey(), (int) pair.getValue()));
Map.Entry<Long, Integer> pair = it.next();
mentionEntry.add(new Entry(pair.getKey(), pair.getValue()));
it.remove();
}
@ -288,8 +288,8 @@ public class OwnerNotificationChartsActivity extends BaseActivity implements OnR
List<Entry> followEntry = new ArrayList<>();
it = charts.getFollows().entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
followEntry.add(new Entry((long) pair.getKey(), (int) pair.getValue()));
Map.Entry<Long, Integer> pair = it.next();
followEntry.add(new Entry(pair.getKey(), pair.getValue()));
it.remove();
}
@ -482,6 +482,7 @@ public class OwnerNotificationChartsActivity extends BaseActivity implements OnR
super.onDestroy();
}
@SuppressLint("ViewConstructor")
public static class CustomMarkerView extends MarkerView {
private TextView tvContent;
private MPPointF mOffset;
@ -503,7 +504,7 @@ public class OwnerNotificationChartsActivity extends BaseActivity implements OnR
@Override
public MPPointF getOffset() {
if (mOffset == null) {
mOffset = new MPPointF(-(getWidth() / 2), -getHeight());
mOffset = new MPPointF(-((float) getWidth() / 2), -getHeight());
}
return mOffset;
}

View File

@ -522,11 +522,11 @@ public class OwnerStatusActivity extends BaseActivity implements OnRetrieveFeeds
frequency.setText(getString(R.string.toot_per_day, df.format(statistics.getFrequency())));
if (statistics.getTagsTrend() != null && statistics.getTagsTrend().size() > 0) {
Iterator it = statistics.getTagsTrend().entrySet().iterator();
Iterator<Map.Entry<String, Integer>> it = statistics.getTagsTrend().entrySet().iterator();
StringBuilder text = new StringBuilder();
int i = 1;
while (it.hasNext() && i <= 10) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<String, Integer> pair = it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
text.append(i).append(" - ").append(pair.getKey()).append("").append(pair.getValue()).append("\r\n");
i++;

View File

@ -639,26 +639,18 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube
@Override
public void onConfigurationChanged(@NotNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (mode != Helper.VIDEO_MODE_WEBVIEW) {
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (mode != Helper.VIDEO_MODE_WEBVIEW) {
openFullscreenDialog();
setFullscreen(FullScreenMediaController.fullscreen.ON);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
}
setFullscreen(FullScreenMediaController.fullscreen.ON);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
if (mode != Helper.VIDEO_MODE_WEBVIEW) {
closeFullscreenDialog();
setFullscreen(FullScreenMediaController.fullscreen.OFF);
}
change();
} else {
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
setFullscreen(FullScreenMediaController.fullscreen.ON);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
setFullscreen(FullScreenMediaController.fullscreen.OFF);
}
change();
setFullscreen(FullScreenMediaController.fullscreen.OFF);
}
change();
}

View File

@ -80,7 +80,6 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
private String videoId;
private Account channel;
@SuppressWarnings("SuspiciousMethodCalls")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -168,12 +167,12 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
translations = new LinkedHashMap<>(peertubeInformation.getTranslations());
//Populate catgories
String[] categoriesA = new String[categories.size()];
Iterator it = categories.entrySet().iterator();
Iterator<Map.Entry<Integer, String>> it = categories.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (translations == null || translations.size() == 0 || !translations.containsKey(pair.getValue()))
categoriesA[i] = (String) pair.getValue();
categoriesA[i] = pair.getValue();
else
categoriesA[i] = translations.get(pair.getValue());
it.remove();
@ -189,9 +188,9 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
it = licences.entrySet().iterator();
i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (translations == null || translations.size() == 0 || !translations.containsKey(pair.getValue()))
licensesA[i] = (String) pair.getValue();
licensesA[i] = pair.getValue();
else
licensesA[i] = translations.get(pair.getValue());
it.remove();
@ -204,12 +203,12 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
//Populate languages
String[] languagesA = new String[languages.size()];
it = languages.entrySet().iterator();
Iterator<Map.Entry<String, String>> itl = languages.entrySet().iterator();
i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<String, String> pair = itl.next();
if (translations == null || translations.size() == 0 || !translations.containsKey(pair.getValue()))
languagesA[i] = (String) pair.getValue();
languagesA[i] = pair.getValue();
else
languagesA[i] = translations.get(pair.getValue());
it.remove();
@ -225,9 +224,9 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
it = privacies.entrySet().iterator();
i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (translations == null || translations.size() == 0 || !translations.containsKey(pair.getValue()))
privaciesA[i] = (String) pair.getValue();
privaciesA[i] = pair.getValue();
else
privaciesA[i] = translations.get(pair.getValue());
it.remove();
@ -347,9 +346,9 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
int languagePosition = 0;
if (languages.containsValue(language)) {
Iterator it = languages.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = languages.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<String, String> pair = it.next();
if (pair.getValue().equals(language))
break;
it.remove();
@ -358,9 +357,9 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
}
int privacyPosition = 0;
if (privacy != null && privacies.containsValue(privacy)) {
Iterator it = privacies.entrySet().iterator();
Iterator<Map.Entry<Integer, String>> it = privacies.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (pair.getValue().equals(privacy))
break;
it.remove();
@ -369,9 +368,9 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
}
int licensePosition = 0;
if (license != null && licences.containsValue(license)) {
Iterator it = licences.entrySet().iterator();
Iterator<Map.Entry<Integer, String>> it = licences.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (pair.getValue().equals(license))
break;
it.remove();
@ -380,9 +379,9 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
}
int categoryPosition = 0;
if (category != null && categories.containsValue(category)) {
Iterator it = categories.entrySet().iterator();
Iterator<Map.Entry<Integer, String>> it = categories.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (pair.getValue().equals(category))
break;
it.remove();
@ -395,13 +394,13 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
LinkedHashMap<Integer, String> privaciesCheck = new LinkedHashMap<>(peertubeInformation.getPrivacies());
Iterator it = privaciesCheck.entrySet().iterator();
Iterator<Map.Entry<Integer, String>> it = privaciesCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (i == position) {
privacyToSend = new HashMap<>();
privacyToSend.put((Integer) pair.getKey(), (String) pair.getValue());
privacyToSend.put(pair.getKey(), pair.getValue());
break;
}
it.remove();
@ -418,13 +417,13 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
LinkedHashMap<Integer, String> licensesCheck = new LinkedHashMap<>(peertubeInformation.getLicences());
Iterator it = licensesCheck.entrySet().iterator();
Iterator<Map.Entry<Integer, String>> it = licensesCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (i == position) {
licenseToSend = new HashMap<>();
licenseToSend.put((Integer) pair.getKey(), (String) pair.getValue());
licenseToSend.put(pair.getKey(), pair.getValue());
break;
}
it.remove();
@ -442,13 +441,13 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
LinkedHashMap<Integer, String> categoriesCheck = new LinkedHashMap<>(peertubeInformation.getCategories());
Iterator it = categoriesCheck.entrySet().iterator();
Iterator<Map.Entry<Integer, String>> it = categoriesCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (i == position) {
categoryToSend = new HashMap<>();
categoryToSend.put((Integer) pair.getKey(), (String) pair.getValue());
categoryToSend.put(pair.getKey(), pair.getValue());
break;
}
it.remove();
@ -467,13 +466,13 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
LinkedHashMap<String, String> languagesCheck = new LinkedHashMap<>(peertubeInformation.getLanguages());
Iterator it = languagesCheck.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = languagesCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<String, String> pair = it.next();
if (i == position) {
languageToSend = new HashMap<>();
languageToSend.put((String) pair.getKey(), (String) pair.getValue());
languageToSend.put(pair.getKey(), pair.getValue());
break;
}
it.remove();
@ -491,13 +490,13 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
LinkedHashMap<String, String> channelsCheck = new LinkedHashMap<>(channels);
Iterator it = channelsCheck.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = channelsCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<String, String> pair = it.next();
if (i == position) {
channelToSend = new HashMap<>();
channelToSend.put((String) pair.getKey(), (String) pair.getValue());
channelToSend.put(pair.getKey(), pair.getValue());
break;
}
@ -540,8 +539,7 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
List<String> tags = peertube.getTags();
if (tags != null && tags.size() > 0) {
//noinspection ToArrayCallWithZeroLengthArrayArgument
String[] tagsA = tags.toArray(new String[tags.size()]);
String[] tagsA = tags.toArray(new String[0]);
p_video_tags.setTags(tagsA);
}
@ -578,12 +576,12 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
int channelPosition = 0;
if (channels.containsKey(channel.getUsername())) {
LinkedHashMap<String, String> channelsIterator = new LinkedHashMap<>(channels);
Iterator it = channelsIterator.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = channelsIterator.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<String, String> pair = it.next();
if (pair.getKey().equals(channel.getUsername())) {
channelToSend = new HashMap<>();
channelToSend.put((String) pair.getKey(), (String) pair.getValue());
channelToSend.put(pair.getKey(), pair.getValue());
break;
}
it.remove();

View File

@ -194,7 +194,6 @@ public class PeertubeUploadActivity extends BaseActivity implements OnRetrievePe
}
@SuppressWarnings("SuspiciousMethodCalls")
@Override
public void onRetrievePeertubeChannels(APIResponse apiResponse) {
if (apiResponse.getError() != null || apiResponse.getAccounts() == null || apiResponse.getAccounts().size() == 0) {
@ -237,12 +236,12 @@ public class PeertubeUploadActivity extends BaseActivity implements OnRetrievePe
LinkedHashMap<Integer, String> privacies = new LinkedHashMap<>(peertubeInformation.getPrivacies());
//Populate privacies
String[] privaciesA = new String[privacies.size()];
Iterator it = privacies.entrySet().iterator();
Iterator<Map.Entry<Integer, String>> it = privacies.entrySet().iterator();
i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (translations == null || translations.size() == 0 || !translations.containsKey(pair.getValue()))
privaciesA[i] = (String) pair.getValue();
privaciesA[i] = pair.getValue();
else
privaciesA[i] = translations.get(pair.getValue());
it.remove();
@ -258,13 +257,13 @@ public class PeertubeUploadActivity extends BaseActivity implements OnRetrievePe
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
LinkedHashMap<Integer, String> privaciesCheck = new LinkedHashMap<>(peertubeInformation.getPrivacies());
Iterator it = privaciesCheck.entrySet().iterator();
Iterator<Map.Entry<Integer, String>> it = privaciesCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<Integer, String> pair = it.next();
if (i == position) {
privacyToSend = new HashMap<>();
privacyToSend.put((Integer) pair.getKey(), (String) pair.getValue());
privacyToSend.put(pair.getKey(), pair.getValue());
break;
}
it.remove();
@ -309,13 +308,13 @@ public class PeertubeUploadActivity extends BaseActivity implements OnRetrievePe
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
LinkedHashMap<String, String> channelsCheck = new LinkedHashMap<>(channels);
Iterator it = channelsCheck.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = channelsCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<String, String> pair = it.next();
if (i == position) {
channelToSend = new HashMap<>();
channelToSend.put((String) pair.getKey(), (String) pair.getValue());
channelToSend.put(pair.getKey(), pair.getValue());
break;
}

View File

@ -18,6 +18,7 @@ import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.net.Uri;
@ -33,6 +34,8 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.exifinterface.media.ExifInterface;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -74,6 +77,7 @@ public class PhotoEditorActivity extends BaseActivity implements OnPhotoEditorLi
private static final int CAMERA_REQUEST = 52;
private static final int PICK_REQUEST = 53;
private final int STORE_REQUEST = 54;
private PhotoEditor mPhotoEditor;
private PhotoEditorView mPhotoEditorView;
private PropertiesBSFragment mPropertiesBSFragment;
@ -302,6 +306,13 @@ public class PhotoEditorActivity extends BaseActivity implements OnPhotoEditorLi
.setClearViewsEnabled(true)
.setTransparencyEnabled(true)
.build();
if (ContextCompat.checkSelfPermission(PhotoEditorActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(PhotoEditorActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
STORE_REQUEST);
return;
}
mPhotoEditor.saveAsFile(file.getAbsolutePath(), saveSettings, new PhotoEditor.OnSaveListener() {
@Override
public void onSuccess(@NonNull String imagePath) {
@ -332,6 +343,18 @@ public class PhotoEditorActivity extends BaseActivity implements OnPhotoEditorLi
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == STORE_REQUEST) {// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// We have the permission.
saveImage();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

View File

@ -254,8 +254,7 @@ public class PixelfedComposeActivity extends BaseActivity implements UploadStatu
final int[] currentCursorPosition = {toot_content.getSelectionStart()};
final String[] newContent = {null};
final int[] searchLength = {searchDeep};
TextWatcher textw = null;
TextWatcher finalTextw = textw;
TextWatcher textw;
textw = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@ -270,7 +269,7 @@ public class PixelfedComposeActivity extends BaseActivity implements UploadStatu
public void afterTextChanged(Editable s) {
if (autocomplete) {
toot_content.removeTextChangedListener(finalTextw);
toot_content.removeTextChangedListener(this);
Thread thread = new Thread() {
@Override
public void run() {
@ -357,11 +356,8 @@ public class PixelfedComposeActivity extends BaseActivity implements UploadStatu
if (s.toString().length() == 0)
currentCursorPosition[0] = 0;
//Only check last 15 characters before cursor position to avoid lags
if (currentCursorPosition[0] < searchDeep) { //Less than 15 characters are written before the cursor position
searchLength[0] = currentCursorPosition[0];
} else {
searchLength[0] = searchDeep;
}
//Less than 15 characters are written before the cursor position
searchLength[0] = Math.min(currentCursorPosition[0], searchDeep);
int totalChar = countLength(social, toot_content);
@ -700,6 +696,9 @@ public class PixelfedComposeActivity extends BaseActivity implements UploadStatu
}
restored = b.getLong("restored", -1);
}
if (!sharedUri.isEmpty()) {
uploadSharedImage(sharedUri);
}
if (scheduledstatus != null)
toot_it.setText(R.string.modify);
if (restoredScheduled) {

View File

@ -81,9 +81,6 @@ public class PlaylistsActivity extends BaseActivity implements OnPlaylistActionI
case Helper.THEME_LIGHT:
setTheme(R.style.AppTheme_NoActionBar_Fedilab);
break;
case Helper.THEME_DARK:
setTheme(R.style.AppThemeDark_NoActionBar);
break;
case Helper.THEME_BLACK:
setTheme(R.style.AppThemeBlack_NoActionBar);
break;
@ -102,12 +99,7 @@ public class PlaylistsActivity extends BaseActivity implements OnPlaylistActionI
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
TextView toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
toolbar_close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
toolbar_close.setOnClickListener(v -> finish());
toolbar_title.setText(R.string.upload_video);
}
@ -140,7 +132,6 @@ public class PlaylistsActivity extends BaseActivity implements OnPlaylistActionI
mainLoader.setVisibility(View.VISIBLE);
nextElementLoader.setVisibility(View.GONE);
boolean isOnWifi = Helper.isOnWIFI(PlaylistsActivity.this);
peertubeAdapter = new PeertubeAdapter(Helper.getLiveInstance(PlaylistsActivity.this), false, this.peertubes);
@ -181,16 +172,13 @@ public class PlaylistsActivity extends BaseActivity implements OnPlaylistActionI
});
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
max_id = null;
firstLoad = true;
flag_loading = true;
swiped = true;
MainActivity.countNewStatus = 0;
new ManagePlaylistsAsyncTask(PlaylistsActivity.this, GET_LIST_VIDEOS, playlist, null, null, PlaylistsActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
swipeRefreshLayout.setOnRefreshListener(() -> {
max_id = null;
firstLoad = true;
flag_loading = true;
swiped = true;
MainActivity.countNewStatus = 0;
new ManagePlaylistsAsyncTask(PlaylistsActivity.this, GET_LIST_VIDEOS, playlist, null, null, PlaylistsActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
});
new ManagePlaylistsAsyncTask(PlaylistsActivity.this, GET_LIST_VIDEOS, playlist, null, null, PlaylistsActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@ -199,19 +187,16 @@ public class PlaylistsActivity extends BaseActivity implements OnPlaylistActionI
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onActionDone(ManagePlaylistsAsyncTask.action actionType, APIResponse apiResponse, int statusCode) {
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);
//Discards 404 - error which can often happen due to toots which have been deleted
@ -236,9 +221,7 @@ public class PlaylistsActivity extends BaseActivity implements OnPlaylistActionI
if (swiped) {
if (previousPosition > 0) {
for (int i = 0; i < previousPosition; i++) {
this.peertubes.remove(0);
}
this.peertubes.subList(0, previousPosition).clear();
peertubeAdapter.notifyItemRangeRemoved(0, previousPosition);
}
swiped = false;

View File

@ -60,13 +60,10 @@ public class ProxyActivity extends BaseActivity {
boolean enable_proxy = sharedpreferences.getBoolean(Helper.SET_PROXY_ENABLED, false);
final CheckBox set_enable_proxy = findViewById(R.id.enable_proxy);
set_enable_proxy.setChecked(enable_proxy);
set_enable_proxy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean(Helper.SET_PROXY_ENABLED, set_enable_proxy.isChecked());
editor.apply();
}
set_enable_proxy.setOnClickListener(v -> {
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean(Helper.SET_PROXY_ENABLED, set_enable_proxy.isChecked());
editor.apply();
});
Button save = findViewById(R.id.set_proxy_save);
@ -112,34 +109,29 @@ public class ProxyActivity extends BaseActivity {
}
});
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String hostVal = host.getText().toString().trim();
String portVal = port.getText().toString().trim();
String proxy_loginVal = proxy_login.getText().toString().trim();
String proxy_passwordVal = proxy_password.getText().toString().trim();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.SET_PROXY_HOST, hostVal);
if (portVal.matches("\\d+"))
editor.putInt(Helper.SET_PROXY_PORT, Integer.parseInt(portVal));
editor.putString(Helper.SET_PROXY_LOGIN, proxy_loginVal);
editor.putString(Helper.SET_PROXY_PASSWORD, proxy_passwordVal);
editor.apply();
finish();
}
save.setOnClickListener(view -> {
String hostVal1 = host.getText().toString().trim();
String portVal1 = port.getText().toString().trim();
String proxy_loginVal = proxy_login.getText().toString().trim();
String proxy_passwordVal = proxy_password.getText().toString().trim();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.SET_PROXY_HOST, hostVal1);
if (portVal1.matches("\\d+"))
editor.putInt(Helper.SET_PROXY_PORT, Integer.parseInt(portVal1));
editor.putString(Helper.SET_PROXY_LOGIN, proxy_loginVal);
editor.putString(Helper.SET_PROXY_PASSWORD, proxy_passwordVal);
editor.apply();
finish();
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}

View File

@ -15,7 +15,6 @@
package app.fedilab.android.activities;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
@ -33,7 +32,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.ImageView;
@ -138,212 +136,174 @@ public class ReorderTimelinesActivity extends BaseActivity implements OnStartDra
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
TextView toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
ImageView add_remote_instance = actionBar.getCustomView().findViewById(R.id.add_remote_instance);
toolbar_close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
toolbar_close.setOnClickListener(v -> finish());
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) {
add_remote_instance.setVisibility(View.VISIBLE);
} else {
add_remote_instance.setVisibility(View.GONE);
}
add_remote_instance.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(ReorderTimelinesActivity.this, style);
LayoutInflater inflater = getLayoutInflater();
@SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.search_instance, null);
dialogBuilder.setView(dialogView);
add_remote_instance.setOnClickListener(v -> {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(ReorderTimelinesActivity.this, style);
LayoutInflater inflater1 = getLayoutInflater();
@SuppressLint("InflateParams") View dialogView = inflater1.inflate(R.layout.search_instance, null);
dialogBuilder.setView(dialogView);
AutoCompleteTextView instance_list = dialogView.findViewById(R.id.search_instance);
//Manage download of attachments
RadioGroup radioGroup = dialogView.findViewById(R.id.set_attachment_group);
radioGroup.setOnCheckedChangeListener((group, checkedId) -> {
if (checkedId == R.id.twitter_accounts) {
instance_list.setHint(R.string.list_of_twitter_accounts);
} else {
instance_list.setHint(R.string.instance);
}
});
instance_list.setFilters(new InputFilter[]{new InputFilter.LengthFilter(60)});
dialogBuilder.setPositiveButton(R.string.validate, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
String instanceName = instance_list.getText().toString().trim().replace("@", "");
new Thread(new Runnable() {
@Override
public void run() {
try {
if (radioGroup.getCheckedRadioButtonId() == R.id.mastodon_instance)
new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://" + instanceName + "/api/v1/timelines/public?local=true", 10, null, null);
else if (radioGroup.getCheckedRadioButtonId() == R.id.peertube_instance)
new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://" + instanceName + "/api/v1/videos/", 10, null, null);
else if (radioGroup.getCheckedRadioButtonId() == R.id.pixelfed_instance) {
new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://" + instanceName + "/api/v1/timelines/public", 10, null, null);
} else if (radioGroup.getCheckedRadioButtonId() == R.id.misskey_instance) {
new HttpsConnection(ReorderTimelinesActivity.this, null).post("https://" + instanceName + "/api/notes/local-timeline", 10, null, null);
} else if (radioGroup.getCheckedRadioButtonId() == R.id.gnu_instance) {
new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://" + instanceName + "/api/statuses/public_timeline.json", 10, null, null);
}
runOnUiThread(new Runnable() {
public void run() {
dialog.dismiss();
if (radioGroup.getCheckedRadioButtonId() == R.id.mastodon_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "MASTODON");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.peertube_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "PEERTUBE");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.pixelfed_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "PIXELFED");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.misskey_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "MISSKEY");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.gnu_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "GNU");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.twitter_accounts) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "NITTER");
}
if (timelines != null && adapter != null) {
List<RemoteInstance> instance = new InstancesDAO(ReorderTimelinesActivity.this, db).getInstanceByName(instanceName);
if (instance != null && instance.size() > 0) {
ManageTimelines manageTimelines = new ManageTimelines();
manageTimelines.setRemoteInstance(instance.get(0));
manageTimelines.setPosition(timelines.size());
manageTimelines.setDisplayed(true);
manageTimelines.setType(ManageTimelines.Type.INSTANCE);
timelines.add(manageTimelines);
adapter.notifyItemInserted((timelines.size() - 1));
}
updated = true;
}
}
});
} catch (final Exception e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
Toasty.warning(ReorderTimelinesActivity.this, getString(R.string.toast_instance_unavailable), Toast.LENGTH_LONG).show();
}
});
AutoCompleteTextView instance_list = dialogView.findViewById(R.id.search_instance);
//Manage download of attachments
RadioGroup radioGroup = dialogView.findViewById(R.id.set_attachment_group);
radioGroup.setOnCheckedChangeListener((group, checkedId) -> {
if (checkedId == R.id.twitter_accounts) {
instance_list.setHint(R.string.list_of_twitter_accounts);
} else {
instance_list.setHint(R.string.instance);
}
});
instance_list.setFilters(new InputFilter[]{new InputFilter.LengthFilter(60)});
dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
String instanceName = instance_list.getText().toString().trim().replace("@", "");
new Thread(() -> {
try {
if (radioGroup.getCheckedRadioButtonId() == R.id.mastodon_instance)
new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://" + instanceName + "/api/v1/timelines/public?local=true", 10, null, null);
else if (radioGroup.getCheckedRadioButtonId() == R.id.peertube_instance)
new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://" + instanceName + "/api/v1/videos/", 10, null, null);
else if (radioGroup.getCheckedRadioButtonId() == R.id.pixelfed_instance) {
new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://" + instanceName + "/api/v1/timelines/public", 10, null, null);
} else if (radioGroup.getCheckedRadioButtonId() == R.id.misskey_instance) {
new HttpsConnection(ReorderTimelinesActivity.this, null).post("https://" + instanceName + "/api/notes/local-timeline", 10, null, null);
} else if (radioGroup.getCheckedRadioButtonId() == R.id.gnu_instance) {
new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://" + instanceName + "/api/statuses/public_timeline.json", 10, null, null);
}
runOnUiThread(() -> {
dialog.dismiss();
if (radioGroup.getCheckedRadioButtonId() == R.id.mastodon_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "MASTODON");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.peertube_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "PEERTUBE");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.pixelfed_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "PIXELFED");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.misskey_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "MISSKEY");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.gnu_instance) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "GNU");
} else if (radioGroup.getCheckedRadioButtonId() == R.id.twitter_accounts) {
new InstancesDAO(ReorderTimelinesActivity.this, db).insertInstance(instanceName, "NITTER");
}
if (timelines != null && adapter != null) {
List<RemoteInstance> instance = new InstancesDAO(ReorderTimelinesActivity.this, db).getInstanceByName(instanceName);
if (instance != null && instance.size() > 0) {
ManageTimelines manageTimelines = new ManageTimelines();
manageTimelines.setRemoteInstance(instance.get(0));
manageTimelines.setPosition(timelines.size());
manageTimelines.setDisplayed(true);
manageTimelines.setType(ManageTimelines.Type.INSTANCE);
timelines.add(manageTimelines);
adapter.notifyItemInserted((timelines.size() - 1));
}
updated = true;
}
}).start();
});
} catch (final Exception e) {
e.printStackTrace();
runOnUiThread(() -> Toasty.warning(ReorderTimelinesActivity.this, getString(R.string.toast_instance_unavailable), Toast.LENGTH_LONG).show());
}
});
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
//Hide keyboard
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(instance_list.getWindowToken(), 0);
}
});
if (alertDialog.getWindow() != null)
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
alertDialog.show();
}).start();
});
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.setOnDismissListener(dialogInterface -> {
//Hide keyboard
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(instance_list.getWindowToken(), 0);
});
if (alertDialog.getWindow() != null)
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
alertDialog.show();
instance_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String oldSearch = parent.getItemAtPosition(position).toString().trim();
}
});
instance_list.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
instance_list.setOnItemClickListener((parent, view1, position, id) -> {
});
instance_list.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}
@Override
public void afterTextChanged(Editable s) {
if (radioGroup.getCheckedRadioButtonId() != R.id.twitter_accounts) {
Pattern host = Pattern.compile("([\\da-z\\.-]+\\.[a-z\\.]{2,12})");
Matcher matcher = host.matcher(s.toString().trim());
if (s.toString().trim().length() == 0 || !matcher.find()) {
alertDialog.getButton(
AlertDialog.BUTTON_POSITIVE).setEnabled(false);
} else {
// Something into edit text. Enable the button.
alertDialog.getButton(
AlertDialog.BUTTON_POSITIVE).setEnabled(true);
}
if (s.length() > 2 && !isLoadingInstance) {
final String action = "/instances/search";
final HashMap<String, String> parameters = new HashMap<>();
parameters.put("q", s.toString().trim());
parameters.put("count", String.valueOf(1000));
parameters.put("name", String.valueOf(true));
isLoadingInstance = true;
if (oldSearch == null || !oldSearch.equals(s.toString().trim()))
new Thread(new Runnable() {
@Override
public void run() {
try {
final String response = new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://instances.social/api/1.0" + action, 30, parameters, Helper.THEKINRAR_SECRET_TOKEN);
runOnUiThread(new Runnable() {
public void run() {
isLoadingInstance = false;
String[] instances;
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("instances");
if (jsonArray != null) {
int length = 0;
for (int i = 0; i < jsonArray.length(); i++) {
if (!jsonArray.getJSONObject(i).get("name").toString().contains("@") && jsonArray.getJSONObject(i).get("up").toString().equals("true"))
length++;
}
instances = new String[length];
int j = 0;
for (int i = 0; i < jsonArray.length(); i++) {
if (!jsonArray.getJSONObject(i).get("name").toString().contains("@") && jsonArray.getJSONObject(i).get("up").toString().equals("true")) {
instances[j] = jsonArray.getJSONObject(i).get("name").toString();
j++;
}
}
} else {
instances = new String[]{};
}
instance_list.setAdapter(null);
ArrayAdapter<String> adapter =
new ArrayAdapter<>(ReorderTimelinesActivity.this, android.R.layout.simple_list_item_1, instances);
instance_list.setAdapter(adapter);
if (instance_list.hasFocus() && !ReorderTimelinesActivity.this.isFinishing())
instance_list.showDropDown();
oldSearch = s.toString().trim();
} catch (JSONException ignored) {
isLoadingInstance = false;
}
}
});
} catch (HttpsConnection.HttpsConnectionException e) {
isLoadingInstance = false;
} catch (Exception e) {
isLoadingInstance = false;
}
}
}).start();
else
isLoadingInstance = false;
}
@Override
public void afterTextChanged(Editable s) {
if (radioGroup.getCheckedRadioButtonId() != R.id.twitter_accounts) {
Pattern host = Pattern.compile("([\\da-z.-]+\\.[a-z.]{2,12})");
Matcher matcher = host.matcher(s.toString().trim());
if (s.toString().trim().length() == 0 || !matcher.find()) {
alertDialog.getButton(
AlertDialog.BUTTON_POSITIVE).setEnabled(false);
} else {
// Something into edit text. Enable the button.
alertDialog.getButton(
AlertDialog.BUTTON_POSITIVE).setEnabled(true);
}
if (s.length() > 2 && !isLoadingInstance) {
final String action = "/instances/search";
final HashMap<String, String> parameters = new HashMap<>();
parameters.put("q", s.toString().trim());
parameters.put("count", String.valueOf(1000));
parameters.put("name", String.valueOf(true));
isLoadingInstance = true;
if (oldSearch == null || !oldSearch.equals(s.toString().trim()))
new Thread(() -> {
try {
final String response = new HttpsConnection(ReorderTimelinesActivity.this, null).get("https://instances.social/api/1.0" + action, 30, parameters, Helper.THEKINRAR_SECRET_TOKEN);
runOnUiThread(() -> {
isLoadingInstance = false;
String[] instances;
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("instances");
int length = 0;
for (int i = 0; i < jsonArray.length(); i++) {
if (!jsonArray.getJSONObject(i).get("name").toString().contains("@") && jsonArray.getJSONObject(i).get("up").toString().equals("true"))
length++;
}
instances = new String[length];
int j = 0;
for (int i = 0; i < jsonArray.length(); i++) {
if (!jsonArray.getJSONObject(i).get("name").toString().contains("@") && jsonArray.getJSONObject(i).get("up").toString().equals("true")) {
instances[j] = jsonArray.getJSONObject(i).get("name").toString();
j++;
}
}
instance_list.setAdapter(null);
ArrayAdapter<String> adapter =
new ArrayAdapter<>(ReorderTimelinesActivity.this, android.R.layout.simple_list_item_1, instances);
instance_list.setAdapter(adapter);
if (instance_list.hasFocus() && !ReorderTimelinesActivity.this.isFinishing())
instance_list.showDropDown();
oldSearch = s.toString().trim();
} catch (JSONException ignored) {
isLoadingInstance = false;
}
});
} catch (Exception e) {
isLoadingInstance = false;
}
}).start();
else
isLoadingInstance = false;
}
} else {
alertDialog.getButton(
AlertDialog.BUTTON_POSITIVE).setEnabled(true);
}
});
}
}
});
});
toolbar_title.setText(R.string.action_reorder_timeline);
}
@ -390,40 +350,34 @@ public class ReorderTimelinesActivity extends BaseActivity implements OnStartDra
break;
}
undo_action.setPaintFlags(undo_action.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
Runnable runnable = new Runnable() {
@Override
public void run() {
undo_container.setVisibility(View.GONE);
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
switch (manageTimelines.getType()) {
case TAG:
new SearchDAO(ReorderTimelinesActivity.this, db).remove(manageTimelines.getTagTimeline().getName());
new TimelinesDAO(ReorderTimelinesActivity.this, db).remove(manageTimelines);
break;
case INSTANCE:
new InstancesDAO(ReorderTimelinesActivity.this, db).remove(manageTimelines.getRemoteInstance().getHost());
new TimelinesDAO(ReorderTimelinesActivity.this, db).remove(manageTimelines);
break;
case LIST:
timeline = manageTimelines;
new ManageListsAsyncTask(ReorderTimelinesActivity.this, ManageListsAsyncTask.action.DELETE_LIST, null, null, manageTimelines.getListTimeline().getId(), null, ReorderTimelinesActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new TimelinesDAO(ReorderTimelinesActivity.this, db).remove(timeline);
refresh_list = true;
break;
}
updated = true;
Runnable runnable = () -> {
undo_container.setVisibility(View.GONE);
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
switch (manageTimelines.getType()) {
case TAG:
new SearchDAO(ReorderTimelinesActivity.this, db).remove(manageTimelines.getTagTimeline().getName());
new TimelinesDAO(ReorderTimelinesActivity.this, db).remove(manageTimelines);
break;
case INSTANCE:
new InstancesDAO(ReorderTimelinesActivity.this, db).remove(manageTimelines.getRemoteInstance().getHost());
new TimelinesDAO(ReorderTimelinesActivity.this, db).remove(manageTimelines);
break;
case LIST:
timeline = manageTimelines;
new ManageListsAsyncTask(ReorderTimelinesActivity.this, ManageListsAsyncTask.action.DELETE_LIST, null, null, manageTimelines.getListTimeline().getId(), null, ReorderTimelinesActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new TimelinesDAO(ReorderTimelinesActivity.this, db).remove(timeline);
refresh_list = true;
break;
}
updated = true;
};
Handler handler = new Handler();
handler.postDelayed(runnable, 4000);
undo_action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
timelines.add(position, manageTimelines);
adapter.notifyItemInserted(position);
undo_container.setVisibility(View.GONE);
handler.removeCallbacks(runnable);
}
undo_action.setOnClickListener(v -> {
timelines.add(position, manageTimelines);
adapter.notifyItemInserted(position);
undo_container.setVisibility(View.GONE);
handler.removeCallbacks(runnable);
});
}

View File

@ -48,6 +48,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
@ -545,14 +546,14 @@ public class ShowAccountActivity extends BaseActivity implements OnPostActionInt
if ((MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) && account.getFields() != null && account.getFields().size() > 0) {
LinkedHashMap<String, String> fields = account.getFields();
LinkedHashMap<String, Boolean> fieldsVerified = account.getFieldsVerified();
Iterator it = fields.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = fields.entrySet().iterator();
int i = 1;
LinearLayout fields_container = findViewById(R.id.fields_container);
if (fields_container != null)
fields_container.setVisibility(View.VISIBLE);
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
String label = (String) pair.getKey();
Map.Entry<String, String> pair = it.next();
String label = pair.getKey();
if (label != null && fieldsVerified != null && fieldsVerified.containsKey(label)) {
boolean verified = fieldsVerified.get(label);
@ -618,7 +619,7 @@ public class ShowAccountActivity extends BaseActivity implements OnPostActionInt
SpannableString spannableString = Helper.clickableElementsDescription(ShowAccountActivity.this, account.getNote());
account.setNoteSpan(spannableString);
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA)
account.makeEmojisAccountProfile(ShowAccountActivity.this, ShowAccountActivity.this, account);
account.fillProfileAccount(ShowAccountActivity.this, ShowAccountActivity.this, account);
account_note.setText(account.getNoteSpan(), TextView.BufferType.SPANNABLE);
account_note.setMovementMethod(LinkMovementMethod.getInstance());
if (!peertubeAccount && tabLayout.getTabAt(0) != null && tabLayout.getTabAt(1) != null && tabLayout.getTabAt(2) != null) {
@ -739,7 +740,15 @@ public class ShowAccountActivity extends BaseActivity implements OnPostActionInt
b.putInt("position", 1);
b.putInt("bgcolor", getResources().getColor(R.color.cyanea_primary_dark));
intent.putExtras(b);
startActivity(intent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation(ShowAccountActivity.this, account_pp, attachment.getUrl());
// start the new activity
startActivity(intent, options.toBundle());
} else {
// start the new activity
startActivity(intent);
}
});
//Follow button
String target = account.getId();
@ -962,24 +971,20 @@ public class ShowAccountActivity extends BaseActivity implements OnPostActionInt
LinkedHashMap<String, Boolean> fieldsVerified = account.getFieldsVerified();
if (account.getFieldsSpan() != null && account.getFieldsSpan().size() > 0) {
HashMap<SpannableString, SpannableString> fieldsSpan = account.getFieldsSpan();
Iterator it = fieldsSpan.entrySet().iterator();
Iterator<Map.Entry<SpannableString, SpannableString>> it = fieldsSpan.entrySet().iterator();
int i = 1;
LinearLayout fields_container = findViewById(R.id.fields_container);
if (fields_container != null)
fields_container.setVisibility(View.VISIBLE);
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
SpannableString label = (SpannableString) pair.getKey();
SpannableString value = (SpannableString) pair.getValue();
Map.Entry<SpannableString, SpannableString> pair = it.next();
SpannableString label = pair.getKey();
SpannableString value = pair.getValue();
LinearLayout field;
TextView labelView;
TextView valueView;
switch (i) {
case 1:
field = findViewById(R.id.field1);
labelView = findViewById(R.id.label1);
valueView = findViewById(R.id.value1);
break;
case 2:
field = findViewById(R.id.field2);
labelView = findViewById(R.id.label2);
@ -1166,7 +1171,7 @@ public class ShowAccountActivity extends BaseActivity implements OnPostActionInt
tags = new ArrayList<>(featuredTagsSet);
}
tags.add(0, getString(R.string.no_tags));
String[] tagsString = tags.toArray(new String[tags.size()]);
String[] tagsString = tags.toArray(new String[0]);
List<String> finalTags = tags;
String tag = sharedpreferences.getString(Helper.SET_FEATURED_TAG_ACTION, null);
int checkedposition = 0;

View File

@ -111,10 +111,6 @@ public class ShowConversationActivity extends BaseActivity implements OnRetrieve
detailsStatus.setFocused(true);
//Some spannable
Status.fillSpan(new WeakReference<>(ShowConversationActivity.this), detailsStatus);
if (detailsStatus.getPoll() != null) {
Status.makeEmojiPoll(new WeakReference<>(ShowConversationActivity.this), detailsStatus.getPoll());
}
Account.makeAccountNameEmoji(new WeakReference<>(ShowConversationActivity.this), detailsStatus.getAccount());
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) {

View File

@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
@ -35,10 +36,12 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
@ -92,13 +95,13 @@ public class SlideMediaActivity extends BaseFragmentActivity implements OnDownlo
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
ContentResolver cR = context.getContentResolver();
if( cR != null && uri != null) {
if (cR != null && uri != null) {
shareIntent.setType(cR.getType(uri));
try {
startActivity(shareIntent);
} catch (Exception ignored) {
}
}else {
} else {
Toasty.error(context, context.getString(R.string.toast_error), Toasty.LENGTH_LONG).show();
}
} else {
@ -123,8 +126,14 @@ public class SlideMediaActivity extends BaseFragmentActivity implements OnDownlo
default:
setTheme(R.style.TransparentDark);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ActivityCompat.postponeEnterTransition(SlideMediaActivity.this);
}
getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.activity_media_pager);
fullscreen = false;
media_description = findViewById(R.id.media_description);
final int med_desc_timeout = sharedpreferences.getInt(Helper.SET_MED_DESC_TIMEOUT, 3) * 1000;
@ -136,39 +145,37 @@ public class SlideMediaActivity extends BaseFragmentActivity implements OnDownlo
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setBackgroundDrawable(new ColorDrawable(bgColor));
actionBar.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
actionBar.setElevation(0);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
assert inflater != null;
View view = inflater.inflate(R.layout.media_action_bar, new LinearLayout(SlideMediaActivity.this), false);
view.setBackgroundColor(bgColor);
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
TextView toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
ImageView media_save = actionBar.getCustomView().findViewById(R.id.media_save);
ImageView media_share = actionBar.getCustomView().findViewById(R.id.media_share);
toolbar_close.setOnClickListener(v -> finish());
toolbar_close.setOnClickListener(v -> ActivityCompat.finishAfterTransition(this));
media_save.setOnClickListener(view12 -> {
int position = mPager.getCurrentItem();
Attachment attachment = attachments.get(position);
if (attachment.getType().compareTo("image") == 0) {
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(SlideMediaActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(SlideMediaActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(SlideMediaActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE);
} else {
Helper.manageMove(SlideMediaActivity.this, attachment.getUrl(), false);
}
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(SlideMediaActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(SlideMediaActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(SlideMediaActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE_MEDIA_SAVE);
} else {
Helper.manageMove(SlideMediaActivity.this, attachment.getUrl(), false);
}
} else {
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(SlideMediaActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(SlideMediaActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(SlideMediaActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE);
if (attachment.getType().compareTo("image") == 0) {
Helper.manageMove(SlideMediaActivity.this, attachment.getUrl(), false);
} else {
Helper.manageDownloadsNoPopup(SlideMediaActivity.this, attachment.getUrl());
downloadID = -1;
}
}
} else {
if (attachment.getType().compareTo("image") == 0) {
Helper.manageMove(SlideMediaActivity.this, attachment.getUrl(), false);
} else {
Helper.manageDownloadsNoPopup(SlideMediaActivity.this, attachment.getUrl());
downloadID = -1;
@ -186,7 +193,7 @@ public class SlideMediaActivity extends BaseFragmentActivity implements OnDownlo
} else {
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(SlideMediaActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(SlideMediaActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(SlideMediaActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE);
ActivityCompat.requestPermissions(SlideMediaActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE_MEDIA_SHARE);
} else {
downloadID = Helper.manageDownloadsNoPopup(SlideMediaActivity.this, attachment.getUrl());
}
@ -208,6 +215,7 @@ public class SlideMediaActivity extends BaseFragmentActivity implements OnDownlo
mPager.setAdapter(mPagerAdapter);
mPager.setCurrentItem(mediaPosition - 1);
mPager.setOffscreenPageLimit(0);
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
String description = attachments.get(mediaPosition - 1).getDescription();
@ -216,10 +224,16 @@ public class SlideMediaActivity extends BaseFragmentActivity implements OnDownlo
media_description.setText(description);
media_description.setVisibility(View.VISIBLE);
handler.postDelayed(() -> media_description.setVisibility(View.GONE), med_desc_timeout);
handler.postDelayed(() -> {
if (!media_description.hasSelection()) {
media_description.setVisibility(View.GONE);
}
}, med_desc_timeout);
} else {
media_description.setVisibility(View.GONE);
if (!media_description.hasSelection()) {
media_description.setVisibility(View.GONE);
}
}
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {
@ -238,10 +252,16 @@ public class SlideMediaActivity extends BaseFragmentActivity implements OnDownlo
media_description.setText(description);
media_description.setVisibility(View.VISIBLE);
handler.postDelayed(() -> media_description.setVisibility(View.GONE), med_desc_timeout);
handler.postDelayed(() -> {
if (!media_description.hasSelection()) {
media_description.setVisibility(View.GONE);
}
}, med_desc_timeout);
} else {
media_description.setVisibility(View.GONE);
if (!media_description.hasSelection()) {
media_description.setVisibility(View.GONE);
}
}
}
});
@ -257,12 +277,36 @@ public class SlideMediaActivity extends BaseFragmentActivity implements OnDownlo
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case Helper.EXTERNAL_STORAGE_REQUEST_CODE_MEDIA_SAVE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
int position = mPager.getCurrentItem();
Attachment attachment = attachments.get(position);
if (attachment.getType().compareTo("image") == 0) {
Helper.manageMove(SlideMediaActivity.this, attachment.getUrl(), false);
} else {
Helper.manageDownloadsNoPopup(SlideMediaActivity.this, attachment.getUrl());
downloadID = -1;
}
} else { /*Todo: Toast "Storage Permission Required" */ }
return;
case Helper.EXTERNAL_STORAGE_REQUEST_CODE_MEDIA_SHARE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
int position = mPager.getCurrentItem();
Attachment attachment = attachments.get(position);
downloadID = Helper.manageDownloadsNoPopup(SlideMediaActivity.this, attachment.getUrl());
} else { /*Todo: Toast "Storage Permission Required" */ }
break;
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
final int med_desc_timeout = sharedpreferences.getInt(Helper.SET_MED_DESC_TIMEOUT, 3) * 1000;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
@ -283,10 +327,16 @@ public class SlideMediaActivity extends BaseFragmentActivity implements OnDownlo
media_description.setText(description);
media_description.setVisibility(View.VISIBLE);
handler.postDelayed(() -> media_description.setVisibility(View.GONE), med_desc_timeout);
handler.postDelayed(() -> {
if (!media_description.hasSelection()) {
media_description.setVisibility(View.GONE);
}
}, med_desc_timeout);
} else {
media_description.setVisibility(View.GONE);
if (!media_description.hasSelection()) {
media_description.setVisibility(View.GONE);
}
}
}
}

View File

@ -19,7 +19,6 @@ import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
@ -70,40 +69,34 @@ public class TagCacheActivity extends BaseActivity {
EditText tag_add = findViewById(R.id.tag_add);
ImageButton save_tag = findViewById(R.id.save_tag);
save_tag.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (tag_add.getText() != null && tag_add.getText().toString().trim().replaceAll("\\#", "").length() > 0) {
String tagToInsert = tag_add.getText().toString().trim().replaceAll("\\#", "");
boolean isPresent = new TagsCacheDAO(TagCacheActivity.this, db).isPresent(tagToInsert);
if (isPresent)
Toasty.warning(TagCacheActivity.this, getString(R.string.tags_already_stored), Toast.LENGTH_LONG).show();
else {
new TagsCacheDAO(TagCacheActivity.this, db).insert(tagToInsert);
int position = tags.size();
tags.add(tagToInsert);
Toasty.success(TagCacheActivity.this, getString(R.string.tags_stored), Toast.LENGTH_LONG).show();
tag_add.setText("");
tagsEditAdapter.notifyItemInserted(position);
}
save_tag.setOnClickListener(v -> {
if (tag_add.getText() != null && tag_add.getText().toString().trim().replaceAll("#", "").length() > 0) {
String tagToInsert = tag_add.getText().toString().trim().replaceAll("#", "");
boolean isPresent = new TagsCacheDAO(TagCacheActivity.this, db).isPresent(tagToInsert);
if (isPresent)
Toasty.warning(TagCacheActivity.this, getString(R.string.tags_already_stored), Toast.LENGTH_LONG).show();
else {
new TagsCacheDAO(TagCacheActivity.this, db).insert(tagToInsert);
int position = tags.size();
tags.add(tagToInsert);
Toasty.success(TagCacheActivity.this, getString(R.string.tags_stored), Toast.LENGTH_LONG).show();
tag_add.setText("");
tagsEditAdapter.notifyItemInserted(position);
}
}
});
setTitle(R.string.manage_tags);
AsyncTask.execute(new Runnable() {
@Override
public void run() {
AsyncTask.execute(() -> {
List<String> tagsTemp = new TagsCacheDAO(TagCacheActivity.this, db).getAll();
if (tagsTemp != null)
tags = tagsTemp;
if (tags != null) {
tagsEditAdapter = new TagsEditAdapter(tags);
tag_list.setAdapter(tagsEditAdapter);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(TagCacheActivity.this);
tag_list.setLayoutManager(mLayoutManager);
}
List<String> tagsTemp = new TagsCacheDAO(TagCacheActivity.this, db).getAll();
if (tagsTemp != null)
tags = tagsTemp;
if (tags != null) {
tagsEditAdapter = new TagsEditAdapter(tags);
tag_list.setAdapter(tagsEditAdapter);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(TagCacheActivity.this);
tag_list.setLayoutManager(mLayoutManager);
}
});

View File

@ -134,7 +134,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.TimeZone;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
@ -330,7 +330,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
final String[] newContent = {null};
final int[] searchLength = {searchDeep};
TextWatcher textw = null;
TextWatcher finalTextw = textw;
textw = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@ -348,7 +348,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
status.setQuickReplyContent(s.toString());
}
if (autocomplete) {
toot_content.removeTextChangedListener(finalTextw);
toot_content.removeTextChangedListener(this);
Thread thread = new Thread() {
@Override
public void run() {
@ -436,11 +436,8 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
if (s.toString().length() == 0)
currentCursorPosition[0] = 0;
//Only check last 15 characters before cursor position to avoid lags
if (currentCursorPosition[0] < searchDeep) { //Less than 15 characters are written before the cursor position
searchLength[0] = currentCursorPosition[0];
} else {
searchLength[0] = searchDeep;
}
//Less than 15 characters are written before the cursor position
searchLength[0] = Math.min(currentCursorPosition[0], searchDeep);
int totalChar = countLength(social, toot_content, toot_cw_content);
@ -894,12 +891,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
if (s.toString().length() == 0)
currentCursorPosition = 0;
//Only check last 15 characters before cursor position to avoid lags
int searchLength;
if (currentCursorPosition < searchDeep) { //Less than 15 characters are written before the cursor position
searchLength = currentCursorPosition;
} else {
searchLength = searchDeep;
}
int searchLength = Math.min(currentCursorPosition, searchDeep);
int totalChar = countLength(wysiwyg, toot_cw_content);
toot_space_left.setText(String.valueOf(totalChar));
if (currentCursorPosition - (searchLength - 1) < 0 || currentCursorPosition == 0 || currentCursorPosition > s.toString().length())
@ -1018,6 +1010,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
if (tootReply.getAccount() != null && tootReply.getAccount().getMoved_to_account() != null) {
warning_message.setVisibility(View.VISIBLE);
}
assert tootReply.getAccount() != null;
new RetrieveRelationshipAsyncTask(TootActivity.this, tootReply.getAccount().getId(), TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
if (scheduledstatus != null)
@ -1329,15 +1322,18 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
final ImageView imageView = new ImageView(TootActivity.this);
imageView.setId(Integer.parseInt(attachment.getId()));
Random rand = new Random();
int n = rand.nextInt(10000000);
imageView.setId(n);
attachment.setViewId(n);
if (social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) {
if (successfullyUploadedFiles != null && successfullyUploadedFiles.size() > 0) {
Iterator it = filesMap.entrySet().iterator();
Iterator<Map.Entry<String, Uri>> it = filesMap.entrySet().iterator();
Uri fileName = null;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
fileName = (Uri) pair.getValue();
Map.Entry<String, Uri> pair = it.next();
fileName = pair.getValue();
it.remove();
}
if (fileName != null) {
@ -1373,11 +1369,11 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
imageView.setImageBitmap(resource);
if (displayWYSIWYG()) {
url_for_media = finalUrl;
Iterator it = filesMap.entrySet().iterator();
Iterator<Map.Entry<String, Uri>> it = filesMap.entrySet().iterator();
String fileName = null;
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
fileName = (String) pair.getKey();
Map.Entry<String, Uri> pair = it.next();
fileName = pair.getKey();
it.remove();
}
if (fileName != null && fileName.contains("fedilabins_")) {
@ -2080,9 +2076,8 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
dialog.dismiss();
});
builderSingle1.setPositiveButton(R.string.server_schedule, (dialog, which) -> {
int offset = TimeZone.getDefault().getRawOffset();
calendar.add(Calendar.MILLISECOND, -offset);
final String date = Helper.dateToString(new Date(calendar.getTimeInMillis()));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
String date = sdf.format(calendar.getTime());
serverSchedule(date);
});
builderSingle1.show();
@ -2367,7 +2362,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
//Text for report
final EditText input = popup_media_description.findViewById(R.id.media_description);
input.setFilters(new InputFilter[]{new InputFilter.LengthFilter(420)});
input.setFilters(new InputFilter[]{new InputFilter.LengthFilter(1500)});
final ImageView media_picture = popup_media_description.findViewById(R.id.media_picture);
Glide.with(TootActivity.this)
.asBitmap()
@ -2418,7 +2413,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
dialog.setPositiveButton(R.string.yes, (dialog12, which) -> {
View namebar = findViewById(viewId);
for (Attachment attachment : attachments) {
if (Integer.parseInt(attachment.getId()) == viewId) {
if (attachment.getViewId() == viewId) {
attachments.remove(attachment);
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
boolean show_media_urls = sharedpreferences.getBoolean(Helper.SET_MEDIA_URLS, false);
@ -3176,10 +3171,12 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
toRemove.clear();
}
String content = status.getContent();
Pattern mentionLink = Pattern.compile("(<\\s?a\\s?href=\"https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[/\\w._-]*)\"\\s?[^.]*<\\s?/\\s?a\\s?>)");
Matcher matcher = mentionLink.matcher(content);
if (matcher.find()) {
content = matcher.replaceAll("$3@$2");
if (content != null) {
Pattern mentionLink = Pattern.compile("(<\\s?a\\s?href=\"https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[/\\w._-]*)\"\\s?[^.]*<\\s?/\\s?a\\s?>)");
Matcher matcher = mentionLink.matcher(content);
if (matcher.find()) {
content = matcher.replaceAll("$3@$2");
}
}
if (removed) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
@ -3220,9 +3217,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
}
});
imageView.setTag(attachment.getId());
imageView.setOnClickListener(view -> {
imageView.setOnClickListener(view1 -> showAddDescription(attachment));
});
imageView.setOnClickListener(view -> imageView.setOnClickListener(view1 -> showAddDescription(attachment)));
imageView.setOnLongClickListener(view -> {
showRemove(imageView.getId());
return false;
@ -3245,7 +3240,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
toot_cw_content.setText("");
toot_cw_content.setVisibility(View.GONE);
}
if( status.getVisibility() == null) {
if (status.getVisibility() == null) {
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
String defaultVisibility = account.isLocked() ? "private" : "public";
String settingsVisibility = sharedpreferences.getString(Helper.SET_TOOT_VISIBILITY + "@" + account.getAcct() + "@" + account.getInstance(), defaultVisibility);
@ -3352,12 +3347,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate,
ownerTootVisibility = 1;
break;
}
int tootVisibility;
if (ownerTootVisibility >= initialTootVisibility) {
tootVisibility = initialTootVisibility;
} else {
tootVisibility = ownerTootVisibility;
}
int tootVisibility = Math.min(ownerTootVisibility, initialTootVisibility);
switch (tootVisibility) {
case 4:
visibility = "public";

View File

@ -126,9 +126,7 @@ public class WebviewConnectActivity extends BaseActivity {
clearCookies(WebviewConnectActivity.this);
webView.getSettings().setJavaScriptEnabled(true);
String user_agent = sharedpreferences.getString(Helper.SET_CUSTOM_USER_AGENT, Helper.USER_AGENT);
if (user_agent != null) {
webView.getSettings().setUserAgentString(user_agent);
}
webView.getSettings().setUserAgentString(user_agent);
if (android.os.Build.VERSION.SDK_INT >= 21) {
CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
} else {

View File

@ -79,9 +79,6 @@ public class WhoToFollowActivity extends BaseActivity implements OnRetrieveWhoTo
case Helper.THEME_LIGHT:
setTheme(R.style.AppTheme_NoActionBar_Fedilab);
break;
case Helper.THEME_DARK:
setTheme(R.style.AppThemeDark_NoActionBar);
break;
case Helper.THEME_BLACK:
setTheme(R.style.AppThemeBlack_NoActionBar);
break;
@ -146,51 +143,41 @@ public class WhoToFollowActivity extends BaseActivity implements OnRetrieveWhoTo
}
Button follow_accounts_select = findViewById(R.id.follow_accounts_select);
follow_accounts_select.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (follow_accounts_select.getText().equals(getString(R.string.select_all))) {
follow_accounts_select.setText(R.string.unselect_all);
for (TrunkAccount trunkAccount : trunkAccounts) {
trunkAccount.setChecked(true);
}
whoToFollowAccountsAdapter.notifyDataSetChanged();
} else {
follow_accounts_select.setText(R.string.select_all);
for (TrunkAccount trunkAccount : trunkAccounts) {
trunkAccount.setChecked(false);
}
whoToFollowAccountsAdapter.notifyDataSetChanged();
}
follow_accounts_select.setOnClickListener(v -> {
if (follow_accounts_select.getText().equals(getString(R.string.select_all))) {
follow_accounts_select.setText(R.string.unselect_all);
} else {
follow_accounts_select.setText(R.string.select_all);
}
for (TrunkAccount trunkAccount : trunkAccounts) {
trunkAccount.setChecked(false);
}
whoToFollowAccountsAdapter.notifyDataSetChanged();
});
Button follow_accounts = findViewById(R.id.follow_accounts);
follow_accounts.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
follow_accounts.setEnabled(false);
follow_accounts_select.setEnabled(false);
progess_action.setVisibility(View.VISIBLE);
toFollowdId = new ArrayList<>();
for (TrunkAccount trunkAccount : trunkAccounts) {
if (trunkAccount.isChecked()) {
toFollowdId.add(trunkAccount.getAcct());
}
follow_accounts.setOnClickListener(v -> {
follow_accounts.setEnabled(false);
follow_accounts_select.setEnabled(false);
progess_action.setVisibility(View.VISIBLE);
toFollowdId = new ArrayList<>();
for (TrunkAccount trunkAccount : trunkAccounts) {
if (trunkAccount.isChecked()) {
toFollowdId.add(trunkAccount.getAcct());
}
if (toFollowdId.size() > 0) {
Account account = new Account();
String[] val = toFollowdId.get(0).split("@");
progess_action.setText(getString(R.string.follow_trunk, toFollowdId.get(0)));
if (val.length > 1) {
account.setAcct(val[0]);
account.setInstance(val[1]);
new PostActionAsyncTask(WhoToFollowActivity.this, null, account, API.StatusAction.FOLLOW, WhoToFollowActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
Toasty.error(WhoToFollowActivity.this, getString(R.string.toast_impossible_to_follow), Toast.LENGTH_LONG).show();
follow_accounts.setEnabled(true);
follow_accounts_select.setEnabled(true);
progess_action.setVisibility(View.GONE);
}
}
if (toFollowdId.size() > 0) {
Account account = new Account();
String[] val = toFollowdId.get(0).split("@");
progess_action.setText(getString(R.string.follow_trunk, toFollowdId.get(0)));
if (val.length > 1) {
account.setAcct(val[0]);
account.setInstance(val[1]);
new PostActionAsyncTask(WhoToFollowActivity.this, null, account, API.StatusAction.FOLLOW, WhoToFollowActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
Toasty.error(WhoToFollowActivity.this, getString(R.string.toast_impossible_to_follow), Toast.LENGTH_LONG).show();
follow_accounts.setEnabled(true);
follow_accounts_select.setEnabled(true);
progess_action.setVisibility(View.GONE);
}
}
});
@ -199,13 +186,11 @@ public class WhoToFollowActivity extends BaseActivity implements OnRetrieveWhoTo
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
@ -237,6 +222,7 @@ public class WhoToFollowActivity extends BaseActivity implements OnRetrieveWhoTo
new ManageListsAsyncTask(WhoToFollowActivity.this, ManageListsAsyncTask.action.CREATE_LIST, null, null, null, item, WhoToFollowActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
Account account = new Account();
assert followedId != null;
String[] val = toFollowdId.get(followedId.size()).split("@");
progess_action.setText(getString(R.string.follow_trunk, toFollowdId.get(followedId.size())));
if (val.length > 1) {
@ -253,7 +239,6 @@ public class WhoToFollowActivity extends BaseActivity implements OnRetrieveWhoTo
List<app.fedilab.android.client.Entities.List> lists = apiResponse.getLists();
if (lists != null && lists.size() > 0 && actionType == ManageListsAsyncTask.action.CREATE_LIST) {
String[] accountsId = followedId.toArray(new String[0]);
progess_action.setText(R.string.add_account_list_trunk);
listId = lists.get(0).getId();
listTitle = lists.get(0).getTitle();
@ -264,18 +249,14 @@ public class WhoToFollowActivity extends BaseActivity implements OnRetrieveWhoTo
if (accountListId.size() >= followedId.size() - 1) {
progess_action.setText(R.string.account_added_list_trunk);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(WhoToFollowActivity.this, ListActivity.class);
Bundle b = new Bundle();
b.putString("id", listId);
b.putString("title", listTitle);
intent.putExtras(b);
startActivity(intent);
finish();
}
handler.postDelayed(() -> {
Intent intent = new Intent(WhoToFollowActivity.this, ListActivity.class);
Bundle b = new Bundle();
b.putString("id", listId);
b.putString("title", listTitle);
intent.putExtras(b);
startActivity(intent);
finish();
}, 1000);
} else {

View File

@ -35,9 +35,7 @@ import app.fedilab.android.interfaces.OnRetrieveContextInterface;
public class RetrieveContextAsyncTask extends AsyncTask<Void, Void, Void> {
private String statusId;
private app.fedilab.android.client.Entities.Context statusContext;
private OnRetrieveContextInterface listener;
private Error error;
private WeakReference<Context> contextReference;
private boolean expanded;
private boolean directtimeline;
@ -55,6 +53,8 @@ public class RetrieveContextAsyncTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
apiResponse = new APIResponse();
apiResponse.setTargetedId(this.statusId);
app.fedilab.android.client.Entities.Context statusContext;
Error error;
if (MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.GNU && MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) {
API api = new API(this.contextReference.get());
statusContext = api.getStatusContext(statusId);
@ -63,7 +63,6 @@ public class RetrieveContextAsyncTask extends AsyncTask<Void, Void, Void> {
statusContext = api.getStatusContext(statusContext.getAncestors().get(0).getId());
}
error = api.getError();
apiResponse.setError(error);
} else {
GNUAPI gnuapi = new GNUAPI(this.contextReference.get());
statusContext = gnuapi.getStatusContext(statusId, directtimeline);
@ -72,8 +71,8 @@ public class RetrieveContextAsyncTask extends AsyncTask<Void, Void, Void> {
statusContext = gnuapi.getStatusContext(statusContext.getAncestors().get(0).getId(), directtimeline);
}
error = gnuapi.getError();
apiResponse.setError(error);
}
apiResponse.setError(error);
apiResponse.setContext(statusContext);
return null;
}

View File

@ -25,13 +25,11 @@ import java.util.List;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.client.API;
import app.fedilab.android.client.APIResponse;
import app.fedilab.android.client.Entities.Account;
import app.fedilab.android.client.Entities.ManageTimelines;
import app.fedilab.android.client.Entities.Peertube;
import app.fedilab.android.client.Entities.RemoteInstance;
import app.fedilab.android.client.Entities.Results;
import app.fedilab.android.client.Entities.RetrieveFeedsParam;
import app.fedilab.android.client.Entities.Status;
import app.fedilab.android.client.GNUAPI;
import app.fedilab.android.client.PeertubeAPI;
import app.fedilab.android.helper.FilterToots;
@ -369,13 +367,9 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
db = Sqlite.getInstance(contextReference.get().getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
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, 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());
if( status.getPoll() != null) {
app.fedilab.android.client.Entities.Status.makeEmojiPoll(contextReference, status.getPoll());
}
}
} else {
statuses = new ArrayList<>();
@ -393,6 +387,9 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
db = Sqlite.getInstance(contextReference.get().getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
statuses = new StatusCacheDAO(contextReference.get(), db).getStatusFromID(StatusCacheDAO.ARCHIVE_CACHE, filterToots, max_id);
if (statuses != null && statuses.size() > 0) {
for (app.fedilab.android.client.Entities.Status status : statuses) {
app.fedilab.android.client.Entities.Status.fillSpan(contextReference, status);
}
apiResponse.setStatuses(statuses);
apiResponse.setSince_id(statuses.get(0).getId());
apiResponse.setMax_id(statuses.get(statuses.size() - 1).getId());
@ -423,10 +420,6 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
peertubeAPI = new PeertubeAPI(this.contextReference.get());
apiResponse = peertubeAPI.getLocalTL(max_id);
break;
case PMYVIDEOS:
peertubeAPI = new PeertubeAPI(this.contextReference.get());
apiResponse = peertubeAPI.getLocalTL(max_id);
break;
case PF_HOME:
api = new API(this.contextReference.get());
apiResponse = api.getHomeTimeline(max_id);
@ -510,7 +503,6 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
POVERVIEW,
PTRENDING,
PRECENTLYADDED,
PMYVIDEOS,
PLOCAL,
CHANNEL,
MYVIDEOS,

View File

@ -57,6 +57,11 @@ public class RetrieveNotificationsCacheAsyncTask extends AsyncTask<Void, Void, V
apiResponse = new APIResponse();
apiResponse.setNotifications(notifications);
if (notifications != null && notifications.size() > 0) {
for (Notification notification : notifications) {
if (notification.getStatus() != null) {
app.fedilab.android.client.Entities.Status.fillSpan(contextReference, notification.getStatus());
}
}
apiResponse.setMax_id(notifications.get(notifications.size() - 1).getId());
}
return null;

File diff suppressed because it is too large Load Diff

View File

@ -78,7 +78,6 @@ public class APIResponse {
private Context context = null;
private List<PixelFedStory> pixelFedStories = null;
private List<PixelFedStoryItem> pixelFedStoryItems = null;
private PixelFedStory pixelFedStory = null;
private List<Trends> trends = null;
private List<IdentityProof> identityProofs = null;

View File

@ -47,7 +47,6 @@ 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;
@ -200,63 +199,6 @@ public class Account implements Parcelable {
this.invited_by_account_id = in.readString();
}
public static void makeAccountNameEmoji(final WeakReference<Context> contextWeakReference, Account account) {
Context context = contextWeakReference.get();
if ((context instanceof Activity && ((Activity) context).isFinishing()) || account == null || account.getDisplay_name() == null)
return;
account.setDisplayNameSpan(new SpannableString(account.getDisplay_name()));
SpannableString displayNameSpan = account.getDisplayNameSpan();
if (displayNameSpan == null)
return;
final List<Emojis> emojis = account.getEmojis();
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean disableAnimatedEmoji = sharedpreferences.getBoolean(Helper.SET_DISABLE_ANIMATED_EMOJI, false);
if (emojis != null && emojis.size() > 0) {
final int[] i = {0};
for (final Emojis emoji : emojis) {
try {
Glide.with(context)
.asDrawable()
.load(disableAnimatedEmoji ? emoji.getStatic_url() : emoji.getUrl())
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (displayNameSpan.toString().contains(targetedEmoji)) {
//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 (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;
}
}
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@Override
public int describeContents() {
@ -534,6 +476,9 @@ public class Account implements Parcelable {
}
public SpannableString getDisplayNameSpan() {
if (this.displayNameSpan == null) {
displayNameSpan = new SpannableString(display_name);
}
return displayNameSpan;
}
@ -745,15 +690,14 @@ public class Account implements Parcelable {
return spannableString;
}
public void makeEmojisAccountProfile(final Context context, final OnRetrieveEmojiAccountInterface listener, Account account) {
public void fillProfileAccount(final Context context, final OnRetrieveEmojiAccountInterface listener, Account account) {
if (context instanceof Activity && ((Activity) context).isFinishing())
return;
if (fields == null)
fields = new LinkedHashMap<>();
if (fieldsSpan == null)
fieldsSpan = new LinkedHashMap<>();
if (account.getDisplay_name() != null)
displayNameSpan = new SpannableString(account.getDisplay_name());
displayNameSpan = account.getDisplayNameSpan();
ArrayList<Account> accountsMentionUnknown = new ArrayList<>();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

View File

@ -37,6 +37,7 @@ public class Attachment implements Parcelable {
}
};
private String id;
private int viewId;
private String type;
private String url;
private String remote_url;
@ -50,8 +51,17 @@ public class Attachment implements Parcelable {
}
public int getViewId() {
return viewId;
}
public void setViewId(int viewId) {
this.viewId = viewId;
}
protected Attachment(Parcel in) {
this.id = in.readString();
this.viewId = in.readInt();
this.type = in.readString();
this.url = in.readString();
this.remote_url = in.readString();
@ -142,6 +152,7 @@ public class Attachment implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.id);
dest.writeInt(this.viewId);
dest.writeString(this.type);
dest.writeString(this.url);
dest.writeString(this.remote_url);

View File

@ -74,6 +74,9 @@ public class PollOptions implements Parcelable {
}
public SpannableString getTitleSpan() {
if (titleSpan == null) {
titleSpan = new SpannableString(title);
}
return titleSpan;
}

View File

@ -52,11 +52,7 @@ import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
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;
@ -88,7 +84,6 @@ import app.fedilab.android.helper.CustomQuoteSpan;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.helper.LongClickableSpan;
import app.fedilab.android.helper.ThemeHelper;
import app.fedilab.android.interfaces.OnRetrieveEmojiInterface;
import es.dmoral.toasty.Toasty;
import static android.content.Context.MODE_PRIVATE;
@ -267,7 +262,6 @@ public class Status implements Parcelable {
public static void fillSpan(WeakReference<Context> contextWeakReference, Status status) {
Status.transform(contextWeakReference, status);
Status.makeEmojis(contextWeakReference, status);
Status.makeImage(contextWeakReference, status);
}
@ -502,11 +496,11 @@ public class Status implements Parcelable {
}
}
SpannableString spannableStringT;
SpannableStringBuilder spannableStringT;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
spannableStringT = new SpannableString(Html.fromHtml(spannableString.toString().replaceAll("[\\s]{2}", "&nbsp;&nbsp;"), Html.FROM_HTML_MODE_LEGACY));
spannableStringT = new SpannableStringBuilder(Html.fromHtml(spannableString.toString().replaceAll("[\\s]{2}", "&nbsp;&nbsp;"), Html.FROM_HTML_MODE_LEGACY));
else
spannableStringT = new SpannableString(Html.fromHtml(spannableString.toString().replaceAll("[\\s]{2}", "&nbsp;&nbsp;")));
spannableStringT = new SpannableStringBuilder(Html.fromHtml(spannableString.toString().replaceAll("[\\s]{2}", "&nbsp;&nbsp;")));
replaceQuoteSpans(context, spannableStringT);
URLSpan[] spans = spannableStringT.getSpans(0, spannableStringT.length(), URLSpan.class);
for (URLSpan span : spans) {
@ -557,7 +551,7 @@ public class Status implements Parcelable {
Iterator<Map.Entry<String, Account>> it = accountsMentionUnknown.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Account> pair = it.next();
String key = pair.getKey();
String key = pair.getKey();
Account account = pair.getValue();
String targetedAccount = "@" + account.getAcct();
if (spannableStringT.toString().toLowerCase().contains(targetedAccount.toLowerCase())) {
@ -571,7 +565,7 @@ public class Status implements Parcelable {
if (ssb.length() >= endPosition) {
ssb.replace(startPosition, endPosition, key);
}
spannableStringT = SpannableString.valueOf(ssb);
spannableStringT = SpannableStringBuilder.valueOf(ssb);
endPosition = startPosition + key.length();
}
//Accounts can be mentioned several times so we have to loop
@ -622,7 +616,7 @@ public class Status implements Parcelable {
if (ssb.length() >= endPosition) {
ssb.replace(startPosition, endPosition, key);
}
spannableStringT = SpannableString.valueOf(ssb);
spannableStringT = SpannableStringBuilder.valueOf(ssb);
endPosition = startPosition + key.length();
}
if (endPosition <= spannableStringT.toString().length() && endPosition >= startPosition) {
@ -841,7 +835,17 @@ public class Status implements Parcelable {
}
}
return spannableStringT;
Pattern carriagePattern = Pattern.compile("(\\n)+$");
matcher = carriagePattern.matcher(spannableStringT);
while (matcher.find()) {
int matchStart = matcher.start();
int matchEnd = matcher.end();
if (matchStart >= 0 && matchEnd <= spannableStringT.toString().length() && matchEnd >= matchStart) {
spannableStringT.delete(matchStart, matchEnd);
}
}
return SpannableString.valueOf(spannableStringT);
}
public static void transformTranslation(Context context, Status status) {
@ -895,148 +899,6 @@ public class Status implements Parcelable {
status.setContentSpanTranslated(contentSpanTranslated);
}
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)
return;
if (status.getReblog() == null && status.getEmojis() == null)
return;
final List<Emojis> emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis();
SpannableString contentSpan = status.getContentSpan();
SpannableString contentSpanCW = status.getContentSpanCW();
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean disableAnimatedEmoji = sharedpreferences.getBoolean(Helper.SET_DISABLE_ANIMATED_EMOJI, false);
if (emojis != null && emojis.size() > 0) {
final int[] i = {0};
for (final Emojis emoji : emojis) {
Glide.with(context)
.asDrawable()
.load(disableAnimatedEmoji ? emoji.getStatic_url() : emoji.getUrl())
.listener(new RequestListener<Drawable>() {
@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) {
return false;
}
})
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (contentSpan != null && contentSpan.toString().contains(targetedEmoji)) {
//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 (resource != null && endPosition <= contentSpan.toString().length() && endPosition >= startPosition) {
ImageSpan imageSpan;
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) {
}
}
}
}
if (contentSpanCW != null && contentSpanCW.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = contentSpanCW.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if (endPosition <= contentSpanCW.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);
contentSpanCW.setSpan(
imageSpan, startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
}
}
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();
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean disableAnimatedEmoji = sharedpreferences.getBoolean(Helper.SET_DISABLE_ANIMATED_EMOJI, false);
int inc = 0;
for (PollOptions pollOption : poll.getOptionsList()) {
inc++;
SpannableString titleSpan = new SpannableString(pollOption.getTitle());
if (emojis != null && emojis.size() > 0) {
final int[] i = {0};
for (final Emojis emoji : emojis) {
Glide.with(context)
.asDrawable()
.load(disableAnimatedEmoji ? emoji.getStatic_url() : emoji.getUrl())
.listener(new RequestListener<Drawable>() {
@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) {
return false;
}
})
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (titleSpan.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = titleSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if (endPosition <= titleSpan.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);
titleSpan.setSpan(
imageSpan, startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
pollOption.setTitleSpan(titleSpan);
}
}
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
}
}
}
private static void makeImage(final WeakReference<Context> contextWeakReference, Status status) {
Context context = contextWeakReference.get();
@ -1056,17 +918,6 @@ public class Status implements Parcelable {
Glide.with(context)
.asBitmap()
.load(imgURL)
.listener(new RequestListener<Bitmap>() {
@Override
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
return false;
}
})
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
@ -1101,79 +952,6 @@ public class Status implements Parcelable {
}
public static void makeEmojisTranslation(final Context context, final OnRetrieveEmojiInterface listener, Status status) {
if (context instanceof Activity && ((Activity) context).isFinishing())
return;
SpannableString spannableStringTranslated = null;
if (status.getContentTranslated() != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
spannableStringTranslated = new SpannableString(Html.fromHtml(status.getContentTranslated(), Html.FROM_HTML_MODE_LEGACY));
else
spannableStringTranslated = new SpannableString(Html.fromHtml(status.getContentTranslated()));
}
final List<Emojis> emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis();
if (emojis != null && emojis.size() > 0) {
final int[] i = {0};
for (final Emojis emoji : emojis) {
final SpannableString finalSpannableStringTranslated = spannableStringTranslated;
Glide.with(context)
.asBitmap()
.load(emoji.getUrl())
.listener(new RequestListener<Bitmap>() {
@Override
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
i[0]++;
if (i[0] == (emojis.size())) {
if (finalSpannableStringTranslated != null)
status.setContentSpanTranslated(finalSpannableStringTranslated);
listener.onRetrieveEmoji(status, true);
}
return false;
}
})
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (finalSpannableStringTranslated != null && finalSpannableStringTranslated.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = finalSpannableStringTranslated.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if (endPosition <= finalSpannableStringTranslated.toString().length() && endPosition >= startPosition)
finalSpannableStringTranslated.setSpan(
new ImageSpan(context,
Bitmap.createScaledBitmap(resource, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false)), startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
i[0]++;
if (i[0] == (emojis.size())) {
if (finalSpannableStringTranslated != null)
status.setContentSpanTranslated(finalSpannableStringTranslated);
status.setEmojiTranslateFound(true);
listener.onRetrieveEmoji(status, true);
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
}
}
private static void replaceQuoteSpans(Context context, Spannable spannable) {
QuoteSpan[] quoteSpans = spannable.getSpans(0, spannable.length(), QuoteSpan.class);
for (QuoteSpan quoteSpan : quoteSpans) {

View File

@ -212,14 +212,24 @@ public class GNUAPI {
return statuses;
}
/**
* Parse json response for unique status
*
* @param resobj JSONObject
* @return Status
*/
@SuppressWarnings("InfiniteRecursion")
private static Status parseStatuses(Context context, JSONObject resobj) {
return parseStatuses(context, resobj, true);
}
/**
* Parse json response for unique status
*
* @param resobj JSONObject
* @return Status
*/
private static Status parseStatuses(Context context, JSONObject resobj, boolean recursive) {
Status status = new Status();
try {
status.setId(resobj.get("id").toString());
@ -337,7 +347,9 @@ public class GNUAPI {
status.setMuted(false);
status.setPinned(false);
try {
status.setReblog(parseStatuses(context, resobj.getJSONObject("retweeted_status")));
if (recursive) {
status.setReblog(parseStatuses(context, resobj.getJSONObject("retweeted_status"), false));
}
} catch (Exception ignored) {
status.setReblog(null);
}
@ -1476,24 +1488,20 @@ public class GNUAPI {
case FAVOURITE:
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU) {
action = "/favorites/create.json";
params = new HashMap<>();
params.put("id", targetedId);
} else {
action = "/friendica/activity/like.json";
params = new HashMap<>();
params.put("id", targetedId);
}
params = new HashMap<>();
params.put("id", targetedId);
break;
case UNFAVOURITE:
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU) {
action = "/favorites/destroy.json";
params = new HashMap<>();
params.put("id", targetedId);
} else {
action = "/friendica/activity/unlike.json";
params = new HashMap<>();
params.put("id", targetedId);
}
params = new HashMap<>();
params.put("id", targetedId);
break;
case REBLOG:
action = String.format("/statuses/retweet/%s.json", targetedId);

View File

@ -11,6 +11,8 @@ import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.module.AppGlideModule;
import org.jetbrains.annotations.NotNull;
import java.io.InputStream;
/**
@ -27,7 +29,7 @@ public final class TLSLibraryGlideModule extends AppGlideModule {
}
@Override
public void applyOptions(Context context, GlideBuilder builder) {
public void applyOptions(@NotNull Context context, @NotNull GlideBuilder builder) {
}
}

View File

@ -147,10 +147,10 @@ public class HttpsConnection {
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator it = paramaters.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
params.put(pair.getKey().toString(), pair.getValue());
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
it.remove();
}
}
@ -236,7 +236,7 @@ public class HttpsConnection {
httpsURLConnection.setInstanceFollowRedirects(false);
httpsURLConnection.setSSLSocketFactory(new TLSSocketFactory(this.instance));
httpsURLConnection.setRequestMethod("HEAD");
if (httpsURLConnection.getResponseCode() == 301) {
if (httpsURLConnection.getResponseCode() == 301 || httpsURLConnection.getResponseCode() == 302) {
Map<String, List<String>> map = httpsURLConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
if (entry.toString().toLowerCase().startsWith("location")) {
@ -362,25 +362,25 @@ public class HttpsConnection {
public String post(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
if (urlConnection.startsWith("https://")) {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpsURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
@ -429,25 +429,6 @@ public class HttpsConnection {
httpsURLConnection.getInputStream().close();
return response;
} else {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
else
@ -499,10 +480,12 @@ public class HttpsConnection {
String postJson(String urlConnection, int timeout, JsonObject jsonObject, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
URL url = new URL(urlConnection);
byte[] postDataBytes;
postDataBytes = jsonObject.toString().getBytes(StandardCharsets.UTF_8);
if (urlConnection.startsWith("https://")) {
URL url = new URL(urlConnection);
byte[] postDataBytes;
postDataBytes = jsonObject.toString().getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpsURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
@ -553,9 +536,6 @@ public class HttpsConnection {
httpsURLConnection.getInputStream().close();
return response;
} else {
URL url = new URL(urlConnection);
byte[] postDataBytes = jsonObject.toString().getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
else
@ -812,9 +792,15 @@ public class HttpsConnection {
public InputStream getPicture(final String downloadUrl) {
URL url;
try {
url = new URL(downloadUrl);
} catch (MalformedURLException e) {
return null;
}
if (downloadUrl.startsWith("https://")) {
try {
URL url = new URL(downloadUrl);
if (proxy != null)
httpsURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
@ -823,7 +809,7 @@ public class HttpsConnection {
httpsURLConnection.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = httpsURLConnection.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
if (responseCode >= 200 && responseCode < 400) {
// opens input stream from the HTTP connection
return httpsURLConnection.getInputStream();
}
@ -835,10 +821,8 @@ public class HttpsConnection {
httpsURLConnection.getInputStream().close();
} catch (Exception ignored) {
}
return null;
} else {
try {
URL url = new URL(downloadUrl);
if (proxy != null)
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
else
@ -846,7 +830,7 @@ public class HttpsConnection {
httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = httpURLConnection.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
if (responseCode >= 200 && responseCode < 400) {
// opens input stream from the HTTP connection
return httpURLConnection.getInputStream();
}
@ -858,8 +842,8 @@ public class HttpsConnection {
httpURLConnection.getInputStream().close();
} catch (Exception ignored) {
}
return null;
}
return null;
}
private void uploadMedia(String urlConnection, InputStream avatar, InputStream header, String filename) {
@ -923,27 +907,27 @@ public class HttpsConnection {
@SuppressWarnings("SameParameterValue")
public String patch(String urlConnection, int timeout, HashMap<String, String> paramaters, InputStream avatar, String avatarName, InputStream header, String headerName, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = (postData.toString()).getBytes(StandardCharsets.UTF_8);
if (urlConnection.startsWith("https://")) {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = (postData.toString()).getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpsURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
@ -1006,25 +990,6 @@ public class HttpsConnection {
httpsURLConnection.getInputStream().close();
return response;
} else {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = (postData.toString()).getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
@ -1088,26 +1053,27 @@ public class HttpsConnection {
}
public String put(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
if (urlConnection.startsWith("https://")) {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
if (urlConnection.startsWith("https://")) {
if (proxy != null)
httpsURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
@ -1157,25 +1123,6 @@ public class HttpsConnection {
httpsURLConnection.getInputStream().close();
return response;
} else {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
else
@ -1228,26 +1175,27 @@ public class HttpsConnection {
}
public int delete(String urlConnection, int timeout, HashMap<String, String> paramaters, String token) throws IOException, NoSuchAlgorithmException, KeyManagementException, HttpsConnectionException {
if (urlConnection.startsWith("https://")) {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator<Map.Entry<String, String>> it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
params.put(pair.getKey(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
if (urlConnection.startsWith("https://")) {
if (proxy != null)
httpsURLConnection = (HttpsURLConnection) url.openConnection(proxy);
else
@ -1292,25 +1240,6 @@ public class HttpsConnection {
throw new HttpsConnectionException(responseCode, error);
}
} else {
URL url = new URL(urlConnection);
Map<String, Object> params = new LinkedHashMap<>();
if (paramaters != null) {
Iterator it = paramaters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
params.put(pair.getKey().toString(), pair.getValue());
it.remove();
}
}
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(param.getKey());
postData.append('=');
postData.append(param.getValue());
}
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
if (proxy != null)
httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
else

View File

@ -40,7 +40,7 @@ import static android.content.Context.MODE_PRIVATE;
* Created by Thomas on 03/10/2019
* Adapter for accounts and live notifications
*/
public class AccountLiveAdapter extends RecyclerView.Adapter {
public class AccountLiveAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Account> accounts;

View File

@ -47,6 +47,8 @@ import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnPostActionInterface;
import es.dmoral.toasty.Toasty;
import static app.fedilab.android.helper.Helper.makeEmojis;
/**
* Created by Thomas on 03/09/2017.
@ -125,6 +127,7 @@ public class AccountSearchDevAdapter extends BaseAdapter implements OnPostAction
}
} else {
holder.account_dn.setText(account.getDisplay_name());
makeEmojis(context, holder.account_dn, account.getDisplayNameSpan(), account.getEmojis());
holder.account_un.setText(account.getAcct());
holder.account_follow.hide();
}

View File

@ -36,12 +36,14 @@ import app.fedilab.android.client.Entities.AccountAdmin;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnRetrieveEmojiAccountInterface;
import static app.fedilab.android.helper.Helper.makeEmojis;
/**
* Created by Thomas on 19/06/2019.
* Adapter for account admins
*/
public class AccountsAdminListAdapter extends RecyclerView.Adapter implements OnRetrieveEmojiAccountInterface {
public class AccountsAdminListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnRetrieveEmojiAccountInterface {
private List<AccountAdmin> accountAdmins;
private Context context;
@ -74,8 +76,11 @@ public class AccountsAdminListAdapter extends RecyclerView.Adapter implements On
else if (account.getDisplay_name() != null) {
holder.account_dn.setText(account.getDisplay_name().replace("@", ""));
}
} else
} else {
holder.account_dn.setText(account.getDisplayNameSpan(), TextView.BufferType.SPANNABLE);
makeEmojis(context, holder.account_dn, account.getDisplayNameSpan(), account.getEmojis());
}
if (account.getDisplayNameSpan() == null || account.getDisplayNameSpan().toString().trim().equals("")) {
if (account.getDisplay_name() != null && !account.getDisplay_name().trim().equals(""))

View File

@ -50,12 +50,14 @@ import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnPostActionInterface;
import es.dmoral.toasty.Toasty;
import static app.fedilab.android.helper.Helper.makeEmojis;
/**
* Created by Thomas on 07/05/2017.
* Adapter for accounts asking a follow request
*/
public class AccountsFollowRequestAdapter extends RecyclerView.Adapter implements OnPostActionInterface {
public class AccountsFollowRequestAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface {
private List<Account> accounts;
private Context context;
@ -88,6 +90,7 @@ public class AccountsFollowRequestAdapter extends RecyclerView.Adapter implement
holder.btn_reject.setVisibility(View.GONE);
}
holder.account_dn.setText(account.getDisplay_name());
makeEmojis(context, holder.account_dn, account.getDisplayNameSpan(), account.getEmojis());
holder.account_un.setText(account.getAcct());
//Profile picture
Glide.with(holder.account_pp.getContext())

View File

@ -45,12 +45,14 @@ import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnListActionInterface;
import es.dmoral.toasty.Toasty;
import static app.fedilab.android.helper.Helper.makeEmojis;
/**
* Created by Thomas on 15/12/2017.
* Adapter for accounts in lists
*/
public class AccountsInAListAdapter extends RecyclerView.Adapter implements OnListActionInterface {
public class AccountsInAListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnListActionInterface {
private List<Account> accounts;
private Context context;
@ -90,6 +92,7 @@ public class AccountsInAListAdapter extends RecyclerView.Adapter implements OnLi
holder.account_un.setText(account.getDisplay_name());
makeEmojis(context, holder.account_un, account.getDisplayNameSpan(), account.getEmojis());
holder.account_ac.setText(account.getAcct());
if (account.getDisplay_name().equals(account.getAcct()))
holder.account_ac.setVisibility(View.GONE);

View File

@ -60,24 +60,38 @@ import app.fedilab.android.sqlite.InstancesDAO;
import app.fedilab.android.sqlite.Sqlite;
import es.dmoral.toasty.Toasty;
import static app.fedilab.android.helper.Helper.makeEmojis;
/**
* Created by Thomas on 27/04/2017.
* Adapter for accounts
*/
public class AccountsListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveEmojiAccountInterface {
public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface, OnRetrieveEmojiAccountInterface {
private List<Account> accounts;
private RetrieveAccountsAsyncTask.Type action;
private Context context;
private AccountsListAdapter accountsListAdapter;
private String targetedId;
private boolean crossAction;
public AccountsListAdapter(RetrieveAccountsAsyncTask.Type action, String targetedId, boolean crossAction, List<Account> accounts) {
this.accounts = accounts;
this.action = action;
this.accountsListAdapter = this;
this.targetedId = targetedId;
this.crossAction = crossAction;
}
public AccountsListAdapter(RetrieveAccountsAsyncTask.Type action, String targetedId, List<Account> accounts) {
this.accounts = accounts;
this.action = action;
this.accountsListAdapter = this;
this.targetedId = targetedId;
crossAction = false;
}
@ -172,8 +186,10 @@ public class AccountsListAdapter extends RecyclerView.Adapter implements OnPostA
holder.account_dn.setText(account.getDisplay_name());
else
holder.account_dn.setText(account.getUsername().replace("@", ""));
} else
} else {
holder.account_dn.setText(account.getDisplayNameSpan(), TextView.BufferType.SPANNABLE);
makeEmojis(context, holder.account_dn, account.getDisplayNameSpan(), account.getEmojis());
}
holder.account_un.setText(String.format("@%s", account.getUsername()));
holder.account_ac.setText(account.getAcct());
if (account.getUsername().equals(account.getAcct()))
@ -239,7 +255,7 @@ public class AccountsListAdapter extends RecyclerView.Adapter implements OnPostA
});
if (action != RetrieveAccountsAsyncTask.Type.GROUPS) {
holder.account_pp.setOnClickListener(v -> {
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE || action != RetrieveAccountsAsyncTask.Type.CHANNELS) {
if (!crossAction && (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE || action != RetrieveAccountsAsyncTask.Type.CHANNELS)) {
//Avoid to reopen details about the current account
if (targetedId == null || !targetedId.equals(account.getId())) {
Intent intent = new Intent(context, ShowAccountActivity.class);

View File

@ -15,6 +15,7 @@ package app.fedilab.android.drawers;
* see <http://www.gnu.org/licenses>. */
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@ -30,6 +31,7 @@ import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityOptionsCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
@ -58,13 +60,14 @@ import app.fedilab.android.sqlite.StatusCacheDAO;
import es.dmoral.toasty.Toasty;
import static android.content.Context.MODE_PRIVATE;
import static app.fedilab.android.helper.Helper.makeEmojis;
/**
* Created by Thomas on 14/01/2019.
* Adapter for art drawer
*/
public class ArtListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface {
public class ArtListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface {
private static final int DISPLAYED_STATUS = 1;
private final int HIDDEN_STATUS = 0;
@ -176,7 +179,16 @@ public class ArtListAdapter extends RecyclerView.Adapter implements OnPostAction
b.putInt("bgcolor", context.getResources().getColor(R.color.cyanea_primary_dark));
b.putInt("position", 1);
intent.putExtras(b);
context.startActivity(intent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, holder.art_media, status.getMedia_attachments().get(0).getUrl());
// start the new activity
context.startActivity(intent, options.toBundle());
} else {
// start the new activity
context.startActivity(intent);
}
});
holder.art_author.setOnClickListener(v -> {
Intent intent = new Intent(context, ShowConversationActivity.class);
@ -186,9 +198,10 @@ public class ArtListAdapter extends RecyclerView.Adapter implements OnPostAction
context.startActivity(intent);
});
if (status.getAccount().getDisplayNameSpan() != null && status.getAccount().getDisplayNameSpan().toString().trim().length() > 0)
if (status.getAccount().getDisplayNameSpan() != null && status.getAccount().getDisplayNameSpan().toString().trim().length() > 0) {
holder.art_username.setText(status.getAccount().getDisplayNameSpan(), TextView.BufferType.SPANNABLE);
else
makeEmojis(context, holder.art_username, status.getAccount().getDisplayNameSpan(), status.getAccount().getEmojis());
} else
holder.art_username.setText(status.getAccount().getUsername());
holder.art_acct.setText(String.format("@%s", status.getAccount().getAcct()));

View File

@ -88,7 +88,9 @@ public class CustomEmojiAdapter extends BaseAdapter {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
emoji.setDrawable(resource);
imageView.setImageDrawable(emoji.getDrawable());
if (imageView != null && emoji.getDrawable() != null) {
imageView.setImageDrawable(emoji.getDrawable());
}
}
@Override

View File

@ -43,7 +43,7 @@ import es.dmoral.toasty.Toasty;
* Created by Thomas on 26/09/2018.
* Adapter for domains
*/
public class DomainsListAdapter extends RecyclerView.Adapter implements OnRetrieveDomainsInterface {
public class DomainsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnRetrieveDomainsInterface {
private List<String> domains;
private Context context;

View File

@ -35,7 +35,7 @@ import app.fedilab.android.helper.Helper;
* Created by Thomas on 19/12/2019.
* Adapter for identity proofs
*/
public class IdentityProofsAdapter extends RecyclerView.Adapter {
public class IdentityProofsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<IdentityProof> identityProofs;

View File

@ -14,6 +14,7 @@ package app.fedilab.android.drawers;
* 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.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@ -23,6 +24,7 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityOptionsCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
@ -43,7 +45,7 @@ import app.fedilab.android.client.Entities.Status;
* Adapter to display media related to status
*/
public class ImageAdapter extends RecyclerView.Adapter {
public class ImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Status> statuses;
@ -86,7 +88,15 @@ public class ImageAdapter extends RecyclerView.Adapter {
b.putInt("position", (viewHolder.getAdapterPosition() + 1));
b.putInt("bgcolor", context.getResources().getColor(R.color.cyanea_primary_dark));
intent.putExtras(b);
context.startActivity(intent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, holder.imageView, attachmentsTmp.get((viewHolder.getAdapterPosition())).getUrl());
// start the new activity
context.startActivity(intent, options.toBundle());
} else {
// start the new activity
context.startActivity(intent);
}
});
holder.imageView.setOnLongClickListener(v -> {
Intent intent = new Intent(context, ShowConversationActivity.class);

View File

@ -37,7 +37,7 @@ import app.fedilab.android.helper.Helper;
* Adapter to display instances
*/
public class InstancePeertubeRegAdapter extends RecyclerView.Adapter {
public class InstancePeertubeRegAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<InstanceReg> instanceRegs;
private LayoutInflater layoutInflater;

View File

@ -43,7 +43,7 @@ import app.fedilab.android.helper.Helper;
* Adapter to display instances
*/
public class InstanceRegAdapter extends RecyclerView.Adapter {
public class InstanceRegAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<InstanceReg> instanceRegs;
private LayoutInflater layoutInflater;

View File

@ -30,7 +30,10 @@ import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@ -53,6 +56,7 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.preference.PreferenceManager;
@ -70,6 +74,8 @@ import java.util.List;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import app.fedilab.android.R;
import app.fedilab.android.activities.AccountReportActivity;
@ -111,6 +117,7 @@ import es.dmoral.toasty.Toasty;
import static android.content.Context.MODE_PRIVATE;
import static app.fedilab.android.activities.BaseMainActivity.social;
import static app.fedilab.android.helper.Helper.makeEmojis;
/**
@ -118,7 +125,7 @@ import static app.fedilab.android.activities.BaseMainActivity.social;
* Adapter for Status
*/
public class NotificationsListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnPostNotificationsActionInterface, OnRetrieveEmojiInterface, OnRetrieveEmojiAccountInterface, OnPollInterface, OnRetrieveImageInterface {
public class NotificationsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface, OnPostNotificationsActionInterface, OnRetrieveEmojiInterface, OnRetrieveEmojiAccountInterface, OnPollInterface, OnRetrieveImageInterface {
private final Object lock = new Object();
private Context context;
@ -261,7 +268,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
else
typeString = String.format("@%s %s", notification.getAccount().getUsername(), context.getString(R.string.notif_mention));
imgH = ContextCompat.getDrawable(context, R.drawable.ic_chat_bubble_outline);
if (notification.getStatus().getVisibility().equals("direct")) {
if (notification.getStatus() != null && notification.getStatus().getVisibility().equals("direct")) {
holder.main_container_trans.setVisibility(View.GONE);
} else {
holder.main_container_trans.setVisibility(View.VISIBLE);
@ -322,8 +329,10 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
if (notification.getAccount().getDisplayNameSpan() == null) {
holder.notification_type.setText(typeString);
notification.getAccount().setStored_displayname(notification.getAccount().getDisplay_name());
} else
holder.notification_type.setText(notification.getAccount().getDisplayNameSpan(), TextView.BufferType.SPANNABLE);
} else {
holder.notification_type.setText(typeString, TextView.BufferType.SPANNABLE);
makeEmojis(context, holder.notification_type, notification.getAccount().getDisplayNameSpan(), notification.getAccount().getEmojis());
}
if (imgH != null) {
DrawableCompat.setTint(imgH, ContextCompat.getColor(context, R.color.cyanea_accent));
@ -376,6 +385,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
holder.status_privacy.setContentDescription(context.getString(R.string.toot_visibility_tilte) + ": " + v);
});
holder.notification_status_content.setText(status.getContentSpan(), TextView.BufferType.SPANNABLE);
makeEmojis(context, holder.notification_status_content, status.getContentSpan(), status.getEmojis());
holder.status_spoiler.setText(status.getContentSpanCW(), TextView.BufferType.SPANNABLE);
holder.status_spoiler.setMovementMethod(LinkMovementMethod.getInstance());
holder.notification_status_content.setMovementMethod(LinkMovementMethod.getInstance());
@ -539,8 +549,9 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
TextView poll_item_percent = item.findViewById(R.id.poll_item_percent);
TextView poll_item_text = item.findViewById(R.id.poll_item_text);
ProgressBar poll_item_value = item.findViewById(R.id.poll_item_value);
poll_item_percent.setText(String.format("%s %%", String.valueOf((int) value)));
poll_item_percent.setText(String.format("%s %%", (int) value));
poll_item_text.setText(pollOption.getTitle(), TextView.BufferType.SPANNABLE);
makeEmojis(context, poll_item_text, pollOption.getTitleSpan(), poll.getEmojis());
poll_item_value.setProgress((int) value);
holder.rated.addView(item);
if (pollOption.getVotes_count() == greaterValue) {
@ -564,6 +575,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
for (PollOptions pollOption : poll.getOptionsList()) {
CheckBox cb = new CheckBox(context);
cb.setText(pollOption.getTitle());
makeEmojis(context, cb, pollOption.getTitleSpan(), poll.getEmojis());
holder.multiple_choice.addView(cb);
}
holder.multiple_choice.setVisibility(View.VISIBLE);
@ -573,6 +585,7 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
for (PollOptions pollOption : poll.getOptionsList()) {
RadioButton rb = new RadioButton(context);
rb.setText(pollOption.getTitle());
makeEmojis(context, rb, pollOption.getTitleSpan(), poll.getEmojis());
holder.radio_group.addView(rb);
}
holder.single_choice.setVisibility(View.VISIBLE);
@ -742,7 +755,27 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
holder.notification_delete.setOnClickListener(v -> displayConfirmationNotificationDialog(notification));
holder.notification_account_username.setVisibility(View.GONE);
if (notification.getAccount() != null) {
SpannableString wordtoSpan = new SpannableString("@" + notification.getAccount().getAcct());
Pattern hashAcct = Pattern.compile("(@" + notification.getAccount().getAcct() + ")");
int theme_text_header_2_line = prefs.getInt("theme_text_header_2_line", -1);
if (theme_text_header_2_line == -1) {
theme_text_header_2_line = ThemeHelper.getAttColor(context, R.attr.textHeader);
}
Matcher matcherAcct = hashAcct.matcher(wordtoSpan);
while (matcherAcct.find()) {
int matchStart = matcherAcct.start(1);
int matchEnd = matcherAcct.end();
if (wordtoSpan.length() >= matchEnd && matchStart < matchEnd) {
wordtoSpan.setSpan(new ForegroundColorSpan(theme_text_header_2_line), matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
holder.notification_account_username.setText(wordtoSpan);
}
final String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
final View attached = holder.status_more;
@ -1046,13 +1079,12 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
* @param notification Notification
*/
private void displayConfirmationNotificationDialog(final Notification notification) {
final ArrayList seletedItems = new ArrayList();
final ArrayList<Integer> seletedItems = new ArrayList<>();
AlertDialog dialog = new AlertDialog.Builder(context, style)
.setTitle(R.string.delete_notification_ask)
.setMultiChoiceItems(new String[]{context.getString(R.string.delete_notification_ask_all)}, null, (dialog1, indexSelected, isChecked) -> {
if (isChecked) {
//noinspection unchecked
seletedItems.add(indexSelected);
} else {
if (seletedItems.contains(indexSelected))
@ -1186,7 +1218,15 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On
b.putInt("position", finalPosition);
b.putInt("bgcolor", context.getResources().getColor(R.color.cyanea_primary_dark));
intent.putExtras(b);
context.startActivity(intent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, imageView, notification.getStatus().getMedia_attachments().get(finalPosition - 1).getUrl());
// start the new activity
context.startActivity(intent, options.toBundle());
} else {
// start the new activity
context.startActivity(intent);
}
});
i++;
position++;

View File

@ -55,7 +55,7 @@ import app.fedilab.android.interfaces.OnListActionInterface;
* Created by Thomas on 06/10/2018.
* Adapter for peertube
*/
public class PeertubeAdapter extends RecyclerView.Adapter implements OnListActionInterface {
public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnListActionInterface {
private List<Peertube> peertubes;
private Context context;

View File

@ -48,7 +48,7 @@ import app.fedilab.android.helper.Helper;
* Adapter for Peertube notifications
*/
public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter {
public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<PeertubeNotification> notifications;

View File

@ -47,6 +47,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.cardview.widget.CardView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityOptionsCompat;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -120,7 +121,7 @@ import static app.fedilab.android.activities.BaseMainActivity.social;
* Created by Thomas on 14/01/2019.
* Adapter for pixelfed drawer
*/
public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveEmojiInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveSearcAccountshInterface, OnRetrieveContextInterface, OnRetrieveFeedsInterface {
public class PixelfedListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface, OnRetrieveEmojiInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveSearcAccountshInterface, OnRetrieveContextInterface, OnRetrieveFeedsInterface {
private static final int DISPLAYED_STATUS = 1;
private final int HIDDEN_STATUS = 0;
@ -399,7 +400,15 @@ public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostA
b.putInt("position", 1);
b.putInt("bgcolor", context.getResources().getColor(R.color.cyanea_primary_dark));
intent.putExtras(b);
context.startActivity(intent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, holder.art_media, status.getMedia_attachments().get(0).getUrl());
// start the new activity
context.startActivity(intent, options.toBundle());
} else {
// start the new activity
context.startActivity(intent);
}
});
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
@ -511,12 +520,7 @@ public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostA
ownerTootVisibility = 1;
break;
}
int tootVisibility;
if (ownerTootVisibility >= initialTootVisibility) {
tootVisibility = initialTootVisibility;
} else {
tootVisibility = ownerTootVisibility;
}
int tootVisibility = Math.min(ownerTootVisibility, initialTootVisibility);
switch (tootVisibility) {
case 4:
visibility = "public";
@ -1063,7 +1067,7 @@ public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostA
status.setTranslationShown(true);
status.setContentTranslated(translate.getTranslatedContent());
Status.transformTranslation(context, status);
Status.makeEmojisTranslation(context, PixelfedListAdapter.this, status);
//makeEmojis(context, view, status.getContentSpan(), status.getReblog()!=null?status.getReblog().getEmojis():status.getEmojis());
notifyStatusChanged(status);
} else {
Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show();

View File

@ -28,6 +28,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
@ -56,7 +57,7 @@ import app.fedilab.android.helper.Helper;
* Created by Thomas on 02/11/2019.
* Adapter for pixelfed stories drawer
*/
public class PixelfedStoriesListAdapter extends RecyclerView.Adapter {
public class PixelfedStoriesListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int DISPLAYED_STATUS = 1;
private Context context;
@ -136,7 +137,15 @@ public class PixelfedStoriesListAdapter extends RecyclerView.Adapter {
b.putInt("position", 1);
b.putInt("bgcolor", context.getResources().getColor(R.color.cyanea_primary_dark));
intent.putExtras(b);
context.startActivity(intent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, holder.art_media, attachments.get(0).getUrl());
// start the new activity
context.startActivity(intent, options.toBundle());
} else {
// start the new activity
context.startActivity(intent);
}
});

View File

@ -46,7 +46,7 @@ import app.fedilab.android.interfaces.OnPostActionInterface;
* Created by Thomas on 10/03/2020.
* Adapter for reactions on messages
*/
public class ReactionAdapter extends RecyclerView.Adapter implements OnPostActionInterface {
public class ReactionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface {
private List<Reaction> reactions;
private RetrieveFeedsAsyncTask.Type type;

View File

@ -41,7 +41,7 @@ import app.fedilab.android.interfaces.OnRetrieveEmojiAccountInterface;
* Created by Thomas on 19/06/2019.
* Adapter for reports
*/
public class ReportsListAdapter extends RecyclerView.Adapter implements OnRetrieveEmojiAccountInterface {
public class ReportsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnRetrieveEmojiAccountInterface {
private List<Report> reports;
private Context context;

View File

@ -151,20 +151,21 @@ public class ScheduledTootsListAdapter extends BaseAdapter implements OnPostActi
Helper.changeDrawableColor(context, R.drawable.ic_mail_outline, R.color.action_light);
}
switch (status.getVisibility()) {
case "public":
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_public);
break;
case "unlisted":
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_lock_open);
break;
case "private":
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_lock_outline);
break;
case "direct":
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_mail_outline);
break;
}
if (status.getVisibility() != null)
switch (status.getVisibility()) {
case "public":
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_public);
break;
case "unlisted":
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_lock_open);
break;
case "private":
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_lock_outline);
break;
case "direct":
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_mail_outline);
break;
}
final SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
int style;
if (theme == Helper.THEME_DARK) {
@ -374,7 +375,7 @@ public class ScheduledTootsListAdapter extends BaseAdapter implements OnPostActi
holder.scheduled_toot_container.setOnClickListener(v -> {
Intent intentToot = new Intent(context, TootActivity.class);
Bundle b = new Bundle();
if (storedStatus.getStatus().getSpoiler_text().equals("null"))
if (storedStatus.getStatus().getSpoiler_text() != null && storedStatus.getStatus().getSpoiler_text().equals("null"))
storedStatus.getStatus().setSpoiler_text("");
b.putParcelable("storedStatus", storedStatus);
intentToot.putExtras(b);

View File

@ -36,6 +36,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityOptionsCompat;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
@ -109,7 +110,15 @@ public class SliderAdapter extends SliderViewAdapter<SliderAdapter.SliderAdapter
b.putInt("position", (position + 1));
b.putInt("bgcolor", contextWeakReference.get().getResources().getColor(R.color.cyanea_primary_dark));
intent.putExtras(b);
contextWeakReference.get().startActivity(intent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) contextWeakReference.get(), viewHolder.imageViewBackground, attachments.get((position)).getUrl());
// start the new activity
contextWeakReference.get().startActivity(intent, options.toBundle());
} else {
// start the new activity
contextWeakReference.get().startActivity(intent);
}
});
} else {
viewHolder.imageViewBackground.setOnClickListener(v -> showAddDescription(attachments.get(position)));
@ -141,7 +150,7 @@ public class SliderAdapter extends SliderViewAdapter<SliderAdapter.SliderAdapter
//Text for report
final EditText input = popup_media_description.findViewById(R.id.media_description);
input.setFilters(new InputFilter[]{new InputFilter.LengthFilter(420)});
input.setFilters(new InputFilter[]{new InputFilter.LengthFilter(1500)});
final ImageView media_picture = popup_media_description.findViewById(R.id.media_picture);
Glide.with(contextWeakReference.get())
.asBitmap()

View File

@ -51,8 +51,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
@ -78,6 +76,7 @@ import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.SwitchCompat;
import androidx.appcompat.widget.TooltipCompat;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -182,7 +181,6 @@ 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;
@ -191,13 +189,15 @@ import static android.content.Context.MODE_PRIVATE;
import static app.fedilab.android.activities.BaseMainActivity.mPageReferenceMap;
import static app.fedilab.android.activities.BaseMainActivity.mutedAccount;
import static app.fedilab.android.activities.BaseMainActivity.social;
import static app.fedilab.android.asynctasks.RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE_FILTERED;
import static app.fedilab.android.helper.Helper.makeEmojis;
/**
* Created by Thomas on 24/04/2017.
* Adapter for Status
*/
public class StatusListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveFeedsInterface, OnRetrieveImageInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface, OnRetrieveCardInterface, OnPollInterface, OnRefreshCachedStatusInterface, OnRetrieveSearcAccountshInterface, OnRetrieveSearchInterface, OnPostStatusActionInterface, OnRetrieveRelationshipQuickReplyInterface, OnSyncBookmarksInterface {
public class StatusListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface, OnRetrieveFeedsInterface, OnRetrieveImageInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface, OnRetrieveCardInterface, OnPollInterface, OnRefreshCachedStatusInterface, OnRetrieveSearcAccountshInterface, OnRetrieveSearchInterface, OnPostStatusActionInterface, OnRetrieveRelationshipQuickReplyInterface, OnSyncBookmarksInterface {
public static final int DISPLAYED_STATUS = 1;
public static final int COMPACT_STATUS = 3;
@ -755,8 +755,10 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
TextView poll_item_percent = item.findViewById(R.id.poll_item_percent);
TextView poll_item_text = item.findViewById(R.id.poll_item_text);
ProgressBar poll_item_value = item.findViewById(R.id.poll_item_value);
poll_item_percent.setText(String.format("%s %%", String.valueOf((int) value)));
poll_item_text.setText(pollOption.getTitle(), TextView.BufferType.SPANNABLE);
poll_item_percent.setText(String.format("%s %%", (int) value));
poll_item_text.setText(pollOption.getTitleSpan(), TextView.BufferType.SPANNABLE);
poll_item_text.setText(pollOption.getTitle());
makeEmojis(context, poll_item_text, pollOption.getTitleSpan(), poll.getEmojis());
poll_item_value.setProgress((int) value);
holder.rated.addView(item);
if (pollOption.getVotes_count() == greaterValue) {
@ -780,11 +782,8 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
(holder.multiple_choice).removeAllViews();
for (PollOptions pollOption : poll.getOptionsList()) {
CheckBox cb = new CheckBox(context);
if (pollOption.getTitleSpan() != null) {
cb.setText(pollOption.getTitleSpan(), TextView.BufferType.SPANNABLE);
} else {
cb.setText(pollOption.getTitle());
}
cb.setText(pollOption.getTitle());
makeEmojis(context, cb, pollOption.getTitleSpan(), poll.getEmojis());
holder.multiple_choice.addView(cb);
}
@ -795,11 +794,8 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
(holder.radio_group).removeAllViews();
for (PollOptions pollOption : poll.getOptionsList()) {
RadioButton rb = new RadioButton(context);
if (pollOption.getTitleSpan() != null) {
rb.setText(pollOption.getTitleSpan(), TextView.BufferType.SPANNABLE);
} else {
rb.setText(pollOption.getTitle());
}
rb.setText(pollOption.getTitle());
makeEmojis(context, rb, pollOption.getTitleSpan(), poll.getEmojis());
holder.radio_group.addView(rb);
}
holder.single_choice.setVisibility(View.VISIBLE);
@ -983,15 +979,10 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
holder.status_spoiler.setTextSize(TypedValue.COMPLEX_UNIT_SP, (float) (14 * textSizePercent) / 100);
switch (translator) {
case Helper.TRANS_NONE:
holder.yandex_translate.setVisibility(View.GONE);
break;
case Helper.TRANS_YANDEX:
holder.yandex_translate.setVisibility(View.VISIBLE);
break;
default:
holder.yandex_translate.setVisibility(View.GONE);
if (translator == Helper.TRANS_YANDEX) {
holder.yandex_translate.setVisibility(View.VISIBLE);
} else {
holder.yandex_translate.setVisibility(View.GONE);
}
//Manages theme for icon colors
@ -1229,7 +1220,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
TooltipCompat.setTooltipText(holder.custom_feature_translate, context.getString(R.string.translate));
holder.custom_feature_translate.setOnClickListener(view -> {
translateToot(status);
translateToot(status, holder.status_content_translated);
status.setCustomFeaturesDisplayed(false);
notifyStatusChanged(status);
});
@ -1324,11 +1315,10 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
assert img != null;
img.setBounds(0, 0, (int) (20 * iconSizePercent / 100 * scale + 0.5f), (int) (15 * iconSizePercent / 100 * scale + 0.5f));
holder.status_account_displayname.setCompoundDrawables(img, null, null, null);
holder.status_toot_date.setCompoundDrawables(imgConversation, null, null, null);
} else {
holder.status_account_displayname.setCompoundDrawables(null, null, null, null);
holder.status_toot_date.setCompoundDrawables(imgConversation, null, null, null);
}
holder.status_toot_date.setCompoundDrawables(imgConversation, null, null, null);
if (expand_media && status.isSensitive() || (status.getReblog() != null && status.getReblog().isSensitive())) {
Helper.changeDrawableColor(context, holder.hide_preview, R.color.red_1);
Helper.changeDrawableColor(context, holder.hide_preview_h, R.color.red_1);
@ -1408,7 +1398,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
}
});
holder.status_content.setOnClickListener(v -> {
if (type != RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE && type != RetrieveFeedsAsyncTask.Type.NEWS) {
if (type != RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE && type != REMOTE_INSTANCE_FILTERED && type != RetrieveFeedsAsyncTask.Type.NEWS) {
Intent intent = new Intent(context, ShowConversationActivity.class);
Bundle b = new Bundle();
if (social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA)
@ -1561,6 +1551,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
holder.status_content.setText(status.getContentSpan(), TextView.BufferType.SPANNABLE);
holder.status_spoiler.setText(status.getContentSpanCW(), TextView.BufferType.SPANNABLE);
}
makeEmojis(context, holder.status_content, status.getContentSpan(), status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis());
holder.status_content.setMovementMethod(LongClickLinkMovementMethod.getInstance());
@ -1613,10 +1604,12 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
context.startActivity(intent);
});
if (status.getReblog().getAccount().getDisplay_name().length() > 0)
if (status.getReblog().getAccount().getDisplay_name().length() > 0) {
holder.status_account_displayname_owner.setText(displayNameSpan, TextView.BufferType.SPANNABLE);
else
makeEmojis(context, holder.status_account_displayname_owner, status.getReblog().getAccount().getDisplayNameSpan(), status.getReblog().getAccount().getEmojis());
} else
holder.status_account_displayname_owner.setText(status.getReblog().getAccount().getAcct().replace("@", ""));
holder.status_account_displayname_owner.setVisibility(View.VISIBLE);
if (holder.status_boosted_date != null) {
holder.status_boosted_date.setText(Helper.dateDiff(context, status.getCreated_at()));
@ -1624,10 +1617,12 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
} else {
accountForUrl = status.getAccount();
holder.status_account_displayname.setVisibility(View.GONE);
if (displayNameSpan == null || displayNameSpan.toString().trim().length() == 0)
if (displayNameSpan == null || displayNameSpan.toString().trim().length() == 0) {
holder.status_account_displayname_owner.setText(status.getAccount().getUsername().replace("@", ""), TextView.BufferType.SPANNABLE);
else
} else {
holder.status_account_displayname_owner.setText(displayNameSpan, TextView.BufferType.SPANNABLE);
makeEmojis(context, holder.status_account_displayname_owner, displayNameSpan, status.getAccount().getEmojis());
}
}
//-------- END -> Displays name & emoji in toot header
@ -1704,6 +1699,9 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
holder.fetch_more.setVisibility(View.GONE);
}
if (type == RetrieveFeedsAsyncTask.Type.CONTEXT) {
holder.fetch_more.setVisibility(View.GONE);
}
if (status.getMentions() != null)
holder.status_mention_spoiler.setText(Helper.makeMentionsClick(context, status.getMentions()), TextView.BufferType.SPANNABLE);
@ -2144,33 +2142,17 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
if (status.getReblog() == null) {
if (status.getWebviewURL() != null) {
String url = status.getWebviewURL().replaceAll("&amp;", "&");
try {
holder.status_cardview_webview.loadUrl(url);
} catch (Exception e) {
e.printStackTrace();
}
holder.status_cardview_webview.setVisibility(View.VISIBLE);
holder.status_cardview_video.setVisibility(View.VISIBLE);
holder.webview_preview.setVisibility(View.GONE);
} else {
holder.status_cardview_webview.setVisibility(View.GONE);
holder.status_cardview_video.setVisibility(View.GONE);
holder.webview_preview.setVisibility(View.VISIBLE);
}
} else {
if (status.getReblog().getWebviewURL() != null) {
String url = status.getReblog().getWebviewURL().replaceAll("&amp;", "&");
try {
holder.status_cardview_webview.loadUrl(url);
} catch (Exception e) {
e.printStackTrace();
}
holder.status_cardview_webview.setVisibility(View.VISIBLE);
holder.status_cardview_video.setVisibility(View.VISIBLE);
holder.webview_preview.setVisibility(View.GONE);
} else {
holder.status_cardview_webview.setVisibility(View.GONE);
holder.status_cardview_video.setVisibility(View.GONE);
holder.webview_preview.setVisibility(View.VISIBLE);
}
@ -2302,17 +2284,14 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
Helper.openBrowser(context, url);
});
} else if (card.getType().toLowerCase().equals("video") && (display_video_preview || (type == RetrieveFeedsAsyncTask.Type.CONTEXT && viewHolder.getAdapterPosition() == conversationPosition))) {
Glide.with(holder.status_cardview_image.getContext())
.load(card.getImage())
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
.into(holder.webview_preview_card);
holder.status_cardview.setVisibility(View.GONE);
holder.status_cardview_video.setVisibility(View.VISIBLE);
String user_agent = sharedpreferences.getString(Helper.SET_CUSTOM_USER_AGENT, Helper.USER_AGENT);
if (user_agent != null) {
holder.status_cardview_webview.getSettings().setUserAgentString(user_agent);
}
holder.status_cardview_webview.getSettings().setJavaScriptEnabled(true);
String html = card.getHtml();
String src = card.getUrl();
if (html != null) {
@ -2321,12 +2300,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
src = matcher.group(1);
}
final String finalSrc = src;
holder.status_cardview_webview.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
holder.status_cardview_video.setVisibility(View.GONE);
}
});
holder.webview_preview.setOnClickListener(v -> {
String url = finalSrc;
if (url != null) {
@ -2344,12 +2318,27 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
}
}
}
if (status.getReblog() == null) {
status.setWebviewURL(url);
Intent intent = new Intent(context, SlideMediaActivity.class);
Bundle b = new Bundle();
Attachment attachment = new Attachment();
attachment.setType("web");
attachment.setUrl(url);
attachment.setPreview_url(card.getImage());
ArrayList<Attachment> attachmentArrayList = new ArrayList<>();
attachmentArrayList.add(attachment);
intent.putParcelableArrayListExtra("mediaArray", attachmentArrayList);
b.putInt("bgcolor", context.getResources().getColor(R.color.cyanea_primary_dark));
b.putInt("position", 1);
intent.putExtras(b);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, holder.webview_preview, attachment.getUrl());
// start the new activity
context.startActivity(intent, options.toBundle());
} else {
status.getReblog().setWebviewURL(url);
// start the new activity
context.startActivity(intent);
}
notifyStatusChanged(status);
});
} else {
holder.status_cardview.setVisibility(View.GONE);
@ -2471,12 +2460,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
break;
}
}
int tootVisibility;
if (ownerTootVisibility >= initialTootVisibility) {
tootVisibility = initialTootVisibility;
} else {
tootVisibility = ownerTootVisibility;
}
int tootVisibility = Math.min(ownerTootVisibility, initialTootVisibility);
switch (tootVisibility) {
case 4:
@ -2670,6 +2654,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
CrossActions.doCrossAction(context, type, status, null, API.StatusAction.REBLOG, statusListAdapter, StatusListAdapter.this, false);
return true;
});
if (!status.getVisibility().equals("direct"))
holder.status_reply.setOnLongClickListener(view -> {
CrossActions.doCrossReply(context, status, type, false);
@ -2888,7 +2873,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
if (translator == Helper.TRANS_NONE)
Toasty.info(context, R.string.toast_error_translations_disabled, Toast.LENGTH_SHORT).show();
else
translateToot(status);
translateToot(status, holder.status_content_translated);
return true;
case R.id.action_report:
builderInner = new AlertDialog.Builder(context, style);
@ -3333,7 +3318,8 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
.asBitmap()
.load(!attachment.getType().toLowerCase().equals("audio") ? url : R.drawable.ic_audio_wave)
.thumbnail(0.1f)
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
//.dontTransform()
.apply(new RequestOptions().transform(new RoundedCorners(10)))
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
@ -3352,6 +3338,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
.asBitmap()
.load(!attachment.getType().toLowerCase().equals("audio") ? url : R.drawable.ic_audio_wave)
.thumbnail(0.1f)
// .dontTransform()
.apply(new RequestOptions().transform(new BlurTransformation(50, 3), new RoundedCorners(10)))
.into(new CustomTarget<Bitmap>() {
@Override
@ -3372,18 +3359,20 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
if (!blur) {
Glide.with(imageView.getContext())
.load(!attachment.getType().toLowerCase().equals("audio") ? url : R.drawable.ic_audio_wave)
.dontTransform()
.thumbnail(0.1f)
// .override(640, 480)
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
// .transition(DrawableTransitionOptions.withCrossFade())
.transition(DrawableTransitionOptions.withCrossFade())
.into(imageView);
} else {
Glide.with(imageView.getContext())
.load(!attachment.getType().toLowerCase().equals("audio") ? url : R.drawable.ic_audio_wave)
.thumbnail(0.1f)
.dontTransform()
// .override(640, 480)
.apply(new RequestOptions().transform(new BlurTransformation(50, 3), new RoundedCorners(10)))
// .transition(DrawableTransitionOptions.withCrossFade())
.apply(new RequestOptions().transform(new CenterCrop(), new BlurTransformation(50, 3), new RoundedCorners(10)))
.transition(DrawableTransitionOptions.withCrossFade())
.into(imageView);
}
}
@ -3408,7 +3397,16 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
b.putInt("bgcolor", context.getResources().getColor(R.color.cyanea_primary_dark));
b.putInt("position", finalPosition);
intent.putExtras(b);
context.startActivity(intent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
ActivityOptionsCompat options = ActivityOptionsCompat
.makeSceneTransitionAnimation((Activity) context, imageView, attachment.getUrl());
// start the new activity
context.startActivity(intent, options.toBundle());
} else {
// start the new activity
context.startActivity(intent);
}
}
} else {
status.setAttachmentShown(true);
@ -3882,11 +3880,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
@Override
public void onRetrieveImage(Status status, boolean fromTranslation) {
if (status != null) {
if (!fromTranslation) {
status.setImageFound(true);
} else {
status.setImageFound(true);
}
status.setImageFound(true);
notifyStatusChanged(status);
}
}
@ -3908,7 +3902,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
}
private void translateToot(Status status) {
private void translateToot(Status status, TextView view) {
//Manages translations
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int trans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX);
@ -3950,7 +3944,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
status.setTranslationShown(true);
status.setContentTranslated(translate.getTranslatedContent());
Status.transformTranslation(context, status);
Status.makeEmojisTranslation(context, StatusListAdapter.this, status);
makeEmojis(context, view, status.getContentSpan(), status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis());
notifyStatusChanged(status);
} else {
Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show();
@ -4078,7 +4072,6 @@ 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;
CustomWebview status_cardview_webview;
ImageView hide_preview, hide_preview_h;
TextView status_toot_app;
RelativeLayout webview_preview;
@ -4192,8 +4185,6 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
status_cardview_content = itemView.findViewById(R.id.status_cardview_content);
status_cardview_url = itemView.findViewById(R.id.status_cardview_url);
status_cardview_video = itemView.findViewById(R.id.status_cardview_video);
status_cardview_webview = Helper.initializeWebview((Activity) context, R.id.status_cardview_webview, itemView);
status_cardview_webview.getSettings().setJavaScriptEnabled(true);
hide_preview = itemView.findViewById(R.id.hide_preview);
hide_preview_h = itemView.findViewById(R.id.hide_preview_h);
status_toot_app = itemView.findViewById(R.id.status_toot_app);

View File

@ -35,7 +35,7 @@ import app.fedilab.android.helper.Helper;
* Created by Thomas on 19/07/2019.
* Adapter for suggestions results
*/
public class SuggestionsAdapter extends RecyclerView.Adapter {
public class SuggestionsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Suggestion> suggestions;

View File

@ -39,7 +39,7 @@ import es.dmoral.toasty.Toasty;
* Created by Thomas on 01/12/2018.
* Adapter for tags when editing
*/
public class TagsEditAdapter extends RecyclerView.Adapter {
public class TagsEditAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<String> tags;

View File

@ -110,7 +110,7 @@ public class TrendsAdapter extends BaseAdapter {
uses += _th.getUses();
tendency.put(_th.getDays(), _th.getUses());
}
if( days > 0 ) {
if (days > 0) {
people = people / days;
uses = uses / days;
}

View File

@ -266,7 +266,7 @@ public class ColorSettingsFragment extends PreferenceFragmentCompat implements S
}
List<String> array = Arrays.asList(getResources().getStringArray(R.array.settings_theme));
CharSequence[] entries = array.toArray(new CharSequence[array.size()]);
CharSequence[] entries = array.toArray(new CharSequence[0]);
CharSequence[] entryValues = new CharSequence[3];
final SharedPreferences sharedpref = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int theme = sharedpref.getInt(Helper.SET_THEME, Helper.THEME_DARK);

View File

@ -1538,7 +1538,7 @@ public class ContentSettingsFragment extends Fragment implements OnRetrieveRemot
if (featuredTagsSet != null) {
tags = new ArrayList<>(featuredTagsSet);
}
String[] tagsString = tags.toArray(new String[tags.size()]);
String[] tagsString = tags.toArray(new String[0]);
set_featured_tags.setTags(tagsString);
set_featured_tags.setTagsListener(new TagsEditText.TagsEditListener() {

View File

@ -15,7 +15,6 @@ package app.fedilab.android.fragments;
* see <http://www.gnu.org/licenses>. */
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
@ -31,6 +30,8 @@ import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@ -61,7 +62,6 @@ public class DisplayMediaFragment extends Fragment implements OnRetrieveFeedsInt
private boolean firstLoad;
private String targetedId;
private boolean showMediaOnly, showPinned, showReply;
private SharedPreferences sharedpreferences;
private ArrayList<Status> statuses;
private ImageAdapter gridAdaper;
private RecyclerView gridview;
@ -84,7 +84,6 @@ public class DisplayMediaFragment extends Fragment implements OnRetrieveFeedsInt
showReply = false;
firstLoad = true;
assert context != null;
sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
mainLoader = rootView.findViewById(R.id.loader);
nextElementLoader = rootView.findViewById(R.id.loading_next_status);
textviewNoAction = rootView.findViewById(R.id.no_action);
@ -105,7 +104,7 @@ public class DisplayMediaFragment extends Fragment implements OnRetrieveFeedsInt
gridview.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) {
int firstVisibleItem = gvLayout.findFirstVisibleItemPosition();
if (dy > 0) {
int visibleItemCount = gvLayout.getChildCount();
@ -129,12 +128,9 @@ public class DisplayMediaFragment extends Fragment implements OnRetrieveFeedsInt
if (context != null) {
asyncTask = new RetrieveFeedsAsyncTask(context, RetrieveFeedsAsyncTask.Type.USER, targetedId, max_id, showMediaOnly, showPinned, showReply, DisplayMediaFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
if (context != null) {
asyncTask = new RetrieveFeedsAsyncTask(context, RetrieveFeedsAsyncTask.Type.USER, targetedId, max_id, showMediaOnly, showPinned, showReply, DisplayMediaFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (context != null) {
asyncTask = new RetrieveFeedsAsyncTask(context, RetrieveFeedsAsyncTask.Type.USER, targetedId, max_id, showMediaOnly, showPinned, showReply, DisplayMediaFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}, 500);
}
@ -158,7 +154,7 @@ public class DisplayMediaFragment extends Fragment implements OnRetrieveFeedsInt
}
@Override
public void onAttach(Context context) {
public void onAttach(@NotNull Context context) {
super.onAttach(context);
this.context = context;
}

View File

@ -40,6 +40,8 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@ -194,7 +196,7 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev
}
@Override
public void onAttach(Context context) {
public void onAttach(@NotNull Context context) {
super.onAttach(context);
this.context = context;
}
@ -224,7 +226,6 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
message = Html.fromHtml(context.getString(R.string.no_scheduled_boosts_indications), Html.FROM_HTML_MODE_LEGACY);
else
//noinspection deprecation
message = Html.fromHtml(context.getString(R.string.no_scheduled_boosts_indications));
no_action_text_subtitle.setText(message, TextView.BufferType.SPANNABLE);
}

View File

@ -30,6 +30,7 @@ import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
@ -40,6 +41,8 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
@ -115,6 +118,12 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
private SlidrInterface slidrInterface;
private boolean swipeEnabled;
private int bgColor;
private RelativeLayout media_fragment_container;
private RelativeLayout content_audio;
private PlayerView videoView;
private CustomWebview webview_video;
private FrameLayout webview_container;
private RelativeLayout videoLayout;
public MediaSliderFragment() {
}
@ -134,7 +143,7 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
swipeEnabled = true;
message_ready = rootView.findViewById(R.id.message_ready);
RelativeLayout content_audio = rootView.findViewById(R.id.content_audio);
content_audio = rootView.findViewById(R.id.content_audio);
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
@ -144,7 +153,7 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
ImageView next = rootView.findViewById(R.id.media_next);
imageView = rootView.findViewById(R.id.media_picture);
PlayerView videoView = rootView.findViewById(R.id.media_video);
videoView = rootView.findViewById(R.id.media_video);
if (theme == Helper.THEME_BLACK) {
changeDrawableColor(context, prev, R.color.dark_icon);
changeDrawableColor(context, next, R.color.dark_icon);
@ -182,68 +191,97 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
url = attachment.getRemote_url();
attachment.setType(type);
}
if (bgColor != -1) {
RelativeLayout media_fragment_container = rootView.findViewById(R.id.media_fragment_container);
media_fragment_container.setBackgroundColor(bgColor);
media_fragment_container = rootView.findViewById(R.id.media_fragment_container);
imageView.setVisibility(View.VISIBLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
imageView.setTransitionName(attachment.getUrl());
}
switch (type.toLowerCase()) {
case "image":
pbar_inf.setScaleY(1f);
imageView.setVisibility(View.VISIBLE);
pbar_inf.setIndeterminate(true);
loader.setVisibility(View.VISIBLE);
if (!url.endsWith(".gif")) {
Glide.with(context)
.asBitmap()
.load(preview_url).into(
new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull final Bitmap resource, Transition<? super Bitmap> transition) {
Bitmap imageCompressed = Helper.compressImageIfNeeded(resource);
imageView.setImageBitmap(imageCompressed);
Glide.with(context)
.asBitmap()
.load(url).into(
new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull final Bitmap resource, Transition<? super Bitmap> transition) {
loader.setVisibility(View.GONE);
Bitmap imageCompressed = Helper.compressImageIfNeeded(resource);
if (imageView.getScale() < 1.1) {
imageView.setImageBitmap(imageCompressed);
} else {
message_ready.setVisibility(View.VISIBLE);
if (Helper.isValidContextForGlide(context)) {
Glide.with(context)
.asBitmap()
.dontTransform()
.load(preview_url).into(
new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull final Bitmap resource, Transition<? super Bitmap> transition) {
//Bitmap imageCompressed = Helper.compressImageIfNeeded(resource);
imageView.setImageBitmap(resource);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scheduleStartPostponedTransition(imageView);
}
if (bgColor != -1) {
media_fragment_container.setBackgroundColor(bgColor);
}
if (attachment.getType().toLowerCase().compareTo("image") == 0 && !attachment.getUrl().endsWith(".gif")) {
final Handler handler = new Handler();
handler.postDelayed(() -> {
pbar_inf.setScaleY(1f);
imageView.setVisibility(View.VISIBLE);
pbar_inf.setIndeterminate(true);
loader.setVisibility(View.VISIBLE);
if (Helper.isValidContextForGlide(context)) {
Glide.with(context)
.asBitmap()
.dontTransform()
.load(url).into(
new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull final Bitmap resource, Transition<? super Bitmap> transition) {
loader.setVisibility(View.GONE);
Bitmap imageCompressed = Helper.compressImageIfNeeded(resource);
if (imageView.getScale() < 1.1) {
imageView.setImageBitmap(imageCompressed);
} else {
message_ready.setVisibility(View.VISIBLE);
}
message_ready.setOnClickListener(view -> {
imageView.setImageBitmap(imageCompressed);
message_ready.setVisibility(View.GONE);
});
}
message_ready.setOnClickListener(view -> {
imageView.setImageBitmap(imageCompressed);
message_ready.setVisibility(View.GONE);
});
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
}
}
);
);
}
}, 1000);
} else if (attachment.getType().toLowerCase().compareTo("image") == 0 && attachment.getUrl().endsWith(".gif")) {
loader.setVisibility(View.GONE);
if (Helper.isValidContextForGlide(context)) {
Glide.with(context)
.load(url).into(imageView);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scheduleStartPostponedTransition(imageView);
}
}
);
} else {
loader.setVisibility(View.GONE);
Glide.with(context)
.load(url).into(imageView);
}
break;
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
scheduleStartPostponedTransition(imageView);
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
}
);
}
switch (type.toLowerCase()) {
case "video":
case "gifv":
if (bgColor != -1) {
media_fragment_container.setBackgroundColor(bgColor);
}
pbar_inf.setIndeterminate(false);
pbar_inf.setScaleY(3f);
try {
@ -272,19 +310,23 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
player.setRepeatMode(Player.REPEAT_MODE_ONE);
videoView.setPlayer(player);
loader.setVisibility(View.GONE);
imageView.setVisibility(View.GONE);
player.prepare(videoSource);
player.setPlayWhenReady(true);
break;
case "web":
if (bgColor != -1) {
media_fragment_container.setBackgroundColor(bgColor);
}
loader.setVisibility(View.GONE);
CustomWebview webview_video = Helper.initializeWebview((Activity) context, R.id.webview_video, null);
imageView.setVisibility(View.GONE);
webview_video = Helper.initializeWebview((Activity) context, R.id.webview_video, rootView);
webview_video.setVisibility(View.VISIBLE);
FrameLayout webview_container = rootView.findViewById(R.id.main_media_frame);
final ViewGroup videoLayout = rootView.findViewById(R.id.videoLayout);
webview_container = rootView.findViewById(R.id.main_media_frame);
videoLayout = rootView.findViewById(R.id.videoLayout);
MastalabWebChromeClient mastalabWebChromeClient = new MastalabWebChromeClient((Activity) context, webview_video, webview_container, videoLayout);
mastalabWebChromeClient.setOnToggledFullscreen(fullscreen -> {
if (fullscreen) {
videoLayout.setVisibility(View.VISIBLE);
WindowManager.LayoutParams attrs = ((Activity) context).getWindow().getAttributes();
@ -312,7 +354,11 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
webview_video.loadUrl(attachment.getUrl());
break;
case "audio":
if (bgColor != -1) {
media_fragment_container.setBackgroundColor(bgColor);
}
loader.setVisibility(View.GONE);
imageView.setVisibility(View.GONE);
content_audio.setVisibility(View.VISIBLE);
int color = getResources().getColor(R.color.mastodonC1);
visualizerView = new GLAudioVisualizationView.Builder(context)
@ -386,7 +432,6 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
} catch (Exception ignored) {
}
}
stopTimer();
}
@ -458,6 +503,9 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
if (playeraudio != null) {
playeraudio.pause();
}
if (webview_video != null) {
webview_video.onPause();
}
try {
visualizerView.onPause();
} catch (Exception ignored) {
@ -478,6 +526,9 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
}
} catch (Exception ignored) {
}
if (webview_video != null) {
webview_video.destroy();
}
if (timer != null) {
timer.cancel();
timer = null;
@ -504,6 +555,9 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
visualizerView.onResume();
} catch (Exception ignored) {
}
if (webview_video != null) {
webview_video.onResume();
}
if (slidrInterface == null && rootView != null) {
slidrInterface = Slidr.replace(rootView.findViewById(R.id.media_fragment_container), new SlidrConfig.Builder().sensitivity(1f)
.scrimColor(Color.BLACK)
@ -521,7 +575,30 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
@Override
public void onSlideChange(float percent) {
((SlideMediaActivity) context).setFullscreen(true);
if (percent < 0.80 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (imageView != null) {
imageView.setVisibility(View.VISIBLE);
}
if (content_audio != null) {
content_audio.setVisibility(View.GONE);
}
if (videoView != null) {
videoView.setVisibility(View.GONE);
}
if (webview_video != null) {
webview_video.setVisibility(View.GONE);
webview_video.destroy();
}
if (webview_container != null) {
webview_container.setVisibility(View.GONE);
}
if (videoLayout != null) {
videoLayout.setVisibility(View.GONE);
}
ActivityCompat.finishAfterTransition((AppCompatActivity) context);
}
}
@Override
@ -538,6 +615,17 @@ public class MediaSliderFragment extends Fragment implements MediaPlayer.OnCompl
}
}
private void scheduleStartPostponedTransition(final ImageView imageView) {
imageView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
imageView.getViewTreeObserver().removeOnPreDrawListener(this);
ActivityCompat.startPostponedEnterTransition((Activity) context);
return true;
}
});
}
private void enableSliding(boolean enable) {
if (enable && !swipeEnabled) {
slidrInterface.unlock();

View File

@ -28,6 +28,8 @@ import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import app.fedilab.android.R;
@ -105,6 +107,7 @@ public class TabLayoutTootsFragment extends Fragment {
this.mNumOfTabs = NumOfTabs;
}
@NotNull
@Override
public Fragment getItem(int position) {
switch (position) {

View File

@ -125,7 +125,7 @@ public class CrossActions {
}
public static void doCrossAction(final Context context, RetrieveFeedsAsyncTask.Type type, final Status status, final Account targetedAccount, final API.StatusAction doAction, final RecyclerView.Adapter baseAdapter, final OnPostActionInterface onPostActionInterface, boolean limitedToOwner) {
public static void doCrossAction(final Context context, RetrieveFeedsAsyncTask.Type type, final Status status, final Account targetedAccount, final API.StatusAction doAction, final RecyclerView.Adapter<RecyclerView.ViewHolder> baseAdapter, final OnPostActionInterface onPostActionInterface, boolean limitedToOwner) {
List<Account> accounts = connectedAccounts(context, status, limitedToOwner);
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
boolean undoAction = (doAction == API.StatusAction.UNPIN || doAction == API.StatusAction.UNREBLOG || doAction == API.StatusAction.UNFAVOURITE);
@ -784,7 +784,7 @@ public class CrossActions {
* @param action int
* @param status Status
*/
private static void displayConfirmationDialog(final Context context, final API.StatusAction action, final Status status, final RecyclerView.Adapter baseAdapter, final OnPostActionInterface onPostActionInterface) {
private static void displayConfirmationDialog(final Context context, final API.StatusAction action, final Status status, final RecyclerView.Adapter<RecyclerView.ViewHolder> baseAdapter, final OnPostActionInterface onPostActionInterface) {
String title = null;
if (action == API.StatusAction.FAVOURITE) {
@ -855,7 +855,7 @@ public class CrossActions {
* @param action int
* @param status Status
*/
private static void displayConfirmationDialogCrossAction(final Context context, Account currentAccount, final API.StatusAction action, final Status status, final OnPostActionInterface onPostActionInterface, final RecyclerView.Adapter baseAdapter) {
private static void displayConfirmationDialogCrossAction(final Context context, Account currentAccount, final API.StatusAction action, final Status status, final OnPostActionInterface onPostActionInterface, final RecyclerView.Adapter<RecyclerView.ViewHolder> baseAdapter) {
String title = null;
if (action == API.StatusAction.FAVOURITE) {
@ -950,7 +950,7 @@ public class CrossActions {
*
* @param status Status
*/
private static void pinAction(Context context, Status status, RecyclerView.Adapter baseAdapter, OnPostActionInterface onPostActionInterface) {
private static void pinAction(Context context, Status status, RecyclerView.Adapter<RecyclerView.ViewHolder> baseAdapter, OnPostActionInterface onPostActionInterface) {
if (status.isPinned()) {
new PostActionAsyncTask(context, API.StatusAction.UNPIN, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

View File

@ -46,6 +46,7 @@ public class FullScreenMediaController extends MediaController {
this.context = context;
}
@SuppressWarnings("unused")
public FullScreenMediaController(Context context, Peertube peertube) {
super(context);
this.peertube = peertube;
@ -80,12 +81,7 @@ public class FullScreenMediaController extends MediaController {
paramsButton.gravity = Gravity.START;
paramsButton.rightMargin = 80;
paramsButton.topMargin = 22;
resolution.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
((PeertubeActivity) getContext()).displayResolution();
}
});
resolution.setOnClickListener(v -> ((PeertubeActivity) getContext()).displayResolution());
addView(resolution, paramsButton);
if (((PeertubeActivity) getContext()).getFullscreen() == fullscreen.ON) {
@ -97,21 +93,19 @@ public class FullScreenMediaController extends MediaController {
}
//add listener to image button to handle full screen and exit full screen events
fullScreen.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
fullScreen.setOnClickListener(v -> {
if (((PeertubeActivity) getContext()).getFullscreen() == fullscreen.ON) {
((PeertubeActivity) getContext()).setFullscreen(fullscreen.OFF);
} else {
((PeertubeActivity) getContext()).setFullscreen(fullscreen.ON);
}
((PeertubeActivity) getContext()).change();
changeIcon();
if (((PeertubeActivity) getContext()).getFullscreen() == fullscreen.ON) {
((PeertubeActivity) getContext()).setFullscreen(fullscreen.OFF);
} else {
((PeertubeActivity) getContext()).setFullscreen(fullscreen.ON);
}
((PeertubeActivity) getContext()).change();
changeIcon();
});
}
@SuppressWarnings("unused")
public void setResolutionVal(String resolutionVal) {
this.resolutionVal = resolutionVal;
if (resolution != null)

View File

@ -56,11 +56,13 @@ import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.text.style.URLSpan;
import android.util.DisplayMetrics;
import android.util.Log;
@ -82,6 +84,7 @@ import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
@ -89,6 +92,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.appcompat.widget.SwitchCompat;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.app.NotificationCompat;
@ -262,6 +266,8 @@ public class Helper {
public static final String REDIRECT_CONTENT = "urn:ietf:wg:oauth:2.0:oob";
public static final String REDIRECT_CONTENT_WEB = "mastalab://backtomastalab";
public static final int EXTERNAL_STORAGE_REQUEST_CODE = 84;
public static final int EXTERNAL_STORAGE_REQUEST_CODE_MEDIA_SAVE = 85;
public static final int EXTERNAL_STORAGE_REQUEST_CODE_MEDIA_SHARE = 86;
//Thekinrar's API: https://instances.social/api/doc/
public static final String THEKINRAR_SECRET_TOKEN = "jGj9gW3z9ptyIpB8CMGhAlTlslcemMV6AgoiImfw3vPP98birAJTHOWiu5ZWfCkLvcaLsFZw9e3Pb7TIwkbIyrj3z6S7r2oE6uy6EFHvls3YtapP8QKNZ980p9RfzTb4";
@ -1639,12 +1645,7 @@ public class Helper {
public static <K, V> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Object>() {
@SuppressWarnings("unchecked")
public int compare(Object o2, Object o1) {
return ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue());
}
});
Collections.sort(list, (Comparator<Object>) (o2, o1) -> ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue()));
Map<K, V> result = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : list) {
@ -1970,7 +1971,8 @@ public class Helper {
activity.startActivity(myIntent);
activity.finish(); //User is logged out to get a new token
} else {
Account.makeAccountNameEmoji(new WeakReference<>(activity), account);
makeEmojis(activity, username, account.getDisplayNameSpan(), account.getEmojis());
username.setText(String.format("@%s", account.getUsername() + "@" + account.getInstance()));
displayedName.setText(account.getDisplayNameSpan(), TextView.BufferType.SPANNABLE);
loadGiF(activity, account, profilePicture);
@ -2078,7 +2080,9 @@ public class Helper {
*/
public static SpannableString clickableElementsDescription(final Context context, String fullContent) {
if (fullContent == null) {
return new SpannableString("");
}
SpannableString spannableString;
SpannableString spannableStringT = new SpannableString(fullContent);
Pattern aLink = Pattern.compile("(<\\s?a\\s?href=\"https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[/\\w._-]*)\"\\s?[^.]*<\\s?/\\s?a\\s?>)");
@ -2654,7 +2658,8 @@ public class Helper {
public static List<String> restoreArrayFromString(String serializedArray) {
Gson gson = new Gson();
try {
Type listType = new TypeToken<ArrayList<String>>() {}.getType();
Type listType = new TypeToken<ArrayList<String>>() {
}.getType();
return gson.fromJson(serializedArray, listType);
} catch (Exception e) {
return null;
@ -4200,12 +4205,12 @@ public class Helper {
fw.append(',');
fw.append("COMMENT");
fw.append('\n');
Iterator it = domainBlocked.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = domainBlocked.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
fw.append((String) pair.getKey());
Map.Entry<String, String> pair = it.next();
fw.append(pair.getKey());
fw.append(',');
fw.append((String) pair.getValue());
fw.append(pair.getValue());
fw.append('\n');
it.remove();
}
@ -4254,16 +4259,16 @@ public class Helper {
linearLayout_main.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
linearLayout_main.setOrientation(LinearLayout.VERTICAL);
Iterator it = instances.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = instances.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Map.Entry<String, String> pair = it.next();
View item = inflater.inflate(R.layout.muted_instance_popup, new LinearLayout(context), false);
CheckBox checkBox = item.findViewById(R.id.popup_domain);
checkBox.setText(pair.getKey().toString().trim());
checkBox.setText(pair.getKey().trim());
item.findViewById(R.id.popup_comment).setVisibility(View.GONE);
if (pair.getValue() != null) {
TextView textView = item.findViewById(R.id.comment_text);
textView.setText(pair.getValue().toString());
textView.setText(pair.getValue());
textView.setVisibility(View.VISIBLE);
}
linearLayout_main.addView(item);
@ -4284,15 +4289,15 @@ public class Helper {
if (domainBlocked.size() > 0) {
new Thread() {
public void run() {
Iterator it1 = domainBlocked.entrySet().iterator();
Iterator<Map.Entry<String, String>> it1 = domainBlocked.entrySet().iterator();
while (it1.hasNext()) {
Map.Entry pair = (Map.Entry) it1.next();
Map.Entry<String, String> pair = it1.next();
try {
sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
new PostActionAsyncTask(context, API.StatusAction.BLOCK_DOMAIN, pair.getKey().toString().trim(), ((MutedInstanceActivity) context)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new PostActionAsyncTask(context, API.StatusAction.BLOCK_DOMAIN, pair.getKey().trim(), ((MutedInstanceActivity) context)).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
it1.remove();
}
}
@ -4399,6 +4404,62 @@ public class Helper {
return null;
}
public static void makeEmojis(Context context, View customTextView, SpannableString contentSpan, List<Emojis> emojis) {
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean disableAnimatedEmoji = sharedpreferences.getBoolean(Helper.SET_DISABLE_ANIMATED_EMOJI, false);
if (emojis != null && emojis.size() > 0) {
for (final Emojis emoji : emojis) {
Glide.with(context)
.asDrawable()
.load(disableAnimatedEmoji ? emoji.getStatic_url() : emoji.getUrl())
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (contentSpan != null && contentSpan.toString().contains(targetedEmoji)) {
//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) {
ImageSpan imageSpan;
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);
if (customTextView instanceof CustomTextView) {
((CustomTextView) customTextView).setText(contentSpan, TextView.BufferType.SPANNABLE);
} else if (customTextView instanceof RadioButton) {
((RadioButton) customTextView).setText(contentSpan, TextView.BufferType.SPANNABLE);
} else if (customTextView instanceof CheckBox) {
((CheckBox) customTextView).setText(contentSpan, TextView.BufferType.SPANNABLE);
} else if (customTextView instanceof AppCompatTextView) {
((AppCompatTextView) customTextView).setText(contentSpan, TextView.BufferType.SPANNABLE);
} else if (customTextView instanceof TextView) {
((TextView) customTextView).setText(contentSpan, TextView.BufferType.SPANNABLE);
}
} catch (Exception ignored) {
}
}
}
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
}
}
//Event Type
public enum EventStreaming {
UPDATE,
@ -4407,6 +4468,7 @@ public class Helper {
NONE
}
public enum NotifType {
FOLLLOW,
MENTION,
@ -4418,7 +4480,6 @@ public class Helper {
TOOT
}
public static class CacheTask extends AsyncTask<Void, Void, Void> {
private float cacheSize;
private WeakReference<Context> contextReference;
@ -4505,4 +4566,6 @@ public class Helper {
.show();
}
}
}

View File

@ -14,7 +14,6 @@ import android.widget.TextView;
//https://stackoverflow.com/a/20435892
public class LongClickLinkMovementMethod extends LinkMovementMethod {
private static int LONG_CLICK_TIME = 1000;
private static LongClickLinkMovementMethod sInstance;
private Handler mLongClickHandler;
private boolean mIsLongPressed = false;
@ -68,13 +67,11 @@ public class LongClickLinkMovementMethod extends LinkMovementMethod {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
mLongClickHandler.postDelayed(new Runnable() {
@Override
public void run() {
link[0].onLongClick(widget);
mIsLongPressed = true;
widget.invalidate();
}
int LONG_CLICK_TIME = 1000;
mLongClickHandler.postDelayed(() -> {
link[0].onLongClick(widget);
mIsLongPressed = true;
widget.invalidate();
}, LONG_CLICK_TIME);
}
return true;

View File

@ -5,6 +5,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.os.Build;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.KeyEvent;
@ -14,7 +15,6 @@ import android.view.inputmethod.InputConnection;
import androidx.annotation.CallSuper;
import androidx.annotation.DimenRes;
import androidx.annotation.Px;
import androidx.core.os.BuildCompat;
import androidx.core.view.inputmethod.EditorInfoCompat;
import androidx.core.view.inputmethod.InputConnectionCompat;
import androidx.core.view.inputmethod.InputContentInfoCompat;
@ -39,7 +39,7 @@ public class MastalabAutoCompleteTextView extends androidx.appcompat.widget.AppC
int flags, Bundle opts) {
// read and display inputContentInfo asynchronously
if (BuildCompat.isAtLeastNMR1() && (flags &
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1 && (flags &
InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
try {
inputContentInfo.requestPermission();
@ -118,10 +118,12 @@ public class MastalabAutoCompleteTextView extends androidx.appcompat.widget.AppC
this.keyBoardInputCallbackListener = keyBoardInputCallbackListener;
}
@SuppressWarnings("unused")
public String[] getImgTypeString() {
return imgTypeString;
}
@SuppressWarnings("unused")
public void setImgTypeString(String[] imgTypeString) {
this.imgTypeString = imgTypeString;
}

View File

@ -2,7 +2,6 @@ package app.fedilab.android.helper;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@ -48,7 +47,8 @@ public class MenuFloating extends com.oguzdev.circularfloatingactionmenu.library
/**
* Attaches it to the content view with specified LayoutParams.
*
* @param layoutParams
* @param view View
* @param layoutParams ViewGroup.LayoutParams
*/
public void attach(View view, ViewGroup.LayoutParams layoutParams) {
if (this.getParent() != null)
@ -57,11 +57,7 @@ public class MenuFloating extends com.oguzdev.circularfloatingactionmenu.library
}
private void setBackgroundResource(Drawable drawable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(drawable);
} else {
setBackgroundDrawable(drawable);
}
setBackground(drawable);
}
/**
@ -85,7 +81,7 @@ public class MenuFloating extends com.oguzdev.circularfloatingactionmenu.library
// Default MenuFloating settings
int size = activity.getResources().getDimensionPixelSize(R.dimen.action_button_size);
int margin = activity.getResources().getDimensionPixelSize(R.dimen.action_button_margin);
FloatingActionButton.LayoutParams layoutParams = new LayoutParams(size, size, Gravity.BOTTOM | Gravity.RIGHT);
FloatingActionButton.LayoutParams layoutParams = new LayoutParams(size, size, Gravity.BOTTOM | Gravity.END);
layoutParams.setMargins(margin, margin, margin, margin);
setLayoutParams(layoutParams);
setTheme(FloatingActionButton.THEME_LIGHT);
@ -112,9 +108,6 @@ public class MenuFloating extends com.oguzdev.circularfloatingactionmenu.library
return this;
}
public Builder setBackgroundDrawable(int drawableId) {
return setBackgroundDrawable(activity.getResources().getDrawable(drawableId));
}
public Builder setPosition(int position) {
this.position = position;

View File

@ -65,6 +65,7 @@ public class ScheduledBoostsSyncJob extends Job {
return jobId;
}
@SuppressWarnings("UnusedReturnValue")
public static int scheduleUpdate(Context context, int tootStoredId, long timestampScheduling) {
long startMs = (timestampScheduling - new Date().getTime());

View File

@ -0,0 +1,39 @@
package app.fedilab.android.services;
/* Copyright 2020 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.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class UpgradeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if( intent.getAction() != null && intent.getAction().compareTo(Intent.ACTION_MY_PACKAGE_REPLACED) == 0) {
Intent streamingServiceIntent = new Intent(context, LiveNotificationDelayedService.class);
streamingServiceIntent.putExtra("stop", true);
try {
context.startService(streamingServiceIntent);
} catch (Exception ignored) {}
streamingServiceIntent = new Intent(context, LiveNotificationService.class);
streamingServiceIntent.putExtra("stop", true);
try {
context.startService(streamingServiceIntent);
} catch (Exception ignored) {}
}
}
}

View File

@ -27,6 +27,7 @@
<TextView
android:id="@+id/media_description"
android:textIsSelectable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"

View File

@ -18,13 +18,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:labelFor="@+id/add_phrase"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/filter_keyword" />
@ -41,7 +42,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:singleLine="true" />
android:singleLine="true"
android:importantForAutofill="no" />
<TextView
android:layout_width="match_parent"
@ -151,8 +153,7 @@
android:id="@+id/filter_expire"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginLeft="30dp" />
android:layout_marginStart="30dp" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -69,6 +69,7 @@
<TextView
android:id="@+id/notification_account_username"
android:layout_width="wrap_content"
android:layout_marginStart="5dp"
android:layout_height="wrap_content" />
<TextView

View File

@ -555,11 +555,6 @@
</RelativeLayout>
<app.fedilab.android.webview.CustomWebview
android:id="@+id/status_cardview_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</FrameLayout>
<RelativeLayout

View File

@ -479,12 +479,6 @@
android:contentDescription="@string/play_video"
android:src="@drawable/ic_play_arrow" />
</RelativeLayout>
<app.fedilab.android.webview.CustomWebview
android:id="@+id/status_cardview_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</FrameLayout>
<RelativeLayout

View File

@ -431,11 +431,6 @@
android:src="@drawable/ic_play_arrow" />
</RelativeLayout>
<app.fedilab.android.webview.CustomWebview
android:id="@+id/status_cardview_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</FrameLayout>
<RelativeLayout

View File

@ -412,12 +412,6 @@
android:src="@drawable/ic_play_arrow" />
</RelativeLayout>
<app.fedilab.android.webview.CustomWebview
android:id="@+id/status_cardview_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</FrameLayout>
<RelativeLayout

View File

@ -39,6 +39,7 @@
</RelativeLayout>
<FrameLayout
android:id="@+id/main_media_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true">
@ -49,6 +50,12 @@
android:layout_height="match_parent"
android:visibility="gone" />
</FrameLayout>
<RelativeLayout
android:id="@+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:visibility="gone" />
<FrameLayout
android:id="@+id/media_picture_container"

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds/>
<changeImageTransform/>
</transitionSet>

File diff suppressed because it is too large Load Diff

View File

@ -61,67 +61,67 @@
<string name="translate">অনুবাদ</string>
<string name="please_wait">অনুগ্রহ করে, এই কাজের জন্য কয়েক সেকেন্ড অপেক্ষা করো।</string>
<!--- Menu -->
<string name="home_menu">Home</string>
<string name="local_menu">Local timeline</string>
<string name="global_menu">Federated timeline</string>
<string name="neutral_menu_title">Options</string>
<string name="favorites_menu">Favourites</string>
<string name="communication_menu_title">Communication</string>
<string name="muted_menu">Muted users</string>
<string name="blocked_menu">Blocked users</string>
<string name="notifications">Notifications</string>
<string name="follow_request">Follow requests</string>
<string name="settings">Settings</string>
<string name="delete_account_title">Delete an account</string>
<string name="delete_account_message" formatted="false">Delete the account %1$s from the application?</string>
<string name="send_email">Send an email</string>
<string name="click_to_change">Tap on the path to change it</string>
<string name="failed">Failed!</string>
<string name="scheduled_toots">Scheduled toots</string>
<string name="disclaimer_full">Information below may reflect the user\'s profile incompletely.</string>
<string name="insert_emoji">Insert emoji</string>
<string name="no_emoji">The app did not collect custom emojis for the moment.</string>
<string name="live_notif">Live notifications</string>
<string name="home_menu">মূল পাতা</string>
<string name="local_menu">স্থানীয় সময়রেখা</string>
<string name="global_menu">যুক্তবিশ্বের সময়রেখা</string>
<string name="neutral_menu_title">অপশন</string>
<string name="favorites_menu">পছন্দ</string>
<string name="communication_menu_title">যোগাযোগ</string>
<string name="muted_menu">নিঃশব্দকৃত ব্যবহারকারী</string>
<string name="blocked_menu">অবরুদ্ধ ব্যবহারকারী</string>
<string name="notifications">বিজ্ঞপ্তি</string>
<string name="follow_request">অনুসরণের অনুরোধ মানো</string>
<string name="settings">সেটিংস</string>
<string name="delete_account_title">অ্যাকাউন্ট মুছে ফেলো</string>
<string name="delete_account_message" formatted="false">%1$s অ্যাকাউন্টটি মুছে ফেলো অ্যাপ্লিকেশন থেকে?</string>
<string name="send_email">একটি ইমেইল পাঠাও</string>
<string name="click_to_change">এটি পরিবর্তন করার জন্য পথে ক্লিক করুন</string>
<string name="failed">ব্যর্থ!</string>
<string name="scheduled_toots">সময় নির্ধারিত টুটগুলি</string>
<string name="disclaimer_full">নিচের তথ্যগুলো ব্যবহারকারীর প্রোফাইলকে অসম্পূর্ণভাবে প্রতিবিম্বিত করতে পারে।</string>
<string name="insert_emoji">ইমোজি ঢোকাও</string>
<string name="no_emoji">অ্যাপটি এই মুহুর্তের জন্য কাস্টম ইমোজিগুলি সংগ্রহ করতে পারেনি।</string>
<string name="live_notif">লাইভ বিজ্ঞপ্তিগুলি</string>
<string name="logout_confirmation">Are you sure you want to logout?</string>
<string name="logout_account_confirmation">Are you sure you want to logout @%1$s@%2$s?</string>
<!-- Status -->
<string name="no_status">No toot to display</string>
<string name="no_status">প্রদর্শনের জন্য কোনো টুট নেই</string>
<string name="no_stories">No stories to display</string>
<string name="stories">Stories</string>
<string name="reblog_by">Boosted by %1$s</string>
<string name="favourite_add">Add this toot to your favourites?</string>
<string name="favourite_remove">Remove this toot from your favourites?</string>
<string name="reblog_add">Boost this toot?</string>
<string name="reblog_remove">Unboost this toot?</string>
<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>
<string name="more_action_4">Remove</string>
<string name="more_action_5">Copy</string>
<string name="more_action_6">Share</string>
<string name="more_action_7">Mention</string>
<string name="more_action_8">Timed mute</string>
<string name="more_action_9">Delete &amp; re-draft</string>
<string name="reblog_by">%1$s দ্বারা সমর্থিত</string>
<string name="favourite_add">এই টুটটি তোমার পছন্দগুলোর সাথে যুক্ত করবে?</string>
<string name="favourite_remove">তোমার পছন্দগুলো থেকে এই টুট সরাবে?</string>
<string name="reblog_add">এই টুটটি সমর্থন করবে?</string>
<string name="reblog_remove">এই টুটটি অসমর্থন করবে?</string>
<string name="pin_add">এই টুটটি পিন করবে?</string>
<string name="pin_remove">এই টুটটি আনপিন করবে?</string>
<string name="more_action_1">নিঃশব্দ</string>
<string name="more_action_2">অবরুদ্ধ</string>
<string name="more_action_3">নিন্দা</string>
<string name="more_action_4">সরাও</string>
<string name="more_action_5">অনুলিপি</string>
<string name="more_action_6">শেয়ার</string>
<string name="more_action_7">উল্লেখ</string>
<string name="more_action_8">নির্দিষ্ট সময়ের জন্য নিঃশব্দ</string>
<string name="more_action_9">মুছে &amp; পুনরায় খসড়া</string>
<string-array name="more_action_confirm">
<item>Mute this account?</item>
<item>Block this account?</item>
<item>Report this toot?</item>
<item>Block this domain?</item>
<item>এই অ্যাকাউন্ট নিঃশব্দ করবে?</item>
<item>এই অ্যাকাউন্ট অবরুদ্ধ করবে?</item>
<item>এই টুটটি নিন্দা করবে?</item>
<item>এই ডোমেইন অবরুদ্ধ করবে?</item>
<item>Unmute this account?</item>
<item>Unblock this account?</item>
</string-array>
<string-array name="action_notification">
<item>Notify</item>
<item>Silent</item>
<item>বিজ্ঞপ্তি দিবে</item>
<item>নিঃশব্দ থাকবে</item>
</string-array>
<string-array name="more_action_owner_confirm">
<item>Remove this toot?</item>
<item>এই টুটটি মুছে ফেলবে?</item>
<item>Delete &amp; re-draft this toot?</item>
</string-array>
<string name="bookmarks">Bookmarks</string>
<string name="bookmark_add">Add to bookmarks</string>
<string name="bookmarks">বুকমার্ক</string>
<string name="bookmark_add">বুকমার্কে যোগ করো</string>
<string name="bookmark_remove">Remove bookmark</string>
<string name="bookmarks_empty">No bookmarks to display</string>
<string name="status_bookmarked">Status has been added to bookmarks!</string>

View File

@ -872,7 +872,7 @@ Ara ja pots connectar-te al compte escrivint <b>%1$s</b> en el primer camp i fen
<string name="set_long_press_media_indication">Guarda els mèdia a mida completa pitjant les previsualitzacions durant un segon</string>
<string name="set_display_timeline_in_list_indication">Afegeix un botó el·líptic a dalt a la dreta per llistar totes les etiquetes/instàncies/llistes</string>
<string name="live_notif_indication">Mantenir connexió oberta a l\'API de streaming per a rebre notificacions m directe.</string>
<string name="set_enable_time_slot_indication">Dins el període definit, l\'app enviarà notificacions. Pots revertir (p. e. silenciar) aquest període amb el spinner adequat.</string>
<string name="set_enable_time_slot_indication">Dins el període definit, l\'app enviarà notificacions. Pots revertir (p. e. silenciar) aquest període amb l\'opció pertinent.</string>
<string name="set_display_fedilab_features_button_indication">Mostrar un botó de Fedilab sota la imatge de perfil. És una drecera per accedir a funcions de l\'app.</string>
<string name="set_quick_reply_indication">Permet de respondre directament dins les pissarres sota les infos d\'estat</string>
<string name="set_fit_preview_indication">Les previsualitzacions de les pissarres no es retallaran</string>

View File

@ -110,7 +110,7 @@
<item>このトゥートを報告しますか?</item>
<item>このドメインをブロックしますか?</item>
<item>このアカウントのミュートを解除しますか?</item>
<item>Unblock this account?</item>
<item>このアカウントのブロックを解除しますか?</item>
</string-array>
<string-array name="action_notification">
<item>通知</item>
@ -984,9 +984,9 @@
<string name="set_nitter">TwitterをNitterに置き換える</string>
<string name="set_nitter_indication">Nitterはプライバシーに重点を置いたオープンソースのTwitter代替フロントエンドです。</string>
<string name="set_nitter_host">カスタムホストを入力してください。空欄にするとnitter.netが使用されます。</string>
<string name="set_bibliogram">Replace Instagram with Bibliogram</string>
<string name="set_bibliogram_indication">Bibliogram is an open source alternative Instagram front-end focused on privacy.</string>
<string name="set_bibliogram_host">Enter your custom host or leave blank for using bibliogram.art</string>
<string name="set_bibliogram">InstagramをBibliogramに置き換える</string>
<string name="set_bibliogram_indication">Bibliogramはプライバシーを重視したオープンソースのInstagramの代替フロントエンドです。</string>
<string name="set_bibliogram_host">カスタムホストを入力してください。空欄にするとbibliogram.artが使用されます。</string>
<string name="set_hide_status_bar">通知バーからFedilabを非表示にする</string>
<string name="set_hide_status_bar_indication">ステータスバー上の通知を非表示にするには、目のアイコンボタンをタップして「ステータスバーに表示する」のチェックを外します</string>
<string name="set_live_type_indication">通知は30秒ごとに遅延が発生します。バッテリーの持ちが改善します。</string>
@ -1105,5 +1105,5 @@
<string name="no_announcements">お知らせはありません!</string>
<string name="add_reaction">リアクションを追加</string>
<string name="set_custom_tabs_indication">アプリ内でお気に入りのブラウザを使用します。リンクを外部アプリで開きたい場合はこのチェックを外してください。</string>
<string name="set_video_cache">Video cache in MB, zero means no cache.</string>
<string name="set_video_cache">MB単位での動画キャッシュ、0でキャッシュしません。</string>
</resources>

View File

@ -59,7 +59,7 @@
<string name="show_replies">Ssekned tiririt</string>
<string name="action_open_in_web">Ldi deg iminig</string>
<string name="translate">Suqel</string>
<string name="please_wait">Please, wait few seconds before making this action.</string>
<string name="please_wait">Ttxil, rǧu kra n tesenatin uqbel ad txedmeḍ tigawt-a.</string>
<!--- Menu -->
<string name="home_menu">Agegdan</string>
<string name="local_menu">Tasuddemt tadigant n yisallen</string>

View File

@ -82,12 +82,12 @@
<string name="insert_emoji">Emoji toevoegen</string>
<string name="no_emoji">De app heeft nog geen lokale emojis verzameld.</string>
<string name="live_notif">Livemeldingen</string>
<string name="logout_confirmation">Are you sure you want to logout?</string>
<string name="logout_confirmation">Weet je zeker dat je wilt uitloggen?</string>
<string name="logout_account_confirmation">Are you sure you want to logout @%1$s@%2$s?</string>
<!-- Status -->
<string name="no_status">Geen toot om weer te geven</string>
<string name="no_stories">No stories to display</string>
<string name="stories">Stories</string>
<string name="no_stories">Geen verhalen om te laten zien</string>
<string name="stories">Verhalen</string>
<string name="reblog_by">Geboost door %1$s</string>
<string name="favourite_add">Deze toot aan jouw favorieten toevoegen?</string>
<string name="favourite_remove">Deze toot uit jouw favorieten verwijderen?</string>
@ -110,7 +110,7 @@
<item>Toot rapporteren?</item>
<item>Dit domein blokkeren?</item>
<item>Dit account niet langer negeren?</item>
<item>Unblock this account?</item>
<item>Deze rekening deblokkeren?</item>
</string-array>
<string-array name="action_notification">
<item>Melden</item>
@ -219,7 +219,7 @@
<string name="notif_reblog">boostte jouw toot</string>
<string name="notif_favourite">markeerde jouw toot als favoriet</string>
<string name="notif_follow">volgt jou nu</string>
<string name="notif_follow_request">asked to follow you</string>
<string name="notif_follow_request">gevraagd om u te volgen</string>
<plurals name="other_notifications">
<item quantity="one">en één andere melding</item>
<item quantity="other">en %d andere meldingen</item>
@ -238,7 +238,7 @@
<string name="pinned_toots">Vastgezet</string>
<!-- TOAST -->
<string name="client_error">Niet in staat om client-id te verkrijgen!</string>
<string name="connect_error">Unable to connect to instance domain!</string>
<string name="connect_error">Niet in staat om verbinding te maken met het instance-domein!</string>
<string name="no_internet">Geen internetverbinding!</string>
<string name="toast_block">Account is geblokkeerd!</string>
<string name="toast_unblock">Account is gedeblokkeerd!</string>
@ -361,7 +361,7 @@
<string name="action_sync">Synchroniseren</string>
<string name="action_filter">Filter</string>
<string name="owner_cached_toots">Jouw toots</string>
<string name="owner_cached_notifications">Your notifications</string>
<string name="owner_cached_notifications">Uw meldingen</string>
<string name="v_public">Openbaar</string>
<string name="v_unlisted">Minder openbaar</string>
<string name="v_private">Alleen volgers</string>
@ -374,8 +374,8 @@
<string name="data_backup_success">Er zijn %1$s nieuwe toots geïmporteerd</string>
<string name="data_backup_notification_success">%1$s new notifications have been imported</string>
<string-array name="filter_order">
<item>Dates descending</item>
<item>Dates ascending</item>
<item>Data aflopend</item>
<item>Data oplopend</item>
</string-array>
<string-array name="filter_select">
<item>Nee</item>
@ -430,7 +430,7 @@
<string name="action_lists_delete">Lijst verwijderen</string>
<string name="action_lists_update">Lijst bewerken</string>
<string name="action_lists_title_placeholder">Naam nieuwe lijst</string>
<string name="action_lists_add_user">The account was added to the list!</string>
<string name="action_lists_add_user">Het account is aan de lijst toegevoegd!</string>
<string name="action_lists_empty">You don\'t have any lists yet!</string>
<!-- Migration -->
<string name="account_moved_to">%1$s is naar %2$s verhuisd</string>
@ -1115,10 +1115,10 @@ Je kunt beginnen met typen en er zullen namen gesuggereerd worden.\n\n
<string name="story_indication">Upload a media, it will be automatically added to your Pixelfed story.</string>
<string name="added_to_story">Media successfully added to your story!</string>
<string name="action_disabled">Action disabled</string>
<string name="action_unfollow">Unfollow</string>
<string name="action_unfollow">Ontvouw</string>
<string name="error_destination_path">Something went wrong, please check your download directory in settings.</string>
<string name="action_announcements">Announcements</string>
<string name="no_announcements">No announcements!</string>
<string name="action_announcements">Aankondigingen</string>
<string name="no_announcements">Geen mededelingen!</string>
<string name="add_reaction">Add a 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_video_cache">Video cache in MB, zero means no cache.</string>

View File

@ -928,7 +928,7 @@ Yandex 有適當的隱私權政策可以在這裡找到https://yandex.ru/l
<string name="first_notification_date">第一個通知日期</string>
<string name="last_notification_date">最後通知日期</string>
<string name="frequency">頻率</string>
<string name="toot_per_day">每日狀態數</string>
<string name="toot_per_day">%s 每日狀態數</string>
<string name="notification_per_day">每天 %s 個通知</string>
<string name="date_range">日期範圍</string>
<string name="action_groups">群組</string>

View File

@ -1,4 +1,4 @@
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
<attr name="cardviewColor" type="color" />
<attr name="iconColor" type="color" />
@ -24,6 +24,10 @@
<item name="android:popupMenuStyle">@style/Fedilab.PopupMenu.Light</item>
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="popupWindowStyle">@style/Cyanea.PopupMenu.Light</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:ignore="NewApi">@transition/anim</item>
</style>
<style name="Cyanea.PopupMenu.Light" parent="@style/Widget.AppCompat.PopupMenu">
<item name="android:popupBackground">@color/cyanea_primary_dark_reference</item>
@ -41,6 +45,10 @@
<item name="linkColor">@color/light_link_toot</item>
<item name="android:popupMenuStyle">@style/Fedilab.PopupMenu.Light</item>
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:ignore="NewApi">@transition/anim</item>
</style>
<!-- BLACK theme -->
<style name="AppThemeBlack" parent="Theme.Cyanea.Dark">
@ -56,6 +64,10 @@
<item name="android:popupMenuStyle">@style/Fedilab.PopupMenu.Dark</item>
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="popupWindowStyle">@style/Cyanea.PopupMenu.black</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:ignore="NewApi">@transition/anim</item>
</style>
<style name="Cyanea.PopupMenu.black" parent="@style/Widget.AppCompat.PopupMenu">
<item name="android:popupBackground">@color/cyanea_primary_dark_reference</item>
@ -73,6 +85,10 @@
<item name="linkColor">@color/black_link_toot</item>
<item name="android:popupMenuStyle">@style/Fedilab.PopupMenu.Dark</item>
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:ignore="NewApi">@transition/anim</item>
</style>
@ -90,6 +106,10 @@
<item name="android:popupMenuStyle">@style/Fedilab.PopupMenu.Dark</item>
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="popupWindowStyle">@style/Cyanea.PopupMenu.Dark</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:ignore="NewApi">@transition/anim</item>
</style>
<style name="Cyanea.PopupMenu.Dark" parent="@style/Widget.AppCompat.PopupMenu">
<item name="android:popupBackground">@color/cyanea_primary_dark_reference</item>
@ -107,6 +127,10 @@
<item name="linkColor">@color/dark_link_toot</item>
<item name="android:popupMenuStyle">@style/Fedilab.PopupMenu.Dark</item>
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:ignore="NewApi">@transition/anim</item>
</style>
@ -153,6 +177,12 @@
<item name="linkColor">@color/light_link_toot</item>
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:ignore="NewApi">@transition/anim</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">shortEdges</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="TransparentDark" parent="Theme.Cyanea.Dark">
@ -163,6 +193,12 @@
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:ignore="NewApi">@transition/anim</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">shortEdges</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="TransparentBlack" parent="Theme.Cyanea.Dark">
@ -174,6 +210,12 @@
<item name="linkColor">@color/black_link_toot</item>
<item name="android:itemBackground">@drawable/menu_selector</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:ignore="NewApi">@transition/anim</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">shortEdges</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="Fedilab.PopupMenu.Light" parent="Cyanea.PopupMenu.Light">

View File

@ -0,0 +1,16 @@
It supports:
- Mastodon, Pleroma, Pixelfed, Peertube, GNU Social, Friendica.
The app has advanced features (especially for Pleroma and Mastodon):
- Multi-accounts support
- Schedule messages from the device
- Schedule boosts
- Bookmark messages
- Follow and interact with remote instances
- Timed mute accounts
- Cross-account actions with a long press
- Translation feature
- Art timelines
- Video timelines

View File

@ -0,0 +1 @@
Fedilab is a multifunctional Android client to access the distributed Fediverse, consisting of micro blogging, photo sharing and video hosting.

View File

@ -0,0 +1,4 @@
Fixed:
- Issue with not clickable URLs
- Custom emoji in polls not displayed
- Auto-split toots feature

View File

@ -0,0 +1,18 @@
Added:
- Select text for media description
changed:
- Increase media description length to 1500 chars
- More details about accounts in notifications
- Media management in timelines
- Allow cross-account replies on followed instances
Fixed:
- Remove extra spaces at the bottom of messages
- Some issue with custom emoji
- Fix issue with "Your toots/notifications"
- Fix issue with CW and Pixelfed
- Fix some media not loaded in profiles
- Scheduled toots from server side have an incorrect date
- Incorrect feeds when checking instance admin account
- Some crashes

View File

@ -0,0 +1,19 @@
Added:
- Select text for media description
changed:
- Increase media description length to 1500 chars
- More details about accounts in notifications
- Media management in timelines
- Allow cross-account replies on followed instances
Fixed:
- Crash when adding media
- Remove extra spaces at the bottom of messages
- Some issue with custom emoji
- Fix issue with "Your toots/notifications"
- Fix issue with CW and Pixelfed
- Fix some media not loaded in profiles
- Scheduled toots from server side have an incorrect date
- Incorrect feeds when checking instance admin account
- Some crashes