Merge branch 'GNU_direct_messages' into develop

This commit is contained in:
stom79 2019-02-28 14:05:20 +01:00
commit b63724d48a
11 changed files with 184 additions and 63 deletions

View File

@ -432,8 +432,6 @@ public abstract class BaseMainActivity extends BaseActivity
else
typePosition.put(0, RetrieveFeedsAsyncTask.Type.GNU_NOTIFICATION);
int i = 2;
if( social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA)
display_direct = false;
if( display_direct) {
tabLayout.addTab(tabDirect);
tabPosition.put("direct",i);
@ -588,7 +586,7 @@ public abstract class BaseMainActivity extends BaseActivity
});
countPage = 2;
if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_DIRECT, true) && social != UpdateAccountInfoAsyncTask.SOCIAL.GNU && social != UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA)
if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_DIRECT, true))
countPage++;
if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_LOCAL, true))
countPage++;

View File

@ -257,7 +257,8 @@ public class ShowConversationActivity extends BaseActivity implements OnRetriev
finish();
if( conversationId != null)
statusIdToFetch = conversationId;
new RetrieveContextAsyncTask(getApplicationContext(), expanded, statusIdToFetch, ShowConversationActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new RetrieveContextAsyncTask(getApplicationContext(),expanded, detailsStatus.getVisibility().equals("direct"), statusIdToFetch, ShowConversationActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
switch (theme){
case Helper.THEME_LIGHT:
swipeRefreshLayout.setColorSchemeResources(R.color.mastodonC4,

View File

@ -98,6 +98,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
@ -215,6 +216,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
private RelativeLayout loader;
private String contentType;
private int max_media_count;
public static HashMap<String, Uri> filesMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -243,7 +245,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}else {
style = R.style.Dialog;
}
filesMap = new HashMap<>();
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA){
max_media_count = 9999;
}else{
@ -934,6 +936,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_picture.setEnabled(false);
toot_it.setEnabled(false);
String filename = Helper.getFileName(this.activityWeakReference.get(), uriFile);
filesMap.put(filename, uriFile);
new HttpsConnection(this.activityWeakReference.get()).upload(bs, filename, accountReply != null ? accountReply.getToken() : null, (TootActivity) this.activityWeakReference.get());
}
}
@ -1602,7 +1605,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}
@Override
public void onRetrieveAttachment(final Attachment attachment, Error error) {
public void onRetrieveAttachment(final Attachment attachment, String fileName, Error error) {
if( error != null || attachment == null){
if( error != null)
Toasty.error(getApplicationContext(), error.getError(), Toast.LENGTH_LONG).show();
@ -1629,18 +1632,39 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
String url = attachment.getPreview_url();
if (url == null || url.trim().equals(""))
url = attachment.getUrl();
final ImageView imageView = new ImageView(getApplicationContext());
imageView.setId(Integer.parseInt(attachment.getId()));
Glide.with(imageView.getContext())
.asBitmap()
.load(url)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
imageView.setImageBitmap(resource);
}
});
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA){
if( fileName != null && filesMap.containsKey(fileName)){
Uri uri = filesMap.get(fileName);
Glide.with(imageView.getContext())
.asBitmap()
.load(uri)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
imageView.setImageBitmap(resource);
}
});
}
}else {
Glide.with(imageView.getContext())
.asBitmap()
.load(url)
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
imageView.setImageBitmap(resource);
}
});
}
LinearLayout.LayoutParams imParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
imParams.setMargins(20, 5, 20, 5);
imParams.height = (int) Helper.convertDpToPixel(100, getApplicationContext());

View File

