diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5f97632e6..f34e05368 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -221,7 +221,10 @@
android:windowSoftInputMode="adjustPan"
android:theme="@style/Base.V7.Theme.AppCompat.Dialog"
android:excludeFromRecents="true"/>
-
+
. */
+package fr.gouv.etalab.mastodon.activities;
+
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import es.dmoral.toasty.Toasty;
+import fr.gouv.etalab.mastodon.R;
+import fr.gouv.etalab.mastodon.drawers.TagsEditAdapter;
+import fr.gouv.etalab.mastodon.helper.Helper;
+import fr.gouv.etalab.mastodon.sqlite.Sqlite;
+import fr.gouv.etalab.mastodon.sqlite.TagsCacheDAO;
+
+
+/**
+ * Created by Thomas on 01/12/2018.
+ * Tag cache activity class
+ */
+
+public class TagCacheActivity extends BaseActivity {
+
+ private RecyclerView tag_list;
+ private List tags;
+ private TagsEditAdapter tagsEditAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
+ int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
+ switch (theme){
+ case Helper.THEME_LIGHT:
+ setTheme(R.style.AppTheme_NoActionBar);
+ getWindow().getDecorView().setBackgroundColor(ContextCompat.getColor(TagCacheActivity.this, R.color.mastodonC3__));
+ break;
+ case Helper.THEME_DARK:
+ setTheme(R.style.AppThemeDark_NoActionBar);
+ getWindow().getDecorView().setBackgroundColor(ContextCompat.getColor(TagCacheActivity.this, R.color.mastodonC1));
+ break;
+ case Helper.THEME_BLACK:
+ setTheme(R.style.AppThemeBlack_NoActionBar);
+ getWindow().getDecorView().setBackgroundColor(ContextCompat.getColor(TagCacheActivity.this, R.color.black_3));
+ break;
+ default:
+ setTheme(R.style.AppThemeDark_NoActionBar);
+ getWindow().getDecorView().setBackgroundColor(ContextCompat.getColor(TagCacheActivity.this, R.color.mastodonC1));
+ }
+ getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ tags = new ArrayList<>();
+ setContentView(R.layout.activity_tag_cache);
+
+ tag_list = findViewById(R.id.tag_list);
+ SQLiteDatabase db = Sqlite.getInstance(TagCacheActivity.this, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
+ EditText tag_add = findViewById(R.id.tag_add);
+ ImageButton save_tag = findViewById(R.id.save_tag);
+
+ save_tag.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if( tag_add.getText() != null && tag_add.getText().toString().trim().replaceAll("\\#","").length() > 0) {
+ String tagToInsert = tag_add.getText().toString().trim().replaceAll("\\#","");
+ boolean isPresent = new TagsCacheDAO(TagCacheActivity.this, db).isPresent(tagToInsert);
+ if( isPresent)
+ Toasty.warning(TagCacheActivity.this, getString(R.string.tags_already_stored), Toast.LENGTH_LONG).show();
+ else {
+ new TagsCacheDAO(TagCacheActivity.this, db).insert(tagToInsert);
+ int position = tags.size();
+ tags.add(tagToInsert);
+ Toasty.success(TagCacheActivity.this, getString(R.string.tags_stored), Toast.LENGTH_LONG).show();
+ tag_add.setText("");
+ tagsEditAdapter.notifyItemInserted(position);
+ }
+ }
+ }
+ });
+
+ setTitle(R.string.manage_tags);
+ AsyncTask.execute(new Runnable() {
+ @Override
+ public void run() {
+
+ List tagsTemp = new TagsCacheDAO(TagCacheActivity.this, db).getAll();
+ if( tagsTemp != null)
+ tags = tagsTemp;
+ if( tags != null){
+ tagsEditAdapter = new TagsEditAdapter(TagCacheActivity.this, tags);
+ tag_list.setAdapter(tagsEditAdapter);
+ LinearLayoutManager mLayoutManager = new LinearLayoutManager(TagCacheActivity.this);
+ tag_list.setLayoutManager(mLayoutManager);
+ }
+ }
+ });
+
+ }
+}
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 8a40d8524..79b10e5db 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
@@ -1126,6 +1126,11 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount
case R.id.action_store:
storeToot(true, true);
return true;
+ case R.id.action_tags:
+ Intent intentTags = new Intent(TootActivity.this, TagCacheActivity.class);
+ intentTags.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+ startActivity(intentTags);
+ return true;
case R.id.action_restore:
try{
final List drafts = new StatusStoredDAO(TootActivity.this, db).getAllDrafts();
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/TagsEditAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/TagsEditAdapter.java
new file mode 100644
index 000000000..5f8111d74
--- /dev/null
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/TagsEditAdapter.java
@@ -0,0 +1,120 @@
+package fr.gouv.etalab.mastodon.drawers;
+/* Copyright 2018 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 Mastalab; if not,
+ * see . */
+
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.support.annotation.NonNull;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.List;
+
+import es.dmoral.toasty.Toasty;
+import fr.gouv.etalab.mastodon.R;
+import fr.gouv.etalab.mastodon.sqlite.Sqlite;
+import fr.gouv.etalab.mastodon.sqlite.TagsCacheDAO;
+
+
+/**
+ * Created by Thomas on 01/12/2018.
+ * Adapter for tags when editing
+ */
+public class TagsEditAdapter extends RecyclerView.Adapter {
+
+ private Context context;
+ private List tags;
+ private LayoutInflater layoutInflater;
+ private TagsEditAdapter tagsEditAdapter;
+
+ public TagsEditAdapter(Context context, List tags){
+ this.tags = tags;
+ this.layoutInflater = LayoutInflater.from(context);
+ this.context = context;
+ tagsEditAdapter = this;
+ }
+
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {
+ return new ViewHolder(layoutInflater.inflate(R.layout.drawer_tag_edit, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
+ final String[] tag = {tags.get(viewHolder.getAdapterPosition())};
+ ViewHolder holder = (ViewHolder) viewHolder;
+ holder.tag_name.setText(String.format("#%s", tag[0]));
+ SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
+ holder.save_tag.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if( holder.tag_name.getText() != null && holder.tag_name.getText().toString().trim().replaceAll("\\#","").length() > 0) {
+ String tagToInsert = holder.tag_name.getText().toString().trim().replaceAll("\\#","");
+ boolean isPresent = new TagsCacheDAO(context, db).isPresent(tagToInsert);
+ if( isPresent)
+ Toasty.warning(context, context.getString(R.string.tags_already_stored), Toast.LENGTH_LONG).show();
+ else {
+ new TagsCacheDAO(context, db).update(tag[0], tagToInsert);
+ Toasty.success(context, context.getString(R.string.tags_renamed), Toast.LENGTH_LONG).show();
+ }
+ }
+ }
+ });
+
+ holder.delete_tag.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ new TagsCacheDAO(context, db).removeTag(tag[0]);
+ tags.remove(tag[0]);
+ tagsEditAdapter.notifyItemRemoved(viewHolder.getAdapterPosition());
+ Toasty.success(context, context.getString(R.string.tags_deleted), Toast.LENGTH_LONG).show();
+ }
+ });
+
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getItemCount() {
+ return tags.size();
+ }
+
+
+ class ViewHolder extends RecyclerView.ViewHolder{
+ TextView tag_name;
+ ImageButton save_tag, delete_tag;
+
+ public ViewHolder(@NonNull View itemView) {
+ super(itemView);
+ tag_name = itemView.findViewById(R.id.tag_name);
+ delete_tag = itemView.findViewById(R.id.delete_tag);
+ save_tag = itemView.findViewById(R.id.save_tag);
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java b/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java
index afdc9b1b2..5af81d446 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java
@@ -261,12 +261,9 @@ public class LiveNotificationService extends Service implements NetworkStateRece
event = Helper.EventStreaming.NOTIFICATION;
notification = API.parseNotificationResponse(getApplicationContext(), new JSONObject(response.get("payload").toString()));
b.putParcelable("data", notification);
-
-
boolean liveNotifications = sharedpreferences.getBoolean(Helper.SET_LIVE_NOTIFICATIONS, true);
boolean canNotify = Helper.canNotify(getApplicationContext());
boolean notify = sharedpreferences.getBoolean(Helper.SET_NOTIFY, true);
-
String targeted_account = null;
Helper.NotifType notifType = Helper.NotifType.MENTION;
boolean activityRunning = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("isMainActivityRunning", false);
@@ -336,53 +333,51 @@ public class LiveNotificationService extends Service implements NetworkStateRece
}
long notif_id = Long.parseLong(account.getId());
final int notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1);
- if (notification.getAccount().getAvatar() != null) {
- final String finalTitle = title;
- Handler mainHandler = new Handler(Looper.getMainLooper());
- Helper.NotifType finalNotifType = notifType;
- Runnable myRunnable = new Runnable() {
- @Override
- public void run() {
- if (finalTitle != null) {
- Glide.with(getApplicationContext())
- .asBitmap()
- .load(notification.getAccount().getAvatar())
- .listener(new RequestListener() {
- @Override
- public boolean onResourceReady(Bitmap resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
- return false;
- }
+ final String finalTitle = title;
+ Handler mainHandler = new Handler(Looper.getMainLooper());
+ Helper.NotifType finalNotifType = notifType;
+ Runnable myRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (finalTitle != null) {
+ Glide.with(getApplicationContext())
+ .asBitmap()
+ .load(notification.getAccount().getAvatar())
+ .listener(new RequestListener() {
+ @Override
+ public boolean onResourceReady(Bitmap resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
+ return false;
+ }
- @Override
- public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
- notify_user(getApplicationContext(), intent, notificationId, BitmapFactory.decodeResource(getResources(),
- R.drawable.mastodonlogo), finalNotifType, finalTitle, "@" + account.getAcct() + "@" + account.getInstance());
- String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
- if (lastNotif == null || Long.parseLong(notification.getId()) > Long.parseLong(lastNotif)) {
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), notification.getId());
- editor.apply();
- }
- return false;
+ @Override
+ public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
+ notify_user(getApplicationContext(), intent, notificationId, BitmapFactory.decodeResource(getResources(),
+ R.drawable.mastodonlogo), finalNotifType, finalTitle, "@" + account.getAcct() + "@" + account.getInstance());
+ String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
+ if (lastNotif == null || Long.parseLong(notification.getId()) > Long.parseLong(lastNotif)) {
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), notification.getId());
+ editor.apply();
}
- })
- .into(new SimpleTarget() {
- @Override
- public void onResourceReady(@NonNull Bitmap resource, Transition super Bitmap> transition) {
- notify_user(getApplicationContext(), intent, notificationId, resource, finalNotifType, finalTitle, "@" + account.getAcct() + "@" + account.getInstance());
- String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
- if (lastNotif == null || Long.parseLong(notification.getId()) > Long.parseLong(lastNotif)) {
- SharedPreferences.Editor editor = sharedpreferences.edit();
- editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), notification.getId());
- editor.apply();
- }
+ return false;
+ }
+ })
+ .into(new SimpleTarget() {
+ @Override
+ public void onResourceReady(@NonNull Bitmap resource, Transition super Bitmap> transition) {
+ notify_user(getApplicationContext(), intent, notificationId, resource, finalNotifType, finalTitle, "@" + account.getAcct() + "@" + account.getInstance());
+ String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
+ if (lastNotif == null || Long.parseLong(notification.getId()) > Long.parseLong(lastNotif)) {
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), notification.getId());
+ editor.apply();
}
- });
- }
+ }
+ });
}
- };
- mainHandler.post(myRunnable);
- }
+ }
+ };
+ mainHandler.post(myRunnable);
}
}
break;
diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TagsCacheDAO.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TagsCacheDAO.java
index f6dd9ea6c..453e6a9b5 100644
--- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TagsCacheDAO.java
+++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TagsCacheDAO.java
@@ -52,6 +52,19 @@ public class TagsCacheDAO {
}catch (Exception ignored) {}
}
+ /**
+ * update a tag in database
+ * @param oldTag String
+ * @param newTag String
+ */
+ public void update(String oldTag, String newTag) {
+ ContentValues values = new ContentValues();
+ values.put(Sqlite.COL_TAGS, newTag);
+ try{
+ db.update(Sqlite.TABLE_CACHE_TAGS, values, Sqlite.COL_TAGS + " = ?",new String[]{ oldTag});
+ }catch (Exception ignored) {}
+ }
+
/***
* Remove all tags
*/
@@ -59,6 +72,11 @@ public class TagsCacheDAO {
db.delete(Sqlite.TABLE_CACHE_TAGS, null, null);
}
+
+ public void removeTag(String tag) {
+ db.delete(Sqlite.TABLE_CACHE_TAGS, Sqlite.COL_TAGS + " = ?", new String[]{tag});
+ }
+
/**
* Returns all tags in db
* @return string tags List
@@ -72,6 +90,18 @@ public class TagsCacheDAO {
}
}
+ /**
+ * Returns tags starting by "search"
+ * @return boolean present
+ */
+ public boolean isPresent(String search){
+ Cursor c = db.query(Sqlite.TABLE_CACHE_TAGS, null, Sqlite.COL_TAGS + " = \"" + search + "\"", null, null, null, null, null);
+ boolean isPresent = (c!= null && c.getCount() > 0);
+ assert c != null;
+ c.close();
+ return isPresent;
+ }
+
/**
* Returns tags starting by "search"
* @return tags List
diff --git a/app/src/main/res/drawable-anydpi/ic_save.xml b/app/src/main/res/drawable-anydpi/ic_save.xml
new file mode 100644
index 000000000..a561d632a
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_save.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_tag_cache.xml b/app/src/main/res/layout/activity_tag_cache.xml
new file mode 100644
index 000000000..01fc7dcad
--- /dev/null
+++ b/app/src/main/res/layout/activity_tag_cache.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/drawer_tag_edit.xml b/app/src/main/res/layout/drawer_tag_edit.xml
new file mode 100644
index 000000000..4020ada19
--- /dev/null
+++ b/app/src/main/res/layout/drawer_tag_edit.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/main_toot.xml b/app/src/main/res/menu/main_toot.xml
index c20fda7a4..4b889bcd8 100644
--- a/app/src/main/res/menu/main_toot.xml
+++ b/app/src/main/res/menu/main_toot.xml
@@ -41,4 +41,9 @@
android:title="@string/schedule"
android:icon="@drawable/ic_schedule"
app:showAsAction="never" />
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index de66370e5..0e30b64f0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -680,6 +680,11 @@
Truncate toots over \'x\' lines. Zero means disabled.
Display more
Display less
+ Manage tags
+ The tag already exists!
+ The tag has been stored!
+ The tag has been changed!
+ The tag has been deleted!
- Never