Merge branch 'fix_cache_notification' into develop

This commit is contained in:
Thomas 2022-11-22 13:44:44 +01:00
commit 2d80e89982
6 changed files with 109 additions and 194 deletions

View File

@ -24,18 +24,13 @@ import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.client.entities.api.Conversation;
import app.fedilab.android.client.entities.api.Conversations;
import app.fedilab.android.client.entities.api.Notification;
import app.fedilab.android.client.entities.api.Notifications;
import app.fedilab.android.client.entities.api.Pagination;
import app.fedilab.android.client.entities.api.Status;
import app.fedilab.android.client.entities.api.Statuses;
import app.fedilab.android.exception.DBException;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.helper.MastodonHelper;
@ -247,7 +242,6 @@ public class StatusCache {
}
Cursor mCount = db.rawQuery("select count(*) from " + Sqlite.TABLE_STATUS_CACHE
+ " where " + Sqlite.COL_TYPE + " != '" + Timeline.TimeLineEnum.HOME.getValue() + "'"
+ " AND " + Sqlite.COL_INSTANCE + " = '" + baseAccount.instance + "'"
+ " AND " + Sqlite.COL_USER_ID + "= '" + baseAccount.user_id + "'", null);
mCount.moveToFirst();
int count = mCount.getInt(0);
@ -266,36 +260,21 @@ public class StatusCache {
if (db == null) {
throw new DBException("db is null. Wrong initialization.");
}
Cursor mCount = db.rawQuery("select count(*) from " + Sqlite.TABLE_STATUS_CACHE
String query = "select count(*) from " + Sqlite.TABLE_STATUS_CACHE
+ " where " + Sqlite.COL_STATUS_ID + " = '" + statusCache.status_id + "'"
+ " AND " + Sqlite.COL_INSTANCE + " = '" + statusCache.instance + "'"
+ " AND " + Sqlite.COL_USER_ID + "= '" + statusCache.user_id + "'", null);
+ " AND " + Sqlite.COL_USER_ID + "= '" + statusCache.user_id + "'";
if (statusCache.type != null) {
query += " AND " + Sqlite.COL_TYPE + " = '" + statusCache.type.getValue() + "'";
}
Cursor mCount = db.rawQuery(query, null);
mCount.moveToFirst();
int count = mCount.getInt(0);
mCount.close();
return (count > 0);
}
/**
* Check if a status exists in db
*
* @param status Status {@link Status}
* @return boolean - StatusCache exists
* @throws DBException Exception
*/
public boolean statusExist(Status status) throws DBException {
if (db == null) {
throw new DBException("db is null. Wrong initialization.");
}
Cursor mCount = db.rawQuery("select count(*) from " + Sqlite.TABLE_STATUS_CACHE
+ " where " + Sqlite.COL_STATUS_ID + " = '" + status.id + "'"
+ " AND " + Sqlite.COL_INSTANCE + " = '" + MainActivity.currentInstance + "'"
+ " AND " + Sqlite.COL_USER_ID + "= '" + MainActivity.currentUserID + "'", null);
mCount.moveToFirst();
int count = mCount.getInt(0);
mCount.close();
return (count > 0);
}
/**
* Insert a status in db
@ -313,7 +292,9 @@ public class StatusCache {
values.put(Sqlite.COL_INSTANCE, statusCache.instance);
values.put(Sqlite.COL_SLUG, slug);
values.put(Sqlite.COL_STATUS_ID, statusCache.status_id);
if (statusCache.type != null) {
values.put(Sqlite.COL_TYPE, statusCache.type.getValue());
}
if (statusCache.status != null) {
values.put(Sqlite.COL_STATUS, mastodonStatusToStringStorage(statusCache.status));
}
@ -345,8 +326,6 @@ public class StatusCache {
throw new DBException("db is null. Wrong initialization.");
}
ContentValues values = new ContentValues();
values.put(Sqlite.COL_USER_ID, statusCache.user_id);
values.put(Sqlite.COL_STATUS_ID, statusCache.status_id);
if (statusCache.status != null) {
values.put(Sqlite.COL_STATUS, mastodonStatusToStringStorage(statusCache.status));
}
@ -360,8 +339,8 @@ public class StatusCache {
//Inserts token
try {
return db.update(Sqlite.TABLE_STATUS_CACHE,
values, Sqlite.COL_STATUS_ID + " = ? AND " + Sqlite.COL_INSTANCE + " =?",
new String[]{statusCache.status_id, statusCache.instance});
values, Sqlite.COL_STATUS_ID + " = ? AND " + Sqlite.COL_INSTANCE + " =? AND " + Sqlite.COL_TYPE + " =? AND " + Sqlite.COL_USER_ID + " =?",
new String[]{statusCache.status_id, statusCache.instance, statusCache.type != null ? statusCache.type.getValue() : "", statusCache.user_id});
} catch (Exception e) {
e.printStackTrace();
return -1;
@ -485,8 +464,8 @@ public class StatusCache {
}
try {
return db.delete(Sqlite.TABLE_STATUS_CACHE,
Sqlite.COL_TYPE + " != ? AND " + Sqlite.COL_USER_ID + " = ? AND " + Sqlite.COL_INSTANCE + " =?",
new String[]{Timeline.TimeLineEnum.HOME.getValue(), account.user_id, account.instance});
Sqlite.COL_TYPE + " != ? AND " + Sqlite.COL_USER_ID + " = ?",
new String[]{Timeline.TimeLineEnum.HOME.getValue(), account.user_id});
} catch (Exception e) {
e.printStackTrace();
return -1;
@ -543,10 +522,10 @@ public class StatusCache {
* @param user_id String - us
* @param max_id String - status having max id
* @param min_id String - status having min id
* @return Statuses
* @return List<Notification>
* @throws DBException - throws a db exception
*/
public Notifications getNotifications(List<String> exclude_type, String instance, String user_id, String max_id, String min_id, String since_id) throws DBException {
public List<Notification> getNotifications(List<String> exclude_type, String instance, String user_id, String max_id, String min_id, String since_id) throws DBException {
if (db == null) {
throw new DBException("db is null. Wrong initialization.");
}
@ -572,8 +551,8 @@ public class StatusCache {
selection += "AND " + Sqlite.COL_SLUG + " NOT IN (" + exclude + ") ";
}
try {
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, Sqlite.COL_STATUS_ID, null, Sqlite.COL_STATUS_ID + order, limit);
return createNotificationReply(cursorToListOfNotifications(c));
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, Sqlite.COL_STATUS_ID, null, Sqlite.COL_STATUS_ID + " + 0 " + order, limit);
return cursorToListOfNotifications(c);
} catch (Exception e) {
e.printStackTrace();
return null;
@ -588,10 +567,10 @@ public class StatusCache {
* @param user_id String - us
* @param max_id String - status having max id
* @param min_id String - status having min id
* @return Statuses
* @return List<Conversation>
* @throws DBException - throws a db exception
*/
public Conversations getConversations(String instance, String user_id, String max_id, String min_id, String since_id) throws DBException {
public List<Conversation> getConversations(String instance, String user_id, String max_id, String min_id, String since_id) throws DBException {
if (db == null) {
throw new DBException("db is null. Wrong initialization.");
}
@ -607,10 +586,9 @@ public class StatusCache {
selection += "AND " + Sqlite.COL_STATUS_ID + " > '" + since_id + "' ";
limit = null;
}
try {
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, Sqlite.COL_STATUS_ID, null, Sqlite.COL_STATUS_ID + order, limit);
return createConversationReply(cursorToListOfConversations(c));
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, Sqlite.COL_STATUS_ID, null, Sqlite.COL_STATUS_ID + " + 0 " + order, limit);
return cursorToListOfConversations(c);
} catch (Exception e) {
e.printStackTrace();
return null;
@ -625,10 +603,10 @@ public class StatusCache {
* @param user_id String - us
* @param max_id String - status having max id
* @param min_id String - status having min id
* @return Statuses
* @return List<Status>
* @throws DBException - throws a db exception
*/
public Statuses geStatuses(String slug, String instance, String user_id, String max_id, String min_id, String since_id) throws DBException {
public List<Status> geStatuses(String slug, String instance, String user_id, String max_id, String min_id, String since_id) throws DBException {
if (db == null) {
throw new DBException("db is null. Wrong initialization.");
}
@ -645,8 +623,8 @@ public class StatusCache {
limit = null;
}
try {
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, Sqlite.COL_STATUS_ID, null, Sqlite.COL_STATUS_ID + order, limit);
return createStatusReply(cursorToListOfStatuses(c));
Cursor c = db.query(Sqlite.TABLE_STATUS_CACHE, null, selection, null, Sqlite.COL_STATUS_ID, null, Sqlite.COL_STATUS_ID + " + 0 " + order, limit);
return cursorToListOfStatuses(c);
} catch (Exception e) {
e.printStackTrace();
return null;
@ -769,75 +747,6 @@ public class StatusCache {
return conversationList;
}
/**
* Create a reply from db in the same way than API call
*
* @param notificationList List<Notification>
* @return Notifications (with pagination)
*/
private Notifications createNotificationReply(List<Notification> notificationList) {
Notifications notifications = new Notifications();
notifications.notifications = notificationList;
Pagination pagination = new Pagination();
if (notificationList != null && notificationList.size() > 0) {
//Status list is inverted, it happens for min_id due to ASC ordering
if (Helper.compareTo(notificationList.get(0).id, notificationList.get(notificationList.size() - 1).id) < 0) {
Collections.reverse(notificationList);
notifications.notifications = notificationList;
}
pagination.max_id = notificationList.get(0).id;
pagination.min_id = notificationList.get(notificationList.size() - 1).id;
}
notifications.pagination = pagination;
return notifications;
}
/**
* Create a reply from db in the same way than API call
*
* @param conversationList List<Conversation>
* @return Conversations (with pagination)
*/
private Conversations createConversationReply(List<Conversation> conversationList) {
Conversations conversations = new Conversations();
conversations.conversations = conversationList;
Pagination pagination = new Pagination();
if (conversationList != null && conversationList.size() > 0) {
//Status list is inverted, it happens for min_id due to ASC ordering
if (Helper.compareTo(conversationList.get(0).id, conversationList.get(conversationList.size() - 1).id) < 0) {
Collections.reverse(conversationList);
conversations.conversations = conversationList;
}
pagination.max_id = conversationList.get(0).id;
pagination.min_id = conversationList.get(conversationList.size() - 1).id;
}
conversations.pagination = pagination;
return conversations;
}
/**
* Create a reply from db in the same way than API call
*
* @param statusList List<Status>
* @return Statuses (with pagination)
*/
private Statuses createStatusReply(List<Status> statusList) {
Statuses statuses = new Statuses();
statuses.statuses = statusList;
Pagination pagination = new Pagination();
if (statusList != null && statusList.size() > 0) {
//Status list is inverted, it happens for min_id due to ASC ordering
if (Helper.compareTo(statusList.get(0).id, statusList.get(statusList.size() - 1).id) < 0) {
Collections.reverse(statusList);
statuses.statuses = statusList;
}
pagination.max_id = statusList.get(0).id;
pagination.min_id = statusList.get(statusList.size() - 1).id;
}
statuses.pagination = pagination;
return statuses;
}
/**
* Read cursor and hydrate without closing it

View File

@ -177,7 +177,6 @@ public class TimelineHelper {
public static List<Notification> filterNotification(Context context, List<Notification> notifications) {
//A security to make sure filters have been fetched before displaying messages
List<Notification> notificationToRemove = new ArrayList<>();
if (!BaseMainActivity.filterFetched) {
try {
FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class);

View File

@ -112,12 +112,11 @@ public class NotificationsVM extends AndroidViewModel {
if (notificationsResponse.isSuccessful()) {
List<Notification> notFiltered = notificationsResponse.body();
notifications.notifications = TimelineHelper.filterNotification(getApplication().getApplicationContext(), notFiltered);
addFetchMoreNotifications(notifications.notifications, notificationList, timelineParams);
notifications.pagination = MastodonHelper.getPagination(notificationsResponse.headers());
if (notifications.notifications != null && notifications.notifications.size() > 0) {
addFetchMoreNotifications(notifications.notifications, notificationList, timelineParams);
for (Notification notification : notifications.notifications) {
if (notFiltered != null && notFiltered.size() > 0) {
for (Notification notification : notFiltered) {
StatusCache statusCacheDAO = new StatusCache(getApplication().getApplicationContext());
StatusCache statusCache = new StatusCache();
statusCache.instance = timelineParams.instance;
@ -134,6 +133,7 @@ public class NotificationsVM extends AndroidViewModel {
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
@ -146,41 +146,39 @@ public class NotificationsVM extends AndroidViewModel {
return notificationsMutableLiveData;
}
public LiveData<Notifications> getNotificationCache(List<Notification> notificationList, TimelinesVM.TimelineParams timelineParams) {
public LiveData<Notifications> getNotificationCache(List<Notification> timelineNotification, TimelinesVM.TimelineParams timelineParams) {
notificationsMutableLiveData = new MutableLiveData<>();
new Thread(() -> {
StatusCache statusCacheDAO = new StatusCache(getApplication().getApplicationContext());
Notifications notifications = null;
Notifications notifications = new Notifications();
List<Notification> notificationsDb;
try {
notifications = statusCacheDAO.getNotifications(timelineParams.excludeType, timelineParams.instance, timelineParams.userId, timelineParams.maxId, timelineParams.minId, timelineParams.sinceId);
if (notifications != null) {
if (notifications.notifications != null && notifications.notifications.size() > 0) {
if (notificationList != null) {
notificationsDb = statusCacheDAO.getNotifications(timelineParams.excludeType, timelineParams.instance, timelineParams.userId, timelineParams.maxId, timelineParams.minId, timelineParams.sinceId);
if (notificationsDb != null && notificationsDb.size() > 0) {
if (timelineNotification != null) {
List<Notification> notPresentNotifications = new ArrayList<>();
for (Notification notification : notifications.notifications) {
if (!notificationList.contains(notification)) {
for (Notification notification : notificationsDb) {
if (!timelineNotification.contains(notification)) {
notification.cached = true;
notPresentNotifications.add(notification);
}
}
//Only not already present statuses are added
notifications.notifications = notPresentNotifications;
notificationsDb = notPresentNotifications;
}
TimelineHelper.filterNotification(getApplication().getApplicationContext(), notifications.notifications);
notifications.notifications = TimelineHelper.filterNotification(getApplication().getApplicationContext(), notificationsDb);
if (notifications.notifications.size() > 0) {
addFetchMoreNotifications(notifications.notifications, notificationList, timelineParams);
addFetchMoreNotifications(notifications.notifications, timelineNotification, timelineParams);
notifications.pagination = new Pagination();
notifications.pagination.min_id = notifications.notifications.get(0).id;
notifications.pagination.max_id = notifications.notifications.get(notifications.notifications.size() - 1).id;
}
}
}
} catch (DBException e) {
e.printStackTrace();
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Notifications finalNotifications = notifications;
Runnable myRunnable = () -> notificationsMutableLiveData.setValue(finalNotifications);
Runnable myRunnable = () -> notificationsMutableLiveData.setValue(notifications);
mainHandler.post(myRunnable);
}).start();
return notificationsMutableLiveData;

View File

@ -463,21 +463,21 @@ public class TimelinesVM extends AndroidViewModel {
StatusCache statusCacheDAO = new StatusCache(getApplication().getApplicationContext());
Statuses statuses = new Statuses();
try {
Statuses statusesDb = statusCacheDAO.geStatuses(timelineParams.slug, timelineParams.instance, timelineParams.userId, timelineParams.maxId, timelineParams.minId, timelineParams.sinceId);
if (statusesDb != null && statusesDb.statuses != null && statusesDb.statuses.size() > 0) {
List<Status> statusesDb = statusCacheDAO.geStatuses(timelineParams.slug, timelineParams.instance, timelineParams.userId, timelineParams.maxId, timelineParams.minId, timelineParams.sinceId);
if (statusesDb != null && statusesDb.size() > 0) {
if (timelineStatuses != null) {
List<Status> notPresentStatuses = new ArrayList<>();
for (Status status : statusesDb.statuses) {
for (Status status : statusesDb) {
if (!timelineStatuses.contains(status)) {
status.cached = true;
notPresentStatuses.add(status);
}
}
//Only not already present statuses are added
statusesDb.statuses = notPresentStatuses;
statusesDb = notPresentStatuses;
}
statuses.statuses = TimelineHelper.filterStatus(getApplication().getApplicationContext(), statusesDb.statuses, timelineParams.type);
if (statuses.statuses != null && statuses.statuses.size() > 0) {
statuses.statuses = TimelineHelper.filterStatus(getApplication().getApplicationContext(), statusesDb, timelineParams.type);
if (statuses.statuses.size() > 0) {
addFetchMore(statuses.statuses, timelineStatuses, timelineParams);
statuses.pagination = new Pagination();
statuses.pagination.min_id = statuses.statuses.get(0).id;
@ -528,21 +528,16 @@ public class TimelinesVM extends AndroidViewModel {
conversationListMutableLiveData = new MutableLiveData<>();
MastodonTimelinesService mastodonTimelinesService = init(timelineParams.instance);
new Thread(() -> {
Conversations conversations = null;
Conversations conversations = new Conversations();
Call<List<Conversation>> conversationsCall = mastodonTimelinesService.getConversations(timelineParams.token, timelineParams.maxId, timelineParams.sinceId, timelineParams.minId, timelineParams.limit);
if (conversationsCall != null) {
conversations = new Conversations();
try {
Response<List<Conversation>> conversationsResponse = conversationsCall.execute();
if (conversationsResponse.isSuccessful()) {
List<Conversation> conversationList = conversationsResponse.body();
conversations.conversations = conversationList;
conversations.conversations = conversationsResponse.body();
conversations.pagination = MastodonHelper.getPagination(conversationsResponse.headers());
if (conversationList != null && conversationList.size() > 0) {
addFetchMoreConversation(conversationList, conversationsTimeline, timelineParams);
if (conversations.conversations != null && conversations.conversations.size() > 0) {
addFetchMoreConversation(conversations.conversations, conversationsTimeline, timelineParams);
for (Conversation conversation : conversations.conversations) {
StatusCache statusCacheDAO = new StatusCache(getApplication().getApplicationContext());
StatusCache statusCache = new StatusCache();
@ -564,8 +559,7 @@ public class TimelinesVM extends AndroidViewModel {
}
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Conversations finalConversations = conversations;
Runnable myRunnable = () -> conversationListMutableLiveData.setValue(finalConversations);
Runnable myRunnable = () -> conversationListMutableLiveData.setValue(conversations);
mainHandler.post(myRunnable);
}).start();
@ -577,22 +571,22 @@ public class TimelinesVM extends AndroidViewModel {
conversationListMutableLiveData = new MutableLiveData<>();
new Thread(() -> {
StatusCache statusCacheDAO = new StatusCache(getApplication().getApplicationContext());
Conversations conversations = null;
Conversations conversations = new Conversations();
try {
conversations = statusCacheDAO.getConversations(timelineParams.instance, timelineParams.userId, timelineParams.maxId, timelineParams.minId, timelineParams.sinceId);
if (conversations != null) {
if (conversations.conversations != null && conversations.conversations.size() > 0) {
List<Conversation> conversationsDb = statusCacheDAO.getConversations(timelineParams.instance, timelineParams.userId, timelineParams.maxId, timelineParams.minId, timelineParams.sinceId);
if (conversationsDb != null && conversationsDb.size() > 0) {
if (timelineConversations != null) {
List<Conversation> notPresentConversations = new ArrayList<>();
for (Conversation conversation : conversations.conversations) {
for (Conversation conversation : conversationsDb) {
if (!timelineConversations.contains(conversation)) {
conversation.cached = true;
timelineConversations.add(conversation);
}
}
//Only not already present statuses are added
conversations.conversations = notPresentConversations;
conversationsDb = notPresentConversations;
}
conversations.conversations = conversationsDb;
if (conversations.conversations.size() > 0) {
addFetchMoreConversation(conversations.conversations, timelineConversations, timelineParams);
conversations.pagination = new Pagination();
@ -600,13 +594,11 @@ public class TimelinesVM extends AndroidViewModel {
conversations.pagination.max_id = conversations.conversations.get(conversations.conversations.size() - 1).id;
}
}
}
} catch (DBException e) {
e.printStackTrace();
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Conversations finalConversations = conversations;
Runnable myRunnable = () -> conversationListMutableLiveData.setValue(finalConversations);
Runnable myRunnable = () -> conversationListMutableLiveData.setValue(conversations);
mainHandler.post(myRunnable);
}).start();
return conversationListMutableLiveData;

View File

@ -71,6 +71,22 @@
app:iconTint="@color/cyanea_accent_dark_reference"
app:strokeColor="@color/cyanea_accent_dark_reference" />
<com.google.android.material.button.MaterialButton
android:id="@+id/domain_block"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:paddingVertical="12dp"
android:text="@string/blocked_domains"
android:textAlignment="textStart"
android:textColor="@color/cyanea_accent_dark_reference"
app:icon="@drawable/ic_baseline_navigate_next_24"
app:iconGravity="end"
app:iconTint="@color/cyanea_accent_dark_reference"
app:strokeColor="@color/cyanea_accent_dark_reference" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.fragment.app.FragmentContainerView

View File

@ -1906,4 +1906,5 @@
<string name="notif_signed_up">Signed up</string>
<string name="Suggestions">Suggestions</string>
<string name="not_interested">Not interested</string>
<string name="blocked_domains">Blocked domains</string>
</resources>