diff --git a/README.md b/README.md index bc5e7b608..d46817c9a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,62 @@ -**Mastalab** est une application Android multi-comptes pour Mastodon +Mastalab is a multi-accounts client for Mastodon + +The number of libraries is minimized and it does not use tracking tools. The source code is free (GPLv3). Any help would be greatly appreciated to fix spelling or for any other suggestions. + +**Features** + +Multi-accounts management +- Add accounts from different instances +- Switch from one account to another by a simple click + +Timelines +- Federated / Local / Home +- Switch from one timeline to another by using the menu or by swiping the screen. +- Clicks on toots display the related conversations (context) +- Clicks on mentioned accounts display details about these accounts +- Clicks on hashtags display toots containing this hashtags + +Actions on toots +- Mute an account related to a toot +- Block an account related to a toot +- Report inappropriate toots to administrators +- Add/Remove a toot from favourites +- Boost/Unboost toots +- Copy the content of a toot +- Download media +- Translation of toots by a simple click (via the Yandex API) + +Write a toot +- Add media +- Change the visibility of the toot +- Mention accounts in toots with autocompletion (@ + 2 characters) +- Mark the content as sensitive +- Add spoilers + +Interaction with accounts +- Follow/Unfollow/Block/Unblock/Mute/Unmute +- Display details of accounts +- Authorize/Reject follow requests (for locked accounts) + +Searches +- A top bar allows to make researches for accounts/tags/toots +- A click on a tag displays toots containing this tag + +Network optimization +- Load of media: Automatic/WIFI only/Ask +- Customization of the number of toots/accounts per load + +Notifications +- Notifications for new toots on the home page (could be disabled in settings) +- Notifications for new events (could be disabled or filtered in settings) + +Built-in browser +- Full screen videos +- Disable JavaScript (default: enabled) +- Disable third-party cookies (default: disabled) +- Disable the built-in browser in settings -Pour toute remarque ou demande d'évolution, vous pouvez me contacter sur cette instance : [@tschneider](https://mastodon.etalab.gouv.fr/@tschneider) +Developer: [@tschneider](https://mastodon.etalab.gouv.fr/@tschneider) diff --git a/app/build.gradle b/app/build.gradle index 94f24bee9..f4c503f39 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "fr.gouv.etalab.mastodon" minSdkVersion 15 targetSdkVersion 25 - versionCode 30 - versionName "1.3.3" + versionCode 31 + versionName "1.3.4" } buildTypes { release { diff --git a/app/mastodon-etalab-v1.3.4.apk b/app/mastodon-etalab-v1.3.4.apk new file mode 100644 index 000000000..d9acb7620 Binary files /dev/null and b/app/mastodon-etalab-v1.3.4.apk differ diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainApplication.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainApplication.java index 136ea3531..8879e865f 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainApplication.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainApplication.java @@ -14,6 +14,7 @@ package fr.gouv.etalab.mastodon.activities; * You should have received a copy of the GNU General Public License along with Thomas Schneider; if not, * see . */ import android.app.Application; +import android.os.StrictMode; import com.evernote.android.job.JobManager; @@ -36,5 +37,8 @@ public class MainApplication extends Application{ JobManager.instance().getConfig().setVerbose(false); NotificationsSyncJob.schedule(false); HomeTimelineSyncJob.schedule(false); + StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); + StrictMode.setVmPolicy(builder.build()); + } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java index 8848b01a8..29765422d 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java @@ -34,7 +34,6 @@ 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.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -60,7 +59,6 @@ import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer; - import java.io.FileNotFoundException; import java.io.InputStream; import java.util.ArrayList; @@ -97,7 +95,6 @@ import mastodon.etalab.gouv.fr.mastodon.R; import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor; - /** * Created by Thomas on 01/05/2017. * Toot activity class @@ -169,10 +166,8 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc toot_lv_accounts = (ListView) findViewById(R.id.toot_lv_accounts); toot_sensitive = (CheckBox) findViewById(R.id.toot_sensitive); - final LinearLayout drawer_layout = (LinearLayout) findViewById(R.id.drawer_layout); - drawer_layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { @@ -242,7 +237,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc }; LocalBroadcastManager.getInstance(this).registerReceiver(search_validate, new IntentFilter(Helper.SEARCH_VALIDATE_ACCOUNT)); - FloatingActionButton toot_close_accounts = (FloatingActionButton) findViewById(R.id.toot_close_accounts); SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); @@ -304,7 +298,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc } }); - toot_it.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -429,7 +422,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc } }else if(requestCode == Helper.REQ_CODE_SPEECH_INPUT && resultCode == Activity.RESULT_OK){ if (null != data) { - ArrayList result = data .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); toot_content.setText(result.get(0)); @@ -725,7 +717,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc private void tootVisibilityDialog(){ - AlertDialog.Builder dialog = new AlertDialog.Builder(TootActivity.this); dialog.setTitle(R.string.toot_visibility_tilte); final String[] stringArray = getResources().getStringArray(R.array.toot_visibility); @@ -960,8 +951,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc } toot_content.setSelection(toot_content.getText().length()); //Put cursor at the end } - - } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayScheduledTootsFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayScheduledTootsFragment.java index cc4fec26e..50323f3cb 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayScheduledTootsFragment.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayScheduledTootsFragment.java @@ -14,31 +14,36 @@ package fr.gouv.etalab.mastodon.fragments; * You should have received a copy of the GNU General Public License along with Thomas Schneider; if not, * see . */ +import android.annotation.SuppressLint; +import android.content.ActivityNotFoundException; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; +import android.os.PowerManager; +import android.provider.Settings; import android.support.v4.app.Fragment; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; import android.widget.RelativeLayout; - -import com.evernote.android.job.JobManager; -import com.evernote.android.job.JobRequest; - +import android.widget.TextView; import java.util.List; -import java.util.Set; - import fr.gouv.etalab.mastodon.asynctasks.RetrieveScheduledTootsAsyncTask; import fr.gouv.etalab.mastodon.client.Entities.StoredStatus; import fr.gouv.etalab.mastodon.drawers.ScheduledTootsListAdapter; +import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveScheduledTootsInterface; -import fr.gouv.etalab.mastodon.jobs.ScheduledTootsSyncJob; import fr.gouv.etalab.mastodon.sqlite.Sqlite; import fr.gouv.etalab.mastodon.sqlite.StatusStoredDAO; import mastodon.etalab.gouv.fr.mastodon.R; +import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor; /** @@ -52,6 +57,7 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev private AsyncTask asyncTask; private RelativeLayout mainLoader, textviewNoAction; private ListView lv_scheduled_toots; + private TextView warning_battery_message; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -62,6 +68,7 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev lv_scheduled_toots = (ListView) rootView.findViewById(R.id.lv_scheduled_toots); mainLoader = (RelativeLayout) rootView.findViewById(R.id.loader); + warning_battery_message = (TextView) rootView.findViewById(R.id.warning_battery_message); textviewNoAction = (RelativeLayout) rootView.findViewById(R.id.no_action); mainLoader.setVisibility(View.VISIBLE); @@ -77,6 +84,61 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev super.onResume(); //Retrieves scheduled toots asyncTask = new RetrieveScheduledTootsAsyncTask(context, DisplayScheduledTootsFragment.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + final PowerManager powerManager = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE); + final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + //Battery saver is one and user never asked to stop showing the message + int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + if( theme == Helper.THEME_DARK) { + changeDrawableColor(context, R.drawable.ic_action_warning, R.color.colorAccentD); + changeDrawableColor(context, R.drawable.ic_cancel, R.color.colorAccentD); + }else { + changeDrawableColor(context, R.drawable.ic_action_warning, R.color.colorAccent); + changeDrawableColor(context, R.drawable.ic_cancel, R.color.colorAccent); + } + if( powerManager.isPowerSaveMode() && sharedpreferences.getBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE,true)){ + warning_battery_message.setVisibility(View.VISIBLE); + }else { + warning_battery_message.setVisibility(View.GONE); + } + warning_battery_message.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + final int DRAWABLE_RIGHT = 2; + if(event.getAction() == MotionEvent.ACTION_UP) { + if(event.getRawX() >= (warning_battery_message.getRight() - warning_battery_message.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) { + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putBoolean(Helper.SHOW_BATTERY_SAVER_MESSAGE, false); + editor.apply(); + warning_battery_message.setVisibility(View.GONE); + return true; + } + } + return false; + } + }); + warning_battery_message.setOnClickListener(new View.OnClickListener() { + @SuppressLint("BatteryLife") + @Override + public void onClick(View v) { + try { + Intent battSaverIntent = new Intent(); + battSaverIntent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings$BatterySaverSettingsActivity")); + startActivityForResult(battSaverIntent, 0); + }catch (ActivityNotFoundException e){ + try { + Intent batterySaverIntent; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { + batterySaverIntent = new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS); + startActivity(batterySaverIntent); + } + }catch (ActivityNotFoundException ignored){} + } + } + }); + }else { + warning_battery_message.setVisibility(View.GONE); + } } @Override @@ -99,7 +161,6 @@ public class DisplayScheduledTootsFragment extends Fragment implements OnRetriev } - @Override public void onRetrieveScheduledToots(List storedStatuses) { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java index e1cfd15aa..6422e2ccf 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java @@ -156,6 +156,7 @@ public class Helper { public static final String SCOPE = "scope"; public static final String SCOPES = "scopes"; public static final String WEBSITE = "website"; + public static final String SHOW_BATTERY_SAVER_MESSAGE = "show_battery_saver_message"; public static final String LAST_NOTIFICATION_MAX_ID = "last_notification_max_id"; public static final String LAST_HOMETIMELINE_MAX_ID = "last_hometimeline_max_id"; public static final String CLIP_BOARD = "clipboard"; diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java index d5f3ced1e..61a993563 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java @@ -82,7 +82,7 @@ public class Sqlite extends SQLiteOpenHelper { 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_STATUS_REPLY_SERIALIZED + " TEXT, " + COL_DATE_CREATION + " 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)"; diff --git a/app/src/main/res/drawable-hdpi/ic_action_warning.png b/app/src/main/res/drawable-hdpi/ic_action_warning.png new file mode 100644 index 000000000..120ec7757 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_warning.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_action_warning.png b/app/src/main/res/drawable-ldpi/ic_action_warning.png new file mode 100644 index 000000000..79570a726 Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_action_warning.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_warning.png b/app/src/main/res/drawable-mdpi/ic_action_warning.png new file mode 100644 index 000000000..b4a333f6f Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_warning.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_warning.png b/app/src/main/res/drawable-xhdpi/ic_action_warning.png new file mode 100644 index 000000000..8b3a1569d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_warning.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_warning.png b/app/src/main/res/drawable-xxhdpi/ic_action_warning.png new file mode 100644 index 000000000..b853a961f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_warning.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_action_warning.png b/app/src/main/res/drawable-xxxhdpi/ic_action_warning.png new file mode 100644 index 000000000..1ed3b2e9d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_action_warning.png differ diff --git a/app/src/main/res/layout/fragment_scheduled_toots.xml b/app/src/main/res/layout/fragment_scheduled_toots.xml index 58fd07b4e..56bf4f06d 100644 --- a/app/src/main/res/layout/fragment_scheduled_toots.xml +++ b/app/src/main/res/layout/fragment_scheduled_toots.xml @@ -31,6 +31,29 @@ android:divider="@null" > + Média(s): %d Le pouet a été programmé ! La date doit être supérieure à l\'heure actuelle ! + L\'économiseur de batterie est activé ! Il se peut que cela ne fonctionne pas comme prévu. Aucune notification à afficher diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4da7682a6..c4d7a25e2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -196,7 +196,7 @@ Media: %d The toot has been scheduled! The scheduled date must be greater than the current hour! - + Battery saver is enabled! It might not work as expected. No notification to display mentioned your status