Compare commits

...

71 commits

Author SHA1 Message Date
a06fb1657d
Add support for Nyastodon-style emoji reactions 2023-02-08 21:13:16 +09:00
Thomas
97ba87aba7 Release 3.17.0 2023-02-05 18:59:05 +01:00
Thomas
7603db8ce0 Missing media description for previews 2023-02-05 18:53:05 +01:00
Thomas
663e33466d Merge remote-tracking branch 'origin/develop' into develop 2023-02-05 16:50:54 +01:00
Thomas
cbed3f1ae1 Fix media cannot be downloaded or shared (Android 10) 2023-02-05 16:50:08 +01:00
Poesty Li
8bdaf8d410
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1077 of 1077 strings)

Co-authored-by: Poesty Li <poesty7450@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/zh_Hans/
Translation: Fedilab/Strings
2023-02-05 11:55:29 +01:00
Thomas
6595af849e Fix forward tags in replies 2023-02-05 11:55:19 +01:00
Thomas
4111d00025 Group mentions at the top 2023-02-05 11:00:34 +01:00
Thomas
f75d8258f4 Fix button sizes not updated 2023-02-04 17:53:25 +01:00
Thomas
7a11e156a5 Merge remote-tracking branch 'origin/develop' into develop 2023-02-04 11:23:56 +01:00
Thomas
8977990fea Cache messages 2023-02-04 11:23:31 +01:00
Poesty Li
bc44a9be15
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1077 of 1077 strings)

Co-authored-by: Poesty Li <poesty7450@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/zh_Hans/
Translation: Fedilab/Strings
2023-02-03 18:36:46 +01:00
Eduardo
88d9bf4629
Translated using Weblate (Portuguese)
Currently translated at 89.8% (968 of 1077 strings)

Co-authored-by: Eduardo <edu200399lim@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/pt/
Translation: Fedilab/Strings
2023-02-03 18:36:45 +01:00
josé m
65706e727c
Translated using Weblate (Galician)
Currently translated at 100.0% (1077 of 1077 strings)

Co-authored-by: josé m <correoxm@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/gl/
Translation: Fedilab/Strings
2023-02-03 18:36:45 +01:00
Thomas
b64fd393e9 Fix worker 2023-02-03 17:42:50 +01:00
Thomas
2b300ceae4 record cache work 2023-02-03 17:23:33 +01:00
Thomas
6e4bb95dda More deep link detection 2023-02-02 18:03:09 +01:00
Thomas
440ad039be Fix issues 2023-02-02 17:44:16 +01:00
Thomas
4c89a855c6 Some fixes 2023-02-02 14:18:52 +01:00
Thomas
0ca53b75d2 Fix crashes when replying 2023-02-02 14:03:13 +01:00
Oğuz Ersen
91eb579e2c
Translated using Weblate (Turkish)
Currently translated at 100.0% (1077 of 1077 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/tr/
Translation: Fedilab/Strings
2023-02-02 11:40:27 +01:00
Ajeje Brazorf
1aad4f07df
Translated using Weblate (Sardinian)
Currently translated at 99.2% (1069 of 1077 strings)

Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/sc/
Translation: Fedilab/Strings
2023-02-02 11:40:26 +01:00
claleb
335842c8a2
Translated using Weblate (German)
Currently translated at 100.0% (1077 of 1077 strings)

Co-authored-by: claleb <weblate@claleb.de>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/de/
Translation: Fedilab/Strings
2023-02-02 11:40:26 +01:00
Lukáš Jelínek
c10d078add
Translated using Weblate (Czech)
Currently translated at 99.9% (1076 of 1077 strings)

Co-authored-by: Lukáš Jelínek <devel@aiken.cz>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/cs/
Translation: Fedilab/Strings
2023-02-02 11:40:26 +01:00
Poesty Li
67cdceb90e
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1075 of 1075 strings)

Co-authored-by: Poesty Li <poesty7450@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/zh_Hans/
Translation: Fedilab/Strings
2023-02-01 19:01:52 +01:00
Thomas
ddbd3f8684 Release 3.16.4 2023-02-01 19:00:38 +01:00
Thomas
4ae8011eff Auto fetch messages 2023-02-01 18:52:55 +01:00
Thomas
d61dbb0315 Auto fetch messages 2023-02-01 17:56:20 +01:00
Thomas
3c13bf7199 Merge remote-tracking branch 'origin/develop' into develop 2023-02-01 15:16:42 +01:00
Thomas
b19cd7c0c9 Add settings 2023-02-01 15:14:37 +01:00
Dan
17438f6f5c
Translated using Weblate (Ukrainian)
Currently translated at 62.6% (668 of 1067 strings)

