Merged in develop (pull request #27)
|
@ -7,8 +7,8 @@ android {
|
|||
applicationId "fr.gouv.etalab.mastodon"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 25
|
||||
versionCode 29
|
||||
versionName "1.3.2"
|
||||
versionCode 30
|
||||
versionName "1.3.3"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
|
|
@ -96,6 +96,14 @@ public class AboutActivity extends AppCompatActivity implements OnRetrieveSearcA
|
|||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
Button about_translation = (Button) findViewById(R.id.about_translation);
|
||||
about_translation.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://translate.yandex.com/"));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
|||
import fr.gouv.etalab.mastodon.fragments.DisplayAccountsFragment;
|
||||
import fr.gouv.etalab.mastodon.fragments.DisplayFollowRequestSentFragment;
|
||||
import fr.gouv.etalab.mastodon.fragments.DisplayNotificationsFragment;
|
||||
import fr.gouv.etalab.mastodon.fragments.DisplayScheduledTootsFragment;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnUpdateAccountInfoInterface;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
@ -202,6 +203,11 @@ public class MainActivity extends AppCompatActivity
|
|||
if( navigationView.getMenu().findItem(tagItem.get(fragmentTag)) != null)
|
||||
navigationView.getMenu().findItem(tagItem.get(fragmentTag)).setChecked(true);
|
||||
}
|
||||
if( fragmentTag.equals("HOME_TIMELINE") || fragmentTag.equals("LOCAL_TIMELINE") || fragmentTag.equals("PUBLIC_TIMELINE") || fragmentTag.equals("SCHEDULED")){
|
||||
toot.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
toot.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -563,7 +569,13 @@ public class MainActivity extends AppCompatActivity
|
|||
fragmentTag = "MUTED";
|
||||
fragmentManager.beginTransaction()
|
||||
.replace(R.id.main_app_container, accountsFragment, fragmentTag).addToBackStack(fragmentTag).commit();
|
||||
}else if( id == R.id.nav_notification){
|
||||
}else if (id == R.id.nav_scheduled) {
|
||||
toot.setVisibility(View.VISIBLE);
|
||||
DisplayScheduledTootsFragment displayScheduledTootsFragment = new DisplayScheduledTootsFragment();
|
||||
fragmentTag = "SCHEDULED";
|
||||
fragmentManager.beginTransaction()
|
||||
.replace(R.id.main_app_container, displayScheduledTootsFragment, fragmentTag).addToBackStack(fragmentTag).commit();
|
||||
} else if( id == R.id.nav_notification){
|
||||
toot.setVisibility(View.GONE);
|
||||
DisplayNotificationsFragment notificationsFragment = new DisplayNotificationsFragment();
|
||||
fragmentTag = "NOTIFICATIONS";
|
||||
|
|
|
@ -35,6 +35,7 @@ import android.text.Editable;
|
|||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
@ -44,6 +45,7 @@ import android.widget.ArrayAdapter;
|
|||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.DatePicker;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
|
@ -51,6 +53,7 @@ import android.widget.LinearLayout;
|
|||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TimePicker;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
|
@ -61,6 +64,9 @@ import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
|
|||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -83,6 +89,7 @@ import fr.gouv.etalab.mastodon.helper.Helper;
|
|||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface;
|
||||
import fr.gouv.etalab.mastodon.jobs.ScheduledTootsSyncJob;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
|
@ -122,6 +129,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
private String sharedContent, sharedSubject;
|
||||
private CheckBox toot_sensitive;
|
||||
public long currentToId;
|
||||
private long restored;
|
||||
|
||||
private String pattern = "^.*(@([a-zA-Z0-9_]{2,}))$";
|
||||
@Override
|
||||
|
@ -180,23 +188,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
|
||||
final LinearLayout drawer_layout = (LinearLayout) findViewById(R.id.drawer_layout);
|
||||
|
||||
/*drawer_layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
int heightDiff = drawer_layout.getRootView().getHeight() - drawer_layout.getHeight();
|
||||
if (heightDiff > 100) {
|
||||
ViewGroup.LayoutParams params = toot_picture_container.getLayoutParams();
|
||||
params.height = (int) Helper.convertDpToPixel(20, getApplicationContext());
|
||||
params.width = (int) Helper.convertDpToPixel(20, getApplicationContext());
|
||||
toot_picture_container.setLayoutParams(params);
|
||||
} else {
|
||||
ViewGroup.LayoutParams params = toot_picture_container.getLayoutParams();
|
||||
params.height = (int) Helper.convertDpToPixel(100, getApplicationContext());
|
||||
params.width = (int) Helper.convertDpToPixel(100, getApplicationContext());
|
||||
toot_picture_container.setLayoutParams(params);
|
||||
}
|
||||
}
|
||||
});*/
|
||||
|
||||
drawer_layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
|
@ -217,10 +208,16 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
});
|
||||
|
||||
Bundle b = getIntent().getExtras();
|
||||
restored = -1;
|
||||
if(b != null) {
|
||||
tootReply = b.getParcelable("tootReply");
|
||||
sharedContent = b.getString("sharedContent", null);
|
||||
sharedSubject = b.getString("sharedSubject", null);
|
||||
restored = b.getLong("restored", -1);
|
||||
}
|
||||
if( restored != -1 ){
|
||||
toot_it.setVisibility(View.GONE);
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
if( tootReply != null) {
|
||||
setTitle(R.string.toot_title_reply);
|
||||
|
@ -463,7 +460,9 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
toot_space_left.setText(String.valueOf((maxChar - totalChar)));
|
||||
}
|
||||
});
|
||||
|
||||
if( restored != -1 ){
|
||||
restoreToot(restored);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -521,7 +520,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
}
|
||||
return true;
|
||||
case R.id.action_store:
|
||||
storeToot();
|
||||
storeToot(true);
|
||||
return true;
|
||||
case R.id.action_restore:
|
||||
try{
|
||||
|
@ -573,74 +572,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
int id = ids[which];
|
||||
StoredStatus draft = new StatusStoredDAO(TootActivity.this, db).getStatus(id);
|
||||
Status status = draft.getStatus();
|
||||
//Retrieves attachments
|
||||
attachments = status.getMedia_attachments();
|
||||
toot_picture_container.removeAllViews();
|
||||
loading_picture.setVisibility(View.GONE);
|
||||
if( attachments != null && attachments.size() > 0){
|
||||
toot_picture_container.setVisibility(View.VISIBLE);
|
||||
int i = 0 ;
|
||||
for(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()));
|
||||
imageLoader.displayImage(url, imageView, options);
|
||||
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);
|
||||
imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showRemove(imageView.getId());
|
||||
}
|
||||
});
|
||||
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);
|
||||
}
|
||||
String content = status.getContent();
|
||||
toot_content.setText(content);
|
||||
toot_content.setSelection(toot_content.getText().length());
|
||||
switch (status.getVisibility()){
|
||||
case "public":
|
||||
visibility = "public";
|
||||
toot_visibility.setImageResource(R.drawable.ic_action_globe);
|
||||
break;
|
||||
case "unlisted":
|
||||
visibility = "unlisted";
|
||||
toot_visibility.setImageResource(R.drawable.ic_action_lock_open);
|
||||
break;
|
||||
case "private":
|
||||
visibility = "private";
|
||||
toot_visibility.setImageResource(R.drawable.ic_action_lock_closed);
|
||||
break;
|
||||
case "direct":
|
||||
visibility = "direct";
|
||||
toot_visibility.setImageResource(R.drawable.ic_local_post_office);
|
||||
break;
|
||||
}
|
||||
//The current id is set to the draft
|
||||
currentToId = draft.getId();
|
||||
restoreToot(id);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
@ -650,13 +582,113 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
}
|
||||
return true;
|
||||
|
||||
/*case R.id.action_schedule:
|
||||
case R.id.action_schedule:
|
||||
if(toot_content.getText().toString().trim().length() == 0 ){
|
||||
Toast.makeText(getApplicationContext(),R.string.toot_error_no_content, Toast.LENGTH_LONG).show();
|
||||
return true;
|
||||
}
|
||||
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(TootActivity.this);
|
||||
LayoutInflater inflater = this.getLayoutInflater();
|
||||
View dialogView = inflater.inflate(R.layout.datetime_picker, null);
|
||||
SharedPreferences sharedpreferences = 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(TootActivity.this, R.drawable.ic_skip_previous,R.color.dark_text);
|
||||
changeDrawableColor(TootActivity.this, R.drawable.ic_skip_next,R.color.dark_text);
|
||||
changeDrawableColor(TootActivity.this, R.drawable.ic_check,R.color.dark_text);
|
||||
}else {
|
||||
changeDrawableColor(TootActivity.this, R.drawable.ic_skip_previous,R.color.black);
|
||||
changeDrawableColor(TootActivity.this, R.drawable.ic_skip_next,R.color.black);
|
||||
changeDrawableColor(TootActivity.this, R.drawable.ic_check,R.color.black);
|
||||
}
|
||||
dialogBuilder.setView(dialogView);
|
||||
final AlertDialog alertDialog = dialogBuilder.create();
|
||||
|
||||
return true;*/
|
||||
final DatePicker datePicker = (DatePicker) dialogView.findViewById(R.id.date_picker);
|
||||
final TimePicker timePicker = (TimePicker) dialogView.findViewById(R.id.time_picker);
|
||||
Button date_time_cancel = (Button) dialogView.findViewById(R.id.date_time_cancel);
|
||||
final ImageButton date_time_previous = (ImageButton) dialogView.findViewById(R.id.date_time_previous);
|
||||
final ImageButton date_time_next = (ImageButton) dialogView.findViewById(R.id.date_time_next);
|
||||
final ImageButton date_time_set = (ImageButton) dialogView.findViewById(R.id.date_time_set);
|
||||
|
||||
//Buttons management
|
||||
date_time_cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
alertDialog.dismiss();
|
||||
}
|
||||
});
|
||||
date_time_next.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
datePicker.setVisibility(View.GONE);
|
||||
timePicker.setVisibility(View.VISIBLE);
|
||||
date_time_previous.setVisibility(View.VISIBLE);
|
||||
date_time_next.setVisibility(View.GONE);
|
||||
date_time_set.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
date_time_previous.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
datePicker.setVisibility(View.VISIBLE);
|
||||
timePicker.setVisibility(View.GONE);
|
||||
date_time_previous.setVisibility(View.GONE);
|
||||
date_time_next.setVisibility(View.VISIBLE);
|
||||
date_time_set.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
date_time_set.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int hour, minute;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
hour = timePicker.getHour();
|
||||
minute = timePicker.getMinute();
|
||||
}else {
|
||||
//noinspection deprecation
|
||||
hour = timePicker.getCurrentHour();
|
||||
//noinspection deprecation
|
||||
minute = timePicker.getCurrentMinute();
|
||||
}
|
||||
Calendar calendar = new GregorianCalendar(datePicker.getYear(),
|
||||
datePicker.getMonth(),
|
||||
datePicker.getDayOfMonth(),
|
||||
hour,
|
||||
minute);
|
||||
long time = calendar.getTimeInMillis();
|
||||
if( (time - new Date().getTime()) < 60000 ){
|
||||
Toast.makeText(getApplicationContext(), R.string.toot_scheduled_date, Toast.LENGTH_LONG).show();
|
||||
}else {
|
||||
//Store the toot as draft first
|
||||
storeToot(false);
|
||||
//Schedules the toot
|
||||
ScheduledTootsSyncJob.schedule(getApplicationContext(), currentToId, time);
|
||||
//Clear content
|
||||
toot_content.setText("");
|
||||
toot_cw_content.setText("");
|
||||
if( attachments != null) {
|
||||
for (Attachment attachment : attachments) {
|
||||
View namebar = findViewById(Integer.parseInt(attachment.getId()));
|
||||
if (namebar != null && namebar.getParent() != null)
|
||||
((ViewGroup) namebar.getParent()).removeView(namebar);
|
||||
}
|
||||
List<Attachment> tmp_attachment = new ArrayList<>();
|
||||
tmp_attachment.addAll(attachments);
|
||||
attachments.removeAll(tmp_attachment);
|
||||
tmp_attachment.clear();
|
||||
}
|
||||
isSensitive = false;
|
||||
toot_sensitive.setVisibility(View.GONE);
|
||||
currentToId = -1;
|
||||
Toast.makeText(TootActivity.this,R.string.toot_scheduled, Toast.LENGTH_LONG).show();
|
||||
alertDialog.dismiss();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
alertDialog.show();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
@ -665,6 +697,14 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.main_toot, menu);
|
||||
if( restored != -1 ){
|
||||
MenuItem itemRestore = menu.findItem(R.id.action_restore);
|
||||
if( itemRestore != null)
|
||||
itemRestore.setVisible(false);
|
||||
MenuItem itemSchedule = menu.findItem(R.id.action_schedule);
|
||||
if( itemSchedule != null)
|
||||
itemSchedule.setVisible(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -798,7 +838,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean storeToot = sharedpreferences.getBoolean(Helper.SET_AUTO_STORE, true);
|
||||
if( storeToot)
|
||||
storeToot();
|
||||
storeToot(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -827,6 +867,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
}
|
||||
isSensitive = false;
|
||||
toot_sensitive.setVisibility(View.GONE);
|
||||
currentToId = -1;
|
||||
Toast.makeText(TootActivity.this,R.string.toot_sent, Toast.LENGTH_LONG).show();
|
||||
}else {
|
||||
Toast.makeText(TootActivity.this,R.string.toast_error, Toast.LENGTH_LONG).show();
|
||||
|
@ -853,7 +894,80 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
}
|
||||
}
|
||||
|
||||
private void storeToot(){
|
||||
private void restoreToot(long id){
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
StoredStatus draft = new StatusStoredDAO(TootActivity.this, db).getStatus(id);
|
||||
Status status = draft.getStatus();
|
||||
//Retrieves attachments
|
||||
attachments = status.getMedia_attachments();
|
||||
toot_picture_container.removeAllViews();
|
||||
loading_picture.setVisibility(View.GONE);
|
||||
if( attachments != null && attachments.size() > 0){
|
||||
toot_picture_container.setVisibility(View.VISIBLE);
|
||||
int i = 0 ;
|
||||
for(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()));
|
||||
imageLoader.displayImage(url, imageView, options);
|
||||
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);
|
||||
imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showRemove(imageView.getId());
|
||||
}
|
||||
});
|
||||
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);
|
||||
}
|
||||
String content = status.getContent();
|
||||
toot_content.setText(content);
|
||||
toot_content.setSelection(toot_content.getText().length());
|
||||
switch (status.getVisibility()){
|
||||
case "public":
|
||||
visibility = "public";
|
||||
toot_visibility.setImageResource(R.drawable.ic_action_globe);
|
||||
break;
|
||||
case "unlisted":
|
||||
visibility = "unlisted";
|
||||
toot_visibility.setImageResource(R.drawable.ic_action_lock_open);
|
||||
break;
|
||||
case "private":
|
||||
visibility = "private";
|
||||
toot_visibility.setImageResource(R.drawable.ic_action_lock_closed);
|
||||
break;
|
||||
case "direct":
|
||||
visibility = "direct";
|
||||
toot_visibility.setImageResource(R.drawable.ic_local_post_office);
|
||||
break;
|
||||
}
|
||||
//The current id is set to the draft
|
||||
currentToId = draft.getId();
|
||||
}
|
||||
|
||||
|
||||
private void storeToot(boolean message){
|
||||
//Nothing to store here....
|
||||
if(toot_content.getText().toString().trim().length() == 0 && (attachments == null || attachments.size() <1) && toot_cw_content.getText().toString().trim().length() == 0)
|
||||
return;
|
||||
|
@ -870,20 +984,21 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
try{
|
||||
if( currentToId == -1 ) {
|
||||
currentToId = new StatusStoredDAO(TootActivity.this, db).insertStatus(toot, false, null);
|
||||
currentToId = new StatusStoredDAO(TootActivity.this, db).insertStatus(toot);
|
||||
|
||||
}else{
|
||||
StoredStatus storedStatus = new StatusStoredDAO(TootActivity.this, db).getStatus(currentToId);
|
||||
if( storedStatus != null ){
|
||||
new StatusStoredDAO(TootActivity.this, db).updateStatus(currentToId, toot);
|
||||
}else { //Might have been deleted, so it needs insertion
|
||||
new StatusStoredDAO(TootActivity.this, db).insertStatus(toot, false, null);
|
||||
new StatusStoredDAO(TootActivity.this, db).insertStatus(toot);
|
||||
}
|
||||
}
|
||||
|
||||
Toast.makeText(getApplicationContext(), R.string.toast_toot_saved, Toast.LENGTH_LONG).show();
|
||||
if( message )
|
||||
Toast.makeText(getApplicationContext(), R.string.toast_toot_saved, Toast.LENGTH_LONG).show();
|
||||
}catch (Exception e){
|
||||
Toast.makeText(getApplicationContext(), R.string.toast_error, Toast.LENGTH_LONG).show();
|
||||
if( message)
|
||||
Toast.makeText(getApplicationContext(), R.string.toast_error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/* Copyright 2017 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.asynctasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveScheduledTootsInterface;
|
||||
import fr.gouv.etalab.mastodon.jobs.ScheduledTootsSyncJob;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 16/07/2017.
|
||||
* Retrieves scheduled toots for an account
|
||||
*/
|
||||
|
||||
public class RetrieveScheduledTootsAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private Context context;
|
||||
private OnRetrieveScheduledTootsInterface listener;
|
||||
private List<StoredStatus> storedStatuses;
|
||||
|
||||
public RetrieveScheduledTootsAsyncTask(Context context, OnRetrieveScheduledTootsInterface onRetrieveScheduledTootsInterface){
|
||||
this.context = context;
|
||||
this.listener = onRetrieveScheduledTootsInterface;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
//Retrieves job asked by the user
|
||||
storedStatuses = new StatusStoredDAO(context, db).getAllScheduled();
|
||||
//Retrieves real jobs still waiting
|
||||
Set<JobRequest> jobRequests = JobManager.instance().getAllJobRequestsForTag(ScheduledTootsSyncJob.SCHEDULED_TOOT);
|
||||
int[] jobIds;
|
||||
if( jobRequests != null && jobRequests.size() > 0 ){
|
||||
int i = 0;
|
||||
jobIds = new int[jobRequests.size()];
|
||||
for(JobRequest jobRequest : jobRequests){
|
||||
jobIds[i] = jobRequest.getJobId();
|
||||
i++;
|
||||
}
|
||||
}else{
|
||||
jobIds = new int[]{};
|
||||
}
|
||||
if( storedStatuses != null && storedStatuses.size() > 0 ){
|
||||
for(StoredStatus ss: storedStatuses){
|
||||
if (!Helper.isJobPresent(jobIds, ss.getJobId())){
|
||||
//JobId is fixed to -1 which means an error occured (it was never sent)
|
||||
new StatusStoredDAO(context, db).updateJobId(ss.getId(),-1);
|
||||
}
|
||||
}
|
||||
//Lets time to update db before dispaying
|
||||
SystemClock.sleep(1000);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
listener.onRetrieveScheduledToots(storedStatuses);
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@ package fr.gouv.etalab.mastodon.client;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.loopj.android.http.AsyncHttpResponseHandler;
|
||||
|
@ -869,6 +870,7 @@ public class API {
|
|||
public void onFailure(int statusCode, Header[] headers, Throwable error, JSONObject response) {
|
||||
actionCode = statusCode;
|
||||
setError(statusCode, error);
|
||||
error.printStackTrace();
|
||||
}
|
||||
});
|
||||
}else{
|
||||
|
@ -1461,7 +1463,6 @@ public class API {
|
|||
}
|
||||
|
||||
private void post(String action, int timeout, RequestParams params, AsyncHttpResponseHandler responseHandler) {
|
||||
|
||||
try {
|
||||
client.setConnectTimeout(timeout); //10s timeout
|
||||
client.setUserAgent(USER_AGENT);
|
||||
|
|
|
@ -14,11 +14,11 @@ public class StoredStatus {
|
|||
private Date creation_date;
|
||||
private Date scheduled_date;
|
||||
private Date sent_date;
|
||||
private boolean isScheduled;
|
||||
private int jobId;
|
||||
private boolean isSent;
|
||||
private Status status;
|
||||
private String instance;
|
||||
private String acct;
|
||||
private String userId;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
|
@ -52,13 +52,6 @@ public class StoredStatus {
|
|||
this.sent_date = sent_date;
|
||||
}
|
||||
|
||||
public boolean isScheduled() {
|
||||
return isScheduled;
|
||||
}
|
||||
|
||||
public void setScheduled(boolean scheduled) {
|
||||
isScheduled = scheduled;
|
||||
}
|
||||
|
||||
public boolean isSent() {
|
||||
return isSent;
|
||||
|
@ -84,11 +77,19 @@ public class StoredStatus {
|
|||
this.instance = instance;
|
||||
}
|
||||
|
||||
public String getAcct() {
|
||||
return acct;
|
||||
public int getJobId() {
|
||||
return jobId;
|
||||
}
|
||||
|
||||
public void setAcct(String acct) {
|
||||
this.acct = acct;
|
||||
public void setJobId(int jobId) {
|
||||
this.jobId = jobId;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ public class DraftsListAdapter extends BaseAdapter {
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setMessage(draft.getStatus().getContent() + '\n' + draft.getCreation_date());
|
||||
builder.setMessage(draft.getStatus().getContent() + '\n' + Helper.dateToString(context, draft.getCreation_date()));
|
||||
builder.setIcon(android.R.drawable.ic_dialog_alert)
|
||||
.setTitle(R.string.remove_draft)
|
||||
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
|
|
|
@ -0,0 +1,321 @@
|
|||
package fr.gouv.etalab.mastodon.drawers;
|
||||
/* Copyright 2017 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.DatePicker;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TimePicker;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
|
||||
import fr.gouv.etalab.mastodon.activities.MainActivity;
|
||||
import fr.gouv.etalab.mastodon.activities.TootActivity;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Application;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.jobs.ApplicationJob;
|
||||
import fr.gouv.etalab.mastodon.jobs.ScheduledTootsSyncJob;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
|
||||
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 {
|
||||
|
||||
private Context context;
|
||||
private List<StoredStatus> storedStatuses;
|
||||
private LayoutInflater layoutInflater;
|
||||
private ScheduledTootsListAdapter scheduledTootsListAdapter;
|
||||
private RelativeLayout textviewNoAction;
|
||||
|
||||
public ScheduledTootsListAdapter(Context context, List<StoredStatus> storedStatuses, RelativeLayout textviewNoAction){
|
||||
this.context = context;
|
||||
this.storedStatuses = storedStatuses;
|
||||
layoutInflater = LayoutInflater.from(this.context);
|
||||
scheduledTootsListAdapter = this;
|
||||
this.textviewNoAction = textviewNoAction;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return storedStatuses.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return storedStatuses.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
|
||||
final StoredStatus storedStatus = storedStatuses.get(position);
|
||||
final ViewHolder holder;
|
||||
if (convertView == null) {
|
||||
convertView = layoutInflater.inflate(R.layout.drawer_scheduled_toot, parent, false);
|
||||
holder = new ViewHolder();
|
||||
holder.scheduled_toot_container = (CardView) convertView.findViewById(R.id.scheduled_toot_container);
|
||||
holder.scheduled_toot_title = (TextView) convertView.findViewById(R.id.scheduled_toot_title);
|
||||
holder.scheduled_toot_date_creation = (TextView) convertView.findViewById(R.id.scheduled_toot_date_creation);
|
||||
holder.scheduled_toot_media_count = (TextView) convertView.findViewById(R.id.scheduled_toot_media_count);
|
||||
holder.scheduled_toot_failed = (TextView) convertView.findViewById(R.id.scheduled_toot_failed);
|
||||
holder.scheduled_toot_delete = (ImageView) convertView.findViewById(R.id.scheduled_toot_delete);
|
||||
holder.scheduled_toot_privacy = (ImageView) convertView.findViewById(R.id.scheduled_toot_privacy);
|
||||
holder.scheduled_toot_date = (Button) convertView.findViewById(R.id.scheduled_toot_date);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
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_action_globe,R.color.dark_text);
|
||||
changeDrawableColor(context, R.drawable.ic_action_lock_open,R.color.dark_text);
|
||||
changeDrawableColor(context, R.drawable.ic_action_lock_closed,R.color.dark_text);
|
||||
changeDrawableColor(context, R.drawable.ic_local_post_office,R.color.dark_text);
|
||||
}else {
|
||||
changeDrawableColor(context, R.drawable.ic_cancel,R.color.black);
|
||||
changeDrawableColor(context, R.drawable.ic_action_globe,R.color.black);
|
||||
changeDrawableColor(context, R.drawable.ic_action_lock_open,R.color.black);
|
||||
changeDrawableColor(context, R.drawable.ic_action_lock_closed,R.color.black);
|
||||
changeDrawableColor(context, R.drawable.ic_local_post_office,R.color.black);
|
||||
}
|
||||
|
||||
final Status status = storedStatus.getStatus();
|
||||
|
||||
switch (status.getVisibility()) {
|
||||
case "public":
|
||||
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_action_globe);
|
||||
break;
|
||||
case "unlisted":
|
||||
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_action_lock_open);
|
||||
break;
|
||||
case "private":
|
||||
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_action_lock_closed);
|
||||
break;
|
||||
case "direct":
|
||||
holder.scheduled_toot_privacy.setImageResource(R.drawable.ic_local_post_office);
|
||||
break;
|
||||
}
|
||||
final SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
|
||||
//Delete scheduled toot
|
||||
holder.scheduled_toot_delete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setMessage(status.getContent() + '\n' + Helper.dateToString(context, storedStatus.getCreation_date()));
|
||||
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());
|
||||
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){}
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
||||
})
|
||||
.show();
|
||||
}
|
||||
});
|
||||
|
||||
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(context, storedStatus.getCreation_date()));
|
||||
holder.scheduled_toot_date.setText(Helper.dateToString(context, storedStatus.getScheduled_date()));
|
||||
holder.scheduled_toot_date.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
|
||||
LayoutInflater inflater = ((MainActivity)context).getLayoutInflater();
|
||||
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);
|
||||
}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);
|
||||
}
|
||||
dialogBuilder.setView(dialogView);
|
||||
final AlertDialog alertDialog = dialogBuilder.create();
|
||||
|
||||
final DatePicker datePicker = (DatePicker) dialogView.findViewById(R.id.date_picker);
|
||||
final TimePicker timePicker = (TimePicker) dialogView.findViewById(R.id.time_picker);
|
||||
Button date_time_cancel = (Button) dialogView.findViewById(R.id.date_time_cancel);
|
||||
final ImageButton date_time_previous = (ImageButton) dialogView.findViewById(R.id.date_time_previous);
|
||||
final ImageButton date_time_next = (ImageButton) dialogView.findViewById(R.id.date_time_next);
|
||||
final ImageButton date_time_set = (ImageButton) dialogView.findViewById(R.id.date_time_set);
|
||||
|
||||
//Buttons management
|
||||
date_time_cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
alertDialog.dismiss();
|
||||
}
|
||||
});
|
||||
date_time_next.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
datePicker.setVisibility(View.GONE);
|
||||
timePicker.setVisibility(View.VISIBLE);
|
||||
date_time_previous.setVisibility(View.VISIBLE);
|
||||
date_time_next.setVisibility(View.GONE);
|
||||
date_time_set.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
date_time_previous.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
datePicker.setVisibility(View.VISIBLE);
|
||||
timePicker.setVisibility(View.GONE);
|
||||
date_time_previous.setVisibility(View.GONE);
|
||||
date_time_next.setVisibility(View.VISIBLE);
|
||||
date_time_set.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
date_time_set.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int hour, minute;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
hour = timePicker.getHour();
|
||||
minute = timePicker.getMinute();
|
||||
}else {
|
||||
//noinspection deprecation
|
||||
hour = timePicker.getCurrentHour();
|
||||
//noinspection deprecation
|
||||
minute = timePicker.getCurrentMinute();
|
||||
}
|
||||
Calendar calendar = new GregorianCalendar(datePicker.getYear(),
|
||||
datePicker.getMonth(),
|
||||
datePicker.getDayOfMonth(),
|
||||
hour,
|
||||
minute);
|
||||
long time = calendar.getTimeInMillis();
|
||||
if( (time - new Date().getTime()) < 60000 ){
|
||||
Toast.makeText(context, 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
|
||||
ScheduledTootsSyncJob.schedule(context, storedStatus.getId(), time);
|
||||
StoredStatus storedStatusnew = new StatusStoredDAO(context, db).getStatus(storedStatus.getId());
|
||||
//Date displayed is changed
|
||||
storedStatus.setScheduled_date(storedStatusnew.getScheduled_date());
|
||||
scheduledTootsListAdapter.notifyDataSetChanged();
|
||||
//Notifiy all is ok
|
||||
Toast.makeText(context,R.string.toot_scheduled, Toast.LENGTH_LONG).show();
|
||||
}catch (Exception ignored){}
|
||||
alertDialog.dismiss();
|
||||
}
|
||||
}
|
||||
});
|
||||
alertDialog.show();
|
||||
}
|
||||
});
|
||||
holder.scheduled_toot_title.setText(status.getContent());
|
||||
|
||||
|
||||
|
||||
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());
|
||||
intentToot.putExtras(b);
|
||||
context.startActivity(intentToot);
|
||||
}
|
||||
});
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private class ViewHolder {
|
||||
CardView scheduled_toot_container;
|
||||
TextView scheduled_toot_title;
|
||||
TextView scheduled_toot_date_creation;
|
||||
TextView scheduled_toot_media_count;
|
||||
TextView scheduled_toot_failed;
|
||||
ImageView scheduled_toot_delete;
|
||||
ImageView scheduled_toot_privacy;
|
||||
Button scheduled_toot_date;
|
||||
}
|
||||
|
||||
}
|
|
@ -197,7 +197,7 @@ public class StatusListAdapter extends BaseAdapter implements OnPostActionInterf
|
|||
statusListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
if( currentLocale != null && !status.getLanguage().trim().equals(currentLocale) && !status.getLanguage().trim().equals("null")){
|
||||
if( currentLocale != null && status.getLanguage() != null && !status.getLanguage().trim().equals(currentLocale) && !status.getLanguage().trim().equals("null")){
|
||||
holder.status_translate.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
holder.status_translate.setVisibility(View.GONE);
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
package fr.gouv.etalab.mastodon.fragments;
|
||||
/* Copyright 2017 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import fr.gouv.etalab.mastodon.asynctasks.RetrieveScheduledTootsAsyncTask;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
import fr.gouv.etalab.mastodon.drawers.ScheduledTootsListAdapter;
|
||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveScheduledTootsInterface;
|
||||
import fr.gouv.etalab.mastodon.jobs.ScheduledTootsSyncJob;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 16/07/2017.
|
||||
* Fragment to display scheduled toots
|
||||
*/
|
||||
public class DisplayScheduledTootsFragment extends Fragment implements OnRetrieveScheduledTootsInterface {
|
||||
|
||||
|
||||
private Context context;
|
||||
private AsyncTask<Void, Void, Void> asyncTask;
|
||||
private RelativeLayout mainLoader, textviewNoAction;
|
||||
private ListView lv_scheduled_toots;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
View rootView = inflater.inflate(R.layout.fragment_scheduled_toots, container, false);
|
||||
context = getContext();
|
||||
|
||||
lv_scheduled_toots = (ListView) rootView.findViewById(R.id.lv_scheduled_toots);
|
||||
|
||||
mainLoader = (RelativeLayout) rootView.findViewById(R.id.loader);
|
||||
textviewNoAction = (RelativeLayout) rootView.findViewById(R.id.no_action);
|
||||
mainLoader.setVisibility(View.VISIBLE);
|
||||
|
||||
//Removes all scheduled toots that have sent
|
||||
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
new StatusStoredDAO(context, db).removeAllSent();
|
||||
return rootView;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
//Retrieves scheduled toots
|
||||
asyncTask = new RetrieveScheduledTootsAsyncTask(context, DisplayScheduledTootsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle saveInstance)
|
||||
{
|
||||
super.onCreate(saveInstance);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if(asyncTask != null && asyncTask.getStatus() == AsyncTask.Status.RUNNING)
|
||||
asyncTask.cancel(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onRetrieveScheduledToots(List<StoredStatus> storedStatuses) {
|
||||
|
||||
mainLoader.setVisibility(View.GONE);
|
||||
if( storedStatuses != null && storedStatuses.size() > 0 ){
|
||||
ScheduledTootsListAdapter scheduledTootsListAdapter = new ScheduledTootsListAdapter(context, storedStatuses, textviewNoAction);
|
||||
lv_scheduled_toots.setAdapter(scheduledTootsListAdapter);
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
}else {
|
||||
textviewNoAction.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -168,7 +168,7 @@ public class SettingsFragment extends Fragment {
|
|||
}else {
|
||||
set_cookies_container.setVisibility(View.GONE);
|
||||
}
|
||||
final String targeted_folder = sharedpreferences.getString(Helper.SET_FOLDER_RECORD, Environment.DIRECTORY_DOWNLOADS);
|
||||
final String targeted_folder = sharedpreferences.getString(Helper.SET_FOLDER_RECORD, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath());
|
||||
|
||||
set_folder = (TextView) rootView.findViewById(R.id.set_folder);
|
||||
set_folder.setText(targeted_folder);
|
||||
|
@ -217,7 +217,7 @@ public class SettingsFragment extends Fragment {
|
|||
DocumentsContract.getTreeDocumentId(treeUri));
|
||||
String path = getPath(context, docUri);
|
||||
if( path == null )
|
||||
path = Environment.DIRECTORY_DOWNLOADS;
|
||||
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.SET_FOLDER_RECORD, path);
|
||||
|
|
|
@ -79,6 +79,7 @@ import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
|||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
@ -573,18 +574,22 @@ public class Helper {
|
|||
public static void manageMoveFileDownload(final Context context, final String preview_url, final String url, Bitmap bitmap, File fileVideo){
|
||||
|
||||
final String fileName = URLUtil.guessFileName(url, null, null);final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
String myDir = sharedpreferences.getString(Helper.SET_FOLDER_RECORD, Environment.DIRECTORY_DOWNLOADS);
|
||||
String myDir = sharedpreferences.getString(Helper.SET_FOLDER_RECORD, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath());
|
||||
|
||||
try {
|
||||
File file;
|
||||
if( bitmap != null) {
|
||||
File filebmp = new File (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
|
||||
FileOutputStream out = new FileOutputStream(filebmp);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
|
||||
out.flush();
|
||||
out.close();
|
||||
file = new File(myDir, fileName);
|
||||
copy(filebmp, file);
|
||||
file.createNewFile();
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
|
||||
byte[] bitmapdata = bos.toByteArray();
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
fos.write(bitmapdata);
|
||||
fos.flush();
|
||||
fos.close();
|
||||
}else{
|
||||
File fileVideoTargeded = new File(myDir, fileName);
|
||||
copy(fileVideo, fileVideoTargeded);
|
||||
|
@ -594,7 +599,6 @@ public class Helper {
|
|||
final int notificationIdTmp = r.nextInt(10000);
|
||||
// prepare intent which is triggered if the
|
||||
// notification is selected
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
final Intent intent = new Intent();
|
||||
intent.setAction(android.content.Intent.ACTION_VIEW);
|
||||
Uri uri = Uri.parse("file://" + file.getAbsolutePath());
|
||||
|
@ -841,6 +845,9 @@ public class Helper {
|
|||
navigationView.getMenu().performIdentifierAction(R.id.nav_home, 0);
|
||||
SQLiteDatabase db = Sqlite.getInstance(activity, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
Account account = new AccountDAO(activity,db).getAccountByID(userID);
|
||||
//Can happen when an account has been deleted and there is a click on an old notification
|
||||
if( account == null)
|
||||
return;
|
||||
//Locked account can see follow request
|
||||
if (account.isLocked()) {
|
||||
navigationView.getMenu().findItem(R.id.nav_follow_request).setVisible(true);
|
||||
|
@ -1222,13 +1229,36 @@ public class Helper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialized a Status class
|
||||
* @param status Status to serialize
|
||||
* @return String serialized Status
|
||||
*/
|
||||
public static String statusToStringStorage(Status status){
|
||||
Gson gson = new Gson();
|
||||
return gson.toJson(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserialized a Status
|
||||
* @param serializedStatus String serialized status
|
||||
* @return Status
|
||||
*/
|
||||
public static Status restoreStatusFromString(String serializedStatus){
|
||||
Gson gson = new Gson();
|
||||
return gson.fromJson(serializedStatus, Status.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a job id is in array of ids
|
||||
* @param jobIds int[]
|
||||
* @param id int id to check
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isJobPresent(int[] jobIds, int id){
|
||||
for(int x:jobIds) {
|
||||
if (x == id) {return true;}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/* Copyright 2017 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package fr.gouv.etalab.mastodon.interfaces;
|
||||
|
||||
import java.util.List;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
|
||||
/**
|
||||
* Created by Thomas on 16/07/2017.
|
||||
* Interface when scheduled toots have been retrieved
|
||||
*/
|
||||
public interface OnRetrieveScheduledTootsInterface {
|
||||
void onRetrieveScheduledToots(List<StoredStatus> storedStatuses);
|
||||
}
|
|
@ -30,6 +30,8 @@ public class ApplicationJob implements JobCreator {
|
|||
return new NotificationsSyncJob();
|
||||
case HomeTimelineSyncJob.HOME_TIMELINE:
|
||||
return new HomeTimelineSyncJob();
|
||||
case ScheduledTootsSyncJob.SCHEDULED_TOOT:
|
||||
return new ScheduledTootsSyncJob();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -38,4 +40,8 @@ public class ApplicationJob implements JobCreator {
|
|||
public static void cancelAllJob(String TAG){
|
||||
JobManager.instance().cancelAllForTag(TAG);
|
||||
}
|
||||
|
||||
public static void cancelJob(int jobId) {
|
||||
JobManager.instance().cancel(jobId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package fr.gouv.etalab.mastodon.jobs;
|
||||
/* Copyright 2017 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Mastalab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import com.evernote.android.job.Job;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import fr.gouv.etalab.mastodon.client.API;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 16/07/2017.
|
||||
* Scheduled a toot a datetime
|
||||
*/
|
||||
|
||||
public class ScheduledTootsSyncJob extends Job {
|
||||
|
||||
public static final String SCHEDULED_TOOT = "job_scheduled_toot";
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Result onRunJob(Params params) {
|
||||
//Code refresh here
|
||||
int jobId = params.getId();
|
||||
SQLiteDatabase db = Sqlite.getInstance(getContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
//Retrieves the stored status
|
||||
StoredStatus storedStatus = new StatusStoredDAO(getContext(), db).getStatusScheduled(jobId);
|
||||
if( storedStatus != null){
|
||||
String userId = storedStatus.getUserId();
|
||||
String instance = storedStatus.getInstance();
|
||||
if( instance != null && userId != null){
|
||||
Account account = new AccountDAO(getContext(), db).getAccountByUserIDInstance(userId, instance);
|
||||
if( account != null){
|
||||
//Retrieves the linked status to toot
|
||||
Status status = storedStatus.getStatus();
|
||||
if( status != null){
|
||||
int statusCode = new API(getContext(), account.getInstance(), account.getToken()).statusAction(status);
|
||||
//Toot was sent
|
||||
if( statusCode == 200){
|
||||
new StatusStoredDAO(getContext(), db).updateScheduledDone(jobId, new Date());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
public static int schedule(Context context, long id, 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)
|
||||
.setPersisted(true)
|
||||
.setUpdateCurrent(false)
|
||||
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
|
||||
.setRequirementsEnforced(false)
|
||||
.build()
|
||||
.schedule();
|
||||
new StatusStoredDAO(context, db).scheduleStatus(id, jobId, new Date(timestampScheduling));
|
||||
return jobId;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -133,6 +133,21 @@ public class AccountDAO {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Account by id and instance
|
||||
* @param accountId String
|
||||
* @param instance String
|
||||
* @return Account
|
||||
*/
|
||||
public Account getAccountByUserIDInstance(String accountId, String instance){
|
||||
try {
|
||||
Cursor c = db.query(Sqlite.TABLE_USER_ACCOUNT, null, Sqlite.COL_USER_ID + " = '" + accountId + "' AND " + Sqlite.COL_INSTANCE + "= '"+ instance +"'", null, null, null, null, "1");
|
||||
return cursorToUser(c);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Account in db
|
||||
* @return Account List<Account>
|
||||
|
|
|
@ -51,7 +51,7 @@ public class StatusStoredDAO {
|
|||
* @param status Status
|
||||
* @return boolean
|
||||
*/
|
||||
public long insertStatus(Status status, boolean isScheduled, Date scheduled_date)
|
||||
public long insertStatus(Status status)
|
||||
{
|
||||
ContentValues values = new ContentValues();
|
||||
String serializedStatus = Helper.statusToStringStorage(status);
|
||||
|
@ -63,13 +63,11 @@ public class StatusStoredDAO {
|
|||
return -1;
|
||||
values.put(Sqlite.COL_STATUS_SERIALIZED, serializedStatus);
|
||||
values.put(Sqlite.COL_DATE_CREATION, Helper.dateToString(context, new Date()));
|
||||
values.put(Sqlite.COL_IS_SCHEDULED, isScheduled?1:0);
|
||||
values.put(Sqlite.COL_IS_SCHEDULED, 0);
|
||||
values.put(Sqlite.COL_INSTANCE, instance);
|
||||
values.put(Sqlite.COL_USER_ID, userId);
|
||||
values.put(Sqlite.COL_SENT, 0);
|
||||
|
||||
if( isScheduled && scheduled_date != null)
|
||||
values.put(Sqlite.COL_DATE_SCHEDULED, Helper.dateToString(context, scheduled_date));
|
||||
//Inserts stored status
|
||||
long last_id;
|
||||
try{
|
||||
|
@ -99,30 +97,61 @@ public class StatusStoredDAO {
|
|||
}
|
||||
|
||||
/**
|
||||
* Update scheduled date for a Status in database
|
||||
* @param scheduled_date Date
|
||||
* @return boolean
|
||||
* Update a Status in database
|
||||
* @param id long
|
||||
* @param jobId int
|
||||
* @return int
|
||||
*/
|
||||
public int updateScheduledDate(long id, Date scheduled_date) {
|
||||
public int updateJobId(long id, int jobId) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Sqlite.COL_DATE_SCHEDULED, Helper.dateToString(context, scheduled_date));
|
||||
values.put(Sqlite.COL_IS_SCHEDULED, jobId);
|
||||
return db.update(Sqlite.TABLE_STATUSES_STORED,
|
||||
values, Sqlite.COL_ID + " = ? ",
|
||||
new String[]{String.valueOf(id)});
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a status in db
|
||||
* @param id long
|
||||
* @param jobId int
|
||||
* @param date_scheduled Date
|
||||
* @return boolean
|
||||
*/
|
||||
public int scheduleStatus(long id, int jobId, Date date_scheduled ) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Sqlite.COL_IS_SCHEDULED, jobId);
|
||||
values.put(Sqlite.COL_DATE_SCHEDULED, Helper.dateToString(context, date_scheduled));
|
||||
return db.update(Sqlite.TABLE_STATUSES_STORED,
|
||||
values, Sqlite.COL_ID + " = ? ",
|
||||
new String[]{String.valueOf(id)});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update scheduled date for a Status in database
|
||||
* @param scheduled_date Date
|
||||
* @return boolean
|
||||
*/
|
||||
public int updateScheduledDate(int jobid, Date scheduled_date) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Sqlite.COL_DATE_SCHEDULED, Helper.dateToString(context, scheduled_date));
|
||||
return db.update(Sqlite.TABLE_STATUSES_STORED,
|
||||
values, Sqlite.COL_IS_SCHEDULED + " = ? ",
|
||||
new String[]{String.valueOf(jobid)});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update date when task is done for a scheduled Status in database
|
||||
* @param jobid int
|
||||
* @param date_sent Date
|
||||
* @return boolean
|
||||
*/
|
||||
public int updateScheduledDone(long id, Date date_sent) {
|
||||
public int updateScheduledDone(int jobid, Date date_sent) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Sqlite.COL_DATE_SENT, Helper.dateToString(context, date_sent));
|
||||
values.put(Sqlite.COL_SENT, 1);
|
||||
return db.update(Sqlite.TABLE_STATUSES_STORED,
|
||||
values, Sqlite.COL_ID + " = ? ",
|
||||
new String[]{String.valueOf(id)});
|
||||
values, Sqlite.COL_IS_SCHEDULED + " = ? ",
|
||||
new String[]{String.valueOf(jobid)});
|
||||
}
|
||||
|
||||
//------- REMOVE -------
|
||||
|
@ -142,6 +171,10 @@ public class StatusStoredDAO {
|
|||
return db.delete(Sqlite.TABLE_STATUSES_STORED, Sqlite.COL_IS_SCHEDULED + " = \"0\" AND " + Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "'", null);
|
||||
}
|
||||
|
||||
public int removeAllSent(){
|
||||
return db.delete(Sqlite.TABLE_STATUSES_STORED, Sqlite.COL_IS_SCHEDULED + " != 0 AND " + Sqlite.COL_SENT + " = 1", null);
|
||||
}
|
||||
|
||||
//------- GETTERS -------
|
||||
|
||||
/**
|
||||
|
@ -176,6 +209,22 @@ public class StatusStoredDAO {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all scheduled Statuses in db
|
||||
* @return stored status List<StoredStatus>
|
||||
*/
|
||||
public List<StoredStatus> getAllScheduled(){
|
||||
try {
|
||||
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_STATUSES_STORED, 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) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns all not sent Statuses in db
|
||||
* @return stored status List<StoredStatus>
|
||||
|
@ -185,7 +234,7 @@ public class StatusStoredDAO {
|
|||
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_STATUSES_STORED, null, Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " +Sqlite.COL_IS_SCHEDULED + " = 1 AND " + Sqlite.COL_SENT + " = 0", null, null, null, Sqlite.COL_DATE_CREATION + " DESC", null);
|
||||
Cursor c = db.query(Sqlite.TABLE_STATUSES_STORED, 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);
|
||||
return cursorToListStatuses(c);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
|
@ -201,7 +250,7 @@ public class StatusStoredDAO {
|
|||
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_STATUSES_STORED, null, Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " +Sqlite.COL_IS_SCHEDULED + " = 1 AND " + Sqlite.COL_SENT + " = 1", null, null, null, Sqlite.COL_DATE_CREATION + " DESC", null);
|
||||
Cursor c = db.query(Sqlite.TABLE_STATUSES_STORED, 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);
|
||||
return cursorToListStatuses(c);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
|
@ -222,6 +271,18 @@ public class StatusStoredDAO {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a stored status by id of job in db
|
||||
* @return stored status StoredStatus
|
||||
*/
|
||||
public StoredStatus getStatusScheduled(int jobid){
|
||||
try {
|
||||
Cursor c = db.query(Sqlite.TABLE_STATUSES_STORED, null, Sqlite.COL_IS_SCHEDULED + " = '" + jobid + "'", null, null, null, null, null);
|
||||
return cursorToStoredStatus(c);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Method to hydrate Stored statuses from database
|
||||
|
@ -240,10 +301,12 @@ public class StatusStoredDAO {
|
|||
Status status = Helper.restoreStatusFromString(c.getString(c.getColumnIndex(Sqlite.COL_STATUS_SERIALIZED)));
|
||||
storedStatus.setStatus(status);
|
||||
storedStatus.setSent(c.getInt(c.getColumnIndex(Sqlite.COL_SENT)) == 1);
|
||||
storedStatus.setScheduled(c.getInt(c.getColumnIndex(Sqlite.COL_IS_SCHEDULED)) == 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)));
|
||||
storedStatus.setInstance(c.getString(c.getColumnIndex(Sqlite.COL_INSTANCE)));
|
||||
//Close the cursor
|
||||
c.close();
|
||||
//Stored status is returned
|
||||
|
@ -267,10 +330,12 @@ public class StatusStoredDAO {
|
|||
Status status = Helper.restoreStatusFromString(c.getString(c.getColumnIndex(Sqlite.COL_STATUS_SERIALIZED)));
|
||||
storedStatus.setStatus(status);
|
||||
storedStatus.setSent(c.getInt(c.getColumnIndex(Sqlite.COL_SENT)) == 1);
|
||||
storedStatus.setScheduled(c.getInt(c.getColumnIndex(Sqlite.COL_IS_SCHEDULED)) == 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)));
|
||||
storedStatus.setInstance(c.getString(c.getColumnIndex(Sqlite.COL_INSTANCE)));
|
||||
storedStatuses.add(storedStatus);
|
||||
}
|
||||
//Close the cursor
|
||||
|
|
After Width: | Height: | Size: 175 B |
After Width: | Height: | Size: 459 B |
After Width: | Height: | Size: 186 B |
After Width: | Height: | Size: 198 B |
After Width: | Height: | Size: 187 B |
After Width: | Height: | Size: 289 B |
After Width: | Height: | Size: 190 B |
After Width: | Height: | Size: 186 B |
After Width: | Height: | Size: 134 B |
After Width: | Height: | Size: 308 B |
After Width: | Height: | Size: 145 B |
After Width: | Height: | Size: 147 B |
After Width: | Height: | Size: 202 B |
After Width: | Height: | Size: 578 B |
After Width: | Height: | Size: 226 B |
After Width: | Height: | Size: 252 B |
After Width: | Height: | Size: 274 B |
After Width: | Height: | Size: 851 B |
After Width: | Height: | Size: 296 B |
After Width: | Height: | Size: 326 B |
After Width: | Height: | Size: 311 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 364 B |
After Width: | Height: | Size: 402 B |
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2017 Thomas Schneider
|
||||
|
||||
This file is a part of Mastalab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<DatePicker
|
||||
android:id="@+id/date_picker"
|
||||
android:layout_width="match_parent"
|
||||
android:calendarViewShown="true"
|
||||
android:gravity="center"
|
||||
android:spinnersShown="false"
|
||||
android:layout_height="wrap_content" />
|
||||
<TimePicker
|
||||
android:visibility="gone"
|
||||
android:gravity="center"
|
||||
android:id="@+id/time_picker"
|
||||
android:layout_weight="4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
<Button
|
||||
android:id="@+id/date_time_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/cancel"
|
||||
android:layout_height="40dp"
|
||||
tools:ignore="ButtonStyle" />
|
||||
<ImageButton
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/date_time_previous"
|
||||
android:layout_width="40dp"
|
||||
android:src="@drawable/ic_skip_previous"
|
||||
android:layout_height="40dp"
|
||||
tools:ignore="ButtonStyle" />
|
||||
<ImageButton
|
||||
android:id="@+id/date_time_next"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:src="@drawable/ic_skip_next"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
tools:ignore="ButtonStyle" />
|
||||
<ImageButton
|
||||
android:visibility="gone"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:id="@+id/date_time_set"
|
||||
android:src="@drawable/ic_check"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
tools:ignore="ButtonStyle" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -56,5 +56,4 @@
|
|||
android:layout_height="40dp"
|
||||
android:padding="10dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,112 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2017 Thomas Schneider
|
||||
|
||||
This file is a part of Mastalab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:card_view="http://schemas.android.com/tools"
|
||||
android:layout_marginTop="10dp"
|
||||
style="?attr/cardStyle"
|
||||
card_view:cardPreventCornerOverlap="true"
|
||||
android:id="@+id/scheduled_toot_container"
|
||||
app:cardUseCompatPadding="true">
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
android:id="@+id/account_container"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/scheduled_toot_title"
|
||||
android:textStyle="bold"
|
||||
android:maxLines="3"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<ImageView
|
||||
android:id="@+id/scheduled_toot_privacy"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:id="@+id/scheduled_toot_media_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<TextView
|
||||
android:id="@+id/scheduled_toot_date_creation"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="italic"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:gravity="end"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<Button
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:focusableInTouchMode="false"
|
||||
android:id="@+id/scheduled_toot_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:id="@+id/scheduled_toot_failed"
|
||||
android:textColor="@color/red_1"
|
||||
android:text="@string/failed"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
<ImageView
|
||||
android:id="@+id/scheduled_toot_delete"
|
||||
android:src="@drawable/ic_cancel"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:padding="10dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
</LinearLayout>
|
||||
</android.support.v7.widget.CardView>
|
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2017 Thomas Schneider
|
||||
|
||||
This file is a part of Mastalab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/fab_margin"
|
||||
android:paddingRight="@dimen/fab_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<!-- Listview Scheduled toots -->
|
||||
<ListView
|
||||
android:id="@+id/lv_scheduled_toots"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none"
|
||||
android:divider="@null"
|
||||
>
|
||||
</ListView>
|
||||
<RelativeLayout
|
||||
android:id="@+id/no_action"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:id="@+id/no_action_text"
|
||||
android:padding="10dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:gravity="center"
|
||||
android:textSize="25sp"
|
||||
android:layout_gravity="center"
|
||||
android:textStyle="italic|bold"
|
||||
android:typeface="serif"
|
||||
android:text="@string/no_scheduled_toots"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<TextView
|
||||
android:padding="10dp"
|
||||
android:layout_below="@+id/no_action_text"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center"
|
||||
android:textStyle="italic"
|
||||
android:layout_gravity="center"
|
||||
android:typeface="serif"
|
||||
android:text="@string/no_scheduled_toots_indications"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</RelativeLayout>
|
||||
<!-- Main Loader -->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/loader"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
>
|
||||
<ProgressBar
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true" />
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
|
@ -30,6 +30,10 @@
|
|||
android:id="@+id/nav_notification"
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:title="@string/notifications" />
|
||||
<item
|
||||
android:id="@+id/nav_scheduled"
|
||||
android:icon="@drawable/ic_schedule_black"
|
||||
android:title="@string/scheduled_toots" />
|
||||
<item
|
||||
android:id="@+id/nav_follow_request"
|
||||
android:icon="@drawable/ic_group_add"
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
android:title="@string/restore"
|
||||
android:icon="@drawable/ic_restore"
|
||||
app:showAsAction="never" />
|
||||
<!--<item
|
||||
<item
|
||||
android:id="@+id/action_schedule"
|
||||
android:title="@string/schedule"
|
||||
android:icon="@drawable/ic_schedule"
|
||||
app:showAsAction="never" />-->
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
<string name="speech_not_supported">Désolé ! Votre appareil ne supporte pas la commande vocale !</string>
|
||||
<string name="delete_all">Tout effacer</string>
|
||||
<string name="schedule">Programmer</string>
|
||||
<string name="next">Suivant</string>
|
||||
<string name="previous">Précédent</string>
|
||||
<!--- Menu -->
|
||||
<string name="home_menu">Accueil</string>
|
||||
<string name="local_menu">Fil public local</string>
|
||||
|
@ -65,6 +67,8 @@
|
|||
<string name="choose_file">Veuillez sélectionner un fichier</string>
|
||||
<string name="choose_file_error">Aucun explorateur de fichiers trouvé !</string>
|
||||
<string name="click_to_change">Cliquer sur le chemin pour changer</string>
|
||||
<string name="failed">Erreur !</string>
|
||||
<string name="scheduled_toots">Pouets programmés</string>
|
||||
<!-- Status -->
|
||||
<string name="no_status">Aucun pouet à afficher !</string>
|
||||
<string name="fav_added">Pouet ajouté aux favoris !</string>
|
||||
|
@ -179,6 +183,14 @@
|
|||
<string name="authorize">Autoriser</string>
|
||||
<string name="reject">Rejeter</string>
|
||||
|
||||
<!-- Scheduled toots -->
|
||||
<string name="no_scheduled_toots">Aucun pouet programmé à afficher !</string>
|
||||
<string name="no_scheduled_toots_indications">Ecrivez un pouet, puis choisissez <b>Programmer</b> dans le menu du haut.</string>
|
||||
<string name="remove_scheduled">Supprimer le pouet programmé ?</string>
|
||||
<string name="media_count">Média(s): %d</string>
|
||||
<string name="toot_scheduled">Le pouet a été programmé !</string>
|
||||
<string name="toot_scheduled_date">La date doit être supérieure à l\'heure actuelle !</string>
|
||||
|
||||
<!-- Notifications -->
|
||||
<string name="no_notifications">Aucune notification à afficher</string>
|
||||
<string name="notif_mention">a mentionné votre pouet</string>
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
<string name="delete_all">Delete all</string>
|
||||
|
||||
<string name="schedule">Schedule</string>
|
||||
|
||||
<string name="next">Next</string>
|
||||
<string name="previous">Previous</string>
|
||||
<!--- Menu -->
|
||||
<string name="home_menu">Home</string>
|
||||
<string name="local_menu">Local timeline</string>
|
||||
|
@ -67,6 +70,8 @@
|
|||
<string name="choose_file">Please select a file</string>
|
||||
<string name="choose_file_error">No file explorer found!</string>
|
||||
<string name="click_to_change">Click on the path to change it</string>
|
||||
<string name="failed">Failed!</string>
|
||||
<string name="scheduled_toots">Scheduled toots</string>
|
||||
<!-- Status -->
|
||||
<string name="no_status">No toot to display</string>
|
||||
<string name="fav_added">The toot was added to favourites</string>
|
||||
|
@ -183,6 +188,15 @@
|
|||
<string name="authorize">Authorize</string>
|
||||
<string name="reject">Reject</string>
|
||||
|
||||
|
||||
<!-- Scheduled toots -->
|
||||
<string name="no_scheduled_toots">No scheduled toot to display!</string>
|
||||
<string name="no_scheduled_toots_indications">Write a toot and then choose <b>Schedule</b> from the top menu.</string>
|
||||
<string name="remove_scheduled">Delete scheduled toot?</string>
|
||||
<string name="media_count">Media: %d</string>
|
||||
<string name="toot_scheduled">The toot has been scheduled!</string>
|
||||
<string name="toot_scheduled_date">The scheduled date must be greater than the current hour!</string>
|
||||
|
||||
<!-- Notifications -->
|
||||
<string name="no_notifications">No notification to display</string>
|
||||
<string name="notif_mention">mentioned your status</string>
|
||||
|
|