Toots saved as drafts
|
@ -32,4 +32,5 @@ dependencies {
|
|||
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||
compile 'com.evernote:android-job:1.1.11'
|
||||
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 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.loopj.android.http.AsyncHttpClient;
|
||||
import com.loopj.android.http.FileAsyncHttpResponseHandler;
|
||||
|
|
|
@ -34,6 +34,7 @@ import android.support.v7.app.AppCompatActivity;
|
|||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
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.Mention;
|
||||
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.DraftsListAdapter;
|
||||
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.sqlite.AccountDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO;
|
||||
import fr.gouv.etalab.mastodon.sqlite.Sqlite;
|
||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||
|
||||
|
@ -117,6 +121,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
private Status tootReply = null;
|
||||
private String sharedContent, sharedSubject;
|
||||
private CheckBox toot_sensitive;
|
||||
public long currentToId;
|
||||
|
||||
private String pattern = "^.*(@([a-zA-Z0-9_]{2,}))$";
|
||||
@Override
|
||||
|
@ -133,7 +138,8 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
|
||||
if( getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
//By default the toot is not restored so the id -1 is defined
|
||||
currentToId = -1;
|
||||
imageLoader = ImageLoader.getInstance();
|
||||
options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false)
|
||||
.cacheOnDisk(true).resetViewBeforeLoading(true).build();
|
||||
|
@ -494,6 +500,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
final SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
|
@ -513,6 +520,143 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
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:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
@ -648,6 +792,15 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
|
|||
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
|
||||
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
|
||||
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 auto_store = sharedpreferences.getBoolean(Helper.SET_AUTO_STORE, true);
|
||||
|
||||
final CheckBox set_show_reply = (CheckBox) rootView.findViewById(R.id.set_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);
|
||||
final CheckBox set_show_error_messages = (CheckBox) rootView.findViewById(R.id.set_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.Toast;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.loopj.android.http.BuildConfig;
|
||||
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
|
||||
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.client.Entities.Account;
|
||||
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.PatchBaseImageDownloader;
|
||||
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_TIME_FROM = "set_time_from";
|
||||
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_WIFI = 2;
|
||||
public static final int ATTACHMENT_ASK = 3;
|
||||
|
@ -1218,4 +1221,14 @@ public class Helper {
|
|||
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")
|
||||
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 SQLiteDatabase db;
|
||||
private static Sqlite sInstance;
|
||||
|
@ -36,7 +36,8 @@ public class Sqlite extends SQLiteOpenHelper {
|
|||
*/
|
||||
//Table of owned accounts
|
||||
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";
|
||||
|
@ -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)";
|
||||
|
||||
|
||||
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) {
|
||||
super(context, name, factory, version);
|
||||
|
@ -86,12 +102,14 @@ public class Sqlite extends SQLiteOpenHelper {
|
|||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_USER_ACCOUNT);
|
||||
|
||||
db.execSQL(CREATE_TABLE_STATUSES_STORED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
switch (oldVersion) {
|
||||
case 1:
|
||||
db.execSQL(CREATE_TABLE_STATUSES_STORED);
|
||||
default:
|
||||
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: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
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -5,5 +5,20 @@
|
|||
android:id="@+id/action_microphone"
|
||||
android:title="@string/microphone"
|
||||
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>
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
<string name="tags">Tags</string>
|
||||
<string name="token">Jeton</string>
|
||||
<string name="save">Sauvegarder</string>
|
||||
<string name="restore">Restaurer</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="no_result">Aucun résultat !</string>
|
||||
|
@ -41,6 +42,8 @@
|
|||
<string name="microphone">Microphone</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="delete_all">Tout effacer</string>
|
||||
<string name="schedule">Programmer</string>
|
||||
<!--- Menu -->
|
||||
<string name="home_menu">Accueil</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 les personnes mentionnées</item>
|
||||
</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 -->
|
||||
<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="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_toot_saved">Brouillon enregistré !</string>
|
||||
<!-- Settings -->
|
||||
<string name="settings_title_optimisation">Optimisation du 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="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_auto_store_toot">Enregistrer les brouillons automatiquement</string>
|
||||
|
||||
<string name="settings_title_notifications">Gestion des notifications</string>
|
||||
<string name="set_notif_follow">Notifier lorsque quelqu’un me suit</string>
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
<string name="tags">Tags</string>
|
||||
<string name="token">Token</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="restore">Restore</string>
|
||||
<string name="two_factor_authentification">Two-step authentication?</string>
|
||||
<string name="other_instance">Other instance than mastodon.etalab.gouv.fr?</string>
|
||||
<string name="no_result">No results!</string>
|
||||
|
@ -42,7 +43,9 @@
|
|||
<string name="microphone">Microphone</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="delete_all">Delete all</string>
|
||||
|
||||
<string name="schedule">Schedule</string>
|
||||
<!--- Menu -->
|
||||
<string name="home_menu">Home</string>
|
||||
<string name="local_menu">Local timeline</string>
|
||||
|
@ -152,6 +155,9 @@
|
|||
<item>Post to mentioned users only</item>
|
||||
</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 -->
|
||||
<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="toast_saved">The media has been saved!</string>
|
||||
<string name="toast_error_translate">An error occurred while translating!</string>
|
||||
<string name="toast_toot_saved">Draft saved!</string>
|
||||
|
||||
<!-- Settings -->
|
||||
<string name="settings_title_optimisation">Optimisation of loading</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="set_display_reply">Display previous message in responses</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="set_notif_follow">Notify when someone follows you</string>
|
||||
<string name="set_notif_follow_ask">Notify when someone requests to follow you</string>
|
||||
|
|