Some fixes

This commit is contained in:
Thomas 2022-06-14 19:17:35 +02:00
parent f3720c56cd
commit e776ea99a1
11 changed files with 251 additions and 75 deletions

View file

@ -9,8 +9,8 @@ android {
defaultConfig {
minSdk 21
targetSdk 31
versionCode 385
versionName "3.0.0-beta-22"
versionCode 386
versionName "3.0.0-beta-23"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
flavorDimensions "default"
@ -71,13 +71,14 @@ allprojects {
dependencies {
implementation project(':autoimageslider')
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation "com.google.code.gson:gson:2.8.6"
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.preference:preference:1.2.0'
implementation "org.conscrypt:conscrypt-android:2.5.2"
implementation 'com.github.evozi:Cyanea:1.0.7'
implementation 'com.vanniktech:emoji-one:0.6.0'
implementation 'com.github.GrenderG:Toasty:1.5.2'
@ -118,8 +119,8 @@ dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
implementation 'androidx.lifecycle:lifecycle-livedata:2.4.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.4.1'
implementation 'androidx.navigation:navigation-fragment:2.4.1'
implementation 'androidx.navigation:navigation-ui:2.4.1'
implementation 'androidx.navigation:navigation-fragment:2.4.2'
implementation 'androidx.navigation:navigation-ui:2.4.2'
testImplementation 'junit:junit:'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

View file

@ -15,6 +15,8 @@ package app.fedilab.android.activities;
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.ui.drawer.StatusAdapter.sendAction;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
@ -28,17 +30,22 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.preference.PreferenceManager;
import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.client.entities.api.Status;
import app.fedilab.android.client.entities.app.QuickLoad;
import app.fedilab.android.client.entities.app.StatusCache;
import app.fedilab.android.databinding.ActivityConversationBinding;
import app.fedilab.android.exception.DBException;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.helper.MastodonHelper;
import app.fedilab.android.helper.SpannableHelper;
import app.fedilab.android.helper.ThemeHelper;
import app.fedilab.android.ui.fragment.timeline.FragmentMastodonContext;
import app.fedilab.android.viewmodel.mastodon.StatusesVM;
public class ContextActivity extends BaseActivity {
@ -91,6 +98,28 @@ public class ContextActivity extends BaseActivity {
};
mainHandler.post(myRunnable);
}).start();
StatusesVM timelinesVM = new ViewModelProvider(ContextActivity.this).get(StatusesVM.class);
timelinesVM.getStatus(MainActivity.currentInstance, MainActivity.currentToken, focusedStatus.id).observe(ContextActivity.this, status -> {
StatusCache statusCache = new StatusCache();
statusCache.instance = MainActivity.currentInstance;
statusCache.user_id = MainActivity.currentUserID;
statusCache.status = status;
statusCache.status_id = status.id;
//Update cache
new Thread(() -> {
try {
new StatusCache(getApplication()).updateIfExists(statusCache);
new QuickLoad(getApplication().getApplicationContext()).updateStatus(MainActivity.accountWeakReference.get(), status);
Handler mainHandler = new Handler(Looper.getMainLooper());
//Update UI
Runnable myRunnable = () -> sendAction(ContextActivity.this, Helper.ARG_STATUS_ACTION, status, null);
mainHandler.post(myRunnable);
} catch (DBException e) {
e.printStackTrace();
}
}).start();
});
}

View file

@ -14,16 +14,13 @@ package app.fedilab.android.activities;
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.BaseMainActivity.api;
import static app.fedilab.android.BaseMainActivity.client_id;
import static app.fedilab.android.BaseMainActivity.client_secret;
import static app.fedilab.android.BaseMainActivity.currentInstance;
import static app.fedilab.android.BaseMainActivity.software;
import static app.fedilab.android.helper.MastodonHelper.REDIRECT_CONTENT_WEB;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.FrameLayout;
@ -36,7 +33,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.regex.Matcher;
import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.client.entities.app.Account;
import app.fedilab.android.helper.Helper;
@ -53,7 +49,8 @@ public class LoginActivity extends BaseActivity {
private final int PICK_IMPORT = 5557;
private boolean requestedAdmin;
public static Account.API apiLogin;
public static String currentInstanceLogin, client_idLogin, client_secretLogin, softwareLogin;
private void manageItent(Intent intent) {
if (intent != null && intent.getData() != null && intent.getData().toString().contains(REDIRECT_CONTENT_WEB + "?code=")) {
@ -65,22 +62,24 @@ public class LoginActivity extends BaseActivity {
}
String code = matcher.group(1);
OauthVM oauthVM = new ViewModelProvider(LoginActivity.this).get(OauthVM.class);
Log.v(Helper.TAG, "finalInstance: " + currentInstanceLogin);
//We are dealing with a Mastodon API
if (api == Account.API.MASTODON) {
if (apiLogin == Account.API.MASTODON) {
//API call to get the user token
String scope = requestedAdmin ? Helper.OAUTH_SCOPES_ADMIN : Helper.OAUTH_SCOPES;
oauthVM.createToken(currentInstance, "authorization_code", client_id, client_secret, Helper.REDIRECT_CONTENT_WEB, scope, code)
oauthVM.createToken(currentInstanceLogin, "authorization_code", client_idLogin, client_secretLogin, Helper.REDIRECT_CONTENT_WEB, scope, code)
.observe(LoginActivity.this, tokenObj -> {
Account account = new Account();
account.client_id = BaseMainActivity.client_id;
account.client_secret = BaseMainActivity.client_secret;
account.client_id = client_idLogin;
account.client_secret = client_secretLogin;
account.token = tokenObj.token_type + " " + tokenObj.access_token;
account.api = api;
account.software = software;
account.instance = currentInstance;
account.api = apiLogin;
account.software = softwareLogin;
account.instance = currentInstanceLogin;
//API call to retrieve account information for the new token
AccountsVM accountsVM = new ViewModelProvider(LoginActivity.this).get(AccountsVM.class);
accountsVM.getConnectedAccount(currentInstance, account.token).observe(LoginActivity.this, mastodonAccount -> {
accountsVM.getConnectedAccount(currentInstanceLogin, account.token).observe(LoginActivity.this, mastodonAccount -> {
account.mastodon_account = mastodonAccount;
account.user_id = mastodonAccount.id;
//We check if user have really moderator rights
@ -112,8 +111,8 @@ public class LoginActivity extends BaseActivity {
ThemeHelper.applyTheme(this);
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(LoginActivity.this);
setContentView(new FrameLayout(this));
Helper.addFragment(getSupportFragmentManager(), android.R.id.content, new FragmentLoginMain(), null, null, null);
FragmentLoginMain fragmentLoginMain = new FragmentLoginMain();
Helper.addFragment(getSupportFragmentManager(), android.R.id.content, fragmentLoginMain, null, null, null);
requestedAdmin = false;
//The activity handles a redirect URI, it will extract token code and will proceed to authentication
//That happens when the user wants to use an external browser
@ -185,5 +184,4 @@ public class LoginActivity extends BaseActivity {
}
}
}

View file

@ -16,9 +16,11 @@
package app.fedilab.android.activities;
import static app.fedilab.android.BaseMainActivity.api;
import static app.fedilab.android.BaseMainActivity.currentInstance;
import static app.fedilab.android.BaseMainActivity.software;
import static app.fedilab.android.activities.LoginActivity.apiLogin;
import static app.fedilab.android.activities.LoginActivity.client_idLogin;
import static app.fedilab.android.activities.LoginActivity.client_secretLogin;
import static app.fedilab.android.activities.LoginActivity.currentInstanceLogin;
import static app.fedilab.android.activities.LoginActivity.softwareLogin;
import static app.fedilab.android.helper.Helper.PREF_USER_TOKEN;
import android.annotation.SuppressLint;
@ -52,7 +54,6 @@ import androidx.preference.PreferenceManager;
import java.util.regex.Matcher;
import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.client.entities.app.Account;
import app.fedilab.android.databinding.ActivityWebviewConnectBinding;
@ -96,9 +97,9 @@ public class WebviewConnectActivity extends BaseActivity {
//update the database
new Account(activity).insertOrUpdate(account);
Handler mainHandler = new Handler(Looper.getMainLooper());
BaseMainActivity.currentToken = account.token;
BaseMainActivity.currentUserID = account.user_id;
api = Account.API.MASTODON;
MainActivity.currentToken = account.token;
MainActivity.currentUserID = account.user_id;
MainActivity.api = Account.API.MASTODON;
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(PREF_USER_TOKEN, account.token);
@ -130,7 +131,6 @@ public class WebviewConnectActivity extends BaseActivity {
if (b != null) {
login_url = b.getString("login_url");
requestedAdmin = b.getBoolean("requestedAdmin", false);
}
if (login_url == null)
finish();
@ -223,18 +223,18 @@ public class WebviewConnectActivity extends BaseActivity {
OauthVM oauthVM = new ViewModelProvider(WebviewConnectActivity.this).get(OauthVM.class);
//API call to get the user token
String scope = requestedAdmin ? Helper.OAUTH_SCOPES_ADMIN : Helper.OAUTH_SCOPES;
oauthVM.createToken(currentInstance, "authorization_code", BaseMainActivity.client_id, BaseMainActivity.client_secret, Helper.REDIRECT_CONTENT_WEB, scope, code)
oauthVM.createToken(currentInstanceLogin, "authorization_code", client_idLogin, client_secretLogin, Helper.REDIRECT_CONTENT_WEB, scope, code)
.observe(WebviewConnectActivity.this, tokenObj -> {
Account account = new Account();
account.client_id = BaseMainActivity.client_id;
account.client_secret = BaseMainActivity.client_secret;
account.client_id = client_idLogin;
account.client_secret = client_secretLogin;
account.token = tokenObj.token_type + " " + tokenObj.access_token;
account.api = api;
account.software = software;
account.instance = currentInstance;
account.api = apiLogin;
account.software = softwareLogin;
account.instance = currentInstanceLogin;
//API call to retrieve account information for the new token
AccountsVM accountsVM = new ViewModelProvider(WebviewConnectActivity.this).get(AccountsVM.class);
accountsVM.getConnectedAccount(currentInstance, account.token).observe(WebviewConnectActivity.this, mastodonAccount -> {
accountsVM.getConnectedAccount(currentInstanceLogin, account.token).observe(WebviewConnectActivity.this, mastodonAccount -> {
account.mastodon_account = mastodonAccount;
account.user_id = mastodonAccount.id;
//We check if user have really moderator rights

View file

@ -198,6 +198,80 @@ public class QuickLoad {
}
}
/**
* Update a status in quickload
*
* @param account {@link Account}
* @param newStatus - Status
* @throws DBException exception with database
*/
public void updateStatus(Account account, Status newStatus) throws DBException {
if (db == null) {
throw new DBException("db is null. Wrong initialization.");
}
QuickLoad homeQuickLoad = getSavedValue(account, Timeline.TimeLineEnum.HOME, null);
QuickLoad localQuickLoad = getSavedValue(account, Timeline.TimeLineEnum.LOCAL, null);
QuickLoad publicQuickLoad = getSavedValue(account, Timeline.TimeLineEnum.PUBLIC, null);
if (homeQuickLoad != null && homeQuickLoad.statuses != null) {
for (int i = 0; i < homeQuickLoad.statuses.size(); i++) {
if (homeQuickLoad.statuses.get(i).id.equals(newStatus.id)) {
homeQuickLoad.statuses.set(i, newStatus);
break;
}
}
ContentValues valuesHome = new ContentValues();
valuesHome.put(Sqlite.COL_STATUSES, StatusDraft.mastodonStatusListToStringStorage(homeQuickLoad.statuses));
//Inserts token
try {
db.update(Sqlite.TABLE_QUICK_LOAD,
valuesHome, Sqlite.COL_USER_ID + " = ? AND " + Sqlite.COL_INSTANCE + " =? AND " + Sqlite.COL_SLUG + "=?",
new String[]{homeQuickLoad.user_id, homeQuickLoad.instance, homeQuickLoad.slug});
} catch (Exception e) {
e.printStackTrace();
}
}
if (localQuickLoad != null && localQuickLoad.statuses != null) {
for (int i = 0; i < localQuickLoad.statuses.size(); i++) {
if (localQuickLoad.statuses.get(i).id.equals(newStatus.id)) {
localQuickLoad.statuses.set(i, newStatus);
break;
}
}
ContentValues valuesLocal = new ContentValues();
valuesLocal.put(Sqlite.COL_STATUSES, StatusDraft.mastodonStatusListToStringStorage(localQuickLoad.statuses));
//Inserts token
try {
db.update(Sqlite.TABLE_QUICK_LOAD,
valuesLocal, Sqlite.COL_USER_ID + " = ? AND " + Sqlite.COL_INSTANCE + " =? AND " + Sqlite.COL_SLUG + "=?",
new String[]{localQuickLoad.user_id, localQuickLoad.instance, localQuickLoad.slug});
} catch (Exception e) {
e.printStackTrace();
}
}
if (publicQuickLoad != null && publicQuickLoad.statuses != null) {
for (int i = 0; i < publicQuickLoad.statuses.size(); i++) {
if (publicQuickLoad.statuses.get(i).id.equals(newStatus.id)) {
publicQuickLoad.statuses.set(i, newStatus);
break;
}
}
ContentValues valuesPublic = new ContentValues();
valuesPublic.put(Sqlite.COL_STATUSES, StatusDraft.mastodonStatusListToStringStorage(publicQuickLoad.statuses));
//Inserts token
try {
db.update(Sqlite.TABLE_QUICK_LOAD,
valuesPublic, Sqlite.COL_USER_ID + " = ? AND " + Sqlite.COL_INSTANCE + " =? AND " + Sqlite.COL_SLUG + "=?",
new String[]{publicQuickLoad.user_id, publicQuickLoad.instance, publicQuickLoad.slug});
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Delete a status in quickload
*

View file

@ -46,6 +46,7 @@ import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
@ -93,6 +94,8 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.jaredrummler.cyanea.Cyanea;
import org.conscrypt.Conscrypt;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
@ -105,6 +108,7 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.security.Security;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
@ -119,6 +123,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.MainApplication;
import app.fedilab.android.R;
import app.fedilab.android.activities.LoginActivity;
import app.fedilab.android.activities.MainActivity;
@ -248,6 +253,7 @@ public class Helper {
public static final String PREF_KEY_ID = "PREF_KEY_ID";
public static final String PREF_INSTANCE = "PREF_INSTANCE";
public static final String SET_SECURITY_PROVIDER = "SET_SECURITY_PROVIDER";
public static final int NOTIFICATION_INTENT = 1;
public static final int OPEN_NOTIFICATION = 2;
@ -433,7 +439,7 @@ public class Helper {
public static void installProvider() {
/* boolean patch_provider = true;
boolean patch_provider = true;
try {
Context ctx = MainApplication.getApp();
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(ctx);
@ -445,7 +451,7 @@ public class Helper {
Security.insertProviderAt(Conscrypt.newProvider(), 1);
} catch (Exception ignored) {
}
}*/
}
}
/***
@ -1597,4 +1603,41 @@ public class Helper {
}
context.deleteDatabase(OLD_DB_NAME);
}
public static String dateDiffFull(Date dateToot) {
SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM, Locale.getDefault());
try {
return df.format(dateToot);
} catch (Exception e) {
return "";
}
}
/**
* Makes the tvDate TextView field clickable, and displays the absolute date & time of a toot
* for 5 seconds.
*
* @param context Context
* @param tvDate TextView
* @param date Date
*/
public static void absoluteDateTimeReveal(final Context context, final TextView tvDate, final Date date) {
tvDate.setOnClickListener(v -> {
tvDate.setText(dateDiffFull(date));
new CountDownTimer((5 * 1000), 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
tvDate.setText(dateDiff(context, date));
}
}.start();
});
}
}

View file

@ -763,6 +763,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.binding.dateShort.setVisibility(View.VISIBLE);
holder.binding.dateShort.setText(Helper.dateDiff(context, status.created_at));
holder.binding.time.setVisibility(View.GONE);
Helper.absoluteDateTimeReveal(context, holder.binding.dateShort, status.created_at);
}
//---- SPOILER TEXT -----
@ -1718,6 +1719,10 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.timer.cancel();
holder.timer = null;
}
if (holder.dateTimer != null) {
holder.dateTimer.cancel();
holder.dateTimer = null;
}
if (status.emojis != null && status.emojis.size() > 0) {
holder.timer = new Timer();
holder.timer.scheduleAtFixedRate(new TimerTask() {
@ -1730,6 +1735,16 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
}, 100, 100);
}
holder.dateTimer = new Timer();
holder.dateTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> holder.binding.dateShort.setText(Helper.dateDiff(context, status.created_at));
mainHandler.post(myRunnable);
}
}, 100, 10000);
} else if (viewHolder.getItemViewType() == STATUS_ART) {
StatusViewHolder holder = (StatusViewHolder) viewHolder;
MastodonHelper.loadPPMastodon(holder.bindingArt.artPp, status.account);
@ -1798,6 +1813,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
if (holder instanceof StatusViewHolder && ((StatusViewHolder) holder).timer != null) {
((StatusViewHolder) holder).timer.cancel();
}
if (holder instanceof StatusViewHolder && ((StatusViewHolder) holder).dateTimer != null) {
((StatusViewHolder) holder).dateTimer.cancel();
}
}
public static class StatusViewHolder extends RecyclerView.ViewHolder {
@ -1808,6 +1826,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
DrawerStatusNotificationBinding bindingNotification;
DrawerStatusArtBinding bindingArt;
Timer timer;
Timer dateTimer;
StatusViewHolder(DrawerStatusBinding itemView) {
super(itemView.getRoot());

View file

@ -14,10 +14,12 @@ package app.fedilab.android.ui.fragment.login;
* 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.BaseMainActivity.api;
import static app.fedilab.android.BaseMainActivity.client_id;
import static app.fedilab.android.BaseMainActivity.client_secret;
import static app.fedilab.android.BaseMainActivity.currentInstance;
import static app.fedilab.android.activities.LoginActivity.apiLogin;
import static app.fedilab.android.activities.LoginActivity.client_idLogin;
import static app.fedilab.android.activities.LoginActivity.client_secretLogin;
import static app.fedilab.android.activities.LoginActivity.currentInstanceLogin;
import static app.fedilab.android.activities.LoginActivity.softwareLogin;
import android.content.Intent;
import android.content.SharedPreferences;
@ -25,6 +27,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.MenuInflater;
@ -135,36 +138,40 @@ public class FragmentLoginMain extends Fragment {
binding.loginInstanceLayout.setErrorEnabled(true);
return;
}
currentInstance = binding.loginInstance.getText().toString().trim().toLowerCase();
if (currentInstance.length() == 0) {
currentInstanceLogin = binding.loginInstance.getText().toString().trim().toLowerCase();
if (currentInstanceLogin.length() == 0) {
return;
}
binding.continueButton.setEnabled(false);
NodeInfoVM nodeInfoVM = new ViewModelProvider(requireActivity()).get(NodeInfoVM.class);
nodeInfoVM.getNodeInfo(binding.loginInstance.getText().toString()).observe(requireActivity(), nodeInfo -> {
if (nodeInfo == null) {
return;
if (nodeInfo != null) {
BaseMainActivity.software = nodeInfo.software.name.toUpperCase();
switch (nodeInfo.software.name.toUpperCase().trim()) {
case "MASTODON":
apiLogin = Account.API.MASTODON;
break;
case "FRIENDICA":
apiLogin = Account.API.FRIENDICA;
break;
case "PIXELFED":
apiLogin = Account.API.PIXELFED;
break;
case "PLEROMA":
apiLogin = Account.API.PLEROMA;
break;
default:
apiLogin = Account.API.UNKNOWN;
break;
}
softwareLogin = nodeInfo.software.name.toUpperCase();
} else {
apiLogin = Account.API.MASTODON;
softwareLogin = "MASTODON";
}
binding.continueButton.setEnabled(true);
BaseMainActivity.software = nodeInfo.software.name.toUpperCase();
switch (nodeInfo.software.name.toUpperCase().trim()) {
case "MASTODON":
api = Account.API.MASTODON;
break;
case "FRIENDICA":
api = Account.API.FRIENDICA;
break;
case "PIXELFED":
api = Account.API.PIXELFED;
break;
case "PLEROMA":
api = Account.API.PLEROMA;
break;
default:
api = Account.API.UNKNOWN;
break;
}
retrievesClientId(currentInstance);
retrievesClientId(currentInstanceLogin);
});
});
return root;
@ -246,20 +253,21 @@ public class FragmentLoginMain extends Fragment {
}
try {
currentInstance = URLEncoder.encode(host, "utf-8");
currentInstanceLogin = URLEncoder.encode(host, "utf-8");
} catch (UnsupportedEncodingException e) {
Toasty.error(requireActivity(), getString(R.string.client_error), Toast.LENGTH_LONG).show();
}
String scopes = ((LoginActivity) requireActivity()).requestedAdmin() ? Helper.OAUTH_SCOPES_ADMIN : Helper.OAUTH_SCOPES;
AppsVM appsVM = new ViewModelProvider(requireActivity()).get(AppsVM.class);
appsVM.createApp(currentInstance, getString(R.string.app_name),
String finalInstance = instance;
appsVM.createApp(currentInstanceLogin, getString(R.string.app_name),
Helper.REDIRECT_CONTENT_WEB,
scopes,
Helper.WEBSITE_VALUE
).observe(requireActivity(), app -> {
client_id = app.client_id;
client_secret = app.client_secret;
String redirectUrl = MastodonHelper.authorizeURL(currentInstance, client_id, ((LoginActivity) requireActivity()).requestedAdmin());
client_idLogin = app.client_id;
client_secretLogin = app.client_secret;
String redirectUrl = MastodonHelper.authorizeURL(currentInstanceLogin, client_idLogin, ((LoginActivity) requireActivity()).requestedAdmin());
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
boolean embedded_browser = sharedpreferences.getBoolean(getString(R.string.SET_EMBEDDED_BROWSER), true);
if (embedded_browser) {
@ -272,6 +280,7 @@ public class FragmentLoginMain extends Fragment {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse(redirectUrl));
Log.v(Helper.TAG, ">value: " + finalInstance);
try {
startActivity(intent);
} catch (Exception e) {

View file

@ -183,7 +183,7 @@ public class FragmentMastodonNotification extends Fragment {
binding.loader.setVisibility(View.GONE);
binding.swipeContainer.setRefreshing(false);
flagLoading = false;
if (notifications == null || notifications.notifications == null) {
if (notifications == null || notifications.notifications == null || notifications.notifications.size() == 0) {
binding.noActionText.setText(R.string.no_notifications);
binding.noAction.setVisibility(View.VISIBLE);
binding.recyclerView.setVisibility(View.GONE);

View file

@ -377,6 +377,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
flagLoading = false;
if (statuses != null && fetched_statuses != null && fetched_statuses.statuses != null && fetched_statuses.statuses.size() > 0) {
flagLoading = fetched_statuses.pagination.max_id == null;
binding.noAction.setVisibility(View.GONE);
if (timelineType == Timeline.TimeLineEnum.ART) {
//We have to split media in different statuses
List<Status> mediaStatuses = new ArrayList<>();

View file

@ -106,7 +106,9 @@ public class NotificationsVM extends AndroidViewModel {
if (notifications.notifications != null) {
for (Notification notification : notifications.notifications) {
if (notification != null) {
notification.status = SpannableHelper.convertStatus(getApplication().getApplicationContext(), notification.status);
if (notification.status != null) {
notification.status = SpannableHelper.convertStatus(getApplication().getApplicationContext(), notification.status);
}
}
}
}