Schedule update remove

This commit is contained in:
stom79 2019-01-20 15:20:07 +01:00
parent 284c118daf
commit f048eea4e1
9 changed files with 459 additions and 129 deletions

View File

@ -102,12 +102,14 @@ import java.util.regex.Pattern;
import es.dmoral.toasty.Toasty;
import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.PostStatusAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsForReplyAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveEmojiAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAccountsAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.UpdateDescriptionAttachmentAsyncTask;
import fr.gouv.etalab.mastodon.client.API;
import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.client.Entities.Account;
import fr.gouv.etalab.mastodon.client.Entities.Attachment;
@ -129,6 +131,7 @@ import fr.gouv.etalab.mastodon.drawers.TagsSearchAdapter;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.helper.MastalabAutoCompleteTextView;
import fr.gouv.etalab.mastodon.interfaces.OnDownloadInterface;
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
import fr.gouv.etalab.mastodon.interfaces.OnPostStatusActionInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAccountsReplyInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface;
@ -152,7 +155,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.convertDpToPixel;
* Toot activity class
*/
public class TootActivity extends BaseActivity implements OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveAccountsReplyInterface, OnRetrieveEmojiInterface, OnDownloadInterface {
public class TootActivity extends BaseActivity implements OnPostActionInterface, OnRetrieveSearcAccountshInterface, OnRetrieveAttachmentInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveAccountsReplyInterface, OnRetrieveEmojiInterface, OnDownloadInterface {
private String visibility;
@ -198,7 +201,8 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
private boolean restoredScheduled;
static boolean active = false;
private int style;
private StoredStatus scheduledstatus;
private boolean isScheduled;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -275,7 +279,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
toot_sensitive = findViewById(R.id.toot_sensitive);
drawer_layout = findViewById(R.id.drawer_layout);
ImageButton toot_emoji = findViewById(R.id.toot_emoji);
isScheduled = false;
if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, true)) {
final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(drawer_layout).build(toot_content);
@ -315,6 +319,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
restored = -1;
if(b != null) {
tootReply = b.getParcelable("tootReply");
scheduledstatus = b.getParcelable("storedStatus");
String accountReplyToken = b.getString("accountReplyToken", null);
accountReply = null;
if( accountReplyToken != null){
@ -348,7 +353,8 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
}
restored = b.getLong("restored", -1);
}
if( scheduledstatus != null)
toot_it.setText(R.string.modify);
if(restoredScheduled){
toot_it.setVisibility(View.GONE);
invalidateOptionsMenu();
@ -627,6 +633,8 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
}
});
if( scheduledstatus != null)
restoreServerSchedule(scheduledstatus.getStatus());
if( restored != -1 ){
restoreToot(restored);
@ -768,6 +776,16 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
}
}
@Override
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
if( error != null){
Toasty.error(getApplicationContext(),getString(R.string.toast_error),Toast.LENGTH_LONG).show();
}else {
Toasty.success(getApplicationContext(),getString(R.string.toot_scheduled),Toast.LENGTH_LONG).show();
resetForNextToot();
}
}
private class asyncPicture extends AsyncTask<Void, Void, Void> {
ByteArrayInputStream bs;
@ -1273,7 +1291,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
private void sendToot(String timestamp){
toot_it.setEnabled(false);
if(toot_content.getText().toString().trim().length() == 0 && attachments.size() == 0){
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();
Toasty.error(getApplicationContext(),getString(R.string.toot_error_no_content),Toast.LENGTH_LONG).show();
toot_it.setEnabled(true);
return;
}
@ -1301,7 +1319,15 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
toot.setContent(tootContent);
if( timestamp == null)
new PostStatusAsyncTask(getApplicationContext(), accountReply, toot, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if( scheduledstatus == null)
new PostStatusAsyncTask(getApplicationContext(), accountReply, toot, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else {
toot.setScheduled_at(Helper.dateToString(scheduledstatus.getScheduled_date()));
scheduledstatus.setStatus(toot);
isScheduled = true;
new PostActionAsyncTask(getApplicationContext(), API.StatusAction.DELETESCHEDULED, scheduledstatus, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new PostStatusAsyncTask(getApplicationContext(), accountReply, toot, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
toot.setScheduled_at(timestamp);
new PostStatusAsyncTask(getApplicationContext(), accountReply, toot, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@ -1312,12 +1338,14 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
private void serverSchedule(String time){
sendToot(time);
isScheduled = true;
resetForNextToot();
}
private void deviceSchedule(long time){
//Store the toot as draft first
storeToot(false, false);
isScheduled = true;
//Schedules the toot
ScheduledTootsSyncJob.schedule(getApplicationContext(), currentToId, time);
resetForNextToot();
@ -1730,7 +1758,10 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
isSensitive = false;
toot_sensitive.setVisibility(View.GONE);
currentToId = -1;
Toasty.success(TootActivity.this, getString(R.string.toot_sent), Toast.LENGTH_LONG).show();
if( scheduledstatus == null && !isScheduled)
Toasty.success(TootActivity.this, getString(R.string.toot_sent), Toast.LENGTH_LONG).show();
else
Toasty.success(TootActivity.this, getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show();
toot_it.setEnabled(true);
//It's a reply, so the user will be redirect to its answer
if( tootReply != null){
@ -2069,6 +2100,139 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
}
private void restoreServerSchedule(Status status){
attachments = status.getMedia_attachments();
int childCount = toot_picture_container.getChildCount();
ArrayList<ImageView> toRemove = new ArrayList<>();
if( childCount > 0 ){
for(int i = 0 ; i < childCount ; i++){
if( toot_picture_container.getChildAt(i) instanceof ImageView)
toRemove.add((ImageView)toot_picture_container.getChildAt(i));
}
if( toRemove.size() > 0){
for(ImageView imageView: toRemove)
toot_picture_container.removeView(imageView);
}
toRemove.clear();
}
String content = status.getContent();
Pattern mentionLink = Pattern.compile("(<\\s?a\\s?href=\"https?:\\/\\/([\\da-z\\.-]+\\.[a-z\\.]{2,10})\\/(@[\\/\\w._-]*)\"\\s?[^.]*<\\s?\\/\\s?a\\s?>)");
Matcher matcher = mentionLink.matcher(content);
if (matcher.find()) {
content = matcher.replaceAll("$3@$2");
}
if( removed ) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
content = Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY).toString();
else
//noinspection deprecation
content = Html.fromHtml(content).toString();
}
if( attachments != null && attachments.size() > 0){
toot_picture_container.setVisibility(View.VISIBLE);
picture_scrollview.setVisibility(View.VISIBLE);
int i = 0 ;
for(final Attachment attachment: attachments){
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()));
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());
imageView.setAdjustViewBounds(true);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
toot_picture_container.addView(imageView, i, imParams);
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);
}
});
imageView.setTag(attachment.getId());
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
String instanceVersion = sharedpreferences.getString(Helper.INSTANCE_VERSION + userId + instance, null);
if (instanceVersion != null) {
Version currentVersion = new Version(instanceVersion);
Version minVersion = new Version("2.0");
if (currentVersion.compareTo(minVersion) == 1 || currentVersion.equals(minVersion)) {
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showAddDescription(attachment);
}
});
}
}
}
});
imageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
showRemove(imageView.getId());
return false;
}
});
addBorder();
if( attachments.size() < 4)
toot_picture.setEnabled(true);
toot_sensitive.setVisibility(View.VISIBLE);
i++;
}
}else {
toot_picture_container.setVisibility(View.GONE);
}
//Sensitive content
toot_sensitive.setChecked(status.isSensitive());
if( status.getSpoiler_text() != null && status.getSpoiler_text().length() > 0 ){
toot_cw_content.setText(status.getSpoiler_text());
toot_cw_content.setVisibility(View.VISIBLE);
}else {
toot_cw_content.setText("");
toot_cw_content.setVisibility(View.GONE);
}
toot_content.setText(content);
toot_space_left.setText(String.valueOf(toot_content.length()));
toot_content.setSelection(toot_content.getText().length());
switch (status.getVisibility()){
case "public":
visibility = "public";
toot_visibility.setImageResource(R.drawable.ic_public_toot);
break;
case "unlisted":
visibility = "unlisted";
toot_visibility.setImageResource(R.drawable.ic_lock_open_toot);
break;
case "private":
visibility = "private";
toot_visibility.setImageResource(R.drawable.ic_lock_outline_toot);
break;
case "direct":
visibility = "direct";
toot_visibility.setImageResource(R.drawable.ic_mail_outline_toot);
break;
}
if( title != null)
title.setText(getString(R.string.toot_title));
else
setTitle(R.string.toot_title);
invalidateOptionsMenu();
initialContent = toot_content.getText().toString();
toot_space_left.setText(String.valueOf(toot_content.getText().length() + toot_cw_content.getText().length()));
}
private void tootReply(){
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE);
if( title != null)

