Replace remaining non-retrofit API calls

Only exception is the OAuth2-related calls
This commit is contained in:
Eugen Rochko 2017-03-09 16:59:18 +01:00
parent f938dff9ed
commit d09e9706b6
7 changed files with 141 additions and 192 deletions

View file

@ -36,6 +36,7 @@ import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.keylesspalace.tusky.entity.Account;
import com.keylesspalace.tusky.entity.Relationship;
import java.util.HashMap;
import java.util.List;
@ -63,6 +64,7 @@ public class AccountFragment extends Fragment implements AccountActionListener,
private EndlessOnScrollListener scrollListener;
private AccountAdapter adapter;
private TabLayout.OnTabSelectedListener onTabSelectedListener;
private MastodonAPI api;
public static AccountFragment newInstance(Type type) {
Bundle arguments = new Bundle();
@ -92,6 +94,7 @@ public class AccountFragment extends Fragment implements AccountActionListener,
getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
domain = preferences.getString("domain", null);
accessToken = preferences.getString("accessToken", null);
api = ((BaseActivity) getActivity()).mastodonAPI;
}
@Override
@ -170,8 +173,6 @@ public class AccountFragment extends Fragment implements AccountActionListener,
}
private void fetchAccounts(final String fromId) {
MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
Callback<List<Account>> cb = new Callback<List<Account>>() {
@Override
public void onResponse(Call<List<Account>> call, retrofit2.Response<List<Account>> response) {
@ -265,35 +266,23 @@ public class AccountFragment extends Fragment implements AccountActionListener,
}
public void onBlock(final boolean block, final String id, final int position) {
String endpoint;
if (!block) {
endpoint = String.format(getString(R.string.endpoint_unblock), id);
} else {
endpoint = String.format(getString(R.string.endpoint_block), id);
}
String url = "https://" + domain + endpoint;
StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
onBlockSuccess(block, position);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onBlockFailure(block, id);
}
}) {
Callback<Relationship> cb = new Callback<Relationship>() {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + accessToken);
return headers;
public void onResponse(Call<Relationship> call, retrofit2.Response<Relationship> response) {
onBlockSuccess(block, position);
}
@Override
public void onFailure(Call<Relationship> call, Throwable t) {
onBlockFailure(block, id);
}
};
request.setTag(TAG);
VolleySingleton.getInstance(getContext()).addToRequestQueue(request);
if (!block) {
api.unblockAccount(id).enqueue(cb);
} else {
api.blockAccount(id).enqueue(cb);
}
}
private void onBlockSuccess(boolean blocked, int position) {

View file

@ -76,6 +76,7 @@ import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.keylesspalace.tusky.entity.Media;
import com.keylesspalace.tusky.entity.Status;
import org.json.JSONArray;
@ -96,6 +97,12 @@ import java.util.Locale;
import java.util.Map;
import java.util.Random;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
public class ComposeActivity extends BaseActivity {
private static final String TAG = "ComposeActivity"; // logging tag, and volley request tag
private static final int STATUS_CHARACTER_LIMIT = 500;
@ -138,7 +145,7 @@ public class ComposeActivity extends BaseActivity {
ImageView preview;
Uri uri;
String id;
Request uploadRequest;
Call<Media> uploadRequest;
ReadyStage readyStage;
byte[] content;
long mediaSize;
@ -630,53 +637,28 @@ public class ComposeActivity extends BaseActivity {
private void sendStatus(String content, String visibility, boolean sensitive,
String spoilerText) {
String endpoint = getString(R.string.endpoint_status);
String url = "https://" + domain + endpoint;
JSONObject parameters = new JSONObject();
try {
parameters.put("status", content);
parameters.put("visibility", visibility);
parameters.put("sensitive", sensitive);
parameters.put("spoiler_text", spoilerText);
if (inReplyToId != null) {
parameters.put("in_reply_to_id", inReplyToId);
}
JSONArray mediaIds = new JSONArray();
for (QueuedMedia item : mediaQueued) {
mediaIds.put(item.id);
}
if (mediaIds.length() > 0) {
parameters.put("media_ids", mediaIds);
}
} catch (JSONException e) {
onSendFailure();
return;
ArrayList<String> mediaIds = new ArrayList<String>();
for (QueuedMedia item : mediaQueued) {
mediaIds.add(item.id);
}
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, parameters,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
onSendSuccess();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onSendFailure();
}
}) {
mastodonAPI.createStatus(content, inReplyToId, spoilerText, visibility, sensitive, mediaIds).enqueue(new Callback<Status>() {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + accessToken);
return headers;
public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
onSendSuccess();
}
};
VolleySingleton.getInstance(this).addToRequestQueue(request);
@Override
public void onFailure(Call<Status> call, Throwable t) {
onSendFailure();
}
});
}
private void onSendSuccess() {
Toast.makeText(this, getString(R.string.confirmation_send), Toast.LENGTH_SHORT).show();
Snackbar bar = Snackbar.make(findViewById(R.id.activity_compose), getString(R.string.confirmation_send), Snackbar.LENGTH_SHORT);
bar.show();
finish();
}
@ -942,9 +924,6 @@ public class ComposeActivity extends BaseActivity {
private void uploadMedia(final QueuedMedia item) {
item.readyStage = QueuedMedia.ReadyStage.UPLOADING;
String endpoint = getString(R.string.endpoint_media);
String url = "https://" + domain + endpoint;
final String mimeType = getContentResolver().getType(item.uri);
MimeTypeMap map = MimeTypeMap.getSingleton();
String fileExtension = map.getExtensionFromMimeType(mimeType);
@ -954,58 +933,42 @@ public class ComposeActivity extends BaseActivity {
randomAlphanumericString(10),
fileExtension);
MultipartRequest request = new MultipartRequest(Request.Method.POST, url, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
item.id = response.getString("id");
} catch (JSONException e) {
onUploadFailure(item);
return;
}
waitForMediaLatch.countDown();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onUploadFailure(item);
}
}) {
byte[] content = item.content;
if (content == null) {
InputStream stream;
try {
stream = getContentResolver().openInputStream(item.uri);
} catch (FileNotFoundException e) {
return;
}
content = inputStreamGetBytes(stream);
IOUtils.closeQuietly(stream);
if (content == null) {
return;
}
}
RequestBody requestFile = RequestBody.create(MediaType.parse(mimeType), content);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", filename, requestFile);
item.uploadRequest = mastodonAPI.uploadMedia(body);
item.uploadRequest.enqueue(new Callback<Media>() {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + accessToken);
return headers;
public void onResponse(Call<Media> call, retrofit2.Response<Media> response) {
item.id = response.body().id;
waitForMediaLatch.countDown();
}
@Override
public DataItem getData() {
byte[] content = item.content;
if (content == null) {
InputStream stream;
try {
stream = getContentResolver().openInputStream(item.uri);
} catch (FileNotFoundException e) {
return null;
}
content = inputStreamGetBytes(stream);
IOUtils.closeQuietly(stream);
if (content == null) {
return null;
}
}
DataItem data = new DataItem();
data.name = "file";
data.filename = filename;
data.mimeType = mimeType;
data.content = content;
return data;
public void onFailure(Call<Media> call, Throwable t) {
onUploadFailure(item);
}
};
request.setTag(TAG);
item.uploadRequest = request;
VolleySingleton.getInstance(this).addToRequestQueue(request);
});
}
private void onUploadFailure(QueuedMedia item) {

View file

@ -41,6 +41,7 @@ import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.keylesspalace.tusky.entity.Account;
import org.json.JSONException;
import org.json.JSONObject;
@ -49,6 +50,9 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import retrofit2.Call;
import retrofit2.Callback;
public class MainActivity extends BaseActivity {
private static final String TAG = "MainActivity"; // logging tag and Volley request tag
@ -148,47 +152,23 @@ public class MainActivity extends BaseActivity {
private void fetchUserInfo() {
SharedPreferences preferences = getSharedPreferences(
getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
String domain = preferences.getString("domain", null);
final String accessToken = preferences.getString("accessToken", null);
String id = preferences.getString("loggedInAccountId", null);
String username = preferences.getString("loggedInAccountUsername", null);
if (id != null && username != null) {
loggedInAccountId = id;
loggedInAccountUsername = username;
} else {
String endpoint = getString(R.string.endpoint_verify_credentials);
String url = "https://" + domain + endpoint;
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
String username;
String id;
try {
id = response.getString("id");
username = response.getString("acct");
} catch (JSONException e) {
onFetchUserInfoFailure(e);
return;
}
onFetchUserInfoSuccess(id, username);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onFetchUserInfoFailure(error);
}
}) {
mastodonAPI.accountVerifyCredentials().enqueue(new Callback<Account>() {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + accessToken);
return headers;
public void onResponse(Call<Account> call, retrofit2.Response<Account> response) {
onFetchUserInfoSuccess(response.body().id, response.body().username);
}
};
request.setTag(TAG);
VolleySingleton.getInstance(this).addToRequestQueue(request);
@Override
public void onFailure(Call<Account> call, Throwable t) {
onFetchUserInfoFailure((Exception) t);
}
});
}
}