Co-authored-by: Dan <denqwerta@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/uk/
Translation: Fedilab/Strings
2023-02-01 13:54:31 +01:00
Oğuz Ersen
f05ab805ff
Translated using Weblate (Turkish)
Currently translated at 100.0% (1067 of 1067 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/tr/
Translation: Fedilab/Strings
2023-02-01 13:54:31 +01:00
Lukáš Jelínek
212cd9d54e
Translated using Weblate (Czech)
Currently translated at 99.9% (1066 of 1067 strings)

Co-authored-by: Lukáš Jelínek <devel@aiken.cz>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/cs/
Translation: Fedilab/Strings
2023-02-01 13:54:31 +01:00
Dan
f4437b6955
Translated using Weblate (Ukrainian)
Currently translated at 15.4% (13 of 84 strings)

Co-authored-by: Dan <denqwerta@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/description/uk/
Translation: Fedilab/description
2023-02-01 13:54:07 +01:00
Thomas
e8950f03ae Fetch home in background to cache messages 2023-02-01 12:33:43 +01:00
0xd9a
0e16cb1730 update schedule dialog 2023-02-01 06:41:33 +05:30
Dan
67cfa9cf01
Translated using Weblate (Ukrainian)
Currently translated at 11.9% (10 of 84 strings)

Co-authored-by: Dan <denqwerta@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/description/uk/
Translation: Fedilab/description
2023-02-01 00:55:43 +01:00
Ajeje Brazorf
7bdf2aa1ad
Translated using Weblate (Sardinian)
Currently translated at 99.2% (1059 of 1067 strings)

Translated using Weblate (Sardinian)

Currently translated at 99.2% (1058 of 1066 strings)

Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/sc/
Translation: Fedilab/Strings
2023-01-31 18:36:50 +01:00
Thomas
44676707f0 Automatically switch to tabs when searching 2023-01-31 18:36:37 +01:00
Thomas
d9e92b13b6 avoid a crash 2023-01-31 18:16:01 +01:00
Thomas
833ea5d0c3 Fix 103 response code for OG 2023-01-31 18:11:22 +01:00
Thomas
04c5f32c53 Merge remote-tracking branch 'origin/develop' into develop 2023-01-31 17:21:15 +01:00
Thomas
93d5995ec1 remove title for media description #771 2023-01-31 17:21:01 +01:00
Eduardo
d679d1fb73
Translated using Weblate (Portuguese)
Currently translated at 90.2% (962 of 1066 strings)

Co-authored-by: Eduardo <edu200399lim@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/pt/
Translation: Fedilab/Strings
2023-01-31 16:41:31 +01:00
Thomas
f8b0ed7f18 Fix some crashes 2023-01-31 15:00:40 +01:00
Poesty Li
d83f787956
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (1066 of 1066 strings)

Co-authored-by: Poesty Li <poesty7450@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/zh_Hans/
Translation: Fedilab/Strings
2023-01-31 02:36:27 +01:00
Eduardo
b958e24dc9
Translated using Weblate (Portuguese)
Currently translated at 90.0% (960 of 1066 strings)

Co-authored-by: Eduardo <edu200399lim@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/pt/
Translation: Fedilab/Strings
2023-01-31 02:36:27 +01:00
josé m
e61de6eb1d
Translated using Weblate (Galician)
Currently translated at 100.0% (1066 of 1066 strings)

Co-authored-by: josé m <correoxm@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/gl/
Translation: Fedilab/Strings
2023-01-31 02:36:27 +01:00
Lukáš Jelínek
b89212a4f6
Translated using Weblate (Czech)
Currently translated at 99.9% (1065 of 1066 strings)

Co-authored-by: Lukáš Jelínek <devel@aiken.cz>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/cs/
Translation: Fedilab/Strings
2023-01-31 02:36:26 +01:00
Thomas
c37d8ab34f Release 3.16.3 2023-01-30 18:18:23 +01:00
Thomas
ca5b37edfe Fix dynamic colors 2023-01-30 18:15:12 +01:00
Thomas
408e51c0a6 Peertube 2FA support 2023-01-30 17:02:24 +01:00
Thomas
9fd834eb44 Merge remote-tracking branch 'origin/develop' into develop 2023-01-29 17:56:48 +01:00
Thomas
58f3d01c87 Release 3.16.2 2023-01-29 17:56:40 +01:00
Thomas
de46b38991 Open profiles only trough avatars 2023-01-29 17:17:57 +01:00
Thomas
926caf2f3f Player layout only for peertube 2023-01-29 16:06:08 +01:00
Poesty Li
8bbe897483
Translated using Weblate (Chinese (Simplified))
Currently translated at 62.2% (664 of 1066 strings)

Co-authored-by: Poesty Li <poesty7450@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/zh_Hans/
Translation: Fedilab/Strings
2023-01-29 08:08:34 +01:00
Oğuz Ersen
59ba9134e7
Translated using Weblate (Turkish)
Currently translated at 100.0% (1066 of 1066 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/tr/
Translation: Fedilab/Strings
2023-01-29 08:08:34 +01:00
claleb
83e68742be
Translated using Weblate (German)
Currently translated at 100.0% (1066 of 1066 strings)

Co-authored-by: claleb <weblate@claleb.de>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/de/
Translation: Fedilab/Strings
2023-01-29 08:08:34 +01:00
Thomas
9a38da9475 fix release note 2023-01-28 18:00:02 +01:00
Thomas
c8d0931d8e Release 3.16.1 2023-01-28 17:55:55 +01:00
Thomas
4d643ae28f Fix a crash for notification with Peertube 2023-01-28 17:46:46 +01:00
Thomas
33b8dd36e4 Add support to edit media 2023-01-28 16:47:56 +01:00
Thomas
25d3803e69 Fix peertube support 2023-01-28 16:26:55 +01:00
Thomas
7b08bf77bf Merge remote-tracking branch 'origin/develop' into develop 2023-01-28 15:49:37 +01:00
Thomas
3f1af73b0e avoid a crash with old peertube instances 2023-01-28 15:49:28 +01:00
Oğuz Ersen
a22dd088a5
Translated using Weblate (Turkish)
Currently translated at 100.0% (1064 of 1064 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/tr/
Translation: Fedilab/Strings
2023-01-28 01:56:17 +01:00
josé m
e88c53d950
Translated using Weblate (Galician)
Currently translated at 100.0% (1064 of 1064 strings)

Co-authored-by: josé m <correoxm@disroot.org>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/gl/
Translation: Fedilab/Strings
2023-01-28 01:56:17 +01:00
claleb
a160d3e212
Translated using Weblate (German)
Currently translated at 100.0% (1064 of 1064 strings)

Co-authored-by: claleb <weblate@claleb.de>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/de/
Translation: Fedilab/Strings
2023-01-28 01:56:16 +01:00
Lukáš Jelínek
dacfba7043
Translated using Weblate (Czech)
Currently translated at 99.9% (1063 of 1064 strings)

Co-authored-by: Lukáš Jelínek <devel@aiken.cz>
Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/cs/
Translation: Fedilab/Strings
2023-01-28 01:56:16 +01:00
Thomas
9683fee1e6 Release 3.16.0 2023-01-27 18:35:27 +01:00
141 changed files with 2495 additions and 1025 deletions

View file

@ -13,8 +13,8 @@ android {
defaultConfig {
minSdk 21
targetSdk 33
versionCode 471
versionName "3.15.2"
versionCode 477
versionName "3.17.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
flavorDimensions "default"

View file

@ -63,6 +63,8 @@ public class BasePeertubeActivity extends BaseBarActivity {
binding = ActivityPeertubeBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
binding.minController.castPlay.setOnClickListener(v -> {
binding.minController.castLoader.setVisibility(View.VISIBLE);
if (PeertubeBaseMainActivity.chromeCast != null) {
@ -98,7 +100,7 @@ public class BasePeertubeActivity extends BaseBarActivity {
if (item.getItemId() == R.id.action_cast) {
if (PeertubeBaseMainActivity.chromeCasts != null && PeertubeBaseMainActivity.chromeCasts.size() > 0) {
String[] chromecast_choice = new String[PeertubeBaseMainActivity.chromeCasts.size()];
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(this);
alt_bld.setTitle(R.string.chromecast_choice);
int i = 0;
for (ChromeCast cc : PeertubeBaseMainActivity.chromeCasts) {

View file

@ -1,4 +1,34 @@
[
{
"version": "3.17.0",
"code": "477",
"note": "Added:\n- Peertube 2FA support\n- Cache home in background (default disabled -> New settings category and per account) / change frequency\n- Auto-fetch missing messages for the Home (default disabled -> in Settings - Timelines)\n- Automatically switch between tabs when searching\n- More deep links detection\n- Allow to group mentions at the top (default: disabled)\n\n\nFixed:\n- Dynamic color for Android 12+\n- Missing media description for previews\n- Fix a crash when replying\n- Fix button size not changed\n- Forward tags in replies\n- Media cannot be downloaded or shared with Android 10\n- Some crashes"
},
{
"version": "3.16.4",
"code": "476",
"note": "Added:\n- Cache home in background (default disabled -> New settings category and per account) / change frequency\n- Auto-fetch missing messages for the Home (default disabled -> in Settings - Timelines)\n- Automatically switch between tabs when searching\n\nFixed:\n- Some crashes"
},
{
"version": "3.16.3",
"code": "475",
"note": "Added:\n- Peertube 2FA support\n\nFixed:\n- Dynamic color for Android 12+"
},
{
"version": "3.16.2",
"code": "474",
"note": "Added:\n- Peertube support\n- Compose shortcut (long press launcher)\n- Long press compose button to write with another account\n- Edit description and focus for media (for the next Mastodon release)\n\nChanged:\n- Cross actions with two accounts display a dialog\n- Order & compact og values when sharing > title - url - content\n- Tap on top message (user info) open threads\n\nFixed:\n- Text cleared when adding a media\n- Fix Maths not working with quotes\n- Fix crashes"
},
{
"version": "3.16.1",
"code": "473",
"note": "Changed:\n- Edit description and focus for media (for the next Mastodon release)\n\nChanged:\n- Peertube: remove role support to avoid crashes with older instances\n\nFixed:\n- Fix some crashes"
},
{
"version": "3.16.0",
"code": "472",
"note": "Changed:\n- Peertube support\n- Compose shortcut\n- Long press compose button to write with another account\n\nChanged:\n- Cross actions with two accounts display a dialog\n- Order & compact og values when sharing > title - url - content\n\nFixed:\n- Text cleared when adding a media\n- Fix crashes"
},
{
"version": "3.15.2",
"code": "471",

View file

@ -22,6 +22,7 @@ import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_INSTANCE;
import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_SOFTWARE;
import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_TOKEN;
import static app.fedilab.android.mastodon.helper.Helper.displayReleaseNotesIfNeeded;
import static app.fedilab.android.mastodon.helper.ThemeHelper.fetchAccentColor;
import static app.fedilab.android.mastodon.ui.drawer.StatusAdapter.sendAction;
import android.Manifest;
@ -35,6 +36,7 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.MatrixCursor;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
@ -83,9 +85,13 @@ import androidx.navigation.ui.NavigationUI;
import androidx.preference.PreferenceManager;
import androidx.viewpager.widget.ViewPager;
import com.avatarfirst.avatargenlib.AvatarGenerator;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.FutureTarget;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
@ -459,16 +465,42 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
}
} else if (account.peertube_account != null) {
acct = account.peertube_account.getAcct();
url = account.peertube_account.getAvatar().getPath();
if (url != null && url.startsWith("/")) {
url = "https://" + account.instance + account.peertube_account.getAvatar().getPath();
if (account.peertube_account.getAvatar() != null) {
url = account.peertube_account.getAvatar().getPath();
if (url != null && url.startsWith("/")) {
url = "https://" + account.instance + account.peertube_account.getAvatar().getPath();
}
}
}
final MenuItem item = currentSubmenu.add("@" + acct);
item.setIcon(R.drawable.ic_person);
if (!activity.isDestroyed() && !activity.isFinishing() && url != null) {
if (url.contains(".gif")) {
if (url.trim().isEmpty()) {
BitmapDrawable avatar = new AvatarGenerator.AvatarBuilder(activity)
.setLabel(account.peertube_account.getAcct())
.setAvatarSize(120)
.setTextSize(30)
.toSquare()
.setBackgroundColor(fetchAccentColor(activity))
.build();
Glide.with(activity)
.asDrawable()
.load(avatar)
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, Transition<? super Drawable> transition) {
item.setIcon(resource);
item.getIcon().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
} else if (url.contains(".gif")) {
Glide.with(activity)
.asGif()
.load(url)
@ -573,7 +605,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
popup.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_logout_account) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(activity);
alt_bld.setTitle(R.string.action_logout);
if (currentAccount.mastodon_account != null && currentAccount.instance != null) {
alt_bld.setMessage(activity.getString(R.string.logout_account_confirmation, currentAccount.mastodon_account.username, currentAccount.instance));
@ -666,9 +698,18 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
} else {
try {
BaseAccount account = new Account(activity).getUniqAccount(userIdIntent, instanceIntent);
if (account == null) {
return;
}
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
headerMenuOpen = false;
Toasty.info(activity, activity.getString(R.string.toast_account_changed, "@" + account.mastodon_account.acct + "@" + account.instance), Toasty.LENGTH_LONG).show();
String acct = "";
if (account.mastodon_account != null) {
acct = "@" + account.mastodon_account.username + "@" + account.instance;
} else if (account.peertube_account != null) {
acct = "@" + account.peertube_account.getUsername() + "@" + account.instance;
}
Toasty.info(activity, activity.getString(R.string.toast_account_changed, acct), Toasty.LENGTH_LONG).show();
BaseMainActivity.currentToken = account.token;
BaseMainActivity.currentUserID = account.user_id;
api = account.api;
@ -755,6 +796,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
Request request = new Request.Builder()
.url(potentialUrl)
.build();
String finalPotentialUrl = potentialUrl;
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
@ -831,6 +873,12 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
} catch (Exception e) {
e.printStackTrace();
}
} else if (response.code() == 103) {
activity.runOnUiThread(() -> {
Bundle b = new Bundle();
b.putString(Helper.ARG_SHARE_DESCRIPTION, finalPotentialUrl);
CrossActionHelper.doCrossShare(activity, b);
});
} else {
activity.runOnUiThread(() -> Toasty.warning(activity, activity.getString(R.string.toast_error), Toast.LENGTH_LONG).show());
}
@ -1529,7 +1577,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
itemShowDMs.setChecked(show_dms);
editor.apply();
} else if (itemId == R.id.action_filter) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(BaseMainActivity.this, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(BaseMainActivity.this);
LayoutInflater inflater = getLayoutInflater();
View dialogView = inflater.inflate(R.layout.popup_filter_regex, new LinearLayout(BaseMainActivity.this), false);
dialogBuilder.setView(dialogView);
@ -1763,9 +1811,9 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
* Allow to scroll to top for bottom navigation items
*/
private void scrollToTop() {
int position = binding.tabLayout.getSelectedTabPosition();
if (binding.viewPager.getAdapter() != null) {
Fragment fragment = (Fragment) binding.viewPager.getAdapter().instantiateItem(binding.viewPager, binding.tabLayout.getSelectedTabPosition());
Fragment fragment = (Fragment) binding.viewPager.getAdapter().instantiateItem(binding.viewPager, Math.max(position, 0));
if (fragment instanceof FragmentMastodonTimeline) {
FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
fragmentMastodonTimeline.scrollToTop();
@ -1850,7 +1898,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_logout) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(BaseMainActivity.this, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(BaseMainActivity.this);
alt_bld.setTitle(R.string.action_logout);
alt_bld.setMessage(getString(R.string.logout_account_confirmation, account.mastodon_account.username, account.instance));
alt_bld.setPositiveButton(R.string.action_logout, (dialog, id) -> {

View file

@ -27,8 +27,6 @@ import androidx.multidex.MultiDex;
import androidx.multidex.MultiDexApplication;
import androidx.preference.PreferenceManager;
import com.google.android.material.color.DynamicColors;
import net.gotev.uploadservice.UploadServiceConfig;
import net.gotev.uploadservice.observer.request.GlobalRequestObserver;
@ -54,15 +52,10 @@ public class MainApplication extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(MainApplication.this);
try {
webView = new WebView(this);
} catch (Exception ignored) {
}
boolean dynamicColor = sharedpreferences.getBoolean(getString(R.string.SET_DYNAMICCOLOR), false);
if (dynamicColor) {
DynamicColors.applyToActivitiesIfAvailable(this);
}
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Toasty.Config.getInstance().apply();

View file

@ -30,6 +30,7 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.PreferenceManager;
import com.google.android.material.color.DynamicColors;
import com.vanniktech.emoji.EmojiManager;
import com.vanniktech.emoji.one.EmojiOneProvider;
@ -53,6 +54,7 @@ public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
boolean patch_provider = true;
final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
@ -142,6 +144,10 @@ public class BaseActivity extends AppCompatActivity {
}
}
super.onCreate(savedInstanceState);
boolean dynamicColor = sharedpreferences.getBoolean(getString(R.string.SET_DYNAMICCOLOR), false);
if (dynamicColor) {
DynamicColors.applyToActivityIfAvailable(this);
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
ThemeHelper.adjustFontScale(this, getResources().getConfiguration());
}

View file

@ -1,153 +0,0 @@
package app.fedilab.android.mastodon.activities;
/* Copyright 2021 Thomas Schneider
*
* This file is a part of Fedilab
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.PreferenceManager;
import com.vanniktech.emoji.EmojiManager;
import com.vanniktech.emoji.one.EmojiOneProvider;
import org.conscrypt.Conscrypt;
import java.security.Security;
import app.fedilab.android.R;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.helper.ThemeHelper;
@SuppressLint("Registered")
public class BaseAlertDialogActivity extends AppCompatActivity {
static {
EmojiManager.install(new EmojiOneProvider());
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean patch_provider = true;
try {
patch_provider = sharedpreferences.getBoolean(Helper.SET_SECURITY_PROVIDER, true);
} catch (Exception ignored) {
}
if (patch_provider) {
try {
Security.insertProviderAt(Conscrypt.newProvider(), 1);
} catch (Exception ignored) {
}
}
String currentTheme = sharedpreferences.getString(getString(R.string.SET_THEME_BASE), getString(R.string.SET_DEFAULT_THEME));
//Default automatic switch
if (currentTheme.equals(getString(R.string.SET_DEFAULT_THEME))) {
int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
switch (currentNightMode) {
case Configuration.UI_MODE_NIGHT_NO:
String defaultLight = sharedpreferences.getString(getString(R.string.SET_THEME_DEFAULT_LIGHT), "LIGHT");
switch (defaultLight) {
case "LIGHT":
setTheme(R.style.AppThemeAlertDialog);
break;
case "SOLARIZED_LIGHT":
setTheme(R.style.SolarizedAlertDialog);
break;
}
break;
case Configuration.UI_MODE_NIGHT_YES:
String defaultDark = sharedpreferences.getString(getString(R.string.SET_THEME_DEFAULT_DARK), "DARK");
switch (defaultDark) {
case "DARK":
setTheme(R.style.AppThemeAlertDialog);
break;
case "SOLARIZED_DARK":
setTheme(R.style.SolarizedAlertDialog);
break;
case "BLACK":
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.BLACK);
setTheme(R.style.BlackAlertDialog);
break;
case "DRACULA":
setTheme(R.style.DraculaAlertDialog);
break;
}
break;
}
} else {
switch (currentTheme) {
case "LIGHT":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
setTheme(R.style.AppThemeAlertDialog);
break;
case "DARK":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.AppThemeAlertDialog);
break;
case "SOLARIZED_LIGHT":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
setTheme(R.style.SolarizedAlertDialog);
break;
case "SOLARIZED_DARK":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.SolarizedAlertDialog);
break;
case "BLACK":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.BLACK);
setTheme(R.style.BlackAlertDialog);
break;
case "DRACULA":
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
setTheme(R.style.DraculaAlertDialog);
break;
}
}
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
ThemeHelper.adjustFontScale(this, getResources().getConfiguration());
}
Helper.setLocale(this);
}
@Override
protected void attachBaseContext(Context newBase) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
final Configuration override = new Configuration(newBase.getResources().getConfiguration());
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(newBase);
override.fontScale = prefs.getFloat(newBase.getString(R.string.SET_FONT_SCALE), 1.1f);
applyOverrideConfiguration(override);
}
super.attachBaseContext(newBase);
}
}

View file

@ -30,6 +30,7 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.PreferenceManager;
import com.google.android.material.color.DynamicColors;
import com.vanniktech.emoji.EmojiManager;
import com.vanniktech.emoji.one.EmojiOneProvider;
@ -128,6 +129,10 @@ public class BaseBarActivity extends AppCompatActivity {
}
}
super.onCreate(savedInstanceState);
boolean dynamicColor = sharedpreferences.getBoolean(getString(R.string.SET_DYNAMICCOLOR), false);
if (dynamicColor) {
DynamicColors.applyToActivityIfAvailable(this);
}
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

View file

@ -1,59 +0,0 @@
package app.fedilab.android.mastodon.activities;
/* Copyright 2022 Thomas Schneider
*
* This file is a part of Fedilab
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.PreferenceManager;
import com.vanniktech.emoji.EmojiManager;
import com.vanniktech.emoji.one.EmojiOneProvider;
import org.conscrypt.Conscrypt;
import java.security.Security;
import app.fedilab.android.mastodon.helper.Helper;
@SuppressLint("Registered")
public class BaseFragmentActivity extends FragmentActivity {
static {
EmojiManager.install(new EmojiOneProvider());
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
boolean patch_provider = true;
try {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(this);
patch_provider = sharedpreferences.getBoolean(Helper.SET_SECURITY_PROVIDER, true);
} catch (Exception ignored) {
}
if (patch_provider) {
try {
Security.insertProviderAt(Conscrypt.newProvider(), 1);
} catch (Exception ignored) {
}
}
super.onCreate(savedInstanceState);
}
}

View file

@ -30,6 +30,7 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.PreferenceManager;
import com.google.android.material.color.DynamicColors;
import com.vanniktech.emoji.EmojiManager;
import com.vanniktech.emoji.one.EmojiOneProvider;
@ -128,6 +129,10 @@ public class BaseTransparentActivity extends AppCompatActivity {
}
}
super.onCreate(savedInstanceState);
boolean dynamicColor = sharedpreferences.getBoolean(getString(R.string.SET_DYNAMICCOLOR), false);
if (dynamicColor) {
DynamicColors.applyToActivityIfAvailable(this);
}
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

View file

@ -121,7 +121,7 @@ public class CacheActivity extends BaseBarActivity {
finish();
return true;
} else if (item.getItemId() == R.id.action_clear) {
AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(CacheActivity.this, Helper.dialogStyle());
AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(CacheActivity.this);
deleteConfirm.setTitle(getString(R.string.delete_cache));
deleteConfirm.setMessage(getString(R.string.delete_cache_message));
deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
@ -131,7 +131,7 @@ public class CacheActivity extends BaseBarActivity {
size = size / 1000000.0f;
}
binding.fileCacheSize.setText(String.format("%s %s", String.format(Locale.getDefault(), "%.2f", size), getString(R.string.cache_units)));
AlertDialog.Builder restartBuilder = new MaterialAlertDialogBuilder(CacheActivity.this, Helper.dialogStyle());
AlertDialog.Builder restartBuilder = new MaterialAlertDialogBuilder(CacheActivity.this);
restartBuilder.setMessage(getString(R.string.restart_the_app));
restartBuilder.setNegativeButton(R.string.no, (dialogRestart, whichRestart) -> {
recreate();

View file

@ -215,7 +215,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
}
if (canBeSent(statusDraft)) {
if (promptSaveDraft) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(ComposeActivity.this, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(ComposeActivity.this);
alt_bld.setMessage(R.string.save_draft);
alt_bld.setPositiveButton(R.string.save, (dialog, id) -> {
dialog.dismiss();
@ -316,7 +316,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
} else if (item.getItemId() == R.id.action_photo_camera) {
photoFileUri = MediaHelper.dispatchTakePictureIntent(ComposeActivity.this);
} else if (item.getItemId() == R.id.action_contacts) {
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(ComposeActivity.this, Helper.dialogStyle());
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(ComposeActivity.this);
builderSingle.setTitle(getString(R.string.select_accounts));
PopupContactBinding popupContactBinding = PopupContactBinding.inflate(getLayoutInflater(), new LinearLayout(ComposeActivity.this), false);

View file

@ -45,7 +45,6 @@ import app.fedilab.android.mastodon.client.entities.api.Attachment;
import app.fedilab.android.mastodon.client.entities.api.Status;
import app.fedilab.android.mastodon.client.entities.app.StatusDraft;
import app.fedilab.android.mastodon.exception.DBException;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.ui.drawer.StatusDraftAdapter;
import app.fedilab.android.mastodon.viewmodel.mastodon.TimelinesVM;
@ -100,7 +99,7 @@ public class DraftActivity extends BaseActivity implements StatusDraftAdapter.Dr
finish();
return true;
} else if (item.getItemId() == R.id.action_delete) {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(DraftActivity.this, Helper.dialogStyle());
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(DraftActivity.this);
unfollowConfirm.setTitle(getString(R.string.delete_all));
unfollowConfirm.setMessage(getString(R.string.remove_draft));
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());

View file

@ -136,7 +136,7 @@ public class EditProfileActivity extends BaseBarActivity {
value = Html.fromHtml(field.value).toString();
fieldItemBinding.value.setText(value);
fieldItemBinding.remove.setOnClickListener(v -> {
AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this);
deleteConfirm.setTitle(getString(R.string.delete_field));
deleteConfirm.setMessage(getString(R.string.delete_field_confirm));
deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
@ -158,7 +158,7 @@ public class EditProfileActivity extends BaseBarActivity {
binding.addField.setOnClickListener(view -> {
AccountFieldItemBinding fieldItemBinding = AccountFieldItemBinding.inflate(getLayoutInflater());
fieldItemBinding.remove.setOnClickListener(v -> {
AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this);
deleteConfirm.setTitle(getString(R.string.delete_field));
deleteConfirm.setMessage(getString(R.string.delete_field_confirm));
deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());

View file

@ -44,7 +44,6 @@ import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.databinding.ActivityFiltersBinding;
import app.fedilab.android.databinding.PopupAddFilterBinding;
import app.fedilab.android.mastodon.client.entities.api.Filter;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.ui.drawer.FilterAdapter;
import app.fedilab.android.mastodon.ui.drawer.KeywordAdapter;
import app.fedilab.android.mastodon.viewmodel.mastodon.FiltersVM;
@ -63,7 +62,7 @@ public class FilterActivity extends BaseBarActivity implements FilterAdapter.Del
* @param listener - {@link FilterAdapter.FilterAction}
*/
public static void addEditFilter(Context context, Filter filter, FilterAdapter.FilterAction listener) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context);
PopupAddFilterBinding popupAddFilterBinding = PopupAddFilterBinding.inflate(LayoutInflater.from(context));
FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class);
dialogBuilder.setView(popupAddFilterBinding.getRoot());

View file

@ -90,7 +90,7 @@ public class FollowedTagActivity extends BaseBarActivity implements FollowedTagA
onBackPressed();
return true;
} else if (item.getItemId() == R.id.action_unfollow && tag != null) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(FollowedTagActivity.this, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(FollowedTagActivity.this);
alt_bld.setTitle(R.string.action_unfollow_tag);
alt_bld.setMessage(R.string.action_unfollow_tag_confirm);
alt_bld.setPositiveButton(R.string.unfollow, (dialog, id) -> {
@ -122,7 +122,7 @@ public class FollowedTagActivity extends BaseBarActivity implements FollowedTagA
AlertDialog alert = alt_bld.create();
alert.show();
} else if (item.getItemId() == R.id.action_follow_tag) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(FollowedTagActivity.this, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(FollowedTagActivity.this);
PopupAddFollowedTagtBinding popupAddFollowedTagtBinding = PopupAddFollowedTagtBinding.inflate(getLayoutInflater());
dialogBuilder.setView(popupAddFollowedTagtBinding.getRoot());
popupAddFollowedTagtBinding.addTag.setFilters(new InputFilter[]{new InputFilter.LengthFilter(255)});

View file

@ -173,7 +173,7 @@ public class HashTagActivity extends BaseActivity {
} else if (item.getItemId() == R.id.action_add_timeline) {
if (pinnedTag) {
AlertDialog.Builder unpinConfirm = new MaterialAlertDialogBuilder(HashTagActivity.this, Helper.dialogStyle());
AlertDialog.Builder unpinConfirm = new MaterialAlertDialogBuilder(HashTagActivity.this);
unpinConfirm.setMessage(getString(R.string.unpin_timeline_description));
unpinConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
unpinConfirm.setPositiveButton(R.string.yes, (dialog, which) -> {
@ -233,6 +233,10 @@ public class HashTagActivity extends BaseActivity {
tagTimeline.any.add(stripTag.trim());
pinnedTimeline.tagTimeline = tagTimeline;
pinned.pinnedTimelines.add(pinnedTimeline);
if (pinned.instance == null || pinned.user_id == null) {
pinned.instance = MainActivity.currentInstance;
pinned.user_id = MainActivity.currentUserID;
}
if (update) {
new Pinned(HashTagActivity.this).updatePinned(pinned);
} else {

View file

@ -147,7 +147,7 @@ public class MastodonListActivity extends BaseBarActivity implements MastodonLis
onBackPressed();
return true;
} else if (item.getItemId() == R.id.action_user_mute_home) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(MastodonListActivity.this, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(MastodonListActivity.this);
dialogBuilder.setTitle(R.string.put_all_accounts_in_home_muted);
dialogBuilder.setPositiveButton(R.string.mute_them_all, (dialog, id) -> {
timelinesVM.getAccountsInList(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, mastodonList.id, null, null, 0)
@ -161,7 +161,7 @@ public class MastodonListActivity extends BaseBarActivity implements MastodonLis
dialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
dialogBuilder.show();
} else if (item.getItemId() == R.id.action_manage_users) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(MastodonListActivity.this, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(MastodonListActivity.this);
PopupManageAccountsListBinding popupManageAccountsListBinding = PopupManageAccountsListBinding.inflate(getLayoutInflater());
dialogBuilder.setView(popupManageAccountsListBinding.getRoot());
popupManageAccountsListBinding.loader.setVisibility(View.VISIBLE);
@ -258,7 +258,7 @@ public class MastodonListActivity extends BaseBarActivity implements MastodonLis
dialogBuilder.setPositiveButton(R.string.close, (dialog, id) -> dialog.dismiss());
dialogBuilder.create().show();
} else if (item.getItemId() == R.id.action_delete && mastodonList != null) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(MastodonListActivity.this, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(MastodonListActivity.this);
alt_bld.setTitle(R.string.action_lists_delete);
alt_bld.setMessage(R.string.action_lists_confirm_delete);
alt_bld.setPositiveButton(R.string.delete, (dialog, id) -> {
@ -296,7 +296,7 @@ public class MastodonListActivity extends BaseBarActivity implements MastodonLis
AlertDialog alert = alt_bld.create();
alert.show();
} else if (item.getItemId() == R.id.action_add_list) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(MastodonListActivity.this, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(MastodonListActivity.this);
PopupAddListBinding popupAddListBinding = PopupAddListBinding.inflate(getLayoutInflater());
dialogBuilder.setView(popupAddListBinding.getRoot());
popupAddListBinding.addList.setFilters(new InputFilter[]{new InputFilter.LengthFilter(255)});
@ -336,7 +336,7 @@ public class MastodonListActivity extends BaseBarActivity implements MastodonLis
dialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
dialogBuilder.create().show();
} else if (item.getItemId() == R.id.action_edit) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(MastodonListActivity.this, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(MastodonListActivity.this);
PopupAddListBinding popupAddListBinding = PopupAddListBinding.inflate(getLayoutInflater());
dialogBuilder.setView(popupAddListBinding.getRoot());
popupAddListBinding.addList.setFilters(new InputFilter[]{new InputFilter.LengthFilter(255)});

View file

@ -250,7 +250,7 @@ public class MediaActivity extends BaseTransparentActivity implements OnDownload
int position = binding.mediaViewpager.getCurrentItem();
Attachment attachment = attachments.get(position);
if (Build.VERSION.SDK_INT >= 23) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (ContextCompat.checkSelfPermission(MediaActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(MediaActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MediaActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE_MEDIA_SAVE);
} else {

View file

@ -477,7 +477,7 @@ public class ProfileActivity extends BaseActivity {
} else if (doAction == action.UNFOLLOW) {
boolean confirm_unfollow = sharedpreferences.getBoolean(getString(R.string.SET_UNFOLLOW_VALIDATION), true);
if (confirm_unfollow) {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(ProfileActivity.this);
unfollowConfirm.setTitle(getString(R.string.unfollow_confirm));
unfollowConfirm.setMessage(account.acct);
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
@ -565,7 +565,7 @@ public class ProfileActivity extends BaseActivity {
//Recyclerview for identity proof has not been inflated yet
if (identityProofsRecycler == null) {
identity_proofs_indicator.setOnClickListener(v -> {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(ProfileActivity.this);
identityProofsRecycler = new RecyclerView(ProfileActivity.this);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ProfileActivity.this);
identityProofsRecycler.setLayoutManager(mLayoutManager);
@ -675,7 +675,7 @@ public class ProfileActivity extends BaseActivity {
binding.personalNote.setText(relationship.note);
}
binding.personalNote.setOnClickListener(view -> {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this);
builderInner.setTitle(R.string.note_for_account);
EditText input = new EditText(ProfileActivity.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
@ -836,6 +836,10 @@ public class ProfileActivity extends BaseActivity {
pinnedTimeline.type = Timeline.TimeLineEnum.REMOTE;
pinnedTimeline.position = pinned.pinnedTimelines.size();
pinned.pinnedTimelines.add(pinnedTimeline);
if (pinned.instance == null || pinned.user_id == null) {
pinned.instance = MainActivity.currentInstance;
pinned.user_id = MainActivity.currentUserID;
}
Pinned finalPinned = pinned;
boolean finalPresent = present;
new Thread(() -> {
@ -860,7 +864,7 @@ public class ProfileActivity extends BaseActivity {
});
return true;
} else if (itemId == R.id.action_filter) {
AlertDialog.Builder filterTagDialog = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder filterTagDialog = new MaterialAlertDialogBuilder(ProfileActivity.this);
Set<String> featuredTagsSet = sharedpreferences.getStringSet(getString(R.string.SET_FEATURED_TAGS), null);
List<String> tags = new ArrayList<>();
if (featuredTagsSet != null) {
@ -941,7 +945,7 @@ public class ProfileActivity extends BaseActivity {
i++;
}
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(ProfileActivity.this);
builder.setTitle(getString(R.string.filter_languages));
builder.setMultiChoiceItems(languagesArr, presentArr, (dialog, which, isChecked) -> {
List<String> languagesFilter = new ArrayList<>();
@ -986,7 +990,7 @@ public class ProfileActivity extends BaseActivity {
}
accountsVM.getListContainingAccount(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, account.id)
.observe(ProfileActivity.this, mastodonListUserIs -> {
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(ProfileActivity.this);
builderSingle.setTitle(getString(R.string.action_lists_add_to));
builderSingle.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss());
String[] listsId = new String[mastodonLists.size()];
@ -1078,7 +1082,7 @@ public class ProfileActivity extends BaseActivity {
});
return true;
}
builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this);
builderInner.setTitle(stringArrayConf[0]);
builderInner.setNeutralButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
@ -1098,7 +1102,7 @@ public class ProfileActivity extends BaseActivity {
builderInner.show();
}
} else if (itemId == R.id.action_mute_home) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this);
builderInner.setMessage(account.acct);
builderInner.setNeutralButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
if (homeMuted) {
@ -1126,7 +1130,7 @@ public class ProfileActivity extends BaseActivity {
});
return true;
} else if (itemId == R.id.action_report) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this);
builderInner.setTitle(R.string.report_account);
//Text for report
EditText input = new EditText(ProfileActivity.this);
@ -1146,7 +1150,7 @@ public class ProfileActivity extends BaseActivity {
builderInner.show();
return true;
} else if (itemId == R.id.action_block) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this);
if (relationship != null) {
if (relationship.blocking) {
builderInner.setTitle(stringArrayConf[5]);
@ -1186,7 +1190,7 @@ public class ProfileActivity extends BaseActivity {
});
builderInner.show();
} else if (itemId == R.id.action_block_instance) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(ProfileActivity.this);
String domain = account.acct.split("@")[1];
builderInner.setMessage(getString(R.string.block_domain_confirm_message, domain));
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());

View file

@ -44,6 +44,7 @@ import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import app.fedilab.android.R;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.databinding.ActivityReorderTabsBinding;
import app.fedilab.android.databinding.PopupSearchInstanceBinding;
import app.fedilab.android.mastodon.client.entities.app.BottomMenu;
@ -170,7 +171,7 @@ public class ReorderTimelinesActivity extends BaseBarActivity implements OnStart
}
private void addInstance() {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(ReorderTimelinesActivity.this, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(ReorderTimelinesActivity.this);
PopupSearchInstanceBinding popupSearchInstanceBinding = PopupSearchInstanceBinding.inflate(getLayoutInflater());
dialogBuilder.setView(popupSearchInstanceBinding.getRoot());
TextWatcher textWatcher = autoComplete(popupSearchInstanceBinding);
@ -261,7 +262,10 @@ public class ReorderTimelinesActivity extends BaseBarActivity implements OnStart
pinnedTimeline.type = Timeline.TimeLineEnum.REMOTE;
pinnedTimeline.position = pinned.pinnedTimelines.size();
pinned.pinnedTimelines.add(pinnedTimeline);
if (pinned.user_id == null || pinned.instance == null) {
pinned.user_id = MainActivity.currentUserID;
pinned.instance = MainActivity.currentInstance;
}
if (update) {
try {
new Pinned(ReorderTimelinesActivity.this).updatePinned(pinned);

View file

@ -70,6 +70,7 @@ public class SearchResultTabActivity extends BaseBarActivity {
private String search;
private ActivitySearchResultTabsBinding binding;
private TabLayout.Tab initial;
public Boolean tagEmpty, accountEmpty;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -277,9 +278,17 @@ public class SearchResultTabActivity extends BaseBarActivity {
public void moveToAccount() {
tagEmpty = null;
accountEmpty = null;
binding.searchViewpager.setCurrentItem(1);
}
public void moveToMessage() {
tagEmpty = null;
accountEmpty = null;
binding.searchViewpager.setCurrentItem(2);
}
/**
* Pager adapter for the 4 fragments
*/

View file

@ -165,7 +165,7 @@ public class AdminActionActivity extends BaseBarActivity {
return true;
} else if (item.getItemId() == R.id.action_filter) {
if (getTitle().toString().equalsIgnoreCase(getString(R.string.accounts))) {
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(AdminActionActivity.this, Helper.dialogStyle());
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(AdminActionActivity.this);
PopupAdminFilterAccountsBinding binding = PopupAdminFilterAccountsBinding.inflate(getLayoutInflater());
alertDialogBuilder.setView(binding.getRoot());
if (local != null && remote == null) {
@ -259,7 +259,7 @@ public class AdminActionActivity extends BaseBarActivity {
AlertDialog alert = alertDialogBuilder.create();
alert.show();
} else {
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(AdminActionActivity.this, Helper.dialogStyle());
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(AdminActionActivity.this);
PopupAdminFilterReportsBinding binding = PopupAdminFilterReportsBinding.inflate(getLayoutInflater());
alertDialogBuilder.setView(binding.getRoot());
if (resolved == null) {

View file

@ -129,7 +129,7 @@ public class AdminDomainBlockActivity extends BaseBarActivity {
return true;
} else if (itemId == R.id.action_delete) {
if (adminDomainBlock.id != null) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(AdminDomainBlockActivity.this, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(AdminDomainBlockActivity.this);
builder.setMessage(getString(R.string.unblock_domain_confirm, adminDomainBlock.domain));
builder
.setPositiveButton(R.string.unblock_domain, (dialog, which) -> {

View file

@ -91,10 +91,12 @@ public interface MastodonStatusesService {
@Field("sensitive") Boolean sensitive,
@Field("spoiler_text") String spoiler_text,
@Field("visibility") String visibility,
@Field("language") String language
@Field("language") String language,
@Field("media_attributes[id][]") List<String> media_id,
@Field("media_attributes[description][]") List<String> media_description,
@Field("media_attributes[focus][]") List<String> focus
);
//Post a scheduled status
@FormUrlEncoded
@POST("statuses")
@ -316,4 +318,18 @@ public interface MastodonStatusesService {
@Header("Authorization") String token,
@Path("id") String id
);
@POST("statuses/{id}/react/{name}")
Call<Void> addReaction(
@Header("Authorization") String app_token,
@Path("id") String id,
@Path("name") String name
);
@POST("statuses/{id}/unreact/{name}")
Call<Void> removeReaction(
@Header("Authorization") String app_token,
@Path("id") String id,
@Path("name") String name
);
}

View file

@ -29,6 +29,7 @@ import java.util.Date;
import java.util.List;
import app.fedilab.android.mastodon.helper.SpannableHelper;
import de.timfreiheit.mathjax.android.MathJaxView;
public class Status implements Serializable, Cloneable {
@ -108,6 +109,8 @@ public class Status implements Serializable, Cloneable {
public boolean cached = false;
@SerializedName("is_maths")
public Boolean isMaths;
@SerializedName("reactions")
public List<Reaction> reactions;
public Attachment art_attachment;
public boolean isExpended = false;
@ -128,6 +131,7 @@ public class Status implements Serializable, Cloneable {
public transient Spannable contentSpan;
public transient Spannable contentSpoilerSpan;
public transient Spannable contentTranslateSpan;
public transient MathJaxView mathJaxView;
@Override
public boolean equals(@Nullable Object obj) {

View file

@ -166,8 +166,8 @@ public class BottomMenu implements Serializable {
throw new DBException("db is null. Wrong initialization.");
}
ContentValues values = new ContentValues();
values.put(Sqlite.COL_INSTANCE, BaseMainActivity.currentInstance);
values.put(Sqlite.COL_USER_ID, BaseMainActivity.currentUserID);
values.put(Sqlite.COL_INSTANCE, bottomMenu.instance);
values.put(Sqlite.COL_USER_ID, bottomMenu.user_id);
values.put(Sqlite.COL_BOTTOM_MENU, menuItemListToStringStorage(bottomMenu.bottom_menu));
//Inserts bottom
try {

View file

@ -28,7 +28,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.mastodon.exception.DBException;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.sqlite.Sqlite;
@ -104,8 +103,8 @@ public class Pinned implements Serializable {
throw new DBException("db is null. Wrong initialization.");
}
ContentValues values = new ContentValues();
values.put(Sqlite.COL_INSTANCE, BaseMainActivity.currentInstance);
values.put(Sqlite.COL_USER_ID, BaseMainActivity.currentUserID);
values.put(Sqlite.COL_INSTANCE, pinned.instance);
values.put(Sqlite.COL_USER_ID, pinned.user_id);
values.put(Sqlite.COL_PINNED_TIMELINES, mastodonPinnedTimelinesToStringStorage(pinned.pinnedTimelines));
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(new Date()));
//Inserts pinned

View file

@ -84,7 +84,7 @@ public class CrossActionHelper {
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(context);
builderSingle.setTitle(context.getString(R.string.choose_accounts));
final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accountList);
final BaseAccount[] accountArray = new BaseAccount[accounts.size()];
@ -99,7 +99,7 @@ public class CrossActionHelper {
boolean confirmBoost = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION), true);
BaseAccount selectedAccount = accountArray[which];
if ((actionType == TypeOfCrossAction.REBLOG_ACTION && confirmBoost) || (actionType == TypeOfCrossAction.FAVOURITE_ACTION && confirmFav)) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context);
if (actionType == TypeOfCrossAction.REBLOG_ACTION) {
alt_bld.setMessage(context.getString(R.string.reblog_add));
} else {
@ -420,7 +420,7 @@ public class CrossActionHelper {
context.startActivity(intentToot);
((BaseActivity) context).finish();
} else {
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(context);
builderSingle.setTitle(context.getString(R.string.choose_accounts));
final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accountList);
final BaseAccount[] accountArray = new BaseAccount[accounts.size()];

View file

@ -18,6 +18,7 @@ import static android.content.Context.DOWNLOAD_SERVICE;
import static app.fedilab.android.BaseMainActivity.currentAccount;
import static app.fedilab.android.mastodon.activities.BaseActivity.currentThemeId;
import static app.fedilab.android.mastodon.helper.LogoHelper.getNotificationIcon;
import static app.fedilab.android.mastodon.helper.ThemeHelper.fetchAccentColor;
import android.annotation.SuppressLint;
import android.app.Activity;
@ -42,6 +43,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.RingtoneManager;
import android.net.ConnectivityManager;
@ -89,6 +91,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.avatarfirst.avatargenlib.AvatarGenerator;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
@ -273,6 +276,7 @@ public class Helper {
public static final String ARG_SCHEDULED_DATE = "ARG_SCHEDULED_DATE";
public static final String WORKER_REFRESH_NOTIFICATION = "WORKER_REFRESH_NOTIFICATION";
public static final String WORKER_REFRESH_HOME = "WORKER_REFRESH_HOME";
public static final String WORKER_SCHEDULED_STATUSES = "WORKER_SCHEDULED_STATUSES";
public static final String WORKER_SCHEDULED_REBLOGS = "WORKER_SCHEDULED_REBLOGS";
@ -413,7 +417,7 @@ public class Helper {
* @param url String download url
*/
public static void manageDownloads(final Context context, final String url) {
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
final DownloadManager.Request request;
try {
request = new DownloadManager.Request(Uri.parse(url.trim()));
@ -1062,9 +1066,25 @@ public class Helper {
if (account.mastodon_account != null) {
targetedUrl = disableGif ? account.mastodon_account.avatar_static : account.mastodon_account.avatar;
} else if (account.peertube_account != null) {
targetedUrl = account.peertube_account.getAvatar().getPath();
if (targetedUrl != null && targetedUrl.startsWith("/")) {
targetedUrl = "https://" + account.instance + account.peertube_account.getAvatar().getPath();
if (account.peertube_account.getAvatar() != null) {
targetedUrl = account.peertube_account.getAvatar().getPath();
if (targetedUrl != null && targetedUrl.startsWith("/")) {
targetedUrl = "https://" + account.instance + account.peertube_account.getAvatar().getPath();
}
} else {
BitmapDrawable avatar = new AvatarGenerator.AvatarBuilder(activity)
.setLabel(account.peertube_account.getAcct())
.setAvatarSize(120)
.setTextSize(30)
.toSquare()
.setBackgroundColor(fetchAccentColor(activity))
.build();
Glide.with(activity)
.asDrawable()
.load(avatar)
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
.into(view);
return;
}
}
@ -1792,7 +1812,7 @@ public class Helper {
is.close();
String json = new String(buffer, StandardCharsets.UTF_8);
Gson gson = new Gson();
AlertDialog.Builder dialogBuilderOptin = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
AlertDialog.Builder dialogBuilderOptin = new MaterialAlertDialogBuilder(activity);
PopupReleaseNotesBinding binding = PopupReleaseNotesBinding.inflate(activity.getLayoutInflater());
dialogBuilderOptin.setView(binding.getRoot());
try {

View file

@ -412,7 +412,7 @@ public class MastodonHelper {
* @param status {@link Status}
*/
public static void scheduleBoost(Context context, ScheduleType scheduleType, Status status, Account account, TimedMuted listener) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context);
DatetimePickerBinding binding = DatetimePickerBinding.inflate(((Activity) context).getLayoutInflater());
dialogBuilder.setView(binding.getRoot());
final AlertDialog alertDialogBoost = dialogBuilder.create();

View file

@ -278,7 +278,7 @@ public class MediaHelper {
AudioRecorder mAudioRecorder = AudioRecorder.getInstance();
File mAudioFile = new File(filePath);
PopupRecordBinding binding = PopupRecordBinding.inflate(activity.getLayoutInflater());
AlertDialog.Builder audioPopup = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
AlertDialog.Builder audioPopup = new MaterialAlertDialogBuilder(activity);
audioPopup.setView(binding.getRoot());
AlertDialog alert = audioPopup.create();
alert.show();
@ -326,7 +326,7 @@ public class MediaHelper {
* @param listener - OnSchedule
*/
public static void scheduleMessage(Activity activity, OnSchedule listener) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
DatetimePickerBinding binding = DatetimePickerBinding.inflate(activity.getLayoutInflater());
dialogBuilder.setView(binding.getRoot());

View file

@ -277,6 +277,7 @@ public class PinnedTimelineHelper {
pinnedTimeline.position = pinnedAll.pinnedTimelines.size();
pinnedTimeline.mastodonList = mastodonList;
pinnedAll.pinnedTimelines.add(pinnedTimeline);
try {
boolean exist = new Pinned(activity).pinnedExist(pinnedAll);
if (exist) {
@ -304,7 +305,7 @@ public class PinnedTimelineHelper {
//Small hack to hide first tabs (they represent the item of the bottom menu)
toRemove = itemToRemoveInBottomMenu(activity);
for (int i = 0; i < (FedilabPageAdapter.BOTTOM_TIMELINE_COUNT - toRemove); i++) {
activityMainBinding.tabLayout.addTab(activityMainBinding.tabLayout.newTab());
activityMainBinding.tabLayout.addTab(activityMainBinding.tabLayout.newTab(), false);
((ViewGroup) activityMainBinding.tabLayout.getChildAt(0)).getChildAt(i).setVisibility(View.GONE);
}
}
@ -413,7 +414,7 @@ public class PinnedTimelineHelper {
//We be used to fetch position of tabs
String slug = pinnedTimeline.type.getValue() + (ident != null ? "|" + ident : "");
tab.setTag(slug);
activityMainBinding.tabLayout.addTab(tab);
activityMainBinding.tabLayout.addTab(tab, false);
pinnedTimelineVisibleList.add(pinnedTimeline);
}
}
@ -697,7 +698,7 @@ public class PinnedTimelineHelper {
itemShowDMs.setChecked(show_dms);
editor.apply();
} else if (itemId == R.id.action_filter) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
LayoutInflater inflater = activity.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.popup_filter_regex, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView);
@ -886,7 +887,7 @@ public class PinnedTimelineHelper {
e.printStackTrace();
}
} else if (itemId == R.id.action_any) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
LayoutInflater inflater = activity.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.tags_any, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView);
@ -915,7 +916,7 @@ public class PinnedTimelineHelper {
LayoutInflater inflater;
View dialogView;
AlertDialog alertDialog;
dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
dialogBuilder = new MaterialAlertDialogBuilder(activity);
inflater = activity.getLayoutInflater();
dialogView = inflater.inflate(R.layout.tags_all, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView);
@ -944,7 +945,7 @@ public class PinnedTimelineHelper {
LayoutInflater inflater;
View dialogView;
AlertDialog alertDialog;
dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
dialogBuilder = new MaterialAlertDialogBuilder(activity);
inflater = activity.getLayoutInflater();
dialogView = inflater.inflate(R.layout.tags_all, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView);
@ -973,7 +974,7 @@ public class PinnedTimelineHelper {
LayoutInflater inflater;
View dialogView;
AlertDialog alertDialog;
dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
dialogBuilder = new MaterialAlertDialogBuilder(activity);
inflater = activity.getLayoutInflater();
dialogView = inflater.inflate(R.layout.tags_name, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView);
@ -1114,7 +1115,7 @@ public class PinnedTimelineHelper {
e.printStackTrace();
}
} else if (itemId == R.id.action_exclude_visibility) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
DialogBubbleExcludeVisibilityBinding dialogBinding = DialogBubbleExcludeVisibilityBinding.inflate(activity.getLayoutInflater());
dialogBuilder.setView(dialogBinding.getRoot());
dialogBuilder.setTitle(R.string.exclude_visibility);
@ -1208,7 +1209,7 @@ public class PinnedTimelineHelper {
} else if (itemId == R.id.action_reply_visibility) {
AlertDialog.Builder dialogBuilder;
AlertDialog alertDialog;
dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
dialogBuilder = new MaterialAlertDialogBuilder(activity);
DialogBubbleReplyVisibilityBinding dialogBinding = DialogBubbleReplyVisibilityBinding.inflate(activity.getLayoutInflater());
dialogBuilder.setView(dialogBinding.getRoot());
dialogBuilder.setTitle(R.string.reply_visibility);
@ -1403,7 +1404,7 @@ public class PinnedTimelineHelper {
}
});
changes[0] = true;
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
LayoutInflater inflater = activity.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.tags_instance, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView);
@ -1497,7 +1498,7 @@ public class PinnedTimelineHelper {
LayoutInflater inflater;
View dialogView;
AlertDialog alertDialog;
dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
dialogBuilder = new MaterialAlertDialogBuilder(activity);
inflater = activity.getLayoutInflater();
dialogView = inflater.inflate(R.layout.tags_name, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView);
@ -1527,7 +1528,7 @@ public class PinnedTimelineHelper {
alertDialog.show();
} else if (itemId == R.id.action_nitter_manage_accounts) {
String accounts = remoteInstance.host;
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity, Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
LayoutInflater inflater = activity.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.tags_any, new LinearLayout(activity), false);
dialogBuilder.setView(dialogView);

View file

@ -59,7 +59,7 @@ public class PushHelper {
Runnable myRunnable = () -> {
List<String> distributors = UnifiedPush.getDistributors(context, new ArrayList<>());
if (distributors.size() == 0) {
AlertDialog.Builder alert = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder alert = new MaterialAlertDialogBuilder(context);
alert.setTitle(R.string.no_distributors_found);
final TextView message = new TextView(context);
String link = "https://fedilab.app/wiki/features/push-notifications/";
@ -136,7 +136,7 @@ public class PushHelper {
return;
}
AlertDialog.Builder alert = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder alert = new MaterialAlertDialogBuilder(context);
alert.setTitle(R.string.select_distributors);
String[] distributorsStr = distributors.toArray(new String[0]);
alert.setSingleChoiceItems(distributorsStr, -1, (dialog, item) -> {

View file

@ -514,6 +514,8 @@ public class SpannableHelper {
Matcher matcherLink = link.matcher(finalUrl);
Pattern linkLong = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[\\w_.-]+@[a-zA-Z0-9][a-zA-Z0-9.-]{1,61}[a-zA-Z0-9](?:\\.[a-zA-Z]{2,})+)(/[0-9]+)?$");
Matcher matcherLinkLong = linkLong.matcher(finalUrl);
Pattern userWithoutAt = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(users/([\\w._-]*[0-9]*))/statuses/([0-9]+)");
Matcher matcherUserWithoutAt = userWithoutAt.matcher(finalUrl);
if (matcherLink.find() && !finalUrl.contains("medium.com")) {
if (matcherLink.group(3) != null && Objects.requireNonNull(matcherLink.group(3)).length() > 0) { //It's a toot
CrossActionHelper.fetchRemoteStatus(context, currentAccount, finalUrl, new CrossActionHelper.Callback() {
@ -567,6 +569,38 @@ public class SpannableHelper {
public void federatedStatus(Status status) {
}
@Override
public void federatedAccount(Account account) {
Intent intent = new Intent(context, ProfileActivity.class);
Bundle b = new Bundle();
b.putSerializable(Helper.ARG_ACCOUNT, account);
intent.putExtras(b);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
} else if (matcherUserWithoutAt.find() && !finalUrl.contains("medium.com")) {
if (matcherUserWithoutAt.group(4) != null && Objects.requireNonNull(matcherUserWithoutAt.group(4)).length() > 0) { //It's a toot
CrossActionHelper.fetchRemoteStatus(context, currentAccount, finalUrl, new CrossActionHelper.Callback() {
@Override
public void federatedStatus(Status status) {
Intent intent = new Intent(context, ContextActivity.class);
intent.putExtra(Helper.ARG_STATUS, status);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
@Override
public void federatedAccount(Account account) {
}
});
} else {//It's an account
CrossActionHelper.fetchRemoteAccount(context, currentAccount, matcherUserWithoutAt.group(3) + "@" + matcherUserWithoutAt.group(1), new CrossActionHelper.Callback() {
@Override
public void federatedStatus(Status status) {
}
@Override
public void federatedAccount(Account account) {
Intent intent = new Intent(context, ProfileActivity.class);
@ -640,7 +674,7 @@ public class SpannableHelper {
return;
}
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
builder.setMessage(context.getString(R.string.mute_tag, tag));
builder
.setPositiveButton(R.string.yes, (dialog, which) -> {

View file

@ -108,7 +108,7 @@ public class TranslateHelper {
}
j++;
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(context.getString(R.string.translate_in));
builder.setItems(languagesArr, (dialogInterface, i) -> {
myTransL.translate(statusToTranslate, codesArr[i], params, new Results() {

View file

@ -265,7 +265,7 @@ public class EditImageActivity extends BaseActivity implements OnPhotoEditorList
.setClearViewsEnabled(true)
.setTransparencyEnabled(true)
.build();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (ContextCompat.checkSelfPermission(EditImageActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(EditImageActivity.this,

View file

@ -158,6 +158,9 @@ public class ComposeWorker extends Worker {
}
dataPost.messageToSend = statuses.size() - startingPosition;
dataPost.messageSent = 0;
List<String> media_edit_id = null;
List<String> media_edit_description = null;
List<String> media_edit_focus = null;
for (int i = startingPosition; i < statuses.size(); i++) {
if (dataPost.notificationBuilder != null) {
dataPost.notificationBuilder.setProgress(100, dataPost.messageSent * 100 / dataPost.messageToSend, true);
@ -170,7 +173,15 @@ public class ComposeWorker extends Worker {
attachmentIds = new ArrayList<>();
for (Attachment attachment : statuses.get(i).media_attachments) {
if (attachment.id != null) {
if (media_edit_id == null) {
media_edit_id = new ArrayList<>();
media_edit_description = new ArrayList<>();
media_edit_focus = new ArrayList<>();
}
attachmentIds.add(attachment.id);
media_edit_id.add(attachment.id);
media_edit_description.add(attachment.description);
media_edit_focus.add(attachment.focus);
} else {
MultipartBody.Part fileMultipartBody;
if (watermark && attachment.mimeType != null && attachment.mimeType.contains("image")) {
@ -221,13 +232,16 @@ public class ComposeWorker extends Worker {
if (statuses.get(i).local_only) {
statuses.get(i).text += " \uD83D\uDC41";
}
if (dataPost.scheduledDate == null) {
if (dataPost.statusEditId == null) {
statusCall = mastodonStatusesService.createStatus(null, dataPost.token, statuses.get(i).text, attachmentIds, poll_options, poll_expire_in,
poll_multiple, poll_hide_totals, statuses.get(i).quote_id == null ? in_reply_to_status : null, statuses.get(i).sensitive, statuses.get(i).spoilerChecked ? statuses.get(i).spoiler_text : null, statuses.get(i).visibility.toLowerCase(), language, statuses.get(i).quote_id, statuses.get(i).content_type);
} else { //Status is edited
statusCall = mastodonStatusesService.updateStatus(null, dataPost.token, dataPost.statusEditId, statuses.get(i).text, attachmentIds, poll_options, poll_expire_in,
poll_multiple, poll_hide_totals, statuses.get(i).quote_id == null ? in_reply_to_status : null, statuses.get(i).sensitive, statuses.get(i).spoilerChecked ? statuses.get(i).spoiler_text : null, statuses.get(i).visibility.toLowerCase(), language);
poll_multiple, poll_hide_totals, statuses.get(i).quote_id == null ? in_reply_to_status : null, statuses.get(i).sensitive,
statuses.get(i).spoilerChecked ? statuses.get(i).spoiler_text : null, statuses.get(i).visibility.toLowerCase(), language,
media_edit_id, media_edit_description, media_edit_focus);
}
try {
Response<Status> statusResponse = statusCall.execute();

View file

@ -0,0 +1,225 @@
package app.fedilab.android.mastodon.jobs;
/* Copyright 2023 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.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.preference.PreferenceManager;
import androidx.work.Data;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.ForegroundInfo;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import app.fedilab.android.R;
import app.fedilab.android.mastodon.client.endpoints.MastodonTimelinesService;
import app.fedilab.android.mastodon.client.entities.api.Pagination;
import app.fedilab.android.mastodon.client.entities.api.Status;
import app.fedilab.android.mastodon.client.entities.app.Account;
import app.fedilab.android.mastodon.client.entities.app.BaseAccount;
import app.fedilab.android.mastodon.client.entities.app.StatusCache;
import app.fedilab.android.mastodon.client.entities.app.Timeline;
import app.fedilab.android.mastodon.exception.DBException;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.helper.MastodonHelper;
import okhttp3.OkHttpClient;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class FetchHomeWorker extends Worker {
private static final int FETCH_HOME_CHANNEL_ID = 5;
private static final String CHANNEL_ID = "fedilab_home";
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.callTimeout(60, TimeUnit.SECONDS)
.proxy(Helper.getProxy(getApplicationContext().getApplicationContext()))
.build();
private final NotificationManager notificationManager;
public FetchHomeWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
public static void setRepeatHome(Context context, BaseAccount account, Data inputData) {
WorkManager.getInstance(context).cancelAllWorkByTag(Helper.WORKER_REFRESH_HOME + account.user_id + account.instance);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String value = prefs.getString(context.getString(R.string.SET_FETCH_HOME_DELAY_VALUE) + account.user_id + account.instance, "60");
PeriodicWorkRequest notificationPeriodic = new PeriodicWorkRequest.Builder(FetchHomeWorker.class, Long.parseLong(value), TimeUnit.MINUTES)
.setInputData(inputData)
.addTag(Helper.WORKER_REFRESH_HOME + account.user_id + account.instance)
.build();
WorkManager.getInstance(context).enqueueUniquePeriodicWork(Helper.WORKER_REFRESH_HOME + account.user_id + account.instance, ExistingPeriodicWorkPolicy.REPLACE, notificationPeriodic);
}
@NonNull
@Override
public ListenableFuture<ForegroundInfo> getForegroundInfoAsync() {
if (Build.VERSION.SDK_INT >= 26) {
String channelName = "Fetch Home";
String channelDescription = "Fetch home messages";
NotificationChannel fetchHomeChannel = new NotificationChannel(CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_LOW);
fetchHomeChannel.setDescription(channelDescription);
fetchHomeChannel.setSound(null, null);
fetchHomeChannel.setShowBadge(false);
notificationManager.createNotificationChannel(fetchHomeChannel);
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
notificationBuilder.setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.ic_launcher_foreground))
.setContentTitle(getApplicationContext().getString(R.string.notifications))
.setContentText(getApplicationContext().getString(R.string.fetch_notifications))
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setPriority(Notification.PRIORITY_DEFAULT);
return Futures.immediateFuture(new ForegroundInfo(FETCH_HOME_CHANNEL_ID, notificationBuilder.build()));
}
@NonNull
private ForegroundInfo createForegroundInfo() {
if (Build.VERSION.SDK_INT >= 26) {
String channelName = "Fetch Home";
String channelDescription = "Fetch home messages";
NotificationChannel fetchHomeChannel = new NotificationChannel(CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_LOW);
fetchHomeChannel.setSound(null, null);
fetchHomeChannel.setShowBadge(false);
fetchHomeChannel.setDescription(channelDescription);
notificationManager.createNotificationChannel(fetchHomeChannel);
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
notificationBuilder.setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.ic_launcher_foreground))
.setContentTitle(getApplicationContext().getString(R.string.fetch_home_messages))
.setContentText(getApplicationContext().getString(R.string.set_fetch_home))
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setSilent(true)
.setPriority(Notification.PRIORITY_LOW);
return new ForegroundInfo(FETCH_HOME_CHANNEL_ID, notificationBuilder.build());
}
@NonNull
@Override
public Result doWork() {
setForegroundAsync(createForegroundInfo());
String instance = getInputData().getString(Helper.ARG_INSTANCE);
String userId = getInputData().getString(Helper.ARG_USER_ID);
try {
BaseAccount account = new Account(getApplicationContext()).getUniqAccount(userId, instance);
if (account != null) {
try {
fetchHome(getApplicationContext(), account);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (DBException e) {
e.printStackTrace();
}
return Result.success(new Data.Builder().putString("WORK_RESULT", getApplicationContext().getString(R.string.notifications)).build());
}
private void fetchHome(Context context, BaseAccount account) throws IOException {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context);
boolean fetch_home = prefs.getBoolean(context.getString(R.string.SET_FETCH_HOME) + account.user_id + account.instance, false);
if (fetch_home) {
int max_calls = 5;
int status_per_page = 80;
//Browse last 400 home messages
boolean canContinue = true;
int call = 0;
String max_id = null;
MastodonTimelinesService mastodonTimelinesService = init(account.instance);
while (canContinue && call < max_calls) {
Call<List<Status>> homeCall = mastodonTimelinesService.getHome(account.token, max_id, null, null, status_per_page, null);
if (homeCall != null) {
Response<List<Status>> homeResponse = homeCall.execute();
if (homeResponse.isSuccessful()) {
List<Status> statusList = homeResponse.body();
if (statusList != null && statusList.size() > 0) {
for (Status status : statusList) {
StatusCache statusCacheDAO = new StatusCache(getApplicationContext());
StatusCache statusCache = new StatusCache();
statusCache.instance = account.instance;
statusCache.user_id = account.user_id;
statusCache.status = status;
statusCache.type = Timeline.TimeLineEnum.HOME;
statusCache.status_id = status.id;
try {
statusCacheDAO.insertOrUpdate(statusCache, Timeline.TimeLineEnum.HOME.getValue());
} catch (DBException e) {
e.printStackTrace();
}
}
Pagination pagination = MastodonHelper.getPagination(homeResponse.headers());
if (pagination.max_id != null) {
max_id = pagination.max_id;
} else {
canContinue = false;
}
} else {
canContinue = false;
}
} else {
canContinue = false;
}
}
//Pause between calls (1 second)
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
call++;
}
}
}
private MastodonTimelinesService init(String instance) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://" + instance + "/api/v1/")
.addConverterFactory(GsonConverterFactory.create(Helper.getDateBuilder()))
.client(okHttpClient)
.build();
return retrofit.create(MastodonTimelinesService.class);
}
}

View file

@ -105,7 +105,7 @@ public class NotificationsWorker extends Worker {
public Result doWork() {
setForegroundAsync(createForegroundInfo());
try {
List<BaseAccount> accounts = new Account(getApplicationContext()).getAll();
List<BaseAccount> accounts = new Account(getApplicationContext()).getCrossAccounts();
for (BaseAccount account : accounts) {
try {
NotificationsHelper.task(getApplicationContext(), account.user_id + "@" + account.instance);

View file

@ -237,7 +237,7 @@ public class AccountAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
} else if (finalDoAction == ProfileActivity.action.UNFOLLOW) {
boolean confirm_unfollow = sharedpreferences.getBoolean(context.getString(R.string.SET_UNFOLLOW_VALIDATION), true);
if (confirm_unfollow) {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context);
unfollowConfirm.setTitle(context.getString(R.string.unfollow_confirm));
unfollowConfirm.setMessage(account.acct);
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());

View file

@ -158,7 +158,7 @@ public class AnnouncementAdapter extends RecyclerView.Adapter<AnnouncementAdapte
emojiPopup.toggle();
});
holder.binding.statusAddCustomEmoji.setOnClickListener(v -> {
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
int paddingPixel = 15;
float density = context.getResources().getDisplayMetrics().density;
int paddingDp = (int) (paddingPixel * density);

View file

@ -28,6 +28,7 @@ import app.fedilab.android.databinding.DrawerCacheBinding;
import app.fedilab.android.mastodon.client.entities.app.CacheAccount;
import app.fedilab.android.mastodon.helper.CacheHelper;
import app.fedilab.android.mastodon.helper.MastodonHelper;
import app.fedilab.android.peertube.helper.Helper;
public class CacheAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@ -61,9 +62,17 @@ public class CacheAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
CacheAccount cacheAccount = accountList.get(position);
AccountCacheViewHolder holder = (AccountCacheViewHolder) viewHolder;
MastodonHelper.loadPPMastodon(holder.binding.pp, cacheAccount.account.mastodon_account);
holder.binding.acct.setText(String.format("@%s@%s", cacheAccount.account.mastodon_account.username, cacheAccount.account.instance));
holder.binding.displayName.setText(cacheAccount.account.mastodon_account.display_name);
if (cacheAccount.account.mastodon_account != null) {
MastodonHelper.loadPPMastodon(holder.binding.pp, cacheAccount.account.mastodon_account);
holder.binding.acct.setText(String.format("@%s@%s", cacheAccount.account.mastodon_account.username, cacheAccount.account.instance));
holder.binding.displayName.setText(cacheAccount.account.mastodon_account.display_name);
} else if (cacheAccount.account.peertube_account != null) {
Helper.loadAvatar(context, cacheAccount.account.peertube_account, holder.binding.pp);
holder.binding.acct.setText(String.format("@%s@%s", cacheAccount.account.peertube_account.getUsername(), cacheAccount.account.instance));
holder.binding.displayName.setText(cacheAccount.account.peertube_account.getDisplayName());
}
CacheHelper.getTimelineValues(context, cacheAccount.account, countStatuses -> {
if (countStatuses != null && countStatuses.size() == 3) {
holder.binding.homeCount.setText(String.valueOf(countStatuses.get(0)));

View file

@ -20,6 +20,7 @@ import static app.fedilab.android.BaseMainActivity.currentAccount;
import static app.fedilab.android.BaseMainActivity.emojis;
import static app.fedilab.android.BaseMainActivity.instanceInfo;
import static app.fedilab.android.mastodon.activities.ComposeActivity.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE;
import static de.timfreiheit.mathjax.android.MathJaxConfig.Input.TeX;
import android.Manifest;
import android.annotation.SuppressLint;
@ -127,6 +128,8 @@ import app.fedilab.android.mastodon.helper.ThemeHelper;
import app.fedilab.android.mastodon.imageeditor.EditImageActivity;
import app.fedilab.android.mastodon.viewmodel.mastodon.AccountsVM;
import app.fedilab.android.mastodon.viewmodel.mastodon.SearchVM;
import de.timfreiheit.mathjax.android.MathJaxConfig;
import de.timfreiheit.mathjax.android.MathJaxView;
import es.dmoral.toasty.Toasty;
@ -311,8 +314,10 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
}
//Put other accounts mentioned at the bottom
boolean capitalize = sharedpreferences.getBoolean(context.getString(R.string.SET_CAPITALIZE), true);
boolean mentionsAtTop = sharedpreferences.getBoolean(context.getString(R.string.SET_MENTIONS_AT_TOP), false);
if (inReplyToUser != null) {
if (capitalize) {
if (capitalize && !mentionsAtTop) {
statusDraft.text = inReplyToUser.acct.startsWith("@") ? inReplyToUser.acct + "\n" : "@" + inReplyToUser.acct + "\n";
} else {
statusDraft.text = inReplyToUser.acct.startsWith("@") ? inReplyToUser.acct + " " : "@" + inReplyToUser.acct + " ";
@ -321,7 +326,9 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
holder.binding.content.setText(statusDraft.text);
statusDraft.cursorPosition = statusDraft.text.length();
if (statusDraft.mentions.size() > 1) {
statusDraft.text += "\n";
if (!mentionsAtTop) {
statusDraft.text += "\n";
}
for (int i = 1; i < statusDraft.mentions.size(); i++) {
String tootTemp = String.format("@%s ", statusDraft.mentions.get(i).acct);
statusDraft.text = String.format("%s ", (statusDraft.text + tootTemp.trim()));
@ -392,7 +399,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
* @param position - int position of the media in the message
*/
private void pickupMedia(ComposeActivity.mediaType type, int position) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) context,
@ -702,19 +709,26 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
}
Matcher mathsPatterns = Helper.mathsComposePattern.matcher((s.toString()));
if (mathsPatterns.find()) {
if (holder.binding.laTexViewContainer.getVisibility() != View.VISIBLE) {
holder.binding.laTexViewContainer.setVisibility(View.VISIBLE);
if (holder.binding.laTexViewContainer.getChildCount() == 0) {
MathJaxConfig mathJaxConfig = new MathJaxConfig();
mathJaxConfig.setAutomaticLinebreaks(true);
mathJaxConfig.setInput(TeX);
switch (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) {
case Configuration.UI_MODE_NIGHT_YES:
holder.binding.laTexView.setTextColor("white");
mathJaxConfig.setTextColor("white");
break;
case Configuration.UI_MODE_NIGHT_NO:
holder.binding.laTexView.setTextColor("black");
mathJaxConfig.setTextColor("black");
break;
}
statusList.get(holder.getBindingAdapterPosition()).mathJaxView = new MathJaxView(context, mathJaxConfig);
holder.binding.laTexViewContainer.addView(statusList.get(holder.getBindingAdapterPosition()).mathJaxView);
holder.binding.laTexViewContainer.setVisibility(View.VISIBLE);
}
holder.binding.laTexView.setInputText(s.toString());
if (statusList.get(holder.getBindingAdapterPosition()).mathJaxView != null) {
statusList.get(holder.getBindingAdapterPosition()).mathJaxView.setInputText(s.toString());
}
} else {
holder.binding.laTexViewContainer.setVisibility(View.GONE);
}
@ -959,14 +973,14 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
}
if (description != null && description.trim().length() > 0) {
if (url != null && !description.contains(url)) {
statusList.get(position).text += url + "\n";
statusList.get(position).text += url + "\n>";
}
statusList.get(position).text += ">" + description + "\n\n";
statusList.get(position).text += description + "\n\n";
} else if (content != null && content.trim().length() > 0) {
if (!content.contains(url)) {
statusList.get(position).text += url + "\n";
statusList.get(position).text += url + "\n>";
}
statusList.get(position).text += ">" + content + "\n\n";
statusList.get(position).text += content + "\n\n";
} else {
statusList.get(position).text += url + "\n\n";
}
@ -1046,12 +1060,12 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
for (Attachment attachment : attachmentList) {
ComposeAttachmentItemBinding composeAttachmentItemBinding = ComposeAttachmentItemBinding.inflate(LayoutInflater.from(context), holder.binding.attachmentsList, false);
composeAttachmentItemBinding.buttonPlay.setVisibility(View.GONE);
if (editMessageId != null && attachment.url != null) {
/* if (editMessageId != null && attachment.url != null) {
composeAttachmentItemBinding.editPreview.setVisibility(View.GONE);
composeAttachmentItemBinding.buttonDescription.setVisibility(View.INVISIBLE);
composeAttachmentItemBinding.buttonOrderDown.setVisibility(View.INVISIBLE);
composeAttachmentItemBinding.buttonOrderUp.setVisibility(View.INVISIBLE);
}
}*/
String attachmentPath = attachment.local_path != null && !attachment.local_path.trim().isEmpty() ? attachment.local_path : attachment.preview_url;
if (attachment.type != null || attachment.mimeType != null) {
if ((attachment.type != null && attachment.type.toLowerCase().startsWith("image")) || (attachment.mimeType != null && attachment.mimeType.toLowerCase().startsWith("image"))) {
@ -1111,8 +1125,8 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
context.startActivity(intent);
});
composeAttachmentItemBinding.buttonDescription.setOnClickListener(v -> {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
builderInner.setTitle(R.string.upload_form_description);
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context);
// builderInner.setTitle(R.string.upload_form_description);
PopupMediaDescriptionBinding popupMediaDescriptionBinding = PopupMediaDescriptionBinding.inflate(LayoutInflater.from(context), null, false);
builderInner.setView(popupMediaDescriptionBinding.getRoot());
@ -1173,7 +1187,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
}
});
composeAttachmentItemBinding.buttonRemove.setOnClickListener(v -> {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context);
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
builderInner.setPositiveButton(R.string.delete, (dialog, which) -> {
attachmentList.remove(attachment);
@ -1297,12 +1311,14 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
ComposeViewHolder holder = (ComposeViewHolder) viewHolder;
boolean extraFeatures = sharedpreferences.getBoolean(context.getString(R.string.SET_EXTAND_EXTRA_FEATURES) + MainActivity.currentUserID + MainActivity.currentInstance, false);
boolean mathsComposer = sharedpreferences.getBoolean(context.getString(R.string.SET_MATHS_COMPOSER), true);
boolean forwardTag = sharedpreferences.getBoolean(context.getString(R.string.SET_FORWARD_TAGS_IN_REPLY), true);
if (mathsComposer) {
holder.binding.buttonMathsComposer.setVisibility(View.VISIBLE);
holder.binding.buttonMathsComposer.setOnClickListener(v -> {
int cursorPosition = holder.binding.content.getSelectionStart();
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
Resources res = context.getResources();
String[] formatArr = res.getStringArray(R.array.SET_MATHS_FORMAT);
builder.setItems(formatArr, (dialogInterface, i) -> {
@ -1333,7 +1349,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
holder.binding.buttonLocalOnly.setVisibility(View.VISIBLE);
}
holder.binding.buttonTextFormat.setOnClickListener(v -> {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(context.getString(R.string.post_format));
Resources res = context.getResources();
String[] formatArr = res.getStringArray(R.array.SET_POST_FORMAT);
@ -1358,7 +1374,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
builder.create().show();
});
holder.binding.buttonLocalOnly.setOnClickListener(v -> {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(context.getString(R.string.local_only));
Resources res = context.getResources();
boolean[] valArr = new boolean[]{false, true};
@ -1565,13 +1581,48 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
currentCursorPosition = holder.getLayoutPosition();
}
});
boolean capitalize = sharedpreferences.getBoolean(context.getString(R.string.SET_CAPITALIZE), true);
boolean mentionsAtTop = sharedpreferences.getBoolean(context.getString(R.string.SET_MENTIONS_AT_TOP), false);
if (statusDraft.cursorPosition <= holder.binding.content.length()) {
holder.binding.content.setSelection(statusDraft.cursorPosition);
if (!mentionsAtTop) {
holder.binding.content.setSelection(statusDraft.cursorPosition);
} else {
if (capitalize && !statusDraft.text.endsWith("\n")) {
statusDraft.text += "\n";
holder.binding.content.setText(statusDraft.text);
}
holder.binding.content.setSelection(holder.binding.content.getText().length());
}
}
if (statusDraft.setCursorToEnd) {
statusDraft.setCursorToEnd = false;
holder.binding.content.setSelection(holder.binding.content.getText().length());
}
if (forwardTag && position > 0 && statusDraft.text != null && !statusDraft.text.contains("#")) {
Status status = statusList.get(position - 1).reblog == null ? statusList.get(position - 1) : statusList.get(position - 1).reblog;
if (status.tags != null && status.tags.size() > 0) {
statusDraft.text += "\n\n";
int lenght = 0;
for (Tag tag : status.tags) {
statusDraft.text += "#" + tag.name + " ";
lenght += ("#" + tag.name + " ").length();
}
holder.binding.content.setText(statusDraft.text);
statusDraft.cursorPosition = statusDraft.text.length() - lenght - 3;
statusDraft.setCursorToEnd = false;
holder.binding.content.setSelection(statusDraft.text.length() - lenght - 3);
}
} else if (forwardTag && position > 0 && statusDraft.text != null && statusDraft.text.contains("#")) {
Status status = statusList.get(position - 1).reblog == null ? statusList.get(position - 1) : statusList.get(position - 1).reblog;
int lenght = 0;
for (Tag tag : status.tags) {
lenght += ("#" + tag.name + " ").length();
}
statusDraft.cursorPosition = statusDraft.text.length() - lenght - 3;
statusDraft.setCursorToEnd = false;
holder.binding.content.setSelection(statusDraft.text.length() - lenght - 3);
}
if (statusDraft.spoiler_text != null) {
holder.binding.contentSpoiler.setText(statusDraft.spoiler_text);
holder.binding.contentSpoiler.setSelection(holder.binding.contentSpoiler.getText().length());
@ -1674,7 +1725,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
}
SharedPreferences.Editor editor = sharedpreferences.edit();
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(context.getString(R.string.message_language));
builder.setSingleChoiceItems(languagesArr, selection, null);
@ -1708,7 +1759,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
* @param position - int position
*/
private void displayPollPopup(ComposeViewHolder holder, Status statusDraft, int position) {
AlertDialog.Builder alertPoll = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder alertPoll = new MaterialAlertDialogBuilder(context);
alertPoll.setTitle(R.string.create_poll);
ComposePollBinding composePollBinding = ComposePollBinding.inflate(LayoutInflater.from(context), new LinearLayout(context), false);
alertPoll.setView(composePollBinding.getRoot());
@ -1951,7 +2002,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
*/
private void displayEmojiPicker(ComposeViewHolder holder, String instance) throws DBException {
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
int paddingPixel = 15;
float density = context.getResources().getDisplayMetrics().density;
int paddingDp = (int) (paddingPixel * density);

View file

@ -76,7 +76,7 @@ public class DomainBlockAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
holder.binding.domainName.setText(domain);
AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(AccountsVM.class);
holder.binding.unblockDomain.setOnClickListener(v -> {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context);
alt_bld.setMessage(context.getString(R.string.unblock_domain_confirm, domain));
alt_bld.setPositiveButton(R.string.yes, (dialog, id) -> {
accountsVM.removeDomainBlocks(MainActivity.currentInstance, MainActivity.currentToken, domain);

View file

@ -34,7 +34,6 @@ import app.fedilab.android.R;
import app.fedilab.android.databinding.DrawerFilterBinding;
import app.fedilab.android.mastodon.activities.FilterActivity;
import app.fedilab.android.mastodon.client.entities.api.Filter;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.viewmodel.mastodon.FiltersVM;
@ -90,7 +89,7 @@ public class FilterAdapter extends RecyclerView.Adapter<FilterAdapter.FilterView
}
}));
holder.binding.deleteFilter.setOnClickListener(v -> {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(R.string.action_filter_delete);
builder.setMessage(R.string.action_lists_confirm_delete);
builder.setIcon(android.R.drawable.ic_dialog_alert)

View file

@ -34,6 +34,7 @@ import app.fedilab.android.mastodon.client.entities.api.Reaction;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.helper.ThemeHelper;
import app.fedilab.android.mastodon.viewmodel.mastodon.AnnouncementsVM;
import app.fedilab.android.mastodon.viewmodel.mastodon.StatusesVM;
import app.fedilab.android.mastodon.viewmodel.pleroma.ActionsVM;
@ -46,18 +47,29 @@ public class ReactionAdapter extends RecyclerView.Adapter<ReactionAdapter.Reacti
private final List<Reaction> reactions;
private final String announcementId;
private final boolean statusReaction;
private final boolean isPleroma;
private Context context;
ReactionAdapter(String announcementId, List<Reaction> reactions, boolean statusReaction, boolean isPleroma) {
this.reactions = reactions;
this.announcementId = announcementId;
this.statusReaction = statusReaction;
this.isPleroma = isPleroma;
}
ReactionAdapter(String announcementId, List<Reaction> reactions, boolean statusReaction) {
this.reactions = reactions;
this.announcementId = announcementId;
this.statusReaction = statusReaction;
this.isPleroma = true;
}
ReactionAdapter(String announcementId, List<Reaction> reactions) {
this.reactions = reactions;
this.announcementId = announcementId;
this.statusReaction = false;
this.isPleroma = true;
}
@NonNull
@ -101,7 +113,7 @@ public class ReactionAdapter extends RecyclerView.Adapter<ReactionAdapter.Reacti
}
notifyItemChanged(position);
});
} else {
} else if (isPleroma) {
ActionsVM actionVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
holder.binding.reactionContainer.setOnClickListener(v -> {
if (reaction.me) {
@ -115,6 +127,20 @@ public class ReactionAdapter extends RecyclerView.Adapter<ReactionAdapter.Reacti
}
notifyItemChanged(position);
});
} else {
StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class);
holder.binding.reactionContainer.setOnClickListener(v -> {
if (reaction.me) {
statusesVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, announcementId, reaction.name);
reaction.me = false;
reaction.count -= 1;
} else {
statusesVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, announcementId, reaction.name);
reaction.me = true;
reaction.count += 1;
}
notifyItemChanged(position);
});
}
}

View file

@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import app.fedilab.android.R;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.databinding.DrawerReorderBinding;
import app.fedilab.android.mastodon.activities.ReorderTimelinesActivity;
import app.fedilab.android.mastodon.client.entities.app.BottomMenu;
@ -100,6 +101,8 @@ public class ReorderBottomMenuAdapter extends RecyclerView.Adapter<RecyclerView.
holder.binding.hide.setOnClickListener(v -> {
bottomMenu.bottom_menu.get(position).visible = !bottomMenu.bottom_menu.get(position).visible;
bottomMenu.user_id = MainActivity.currentUserID;
bottomMenu.instance = MainActivity.currentInstance;
if (bottomMenu.bottom_menu.get(position).visible) {
holder.binding.hide.setImageResource(R.drawable.ic_baseline_visibility_24);
} else {

View file

@ -42,7 +42,6 @@ import app.fedilab.android.mastodon.client.entities.app.PinnedTimeline;
import app.fedilab.android.mastodon.client.entities.app.RemoteInstance;
import app.fedilab.android.mastodon.client.entities.app.Timeline;
import app.fedilab.android.mastodon.exception.DBException;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.helper.itemtouchhelper.ItemTouchHelperAdapter;
import app.fedilab.android.mastodon.helper.itemtouchhelper.ItemTouchHelperViewHolder;
import app.fedilab.android.mastodon.helper.itemtouchhelper.OnStartDragListener;
@ -185,7 +184,7 @@ public class ReorderTabAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
}
holder.binding.delete.setOnClickListener(v -> {
if (item.type == Timeline.TimeLineEnum.TAG || item.type == Timeline.TimeLineEnum.REMOTE || item.type == Timeline.TimeLineEnum.LIST) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context);
String title = "";
String message = "";
alt_bld.setTitle(R.string.action_lists_delete);

View file

@ -50,6 +50,7 @@ import android.os.Looper;
import android.text.Html;
import android.text.SpannableString;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@ -414,6 +415,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
boolean compactButtons = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_COMPACT_ACTION_BUTTON), false);
boolean originalDateForBoost = sharedpreferences.getBoolean(context.getString(R.string.SET_BOOST_ORIGINAL_DATE), true);
boolean hideSingleMediaWithCard = sharedpreferences.getBoolean(context.getString(R.string.SET_HIDE_SINGLE_MEDIA_WITH_CARD), false);
boolean autofetch = sharedpreferences.getBoolean(context.getString(R.string.SET_AUTO_FETCH_MISSING_MESSAGES), false);
if (compactButtons) {
ConstraintSet set = new ConstraintSet();
@ -517,7 +520,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.binding.quotedMessage.cardviewContainer.setVisibility(View.GONE);
}
if (currentAccount != null && currentAccount.api == Account.API.PLEROMA) {
if (currentAccount != null && currentAccount.api == Account.API.PLEROMA || status.reactions != null) {
if (status.pleroma != null && status.pleroma.emoji_reactions != null && status.pleroma.emoji_reactions.size() > 0) {
holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE);
ReactionAdapter reactionAdapter = new ReactionAdapter(status.id, status.pleroma.emoji_reactions, true);
@ -525,6 +528,13 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
LinearLayoutManager layoutManager
= new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
holder.binding.layoutReactions.reactionsView.setLayoutManager(layoutManager);
} else if (status.reactions != null && status.reactions.size() > 0) {
holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE);
ReactionAdapter reactionAdapter = new ReactionAdapter(status.id, status.reactions, true, false);
holder.binding.layoutReactions.reactionsView.setAdapter(reactionAdapter);
LinearLayoutManager layoutManager
= new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
holder.binding.layoutReactions.reactionsView.setLayoutManager(layoutManager);
} else {
holder.binding.layoutReactions.getRoot().setVisibility(View.GONE);
holder.binding.layoutReactions.reactionsView.setAdapter(null);
@ -537,33 +547,57 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}).setOnEmojiClickListener((emoji, imageView) -> {
String emojiStr = imageView.getUnicode();
boolean alreadyAdded = false;
if (status.pleroma == null || status.pleroma.emoji_reactions == null) {
return;
}
for (Reaction reaction : status.pleroma.emoji_reactions) {
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) {
alreadyAdded = true;
reaction.count = (reaction.count - 1);
if (reaction.count == 0) {
status.pleroma.emoji_reactions.remove(reaction);
if (status.pleroma != null && status.pleroma.emoji_reactions != null) {
for (Reaction reaction : status.pleroma.emoji_reactions) {
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) {
alreadyAdded = true;
reaction.count = (reaction.count - 1);
if (reaction.count == 0) {
status.pleroma.emoji_reactions.remove(reaction);
}
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
}
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
}
}
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
status.pleroma.emoji_reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
}
ActionsVM actionVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
if (alreadyAdded) {
actionVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
} else {
actionVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
status.pleroma.emoji_reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
}
ActionsVM actionVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
if (alreadyAdded) {
actionVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
} else {
actionVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
}
} else if (status.reactions != null) {
for (Reaction reaction : status.reactions) {
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) {
alreadyAdded = true;
reaction.count = (reaction.count - 1);
if (reaction.count == 0) {
status.reactions.remove(reaction);
}
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
}
}
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
status.reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
}
if (alreadyAdded) {
statusesVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
} else {
statusesVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
}
}
})
.build(holder.binding.layoutReactions.fakeEdittext);
@ -571,7 +605,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
});
holder.binding.statusAddCustomEmoji.setOnClickListener(v -> {
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
int paddingPixel = 15;
float density = context.getResources().getDisplayMetrics().density;
int paddingDp = (int) (paddingPixel * density);
@ -589,32 +623,61 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
String url = emojis.get(BaseMainActivity.currentInstance).get(index).url;
String static_url = emojis.get(BaseMainActivity.currentInstance).get(index).static_url;
boolean alreadyAdded = false;
for (Reaction reaction : status.pleroma.emoji_reactions) {
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) {
alreadyAdded = true;
reaction.count = (reaction.count - 1);
if (reaction.count == 0) {
status.pleroma.emoji_reactions.remove(reaction);
if (status.pleroma != null && status.pleroma.emoji_reactions != null) {
for (Reaction reaction : status.pleroma.emoji_reactions) {
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) {
alreadyAdded = true;
reaction.count = (reaction.count - 1);
if (reaction.count == 0) {
status.pleroma.emoji_reactions.remove(reaction);
}
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
}
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
}
}
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
reaction.url = url;
reaction.static_url = static_url;
status.pleroma.emoji_reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
}
ActionsVM actionsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
if (alreadyAdded) {
actionsVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
} else {
actionsVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
reaction.url = url;
reaction.static_url = static_url;
status.pleroma.emoji_reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
}
ActionsVM actionsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
if (alreadyAdded) {
actionsVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
} else {
actionsVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
}
} else if (status.reactions != null) {
for (Reaction reaction : status.reactions) {
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) {
alreadyAdded = true;
reaction.count = (reaction.count - 1);
if (reaction.count == 0) {
status.reactions.remove(reaction);
}
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
}
}
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
reaction.url = url;
reaction.static_url = static_url;
status.reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
}
if (alreadyAdded) {
statusesVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
} else {
statusesVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
}
}
});
gridView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);
@ -680,7 +743,10 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
MathJaxView mathview = new MathJaxView(context, mathJaxConfig);
holder.binding.statusContentMaths.addView(mathview);
if (status.contentSpan != null) {
mathview.setInputText(status.contentSpan.toString());
String input = status.contentSpan.toString();
input = input.replaceAll("'", "&#39;");
input = input.replaceAll("\"", "&#34;");
mathview.setInputText(input);
} else {
status.mathsShown = false;
holder.binding.statusContentMaths.setVisibility(View.GONE);
@ -841,7 +907,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
});
holder.binding.actionButtonFavorite.setChecked(statusToDeal.favourited);
holder.binding.statusUserInfo.setOnClickListener(v -> {
holder.binding.avatar.setOnClickListener(v -> {
if (remote) {
Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show();
searchVM.search(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.uri, null, "statuses", false, true, false, 0, null, null, 1)
@ -911,7 +977,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
});
holder.binding.actionButtonBoost.setOnClickListener(v -> {
if (confirmBoost) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context);
if (statusToDeal.reblogged) {
alt_bld.setMessage(context.getString(R.string.reblog_remove));
} else {
@ -981,7 +1047,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
});
holder.binding.actionButtonFavorite.setOnClickListener(v -> {
if (confirmFav) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context);
if (status.favourited) {
alt_bld.setMessage(context.getString(R.string.favourite_remove));
} else {
@ -1064,7 +1130,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
//Button sizes depending of the defined scale
float normalSize = Helper.convertDpToPixel(28, context);
holder.binding.actionButtonReply.getLayoutParams().width = (int) (normalSize * scaleIcon);
holder.binding.actionButtonReply.getLayoutParams().height = (int) (normalSize * scaleIcon);
holder.binding.actionButtonReply.requestLayout();
@ -1077,6 +1142,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.binding.actionButtonFavorite.setImageSize((int) (normalSize * scaleIcon));
holder.binding.actionButtonBookmark.setImageSize((int) (normalSize * scaleIcon));
holder.binding.statusAddCustomEmoji.getLayoutParams().width = (int) (normalSize * scaleIcon);
holder.binding.statusAddCustomEmoji.getLayoutParams().height = (int) (normalSize * scaleIcon);
holder.binding.statusAddCustomEmoji.requestLayout();
@ -1657,6 +1723,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
});
if (!minified && canBeFederated) {
holder.binding.mainContainer.setOnClickListener(v -> holder.binding.statusContent.callOnClick());
holder.binding.statusUserInfo.setOnClickListener(v -> {
holder.binding.statusContent.callOnClick();
});
holder.binding.statusContent.setOnClickListener(v -> {
if (status.isFocused || v.getTag() == SpannableHelper.CLICKABLE_SPAN) {
if (v.getTag() == SpannableHelper.CLICKABLE_SPAN) {
@ -1753,7 +1822,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
popup.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_redraft) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context);
builderInner.setTitle(stringArrayConf[1]);
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
builderInner.setPositiveButton(R.string.yes, (dialog, which) -> {
@ -1812,7 +1881,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
} else if (itemId == R.id.action_open_browser) {
Helper.openBrowser(context, statusToDeal.url);
} else if (itemId == R.id.action_remove) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context);
builderInner.setTitle(stringArrayConf[0]);
builderInner.setMessage(statusToDeal.content);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
@ -1829,7 +1898,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}));
builderInner.show();
} else if (itemId == R.id.action_block_domain) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context);
builderInner.setTitle(stringArrayConf[3]);
String domain = statusToDeal.account.acct.split("@")[1];
builderInner.setMessage(context.getString(R.string.block_domain_confirm_message, domain));
@ -1840,7 +1909,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
});
builderInner.show();
} else if (itemId == R.id.action_mute) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context);
builderInner.setTitle(stringArrayConf[0]);
builderInner.setMessage(statusToDeal.account.acct);
builderInner.setNeutralButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
@ -1856,7 +1925,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}));
builderInner.show();
} else if (itemId == R.id.action_mute_home) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context);
builderInner.setTitle(R.string.mute_home);
builderInner.setMessage(statusToDeal.account.acct);
builderInner.setNeutralButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
@ -1887,7 +1956,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
MastodonHelper.scheduleBoost(context, MastodonHelper.ScheduleType.TIMED_MUTED, statusToDeal, null, null);
return true;
} else if (itemId == R.id.action_block) {
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context);
builderInner.setTitle(stringArrayConf[1]);
builderInner.setMessage(statusToDeal.account.acct);
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
@ -1976,7 +2045,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(context);
builderSingle.setTitle(context.getString(R.string.choose_accounts));
final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accountList);
final BaseAccount[] accountArray = new BaseAccount[accounts.size()];
@ -2089,44 +2158,65 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
if (status.isFetchMore && fetchMoreCallBack != null) {
DrawerFetchMoreBinding drawerFetchMoreBinding = DrawerFetchMoreBinding.inflate(LayoutInflater.from(context));
if (status.positionFetchMore == Status.PositionFetchMore.BOTTOM) {
holder.binding.fetchMoreContainerBottom.setVisibility(View.GONE);
holder.binding.fetchMoreContainerTop.setVisibility(View.VISIBLE);
holder.binding.fetchMoreContainerTop.removeAllViews();
holder.binding.fetchMoreContainerTop.addView(drawerFetchMoreBinding.getRoot());
} else {
holder.binding.fetchMoreContainerBottom.setVisibility(View.VISIBLE);
holder.binding.fetchMoreContainerTop.setVisibility(View.GONE);
holder.binding.fetchMoreContainerBottom.removeAllViews();
holder.binding.fetchMoreContainerBottom.addView(drawerFetchMoreBinding.getRoot());
}
drawerFetchMoreBinding.fetchMoreMin.setOnClickListener(v -> {
status.isFetchMore = false;
int position = holder.getBindingAdapterPosition();
adapter.notifyItemChanged(position);
if (position < statusList.size() - 1) {
if (!autofetch) {
DrawerFetchMoreBinding drawerFetchMoreBinding = DrawerFetchMoreBinding.inflate(LayoutInflater.from(context));
if (status.positionFetchMore == Status.PositionFetchMore.BOTTOM) {
holder.binding.fetchMoreContainerBottom.setVisibility(View.GONE);
holder.binding.fetchMoreContainerTop.setVisibility(View.VISIBLE);
holder.binding.fetchMoreContainerTop.removeAllViews();
holder.binding.fetchMoreContainerTop.addView(drawerFetchMoreBinding.getRoot());
} else {
holder.binding.fetchMoreContainerBottom.setVisibility(View.VISIBLE);
holder.binding.fetchMoreContainerTop.setVisibility(View.GONE);
holder.binding.fetchMoreContainerBottom.removeAllViews();
holder.binding.fetchMoreContainerBottom.addView(drawerFetchMoreBinding.getRoot());
}
drawerFetchMoreBinding.fetchMoreMin.setOnClickListener(v -> {
status.isFetchMore = false;
int position = holder.getBindingAdapterPosition();
adapter.notifyItemChanged(position);
if (position < statusList.size() - 1) {
String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
fromId = statusList.get(position + 1).id;
} else {
fromId = status.id;
}
fetchMoreCallBack.onClickMinId(fromId, status);
}
});
drawerFetchMoreBinding.fetchMoreMax.setOnClickListener(v -> {
//We hide the button
status.isFetchMore = false;
String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
fromId = statusList.get(position + 1).id;
fromId = statusList.get(holder.getBindingAdapterPosition()).id;
} else {
fromId = status.id;
fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id;
}
fetchMoreCallBack.onClickMinId(fromId, status);
}
});
drawerFetchMoreBinding.fetchMoreMax.setOnClickListener(v -> {
//We hide the button
fetchMoreCallBack.onClickMaxId(fromId, status);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
});
} else {
holder.binding.fetchMoreContainerBottom.setVisibility(View.GONE);
holder.binding.fetchMoreContainerTop.setVisibility(View.GONE);
status.isFetchMore = false;
String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
fromId = statusList.get(holder.getBindingAdapterPosition()).id;
} else {
fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id;
int position = holder.getBindingAdapterPosition();
String statusIdMin = null, statusIdMax;
if (position < statusList.size() - 1) {
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
statusIdMin = statusList.get(position + 1).id;
} else {
statusIdMin = status.id;
}
}
fetchMoreCallBack.onClickMaxId(fromId, status);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
});
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
statusIdMax = statusList.get(holder.getBindingAdapterPosition()).id;
} else {
statusIdMax = statusList.get(holder.getBindingAdapterPosition() - 1).id;
}
fetchMoreCallBack.autoFetch(statusIdMin, statusIdMax, status);
}
} else {
holder.binding.fetchMoreContainerBottom.setVisibility(View.GONE);
holder.binding.fetchMoreContainerTop.setVisibility(View.GONE);
@ -2230,6 +2320,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
if ((!fullAttachement || statusToDeal.sensitive) && !singleImage) {
layoutMediaBinding.count.setText(String.format(Locale.getDefault(), "%d/%d", mediaPosition, statusToDeal.media_attachments.size()));
}
if (attachment.description != null && attachment.description.trim().length() > 0) {
layoutMediaBinding.media.setContentDescription(attachment.description.trim());
}
String finalUrl;
if (attachment.url == null) {
finalUrl = attachment.remote_url;
@ -2428,26 +2521,17 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
@Override
public List<Attachment> getPreloadItems(int position) {
List<Attachment> attachments = new ArrayList<>();
if (position == 0 && statusList.size() > 0) {
for (Status status : statusList.subList(0, 1)) {
Status statusToDeal = status.reblog != null ? status.reblog : status;
if (statusToDeal.media_attachments != null && statusToDeal.media_attachments.size() > 0) {
attachments.addAll(statusToDeal.media_attachments);
}
}
} else if (position > 0 && position < (statusList.size() - 1)) {
for (Status status : statusList.subList(position - 1, position + 1)) {
Status statusToDeal = status.reblog != null ? status.reblog : status;
if (statusToDeal.media_attachments != null && statusToDeal.media_attachments.size() > 0) {
attachments.addAll(statusToDeal.media_attachments);
}
}
} else {
for (Status status : statusList.subList(position, position)) {
Status statusToDeal = status.reblog != null ? status.reblog : status;
if (statusToDeal.media_attachments != null && statusToDeal.media_attachments.size() > 0) {
attachments.addAll(statusToDeal.media_attachments);
}
int max_size = statusList.size();
int siblings = 3;
int from = Math.max((position - siblings), 0);
if (from > max_size - 1) {
from = max_size - 1;
}
int to = Math.min(position + siblings, max_size - 1);
for (Status status : statusList.subList(from, to)) {
Status statusToDeal = status.reblog != null ? status.reblog : status;
if (statusToDeal.media_attachments != null && statusToDeal.media_attachments.size() > 0) {
attachments.addAll(statusToDeal.media_attachments);
}
}
return attachments;
@ -2593,32 +2677,53 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.bindingFilteredHide.dividerCard.setVisibility(View.GONE);
}
if (status.isFetchMore && fetchMoreCallBack != null) {
holder.bindingFilteredHide.layoutFetchMore.fetchMoreContainer.setVisibility(View.VISIBLE);
holder.bindingFilteredHide.layoutFetchMore.fetchMoreMin.setOnClickListener(v -> {
status.isFetchMore = false;
notifyItemChanged(holder.getBindingAdapterPosition());
if (holder.getBindingAdapterPosition() < statusList.size() - 1) {
boolean autofetch = sharedpreferences.getBoolean(context.getString(R.string.SET_AUTO_FETCH_MISSING_MESSAGES), false);
if (!autofetch) {
holder.bindingFilteredHide.layoutFetchMore.fetchMoreContainer.setVisibility(View.VISIBLE);
holder.bindingFilteredHide.layoutFetchMore.fetchMoreMin.setOnClickListener(v -> {
status.isFetchMore = false;
notifyItemChanged(holder.getBindingAdapterPosition());
if (holder.getBindingAdapterPosition() < statusList.size() - 1) {
String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
fromId = statusList.get(holder.getBindingAdapterPosition() + 1).id;
} else {
fromId = status.id;
}
fetchMoreCallBack.onClickMinId(fromId, status);
}
});
holder.bindingFilteredHide.layoutFetchMore.fetchMoreMax.setOnClickListener(v -> {
//We hide the button
status.isFetchMore = false;
notifyItemChanged(holder.getBindingAdapterPosition());
String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
fromId = statusList.get(holder.getBindingAdapterPosition() + 1).id;
fromId = statusList.get(holder.getBindingAdapterPosition()).id;
} else {
fromId = status.id;
fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id;
}
fetchMoreCallBack.onClickMinId(fromId, status);
}
});
holder.bindingFilteredHide.layoutFetchMore.fetchMoreMax.setOnClickListener(v -> {
//We hide the button
fetchMoreCallBack.onClickMaxId(fromId, status);
});
} else {
status.isFetchMore = false;
String fromId;
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
fromId = statusList.get(holder.getBindingAdapterPosition()).id;
} else {
fromId = statusList.get(holder.getBindingAdapterPosition() - 1).id;
String minId = null, maxId;
if (holder.getBindingAdapterPosition() < statusList.size() - 1) {
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
minId = statusList.get(holder.getBindingAdapterPosition() + 1).id;
} else {
minId = status.id;
}
}
fetchMoreCallBack.onClickMaxId(fromId, status);
notifyItemChanged(holder.getBindingAdapterPosition());
});
if (status.positionFetchMore == Status.PositionFetchMore.TOP) {
maxId = statusList.get(holder.getBindingAdapterPosition()).id;
} else {
maxId = statusList.get(holder.getBindingAdapterPosition() - 1).id;
}
fetchMoreCallBack.autoFetch(minId, maxId, status);
}
} else {
holder.bindingFilteredHide.layoutFetchMore.fetchMoreContainer.setVisibility(View.GONE);
}
@ -2774,6 +2879,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
void onClickMinId(String min_id, Status statusToUpdate);
void onClickMaxId(String max_id, Status statusToUpdate);
void autoFetch(String min_id, String max_id, Status status);
}
public static class StatusViewHolder extends RecyclerView.ViewHolder {

View file

@ -106,7 +106,7 @@ public class StatusDraftAdapter extends RecyclerView.Adapter<StatusDraftAdapter.
holder.binding.delete.setOnClickListener(v -> {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context);
unfollowConfirm.setMessage(context.getString(R.string.remove_draft));
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
unfollowConfirm.setPositiveButton(R.string.delete, (dialog, which) -> {

View file

@ -132,7 +132,7 @@ public class StatusScheduledAdapter extends RecyclerView.Adapter<StatusScheduled
});
holder.binding.delete.setOnClickListener(v -> {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context, Helper.dialogStyle());
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context);
unfollowConfirm.setMessage(context.getString(R.string.remove_scheduled));
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
unfollowConfirm.setPositiveButton(R.string.delete, (dialog, which) -> {

View file

@ -18,14 +18,11 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.preference.EditTextPreference;
import androidx.preference.MultiSelectListPreference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.SwitchPreferenceCompat;
import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.mastodon.helper.Helper;
public class FragmentComposeSettings extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -36,20 +33,13 @@ public class FragmentComposeSettings extends PreferenceFragmentCompat implements
}
private void createPref() {
SwitchPreferenceCompat SET_WATERMARK = findPreference(getString(R.string.SET_WATERMARK));
if (SET_WATERMARK != null) {
SET_WATERMARK.getContext().setTheme(Helper.dialogStyle());
}
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
EditTextPreference SET_WATERMARK_TEXT = findPreference(getString(R.string.SET_WATERMARK_TEXT));
if (SET_WATERMARK_TEXT != null) {
String val = sharedPreferences.getString(getString(R.string.SET_WATERMARK_TEXT) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance, sharedPreferences.getString(getString(R.string.SET_WATERMARK_TEXT), null));
SET_WATERMARK_TEXT.setText(val);
}
MultiSelectListPreference SET_SELECTED_LANGUAGE = findPreference(getString(R.string.SET_SELECTED_LANGUAGE));
if (SET_SELECTED_LANGUAGE != null) {
SET_SELECTED_LANGUAGE.getContext().setTheme(Helper.dialogStyle());
}
}
@Override

View file

@ -25,7 +25,6 @@ import androidx.preference.SwitchPreferenceCompat;
import app.fedilab.android.R;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.mastodon.helper.Helper;
public class FragmentExtraFeaturesSettings extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -72,14 +71,12 @@ public class FragmentExtraFeaturesSettings extends PreferenceFragmentCompat impl
ListPreference SET_POST_FORMAT = findPreference(getString(R.string.SET_POST_FORMAT));
if (SET_POST_FORMAT != null) {
SET_POST_FORMAT.getContext().setTheme(Helper.dialogStyle());
String format = sharedpreferences.getString(getString(R.string.SET_POST_FORMAT) + MainActivity.currentUserID + MainActivity.currentInstance, "text/plain");
SET_POST_FORMAT.setValue(format);
}
ListPreference SET_COMPOSE_LOCAL_ONLY = findPreference(getString(R.string.SET_COMPOSE_LOCAL_ONLY));
if (SET_COMPOSE_LOCAL_ONLY != null) {
SET_COMPOSE_LOCAL_ONLY.getContext().setTheme(Helper.dialogStyle());
int localOnly = sharedpreferences.getInt(getString(R.string.SET_COMPOSE_LOCAL_ONLY) + MainActivity.currentUserID + MainActivity.currentInstance, 0);
SET_COMPOSE_LOCAL_ONLY.setValue(String.valueOf(localOnly));
}

View file

@ -0,0 +1,120 @@
package app.fedilab.android.mastodon.ui.fragment.settings;
/* Copyright 2023 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.SharedPreferences;
import android.os.Bundle;
import androidx.preference.ListPreference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.work.Data;
import androidx.work.WorkManager;
import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.jobs.FetchHomeWorker;
import es.dmoral.toasty.Toasty;
public class FragmentHomeCacheSettings extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.pref_home_cache);
createPref();
}
private void createPref() {
getPreferenceScreen().removeAll();
addPreferencesFromResource(R.xml.pref_home_cache);
PreferenceScreen preferenceScreen = getPreferenceScreen();
if (preferenceScreen == null) {
Toasty.error(requireActivity(), getString(R.string.toast_error), Toasty.LENGTH_SHORT).show();
return;
}
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
SwitchPreference SET_FETCH_HOME = findPreference(getString(R.string.SET_FETCH_HOME));
if (SET_FETCH_HOME != null) {
boolean checked = sharedpreferences.getBoolean(getString(R.string.SET_FETCH_HOME) + MainActivity.currentUserID + MainActivity.currentInstance, false);
SET_FETCH_HOME.setChecked(checked);
}
ListPreference SET_FETCH_HOME_DELAY_VALUE = findPreference(getString(R.string.SET_FETCH_HOME_DELAY_VALUE));
if (SET_FETCH_HOME_DELAY_VALUE != null) {
String timeRefresh = sharedpreferences.getString(getString(R.string.SET_FETCH_HOME_DELAY_VALUE) + MainActivity.currentUserID + MainActivity.currentInstance, "60");
SET_FETCH_HOME_DELAY_VALUE.setValue(timeRefresh);
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (getActivity() != null) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
Data inputData = new Data.Builder()
.putString(Helper.ARG_INSTANCE, BaseMainActivity.currentInstance)
.putString(Helper.ARG_USER_ID, BaseMainActivity.currentUserID)
.build();
if (key.compareToIgnoreCase(getString(R.string.SET_FETCH_HOME)) == 0) {
SharedPreferences.Editor editor = sharedpreferences.edit();
SwitchPreference SET_FETCH_HOME = findPreference(getString(R.string.SET_FETCH_HOME));
if (SET_FETCH_HOME != null) {
editor.putBoolean(getString(R.string.SET_FETCH_HOME) + MainActivity.currentUserID + MainActivity.currentInstance, SET_FETCH_HOME.isChecked());
editor.commit();
if (SET_FETCH_HOME.isChecked()) {
FetchHomeWorker.setRepeatHome(requireActivity(), MainActivity.currentAccount, inputData);
} else {
WorkManager.getInstance(requireActivity()).cancelAllWorkByTag(Helper.WORKER_REFRESH_HOME + MainActivity.currentUserID + MainActivity.currentInstance);
}
}
}
if (key.compareToIgnoreCase(getString(R.string.SET_FETCH_HOME_DELAY_VALUE)) == 0) {
ListPreference SET_FETCH_HOME_DELAY_VALUE = findPreference(getString(R.string.SET_FETCH_HOME_DELAY_VALUE));
if (SET_FETCH_HOME_DELAY_VALUE != null) {
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(getString(R.string.SET_FETCH_HOME_DELAY_VALUE) + MainActivity.currentUserID + MainActivity.currentInstance, SET_FETCH_HOME_DELAY_VALUE.getValue());
editor.commit();
FetchHomeWorker.setRepeatHome(requireActivity(), MainActivity.currentAccount, inputData);
}
}
}
}
@Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
}

View file

@ -66,7 +66,6 @@ public class FragmentInterfaceSettings extends PreferenceFragmentCompat implemen
}
ListPreference SET_LOGO_LAUNCHER = findPreference(getString(R.string.SET_LOGO_LAUNCHER));
if (SET_LOGO_LAUNCHER != null) {
SET_LOGO_LAUNCHER.getContext().setTheme(Helper.dialogStyle());
SET_LOGO_LAUNCHER.setIcon(LogoHelper.getDrawable(SET_LOGO_LAUNCHER.getValue()));
}
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());

View file

@ -18,7 +18,6 @@ import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
@ -36,10 +35,6 @@ public class FragmentLanguageSettings extends PreferenceFragmentCompat implement
@SuppressLint("ApplySharedPref")
private void createPref() {
ListPreference SET_DEFAULT_LOCALE_NEW = findPreference(getString(R.string.SET_DEFAULT_LOCALE_NEW));
if (SET_DEFAULT_LOCALE_NEW != null) {
SET_DEFAULT_LOCALE_NEW.getContext().setTheme(Helper.dialogStyle());
}
Preference SET_TRANSLATE_VALUES_RESET = findPreference(getString(R.string.SET_TRANSLATE_VALUES_RESET));
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
if (SET_TRANSLATE_VALUES_RESET != null) {

View file

@ -36,7 +36,6 @@ import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.R;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.helper.PushHelper;
import app.fedilab.android.mastodon.helper.settings.TimePreference;
import app.fedilab.android.mastodon.helper.settings.TimePreferenceDialogFragment;
@ -80,9 +79,6 @@ public class FragmentNotificationsSettings extends PreferenceFragmentCompat impl
ListPreference SET_NOTIFICATION_TYPE = findPreference(getString(R.string.SET_NOTIFICATION_TYPE));
if (SET_NOTIFICATION_TYPE != null) {
SET_NOTIFICATION_TYPE.getContext().setTheme(Helper.dialogStyle());
}
String[] notificationValues = getResources().getStringArray(R.array.SET_NOTIFICATION_TYPE_VALUE);
if (SET_NOTIFICATION_TYPE != null && SET_NOTIFICATION_TYPE.getValue().equals(notificationValues[2])) {
PreferenceCategory notification_sounds = findPreference("notification_sounds");
@ -107,10 +103,6 @@ public class FragmentNotificationsSettings extends PreferenceFragmentCompat impl
}
return;
} else if (SET_NOTIFICATION_TYPE != null && SET_NOTIFICATION_TYPE.getValue().equals(notificationValues[1])) {
ListPreference SET_NOTIFICATION_DELAY_VALUE = findPreference(getString(R.string.SET_NOTIFICATION_DELAY_VALUE));
if (SET_NOTIFICATION_DELAY_VALUE != null) {
SET_NOTIFICATION_DELAY_VALUE.getContext().setTheme(Helper.dialogStyle());
}
ListPreference SET_PUSH_DISTRIBUTOR = findPreference("SET_PUSH_DISTRIBUTOR");
if (SET_PUSH_DISTRIBUTOR != null) {
preferenceScreen.removePreferenceRecursively("SET_PUSH_DISTRIBUTOR");
@ -122,7 +114,6 @@ public class FragmentNotificationsSettings extends PreferenceFragmentCompat impl
}
ListPreference SET_PUSH_DISTRIBUTOR = findPreference(getString(R.string.SET_PUSH_DISTRIBUTOR));
if (SET_PUSH_DISTRIBUTOR != null) {
SET_PUSH_DISTRIBUTOR.getContext().setTheme(Helper.dialogStyle());
List<String> distributors = UnifiedPush.getDistributors(requireActivity(), new ArrayList<>());
SET_PUSH_DISTRIBUTOR.setValue(UnifiedPush.getDistributor(requireActivity()));
SET_PUSH_DISTRIBUTOR.setEntries(distributors.toArray(new String[0]));

View file

@ -18,11 +18,9 @@ package app.fedilab.android.mastodon.ui.fragment.settings;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.preference.EditTextPreference;
import androidx.preference.PreferenceFragmentCompat;
import app.fedilab.android.R;
import app.fedilab.android.mastodon.helper.Helper;
public class FragmentPrivacySettings extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -33,10 +31,6 @@ public class FragmentPrivacySettings extends PreferenceFragmentCompat implements
}
private void createPref() {
EditTextPreference SET_INVIDIOUS_HOST = findPreference(getString(R.string.SET_INVIDIOUS_HOST));
if (SET_INVIDIOUS_HOST != null) {
SET_INVIDIOUS_HOST.getContext().setTheme(Helper.dialogStyle());
}
}
@Override

View file

@ -112,6 +112,15 @@ public class FragmentSettingsCategories extends PreferenceFragmentCompat {
});
}
Preference pref_category_key_home_cache = findPreference(getString(R.string.pref_category_key_home_cache));
if (pref_category_key_home_cache != null) {
pref_category_key_home_cache.setOnPreferenceClickListener(preference -> {
NavController navController = Navigation.findNavController(requireActivity(), R.id.fragment_container);
navController.navigate(FragmentSettingsCategoriesDirections.Companion.categoriesToHomeCache());
return false;
});
}
Preference pref_category_key_theming = findPreference(getString(R.string.pref_category_key_theming));
if (pref_category_key_theming != null) {
pref_category_key_theming.setOnPreferenceClickListener(preference -> {
@ -145,7 +154,7 @@ public class FragmentSettingsCategories extends PreferenceFragmentCompat {
Preference pref_export_settings = findPreference(getString(R.string.pref_export_settings));
if (pref_export_settings != null) {
pref_export_settings.setOnPreferenceClickListener(preference -> {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE);
} else {
try {

View file

@ -82,18 +82,7 @@ public class FragmentThemingSettings extends PreferenceFragmentCompat implements
if (getPreferenceScreen() == null) {
Toasty.error(requireActivity(), getString(R.string.toast_error), Toasty.LENGTH_SHORT).show();
}
ListPreference SET_THEME_BASE = findPreference(getString(R.string.SET_THEME_BASE));
if (SET_THEME_BASE != null) {
SET_THEME_BASE.getContext().setTheme(Helper.dialogStyle());
}
ListPreference SET_THEME_DEFAULT_LIGHT = findPreference(getString(R.string.SET_THEME_DEFAULT_LIGHT));
if (SET_THEME_DEFAULT_LIGHT != null) {
SET_THEME_DEFAULT_LIGHT.getContext().setTheme(Helper.dialogStyle());
}
ListPreference SET_THEME_DEFAULT_DARK = findPreference(getString(R.string.SET_THEME_DEFAULT_DARK));
if (SET_THEME_DEFAULT_DARK != null) {
SET_THEME_DEFAULT_DARK.getContext().setTheme(Helper.dialogStyle());
}
Preference SET_CUSTOMIZE_LIGHT_COLORS_ACTION = findPreference(getString(R.string.SET_CUSTOMIZE_LIGHT_COLORS_ACTION));
if (SET_CUSTOMIZE_LIGHT_COLORS_ACTION != null) {
@ -118,9 +107,8 @@ public class FragmentThemingSettings extends PreferenceFragmentCompat implements
Preference SET_RESET_CUSTOM_COLOR = findPreference(getString(R.string.SET_RESET_CUSTOM_COLOR));
if (SET_RESET_CUSTOM_COLOR != null) {
SET_RESET_CUSTOM_COLOR.getContext().setTheme(Helper.dialogStyle());
SET_RESET_CUSTOM_COLOR.setOnPreferenceClickListener(preference -> {
AlertDialog.Builder resetConfirm = new MaterialAlertDialogBuilder(requireActivity(), Helper.dialogStyle());
AlertDialog.Builder resetConfirm = new MaterialAlertDialogBuilder(requireActivity());
resetConfirm.setMessage(getString(R.string.reset_color));
resetConfirm.setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss());
resetConfirm.setPositiveButton(R.string.reset, (dialog, which) -> {

View file

@ -26,7 +26,6 @@ import androidx.preference.SwitchPreferenceCompat;
import app.fedilab.android.R;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.mastodon.helper.Helper;
public class FragmentTimelinesSettings extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -42,18 +41,11 @@ public class FragmentTimelinesSettings extends PreferenceFragmentCompat implemen
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
addPreferencesFromResource(R.xml.pref_timelines);
PreferenceScreen preferenceScreen = getPreferenceScreen();
ListPreference SET_LOAD_MEDIA_TYPE = findPreference(getString(R.string.SET_LOAD_MEDIA_TYPE));
if (SET_LOAD_MEDIA_TYPE != null) {
SET_LOAD_MEDIA_TYPE.getContext().setTheme(Helper.dialogStyle());
}
ListPreference SET_TRANSLATOR = findPreference(getString(R.string.SET_TRANSLATOR));
if (SET_TRANSLATOR != null) {
SET_TRANSLATOR.getContext().setTheme(Helper.dialogStyle());
}
ListPreference SET_TRANSLATOR_VERSION = findPreference(getString(R.string.SET_TRANSLATOR_VERSION));
if (SET_TRANSLATOR_VERSION != null) {
SET_TRANSLATOR_VERSION.getContext().setTheme(Helper.dialogStyle());
}
EditTextPreference SET_TRANSLATOR_API_KEY = findPreference(getString(R.string.SET_TRANSLATOR_API_KEY));
if (SET_TRANSLATOR != null && SET_TRANSLATOR.getValue().equals("FEDILAB")) {
if (SET_TRANSLATOR_API_KEY != null) {

View file

@ -36,6 +36,7 @@ import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.databinding.FragmentPaginationBinding;
import app.fedilab.android.mastodon.activities.SearchResultTabActivity;
import app.fedilab.android.mastodon.client.entities.api.Account;
import app.fedilab.android.mastodon.client.entities.api.Accounts;
import app.fedilab.android.mastodon.client.entities.api.Pagination;
@ -223,10 +224,25 @@ public class FragmentMastodonAccount extends Fragment {
router(true);
});
if (accounts == null || accounts.accounts == null || accounts.accounts.size() == 0) {
if (requireActivity() instanceof SearchResultTabActivity) {
((SearchResultTabActivity) requireActivity()).accountEmpty = true;
if (((SearchResultTabActivity) requireActivity()).tagEmpty != null) {
if (((SearchResultTabActivity) requireActivity()).tagEmpty) {
((SearchResultTabActivity) requireActivity()).moveToMessage();
}
}
}
binding.noAction.setVisibility(View.VISIBLE);
binding.noActionText.setText(R.string.no_accounts);
return;
}
if (requireActivity() instanceof SearchResultTabActivity) {
if (((SearchResultTabActivity) requireActivity()).tagEmpty != null) {
if (((SearchResultTabActivity) requireActivity()).tagEmpty) {
((SearchResultTabActivity) requireActivity()).moveToAccount();
}
}
}
binding.recyclerView.setVisibility(View.VISIBLE);
if (accountAdapter != null && this.accounts != null) {
int size = this.accounts.size();

View file

@ -146,7 +146,15 @@ public class FragmentMastodonTag extends Fragment {
});
if (tags == null || tags.size() == 0) {
if (requireActivity() instanceof SearchResultTabActivity) {
((SearchResultTabActivity) requireActivity()).moveToAccount();
((SearchResultTabActivity) requireActivity()).tagEmpty = true;
if (((SearchResultTabActivity) requireActivity()).accountEmpty != null) {
if (((SearchResultTabActivity) requireActivity()).accountEmpty) {
((SearchResultTabActivity) requireActivity()).moveToMessage();
} else {
((SearchResultTabActivity) requireActivity()).moveToAccount();
}
}
}
binding.recyclerView.setVisibility(View.GONE);
binding.noAction.setVisibility(View.VISIBLE);

View file

@ -75,7 +75,7 @@ import es.dmoral.toasty.Toasty;
public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.FetchMoreCallBack {
private boolean scrollingUp;
private static final int PRELOAD_AHEAD_ITEMS = 10;
public UpdateCounters update;
private FragmentPaginationBinding binding;
@ -506,9 +506,9 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
} else if (update != null && insertedStatus == 0 && direction == DIRECTION.REFRESH) {
update.onUpdate(0, timelineType, slug);
}
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
if (direction == DIRECTION.TOP && fetchingMissing) {
int position = getAbsolutePosition(fetched_statuses.statuses.get(fetched_statuses.statuses.size() - 1));
if (position != -1) {
binding.recyclerView.scrollToPosition(position + 1);
}
@ -656,7 +656,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
binding.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
scrollingUp = dy < 0;
if (requireActivity() instanceof BaseMainActivity) {
if (dy < 0 && !((BaseMainActivity) requireActivity()).getFloatingVisibility())
((BaseMainActivity) requireActivity()).manageFloatingButton(true);
@ -1228,6 +1228,17 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
route(DIRECTION.BOTTOM, true, statusToUpdate);
}
@Override
public void autoFetch(String min_id, String max_id, Status statusToUpdate) {
if (scrollingUp) {
min_id_fetch_more = min_id;
route(DIRECTION.TOP, true, statusToUpdate);
} else {
max_id_fetch_more = max_id;
route(DIRECTION.BOTTOM, true, statusToUpdate);
}
}
public enum DIRECTION {
TOP,
BOTTOM,

View file

@ -44,7 +44,6 @@ import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.databinding.FragmentNotificationContainerBinding;
import app.fedilab.android.databinding.PopupNotificationSettingsBinding;
import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.ui.pageadapter.FedilabNotificationPageAdapter;
import app.fedilab.android.mastodon.viewmodel.mastodon.NotificationsVM;
import es.dmoral.toasty.Toasty;
@ -89,13 +88,13 @@ public class FragmentNotificationContainer extends Fragment {
}
AtomicBoolean changes = new AtomicBoolean(false);
binding.settings.setOnClickListener(v -> {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireActivity(), Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireActivity());
PopupNotificationSettingsBinding dialogView = PopupNotificationSettingsBinding.inflate(getLayoutInflater());
dialogBuilder.setView(dialogView.getRoot());
dialogView.clearAllNotif.setOnClickListener(v1 -> {
AlertDialog.Builder db = new MaterialAlertDialogBuilder(requireActivity(), Helper.dialogStyle());
AlertDialog.Builder db = new MaterialAlertDialogBuilder(requireActivity());
db.setTitle(R.string.delete_notification_ask_all);
db.setMessage(R.string.delete_notification_all_warning);
db.setPositiveButton(R.string.delete_all, (dialog, id) -> {

View file

@ -30,6 +30,7 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
import app.fedilab.android.R;
import app.fedilab.android.mastodon.client.endpoints.MastodonAnnouncementsService;
import app.fedilab.android.mastodon.client.endpoints.MastodonStatusesService;
import app.fedilab.android.mastodon.client.entities.api.Account;
import app.fedilab.android.mastodon.client.entities.api.Accounts;
@ -1292,4 +1293,48 @@ public class StatusesVM extends AndroidViewModel {
}).start();
return voidMutableLiveData;
}
/**
* React to a status with an emoji.
*
* @param instance Instance domain of the active account
* @param token Access token of the active account
* @param id Local ID of an announcement
* @param name Unicode emoji, or shortcode of custom emoji
*/
public void addReaction(@NonNull String instance, String token, @NonNull String id, @NonNull String name) {
MastodonStatusesService mastodonStatusesService = init(instance);
new Thread(() -> {
Call<Void> addReactionCall = mastodonStatusesService.addReaction(token, id, name);
if (addReactionCall != null) {
try {
addReactionCall.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
/**
* Undo a react emoji to a status.
*
* @param instance Instance domain of the active account
* @param token Access token of the active account
* @param id Local ID of an announcement
* @param name Unicode emoji, or shortcode of custom emoji
*/
public void removeReaction(@NonNull String instance, String token, @NonNull String id, @NonNull String name) {
MastodonStatusesService mastodonStatusesService = init(instance);
new Thread(() -> {
Call<Void> removeReactionCall = mastodonStatusesService.removeReaction(token, id, name);
if (removeReactionCall != null) {
try {
removeReactionCall.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}

View file

@ -161,7 +161,7 @@ public class AllPlaylistsActivity extends BaseBarActivity implements PlaylistAda
public void manageAlert(Playlist playlistParam) {
playlistToEdit = playlistParam;
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(AllPlaylistsActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(AllPlaylistsActivity.this);
bindingDialog = AddPlaylistPeertubeBinding.inflate(LayoutInflater.from(AllPlaylistsActivity.this), null, false);
dialogBuilder.setView(bindingDialog.getRoot());

View file

@ -17,18 +17,12 @@ package app.fedilab.android.peertube.activities;
import static app.fedilab.android.peertube.client.RetrofitPeertubeAPI.updateCredential;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.util.Patterns;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.preference.PreferenceManager;
@ -160,6 +154,7 @@ public class LoginActivity extends BaseBarActivity {
oauthParams.setClient_secret(client_secret);
oauthParams.setGrant_type("password");
oauthParams.setScope("user");
oauthParams.x_peertube_otp = binding.loginOtp.getText().toString().isEmpty() ? null : binding.loginOtp.getText().toString();
if (binding.loginUid.getText() != null) {
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
}
@ -169,22 +164,21 @@ public class LoginActivity extends BaseBarActivity {
try {
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
proceedLogin(token, finalInstance);
} catch (final Exception e) {
oauthParams.setUsername(binding.loginUid.getText().toString().toLowerCase().trim());
Token token = null;
try {
token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
} catch (Error ex) {
ex.printStackTrace();
}
proceedLogin(token, finalInstance);
} catch (Error e) {
runOnUiThread(() -> {
Toasty.error(LoginActivity.this, e.getError() != null && !e.getError().isEmpty() ? e.getError() : getString(R.string.toast_error), Toasty.LENGTH_SHORT).show();
binding.loginButton.setEnabled(true);
});
e.printStackTrace();
if (e.getError() != null && e.getError().contains("missing_two_factor")) {
runOnUiThread(() -> {
binding.loginOtpContainer.setVisibility(View.VISIBLE);
binding.loginOtp.setFocusable(true);
binding.loginOtp.requestFocus();
binding.loginButton.setEnabled(true);
});
} else {
runOnUiThread(() -> {
Toasty.error(LoginActivity.this, e.getError() != null && !e.getError().isEmpty() ? e.getError() : getString(R.string.toast_error), Toasty.LENGTH_SHORT).show();
binding.loginButton.setEnabled(true);
});
e.printStackTrace();
}
}
}

View file

@ -93,7 +93,7 @@ public class ManageInstancesActivity extends BaseBarActivity implements AboutIns
@SuppressLint("ApplySharedPref")
private void showRadioButtonDialogFullInstances(Activity activity) {
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(activity, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(activity);
alt_bld.setTitle(R.string.instance_choice);
String instance = HelperInstance.getLiveInstance(activity);
final EditText input = new EditText(activity);

View file

@ -679,7 +679,7 @@ public class PeertubeActivity extends BasePeertubeActivity implements CommentLis
}
private void reportAlert(RetrofitPeertubeAPI.ActionType type, AlertDialog alertDialog) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(PeertubeActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(PeertubeActivity.this);
LayoutInflater inflater1 = getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report_peertube, new LinearLayout(PeertubeActivity.this), false);
dialogBuilder.setView(dialogView);
@ -879,7 +879,7 @@ public class PeertubeActivity extends BasePeertubeActivity implements CommentLis
});
binding.videoInformation.setOnClickListener(v -> {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(PeertubeActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(PeertubeActivity.this);
PopupVideoInfoPeertubeBinding videoInfo = PopupVideoInfoPeertubeBinding.inflate(getLayoutInflater());
@ -1109,7 +1109,7 @@ public class PeertubeActivity extends BasePeertubeActivity implements CommentLis
} else if (itemId == R.id.action_report) {
AlertDialog alertDialog;
AlertDialog.Builder dialogBuilder;
dialogBuilder = new MaterialAlertDialogBuilder(PeertubeActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
dialogBuilder = new MaterialAlertDialogBuilder(PeertubeActivity.this);
LayoutInflater inflater1 = getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report_choice, new LinearLayout(PeertubeActivity.this), false);
dialogBuilder.setView(dialogView);
@ -1241,7 +1241,7 @@ public class PeertubeActivity extends BasePeertubeActivity implements CommentLis
if (promptNSFW && peertube != null && peertube.isNsfw() && (nsfwAction.compareTo(Helper.BLUR) == 0 || nsfwAction.compareTo(Helper.DO_NOT_LIST) == 0)) {
AlertDialog alertDialog;
AlertDialog.Builder dialogBuilder;
dialogBuilder = new MaterialAlertDialogBuilder(PeertubeActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
dialogBuilder = new MaterialAlertDialogBuilder(PeertubeActivity.this);
dialogBuilder.setTitle(R.string.nsfw_title_warning);
dialogBuilder.setCancelable(false);
dialogBuilder.setMessage(R.string.nsfw_message_warning);
@ -2033,7 +2033,7 @@ public class PeertubeActivity extends BasePeertubeActivity implements CommentLis
return;
}
if (apiResponse.getPlaylists() != null && apiResponse.getPlaylists().size() > 0) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(PeertubeActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(PeertubeActivity.this);
builder.setTitle(R.string.modify_playlists);
List<PlaylistData.Playlist> ownerPlaylists = apiResponse.getPlaylists();

View file

@ -109,7 +109,7 @@ public class PeertubeEditUploadActivity extends BaseBarActivity {
binding.setUploadDelete.setOnClickListener(v -> {
AlertDialog.Builder builderInner;
builderInner = new MaterialAlertDialogBuilder(PeertubeEditUploadActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
builderInner = new MaterialAlertDialogBuilder(PeertubeEditUploadActivity.this);
builderInner.setMessage(getString(R.string.delete_video_confirmation));
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
builderInner.setPositiveButton(R.string.yes, (dialog, which) -> {

View file

@ -540,7 +540,7 @@ public class PeertubeMainActivity extends PeertubeBaseMainActivity {
instanceConfig = new RetrofitPeertubeAPI(PeertubeMainActivity.this).getConfigInstance();
} catch (Error error) {
runOnUiThread(() -> {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(this);
alt_bld.setTitle(R.string.refresh_token_failed);
alt_bld.setMessage(R.string.refresh_token_failed_message);
alt_bld.setNegativeButton(R.string.action_logout, (dialog, id) -> {
@ -683,7 +683,7 @@ public class PeertubeMainActivity extends PeertubeBaseMainActivity {
@SuppressLint("ApplySharedPref")
private void showRadioButtonDialog() {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(this);
alt_bld.setTitle(R.string.instance_choice);
final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(PeertubeMainActivity.this);
String acad = HelperInstance.getLiveInstance(PeertubeMainActivity.this);

View file

@ -113,7 +113,7 @@ public class ShowAccountActivity extends BaseBarActivity {
PostActionsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(PostActionsVM.class);
viewModel.post(MUTE, accountAcct == null ? account.getUsername() + "@" + account.getHost() : accountAcct, null).observe(ShowAccountActivity.this, apiResponse -> manageVIewPostActions(MUTE, apiResponse));
} else if (item.getItemId() == R.id.action_report) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(ShowAccountActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(ShowAccountActivity.this);
LayoutInflater inflater1 = getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report_peertube, new LinearLayout(ShowAccountActivity.this), false);
dialogBuilder.setView(dialogView);

View file

@ -134,7 +134,7 @@ public class ShowChannelActivity extends BaseBarActivity {
PostActionsVM viewModel = new ViewModelProvider(ShowChannelActivity.this).get(PostActionsVM.class);
viewModel.post(MUTE, channel.getOwnerAccount().getAcct(), null).observe(ShowChannelActivity.this, apiResponse -> manageVIewPostActions(MUTE, apiResponse));
} else if (item.getItemId() == R.id.action_report) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(ShowChannelActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(ShowChannelActivity.this);
LayoutInflater inflater1 = getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report_peertube, new LinearLayout(ShowChannelActivity.this), false);
dialogBuilder.setView(dialogView);
@ -265,7 +265,7 @@ public class ShowChannelActivity extends BaseBarActivity {
} else if (doAction == action.UNFOLLOW) {
boolean confirm_unfollow = sharedpreferences.getBoolean(Helper.SET_UNFOLLOW_VALIDATION, true);
if (confirm_unfollow) {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(ShowChannelActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(ShowChannelActivity.this);
unfollowConfirm.setTitle(getString(R.string.unfollow_confirm));
unfollowConfirm.setMessage(channel.getAcct());
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());

View file

@ -145,7 +145,7 @@ public class VideosTimelineActivity extends BaseBarActivity {
finish();
return true;
} else if (item.getItemId() == R.id.action_delete) {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(VideosTimelineActivity.this, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(VideosTimelineActivity.this);
builder.setTitle(R.string.delete_history);
builder.setMessage(R.string.delete_history_confirm);
builder.setIcon(android.R.drawable.ic_dialog_alert)

View file

@ -122,6 +122,18 @@ public interface PeertubeService {
@Field("password") String password,
@Field("externalAuthToken") String externalAuthToken);
@FormUrlEncoded
@POST("users/token")
Call<Token> otpConnetion(
@Header("x-peertube-otp") String externalAuthToken,
@Field("client_id") String client_id,
@Field("client_secret") String client_secret,
@Field("response_type") String response_type,
@Field("grant_type") String grant_type,
@Field("scope") String scope,
@Field("username") String username,
@Field("password") String password);
//TOKEN
//Refresh
@FormUrlEncoded

View file

@ -33,6 +33,9 @@ import android.webkit.URLUtil;
import androidx.documentfile.provider.DocumentFile;
import androidx.preference.PreferenceManager;
import com.google.android.material.button.MaterialButton;
import com.google.gson.JsonSyntaxException;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
@ -92,6 +95,7 @@ import app.fedilab.android.peertube.viewmodel.CommentVM;
import app.fedilab.android.peertube.viewmodel.PlaylistsVM;
import app.fedilab.android.peertube.viewmodel.TimelineVM;
import app.fedilab.android.sqlite.Sqlite;
import es.dmoral.toasty.Toasty;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
@ -156,7 +160,18 @@ public class RetrofitPeertubeAPI {
String instance = host;
try {
UserMe userMe = new RetrofitPeertubeAPI(activity, instance, token).verifyCredentials();
if (userMe == null) {
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
MaterialButton login = activity.findViewById(R.id.login_button);
if (login != null) {
login.setEnabled(true);
}
Toasty.error(activity, activity.getString(R.string.toast_error_peertube_not_supported), Toasty.LENGTH_SHORT).show();
};
mainHandler.post(myRunnable);
return;
}
peertubeAccount = userMe.getAccount();
} catch (Error error) {
Error.displayError(activity, error);
@ -252,7 +267,9 @@ public class RetrofitPeertubeAPI {
public Token manageToken(OauthParams oauthParams) throws Error {
PeertubeService peertubeService = init();
Call<Token> refreshTokenCall = null;
if (oauthParams.getGrant_type().compareTo("password") == 0) {
if (oauthParams.x_peertube_otp != null) {
refreshTokenCall = peertubeService.otpConnetion(oauthParams.x_peertube_otp, oauthParams.getClient_id(), oauthParams.getClient_secret(), "code", oauthParams.getGrant_type(), "upload", oauthParams.getUsername(), oauthParams.getPassword());
} else if (oauthParams.getGrant_type().compareTo("password") == 0) {
refreshTokenCall = peertubeService.createToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getGrant_type(), oauthParams.getUsername(), oauthParams.getPassword());
} else if (oauthParams.getGrant_type().compareTo("refresh_token") == 0) {
refreshTokenCall = peertubeService.refreshToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getRefresh_token(), oauthParams.getGrant_type());
@ -1188,9 +1205,9 @@ public class RetrofitPeertubeAPI {
}
throw error;
}
} catch (IOException e) {
} catch (IOException | JsonSyntaxException e) {
Error error = new Error();
error.setError(_context.getString(R.string.toast_error));
error.setError(_context.getString(R.string.toast_error_peertube_not_supported));
apiResponse.setError(error);
e.printStackTrace();
}

View file

@ -44,6 +44,9 @@ public class OauthParams {
private String code;
@SerializedName("redirect_uri")
private String redirect_uri;
@SerializedName("x_peertube_otp")
public String x_peertube_otp;
public String getClient_secret() {
return client_secret;

View file

@ -55,8 +55,8 @@ public class UserMe {
private NotificationSettings notificationSettings;
@SerializedName("nsfwPolicy")
private String nsfwPolicy;
@SerializedName("role")
private Role role;
/* @SerializedName("role")
private Role role;*/
@SerializedName("roleLabel")
private String roleLabel;
@SerializedName("username")
@ -74,13 +74,13 @@ public class UserMe {
@SerializedName("webTorrentEnabled")
private boolean webTorrentEnabled;
public Role getRole() {
/* public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}*/
public PeertubeAccount getAccount() {
return account;

View file

@ -17,7 +17,6 @@ package app.fedilab.android.peertube.drawer;
import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY;
import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_INSTANCE;
import static app.fedilab.android.mastodon.helper.Helper.dialogStyle;
import android.annotation.SuppressLint;
import android.app.Activity;
@ -143,7 +142,7 @@ public class AboutInstanceAdapter extends RecyclerView.Adapter<RecyclerView.View
popup.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_delete) {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context, dialogStyle());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(R.string.delete_instance);
builder.setMessage(R.string.delete_instance_confirm);
builder.setIcon(android.R.drawable.ic_dialog_alert)

View file

@ -16,7 +16,6 @@ package app.fedilab.android.peertube.drawer;
import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_ID;
import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_INSTANCE;
import static app.fedilab.android.mastodon.helper.Helper.dialogStyle;
import android.content.Context;
import android.content.Intent;
@ -90,7 +89,7 @@ public class ChannelListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
popup.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_delete) {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context, dialogStyle());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(context.getString(R.string.delete_channel) + ": " + channel.getName());
builder.setMessage(context.getString(R.string.action_channel_confirm_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert)

View file

@ -14,7 +14,7 @@ package app.fedilab.android.peertube.drawer;
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.mastodon.helper.Helper.dialogStyle;
import static app.fedilab.android.peertube.client.RetrofitPeertubeAPI.ActionType.MUTE;
import static app.fedilab.android.peertube.client.RetrofitPeertubeAPI.ActionType.REPLY;
@ -163,7 +163,7 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
int itemId = item.getItemId();
MaterialAlertDialogBuilder builder;
if (itemId == R.id.action_delete) {
builder = new MaterialAlertDialogBuilder(context, dialogStyle());
builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(R.string.delete_comment);
builder.setMessage(R.string.delete_comment_confirm);
builder.setIcon(android.R.drawable.ic_dialog_alert)
@ -196,7 +196,7 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
allCommentRemoved.onAllCommentRemoved();
}
} else if (itemId == R.id.action_remove_comments) {
builder = new MaterialAlertDialogBuilder(context, dialogStyle());
builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(R.string.delete_account_comment);
builder.setMessage(R.string.delete_account_comment_confirm);
builder.setIcon(android.R.drawable.ic_dialog_alert)

View file

@ -14,7 +14,7 @@ package app.fedilab.android.peertube.drawer;
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.mastodon.helper.Helper.dialogStyle;
import static app.fedilab.android.peertube.client.RetrofitPeertubeAPI.ActionType.FOLLOW;
import static app.fedilab.android.peertube.client.RetrofitPeertubeAPI.ActionType.UNFOLLOW;
import static app.fedilab.android.peertube.viewmodel.TimelineVM.TimelineType.MY_VIDEOS;
@ -229,7 +229,7 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
popup.getMenu().findItem(R.id.action_follow).setTitle(context.getString(R.string.action_follow));
boolean confirm_unfollow = sharedpreferences.getBoolean(Helper.SET_UNFOLLOW_VALIDATION, true);
if (confirm_unfollow) {
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context, dialogStyle());
AlertDialog.Builder unfollowConfirm = new MaterialAlertDialogBuilder(context);
unfollowConfirm.setTitle(context.getString(R.string.unfollow_confirm));
unfollowConfirm.setMessage(video.getChannel().getAcct());
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
@ -259,7 +259,7 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
intent.putExtras(b);
context.startActivity(intent);
} else if (itemId == R.id.action_report) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context, dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context);
LayoutInflater inflater1 = ((Activity) context).getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report_peertube, new LinearLayout(context), false);
dialogBuilder.setView(dialogView);
@ -323,7 +323,7 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
return;
}
if (apiResponse.getPlaylists() != null && apiResponse.getPlaylists().size() > 0) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, dialogStyle());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(R.string.modify_playlists);
List<PlaylistData.Playlist> ownerPlaylists = apiResponse.getPlaylists();

View file

@ -15,7 +15,7 @@ package app.fedilab.android.peertube.drawer;
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.mastodon.helper.Helper.dialogStyle;
import android.annotation.SuppressLint;
import android.content.Context;
@ -105,7 +105,7 @@ public class PlaylistAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
popup.setOnMenuItemClickListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.action_delete) {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context, dialogStyle());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
builder.setTitle(context.getString(R.string.action_lists_delete) + ": " + playlist.getDisplayName());
builder.setMessage(context.getString(R.string.action_lists_confirm_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert)

View file

@ -14,7 +14,7 @@ package app.fedilab.android.peertube.fragment;
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.mastodon.helper.Helper.dialogStyle;
import static app.fedilab.android.peertube.activities.PeertubeUploadActivity.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE;
import android.Manifest;
@ -230,7 +230,7 @@ public class DisplayChannelsFragment extends Fragment implements ChannelListAdap
public void manageAlert(ChannelParams oldChannelValues) {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context, dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(context);
bindingDialog = AddChannelPeertubeBinding.inflate(LayoutInflater.from(context), null, false);
dialogBuilder.setView(bindingDialog.getRoot());

View file

@ -14,7 +14,7 @@ package app.fedilab.android.peertube.fragment;
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.mastodon.helper.Helper.dialogStyle;
import static app.fedilab.android.peertube.client.RetrofitPeertubeAPI.DataType.MY_CHANNELS;
import static app.fedilab.android.peertube.helper.Helper.peertubeInformation;
@ -103,7 +103,7 @@ public class DisplayPlaylistsFragment extends Fragment {
}
binding.addNew.setOnClickListener(view -> {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireActivity(), dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireActivity());
bindingAlert = AddPlaylistPeertubeBinding.inflate(getLayoutInflater());
dialogBuilder.setView(bindingAlert.getRoot());

View file

@ -108,7 +108,7 @@ public class FragmentLoginPickInstancePeertube extends Fragment implements Insta
itemsKeyLanguage = new String[languages.size()];
binding.pickupLanguages.setOnClickListener(v -> {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireContext(), app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireContext());
int i = 0;
if (languages.size() > 0) {
@ -175,7 +175,7 @@ public class FragmentLoginPickInstancePeertube extends Fragment implements Insta
binding.pickupCategories.setOnClickListener(v -> {
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireContext(), app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireContext());
int i = 0;
if (categories.size() > 0) {
Iterator<Map.Entry<Integer, String>> it = categories.entrySet().iterator();

View file

@ -172,7 +172,7 @@ public class PeertubeRegisterFragment extends Fragment {
return;
}
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireContext(), app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(requireContext());
dialogBuilder.setCancelable(false);
dialogBuilder.setPositiveButton(R.string.validate, (dialog, which) -> {
dialog.dismiss();

View file

@ -329,18 +329,6 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
//****** App theme *******
final SharedPreferences sharedpref = PreferenceManager.getDefaultSharedPreferences(requireActivity());
ListPreference SET_THEME_BASE = findPreference(getString(R.string.SET_THEME_BASE));
if (SET_THEME_BASE != null) {
SET_THEME_BASE.getContext().setTheme(app.fedilab.android.mastodon.helper.Helper.dialogStyle());
}
ListPreference SET_THEME_DEFAULT_LIGHT = findPreference(getString(R.string.SET_THEME_DEFAULT_LIGHT));
if (SET_THEME_DEFAULT_LIGHT != null) {
SET_THEME_DEFAULT_LIGHT.getContext().setTheme(app.fedilab.android.mastodon.helper.Helper.dialogStyle());
}
ListPreference SET_THEME_DEFAULT_DARK = findPreference(getString(R.string.SET_THEME_DEFAULT_DARK));
if (SET_THEME_DEFAULT_DARK != null) {
SET_THEME_DEFAULT_DARK.getContext().setTheme(app.fedilab.android.mastodon.helper.Helper.dialogStyle());
}
//****** Video mode *******

View file

@ -19,7 +19,6 @@ import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_ID;
import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_INSTANCE;
import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_SOFTWARE;
import static app.fedilab.android.mastodon.helper.Helper.PREF_USER_TOKEN;
import static app.fedilab.android.mastodon.helper.Helper.dialogStyle;
import static app.fedilab.android.peertube.activities.PeertubeMainActivity.typeOfConnection;
import android.Manifest;
@ -54,6 +53,8 @@ import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
@ -65,6 +66,8 @@ import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.io.IOException;
@ -379,10 +382,36 @@ public class Helper {
}
try {
RequestBuilder<Drawable> requestBuilder = Glide.with(imageView.getContext())
.load(url)
.thumbnail(0.1f);
.load(url);
requestBuilder.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
.into(imageView);
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, Transition<? super Drawable> transition) {
imageView.setImageDrawable(resource);
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(errorDrawable);
BitmapDrawable avatar = new AvatarGenerator.AvatarBuilder(context)
.setLabel(channel.getAcct())
.setAvatarSize(120)
.setTextSize(30)
.toSquare()
.setBackgroundColor(fetchAccentColor(context))
.build();
Glide.with(imageView.getContext())
.asDrawable()
.load(avatar)
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
.into(imageView);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
} catch (Exception e) {
try {
BitmapDrawable avatar = new AvatarGenerator.AvatarBuilder(context)
@ -429,7 +458,27 @@ public class Helper {
} else {
requestBuilder.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(round)));
}
requestBuilder.into(imageView);
requestBuilder.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, Transition<? super Drawable> transition) {
imageView.setImageDrawable(resource);
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(errorDrawable);
Glide.with(imageView.getContext())
.asDrawable()
.load(R.drawable.missing_peertube)
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners(10)))
.into(imageView);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
} catch (Exception e) {
try {
Glide.with(imageView.getContext())
@ -505,7 +554,7 @@ public class Helper {
* @param url String download url
*/
public static void manageDownloads(final Context context, final String url) {
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context, dialogStyle());
final AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
final DownloadManager.Request request;
try {
request = new DownloadManager.Request(Uri.parse(url.trim()));
@ -540,7 +589,7 @@ public class Helper {
* @param currentAccount BaseAccount
*/
public static void logoutCurrentUser(Activity activity, BaseAccount currentAccount) {
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(activity, dialogStyle());
AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(activity);
alt_bld.setTitle(R.string.action_logout);
if (currentAccount.mastodon_account != null && currentAccount.mastodon_account.username != null && currentAccount.instance != null) {
alt_bld.setMessage(activity.getString(R.string.logout_account_confirmation, currentAccount.mastodon_account.username, currentAccount.instance));
@ -772,7 +821,7 @@ public class Helper {
public static void requestPermissionAndProceed(Activity activity, PermissionGranted permissionGranted) {
if (Build.VERSION.SDK_INT >= 23) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, app.fedilab.android.mastodon.helper.Helper.EXTERNAL_STORAGE_REQUEST_CODE_MEDIA_SAVE);
} else {

View file

@ -49,7 +49,7 @@ public class SwitchAccountHelper {
e.printStackTrace();
}
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(activity, app.fedilab.android.mastodon.helper.Helper.dialogStyle());
AlertDialog.Builder builderSingle = new MaterialAlertDialogBuilder(activity);
builderSingle.setTitle(activity.getString(R.string.list_of_accounts));
if (accounts != null) {
final OwnAccountsAdapter accountsListAdapter = new OwnAccountsAdapter(activity, accounts);

View file

@ -93,6 +93,15 @@ public class Sqlite extends SQLiteOpenHelper {
public static final String COL_ABOUT = "ABOUT";
public static final String COL_USER_INSTANCE = "USER_INSTANCE";
//Home fetch logs
public static final String TABLE_HOME_FETCH_LOGS = "TABLE_HOME_FETCH_LOGS";
public static final String COL_INSERTED = "INSERTED";
public static final String COL_UPDATED = "UPDATED";
public static final String COL_FAILED = "FAILED";
public static final String COL_FREQUENCY = "FREQUENCY";
public static final String COL_FETCHED_COUNT = "FETCHED_COUNT";
private static final String CREATE_TABLE_USER_ACCOUNT = "CREATE TABLE " + TABLE_USER_ACCOUNT + " ("
+ COL_USER_ID + " TEXT NOT NULL, "
+ COL_INSTANCE + " TEXT NOT NULL, "
@ -192,8 +201,8 @@ public class Sqlite extends SQLiteOpenHelper {
+ COL_USER_ID + " TEXT NOT NULL, "
+ COL_TYPE + " TEXT NOT NULL, "
+ COL_MUTED_ACCOUNTS + " TEXT)";
public static SQLiteDatabase db;
private static Sqlite sInstance;
private final String CREATE_TABLE_STORED_INSTANCES = "CREATE TABLE "
+ TABLE_BOOKMARKED_INSTANCES + "("
+ COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
@ -202,6 +211,11 @@ public class Sqlite extends SQLiteOpenHelper {
+ COL_ABOUT + " TEXT NOT NULL, "
+ COL_USER_INSTANCE + " TEXT NOT NULL)";
public static SQLiteDatabase db;
private static Sqlite sInstance;
public Sqlite(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}

View file

@ -237,7 +237,7 @@ public class FragmentLoginMain extends Fragment {
}
});
} else if (itemId == R.id.action_import_data) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE);
} else {
proceed();

View file

@ -2,10 +2,10 @@
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:tint="?attr/colorControlNormal"
android:tint="?colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z" />
android:pathData="M14.91,6.71c-0.39,-0.39 -1.02,-0.39 -1.41,0L8.91,11.3c-0.39,0.39 -0.39,1.02 0,1.41l4.59,4.59c0.39,0.39 1.02,0.39 1.41,0 0.39,-0.39 0.39,-1.02 0,-1.41L11.03,12l3.88,-3.88c0.38,-0.39 0.38,-1.03 0,-1.41z" />
</vector>

View file

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:tint="?colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M9.31,6.71c-0.39,0.39 -0.39,1.02 0,1.41L13.19,12l-3.88,3.88c-0.39,0.39 -0.39,1.02 0,1.41 0.39,0.39 1.02,0.39 1.41,0l4.59,-4.59c0.39,-0.39 0.39,-1.02 0,-1.41L10.72,6.7c-0.38,-0.38 -1.02,-0.38 -1.41,0.01z" />
</vector>

View file

@ -21,7 +21,7 @@
android:text="@string/bookmarks"
android:textAlignment="textStart"
android:textColor="?attr/colorAccent"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end"
app:iconTint="?attr/colorAccent"
app:strokeColor="?attr/colorAccent" />
@ -36,7 +36,7 @@
android:text="@string/muted_menu"
android:textAlignment="textStart"
android:textColor="?attr/colorAccent"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end"
app:iconTint="?attr/colorAccent"
app:strokeColor="?attr/colorAccent" />
@ -51,7 +51,7 @@
android:text="@string/muted_menu_home"
android:textAlignment="textStart"
android:textColor="?attr/colorAccent"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end"
app:iconTint="?attr/colorAccent"
app:strokeColor="?attr/colorAccent" />
@ -66,7 +66,7 @@
android:text="@string/blocked_menu"
android:textAlignment="textStart"
android:textColor="?attr/colorAccent"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end"
app:iconTint="?attr/colorAccent"
app:strokeColor="?attr/colorAccent" />
@ -82,7 +82,7 @@
android:text="@string/favourite"
android:textAlignment="textStart"
android:textColor="?attr/colorAccent"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end"
app:iconTint="?attr/colorAccent"
app:strokeColor="?attr/colorAccent" />
@ -98,7 +98,7 @@
android:text="@string/blocked_domains"
android:textAlignment="textStart"
android:textColor="?attr/colorAccent"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end"
app:iconTint="?attr/colorAccent"
app:strokeColor="?attr/colorAccent" />

View file

@ -20,7 +20,7 @@
android:paddingVertical="12dp"
android:text="@string/reports"
android:textAlignment="textStart"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end" />
<com.google.android.material.button.MaterialButton
@ -32,7 +32,7 @@
android:paddingVertical="12dp"
android:text="@string/accounts"
android:textAlignment="textStart"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end" />
<com.google.android.material.button.MaterialButton
@ -44,7 +44,7 @@
android:paddingVertical="12dp"
android:text="@string/blocked_domains"
android:textAlignment="textStart"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end" />
</androidx.appcompat.widget.LinearLayoutCompat>

View file

@ -16,15 +16,15 @@
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="wrap_content">
<DatePicker
android:id="@+id/date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:calendarViewShown="true"
android:spinnersShown="false"
android:datePickerMode="calendar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -47,67 +47,58 @@
<com.google.android.material.button.MaterialButton
android:id="@+id/date_time_cancel"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_margin="10dp"
android:layout_height="wrap_content"
android:layout_marginVertical="12dp"
android:layout_marginStart="12dp"
android:text="@string/cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/date_time_previous"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_date_time_bottom" />
<com.google.android.material.button.MaterialButton
android:id="@+id/date_time_previous"
style="@style/Widget.Material3.Button.Icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="10dp"
style="@style/Widget.Material3.Button.IconButton.Outlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:contentDescription="@string/previous"
android:padding="0dp"
android:visibility="gone"
app:icon="@drawable/ic_baseline_skip_previous_24"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:icon="@drawable/ic_navigate_before"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/date_time_next"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/date_time_cancel"
app:layout_constraintTop_toBottomOf="@id/barrier_date_time_bottom" />
app:layout_constraintTop_toBottomOf="@id/barrier_date_time_bottom"
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton
android:id="@+id/date_time_next"
style="@style/Widget.Material3.Button.Icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="10dp"
style="@style/Widget.Material3.Button.IconButton.Filled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:contentDescription="@string/next"
android:padding="0dp"
app:icon="@drawable/ic_baseline_skip_next_24"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:icon="@drawable/ic_navigate_next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/date_time_set"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/date_time_previous"
app:layout_constraintTop_toBottomOf="@id/barrier_date_time_bottom" />
<com.google.android.material.button.MaterialButton
android:id="@+id/date_time_set"
style="@style/Widget.Material3.Button.Icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="10dp"
android:contentDescription="@string/validate"
android:padding="0dp"
style="@style/Widget.Material3.Button.IconButton.Filled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="12dp"
android:layout_marginEnd="12dp"
android:contentDescription="@string/schedule"
android:visibility="gone"
app:icon="@drawable/ic_baseline_check_24"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/date_time_next"
app:layout_constraintTop_toBottomOf="@id/barrier_date_time_bottom" />
app:layout_constraintTop_toBottomOf="@id/barrier_date_time_bottom"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -8,5 +8,5 @@
android:layout_marginTop="24dp"
android:paddingVertical="12dp"
android:textAlignment="textStart"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:icon="@drawable/ic_navigate_next"
app:iconGravity="end" />

Some files were not shown because too many files have changed in this diff Show more