@ -39,12 +39,15 @@ public class RetrieveContextAsyncTask extends AsyncTask<Void, Void, Void> {
private Error error;
private WeakReference<Context> contextReference;
private boolean expanded;
private boolean directtimeline;
public RetrieveContextAsyncTask(Context context, boolean expanded, String statusId, OnRetrieveContextInterface onRetrieveContextInterface){
public RetrieveContextAsyncTask(Context context, boolean expanded, boolean directtimeline, String statusId, OnRetrieveContextInterface onRetrieveContextInterface){
this.contextReference = new WeakReference<>(context);
this.statusId = statusId;
this.listener = onRetrieveContextInterface;
this.expanded = expanded;
this.directtimeline = directtimeline;
}
@Override
@ -59,10 +62,10 @@ public class RetrieveContextAsyncTask extends AsyncTask<Void, Void, Void> {
error = api.getError();
}else{
GNUAPI gnuapi = new GNUAPI(this.contextReference.get());
statusContext = gnuapi.getStatusContext(statusId);
statusContext = gnuapi.getStatusContext(statusId, directtimeline);
//Retrieves the first toot
if (expanded && statusContext != null && statusContext.getAncestors() != null && statusContext.getAncestors().size() > 0) {
statusContext = gnuapi.getStatusContext(statusContext.getAncestors().get(0).getId());
statusContext = gnuapi.getStatusContext(statusContext.getAncestors().get(0).getId(), directtimeline);
}
error = gnuapi.getError();
}

View File

@ -361,7 +361,7 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
break;
case GNU_DM:
gnuAPI = new GNUAPI(this.contextReference.get());
gnuAPI.getDirectTimeline(max_id);
apiResponse = gnuAPI.getDirectTimeline(max_id);
break;
}
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) {

View File

@ -59,7 +59,7 @@ public class UpdateDescriptionAttachmentAsyncTask extends AsyncTask<Void, Void,
@Override
protected void onPostExecute(Void result) {
listener.onRetrieveAttachment(attachment, api.getError());
listener.onRetrieveAttachment(attachment, null, api.getError());
}
}

View File

