From 523e1ecd091b647827ea12759e13a5a1ee6f139e Mon Sep 17 00:00:00 2001 From: stom79 Date: Sun, 9 Dec 2018 15:47:26 +0100 Subject: [PATCH] Issue #622 - Frontend for scheduled boosts --- .../drawers/ScheduledTootsListAdapter.java | 149 +++++++++++++----- .../mastodon/drawers/StatusListAdapter.java | 78 +++++++++ .../DisplayScheduledTootsFragment.java | 20 ++- .../fragments/TabLayoutScheduleFragment.java | 1 + .../etalab/mastodon/jobs/ApplicationJob.java | 2 + .../mastodon/jobs/ScheduledBoostsSyncJob.java | 25 ++- .../mastodon/sqlite/BoostScheduleDAO.java | 22 ++- .../main/res/layout/drawer_scheduled_toot.xml | 9 +- .../res/layout/fragment_scheduled_toots.xml | 1 + app/src/main/res/menu/option_toot.xml | 16 +- app/src/main/res/values/strings.xml | 6 +- 11 files changed, 267 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ScheduledTootsListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ScheduledTootsListAdapter.java index f8157fce6..a61d590dd 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ScheduledTootsListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/ScheduledTootsListAdapter.java @@ -23,6 +23,8 @@ import android.database.sqlite.SQLiteDatabase; import android.os.Build; import android.os.Bundle; import android.support.v7.app.AlertDialog; +import android.text.Html; +import android.text.Spanned; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -45,12 +47,16 @@ import java.util.List; import es.dmoral.toasty.Toasty; 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.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.jobs.ApplicationJob; +import fr.gouv.etalab.mastodon.jobs.ScheduledBoostsSyncJob; import fr.gouv.etalab.mastodon.jobs.ScheduledTootsSyncJob; +import fr.gouv.etalab.mastodon.sqlite.BoostScheduleDAO; import fr.gouv.etalab.mastodon.sqlite.Sqlite; import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO; @@ -68,13 +74,15 @@ public class ScheduledTootsListAdapter extends BaseAdapter { private LayoutInflater layoutInflater; private ScheduledTootsListAdapter scheduledTootsListAdapter; private RelativeLayout textviewNoAction; + private DisplayScheduledTootsFragment.typeOfSchedule type; - public ScheduledTootsListAdapter(Context context, List storedStatuses, RelativeLayout textviewNoAction){ + public ScheduledTootsListAdapter(Context context, DisplayScheduledTootsFragment.typeOfSchedule type, List storedStatuses, RelativeLayout textviewNoAction){ this.context = context; this.storedStatuses = storedStatuses; layoutInflater = LayoutInflater.from(this.context); scheduledTootsListAdapter = this; this.textviewNoAction = textviewNoAction; + this.type = type; } @@ -103,6 +111,7 @@ public class ScheduledTootsListAdapter extends BaseAdapter { if (convertView == null) { convertView = layoutInflater.inflate(R.layout.drawer_scheduled_toot, parent, false); holder = new ViewHolder(); + holder.scheduled_toot_pp= convertView.findViewById(R.id.scheduled_toot_pp); holder.scheduled_toot_title = convertView.findViewById(R.id.scheduled_toot_title); holder.scheduled_toot_date_creation = convertView.findViewById(R.id.scheduled_toot_date_creation); holder.scheduled_toot_media_count = convertView.findViewById(R.id.scheduled_toot_media_count); @@ -119,18 +128,24 @@ public class ScheduledTootsListAdapter extends BaseAdapter { final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); final int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); - if( theme == Helper.THEME_DARK){ - changeDrawableColor(context, R.drawable.ic_cancel,R.color.dark_text); - changeDrawableColor(context, R.drawable.ic_public,R.color.dark_text); - changeDrawableColor(context, R.drawable.ic_lock_open,R.color.dark_text); - changeDrawableColor(context, R.drawable.ic_lock_outline,R.color.dark_text); - changeDrawableColor(context, R.drawable.ic_mail_outline,R.color.dark_text); + if( theme == Helper.THEME_BLACK) { + changeDrawableColor(context, R.drawable.ic_cancel,R.color.action_black); + changeDrawableColor(context, R.drawable.ic_public,R.color.action_black); + changeDrawableColor(context, R.drawable.ic_lock_open,R.color.action_black); + changeDrawableColor(context, R.drawable.ic_lock_outline,R.color.action_black); + changeDrawableColor(context, R.drawable.ic_mail_outline,R.color.action_black); + }else if( theme == Helper.THEME_DARK){ + changeDrawableColor(context, R.drawable.ic_cancel,R.color.action_dark); + changeDrawableColor(context, R.drawable.ic_public,R.color.action_dark); + changeDrawableColor(context, R.drawable.ic_lock_open,R.color.action_dark); + changeDrawableColor(context, R.drawable.ic_lock_outline,R.color.action_dark); + changeDrawableColor(context, R.drawable.ic_mail_outline,R.color.action_dark); }else { - changeDrawableColor(context, R.drawable.ic_cancel,R.color.black); - changeDrawableColor(context, R.drawable.ic_public,R.color.black); - changeDrawableColor(context, R.drawable.ic_lock_open,R.color.black); - changeDrawableColor(context, R.drawable.ic_lock_outline,R.color.black); - changeDrawableColor(context, R.drawable.ic_mail_outline,R.color.black); + changeDrawableColor(context, R.drawable.ic_cancel,R.color.action_light); + changeDrawableColor(context, R.drawable.ic_public,R.color.action_light); + changeDrawableColor(context, R.drawable.ic_lock_open,R.color.action_light); + changeDrawableColor(context, R.drawable.ic_lock_outline,R.color.action_light); + changeDrawableColor(context, R.drawable.ic_mail_outline,R.color.action_light); } final Status status = storedStatus.getStatus(); @@ -163,13 +178,28 @@ public class ScheduledTootsListAdapter extends BaseAdapter { @Override public void onClick(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(context, style); - builder.setMessage(status.getContent() + '\n' + Helper.dateToString(storedStatus.getCreation_date())); + + String message; + if( type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT) + message = status.getContent() + '\n' + Helper.dateToString(storedStatus.getCreation_date()); + else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + message = Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_LEGACY).toString(); + else + //noinspection deprecation + message = Html.fromHtml(status.getContent()).toString(); + message += '\n' + Helper.dateToString(storedStatus.getScheduled_date()); + } + builder.setMessage(message); builder.setIcon(android.R.drawable.ic_dialog_alert) .setTitle(R.string.remove_scheduled) .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - new StatusStoredDAO(context, db).remove(storedStatus.getId()); + 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) @@ -200,6 +230,14 @@ public class ScheduledTootsListAdapter extends BaseAdapter { 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())); holder.scheduled_toot_date.setText(Helper.dateToString(storedStatus.getScheduled_date())); + if( type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST){ + holder.scheduled_toot_media_count.setVisibility(View.GONE); + holder.scheduled_toot_date_creation.setVisibility(View.GONE); + holder.scheduled_toot_privacy.setVisibility(View.GONE); + Helper.loadGiF(context, storedStatus.getStatus().getAccount().getAvatar(), holder.scheduled_toot_pp); + }else { + holder.scheduled_toot_pp.setVisibility(View.GONE); + } holder.scheduled_toot_date.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -208,14 +246,19 @@ public class ScheduledTootsListAdapter extends BaseAdapter { @SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.datetime_picker, null); SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE); int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); - if( theme == Helper.THEME_DARK){ - changeDrawableColor(context, R.drawable.ic_skip_previous,R.color.dark_text); - changeDrawableColor(context, R.drawable.ic_skip_next,R.color.dark_text); - changeDrawableColor(context, R.drawable.ic_check,R.color.dark_text); + + if( theme == Helper.THEME_BLACK){ + changeDrawableColor(context, R.drawable.ic_skip_previous,R.color.action_black); + changeDrawableColor(context, R.drawable.ic_skip_next,R.color.action_black); + changeDrawableColor(context, R.drawable.ic_check,R.color.action_black); + }else if( theme == Helper.THEME_DARK){ + changeDrawableColor(context, R.drawable.ic_skip_previous,R.color.action_dark); + changeDrawableColor(context, R.drawable.ic_skip_next,R.color.action_dark); + changeDrawableColor(context, R.drawable.ic_check,R.color.action_dark); }else { - changeDrawableColor(context, R.drawable.ic_skip_previous,R.color.black); - changeDrawableColor(context, R.drawable.ic_skip_next,R.color.black); - changeDrawableColor(context, R.drawable.ic_check,R.color.black); + changeDrawableColor(context, R.drawable.ic_skip_previous,R.color.action_light); + changeDrawableColor(context, R.drawable.ic_skip_next,R.color.action_light); + changeDrawableColor(context, R.drawable.ic_check,R.color.action_light); } dialogBuilder.setView(dialogView); final AlertDialog alertDialog = dialogBuilder.create(); @@ -281,13 +324,23 @@ public class ScheduledTootsListAdapter extends BaseAdapter { //Removes the job ApplicationJob.cancelJob(storedStatus.getJobId()); //Replace it by the new one - ScheduledTootsSyncJob.schedule(context, storedStatus.getId(), time); - StoredStatus storedStatusnew = new StatusStoredDAO(context, db).getStatus(storedStatus.getId()); + 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 - Toasty.success(context,context.getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show(); + 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){} alertDialog.dismiss(); } @@ -296,22 +349,43 @@ public class ScheduledTootsListAdapter extends BaseAdapter { alertDialog.show(); } }); - holder.scheduled_toot_title.setText(status.getContent()); + if( type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT) + holder.scheduled_toot_title.setText(status.getContent()); + else if( type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST){ + Spanned message; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + message = Html.fromHtml(status.getContent(), Html.FROM_HTML_MODE_LEGACY); + else + //noinspection deprecation + message = Html.fromHtml(status.getContent()); + holder.scheduled_toot_title.setText(message, TextView.BufferType.SPANNABLE); + } - 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(); - b.putLong("restored", storedStatus.getId()); - b.putBoolean("restoredScheduled", true); - intentToot.putExtras(b); - context.startActivity(intentToot); - } - }); - + if( type == DisplayScheduledTootsFragment.typeOfSchedule.TOOT) + 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(); + b.putLong("restored", storedStatus.getId()); + b.putBoolean("restoredScheduled", true); + intentToot.putExtras(b); + context.startActivity(intentToot); + } + }); + else if( type == DisplayScheduledTootsFragment.typeOfSchedule.BOOST) + holder.scheduled_toot_container.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intentToot = new Intent(context, ShowConversationActivity.class); + Bundle b = new Bundle(); + b.putParcelable("status", storedStatus.getStatus()); + intentToot.putExtras(b); + context.startActivity(intentToot); + } + }); return convertView; } @@ -323,6 +397,7 @@ public class ScheduledTootsListAdapter extends BaseAdapter { TextView scheduled_toot_failed; ImageView scheduled_toot_delete; ImageView scheduled_toot_privacy; + ImageView scheduled_toot_pp; Button scheduled_toot_date; } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java index 7a659506f..8989616af 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java @@ -114,6 +114,7 @@ import fr.gouv.etalab.mastodon.interfaces.OnRetrieveCardInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveRepliesInterface; +import fr.gouv.etalab.mastodon.jobs.ScheduledBoostsSyncJob; import fr.gouv.etalab.mastodon.sqlite.AccountDAO; import fr.gouv.etalab.mastodon.sqlite.Sqlite; import fr.gouv.etalab.mastodon.sqlite.StatusCacheDAO; @@ -1600,6 +1601,8 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct else popup.getMenu().findItem(R.id.action_bookmark).setTitle(R.string.bookmark_add); final String[] stringArrayConf; + if( status.getVisibility().equals("direct") || (status.getVisibility().equals("private") && !isOwner)) + popup.getMenu().findItem(R.id.action_schedule_boost).setVisible(false); if( isOwner) { popup.getMenu().findItem(R.id.action_block).setVisible(false); popup.getMenu().findItem(R.id.action_mute).setVisible(false); @@ -1644,6 +1647,81 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct //noinspection deprecation builderInner.setMessage(Html.fromHtml(status.getContent())); break; + case R.id.action_schedule_boost: + AlertDialog.Builder dialogBuilderBoost = new AlertDialog.Builder(context, style); + LayoutInflater inflaterBoost = ((Activity)context).getLayoutInflater(); + @SuppressLint("InflateParams") View dialogViewBoost = inflaterBoost.inflate(R.layout.datetime_picker, null); + dialogBuilderBoost.setView(dialogViewBoost); + final AlertDialog alertDialogBoost = dialogBuilderBoost.create(); + + final DatePicker datePickerBoost = dialogViewBoost.findViewById(R.id.date_picker); + final TimePicker timePickerBoost = dialogViewBoost.findViewById(R.id.time_picker); + timePickerBoost.setIs24HourView(true); + Button date_time_cancelBoost = dialogViewBoost.findViewById(R.id.date_time_cancel); + final ImageButton date_time_previousBoost = dialogViewBoost.findViewById(R.id.date_time_previous); + final ImageButton date_time_nextBoost = dialogViewBoost.findViewById(R.id.date_time_next); + final ImageButton date_time_setBoost = dialogViewBoost.findViewById(R.id.date_time_set); + + //Buttons management + date_time_cancelBoost.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + alertDialogBoost.dismiss(); + } + }); + date_time_nextBoost.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + datePickerBoost.setVisibility(View.GONE); + timePickerBoost.setVisibility(View.VISIBLE); + date_time_previousBoost.setVisibility(View.VISIBLE); + date_time_nextBoost.setVisibility(View.GONE); + date_time_setBoost.setVisibility(View.VISIBLE); + } + }); + date_time_previousBoost.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + datePickerBoost.setVisibility(View.VISIBLE); + timePickerBoost.setVisibility(View.GONE); + date_time_previousBoost.setVisibility(View.GONE); + date_time_nextBoost.setVisibility(View.VISIBLE); + date_time_setBoost.setVisibility(View.GONE); + } + }); + date_time_setBoost.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int hour, minute; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + hour = timePickerBoost.getHour(); + minute = timePickerBoost.getMinute(); + }else { + //noinspection deprecation + hour = timePickerBoost.getCurrentHour(); + //noinspection deprecation + minute = timePickerBoost.getCurrentMinute(); + } + Calendar calendar = new GregorianCalendar(datePickerBoost.getYear(), + datePickerBoost.getMonth(), + datePickerBoost.getDayOfMonth(), + hour, + minute); + long time = calendar.getTimeInMillis(); + if( (time - new Date().getTime()) < 60000 ){ + Toasty.warning(context, context.getString(R.string.toot_scheduled_date), Toast.LENGTH_LONG).show(); + }else { + //Schedules the toot + ScheduledBoostsSyncJob.schedule(context,status, time); + //Clear content + Toasty.info(context, context.getString(R.string.boost_scheduled), Toast.LENGTH_LONG).show(); + alertDialogBoost.dismiss(); + } + } + }); + alertDialogBoost.show(); + + return true; case R.id.action_info: Intent intent = new Intent(context, TootInfoActivity.class); Bundle b = new Bundle(); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayScheduledTootsFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayScheduledTootsFragment.java index 2b851f2fa..75580b77d 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayScheduledTootsFragment.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayScheduledTootsFragment.java @@ -28,6 +28,8 @@ import android.os.PowerManager; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; +import android.text.Html; +import android.text.Spanned; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -75,7 +77,8 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev View rootView = inflater.inflate(R.layout.fragment_scheduled_toots, container, false); context = getContext(); - Bundle bundle = new Bundle(); + Bundle bundle = this.getArguments(); + assert bundle != null; type = (typeOfSchedule) bundle.get("type"); if( type == null) type = typeOfSchedule.TOOT; @@ -177,11 +180,24 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev mainLoader.setVisibility(View.GONE); if( storedStatuses != null && storedStatuses.size() > 0 ){ - ScheduledTootsListAdapter scheduledTootsListAdapter = new ScheduledTootsListAdapter(context, storedStatuses, textviewNoAction); + ScheduledTootsListAdapter scheduledTootsListAdapter = new ScheduledTootsListAdapter(context, type, storedStatuses, textviewNoAction); lv_scheduled_toots.setAdapter(scheduledTootsListAdapter); textviewNoAction.setVisibility(View.GONE); }else { textviewNoAction.setVisibility(View.VISIBLE); + if( type == typeOfSchedule.BOOST) { + TextView no_action_text = textviewNoAction.findViewById(R.id.no_action_text); + TextView no_action_text_subtitle = textviewNoAction.findViewById(R.id.no_action_text_subtitle); + no_action_text.setText(context.getString(R.string.no_scheduled_boosts)); + + Spanned message; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + message = Html.fromHtml(context.getString(R.string.no_scheduled_boosts_indications), Html.FROM_HTML_MODE_LEGACY); + else + //noinspection deprecation + message = Html.fromHtml(context.getString(R.string.no_scheduled_boosts_indications)); + no_action_text_subtitle.setText(message, TextView.BufferType.SPANNABLE); + } } } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/TabLayoutScheduleFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/TabLayoutScheduleFragment.java index f3118826f..db52f3ee8 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/TabLayoutScheduleFragment.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/TabLayoutScheduleFragment.java @@ -95,6 +95,7 @@ public class TabLayoutScheduleFragment extends Fragment { bundle = new Bundle(); bundle.putSerializable("type", DisplayScheduledTootsFragment.typeOfSchedule.BOOST); displayScheduledTootsFragment.setArguments(bundle); + return displayScheduledTootsFragment; default: displayScheduledTootsFragment = new DisplayScheduledTootsFragment(); bundle = new Bundle(); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java index d95df9d8e..1cfc5a48b 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java @@ -34,6 +34,8 @@ public class ApplicationJob implements JobCreator { return new HomeTimelineSyncJob(); case ScheduledTootsSyncJob.SCHEDULED_TOOT: return new ScheduledTootsSyncJob(); + case ScheduledBoostsSyncJob.SCHEDULED_BOOST: + return new ScheduledBoostsSyncJob(); default: return null; } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ScheduledBoostsSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ScheduledBoostsSyncJob.java index 83c193a6d..1334cbd36 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ScheduledBoostsSyncJob.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ScheduledBoostsSyncJob.java @@ -63,7 +63,8 @@ public class ScheduledBoostsSyncJob extends Job { //Retrieves the linked status to toot Status status = storedStatus.getStatus(); if( status != null){ - int statusCode = new API(getContext(), account.getInstance(), account.getToken()).statusAction(status); + int statusCode = new API(getContext(), account.getInstance(), account.getToken()).postAction( API.StatusAction.REBLOG, status.getId()); + //Toot was sent if( statusCode == 200){ new BoostScheduleDAO(getContext(), db).updateScheduledDone(jobId, new Date()); @@ -76,7 +77,7 @@ public class ScheduledBoostsSyncJob extends Job { } - public static int schedule(Context context, Status status, long id, long timestampScheduling){ + public static int schedule(Context context, Status status, long timestampScheduling){ long startMs = (timestampScheduling - new Date().getTime()); long endMs = startMs + TimeUnit.MINUTES.toMillis(5); @@ -89,7 +90,25 @@ public class ScheduledBoostsSyncJob extends Job { .setRequirementsEnforced(false) .build() .schedule(); - new BoostScheduleDAO(context, db).insert(status, id, jobId, new Date(timestampScheduling)); + new BoostScheduleDAO(context, db).insert(status, jobId, new Date(timestampScheduling)); + return jobId; + } + + + public static int scheduleUpdate(Context context, int tootStoredId, long timestampScheduling){ + + long startMs = (timestampScheduling - new Date().getTime()); + long endMs = startMs + TimeUnit.MINUTES.toMillis(5); + SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + + int jobId = new JobRequest.Builder(ScheduledTootsSyncJob.SCHEDULED_TOOT) + .setExecutionWindow(startMs, endMs) + .setUpdateCurrent(false) + .setRequiredNetworkType(JobRequest.NetworkType.METERED) + .setRequirementsEnforced(false) + .build() + .schedule(); + new BoostScheduleDAO(context, db).updateScheduledDate(tootStoredId, jobId, new Date(timestampScheduling)); return jobId; } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/BoostScheduleDAO.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/BoostScheduleDAO.java index b010237e5..a1d13f3a8 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/BoostScheduleDAO.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/BoostScheduleDAO.java @@ -51,11 +51,11 @@ public class BoostScheduleDAO { /** * Insert a status in database * @param status Status - * @param id long * @param jobId int * @return boolean */ - public long insert(Status status, long id, int jobId, Date date_scheduled ) { + public long insert(Status status, int jobId, Date date_scheduled ) { + ContentValues values = new ContentValues(); String serializedStatus = Helper.statusToStringStorage(status); SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); @@ -64,7 +64,6 @@ public class BoostScheduleDAO { if( userId == null || instance == null) return -1; values.put(Sqlite.COL_STATUS_SERIALIZED, serializedStatus); - values.put(Sqlite.COL_DATE_CREATION, Helper.dateToString(new Date())); values.put(Sqlite.COL_INSTANCE, instance); values.put(Sqlite.COL_USER_ID, userId); values.put(Sqlite.COL_SENT, 0); @@ -75,6 +74,7 @@ public class BoostScheduleDAO { try{ last_id = db.insert(Sqlite.TABLE_BOOST_SCHEDULE, null, values); }catch (Exception e) { + e.printStackTrace(); last_id = -1; } return last_id; @@ -100,12 +100,12 @@ public class BoostScheduleDAO { * @param scheduled_date Date * @return boolean */ - public int updateScheduledDate(int jobid, Date scheduled_date) { + public int updateScheduledDate(int statusStoredId, int jobid, Date scheduled_date) { ContentValues values = new ContentValues(); values.put(Sqlite.COL_DATE_SCHEDULED, Helper.dateToString(scheduled_date)); return db.update(Sqlite.TABLE_BOOST_SCHEDULE, - values, Sqlite.COL_IS_SCHEDULED + " = ? ", - new String[]{String.valueOf(jobid)}); + values, Sqlite.COL_IS_SCHEDULED + " = ? AND " + Sqlite.COL_ID + " = ?", + new String[]{String.valueOf(jobid), String.valueOf(statusStoredId)}); } /** @@ -152,6 +152,7 @@ public class BoostScheduleDAO { Cursor c = db.query(Sqlite.TABLE_BOOST_SCHEDULE, null, Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_IS_SCHEDULED + " != 0 AND " + Sqlite.COL_SENT + " = 0", null, null, null, Sqlite.COL_DATE_SCHEDULED + " ASC", null); return cursorToListStatuses(c); } catch (Exception e) { + e.printStackTrace(); return null; } } @@ -164,7 +165,7 @@ public class BoostScheduleDAO { SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); String instance = Helper.getLiveInstance(context); - Cursor c = db.query(Sqlite.TABLE_BOOST_SCHEDULE, null, Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " +Sqlite.COL_IS_SCHEDULED + " != 0 AND " + Sqlite.COL_SENT + " = 0", null, null, null, Sqlite.COL_DATE_CREATION + " DESC", null); + Cursor c = db.query(Sqlite.TABLE_BOOST_SCHEDULE, null, Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " +Sqlite.COL_IS_SCHEDULED + " != 0 AND " + Sqlite.COL_SENT + " = 0", null, null, null, Sqlite.COL_DATE_SCHEDULED + " DESC", null); return cursorToListStatuses(c); } catch (Exception e) { return null; @@ -180,7 +181,7 @@ public class BoostScheduleDAO { SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); String instance = Helper.getLiveInstance(context); - Cursor c = db.query(Sqlite.TABLE_BOOST_SCHEDULE, null, Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " +Sqlite.COL_IS_SCHEDULED + " != 0 AND " + Sqlite.COL_SENT + " = 1", null, null, null, Sqlite.COL_DATE_CREATION + " DESC", null); + Cursor c = db.query(Sqlite.TABLE_BOOST_SCHEDULE, null, Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " +Sqlite.COL_IS_SCHEDULED + " != 0 AND " + Sqlite.COL_SENT + " = 1", null, null, null, Sqlite.COL_DATE_SCHEDULED + " DESC", null); return cursorToListStatuses(c); } catch (Exception e) { return null; @@ -237,7 +238,6 @@ public class BoostScheduleDAO { storedStatus.setStatusReply(null); storedStatus.setSent(c.getInt(c.getColumnIndex(Sqlite.COL_SENT)) == 1); storedStatus.setJobId(c.getInt(c.getColumnIndex(Sqlite.COL_IS_SCHEDULED))); - storedStatus.setCreation_date(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_DATE_CREATION)))); storedStatus.setScheduled_date(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_DATE_SCHEDULED)))); storedStatus.setSent_date(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_DATE_SENT)))); storedStatus.setUserId(c.getString(c.getColumnIndex(Sqlite.COL_USER_ID))); @@ -268,11 +268,9 @@ public class BoostScheduleDAO { continue; } storedStatus.setStatus(status); - Status statusReply = Helper.restoreStatusFromString(c.getString(c.getColumnIndex(Sqlite.COL_STATUS_REPLY_SERIALIZED))); - storedStatus.setStatusReply(statusReply); + storedStatus.setStatusReply(null); storedStatus.setSent(c.getInt(c.getColumnIndex(Sqlite.COL_SENT)) == 1); storedStatus.setJobId(c.getInt(c.getColumnIndex(Sqlite.COL_IS_SCHEDULED)) ); - storedStatus.setCreation_date(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_DATE_CREATION)))); storedStatus.setScheduled_date(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_DATE_SCHEDULED)))); storedStatus.setSent_date(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_DATE_SENT)))); storedStatus.setUserId(c.getString(c.getColumnIndex(Sqlite.COL_USER_ID))); diff --git a/app/src/main/res/layout/drawer_scheduled_toot.xml b/app/src/main/res/layout/drawer_scheduled_toot.xml index 8bf1a1a63..3023356be 100644 --- a/app/src/main/res/layout/drawer_scheduled_toot.xml +++ b/app/src/main/res/layout/drawer_scheduled_toot.xml @@ -22,6 +22,14 @@ android:orientation="horizontal" android:id="@+id/scheduled_toot_container" > + + + - - No scheduled toot to display! + No scheduled toots to display! Write a toot and then choose Schedule from the top menu. Delete scheduled toot? Media: %d @@ -686,6 +686,10 @@ The tag has been changed! The tag has been deleted! Display Art timeline + Schedule boost + The boost is scheduled! + No scheduled boost to display! + Schedule boost.]]> Never