Toots saved as drafts
|
@ -32,4 +32,5 @@ dependencies {
|
||||||
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||||
compile 'com.evernote:android-job:1.1.11'
|
compile 'com.evernote:android-job:1.1.11'
|
||||||
compile 'com.github.chrisbanes:PhotoView:2.0.0'
|
compile 'com.github.chrisbanes:PhotoView:2.0.0'
|
||||||
|
compile 'com.google.code.gson:gson:2.8.0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,6 @@ import android.widget.Toast;
|
||||||
import android.widget.VideoView;
|
import android.widget.VideoView;
|
||||||
|
|
||||||
import com.github.chrisbanes.photoview.OnMatrixChangedListener;
|
import com.github.chrisbanes.photoview.OnMatrixChangedListener;
|
||||||
import com.github.chrisbanes.photoview.OnPhotoTapListener;
|
|
||||||
import com.github.chrisbanes.photoview.OnScaleChangedListener;
|
|
||||||
import com.github.chrisbanes.photoview.PhotoView;
|
import com.github.chrisbanes.photoview.PhotoView;
|
||||||
import com.loopj.android.http.AsyncHttpClient;
|
import com.loopj.android.http.AsyncHttpClient;
|
||||||
import com.loopj.android.http.FileAsyncHttpResponseHandler;
|
import com.loopj.android.http.FileAsyncHttpResponseHandler;
|
||||||
|
|
|
@ -34,6 +34,7 @@ import android.support.v7.app.AppCompatActivity;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -75,12 +76,15 @@ import fr.gouv.etalab.mastodon.client.Entities.Attachment;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
import fr.gouv.etalab.mastodon.client.Entities.Error;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||||
|
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||||
import fr.gouv.etalab.mastodon.drawers.AccountsSearchAdapter;
|
import fr.gouv.etalab.mastodon.drawers.AccountsSearchAdapter;
|
||||||
|
import fr.gouv.etalab.mastodon.drawers.DraftsListAdapter;
|
||||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||||
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
|
||||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface;
|
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface;
|
||||||
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface;
|
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface;
|
||||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||||
|
import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO;
|
||||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||||
|
|
||||||
|
@ -117,6 +121,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
||||||
private Status tootReply = null;
|
private Status tootReply = null;
|
||||||
private String sharedContent, sharedSubject;
|
private String sharedContent, sharedSubject;
|
||||||
private CheckBox toot_sensitive;
|
private CheckBox toot_sensitive;
|
||||||
|
public long currentToId;
|
||||||
|
|
||||||
private String pattern = "^.*(@([a-zA-Z0-9_]{2,}))$";
|
private String pattern = "^.*(@([a-zA-Z0-9_]{2,}))$";
|
||||||
@Override
|
@Override
|
||||||
|
@ -133,7 +138,8 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
||||||
|
|
||||||
if( getSupportActionBar() != null)
|
if( getSupportActionBar() != null)
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
//By default the toot is not restored so the id -1 is defined
|
||||||
|
currentToId = -1;
|
||||||
imageLoader = ImageLoader.getInstance();
|
imageLoader = ImageLoader.getInstance();
|
||||||
options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
||||||
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
||||||
|
@ -494,6 +500,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
final SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case android.R.id.home:
|
case android.R.id.home:
|
||||||
finish();
|
finish();
|
||||||
|
@ -513,6 +520,143 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case R.id.action_store:
|
||||||
|
storeToot();
|
||||||
|
return true;
|
||||||
|
case R.id.action_restore:
|
||||||
|
try{
|
||||||
|
final List<StoredStatus> drafts = new StatusStoredDAO(TootActivity.this, db).getAllDrafts();
|
||||||
|
if( drafts == null || drafts.size() == 0){
|
||||||
|
Toast.makeText(getApplicationContext(), R.string.no_draft, Toast.LENGTH_LONG).show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
AlertDialog.Builder builderSingle = new AlertDialog.Builder(TootActivity.this);
|
||||||
|
builderSingle.setTitle(getString(R.string.choose_toot));
|
||||||
|
final DraftsListAdapter draftsListAdapter = new DraftsListAdapter(TootActivity.this, drafts);
|
||||||
|
final int[] ids = new int[drafts.size()];
|
||||||
|
int i = 0;
|
||||||
|
for(StoredStatus draft: drafts){
|
||||||
|
ids[i] = draft.getId();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
builderSingle.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builderSingle.setPositiveButton(R.string.delete_all, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(final DialogInterface dialog, int which) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(TootActivity.this);
|
||||||
|
builder.setTitle(R.string.delete_all);
|
||||||
|
builder.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
|
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogConfirm, int which) {
|
||||||
|
new StatusStoredDAO(getApplicationContext(), db).removeAllDrafts();
|
||||||
|
dialogConfirm.dismiss();
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogConfirm, int which) {
|
||||||
|
dialogConfirm.dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builderSingle.setAdapter(draftsListAdapter, new DialogInterface.OnClickListener() {
|
||||||
|
@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();
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builderSingle.show();
|
||||||
|
}catch (Exception e){
|
||||||
|
Toast.makeText(getApplicationContext(), R.string.toast_error, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/*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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;*/
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
@ -648,6 +792,15 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause(){
|
||||||
|
super.onPause();
|
||||||
|
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
boolean storeToot = sharedpreferences.getBoolean(Helper.SET_AUTO_STORE, true);
|
||||||
|
if( storeToot)
|
||||||
|
storeToot();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
|
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
|
||||||
if( error != null){
|
if( error != null){
|
||||||
|
@ -700,4 +853,38 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void storeToot(){
|
||||||
|
//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;
|
||||||
|
|
||||||
|
Status toot = new Status();
|
||||||
|
toot.setSensitive(isSensitive);
|
||||||
|
toot.setMedia_attachments(attachments);
|
||||||
|
if( toot_cw_content.getText().toString().trim().length() > 0)
|
||||||
|
toot.setSpoiler_text(toot_cw_content.getText().toString().trim());
|
||||||
|
toot.setVisibility(visibility);
|
||||||
|
toot.setContent(toot_content.getText().toString().trim());
|
||||||
|
if( tootReply != null)
|
||||||
|
toot.setIn_reply_to_id(tootReply.getId());
|
||||||
|
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);
|
||||||
|
|
||||||
|
}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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
package fr.gouv.etalab.mastodon.client.Entities;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Thomas on 15/07/2017.
|
||||||
|
* Manage Stored status
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StoredStatus {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private Date creation_date;
|
||||||
|
private Date scheduled_date;
|
||||||
|
private Date sent_date;
|
||||||
|
private boolean isScheduled;
|
||||||
|
private boolean isSent;
|
||||||
|
private Status status;
|
||||||
|
private String instance;
|
||||||
|
private String acct;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreation_date() {
|
||||||
|
return creation_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreation_date(Date creation_date) {
|
||||||
|
this.creation_date = creation_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getScheduled_date() {
|
||||||
|
return scheduled_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScheduled_date(Date scheduled_date) {
|
||||||
|
this.scheduled_date = scheduled_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getSent_date() {
|
||||||
|
return sent_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSent_date(Date sent_date) {
|
||||||
|
this.sent_date = sent_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isScheduled() {
|
||||||
|
return isScheduled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScheduled(boolean scheduled) {
|
||||||
|
isScheduled = scheduled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSent() {
|
||||||
|
return isSent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSent(boolean sent) {
|
||||||
|
isSent = sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Status status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstance(String instance) {
|
||||||
|
this.instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAcct() {
|
||||||
|
return acct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAcct(String acct) {
|
||||||
|
this.acct = acct;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
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.SharedPreferences;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||||
|
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||||
|
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 15/07/2017.
|
||||||
|
* Adapter for toot drafts
|
||||||
|
*/
|
||||||
|
public class DraftsListAdapter extends BaseAdapter {
|
||||||
|
|
||||||
|
private List<StoredStatus> storedStatuses;
|
||||||
|
private LayoutInflater layoutInflater;
|
||||||
|
private Context context;
|
||||||
|
private DraftsListAdapter draftsListAdapter;
|
||||||
|
|
||||||
|
public DraftsListAdapter(Context context, List<StoredStatus> storedStatuses){
|
||||||
|
this.storedStatuses = storedStatuses;
|
||||||
|
this.context = context;
|
||||||
|
layoutInflater = LayoutInflater.from(context);
|
||||||
|
draftsListAdapter = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 draft = storedStatuses.get(position);
|
||||||
|
final ViewHolder holder;
|
||||||
|
if (convertView == null) {
|
||||||
|
convertView = layoutInflater.inflate(R.layout.drawer_draft, parent, false);
|
||||||
|
holder = new ViewHolder();
|
||||||
|
holder.draft_title = (TextView) convertView.findViewById(R.id.draft_title);
|
||||||
|
holder.draft_date = (TextView) convertView.findViewById(R.id.draft_date);
|
||||||
|
holder.draft_delete = (ImageView) convertView.findViewById(R.id.draft_delete);
|
||||||
|
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);
|
||||||
|
}else {
|
||||||
|
changeDrawableColor(context, R.drawable.ic_cancel,R.color.black);
|
||||||
|
}
|
||||||
|
final SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||||
|
if(draft.getStatus() != null && draft.getStatus().getContent() != null ) {
|
||||||
|
if (draft.getStatus().getContent().length() > 20)
|
||||||
|
holder.draft_title.setText(draft.getStatus().getContent().substring(0, 20));
|
||||||
|
else
|
||||||
|
holder.draft_title.setText(draft.getStatus().getContent());
|
||||||
|
}
|
||||||
|
holder.draft_date.setText(Helper.dateToString(context, draft.getCreation_date()));
|
||||||
|
holder.draft_delete.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
builder.setMessage(draft.getStatus().getContent() + '\n' + draft.getCreation_date());
|
||||||
|
builder.setIcon(android.R.drawable.ic_dialog_alert)
|
||||||
|
.setTitle(R.string.remove_draft)
|
||||||
|
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
new StatusStoredDAO(context, db).remove(draft.getId());
|
||||||
|
storedStatuses.remove(draft);
|
||||||
|
draftsListAdapter.notifyDataSetChanged();
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class ViewHolder {
|
||||||
|
TextView draft_title;
|
||||||
|
TextView draft_date;
|
||||||
|
ImageView draft_delete;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -62,6 +62,8 @@ public class SettingsFragment extends Fragment {
|
||||||
|
|
||||||
|
|
||||||
boolean show_reply = sharedpreferences.getBoolean(Helper.SET_SHOW_REPLY, false);
|
boolean show_reply = sharedpreferences.getBoolean(Helper.SET_SHOW_REPLY, false);
|
||||||
|
boolean auto_store = sharedpreferences.getBoolean(Helper.SET_AUTO_STORE, true);
|
||||||
|
|
||||||
final CheckBox set_show_reply = (CheckBox) rootView.findViewById(R.id.set_show_reply);
|
final CheckBox set_show_reply = (CheckBox) rootView.findViewById(R.id.set_show_reply);
|
||||||
set_show_reply.setChecked(show_reply);
|
set_show_reply.setChecked(show_reply);
|
||||||
|
|
||||||
|
@ -74,6 +76,17 @@ public class SettingsFragment extends Fragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final CheckBox set_auto_store = (CheckBox) rootView.findViewById(R.id.set_auto_store);
|
||||||
|
set_auto_store.setChecked(auto_store);
|
||||||
|
set_auto_store.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putBoolean(Helper.SET_AUTO_STORE, set_auto_store.isChecked());
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);
|
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);
|
||||||
final CheckBox set_show_error_messages = (CheckBox) rootView.findViewById(R.id.set_show_error_messages);
|
final CheckBox set_show_error_messages = (CheckBox) rootView.findViewById(R.id.set_show_error_messages);
|
||||||
set_show_error_messages.setChecked(show_error_messages);
|
set_show_error_messages.setChecked(show_error_messages);
|
||||||
|
|
|
@ -67,6 +67,7 @@ import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
import com.loopj.android.http.BuildConfig;
|
import com.loopj.android.http.BuildConfig;
|
||||||
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
|
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
|
@ -108,6 +109,7 @@ import fr.gouv.etalab.mastodon.activities.WebviewActivity;
|
||||||
import fr.gouv.etalab.mastodon.asynctasks.RemoveAccountAsyncTask;
|
import fr.gouv.etalab.mastodon.asynctasks.RemoveAccountAsyncTask;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
||||||
|
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Tag;
|
import fr.gouv.etalab.mastodon.client.Entities.Tag;
|
||||||
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
|
||||||
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
import fr.gouv.etalab.mastodon.sqlite.AccountDAO;
|
||||||
|
@ -168,6 +170,7 @@ public class Helper {
|
||||||
public static final String SET_THEME = "set_theme";
|
public static final String SET_THEME = "set_theme";
|
||||||
public static final String SET_TIME_FROM = "set_time_from";
|
public static final String SET_TIME_FROM = "set_time_from";
|
||||||
public static final String SET_TIME_TO = "set_time_to";
|
public static final String SET_TIME_TO = "set_time_to";
|
||||||
|
public static final String SET_AUTO_STORE = "set_auto_store";
|
||||||
public static final int ATTACHMENT_ALWAYS = 1;
|
public static final int ATTACHMENT_ALWAYS = 1;
|
||||||
public static final int ATTACHMENT_WIFI = 2;
|
public static final int ATTACHMENT_WIFI = 2;
|
||||||
public static final int ATTACHMENT_ASK = 3;
|
public static final int ATTACHMENT_ASK = 3;
|
||||||
|
@ -1218,4 +1221,14 @@ public class Helper {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String statusToStringStorage(Status status){
|
||||||
|
Gson gson = new Gson();
|
||||||
|
return gson.toJson(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Status restoreStatusFromString(String serializedStatus){
|
||||||
|
Gson gson = new Gson();
|
||||||
|
return gson.fromJson(serializedStatus, Status.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import android.database.sqlite.SQLiteOpenHelper;
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public class Sqlite extends SQLiteOpenHelper {
|
public class Sqlite extends SQLiteOpenHelper {
|
||||||
|
|
||||||
public static final int DB_VERSION = 1;
|
public static final int DB_VERSION = 2;
|
||||||
public static final String DB_NAME = "mastodon_etalab_db";
|
public static final String DB_NAME = "mastodon_etalab_db";
|
||||||
public static SQLiteDatabase db;
|
public static SQLiteDatabase db;
|
||||||
private static Sqlite sInstance;
|
private static Sqlite sInstance;
|
||||||
|
@ -36,7 +36,8 @@ public class Sqlite extends SQLiteOpenHelper {
|
||||||
*/
|
*/
|
||||||
//Table of owned accounts
|
//Table of owned accounts
|
||||||
static final String TABLE_USER_ACCOUNT = "USER_ACCOUNT";
|
static final String TABLE_USER_ACCOUNT = "USER_ACCOUNT";
|
||||||
|
//Table of stored status
|
||||||
|
static final String TABLE_STATUSES_STORED = "STATUSES_STORED";
|
||||||
|
|
||||||
|
|
||||||
public static final String COL_USER_ID = "USER_ID";
|
public static final String COL_USER_ID = "USER_ID";
|
||||||
|
@ -69,6 +70,21 @@ public class Sqlite extends SQLiteOpenHelper {
|
||||||
+ COL_INSTANCE + " TEXT NOT NULL, " + COL_OAUTHTOKEN + " TEXT NOT NULL, " + COL_CREATED_AT + " TEXT NOT NULL)";
|
+ COL_INSTANCE + " TEXT NOT NULL, " + COL_OAUTHTOKEN + " TEXT NOT NULL, " + COL_CREATED_AT + " TEXT NOT NULL)";
|
||||||
|
|
||||||
|
|
||||||
|
public static final String COL_ID = "ID";
|
||||||
|
public static final String COL_STATUS_SERIALIZED = "STATUS_SERIALIZED";
|
||||||
|
public static final String COL_DATE_CREATION = "DATE_CREATION";
|
||||||
|
public static final String COL_IS_SCHEDULED = "IS_SCHEDULED";
|
||||||
|
public static final String COL_DATE_SCHEDULED = "DATE_SCHEDULED";
|
||||||
|
public static final String COL_SENT = "SENT";
|
||||||
|
public static final String COL_DATE_SENT = "DATE_SENT";
|
||||||
|
|
||||||
|
private static final String CREATE_TABLE_STATUSES_STORED = "CREATE TABLE " + TABLE_STATUSES_STORED + " ("
|
||||||
|
+ COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
|
+ COL_USER_ID + " TEXT NOT NULL, " + COL_INSTANCE + " TEXT NOT NULL, "
|
||||||
|
+ COL_STATUS_SERIALIZED + " TEXT NOT NULL, " + COL_DATE_CREATION + " TEXT NOT NULL, "
|
||||||
|
+ COL_IS_SCHEDULED + " INTEGER NOT NULL, " + COL_DATE_SCHEDULED + " TEXT, "
|
||||||
|
+ COL_SENT + " INTEGER NOT NULL, " + COL_DATE_SENT + " TEXT)";
|
||||||
|
|
||||||
|
|
||||||
public Sqlite(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
|
public Sqlite(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
|
||||||
super(context, name, factory, version);
|
super(context, name, factory, version);
|
||||||
|
@ -86,12 +102,14 @@ public class Sqlite extends SQLiteOpenHelper {
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(SQLiteDatabase db) {
|
public void onCreate(SQLiteDatabase db) {
|
||||||
db.execSQL(CREATE_TABLE_USER_ACCOUNT);
|
db.execSQL(CREATE_TABLE_USER_ACCOUNT);
|
||||||
|
db.execSQL(CREATE_TABLE_STATUSES_STORED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
switch (oldVersion) {
|
switch (oldVersion) {
|
||||||
|
case 1:
|
||||||
|
db.execSQL(CREATE_TABLE_STATUSES_STORED);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,281 @@
|
||||||
|
package fr.gouv.etalab.mastodon.sqlite;
|
||||||
|
/* 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.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import fr.gouv.etalab.mastodon.client.Entities.Status;
|
||||||
|
import fr.gouv.etalab.mastodon.client.Entities.StoredStatus;
|
||||||
|
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Thomas on 15/07/2017.
|
||||||
|
* Manage Status storage in DB
|
||||||
|
*/
|
||||||
|
public class StatusStoredDAO {
|
||||||
|
|
||||||
|
private SQLiteDatabase db;
|
||||||
|
public Context context;
|
||||||
|
|
||||||
|
|
||||||
|
public StatusStoredDAO(Context context, SQLiteDatabase db) {
|
||||||
|
//Creation of the DB with tables
|
||||||
|
this.context = context;
|
||||||
|
this.db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------- INSERTIONS -------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a status in database
|
||||||
|
* @param status Status
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public long insertStatus(Status status, boolean isScheduled, Date scheduled_date)
|
||||||
|
{
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
String serializedStatus = Helper.statusToStringStorage(status);
|
||||||
|
|
||||||
|
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||||
|
String instance = Helper.getLiveInstance(context);
|
||||||
|
if( userId == null || instance == null)
|
||||||
|
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_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{
|
||||||
|
last_id = db.insert(Sqlite.TABLE_STATUSES_STORED, null, values);
|
||||||
|
}catch (Exception e) {
|
||||||
|
last_id = -1;
|
||||||
|
}
|
||||||
|
return last_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------- UPDATES -------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a Status in database
|
||||||
|
* @param status Status
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public int updateStatus(long id, Status status ) {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
|
||||||
|
String serializedStatus = Helper.statusToStringStorage(status);
|
||||||
|
values.put(Sqlite.COL_STATUS_SERIALIZED, serializedStatus);
|
||||||
|
values.put(Sqlite.COL_DATE_CREATION, Helper.dateToString(context, new Date()));
|
||||||
|
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(long id, 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_ID + " = ? ",
|
||||||
|
new String[]{String.valueOf(id)});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update date when task is done for a scheduled Status in database
|
||||||
|
* @param date_sent Date
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public int updateScheduledDone(long id, 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)});
|
||||||
|
}
|
||||||
|
|
||||||
|
//------- REMOVE -------
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Remove stored status by id
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public int remove(long id){
|
||||||
|
return db.delete(Sqlite.TABLE_STATUSES_STORED, Sqlite.COL_ID + " = \"" + id + "\"", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int removeAllDrafts(){
|
||||||
|
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||||
|
String instance = Helper.getLiveInstance(context);
|
||||||
|
return db.delete(Sqlite.TABLE_STATUSES_STORED, Sqlite.COL_IS_SCHEDULED + " = \"0\" AND " + Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "'", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------- GETTERS -------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all stored Statuses in db
|
||||||
|
* @return stored status List<StoredStatus>
|
||||||
|
*/
|
||||||
|
public List<StoredStatus> getAllStatus(){
|
||||||
|
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||||
|
String instance = Helper.getLiveInstance(context);
|
||||||
|
try {
|
||||||
|
Cursor c = db.query(Sqlite.TABLE_STATUSES_STORED, null, Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "'", null, null, null, Sqlite.COL_DATE_CREATION + " DESC", null);
|
||||||
|
return cursorToListStatuses(c);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all stored Statuses in db
|
||||||
|
* @return stored status List<StoredStatus>
|
||||||
|
*/
|
||||||
|
public List<StoredStatus> getAllDrafts(){
|
||||||
|
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", null, null, null, Sqlite.COL_DATE_CREATION + " DESC", null);
|
||||||
|
return cursorToListStatuses(c);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all not sent Statuses in db
|
||||||
|
* @return stored status List<StoredStatus>
|
||||||
|
*/
|
||||||
|
public List<StoredStatus> getAllNotSent(){
|
||||||
|
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 + " = 1 AND " + Sqlite.COL_SENT + " = 0", null, null, null, Sqlite.COL_DATE_CREATION + " DESC", null);
|
||||||
|
return cursorToListStatuses(c);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all sent Statuses in db
|
||||||
|
* @return stored status List<StoredStatus>
|
||||||
|
*/
|
||||||
|
public List<StoredStatus> getAllSent(){
|
||||||
|
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 + " = 1 AND " + Sqlite.COL_SENT + " = 1", null, null, null, Sqlite.COL_DATE_CREATION + " DESC", null);
|
||||||
|
return cursorToListStatuses(c);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a stored status by id in db
|
||||||
|
* @return stored status StoredStatus
|
||||||
|
*/
|
||||||
|
public StoredStatus getStatus(long id){
|
||||||
|
try {
|
||||||
|
Cursor c = db.query(Sqlite.TABLE_STATUSES_STORED, null, Sqlite.COL_ID + " = '" + id + "'", null, null, null, null, null);
|
||||||
|
return cursorToStoredStatus(c);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Method to hydrate Stored statuses from database
|
||||||
|
* @param c Cursor
|
||||||
|
* @return StoredStatus
|
||||||
|
*/
|
||||||
|
private StoredStatus cursorToStoredStatus(Cursor c){
|
||||||
|
//No element found
|
||||||
|
if (c.getCount() == 0)
|
||||||
|
return null;
|
||||||
|
//Take the first element
|
||||||
|
c.moveToFirst();
|
||||||
|
//New user
|
||||||
|
StoredStatus storedStatus = new StoredStatus();
|
||||||
|
storedStatus.setId(c.getInt(c.getColumnIndex(Sqlite.COL_ID)));
|
||||||
|
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.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))));
|
||||||
|
//Close the cursor
|
||||||
|
c.close();
|
||||||
|
//Stored status is returned
|
||||||
|
return storedStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Method to hydrate stored statuses from database
|
||||||
|
* @param c Cursor
|
||||||
|
* @return List<StoredStatus>
|
||||||
|
*/
|
||||||
|
private List<StoredStatus> cursorToListStatuses(Cursor c){
|
||||||
|
//No element found
|
||||||
|
if (c.getCount() == 0)
|
||||||
|
return null;
|
||||||
|
List<StoredStatus> storedStatuses = new ArrayList<>();
|
||||||
|
while (c.moveToNext() ) {
|
||||||
|
//Restore the status
|
||||||
|
StoredStatus storedStatus = new StoredStatus();
|
||||||
|
storedStatus.setId(c.getInt(c.getColumnIndex(Sqlite.COL_ID)));
|
||||||
|
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.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))));
|
||||||
|
storedStatuses.add(storedStatus);
|
||||||
|
}
|
||||||
|
//Close the cursor
|
||||||
|
c.close();
|
||||||
|
//Statuses list is returned
|
||||||
|
return storedStatuses;
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 571 B |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 494 B |
After Width: | Height: | Size: 465 B |
After Width: | Height: | Size: 352 B |
After Width: | Height: | Size: 384 B |
After Width: | Height: | Size: 706 B |
After Width: | Height: | Size: 772 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,60 @@
|
||||||
|
<?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:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
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/draft_title"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginLeft="10dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/draft_date"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:textStyle="italic"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
android:layout_marginRight="10dp"
|
||||||
|
android:gravity="end"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/draft_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>
|
|
@ -53,7 +53,12 @@
|
||||||
android:text="@string/set_display_reply"
|
android:text="@string/set_display_reply"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:id="@+id/set_auto_store"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="@string/set_auto_store_toot"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -5,5 +5,20 @@
|
||||||
android:id="@+id/action_microphone"
|
android:id="@+id/action_microphone"
|
||||||
android:title="@string/microphone"
|
android:title="@string/microphone"
|
||||||
android:icon="@drawable/ic_action_mic"
|
android:icon="@drawable/ic_action_mic"
|
||||||
app:showAsAction="always" />
|
app:showAsAction="ifRoom" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_store"
|
||||||
|
android:title="@string/save"
|
||||||
|
android:icon="@drawable/ic_save"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_restore"
|
||||||
|
android:title="@string/restore"
|
||||||
|
android:icon="@drawable/ic_restore"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
<!--<item
|
||||||
|
android:id="@+id/action_schedule"
|
||||||
|
android:title="@string/schedule"
|
||||||
|
android:icon="@drawable/ic_schedule"
|
||||||
|
app:showAsAction="never" />-->
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
<string name="tags">Tags</string>
|
<string name="tags">Tags</string>
|
||||||
<string name="token">Jeton</string>
|
<string name="token">Jeton</string>
|
||||||
<string name="save">Sauvegarder</string>
|
<string name="save">Sauvegarder</string>
|
||||||
|
<string name="restore">Restaurer</string>
|
||||||
<string name="two_factor_authentification">Authentification en deux étapes ?</string>
|
<string name="two_factor_authentification">Authentification en deux étapes ?</string>
|
||||||
<string name="other_instance">Autre instance que mastodon.etalab.gouv.fr ?</string>
|
<string name="other_instance">Autre instance que mastodon.etalab.gouv.fr ?</string>
|
||||||
<string name="no_result">Aucun résultat !</string>
|
<string name="no_result">Aucun résultat !</string>
|
||||||
|
@ -41,6 +42,8 @@
|
||||||
<string name="microphone">Microphone</string>
|
<string name="microphone">Microphone</string>
|
||||||
<string name="speech_prompt">Veuillez dire quelque chose</string>
|
<string name="speech_prompt">Veuillez dire quelque chose</string>
|
||||||
<string name="speech_not_supported">Désolé ! Votre appareil ne supporte pas la commande vocale !</string>
|
<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>
|
||||||
<!--- Menu -->
|
<!--- Menu -->
|
||||||
<string name="home_menu">Accueil</string>
|
<string name="home_menu">Accueil</string>
|
||||||
<string name="local_menu">Fil public local</string>
|
<string name="local_menu">Fil public local</string>
|
||||||
|
@ -149,7 +152,9 @@
|
||||||
<item>N\'afficher que pour vos abonné(e)s</item>
|
<item>N\'afficher que pour vos abonné(e)s</item>
|
||||||
<item>N\'afficher que pour les personnes mentionnées</item>
|
<item>N\'afficher que pour les personnes mentionnées</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string name="no_draft">Aucun brouillon !</string>
|
||||||
|
<string name="choose_toot">Choisissez un pouet</string>
|
||||||
|
<string name="remove_draft">Supprimer le brouillon ?</string>
|
||||||
<!-- Instance -->
|
<!-- Instance -->
|
||||||
<string name="instance_no_description">Aucune description !</string>
|
<string name="instance_no_description">Aucune description !</string>
|
||||||
|
|
||||||
|
@ -215,6 +220,7 @@
|
||||||
<string name="nothing_to_do">Aucune action ne peut être réalisée</string>
|
<string name="nothing_to_do">Aucune action ne peut être réalisée</string>
|
||||||
<string name="toast_saved">Le média a été enregistré !</string>
|
<string name="toast_saved">Le média a été enregistré !</string>
|
||||||
<string name="toast_error_translate">Une erreur est survenue lors de la traduction !</string>
|
<string name="toast_error_translate">Une erreur est survenue lors de la traduction !</string>
|
||||||
|
<string name="toast_toot_saved">Brouillon enregistré !</string>
|
||||||
<!-- Settings -->
|
<!-- Settings -->
|
||||||
<string name="settings_title_optimisation">Optimisation du chargement</string>
|
<string name="settings_title_optimisation">Optimisation du chargement</string>
|
||||||
<string name="set_toots_page">Nombre de pouets par chargement</string>
|
<string name="set_toots_page">Nombre de pouets par chargement</string>
|
||||||
|
@ -229,6 +235,7 @@
|
||||||
<string name="load_sensitive_attachment">Charger les images sensibles</string>
|
<string name="load_sensitive_attachment">Charger les images sensibles</string>
|
||||||
<string name="set_display_reply">Afficher le message précédent lors d\'une réponse</string>
|
<string name="set_display_reply">Afficher le message précédent lors d\'une réponse</string>
|
||||||
<string name="set_folder_title">Destination : </string>
|
<string name="set_folder_title">Destination : </string>
|
||||||
|
<string name="set_auto_store_toot">Enregistrer les brouillons automatiquement</string>
|
||||||
|
|
||||||
<string name="settings_title_notifications">Gestion des notifications</string>
|
<string name="settings_title_notifications">Gestion des notifications</string>
|
||||||
<string name="set_notif_follow">Notifier lorsque quelqu’un me suit</string>
|
<string name="set_notif_follow">Notifier lorsque quelqu’un me suit</string>
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
<string name="tags">Tags</string>
|
<string name="tags">Tags</string>
|
||||||
<string name="token">Token</string>
|
<string name="token">Token</string>
|
||||||
<string name="save">Save</string>
|
<string name="save">Save</string>
|
||||||
|
<string name="restore">Restore</string>
|
||||||
<string name="two_factor_authentification">Two-step authentication?</string>
|
<string name="two_factor_authentification">Two-step authentication?</string>
|
||||||
<string name="other_instance">Other instance than mastodon.etalab.gouv.fr?</string>
|
<string name="other_instance">Other instance than mastodon.etalab.gouv.fr?</string>
|
||||||
<string name="no_result">No results!</string>
|
<string name="no_result">No results!</string>
|
||||||
|
@ -42,7 +43,9 @@
|
||||||
<string name="microphone">Microphone</string>
|
<string name="microphone">Microphone</string>
|
||||||
<string name="speech_prompt">Please, say something</string>
|
<string name="speech_prompt">Please, say something</string>
|
||||||
<string name="speech_not_supported">Sorry! Your device does not support the voice input!</string>
|
<string name="speech_not_supported">Sorry! Your device does not support the voice input!</string>
|
||||||
|
<string name="delete_all">Delete all</string>
|
||||||
|
|
||||||
|
<string name="schedule">Schedule</string>
|
||||||
<!--- Menu -->
|
<!--- Menu -->
|
||||||
<string name="home_menu">Home</string>
|
<string name="home_menu">Home</string>
|
||||||
<string name="local_menu">Local timeline</string>
|
<string name="local_menu">Local timeline</string>
|
||||||
|
@ -152,6 +155,9 @@
|
||||||
<item>Post to mentioned users only</item>
|
<item>Post to mentioned users only</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string name="no_draft">No draft!</string>
|
||||||
|
<string name="choose_toot">Choose a toot</string>
|
||||||
|
<string name="remove_draft">Remove draft?</string>
|
||||||
<!-- Instance -->
|
<!-- Instance -->
|
||||||
<string name="instance_no_description">No description available!</string>
|
<string name="instance_no_description">No description available!</string>
|
||||||
|
|
||||||
|
@ -218,6 +224,8 @@
|
||||||
<string name="nothing_to_do">No action can be taken</string>
|
<string name="nothing_to_do">No action can be taken</string>
|
||||||
<string name="toast_saved">The media has been saved!</string>
|
<string name="toast_saved">The media has been saved!</string>
|
||||||
<string name="toast_error_translate">An error occurred while translating!</string>
|
<string name="toast_error_translate">An error occurred while translating!</string>
|
||||||
|
<string name="toast_toot_saved">Draft saved!</string>
|
||||||
|
|
||||||
<!-- Settings -->
|
<!-- Settings -->
|
||||||
<string name="settings_title_optimisation">Optimisation of loading</string>
|
<string name="settings_title_optimisation">Optimisation of loading</string>
|
||||||
<string name="set_toots_page">Number of toots per load</string>
|
<string name="set_toots_page">Number of toots per load</string>
|
||||||
|
@ -232,7 +240,7 @@
|
||||||
<string name="load_sensitive_attachment">Sensitive content</string>
|
<string name="load_sensitive_attachment">Sensitive content</string>
|
||||||
<string name="set_display_reply">Display previous message in responses</string>
|
<string name="set_display_reply">Display previous message in responses</string>
|
||||||
<string name="set_folder_title">Path: </string>
|
<string name="set_folder_title">Path: </string>
|
||||||
|
<string name="set_auto_store_toot">Save drafts automatically</string>
|
||||||
<string name="settings_title_notifications">Manage notifications</string>
|
<string name="settings_title_notifications">Manage notifications</string>
|
||||||
<string name="set_notif_follow">Notify when someone follows you</string>
|
<string name="set_notif_follow">Notify when someone follows you</string>
|
||||||
<string name="set_notif_follow_ask">Notify when someone requests to follow you</string>
|
<string name="set_notif_follow_ask">Notify when someone requests to follow you</string>
|
||||||
|
|