View file

@ -9,6 +9,7 @@ import com.keylesspalace.tusky.entity.StatusContext;
import java.util.List;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
@ -54,7 +55,7 @@ public interface MastodonAPI {
@Multipart
@POST("api/v1/media")
Call<Media> uploadMedia(@Part("file") RequestBody file);
Call<Media> uploadMedia(@Part("file") MultipartBody.Part file);
@FormUrlEncoded
@POST("api/v1/statuses")
@ -162,4 +163,8 @@ public interface MastodonAPI {
Call<Relationship> authorizeFollowRequest(@Path("id") String accountId);
@POST("api/v1/follow_requests/{id}/reject")
Call<Relationship> rejectFollowRequest(@Path("id") String accountId);
@FormUrlEncoded
@POST("api/v1/reports")
Call<ResponseBody> report(@Field("account_id") String accountId, @Field("status_ids[]") List<String> statusIds, @Field("comment") String comment);
}

View file

@ -45,10 +45,12 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
@ -145,45 +147,22 @@ public class ReportActivity extends BaseActivity {
private void sendReport(final String accountId, final String[] statusIds,
final String comment) {
JSONObject parameters = new JSONObject();
try {
parameters.put("account_id", accountId);
parameters.put("status_ids", makeStringArrayCompat(statusIds));
parameters.put("comment", comment);
} catch (JSONException e) {
Log.e(TAG, "Not all the report parameters have been properly set. " + e.getMessage());
onSendFailure(accountId, statusIds, comment);
return;
}
String endpoint = getString(R.string.endpoint_reports);
String url = "https://" + domain + endpoint;
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, parameters,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
onSendSuccess();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onSendFailure(accountId, statusIds, comment);
}
}) {
mastodonAPI.report(accountId, Arrays.asList(statusIds), comment).enqueue(new Callback<ResponseBody>() {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + accessToken);
return headers;
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
onSendSuccess();
}
};
request.setTag(TAG);
VolleySingleton.getInstance(this).addToRequestQueue(request);
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
onSendFailure(accountId, statusIds, comment);
}
});
}
private void onSendSuccess() {
Toast.makeText(this, getString(R.string.confirmation_reported), Toast.LENGTH_SHORT)
.show();
Snackbar bar = Snackbar.make(anyView, getString(R.string.confirmation_reported), Snackbar.LENGTH_SHORT);
bar.show();
finish();
}

