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.VolleyError;
import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.StringRequest;
import com.keylesspalace.tusky.entity.Account; import com.keylesspalace.tusky.entity.Account;
import com.keylesspalace.tusky.entity.Relationship;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -63,6 +64,7 @@ public class AccountFragment extends Fragment implements AccountActionListener,
private EndlessOnScrollListener scrollListener; private EndlessOnScrollListener scrollListener;
private AccountAdapter adapter; private AccountAdapter adapter;
private TabLayout.OnTabSelectedListener onTabSelectedListener; private TabLayout.OnTabSelectedListener onTabSelectedListener;
private MastodonAPI api;
public static AccountFragment newInstance(Type type) { public static AccountFragment newInstance(Type type) {
Bundle arguments = new Bundle(); Bundle arguments = new Bundle();
@ -92,6 +94,7 @@ public class AccountFragment extends Fragment implements AccountActionListener,
getString(R.string.preferences_file_key), Context.MODE_PRIVATE); getString(R.string.preferences_file_key), Context.MODE_PRIVATE);
domain = preferences.getString("domain", null); domain = preferences.getString("domain", null);
accessToken = preferences.getString("accessToken", null); accessToken = preferences.getString("accessToken", null);
api = ((BaseActivity) getActivity()).mastodonAPI;
} }
@Override @Override
@ -170,8 +173,6 @@ public class AccountFragment extends Fragment implements AccountActionListener,
} }
private void fetchAccounts(final String fromId) { private void fetchAccounts(final String fromId) {
MastodonAPI api = ((BaseActivity) getActivity()).mastodonAPI;
Callback<List<Account>> cb = new Callback<List<Account>>() { Callback<List<Account>> cb = new Callback<List<Account>>() {
@Override @Override
public void onResponse(Call<List<Account>> call, retrofit2.Response<List<Account>> response) { 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) { public void onBlock(final boolean block, final String id, final int position) {
String endpoint; Callback<Relationship> cb = new Callback<Relationship>() {
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);
}
}) {
@Override @Override
public Map<String, String> getHeaders() throws AuthFailureError { public void onResponse(Call<Relationship> call, retrofit2.Response<Relationship> response) {
Map<String, String> headers = new HashMap<>(); onBlockSuccess(block, position);
headers.put("Authorization", "Bearer " + accessToken); }
return headers;
@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) { 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.Response;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.JsonObjectRequest;
import com.keylesspalace.tusky.entity.Media;
import com.keylesspalace.tusky.entity.Status; import com.keylesspalace.tusky.entity.Status;
import org.json.JSONArray; import org.json.JSONArray;
@ -96,6 +97,12 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
public class ComposeActivity extends BaseActivity { public class ComposeActivity extends BaseActivity {
private static final String TAG = "ComposeActivity"; // logging tag, and volley request tag private static final String TAG = "ComposeActivity"; // logging tag, and volley request tag
private static final int STATUS_CHARACTER_LIMIT = 500; private static final int STATUS_CHARACTER_LIMIT = 500;
@ -138,7 +145,7 @@ public class ComposeActivity extends BaseActivity {
ImageView preview; ImageView preview;
Uri uri; Uri uri;
String id; String id;
Request uploadRequest; Call<Media> uploadRequest;
ReadyStage readyStage; ReadyStage readyStage;
byte[] content; byte[] content;
long mediaSize; long mediaSize;
@ -630,53 +637,28 @@ 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) {
String endpoint = getString(R.string.endpoint_status); ArrayList<String> mediaIds = new ArrayList<String>();
String url = "https://" + domain + endpoint;
JSONObject parameters = new JSONObject(); for (QueuedMedia item : mediaQueued) {
try { mediaIds.add(item.id);
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;
} }
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, parameters,
new Response.Listener<JSONObject>() { mastodonAPI.createStatus(content, inReplyToId, spoilerText, visibility, sensitive, mediaIds).enqueue(new Callback<Status>() {
@Override
public void onResponse(JSONObject response) {
onSendSuccess();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onSendFailure();
}
}) {
@Override @Override
public Map<String, String> getHeaders() throws AuthFailureError { public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
Map<String, String> headers = new HashMap<>(); onSendSuccess();
headers.put("Authorization", "Bearer " + accessToken);
return headers;
} }
};
VolleySingleton.getInstance(this).addToRequestQueue(request); @Override
public void onFailure(Call<Status> call, Throwable t) {
onSendFailure();
}
});
} }
private void onSendSuccess() { 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(); finish();
} }
@ -942,9 +924,6 @@ public class ComposeActivity extends BaseActivity {
private void uploadMedia(final QueuedMedia item) { private void uploadMedia(final QueuedMedia item) {
item.readyStage = QueuedMedia.ReadyStage.UPLOADING; item.readyStage = QueuedMedia.ReadyStage.UPLOADING;
String endpoint = getString(R.string.endpoint_media);
String url = "https://" + domain + endpoint;
final String mimeType = getContentResolver().getType(item.uri); final String mimeType = getContentResolver().getType(item.uri);
MimeTypeMap map = MimeTypeMap.getSingleton(); MimeTypeMap map = MimeTypeMap.getSingleton();
String fileExtension = map.getExtensionFromMimeType(mimeType); String fileExtension = map.getExtensionFromMimeType(mimeType);
@ -954,58 +933,42 @@ public class ComposeActivity extends BaseActivity {
randomAlphanumericString(10), randomAlphanumericString(10),
fileExtension); fileExtension);
MultipartRequest request = new MultipartRequest(Request.Method.POST, url, null, byte[] content = item.content;
new Response.Listener<JSONObject>() {
@Override if (content == null) {
public void onResponse(JSONObject response) { InputStream stream;
try {
item.id = response.getString("id"); try {
} catch (JSONException e) { stream = getContentResolver().openInputStream(item.uri);
onUploadFailure(item); } catch (FileNotFoundException e) {
return; return;
} }
waitForMediaLatch.countDown();
} content = inputStreamGetBytes(stream);
}, new Response.ErrorListener() { IOUtils.closeQuietly(stream);
@Override
public void onErrorResponse(VolleyError error) { if (content == null) {
onUploadFailure(item); 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 @Override
public Map<String, String> getHeaders() throws AuthFailureError { public void onResponse(Call<Media> call, retrofit2.Response<Media> response) {
Map<String, String> headers = new HashMap<>(); item.id = response.body().id;
headers.put("Authorization", "Bearer " + accessToken); waitForMediaLatch.countDown();
return headers;
} }
@Override @Override
public DataItem getData() { public void onFailure(Call<Media> call, Throwable t) {
byte[] content = item.content; onUploadFailure(item);
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;
} }
}; });
request.setTag(TAG);
item.uploadRequest = request;
VolleySingleton.getInstance(this).addToRequestQueue(request);
} }
private void onUploadFailure(QueuedMedia item) { 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.Response;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.JsonObjectRequest;
import com.keylesspalace.tusky.entity.Account;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -49,6 +50,9 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
import retrofit2.Call;
import retrofit2.Callback;
public class MainActivity extends BaseActivity { public class MainActivity extends BaseActivity {
private static final String TAG = "MainActivity"; // logging tag and Volley request tag private static final String TAG = "MainActivity"; // logging tag and Volley request tag
@ -148,47 +152,23 @@ public class MainActivity extends BaseActivity {
private void fetchUserInfo() { private void fetchUserInfo() {
SharedPreferences preferences = getSharedPreferences( SharedPreferences preferences = getSharedPreferences(
getString(R.string.preferences_file_key), Context.MODE_PRIVATE); 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 id = preferences.getString("loggedInAccountId", null);
String username = preferences.getString("loggedInAccountUsername", null); String username = preferences.getString("loggedInAccountUsername", null);
if (id != null && username != null) { if (id != null && username != null) {
loggedInAccountId = id; loggedInAccountId = id;
loggedInAccountUsername = username; loggedInAccountUsername = username;
} else { } else {
String endpoint = getString(R.string.endpoint_verify_credentials); mastodonAPI.accountVerifyCredentials().enqueue(new Callback<Account>() {
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);
}
}) {
@Override @Override
public Map<String, String> getHeaders() throws AuthFailureError { public void onResponse(Call<Account> call, retrofit2.Response<Account> response) {
Map<String, String> headers = new HashMap<>(); onFetchUserInfoSuccess(response.body().id, response.body().username);
headers.put("Authorization", "Bearer " + accessToken);
return headers;
} }
};
request.setTag(TAG); @Override
VolleySingleton.getInstance(this).addToRequestQueue(request); 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 java.util.List;
import okhttp3.MultipartBody;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
@ -54,7 +55,7 @@ public interface MastodonAPI {
@Multipart @Multipart
@POST("api/v1/media") @POST("api/v1/media")
Call<Media> uploadMedia(@Part("file") RequestBody file); Call<Media> uploadMedia(@Part("file") MultipartBody.Part file);
@FormUrlEncoded @FormUrlEncoded
@POST("api/v1/statuses") @POST("api/v1/statuses")
@ -162,4 +163,8 @@ public interface MastodonAPI {
Call<Relationship> authorizeFollowRequest(@Path("id") String accountId); Call<Relationship> authorizeFollowRequest(@Path("id") String accountId);
@POST("api/v1/follow_requests/{id}/reject") @POST("api/v1/follow_requests/{id}/reject")
Call<Relationship> rejectFollowRequest(@Path("id") String accountId); 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 org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -145,45 +147,22 @@ public class ReportActivity extends BaseActivity {
private void sendReport(final String accountId, final String[] statusIds, private void sendReport(final String accountId, final String[] statusIds,
final String comment) { final String comment) {
JSONObject parameters = new JSONObject(); mastodonAPI.report(accountId, Arrays.asList(statusIds), comment).enqueue(new Callback<ResponseBody>() {
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);
}
}) {
@Override @Override
public Map<String, String> getHeaders() throws AuthFailureError { public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
Map<String, String> headers = new HashMap<>(); onSendSuccess();
headers.put("Authorization", "Bearer " + accessToken);
return headers;
} }
};
request.setTag(TAG); @Override
VolleySingleton.getInstance(this).addToRequestQueue(request); public void onFailure(Call<ResponseBody> call, Throwable t) {
onSendFailure(accountId, statusIds, comment);
}
});
} }
private void onSendSuccess() { private void onSendSuccess() {
Toast.makeText(this, getString(R.string.confirmation_reported), Toast.LENGTH_SHORT) Snackbar bar = Snackbar.make(anyView, getString(R.string.confirmation_reported), Snackbar.LENGTH_SHORT);
.show(); bar.show();
finish(); finish();
} }

View File

@ -33,6 +33,7 @@ import com.android.volley.Request;
import com.android.volley.Response; import com.android.volley.Response;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.JsonObjectRequest;
import com.keylesspalace.tusky.entity.Relationship;
import com.keylesspalace.tusky.entity.Status; import com.keylesspalace.tusky.entity.Status;
import org.json.JSONObject; import org.json.JSONObject;
@ -42,6 +43,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -144,15 +146,45 @@ public class SFragment extends Fragment {
} }
protected void follow(String id) { 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) { 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) { 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, 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 android.text.Spanned;
import com.emojione.Emojione;
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -12,6 +13,6 @@ import java.lang.reflect.Type;
class SpannedTypeAdapter implements JsonDeserializer<Spanned> { class SpannedTypeAdapter implements JsonDeserializer<Spanned> {
@Override @Override
public Spanned deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public Spanned deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return HtmlUtils.fromHtml(json.getAsString()); return HtmlUtils.fromHtml(Emojione.shortnameToUnicode(json.getAsString(), false));
} }
} }