Fixed intermittent null pointer exceptions and disabled the light theme temporarily. This closes #21, closes #22, and closes #17.

This commit is contained in:
Vavassor 2017-03-13 20:49:12 -04:00
parent 64da1329b9
commit b937a7bc9e
14 changed files with 128 additions and 64 deletions

View file

@ -1,35 +1,35 @@
{ {
"project_info": { "project_info": {
"project_number": "1050186150447", "project_number": "268851337880",
"firebase_url": "https://tusky-fc880.firebaseio.com", "firebase_url": "https://tusky-62772.firebaseio.com",
"project_id": "tusky-fc880", "project_id": "tusky-62772",
"storage_bucket": "tusky-fc880.appspot.com" "storage_bucket": "tusky-62772.appspot.com"
}, },
"client": [ "client": [
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:1050186150447:android:fc4111b1d145a00e", "mobilesdk_app_id": "1:268851337880:android:fc4111b1d145a00e",
"android_client_info": { "android_client_info": {
"package_name": "com.keylesspalace.tusky" "package_name": "com.keylesspalace.tusky"
} }
}, },
"oauth_client": [ "oauth_client": [
{ {
"client_id": "1050186150447-fg4nj4vlekpa9bcl8q8290hqln1s048e.apps.googleusercontent.com", "client_id": "268851337880-eie2ssto2d21bfihn9d1qupcrke8oebf.apps.googleusercontent.com",
"client_type": 1, "client_type": 1,
"android_info": { "android_info": {
"package_name": "com.keylesspalace.tusky", "package_name": "com.keylesspalace.tusky",
"certificate_hash": "a3bb387437e149dd7763107e8da83ad6b421264f" "certificate_hash": "18d196307d6e928e99c2e0bb9818c01c38aff2f9"
} }
}, },
{ {
"client_id": "1050186150447-4u9m96ub04cuppmnkfdk7ua51o9r7pf3.apps.googleusercontent.com", "client_id": "268851337880-n19d05m282nirs1fc9kdd5n4of6je4fk.apps.googleusercontent.com",
"client_type": 3 "client_type": 3
} }
], ],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyBTWsu3Z5EjCnm3nUoWamuMLmGvM0nGq7o" "current_key": "AIzaSyD6erhkj_KOB7WrhdunV1uN29QOoLJHTaQ"
} }
], ],
"services": { "services": {
@ -40,7 +40,7 @@
"status": 2, "status": 2,
"other_platform_oauth_client": [ "other_platform_oauth_client": [
{ {
"client_id": "1050186150447-4u9m96ub04cuppmnkfdk7ua51o9r7pf3.apps.googleusercontent.com", "client_id": "268851337880-n19d05m282nirs1fc9kdd5n4of6je4fk.apps.googleusercontent.com",
"client_type": 3 "client_type": 3
} }
] ]

View file

@ -160,7 +160,11 @@ public class AccountActivity extends BaseActivity {
mastodonAPI.account(accountId).enqueue(new Callback<Account>() { mastodonAPI.account(accountId).enqueue(new Callback<Account>() {
@Override @Override
public void onResponse(Call<Account> call, retrofit2.Response<Account> response) { public void onResponse(Call<Account> call, retrofit2.Response<Account> response) {
if (response.isSuccessful()) {
onObtainAccountSuccess(response.body()); onObtainAccountSuccess(response.body());
} else {
onObtainAccountFailure();
}
} }
@Override @Override
@ -238,8 +242,12 @@ public class AccountActivity extends BaseActivity {
mastodonAPI.relationships(ids).enqueue(new Callback<List<Relationship>>() { mastodonAPI.relationships(ids).enqueue(new Callback<List<Relationship>>() {
@Override @Override
public void onResponse(Call<List<Relationship>> call, retrofit2.Response<List<Relationship>> response) { public void onResponse(Call<List<Relationship>> call, retrofit2.Response<List<Relationship>> response) {
if (response.isSuccessful()) {
Relationship relationship = response.body().get(0); Relationship relationship = response.body().get(0);
onObtainRelationshipsSuccess(relationship.following, relationship.blocking, relationship.muting); onObtainRelationshipsSuccess(relationship.following, relationship.blocking, relationship.muting);
} else {
onObtainRelationshipsFailure(new Exception(response.message()));
}
} }
@Override @Override
@ -326,9 +334,13 @@ public class AccountActivity extends BaseActivity {
Callback<Relationship> cb = new Callback<Relationship>() { Callback<Relationship> cb = new Callback<Relationship>() {
@Override @Override
public void onResponse(Call<Relationship> call, retrofit2.Response<Relationship> response) { public void onResponse(Call<Relationship> call, retrofit2.Response<Relationship> response) {
if (response.isSuccessful()) {
following = response.body().following; following = response.body().following;
// TODO: display message/indicator when "requested" is true (i.e. when the follow is awaiting approval) // TODO: display message/indicator when "requested" is true (i.e. when the follow is awaiting approval)
updateButtons(); updateButtons();
} else {
onFollowFailure(id);
}
} }
@Override @Override
@ -366,8 +378,12 @@ public class AccountActivity extends BaseActivity {
Callback<Relationship> cb = new Callback<Relationship>() { Callback<Relationship> cb = new Callback<Relationship>() {
@Override @Override
public void onResponse(Call<Relationship> call, retrofit2.Response<Relationship> response) { public void onResponse(Call<Relationship> call, retrofit2.Response<Relationship> response) {
if (response.isSuccessful()) {
blocking = response.body().blocking; blocking = response.body().blocking;
updateButtons(); updateButtons();
} else {
onBlockFailure(id);
}
} }
@Override @Override
@ -405,8 +421,12 @@ public class AccountActivity extends BaseActivity {
Callback<Relationship> cb = new Callback<Relationship>() { Callback<Relationship> cb = new Callback<Relationship>() {
@Override @Override
public void onResponse(Call<Relationship> call, Response<Relationship> response) { public void onResponse(Call<Relationship> call, Response<Relationship> response) {
if (response.isSuccessful()) {
muting = response.body().muting; muting = response.body().muting;
updateButtons(); updateButtons();
} else {
onMuteFailure(id);
}
} }
@Override @Override

View file

@ -56,9 +56,12 @@ public class BaseActivity extends AppCompatActivity {
createMastodonAPI(); createMastodonAPI();
createTuskyAPI(); createTuskyAPI();
/* Note from Andrew March 13, 2017: Keep this and restore it when the light theme is no
longer bugged.
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("lightTheme", false)) { if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("lightTheme", false)) {
setTheme(R.style.AppTheme_Light); setTheme(R.style.AppTheme_Light);
} }
*/
} }
@Override @Override

View file

@ -653,7 +653,7 @@ public class ComposeActivity extends BaseActivity {
private void sendStatus(String content, String visibility, boolean sensitive, private void sendStatus(String content, String visibility, boolean sensitive,
String spoilerText) { String spoilerText) {
ArrayList<String> mediaIds = new ArrayList<String>(); ArrayList<String> mediaIds = new ArrayList<>();
for (QueuedMedia item : mediaQueued) { for (QueuedMedia item : mediaQueued) {
mediaIds.add(item.id); mediaIds.add(item.id);
@ -662,7 +662,11 @@ public class ComposeActivity extends BaseActivity {
mastodonAPI.createStatus(content, inReplyToId, spoilerText, visibility, sensitive, mediaIds).enqueue(new Callback<Status>() { mastodonAPI.createStatus(content, inReplyToId, spoilerText, visibility, sensitive, mediaIds).enqueue(new Callback<Status>() {
@Override @Override
public void onResponse(Call<Status> call, retrofit2.Response<Status> response) { public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
if (response.isSuccessful()) {
onSendSuccess(); onSendSuccess();
} else {
onSendFailure();
}
} }
@Override @Override
@ -970,8 +974,13 @@ public class ComposeActivity extends BaseActivity {
item.uploadRequest.enqueue(new Callback<Media>() { item.uploadRequest.enqueue(new Callback<Media>() {
@Override @Override
public void onResponse(Call<Media> call, retrofit2.Response<Media> response) { public void onResponse(Call<Media> call, retrofit2.Response<Media> response) {
if (response.isSuccessful()) {
item.id = response.body().id; item.id = response.body().id;
waitForMediaLatch.countDown(); waitForMediaLatch.countDown();
} else {
Log.d(TAG, "Upload request failed. " + response.message());
onUploadFailure(item);
}
} }
@Override @Override

View file

@ -31,9 +31,7 @@ import android.widget.TextView;
import com.keylesspalace.tusky.entity.AccessToken; import com.keylesspalace.tusky.entity.AccessToken;
import com.keylesspalace.tusky.entity.AppCredentials; import com.keylesspalace.tusky.entity.AppCredentials;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import retrofit2.Call; import retrofit2.Call;
@ -43,6 +41,7 @@ import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
public class LoginActivity extends BaseActivity { public class LoginActivity extends BaseActivity {
private static final String TAG = "LoginActivity"; // logging tag
private static String OAUTH_SCOPES = "read write follow"; private static String OAUTH_SCOPES = "read write follow";
private SharedPreferences preferences; private SharedPreferences preferences;
@ -126,6 +125,13 @@ public class LoginActivity extends BaseActivity {
Callback<AppCredentials> callback = new Callback<AppCredentials>() { Callback<AppCredentials> callback = new Callback<AppCredentials>() {
@Override @Override
public void onResponse(Call<AppCredentials> call, Response<AppCredentials> response) { public void onResponse(Call<AppCredentials> call, Response<AppCredentials> response) {
if (!response.isSuccessful()) {
editText.setError(
"This app could not obtain authentication from that server " +
"instance.");
Log.e(TAG, "App authentication failed. " + response.message());
return;
}
AppCredentials credentials = response.body(); AppCredentials credentials = response.body();
clientId = credentials.clientId; clientId = credentials.clientId;
clientSecret = credentials.clientSecret; clientSecret = credentials.clientSecret;
@ -246,7 +252,11 @@ public class LoginActivity extends BaseActivity {
Callback<AccessToken> callback = new Callback<AccessToken>() { Callback<AccessToken> callback = new Callback<AccessToken>() {
@Override @Override
public void onResponse(Call<AccessToken> call, Response<AccessToken> response) { public void onResponse(Call<AccessToken> call, Response<AccessToken> response) {
if (response.isSuccessful()) {
onLoginSuccess(response.body().accessToken); onLoginSuccess(response.body().accessToken);
} else {
editText.setError(response.message());
}
} }
@Override @Override

View file

@ -15,8 +15,6 @@
package com.keylesspalace.tusky; package com.keylesspalace.tusky;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -24,15 +22,11 @@ import android.graphics.PorterDuff;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TabLayout; import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
@ -55,7 +49,6 @@ import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem; import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem; import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IProfile;
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader; import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader;
import com.mikepenz.materialdrawer.util.DrawerImageLoader; import com.mikepenz.materialdrawer.util.DrawerImageLoader;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
@ -75,7 +68,7 @@ public class MainActivity extends BaseActivity {
private String loggedInAccountId; private String loggedInAccountId;
private String loggedInAccountUsername; private String loggedInAccountUsername;
Stack<Integer> pageHistory = new Stack<Integer>(); Stack<Integer> pageHistory = new Stack<>();
private AccountHeader headerResult; private AccountHeader headerResult;
private Drawer drawer; private Drawer drawer;
@ -296,8 +289,12 @@ public class MainActivity extends BaseActivity {
mastodonAPI.searchAccounts(newQuery, false, 5).enqueue(new Callback<List<Account>>() { mastodonAPI.searchAccounts(newQuery, false, 5).enqueue(new Callback<List<Account>>() {
@Override @Override
public void onResponse(Call<List<Account>> call, Response<List<Account>> response) { public void onResponse(Call<List<Account>> call, Response<List<Account>> response) {
if (response.isSuccessful()) {
searchView.swapSuggestions(response.body()); searchView.swapSuggestions(response.body());
searchView.hideProgress(); searchView.hideProgress();
} else {
searchView.hideProgress();
}
} }
@Override @Override
@ -359,6 +356,11 @@ public class MainActivity extends BaseActivity {
mastodonAPI.accountVerifyCredentials().enqueue(new Callback<Account>() { mastodonAPI.accountVerifyCredentials().enqueue(new Callback<Account>() {
@Override @Override
public void onResponse(Call<Account> call, retrofit2.Response<Account> response) { public void onResponse(Call<Account> call, retrofit2.Response<Account> response) {
if (!response.isSuccessful()) {
onFetchUserInfoFailure(new Exception(response.message()));
return;
}
Account me = response.body(); Account me = response.body();
ImageView background = headerResult.getHeaderBackgroundView(); ImageView background = headerResult.getHeaderBackgroundView();

View file

@ -56,8 +56,10 @@ public class MyFirebaseMessagingService extends FirebaseMessagingService {
mastodonAPI.notification(notificationId).enqueue(new Callback<Notification>() { mastodonAPI.notification(notificationId).enqueue(new Callback<Notification>() {
@Override @Override
public void onResponse(Call<Notification> call, Response<Notification> response) { public void onResponse(Call<Notification> call, Response<Notification> response) {
if (response.isSuccessful()) {
buildNotification(response.body()); buildNotification(response.body());
} }
}
@Override @Override
public void onFailure(Call<Notification> call, Throwable t) { public void onFailure(Call<Notification> call, Throwable t) {

View file

@ -15,7 +15,6 @@
package com.keylesspalace.tusky; package com.keylesspalace.tusky;
import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@ -141,7 +140,11 @@ public class NotificationsFragment extends SFragment implements
api.notifications(fromId, uptoId, null).enqueue(new Callback<List<Notification>>() { api.notifications(fromId, uptoId, null).enqueue(new Callback<List<Notification>>() {
@Override @Override
public void onResponse(Call<List<Notification>> call, retrofit2.Response<List<Notification>> response) { public void onResponse(Call<List<Notification>> call, retrofit2.Response<List<Notification>> response) {
if (response.isSuccessful()) {
onFetchNotificationsSuccess(response.body(), fromId); onFetchNotificationsSuccess(response.body(), fromId);
} else {
onFetchNotificationsFailure(new Exception(response.message()));
}
} }
@Override @Override

View file

@ -17,7 +17,6 @@ package com.keylesspalace.tusky;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
@ -29,7 +28,6 @@ import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import com.keylesspalace.tusky.entity.Status; import com.keylesspalace.tusky.entity.Status;
@ -122,7 +120,11 @@ public class ReportActivity extends BaseActivity {
mastodonAPI.report(accountId, Arrays.asList(statusIds), comment).enqueue(new Callback<ResponseBody>() { mastodonAPI.report(accountId, Arrays.asList(statusIds), comment).enqueue(new Callback<ResponseBody>() {
@Override @Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) { public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
if (response.isSuccessful()) {
onSendSuccess(); onSendSuccess();
} else {
onSendFailure(accountId, statusIds, comment);
}
} }
@Override @Override
@ -155,6 +157,10 @@ public class ReportActivity extends BaseActivity {
mastodonAPI.accountStatuses(accountId, null, null, null).enqueue(new Callback<List<Status>>() { mastodonAPI.accountStatuses(accountId, null, null, null).enqueue(new Callback<List<Status>>() {
@Override @Override
public void onResponse(Call<List<Status>> call, retrofit2.Response<List<Status>> response) { public void onResponse(Call<List<Status>> call, retrofit2.Response<List<Status>> response) {
if (!response.isSuccessful()) {
onFetchStatusesFailure(new Exception(response.message()));
return;
}
List<Status> statusList = response.body(); List<Status> statusList = response.body();
List<ReportAdapter.ReportStatus> itemList = new ArrayList<>(); List<ReportAdapter.ReportStatus> itemList = new ArrayList<>();
for (Status status : statusList) { for (Status status : statusList) {

View file

@ -83,9 +83,11 @@ public class SFragment extends Fragment {
Callback<Status> cb = new Callback<Status>() { Callback<Status> cb = new Callback<Status>() {
@Override @Override
public void onResponse(Call<Status> call, retrofit2.Response<Status> response) { public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
if (response.isSuccessful()) {
status.reblogged = reblog; status.reblogged = reblog;
adapter.notifyItemChanged(position); adapter.notifyItemChanged(position);
} }
}
@Override @Override
public void onFailure(Call<Status> call, Throwable t) { public void onFailure(Call<Status> call, Throwable t) {
@ -107,9 +109,11 @@ public class SFragment extends Fragment {
Callback<Status> cb = new Callback<Status>() { Callback<Status> cb = new Callback<Status>() {
@Override @Override
public void onResponse(Call<Status> call, retrofit2.Response<Status> response) { public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
if (response.isSuccessful()) {
status.favourited = favourite; status.favourited = favourite;
adapter.notifyItemChanged(position); adapter.notifyItemChanged(position);
} }
}
@Override @Override
public void onFailure(Call<Status> call, Throwable t) { public void onFailure(Call<Status> call, Throwable t) {

View file

@ -86,8 +86,10 @@ class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover
int update(List<Status> newStatuses) { int update(List<Status> newStatuses) {
int scrollToPosition; int scrollToPosition;
if (statuses == null || statuses.isEmpty()) { if (statuses.isEmpty()) {
if (newStatuses != null) {
statuses = newStatuses; statuses = newStatuses;
}
scrollToPosition = 0; scrollToPosition = 0;
} else { } else {
int index = newStatuses.indexOf(statuses.get(0)); int index = newStatuses.indexOf(statuses.get(0));

View file

@ -168,7 +168,11 @@ public class TimelineFragment extends SFragment implements
Callback<List<Status>> cb = new Callback<List<Status>>() { Callback<List<Status>> cb = new Callback<List<Status>>() {
@Override @Override
public void onResponse(Call<List<Status>> call, retrofit2.Response<List<Status>> response) { public void onResponse(Call<List<Status>> call, retrofit2.Response<List<Status>> response) {
if (response.isSuccessful()) {
onFetchTimelineSuccess(response.body(), fromId); onFetchTimelineSuccess(response.body(), fromId);
} else {
onFetchTimelineFailure(new Exception(response.message()));
}
} }
@Override @Override

View file

@ -82,8 +82,12 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
api.status(id).enqueue(new Callback<Status>() { api.status(id).enqueue(new Callback<Status>() {
@Override @Override
public void onResponse(Call<Status> call, retrofit2.Response<Status> response) { public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
if (response.isSuccessful()) {
int position = adapter.insertStatus(response.body()); int position = adapter.insertStatus(response.body());
recyclerView.scrollToPosition(position); recyclerView.scrollToPosition(position);
} else {
onThreadRequestFailure(id);
}
} }
@Override @Override
@ -99,10 +103,14 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
api.statusContext(id).enqueue(new Callback<StatusContext>() { api.statusContext(id).enqueue(new Callback<StatusContext>() {
@Override @Override
public void onResponse(Call<StatusContext> call, retrofit2.Response<StatusContext> response) { public void onResponse(Call<StatusContext> call, retrofit2.Response<StatusContext> response) {
if (response.isSuccessful()) {
StatusContext context = response.body(); StatusContext context = response.body();
adapter.addAncestors(context.ancestors); adapter.addAncestors(context.ancestors);
adapter.addDescendants(context.descendants); adapter.addDescendants(context.descendants);
} else {
onThreadRequestFailure(id);
}
} }
@Override @Override

View file

@ -20,13 +20,4 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_title_appearance_settings">
<CheckBoxPreference
android:key="lightTheme"
android:title="@string/pref_title_light_theme"
android:defaultValue="false" />
</PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>