diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/ManageCachedStatusAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/ManageCachedStatusAsyncTask.java new file mode 100644 index 000000000..1d3fb72b1 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/ManageCachedStatusAsyncTask.java @@ -0,0 +1,63 @@ +/* Copyright 2019 Thomas Schneider + * + * This file is a part of Fedilab + * + * 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. + * + * Fedilab 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 Fedilab; if not, + * see . */ +package fr.gouv.etalab.mastodon.asynctasks; + +import android.content.Context; +import android.os.AsyncTask; + +import java.lang.ref.WeakReference; + +import fr.gouv.etalab.mastodon.client.API; +import fr.gouv.etalab.mastodon.client.APIResponse; +import fr.gouv.etalab.mastodon.interfaces.OnRefreshCachedStatusInterface; + +/** + * Created by Thomas on 12/05/2019. + * Manage refresh for statuses + */ + +public class ManageCachedStatusAsyncTask extends AsyncTask { + + private OnRefreshCachedStatusInterface listener; + private String statusId; + private fr.gouv.etalab.mastodon.client.Entities.Status refreshedStatus; + private WeakReference contextReference; + + + + + public ManageCachedStatusAsyncTask(Context context, String statusId, OnRefreshCachedStatusInterface onRefreshCachedStatusInterface){ + this.contextReference = new WeakReference<>(context); + this.listener = onRefreshCachedStatusInterface; + this.statusId = statusId; + + } + + @Override + protected Void doInBackground(Void... params) { + APIResponse apiResponse = new API(contextReference.get()).getStatusbyIdAndCache(statusId); + refreshedStatus = apiResponse.getStatuses().get(0); + if( refreshedStatus != null){ + refreshedStatus.setcached(true); + } + return null; + } + + @Override + protected void onPostExecute(Void result) { + listener.onRefresh(refreshedStatus); + } + +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java index 788e64c75..12862d8a8 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java @@ -786,6 +786,36 @@ public class API { return apiResponse; } + /** + * Retrieves one status *synchronously* + * + * @param statusId String Id of the status + * @return APIResponse + */ + public APIResponse getStatusbyIdAndCache(String statusId) { + statuses = new ArrayList<>(); + try { + HttpsConnection httpsConnection = new HttpsConnection(context); + String response = httpsConnection.get(getAbsoluteUrl(String.format("/statuses/%s", statusId)), 60, null, prefKeyOauthTokenT); + Status status = parseStatuses(context, new JSONObject(response)); + SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + new TimelineCacheDAO(context, db).update(status.getId(), response); + statuses.add(status); + } catch (HttpsConnection.HttpsConnectionException e) { + setError(e.getStatusCode(), e); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (KeyManagementException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + apiResponse.setStatuses(statuses); + return apiResponse; + } + /** * Retrieves the context of status with replies *synchronously* * @@ -2270,6 +2300,11 @@ public class API { b.putParcelable("status", status); Intent intentBC = new Intent(Helper.RECEIVE_ACTION); intentBC.putExtras(b); + SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + Status alreadyCached = new TimelineCacheDAO(context, db).getSingle(status.getId()); + if (alreadyCached != null) { + new TimelineCacheDAO(context, db).update(status.getId(), response); + } LocalBroadcastManager.getInstance(context).sendBroadcast(intentBC); return parsePoll(context, new JSONObject(response)); } catch (HttpsConnection.HttpsConnectionException e) { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java index 2c571fcf7..aaaa578e6 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/StatusListAdapter.java @@ -50,7 +50,6 @@ import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; import android.text.style.URLSpan; -import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.MenuItem; @@ -113,6 +112,7 @@ import fr.gouv.etalab.mastodon.activities.ShowAccountActivity; import fr.gouv.etalab.mastodon.activities.ShowConversationActivity; import fr.gouv.etalab.mastodon.activities.TootActivity; import fr.gouv.etalab.mastodon.activities.TootInfoActivity; +import fr.gouv.etalab.mastodon.asynctasks.ManageCachedStatusAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.ManagePollAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask; @@ -137,6 +137,7 @@ import fr.gouv.etalab.mastodon.helper.CustomTextView; import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.interfaces.OnPollInterface; import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface; +import fr.gouv.etalab.mastodon.interfaces.OnRefreshCachedStatusInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveCardInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveEmojiInterface; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveFeedsInterface; @@ -165,7 +166,7 @@ import static fr.gouv.etalab.mastodon.sqlite.Sqlite.DB_NAME; * Created by Thomas on 24/04/2017. * Adapter for Status */ -public class StatusListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveFeedsInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface, OnRetrieveCardInterface, OnPollInterface { +public class StatusListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveFeedsInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface, OnRetrieveCardInterface, OnPollInterface, OnRefreshCachedStatusInterface { private Context context; private List statuses; @@ -264,6 +265,11 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct notifyStatusChanged(status); } + @Override + public void onRefresh(Status refreshedStatus) { + statusListAdapter.notifyStatusWithActionChanged(refreshedStatus); + } + private class ViewHolderEmpty extends RecyclerView.ViewHolder{ ViewHolderEmpty(View itemView) { @@ -942,6 +948,13 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct }else{ holder.cached_status.setVisibility(View.GONE); } + holder.cached_status.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new ManageCachedStatusAsyncTask(context, status.getId(), StatusListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + }); + //Redraws top icons (boost/reply) final float scale = context.getResources().getDisplayMetrics().density; holder.spark_button_fav.pressOnTouch(false); @@ -3080,6 +3093,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct public void onRetrieveFeeds(APIResponse apiResponse) { if( apiResponse.getStatuses() != null && apiResponse.getStatuses().size() > 0){ + SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); long id = new StatusStoredDAO(context, db).insertStatus(toot, apiResponse.getStatuses().get(0)); Intent intentToot = new Intent(context, TootActivity.class); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRefreshCachedStatusInterface.java b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRefreshCachedStatusInterface.java new file mode 100644 index 000000000..8d8bb35e6 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRefreshCachedStatusInterface.java @@ -0,0 +1,25 @@ +/* Copyright 2019 Thomas Schneider + * + * This file is a part of Fedilab + * + * 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. + * + * Fedilab 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 Fedilab; if not, + * see . */ +package fr.gouv.etalab.mastodon.interfaces; + +import fr.gouv.etalab.mastodon.client.Entities.Status; + +/** + * Created by Thomas on 12/05/2019. + * Interface when refreshing status cache + */ +public interface OnRefreshCachedStatusInterface { + void onRefresh(Status refreshedStatus); +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TimelineCacheDAO.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TimelineCacheDAO.java index 4e0b947cb..47fd093eb 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TimelineCacheDAO.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TimelineCacheDAO.java @@ -73,6 +73,23 @@ public class TimelineCacheDAO { } return last_id; } + + //------- UPDATE ------- + /** + * Update a status in database + */ + public void update(String statusId, String jsonString) { + SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); + String instance = Helper.getLiveInstance(context); + ContentValues values = new ContentValues(); + values.put(Sqlite.COL_DATE, Helper.dateToString(new Date())); + values.put(Sqlite.COL_CACHE, jsonString); + try{ + db.update(Sqlite.TABLE_TIMELINE_CACHE, values, Sqlite.COL_INSTANCE + " = ? AND " + Sqlite.COL_STATUS_ID + " = ? AND " + Sqlite.COL_USER_ID + " = ?", new String[]{instance, statusId, userId}); + }catch (Exception ignored) {} + } + //------- REMOVE ------- /*** diff --git a/app/src/main/res/layout/drawer_status.xml b/app/src/main/res/layout/drawer_status.xml index 9b2d6d640..312f11ad6 100644 --- a/app/src/main/res/layout/drawer_status.xml +++ b/app/src/main/res/layout/drawer_status.xml @@ -181,6 +181,7 @@ android:layout_weight="1" android:layout_height="wrap_content">