TODO's have been erradicated.

main
Vavassor 8 years ago
parent c1d4bdbdfb
commit 9dceb7a226
  1. 2
      README.md
  2. 19
      app/src/main/java/com/keylesspalace/tusky/AccountActivity.java
  3. 24
      app/src/main/java/com/keylesspalace/tusky/LoginActivity.java
  4. 1
      app/src/main/java/com/keylesspalace/tusky/MainActivity.java
  5. 1
      app/src/main/java/com/keylesspalace/tusky/PullNotificationService.java
  6. 27
      app/src/main/java/com/keylesspalace/tusky/SFragment.java
  7. 37
      app/src/main/java/com/keylesspalace/tusky/ViewThreadFragment.java
  8. 5
      app/src/main/res/layout/item_blocked_user.xml
  9. 6
      app/src/main/res/values/strings.xml

@ -2,7 +2,7 @@
This is an android client for [Mastodon, a GNU Social-compatible microblogging server](https://mastodon.social). Presently, it is in active development and its current state does not represent the features or design of the final program. This is an android client for [Mastodon, a GNU Social-compatible microblogging server](https://mastodon.social). Presently, it is in active development and its current state does not represent the features or design of the final program.
It is currently available for alpha testing on the [Tusky Google Play store page](https://play.google.com/store/apps/details?id=com.keylesspalace.tusky). It is currently available for alpha testing on the Tusky [Google Play store page](https://play.google.com/store/apps/details?id=com.keylesspalace.tusky). You can also find it on F-Droid or at its [F-Droid page](https://f-droid.org/repository/browse/?fdid=com.keylesspalace.tusky).
Also, [my mastodon account is Vavassor@mastodon.social](https://mastodon.social/users/Vavassor). Also, [my mastodon account is Vavassor@mastodon.social](https://mastodon.social/users/Vavassor).

@ -210,8 +210,14 @@ public class AccountActivity extends BaseActivity {
} }
private void onObtainAccountFailure() { private void onObtainAccountFailure() {
//TODO: help Snackbar.make(tabLayout, R.string.error_obtain_account, Snackbar.LENGTH_LONG)
Log.e(TAG, "Failed to obtain that account."); .setAction(R.string.action_retry, new View.OnClickListener() {
@Override
public void onClick(View v) {
obtainAccount();
}
})
.show();
} }
private void obtainRelationships() { private void obtainRelationships() {
@ -228,7 +234,7 @@ public class AccountActivity extends BaseActivity {
following = object.getBoolean("following"); following = object.getBoolean("following");
blocking = object.getBoolean("blocking"); blocking = object.getBoolean("blocking");
} catch (JSONException e) { } catch (JSONException e) {
onObtainRelationshipsFailure(); onObtainRelationshipsFailure(e);
return; return;
} }
onObtainRelationshipsSuccess(following, blocking); onObtainRelationshipsSuccess(following, blocking);
@ -237,7 +243,7 @@ public class AccountActivity extends BaseActivity {
new Response.ErrorListener() { new Response.ErrorListener() {
@Override @Override
public void onErrorResponse(VolleyError error) { public void onErrorResponse(VolleyError error) {
onObtainRelationshipsFailure(); onObtainRelationshipsFailure(error);
} }
}) { }) {
@Override @Override
@ -259,9 +265,8 @@ public class AccountActivity extends BaseActivity {
} }
} }
private void onObtainRelationshipsFailure() { private void onObtainRelationshipsFailure(Exception exception) {
//TODO: help Log.e(TAG, "Could not obtain relationships. " + exception.getMessage());
Log.e(TAG, "Could not obtain relationships?");
} }
@Override @Override

@ -37,7 +37,6 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -54,15 +53,14 @@ public class LoginActivity extends BaseActivity {
* Chain together the key-value pairs into a query string, for either appending to a URL or * Chain together the key-value pairs into a query string, for either appending to a URL or
* as the content of an HTTP request. * as the content of an HTTP request.
*/ */
private String toQueryString(Map<String, String> parameters) private String toQueryString(Map<String, String> parameters) {
throws UnsupportedEncodingException {
StringBuilder s = new StringBuilder(); StringBuilder s = new StringBuilder();
String between = ""; String between = "";
for (Map.Entry<String, String> entry : parameters.entrySet()) { for (Map.Entry<String, String> entry : parameters.entrySet()) {
s.append(between); s.append(between);
s.append(URLEncoder.encode(entry.getKey(), "UTF-8")); s.append(entry.getKey());
s.append("="); s.append("=");
s.append(URLEncoder.encode(entry.getValue(), "UTF-8")); s.append(entry.getValue());
between = "&"; between = "&";
} }
return s.toString(); return s.toString();
@ -91,15 +89,7 @@ public class LoginActivity extends BaseActivity {
parameters.put("redirect_uri", redirectUri); parameters.put("redirect_uri", redirectUri);
parameters.put("response_type", "code"); parameters.put("response_type", "code");
parameters.put("scope", OAUTH_SCOPES); parameters.put("scope", OAUTH_SCOPES);
String queryParameters; String url = "https://" + domain + endpoint + "?" + toQueryString(parameters);
try {
queryParameters = toQueryString(parameters);
} catch (UnsupportedEncodingException e) {
//TODO: No clue how to handle this error case??
Log.e(TAG, "Was not able to build the authorization URL.");
return;
}
String url = "https://" + domain + endpoint + "?" + queryParameters;
Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse(url)); Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse(url));
startActivity(viewIntent); startActivity(viewIntent);
} }
@ -269,9 +259,8 @@ public class LoginActivity extends BaseActivity {
parameters.put("code", code); parameters.put("code", code);
parameters.put("grant_type", "authorization_code"); parameters.put("grant_type", "authorization_code");
} catch (JSONException e) { } catch (JSONException e) {
errorText.setText("Heck."); errorText.setText(e.getMessage());
return; return;
//TODO: I don't even know how to handle this error state.
} }
String endpoint = getString(R.string.endpoint_token); String endpoint = getString(R.string.endpoint_token);
String url = "https://" + domain + endpoint; String url = "https://" + domain + endpoint;
@ -284,9 +273,8 @@ public class LoginActivity extends BaseActivity {
try { try {
accessToken = response.getString("access_token"); accessToken = response.getString("access_token");
} catch(JSONException e) { } catch(JSONException e) {
errorText.setText("Heck."); errorText.setText(e.getMessage());
return; return;
//TODO: I don't even know how to handle this error state.
} }
onLoginSuccess(accessToken); onLoginSuccess(accessToken);
} }