View file

@ -33,6 +33,7 @@ import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.keylesspalace.tusky.entity.Relationship;
import com.keylesspalace.tusky.entity.Status;
import org.json.JSONObject;
@ -42,6 +43,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
@ -144,15 +146,45 @@ public class SFragment extends Fragment {
}
protected void follow(String id) {
api.followAccount(id).enqueue(null);
api.followAccount(id).enqueue(new Callback<Relationship>() {
@Override
public void onResponse(Call<Relationship> call, retrofit2.Response<Relationship> response) {
}
@Override
public void onFailure(Call<Relationship> call, Throwable t) {
}
});
}
private void block(String id) {
api.blockAccount(id).enqueue(null);
api.blockAccount(id).enqueue(new Callback<Relationship>() {
@Override
public void onResponse(Call<Relationship> call, retrofit2.Response<Relationship> response) {
}
@Override
public void onFailure(Call<Relationship> call, Throwable t) {
}
});
}
private void delete(String id) {
api.deleteStatus(id).enqueue(null);
api.deleteStatus(id).enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
protected void more(Status status, View view, final AdapterItemRemover adapter,

View file

@ -2,6 +2,7 @@ package com.keylesspalace.tusky;
import android.text.Spanned;
import com.emojione.Emojione;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
@ -12,6 +13,6 @@ import java.lang.reflect.Type;
class SpannedTypeAdapter implements JsonDeserializer<Spanned> {
@Override
public Spanned deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return HtmlUtils.fromHtml(json.getAsString());
return HtmlUtils.fromHtml(Emojione.shortnameToUnicode(json.getAsString(), false));
}
}