@ -183,7 +183,7 @@ public class API {
nodeInfos.add(nodeInfo);
}
if( nodeInfos.size() > 0){
NodeInfo nodeInfo = nodeInfos.get(nodeInfos.size()-1);
NodeInfo nodeInfo = nodeInfos.get(0);
response = new HttpsConnection(context).get(nodeInfo.getHref(), 30, null, null);
JSONObject resobj = new JSONObject(response);
JSONObject jsonObject = resobj.getJSONObject("software");
@ -193,6 +193,8 @@ public class API {
case "PEERTUBE":
name = "PEERTUBE";
break;
case "HUBZILLA":
case "REDMATRIX":
case "FRIENDICA":
name = "GNU";
break;

View File

@ -77,6 +77,7 @@ public class GNUAPI {
private String prefKeyOauthTokenT;
private APIResponse apiResponse;
private Error APIError;
private String userId;
public enum accountPrivacy {
PUBLIC,
@ -89,11 +90,11 @@ public class GNUAPI {
accountPerPage = sharedpreferences.getInt(Helper.SET_ACCOUNTS_PER_PAGE, 40);
notificationPerPage = sharedpreferences.getInt(Helper.SET_NOTIFICATIONS_PER_PAGE, 15);
this.prefKeyOauthTokenT = sharedpreferences.getString(PREF_KEY_OAUTH_TOKEN, null);
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
if( Helper.getLiveInstance(context) != null)
this.instance = Helper.getLiveInstance(context);
else {
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
String instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(context));
Account account = new AccountDAO(context, db).getUniqAccount(userId, instance);
if( account == null) {
@ -543,11 +544,18 @@ public class GNUAPI {
* @param statusId Id of the status
* @return List<Status>
*/
public fr.gouv.etalab.mastodon.client.Entities.Context getStatusContext(String statusId) {
public fr.gouv.etalab.mastodon.client.Entities.Context getStatusContext(String statusId, boolean directtimeline) {
fr.gouv.etalab.mastodon.client.Entities.Context statusContext = new fr.gouv.etalab.mastodon.client.Entities.Context();
try {
HttpsConnection httpsConnection = new HttpsConnection(context);
String response = httpsConnection.get(getAbsoluteUrl(String.format("/statusnet/conversation/%s.json", statusId)), 60, null, prefKeyOauthTokenT);
String response;
if( !directtimeline)
response = httpsConnection.get(getAbsoluteUrl(String.format("/statusnet/conversation/%s.json", statusId)), 60, null, prefKeyOauthTokenT);
else {
HashMap<String, String> params = new HashMap<>();
params.put("uri", statusId);
response = httpsConnection.get(getAbsoluteUrl("/direct_messages/conversation.json"), 60, params, prefKeyOauthTokenT);
}
statuses = parseStatuses(context, new JSONArray(response));
if( statuses != null && statuses.size() > 0){
ArrayList<Status> descendants = new ArrayList<>();
@ -617,7 +625,7 @@ public class GNUAPI {
List<Conversation> conversations = new ArrayList<>();
try {
HttpsConnection httpsConnection = new HttpsConnection(context);
String response = httpsConnection.get(getAbsoluteUrl("/conversations"), 60, params, prefKeyOauthTokenT);
String response = httpsConnection.get(getAbsoluteUrl("/direct_messages.json"), 60, params, prefKeyOauthTokenT);
apiResponse.setSince_id(httpsConnection.getSince_id());
apiResponse.setMax_id(httpsConnection.getMax_id());
conversations = parseConversations(new JSONArray(response));
@ -1260,14 +1268,26 @@ public class GNUAPI {
HashMap<String, String> params = null;
switch (statusAction){
case FAVOURITE:
action = "/favorites/create.json";
params = new HashMap<>();
params.put("id", targetedId);
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU) {
action = "/favorites/create.json";
params = new HashMap<>();
params.put("id", targetedId);
}else {
action = "/friendica/activity/like.json";
params = new HashMap<>();
params.put("id", targetedId);
}
break;
case UNFAVOURITE:
action = "/favorites/destroy.json";
params = new HashMap<>();
params.put("id", targetedId);
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU) {
action = "/favorites/destroy.json";
params = new HashMap<>();
params.put("id", targetedId);
}else {
action = "/friendica/activity/unlike.json";
params = new HashMap<>();
params.put("id", targetedId);
}
break;
case REBLOG:
action = String.format("/statuses/retweet/%s.json", targetedId);
@ -1311,20 +1331,41 @@ public class GNUAPI {
params.put("user_id", targetedId);
break;
case UNSTATUS:
action = String.format("/statuses/destroy/%s.json", targetedId);
if( !status.getVisibility().equals("direct"))
action = String.format("/statuses/destroy/%s.json", targetedId);
else {
action = "/direct_messages/destroy.json";
params = new HashMap<>();
params.put("id", targetedId);
}
break;
case CREATESTATUS:
params = new HashMap<>();
action = "/statuses/update.json";
try {
params.put("status", URLEncoder.encode(status.getContent(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
params.put("status", status.getContent());
if(! status.getVisibility().equals("direct"))
action = "/statuses/update.json";
else
action = "/direct_messages/new.json";
if( !status.getVisibility().equals("direct")) {
try {
params.put("status", URLEncoder.encode(status.getContent(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
params.put("status", status.getContent());
}
}else{
try {
params.put("text", URLEncoder.encode(status.getContent(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
params.put("text", status.getContent());
}
}
if( status.getContentType() != null)
params.put("content_type", status.getContentType());
if( status.getIn_reply_to_id() != null)
params.put("in_reply_to_status_id", status.getIn_reply_to_id());
if( status.getIn_reply_to_id() != null) {
if( !status.getVisibility().equals("direct"))
params.put("in_reply_to_status_id", status.getIn_reply_to_id());
else
params.put("replyto", status.getConversationId());
}
if( status.getMedia_attachments() != null && status.getMedia_attachments().size() > 0 ) {
StringBuilder parameters = new StringBuilder();
for(Attachment attachment: status.getMedia_attachments())
@ -1378,15 +1419,34 @@ public class GNUAPI {
public APIResponse postStatusAction(Status status){
HashMap<String, String> params = new HashMap<>();
try {
params.put("status", URLEncoder.encode(status.getContent(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
params.put("status", status.getContent());
}
if( status.getContentType() != null)
params.put("content_type", status.getContentType());
if( !status.getVisibility().equals("direct")) {
try {
params.put("status", URLEncoder.encode(status.getContent(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
params.put("status", status.getContent());
}
}else{
try {
params.put("text", URLEncoder.encode(status.getContent(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
params.put("text", status.getContent());
}
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
//Current user
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
Account currentAccount = new AccountDAO(context, db).getAccountByUserIDInstance(userId, Helper.getLiveInstance(context));
params.put("user_id", currentAccount.getId());
params.put("screen_name", currentAccount.getAcct());
}
if( status.getIn_reply_to_id() != null)
params.put("in_reply_to_status_id", status.getIn_reply_to_id());
if( !status.getVisibility().equals("direct"))
params.put("in_reply_to_status_id", status.getIn_reply_to_id());
else
params.put("replyto", status.getIn_reply_to_id());
if( status.getMedia_attachments() != null && status.getMedia_attachments().size() > 0 ) {
StringBuilder parameters = new StringBuilder();
for(Attachment attachment: status.getMedia_attachments())
@ -1399,7 +1459,11 @@ public class GNUAPI {
statuses = new ArrayList<>();
try {
HttpsConnection httpsConnection = new HttpsConnection(context);
String response = httpsConnection.post(getAbsoluteUrl("/statuses/update.json"), 60, params, prefKeyOauthTokenT);
String response;
if( !status.getVisibility().equals("direct"))
response = httpsConnection.post(getAbsoluteUrl("/statuses/update.json"), 60, params, prefKeyOauthTokenT);
else
response = httpsConnection.post(getAbsoluteUrl("/direct_messages/new.json"), 60, params, prefKeyOauthTokenT);
apiResponse.setSince_id(httpsConnection.getSince_id());
apiResponse.setMax_id(httpsConnection.getMax_id());
Status statusreturned = parseStatuses(context, new JSONObject(response));
@ -1758,7 +1822,7 @@ public class GNUAPI {
* @param jsonArray JSONArray
* @return List<Status>
*/
private static List<Status> parseStatuses(Context context, JSONArray jsonArray){
private List<Status> parseStatuses(Context context, JSONArray jsonArray){
List<Status> statuses = new ArrayList<>();
try {
@ -1783,7 +1847,7 @@ public class GNUAPI {
* @return Status
*/
@SuppressWarnings("InfiniteRecursion")
public static Status parseStatuses(Context context, JSONObject resobj){
private Status parseStatuses(Context context, JSONObject resobj){
Status status = new Status();
try {
status.setId(resobj.get("id").toString());
@ -1793,12 +1857,18 @@ public class GNUAPI {
status.setUri(resobj.get("id").toString());
}
status.setCreated_at(Helper.mstStringToDate(context, resobj.get("created_at").toString()));
status.setIn_reply_to_id(resobj.get("in_reply_to_status_id").toString());
status.setIn_reply_to_account_id(resobj.get("in_reply_to_user_id").toString());
if( resobj.has("in_reply_to_status_id"))
status.setIn_reply_to_id(resobj.get("in_reply_to_status_id").toString());
if( resobj.has("in_reply_to_user_id"))
status.setIn_reply_to_account_id(resobj.get("in_reply_to_user_id").toString());
status.setSensitive(false);
status.setSpoiler_text(null);
status.setVisibility("public");
status.setLanguage(resobj.isNull("geo")?null:resobj.getString("geo"));
if( !resobj.has("sender"))
status.setVisibility("public");
else
status.setVisibility("direct");
if( resobj.has("geo"))
status.setLanguage(resobj.isNull("geo")?null:resobj.getString("geo"));
if( resobj.has("external_url"))
status.setUrl(resobj.get("external_url").toString());
//Retrieves attachments
@ -1812,7 +1882,10 @@ public class GNUAPI {
try {
status.setConversationId(resobj.get("statusnet_conversation_id").toString());
}catch (Exception ignored){
status.setConversationId(resobj.get("id").toString());
if( resobj.has("friendica_parent_uri"))
status.setConversationId(resobj.get("friendica_parent_uri").toString());
else
status.setConversationId(resobj.get("id").toString());
}
//Retrieves mentions
List<Mention> mentions = new ArrayList<>();
@ -1849,8 +1922,14 @@ public class GNUAPI {
application = new Application();
}
status.setApplication(application);
status.setAccount(parseAccountResponse(context, resobj.getJSONObject("user")));
status.setContent(resobj.get("statusnet_html").toString());
if( resobj.has("user"))
status.setAccount(parseAccountResponse(context, resobj.getJSONObject("user")));
else if( resobj.has("sender"))
status.setAccount(parseAccountResponse(context, resobj.getJSONObject("sender")));
if( resobj.has("statusnet_html"))
status.setContent(resobj.get("statusnet_html").toString());
else if( resobj.has("text"))
status.setContent(resobj.get("text").toString());
if(resobj.has("fave_num"))
status.setFavourites_count(Integer.valueOf(resobj.get("fave_num").toString()));
else
@ -1870,6 +1949,18 @@ public class GNUAPI {
}catch (Exception e){
status.setFavourited(false);
}
if( resobj.has("friendica_activities") && resobj.getJSONObject("friendica_activities").has("like")){
status.setFavourited(false);
JSONArray jsonArray = resobj.getJSONObject("friendica_activities").getJSONArray("like");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject like = jsonArray.getJSONObject(i);
if( like.getString("id").equals(userId)) {
status.setFavourited(true);
break;
}
}
}
status.setMuted(false);
status.setPinned(false);
try{
@ -2173,7 +2264,7 @@ public class GNUAPI {
* @param resobj JSONObject
* @return Account
*/
public static Notification parseNotificationResponse(Context context, JSONObject resobj){
private Notification parseNotificationResponse(Context context, JSONObject resobj){
Notification notification = new Notification();
try {

View File

@ -1258,7 +1258,7 @@ public class HttpsConnection {
((TootActivity) context).runOnUiThread(new Runnable() {
public void run() {
listener.onRetrieveAttachment(attachment, null);
listener.onRetrieveAttachment(attachment, fileName,null);
}
});
} catch (Exception e) {
@ -1276,7 +1276,7 @@ public class HttpsConnection {
} catch (Exception ignored) { }
((TootActivity) context).runOnUiThread(new Runnable() {
public void run() {
listener.onRetrieveAttachment(null, error);
listener.onRetrieveAttachment(null, fileName, error);
}
});
@ -1420,7 +1420,7 @@ public class HttpsConnection {
((TootActivity)context).runOnUiThread(new Runnable() {
public void run() {
listener.onRetrieveAttachment(attachment, null);
listener.onRetrieveAttachment(attachment, fileName,null);
}});
}catch (Exception e) {
((TootActivity)context).runOnUiThread(new Runnable() {
@ -1435,7 +1435,7 @@ public class HttpsConnection {
} catch (Exception ignored) { }
((TootActivity)context).runOnUiThread(new Runnable() {
public void run() {
listener.onRetrieveAttachment(null, error);
listener.onRetrieveAttachment(null, fileName,error);
}});
}

View File

@ -438,6 +438,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
//hide loaders
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);
//handle other API error but discards 404 - error which can often happen due to toots which have been deleted
if( this.peertubes == null || this.statuses == null || apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404) ){
if( apiResponse == null)
@ -448,6 +449,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
flag_loading = false;
return;
}
//For remote Peertube remote instances
if(instanceType.equals("PEERTUBE")){
int previousPosition = this.peertubes.size();
@ -588,7 +590,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
statusListAdapter.notifyItemInserted(0);
}
} else if (type == RetrieveFeedsAsyncTask.Type.PUBLIC || type == RetrieveFeedsAsyncTask.Type.LOCAL|| type == RetrieveFeedsAsyncTask.Type.DIRECT) {
} else if (type == RetrieveFeedsAsyncTask.Type.PUBLIC || type == RetrieveFeedsAsyncTask.Type.LOCAL|| type == RetrieveFeedsAsyncTask.Type.DIRECT|| type == RetrieveFeedsAsyncTask.Type.GNU_DM) {
status.setNew(false);
statuses.add(0, status);
@ -657,7 +659,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn
if( statuses != null && statuses.size() > 0)
retrieveMissingToots(statuses.get(0).getId());
}
}else if (type == RetrieveFeedsAsyncTask.Type.DIRECT){
}else if (type == RetrieveFeedsAsyncTask.Type.DIRECT|| type == RetrieveFeedsAsyncTask.Type.GNU_DM){
if( getUserVisibleHint() ){
if( statuses != null && statuses.size() > 0)
retrieveMissingToots(statuses.get(0).getId());

View File

@ -22,6 +22,6 @@ import fr.gouv.etalab.mastodon.client.Entities.Error;
* Interface when an attachment has been retrieved
*/
public interface OnRetrieveAttachmentInterface {
void onRetrieveAttachment(Attachment attachment, Error error);
void onRetrieveAttachment(Attachment attachment, String fileName, Error error);
void onUpdateProgress(int progress);
}