View File

@ -25,6 +25,7 @@ import fr.gouv.etalab.mastodon.client.API;
import fr.gouv.etalab.mastodon.client.Entities.Account;
import fr.gouv.etalab.mastodon.client.Entities.Error;
import fr.gouv.etalab.mastodon.client.Entities.Results;
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
import fr.gouv.etalab.mastodon.client.PeertubeAPI;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
@ -48,6 +49,14 @@ public class PostActionAsyncTask extends AsyncTask<Void, Void, Void> {
private WeakReference<Context> contextReference;
private boolean muteNotifications;
private Error error;
private StoredStatus storedStatus;
public PostActionAsyncTask(Context context, API.StatusAction apiAction, StoredStatus storedStatus, OnPostActionInterface onPostActionInterface){
this.contextReference = new WeakReference<>(context);
this.listener = onPostActionInterface;
this.apiAction = apiAction;
this.storedStatus = storedStatus;
}
public PostActionAsyncTask(Context context, API.StatusAction apiAction, String targetedId, OnPostActionInterface onPostActionInterface){
this.contextReference = new WeakReference<>(context);
@ -154,7 +163,12 @@ public class PostActionAsyncTask extends AsyncTask<Void, Void, Void> {
statusCode = api.reportAction(status, comment);
else if (apiAction == API.StatusAction.CREATESTATUS)
statusCode = api.statusAction(status);
else if (apiAction == API.StatusAction.MUTE_NOTIFICATIONS)
else if(apiAction == API.StatusAction.UPDATESERVERSCHEDULE) {
api.scheduledAction("PUT", storedStatus.getStatus(), null, storedStatus.getScheduledServerdId());
}
else if(apiAction == API.StatusAction.DELETESCHEDULED) {
api.scheduledAction("DELETE", null, null, storedStatus.getScheduledServerdId());
}else if (apiAction == API.StatusAction.MUTE_NOTIFICATIONS)
statusCode = api.muteNotifications(targetedId, muteNotifications);
else
statusCode = api.postAction(apiAction, targetedId);

View File

@ -170,7 +170,7 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
apiResponse = api.getPublicTimeline(false, max_id);
break;
case SCHEDULED_TOOTS:
apiResponse = api.scheduledAction("GET", null, max_id);
apiResponse = api.scheduledAction("GET", null, max_id, null);
break;
case DIRECT:
apiResponse = api.getDirectTimeline(max_id);

View File

@ -120,7 +120,9 @@ public class API {
PEERTUBECOMMENT,
PEERTUBEREPLY,
PEERTUBEDELETECOMMENT,
PEERTUBEDELETEVIDEO
PEERTUBEDELETEVIDEO,
UPDATESERVERSCHEDULE,
DELETESCHEDULED
}
public enum accountPrivacy {
@ -1856,33 +1858,12 @@ public class API {
* @param status Status object related to the status
* @return APIResponse
*/
public APIResponse scheduledAction(String call, Status status, String max_id){
public APIResponse scheduledAction(String call, Status status, String max_id, String targetedId){
HashMap<String, String> params = new HashMap<>();
if( call.equals("PUT")){
try {
params.put("status", URLEncoder.encode(status.getContent(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
params.put("status", status.getContent());
}
if( status.getIn_reply_to_id() != null)
params.put("in_reply_to_id", 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())
parameters.append("media_ids[]=").append(attachment.getId()).append("&");
parameters = new StringBuilder(parameters.substring(0, parameters.length() - 1).substring(12));
params.put("media_ids[]", parameters.toString());
}
if( status.isSensitive())
params.put("sensitive", Boolean.toString(status.isSensitive()));
if( status.getSpoiler_text() != null)
try {
params.put("spoiler_text", URLEncoder.encode(status.getSpoiler_text(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
params.put("spoiler_text", status.getSpoiler_text());
}
params.put("visibility", status.getVisibility());
if( status.getScheduled_at() != null)
params.put("scheduled_at", status.getScheduled_at());
}else if(call.equals("GET")){
if( max_id != null )
params.put("max_id", max_id);
@ -1891,30 +1872,30 @@ public class API {
try {
HttpsConnection httpsConnection = new HttpsConnection(context);
String response = null;
int responseCode;
int responseCode = -1;
if( call.equals("GET"))
response = httpsConnection.get(getAbsoluteUrl("/scheduled_statuses/"), 60, null, prefKeyOauthTokenT);
else if( call.equals("PUT"))
response = httpsConnection.get(getAbsoluteUrl(String.format("/scheduled_statuses/%s", status.getId())), 60, params, prefKeyOauthTokenT);
response = httpsConnection.put(getAbsoluteUrl(String.format("/scheduled_statuses/%s", targetedId)), 60, params, prefKeyOauthTokenT);
else if( call.equals("DELETE"))
responseCode = httpsConnection.delete(getAbsoluteUrl(String.format("/scheduled_statuses/%s", status.getId())), 60, params, prefKeyOauthTokenT);
responseCode = httpsConnection.delete(getAbsoluteUrl(String.format("/scheduled_statuses/%s",targetedId)), 60, null, prefKeyOauthTokenT);
if(call.equals("GET")) {
apiResponse.setSince_id(httpsConnection.getSince_id());
apiResponse.setMax_id(httpsConnection.getMax_id());
}
if (response != null && call.equals("PUT")) {
Status statusreturned = parseStatuses(context, new JSONObject(response));
Schedule schedule = parseSimpleSchedule(context, new JSONObject(response));
StoredStatus st = new StoredStatus();
st.setCreation_date(status.getCreated_at());
st.setId(-1);
st.setJobId(-1);
st.setScheduled_date(new Date(Long.parseLong(status.getScheduled_at())));
st.setScheduled_date(schedule.getScheduled_at());
st.setStatusReply(null);
st.setSent_date(null);
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
st.setUserId(userId);
st.setStatus(statusreturned);
st.setStatus(schedule.getStatus());
storedStatus.add(st);
}else if (response != null && call.equals("GET")) {
List<Schedule> scheduleList = parseSchedule(context, new JSONArray(response));
@ -1923,7 +1904,7 @@ public class API {
for(Schedule schedule: scheduleList){
StoredStatus st = new StoredStatus();
st.setCreation_date(null);
st.setId(-1);
st.setScheduledServerdId(schedule.getId());
st.setJobId(-1);
st.setScheduled_date(schedule.getScheduled_at());
st.setStatusReply(null);
@ -3196,6 +3177,29 @@ public class API {
return conversation;
}
/**
* Parse json response for several scheduled toots
* @param jsonObject JSONObject
* @return List<Status>
*/
private static Schedule parseSimpleSchedule(Context context, JSONObject jsonObject){
Schedule schedule = new Schedule();
try {
JSONObject resobj = jsonObject.getJSONObject("params");
Status status = parseSchedule(context, resobj);
List<Attachment> attachements = parseAttachmentResponse(jsonObject.getJSONArray("media_attachments"));
status.setMedia_attachments((ArrayList<Attachment>) attachements);
schedule.setStatus(status);
schedule.setAttachmentList(attachements);
schedule.setId(jsonObject.get("id").toString());
schedule.setScheduled_at(Helper.mstStringToDate(context, jsonObject.get("scheduled_at").toString()));
} catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
return schedule;
}
/**
* Parse json response for several scheduled toots
@ -3217,11 +3221,13 @@ public class API {
schedule.setAttachmentList(attachements);
schedules.add(schedule);
schedule.setId(jsonArray.getJSONObject(i).get("id").toString());
schedule.setScheduled_at(Helper.stringToDate(context, resobj.get("scheduled_at").toString()));
schedule.setScheduled_at(Helper.mstStringToDate(context, jsonArray.getJSONObject(i).get("scheduled_at").toString()));
i++;
}
} catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
return schedules;
}

View File

@ -15,6 +15,9 @@
package fr.gouv.etalab.mastodon.client.Entities;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Date;
import java.util.List;
@ -23,7 +26,7 @@ import java.util.List;
* Manages scheduled toots
*/
public class Schedule {
public class Schedule implements Parcelable {
private String id;
private Date scheduled_at;
@ -64,4 +67,37 @@ public class Schedule {
public void setAttachmentList(List<Attachment> attachmentList) {
this.attachmentList = attachmentList;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.id);
dest.writeLong(this.scheduled_at != null ? this.scheduled_at.getTime() : -1);
dest.writeParcelable(this.status, flags);
dest.writeTypedList(this.attachmentList);
}
protected Schedule(Parcel in) {
this.id = in.readString();
long tmpScheduled_at = in.readLong();
this.scheduled_at = tmpScheduled_at == -1 ? null : new Date(tmpScheduled_at);
this.status = in.readParcelable(Status.class.getClassLoader());
this.attachmentList = in.createTypedArrayList(Attachment.CREATOR);
}
public static final Parcelable.Creator<Schedule> CREATOR = new Parcelable.Creator<Schedule>() {
@Override
public Schedule createFromParcel(Parcel source) {
return new Schedule(source);
}
@Override
public Schedule[] newArray(int size) {
return new Schedule[size];
}
};
}

View File

@ -1,5 +1,8 @@
package fr.gouv.etalab.mastodon.client.Entities;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Date;
@ -8,7 +11,7 @@ import java.util.Date;
* Manage Stored status
*/
public class StoredStatus {
public class StoredStatus implements Parcelable {
private int id;
private Date creation_date;
@ -20,6 +23,7 @@ public class StoredStatus {
private Status statusReply;
private String instance;
private String userId;
private String scheduledServerdId;
public int getId() {
return id;
@ -101,4 +105,65 @@ public class StoredStatus {
public void setStatusReply(Status statusReply) {
this.statusReply = statusReply;
}
public String getScheduledServerdId() {
return scheduledServerdId;
}
public void setScheduledServerdId(String scheduledServerdId) {
this.scheduledServerdId = scheduledServerdId;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeLong(this.creation_date != null ? this.creation_date.getTime() : -1);
dest.writeLong(this.scheduled_date != null ? this.scheduled_date.getTime() : -1);
dest.writeLong(this.sent_date != null ? this.sent_date.getTime() : -1);
dest.writeInt(this.jobId);
dest.writeByte(this.isSent ? (byte) 1 : (byte) 0);
dest.writeParcelable(this.status, flags);
dest.writeParcelable(this.statusReply, flags);
dest.writeString(this.instance);
dest.writeString(this.userId);
dest.writeString(this.scheduledServerdId);
}
public StoredStatus() {
}
protected StoredStatus(Parcel in) {
this.id = in.readInt();
long tmpCreation_date = in.readLong();
this.creation_date = tmpCreation_date == -1 ? null : new Date(tmpCreation_date);
long tmpScheduled_date = in.readLong();
this.scheduled_date = tmpScheduled_date == -1 ? null : new Date(tmpScheduled_date);
long tmpSent_date = in.readLong();
this.sent_date = tmpSent_date == -1 ? null : new Date(tmpSent_date);
this.jobId = in.readInt();
this.isSent = in.readByte() != 0;
this.status = in.readParcelable(Status.class.getClassLoader());
this.statusReply = in.readParcelable(Status.class.getClassLoader());
this.instance = in.readString();
this.userId = in.readString();
this.scheduledServerdId = in.readString();
}
public static final Creator<StoredStatus> CREATOR = new Creator<StoredStatus>() {
@Override
public StoredStatus createFromParcel(Parcel source) {
return new StoredStatus(source);
}
@Override
public StoredStatus[] newArray(int size) {
return new StoredStatus[size];
}
};
}

View File

@ -20,6 +20,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
@ -49,10 +50,14 @@ import fr.gouv.etalab.mastodon.R;
import fr.gouv.etalab.mastodon.activities.MainActivity;
import fr.gouv.etalab.mastodon.activities.ShowConversationActivity;
import fr.gouv.etalab.mastodon.activities.TootActivity;
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
import fr.gouv.etalab.mastodon.client.API;
import fr.gouv.etalab.mastodon.client.Entities.Error;
import fr.gouv.etalab.mastodon.client.Entities.Status;
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
import fr.gouv.etalab.mastodon.fragments.DisplayScheduledTootsFragment;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
import fr.gouv.etalab.mastodon.jobs.ApplicationJob;
import fr.gouv.etalab.mastodon.jobs.ScheduledBoostsSyncJob;
import fr.gouv.etalab.mastodon.jobs.ScheduledTootsSyncJob;
@ -67,7 +72,7 @@ import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor;
* Created by Thomas on 16/07/2017.
* Adapter for scheduled toots
*/
public class ScheduledTootsListAdapter extends BaseAdapter {
public class ScheduledTootsListAdapter extends BaseAdapter implements OnPostActionInterface {
private Context context;
private List<StoredStatus> storedStatuses;
@ -195,18 +200,27 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if( type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT)
new StatusStoredDAO(context, db).remove(storedStatus.getId());
else if (type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST)
new BoostScheduleDAO(context, db).remove(storedStatus.getId());
storedStatuses.remove(storedStatus);
scheduledTootsListAdapter.notifyDataSetChanged();
if( storedStatuses.size() == 0 && textviewNoAction != null && textviewNoAction.getVisibility() == View.GONE)
if( type != DisplayScheduledTootsFragment.typeOfSchedule.SERVER) {
if (type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT)
new StatusStoredDAO(context, db).remove(storedStatus.getId());
else if (type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST)
new BoostScheduleDAO(context, db).remove(storedStatus.getId());
storedStatuses.remove(storedStatus);
scheduledTootsListAdapter.notifyDataSetChanged();
if (storedStatuses.size() == 0 && textviewNoAction != null && textviewNoAction.getVisibility() == View.GONE)
textviewNoAction.setVisibility(View.VISIBLE);
try {
//Cancel the job
ApplicationJob.cancelJob(storedStatus.getJobId());
}catch (Exception ignored){}
try {
//Cancel the job
ApplicationJob.cancelJob(storedStatus.getJobId());
} catch (Exception ignored) {
}
}else{
new PostActionAsyncTask(context, API.StatusAction.DELETESCHEDULED, storedStatus, ScheduledTootsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
storedStatuses.remove(storedStatus);
scheduledTootsListAdapter.notifyDataSetChanged();
if (storedStatuses.size() == 0 && textviewNoAction != null && textviewNoAction.getVisibility() == View.GONE)
textviewNoAction.setVisibility(View.VISIBLE);
}
dialog.dismiss();
}
})
@ -221,10 +235,12 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
}
});
if (storedStatus.getJobId() > 0) {
holder.scheduled_toot_failed.setVisibility(View.GONE);
}else {
holder.scheduled_toot_failed.setVisibility(View.VISIBLE);
if( type != DisplayScheduledTootsFragment.typeOfSchedule.SERVER) {
if (storedStatus.getJobId() > 0) {
holder.scheduled_toot_failed.setVisibility(View.GONE);
} else {
holder.scheduled_toot_failed.setVisibility(View.VISIBLE);
}
}
holder.scheduled_toot_media_count.setText(context.getString(R.string.media_count, status.getMedia_attachments().size()));
holder.scheduled_toot_date_creation.setText(Helper.dateToString(storedStatus.getCreation_date()));
@ -319,28 +335,35 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
Toasty.error(context, context.getString(R.string.toot_scheduled_date), Toast.LENGTH_LONG).show();
}else {
//Schedules the toot to the new date
try {
//Removes the job
ApplicationJob.cancelJob(storedStatus.getJobId());
//Replace it by the new one
StoredStatus storedStatusnew = null;
if( type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT) {
ScheduledTootsSyncJob.schedule(context, storedStatus.getId(), time);
storedStatusnew = new StatusStoredDAO(context, db).getStatus(storedStatus.getId());
}else if(type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST){
ScheduledBoostsSyncJob.scheduleUpdate(context, storedStatus.getId(), time);
storedStatusnew = new BoostScheduleDAO(context, db).getStatus(storedStatus.getId());
if( type != DisplayScheduledTootsFragment.typeOfSchedule.SERVER) {
try {
//Removes the job
ApplicationJob.cancelJob(storedStatus.getJobId());
//Replace it by the new one
StoredStatus storedStatusnew = null;
if (type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT) {
ScheduledTootsSyncJob.schedule(context, storedStatus.getId(), time);
storedStatusnew = new StatusStoredDAO(context, db).getStatus(storedStatus.getId());
} else if (type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST) {
ScheduledBoostsSyncJob.scheduleUpdate(context, storedStatus.getId(), time);
storedStatusnew = new BoostScheduleDAO(context, db).getStatus(storedStatus.getId());
}
//Date displayed is changed
assert storedStatusnew != null;
storedStatus.setScheduled_date(storedStatusnew.getScheduled_date());
scheduledTootsListAdapter.notifyDataSetChanged();
//Notifiy all is ok
if (type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT)
Toasty.success(context, context.getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show();
else
Toasty.success(context, context.getString(R.string.boost_scheduled), Toast.LENGTH_LONG).show();
} catch (Exception ignored) {
}
//Date displayed is changed
assert storedStatusnew != null;
storedStatus.setScheduled_date(storedStatusnew.getScheduled_date());
scheduledTootsListAdapter.notifyDataSetChanged();
//Notifiy all is ok
if( type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT)
Toasty.success(context,context.getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show();
else
Toasty.success(context,context.getString(R.string.boost_scheduled), Toast.LENGTH_LONG).show();
}catch (Exception ignored){}
}else{
storedStatus.getStatus().setScheduled_at(Helper.dateToString(calendar.getTime()));
new PostActionAsyncTask(context, API.StatusAction.UPDATESERVERSCHEDULE, storedStatus, ScheduledTootsListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Toasty.success(context, context.getString(R.string.boost_scheduled), Toast.LENGTH_LONG).show();
}
alertDialog.dismiss();
}
}
@ -385,9 +408,27 @@ public class ScheduledTootsListAdapter extends BaseAdapter {
context.startActivity(intentToot);
}
});
else if( type == DisplayScheduledTootsFragment.typeOfSchedule.SERVER)
holder.scheduled_toot_container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intentToot = new Intent(context, TootActivity.class);
Bundle b = new Bundle();
if( storedStatus.getStatus().getSpoiler_text().equals("null"))
storedStatus.getStatus().setSpoiler_text("");
b.putParcelable("storedStatus", storedStatus);
intentToot.putExtras(b);
context.startActivity(intentToot);
}
});
return convertView;
}
@Override
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
}
private class ViewHolder {
LinearLayout scheduled_toot_container;
TextView scheduled_toot_title;

View File

@ -135,56 +135,59 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev
@Override
public void onResume(){
super.onResume();
//Retrieves scheduled toots
asyncTask = new RetrieveScheduledTootsAsyncTask(context, type,DisplayScheduledTootsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
final PowerManager powerManager = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
//Battery saver is one and user never asked to stop showing the message
changeDrawableColor(context, R.drawable.ic_report, R.color.mastodonC4);
changeDrawableColor(context, R.drawable.ic_cancel, R.color.mastodonC4);
if( powerManager != null && powerManager.isPowerSaveMode() && sharedpreferences.getBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE,true)){
warning_battery_message.setVisibility(View.VISIBLE);
}else {
warning_battery_message.setVisibility(View.GONE);
}
warning_battery_message.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
final int DRAWABLE_RIGHT = 2;
if(event.getAction() == MotionEvent.ACTION_UP) {
if(event.getRawX() >= (warning_battery_message.getRight() - warning_battery_message.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE, false);
editor.apply();
warning_battery_message.setVisibility(View.GONE);
return true;
if( type != null && type != typeOfSchedule.SERVER) {
//Retrieves scheduled toots
asyncTask = new RetrieveScheduledTootsAsyncTask(context, type, DisplayScheduledTootsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
final PowerManager powerManager = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
//Battery saver is one and user never asked to stop showing the message
changeDrawableColor(context, R.drawable.ic_report, R.color.mastodonC4);
changeDrawableColor(context, R.drawable.ic_cancel, R.color.mastodonC4);
if (powerManager != null && powerManager.isPowerSaveMode() && sharedpreferences.getBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE, true)) {
warning_battery_message.setVisibility(View.VISIBLE);
} else {
warning_battery_message.setVisibility(View.GONE);
}
warning_battery_message.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
final int DRAWABLE_RIGHT = 2;
if (event.getAction() == MotionEvent.ACTION_UP) {
if (event.getRawX() >= (warning_battery_message.getRight() - warning_battery_message.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE, false);
editor.apply();
warning_battery_message.setVisibility(View.GONE);
return true;
}
}
return false;
}
});
warning_battery_message.setOnClickListener(new View.OnClickListener() {
@SuppressLint("BatteryLife")
@Override
public void onClick(View v) {
try {
Intent battSaverIntent = new Intent();
battSaverIntent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings$BatterySaverSettingsActivity"));
startActivityForResult(battSaverIntent, 0);
} catch (ActivityNotFoundException e) {
try {
Intent batterySaverIntent;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
batterySaverIntent = new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS);
startActivity(batterySaverIntent);
}
} catch (ActivityNotFoundException ignored) {
}
}
}
return false;
}
});
warning_battery_message.setOnClickListener(new View.OnClickListener() {
@SuppressLint("BatteryLife")
@Override
public void onClick(View v) {
try {
Intent battSaverIntent = new Intent();
battSaverIntent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings$BatterySaverSettingsActivity"));
startActivityForResult(battSaverIntent, 0);
}catch (ActivityNotFoundException e){
try {
Intent batterySaverIntent;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
batterySaverIntent = new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS);
startActivity(batterySaverIntent);
}
}catch (ActivityNotFoundException ignored){}
}
}
});
}else {
warning_battery_message.setVisibility(View.GONE);
});
} else {
warning_battery_message.setVisibility(View.GONE);
}
}
}

View File

@ -833,6 +833,7 @@
<string name="server_schedule">From server</string>
<string name="toots_server">Toots (Server)</string>
<string name="toots_client">Toots (Device)</string>
<string name="modify">Modify</string>
<!-- end languages -->