@ -158,7 +158,6 @@ public class MainActivity extends BaseActivity {
} }
private void onFetchUserInfoFailure(Exception exception) { private void onFetchUserInfoFailure(Exception exception) {
//TODO: help
Log.e(TAG, "Failed to fetch user info. " + exception.getMessage()); Log.e(TAG, "Failed to fetch user info. " + exception.getMessage());
} }

@ -142,7 +142,6 @@ public class PullNotificationService extends IntentService {
} }
private void onCheckNotificationsFailure(Exception exception) { private void onCheckNotificationsFailure(Exception exception) {
//TODO: not sure if just logging here is enough?
Log.e(TAG, "Failed to check notifications. " + exception.getMessage()); Log.e(TAG, "Failed to check notifications. " + exception.getMessage());
} }

@ -74,7 +74,8 @@ public class SFragment extends Fragment {
protected void sendRequest( protected void sendRequest(
int method, String endpoint, JSONObject parameters, int method, String endpoint, JSONObject parameters,
@Nullable Response.Listener<JSONObject> responseListener) { @Nullable Response.Listener<JSONObject> responseListener,
@Nullable Response.ErrorListener errorListener) {
if (responseListener == null) { if (responseListener == null) {
// Use a dummy listener if one wasn't specified so the request can be constructed. // Use a dummy listener if one wasn't specified so the request can be constructed.
responseListener = new Response.Listener<JSONObject>() { responseListener = new Response.Listener<JSONObject>() {
@ -82,15 +83,17 @@ public class SFragment extends Fragment {
public void onResponse(JSONObject response) {} public void onResponse(JSONObject response) {}
}; };
} }
if (errorListener == null) {
errorListener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Request Failed: " + error.getMessage());
}
};
}
String url = "https://" + domain + endpoint; String url = "https://" + domain + endpoint;
JsonObjectRequest request = new JsonObjectRequest( JsonObjectRequest request = new JsonObjectRequest(
method, url, parameters, responseListener, method, url, parameters, responseListener, errorListener) {
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Request Failed: " + error.getMessage());
}
}) {
@Override @Override
public Map<String, String> getHeaders() throws AuthFailureError { public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>(); Map<String, String> headers = new HashMap<>();
@ -103,7 +106,7 @@ public class SFragment extends Fragment {
} }
protected void postRequest(String endpoint) { protected void postRequest(String endpoint) {
sendRequest(Request.Method.POST, endpoint, null, null); sendRequest(Request.Method.POST, endpoint, null, null, null);
} }
protected void reply(Status status) { protected void reply(Status status) {
@ -137,7 +140,7 @@ public class SFragment extends Fragment {
status.setReblogged(reblog); status.setReblogged(reblog);
adapter.notifyItemChanged(position); adapter.notifyItemChanged(position);
} }
}); }, null);
} }
protected void favourite(final Status status, final boolean favourite, protected void favourite(final Status status, final boolean favourite,
@ -155,7 +158,7 @@ public class SFragment extends Fragment {
status.setFavourited(favourite); status.setFavourited(favourite);
adapter.notifyItemChanged(position); adapter.notifyItemChanged(position);
} }
}); }, null);
} }
private void follow(String id) { private void follow(String id) {
@ -170,7 +173,7 @@ public class SFragment extends Fragment {
private void delete(String id) { private void delete(String id) {
String endpoint = String.format(getString(R.string.endpoint_delete), id); String endpoint = String.format(getString(R.string.endpoint_delete), id);
sendRequest(Request.Method.DELETE, endpoint, null, null); sendRequest(Request.Method.DELETE, endpoint, null, null, null);
} }
protected void more(Status status, View view, final AdapterItemRemover adapter, protected void more(Status status, View view, final AdapterItemRemover adapter,

@ -19,6 +19,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
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.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
@ -29,6 +30,7 @@ import android.view.ViewGroup;
import com.android.volley.Request; import com.android.volley.Request;
import com.android.volley.Response; import com.android.volley.Response;
import com.android.volley.VolleyError;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -36,8 +38,6 @@ import org.json.JSONObject;
import java.util.List; import java.util.List;
public class ViewThreadFragment extends SFragment implements StatusActionListener { public class ViewThreadFragment extends SFragment implements StatusActionListener {
private static final String TAG = "ViewThread"; // logging tag
private RecyclerView recyclerView; private RecyclerView recyclerView;
private ThreadAdapter adapter; private ThreadAdapter adapter;
@ -75,7 +75,7 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
return rootView; return rootView;
} }
private void sendStatusRequest(String id) { private void sendStatusRequest(final String id) {
String endpoint = String.format(getString(R.string.endpoint_get_status), id); String endpoint = String.format(getString(R.string.endpoint_get_status), id);
super.sendRequest(Request.Method.GET, endpoint, null, super.sendRequest(Request.Method.GET, endpoint, null,
new Response.Listener<JSONObject>() { new Response.Listener<JSONObject>() {
@ -85,16 +85,22 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
try { try {
status = Status.parse(response, false); status = Status.parse(response, false);
} catch (JSONException e) { } catch (JSONException e) {
onThreadRequestFailure(); onThreadRequestFailure(id);
return; return;
} }
int position = adapter.insertStatus(status); int position = adapter.insertStatus(status);
recyclerView.scrollToPosition(position); recyclerView.scrollToPosition(position);
} }
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onThreadRequestFailure(id);
}
}); });
} }
private void sendThreadRequest(String id) { private void sendThreadRequest(final String id) {
String endpoint = String.format(getString(R.string.endpoint_context), id); String endpoint = String.format(getString(R.string.endpoint_context), id);
super.sendRequest(Request.Method.GET, endpoint, null, super.sendRequest(Request.Method.GET, endpoint, null,
new Response.Listener<JSONObject>() { new Response.Listener<JSONObject>() {
@ -108,15 +114,28 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
adapter.addAncestors(ancestors); adapter.addAncestors(ancestors);
adapter.addDescendants(descendants); adapter.addDescendants(descendants);
} catch (JSONException e) { } catch (JSONException e) {
onThreadRequestFailure(); onThreadRequestFailure(id);
} }
} }
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onThreadRequestFailure(id);
}
}); });
} }
private void onThreadRequestFailure() { private void onThreadRequestFailure(final String id) {
Log.e(TAG, "The request to fetch the thread has failed."); Snackbar.make(recyclerView, R.string.error_view_thread, Snackbar.LENGTH_LONG)
//TODO: no .setAction(R.string.action_retry, new View.OnClickListener() {
@Override
public void onClick(View v) {
sendThreadRequest(id);
sendStatusRequest(id);
}
})
.show();
} }
public void onReply(int position) { public void onReply(int position) {

@ -26,7 +26,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/blocked_user_display_name" android:id="@+id/blocked_user_display_name"
android:text="Display Name" /> android:textAppearance="@android:style/TextAppearance.DeviceDefault.Small"
android:textStyle="normal|bold" />
<Space <Space
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -37,7 +38,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/blocked_user_username" android:id="@+id/blocked_user_username"
android:text="\@username\@example.com" /> android:textColor="?attr/status_text_color_secondary" />
<Space <Space
android:layout_width="wrap_content" android:layout_width="wrap_content"

@ -55,6 +55,8 @@
<string name="error_unfollowing">That user wasn\'t unfollowed.</string> <string name="error_unfollowing">That user wasn\'t unfollowed.</string>
<string name="error_blocking">That user wasn\'t blocked.</string> <string name="error_blocking">That user wasn\'t blocked.</string>
<string name="error_unblocking">That user wasn\'t unblocked.</string> <string name="error_unblocking">That user wasn\'t unblocked.</string>
<string name="error_view_thread">Couldn\'t fetch that thread.</string>
<string name="error_obtain_account">Failed to obtain that account.</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_notifications">Notifications</string> <string name="title_notifications">Notifications</string>
@ -86,7 +88,7 @@
<string name="notification_follow_format">%s followed you</string> <string name="notification_follow_format">%s followed you</string>
<string name="action_compose">Compose</string> <string name="action_compose">Compose</string>
<string name="action_login">Log In</string> <string name="action_login">Ask Site To Log In</string>
<string name="action_logout">Log Out</string> <string name="action_logout">Log Out</string>
<string name="action_follow">Follow</string> <string name="action_follow">Follow</string>
<string name="action_unfollow">Unfollow</string> <string name="action_unfollow">Unfollow</string>
@ -110,7 +112,7 @@
<string name="confirmation_send">Toot!</string> <string name="confirmation_send">Toot!</string>
<string name="hint_domain">example.com</string> <string name="hint_domain">Which Site?</string>
<string name="hint_compose">What\'s Happening?</string> <string name="hint_compose">What\'s Happening?</string>
<string name="hint_content_warning">Beware, folks</string> <string name="hint_content_warning">Beware, folks</string>

Loading…
Cancel
Save