cache
This commit is contained in:
parent
29b3107889
commit
70c581ba21
|
@ -92,6 +92,8 @@ public class Status implements Serializable, Cloneable {
|
||||||
public Poll poll;
|
public Poll poll;
|
||||||
@SerializedName("pleroma")
|
@SerializedName("pleroma")
|
||||||
public Pleroma pleroma;
|
public Pleroma pleroma;
|
||||||
|
@SerializedName("cached")
|
||||||
|
public boolean cached = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(@Nullable Object obj) {
|
public boolean equals(@Nullable Object obj) {
|
||||||
|
|
|
@ -194,8 +194,9 @@ public class StatusCache {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(Sqlite.COL_USER_ID, statusCache.user_id);
|
values.put(Sqlite.COL_USER_ID, statusCache.user_id);
|
||||||
values.put(Sqlite.COL_INSTANCE, statusCache.instance);
|
values.put(Sqlite.COL_INSTANCE, statusCache.instance);
|
||||||
values.put(Sqlite.COL_SLUG, statusCache.slug);
|
values.put(Sqlite.COL_SLUG, slug);
|
||||||
values.put(Sqlite.COL_STATUS_ID, statusCache.status_id);
|
values.put(Sqlite.COL_STATUS_ID, statusCache.status_id);
|
||||||
|
values.put(Sqlite.COL_TYPE, statusCache.type.getValue());
|
||||||
values.put(Sqlite.COL_STATUS, mastodonStatusToStringStorage(statusCache.status));
|
values.put(Sqlite.COL_STATUS, mastodonStatusToStringStorage(statusCache.status));
|
||||||
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(new Date()));
|
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(new Date()));
|
||||||
//Inserts token
|
//Inserts token
|
||||||
|
@ -415,7 +416,6 @@ public class StatusCache {
|
||||||
/**
|
/**
|
||||||
* Get statuses from db
|
* Get statuses from db
|
||||||
*
|
*
|
||||||
* @param statusCache StatusCache - status in cache to compare
|
|
||||||
* @return Statuses
|
* @return Statuses
|
||||||
* @throws DBException - throws a db exception
|
* @throws DBException - throws a db exception
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -362,6 +362,8 @@ public class Timeline {
|
||||||
LOCAL("LOCAL"),
|
LOCAL("LOCAL"),
|
||||||
@SerializedName("PUBLIC")
|
@SerializedName("PUBLIC")
|
||||||
PUBLIC("PUBLIC"),
|
PUBLIC("PUBLIC"),
|
||||||
|
@SerializedName("CONTEXT")
|
||||||
|
CONTEXT("CONTEXT"),
|
||||||
@SerializedName("TAG")
|
@SerializedName("TAG")
|
||||||
TAG("TAG"),
|
TAG("TAG"),
|
||||||
@SerializedName("ART")
|
@SerializedName("ART")
|
||||||
|
|
|
@ -22,8 +22,6 @@ import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.lifecycle.ViewModelStoreOwner;
|
import androidx.lifecycle.ViewModelStoreOwner;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -36,6 +34,7 @@ import app.fedilab.android.client.endpoints.MastodonAccountsService;
|
||||||
import app.fedilab.android.client.entities.api.Filter;
|
import app.fedilab.android.client.entities.api.Filter;
|
||||||
import app.fedilab.android.client.entities.api.Notification;
|
import app.fedilab.android.client.entities.api.Notification;
|
||||||
import app.fedilab.android.client.entities.api.Status;
|
import app.fedilab.android.client.entities.api.Status;
|
||||||
|
import app.fedilab.android.client.entities.app.Timeline;
|
||||||
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
|
@ -64,10 +63,22 @@ public class TimelineHelper {
|
||||||
*
|
*
|
||||||
* @param context - Context
|
* @param context - Context
|
||||||
* @param statuses - List of {@link Status}
|
* @param statuses - List of {@link Status}
|
||||||
* @param filterTimeLineType - {@link FilterTimeLineType}
|
* @param filterTimeLineType - {@link Timeline.TimeLineEnum}
|
||||||
* @return filtered List<Status>
|
* @return filtered List<Status>
|
||||||
*/
|
*/
|
||||||
public static List<Status> filterStatus(Context context, List<Status> statuses, FilterTimeLineType filterTimeLineType) {
|
public static List<Status> filterStatus(Context context, List<Status> statuses, Timeline.TimeLineEnum filterTimeLineType) {
|
||||||
|
return filterStatus(context, statuses, filterTimeLineType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to filter statuses, should be called in API calls (background)
|
||||||
|
*
|
||||||
|
* @param context - Context
|
||||||
|
* @param statuses - List of {@link Status}
|
||||||
|
* @param filterTimeLineType - {@link Timeline.TimeLineEnum}
|
||||||
|
* @return filtered List<Status>
|
||||||
|
*/
|
||||||
|
public static List<Status> filterStatus(Context context, List<Status> statuses, Timeline.TimeLineEnum filterTimeLineType, boolean cached) {
|
||||||
//A security to make sure filters have been fetched before displaying messages
|
//A security to make sure filters have been fetched before displaying messages
|
||||||
List<Status> statusesToRemove = new ArrayList<>();
|
List<Status> statusesToRemove = new ArrayList<>();
|
||||||
if (!BaseMainActivity.filterFetched) {
|
if (!BaseMainActivity.filterFetched) {
|
||||||
|
@ -95,11 +106,12 @@ public class TimelineHelper {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (String filterContext : filter.context) {
|
for (String filterContext : filter.context) {
|
||||||
if (filterTimeLineType.value.equalsIgnoreCase(filterContext)) {
|
if (filterTimeLineType.getValue().equalsIgnoreCase(filterContext)) {
|
||||||
if (filter.whole_word) {
|
if (filter.whole_word) {
|
||||||
Pattern p = Pattern.compile("(^" + Pattern.quote(filter.phrase) + "\\b|\\b" + Pattern.quote(filter.phrase) + "$)");
|
Pattern p = Pattern.compile("(^" + Pattern.quote(filter.phrase) + "\\b|\\b" + Pattern.quote(filter.phrase) + "$)");
|
||||||
for (Status status : statuses) {
|
for (Status status : statuses) {
|
||||||
String content;
|
String content;
|
||||||
|
status.cached = cached;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
content = Html.fromHtml(status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
content = Html.fromHtml(status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
else
|
else
|
||||||
|
@ -124,6 +136,7 @@ public class TimelineHelper {
|
||||||
} else {
|
} else {
|
||||||
for (Status status : statuses) {
|
for (Status status : statuses) {
|
||||||
String content;
|
String content;
|
||||||
|
status.cached = cached;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
content = Html.fromHtml(status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
content = Html.fromHtml(status.content, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||||
else
|
else
|
||||||
|
@ -183,7 +196,7 @@ public class TimelineHelper {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (String filterContext : filter.context) {
|
for (String filterContext : filter.context) {
|
||||||
if (FilterTimeLineType.NOTIFICATION.value.equalsIgnoreCase(filterContext)) {
|
if (Timeline.TimeLineEnum.NOTIFICATION.getValue().equalsIgnoreCase(filterContext)) {
|
||||||
if (filter.whole_word) {
|
if (filter.whole_word) {
|
||||||
Pattern p = Pattern.compile("(^" + Pattern.quote(filter.phrase) + "\\b|\\b" + Pattern.quote(filter.phrase) + "$)");
|
Pattern p = Pattern.compile("(^" + Pattern.quote(filter.phrase) + "\\b|\\b" + Pattern.quote(filter.phrase) + "$)");
|
||||||
for (Notification notification : notifications) {
|
for (Notification notification : notifications) {
|
||||||
|
@ -219,23 +232,4 @@ public class TimelineHelper {
|
||||||
return notifications;
|
return notifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FilterTimeLineType {
|
|
||||||
@SerializedName("HOME")
|
|
||||||
HOME("HOME"),
|
|
||||||
@SerializedName("PUBLIC")
|
|
||||||
PUBLIC("PUBLIC"),
|
|
||||||
@SerializedName("CONTEXT")
|
|
||||||
CONTEXT("CONTEXT"),
|
|
||||||
@SerializedName("NOTIFICATION")
|
|
||||||
NOTIFICATION("NOTIFICATION");
|
|
||||||
private final String value;
|
|
||||||
|
|
||||||
FilterTimeLineType(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -495,7 +495,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||||
holder.binding.actionButtonFavorite.setInActiveImageTintColor(theme_icons_color);
|
holder.binding.actionButtonFavorite.setInActiveImageTintColor(theme_icons_color);
|
||||||
holder.binding.actionButtonBookmark.setInActiveImageTintColor(theme_icons_color);
|
holder.binding.actionButtonBookmark.setInActiveImageTintColor(theme_icons_color);
|
||||||
holder.binding.actionButtonBoost.setInActiveImageTintColor(theme_icons_color);
|
holder.binding.actionButtonBoost.setInActiveImageTintColor(theme_icons_color);
|
||||||
holder.binding.replyCount.setTextColor(theme_text_color);
|
Helper.changeDrawableColor(context, R.drawable.ic_baseline_cached_24, theme_icons_color);
|
||||||
|
holder.binding.replyCount.setTextColor(theme_icons_color);
|
||||||
} else {
|
} else {
|
||||||
holder.binding.actionButtonFavorite.setInActiveImageTintColor(ThemeHelper.getAttColor(context, R.attr.colorControlNormal));
|
holder.binding.actionButtonFavorite.setInActiveImageTintColor(ThemeHelper.getAttColor(context, R.attr.colorControlNormal));
|
||||||
holder.binding.actionButtonBookmark.setInActiveImageTintColor(ThemeHelper.getAttColor(context, R.attr.colorControlNormal));
|
holder.binding.actionButtonBookmark.setInActiveImageTintColor(ThemeHelper.getAttColor(context, R.attr.colorControlNormal));
|
||||||
|
@ -515,6 +516,12 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||||
holder.binding.actionButtonBoost.setActiveImageTint(R.color.boost_icon);
|
holder.binding.actionButtonBoost.setActiveImageTint(R.color.boost_icon);
|
||||||
holder.binding.actionButtonBookmark.setActiveImageTint(R.color.marked_icon);
|
holder.binding.actionButtonBookmark.setActiveImageTint(R.color.marked_icon);
|
||||||
|
|
||||||
|
if (status.cached) {
|
||||||
|
holder.binding.cacheIndicator.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
holder.binding.cacheIndicator.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (status.pinned) {
|
if (status.pinned) {
|
||||||
holder.binding.statusPinned.setVisibility(View.VISIBLE);
|
holder.binding.statusPinned.setVisibility(View.VISIBLE);
|
||||||
|
|
|
@ -574,9 +574,19 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
//Initialize with default params
|
//Initialize with default params
|
||||||
TimelinesVM.TimelineParams timelineParams = new TimelinesVM.TimelineParams(timelineType, direction, ident);
|
TimelinesVM.TimelineParams timelineParams = new TimelinesVM.TimelineParams(timelineType, direction, ident);
|
||||||
timelineParams.limit = MastodonHelper.statusesPerCall(requireActivity());
|
timelineParams.limit = MastodonHelper.statusesPerCall(requireActivity());
|
||||||
timelineParams.maxId = fetchingMissing ? max_id_fetch_more : max_id;
|
|
||||||
timelineParams.minId = fetchingMissing ? min_id_fetch_more : min_id;
|
if (direction == DIRECTION.REFRESH || direction == DIRECTION.SCROLL_TOP) {
|
||||||
|
timelineParams.maxId = null;
|
||||||
|
timelineParams.minId = null;
|
||||||
|
} else if (direction == DIRECTION.BOTTOM) {
|
||||||
|
timelineParams.maxId = fetchingMissing ? max_id_fetch_more : max_id;
|
||||||
|
timelineParams.minId = null;
|
||||||
|
} else {
|
||||||
|
timelineParams.minId = fetchingMissing ? min_id_fetch_more : min_id;
|
||||||
|
timelineParams.maxId = null;
|
||||||
|
}
|
||||||
timelineParams.fetchingMissing = fetchingMissing;
|
timelineParams.fetchingMissing = fetchingMissing;
|
||||||
|
|
||||||
switch (timelineType) {
|
switch (timelineType) {
|
||||||
case LOCAL:
|
case LOCAL:
|
||||||
timelineParams.local = true;
|
timelineParams.local = true;
|
||||||
|
|
|
@ -43,6 +43,7 @@ import app.fedilab.android.client.entities.api.ScheduledStatuses;
|
||||||
import app.fedilab.android.client.entities.api.Status;
|
import app.fedilab.android.client.entities.api.Status;
|
||||||
import app.fedilab.android.client.entities.app.BaseAccount;
|
import app.fedilab.android.client.entities.app.BaseAccount;
|
||||||
import app.fedilab.android.client.entities.app.StatusCache;
|
import app.fedilab.android.client.entities.app.StatusCache;
|
||||||
|
import app.fedilab.android.client.entities.app.Timeline;
|
||||||
import app.fedilab.android.exception.DBException;
|
import app.fedilab.android.exception.DBException;
|
||||||
import app.fedilab.android.helper.Helper;
|
import app.fedilab.android.helper.Helper;
|
||||||
import app.fedilab.android.helper.MastodonHelper;
|
import app.fedilab.android.helper.MastodonHelper;
|
||||||
|
@ -352,8 +353,8 @@ public class StatusesVM extends AndroidViewModel {
|
||||||
if (contextResponse.isSuccessful()) {
|
if (contextResponse.isSuccessful()) {
|
||||||
context = contextResponse.body();
|
context = contextResponse.body();
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
TimelineHelper.filterStatus(getApplication().getApplicationContext(), context.descendants, TimelineHelper.FilterTimeLineType.CONTEXT);
|
TimelineHelper.filterStatus(getApplication().getApplicationContext(), context.descendants, Timeline.TimeLineEnum.CONTEXT);
|
||||||
TimelineHelper.filterStatus(getApplication().getApplicationContext(), context.ancestors, TimelineHelper.FilterTimeLineType.CONTEXT);
|
TimelineHelper.filterStatus(getApplication().getApplicationContext(), context.ancestors, Timeline.TimeLineEnum.CONTEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,6 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
Response<List<Status>> publicTlResponse = publicTlCall.execute();
|
Response<List<Status>> publicTlResponse = publicTlCall.execute();
|
||||||
if (publicTlResponse.isSuccessful()) {
|
if (publicTlResponse.isSuccessful()) {
|
||||||
statusList = publicTlResponse.body();
|
statusList = publicTlResponse.body();
|
||||||
statusList = statusList;
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -248,7 +247,7 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
statusList.add(status);
|
statusList.add(status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statuses.statuses = TimelineHelper.filterStatus(getApplication(), statusList, TimelineHelper.FilterTimeLineType.PUBLIC);
|
statuses.statuses = TimelineHelper.filterStatus(getApplication(), statusList, Timeline.TimeLineEnum.PUBLIC);
|
||||||
statuses.pagination = new Pagination();
|
statuses.pagination = new Pagination();
|
||||||
if (statusList.size() > 0) {
|
if (statusList.size() > 0) {
|
||||||
statuses.pagination.min_id = statusList.get(0).id;
|
statuses.pagination.min_id = statusList.get(0).id;
|
||||||
|
@ -294,7 +293,7 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
statusList.add(status);
|
statusList.add(status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statuses.statuses = TimelineHelper.filterStatus(getApplication(), statusList, TimelineHelper.FilterTimeLineType.PUBLIC);
|
statuses.statuses = TimelineHelper.filterStatus(getApplication(), statusList, Timeline.TimeLineEnum.PUBLIC);
|
||||||
statuses.pagination = new Pagination();
|
statuses.pagination = new Pagination();
|
||||||
if (statusList.size() > 0) {
|
if (statusList.size() > 0) {
|
||||||
//These values are not used.
|
//These values are not used.
|
||||||
|
@ -371,8 +370,9 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
Response<List<Status>> timelineResponse = timelineCall.execute();
|
Response<List<Status>> timelineResponse = timelineCall.execute();
|
||||||
if (timelineResponse.isSuccessful()) {
|
if (timelineResponse.isSuccessful()) {
|
||||||
List<Status> statusList = timelineResponse.body();
|
List<Status> statusList = timelineResponse.body();
|
||||||
statuses.statuses = TimelineHelper.filterStatus(getApplication().getApplicationContext(), statusList, TimelineHelper.FilterTimeLineType.PUBLIC);
|
statuses.statuses = TimelineHelper.filterStatus(getApplication().getApplicationContext(), statusList, timelineParams.type);
|
||||||
statuses.pagination = MastodonHelper.getPagination(timelineResponse.headers());
|
statuses.pagination = MastodonHelper.getPagination(timelineResponse.headers());
|
||||||
|
|
||||||
if (statusList != null && statusList.size() > 0) {
|
if (statusList != null && statusList.size() > 0) {
|
||||||
if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.REFRESH || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.SCROLL_TOP) {
|
if (timelineParams.direction == FragmentMastodonTimeline.DIRECTION.REFRESH || timelineParams.direction == FragmentMastodonTimeline.DIRECTION.SCROLL_TOP) {
|
||||||
Status newestStatus = new StatusCache(getApplication().getApplicationContext()).getNewestStatus(timelineParams.slug, timelineParams.instance, timelineParams.userId);
|
Status newestStatus = new StatusCache(getApplication().getApplicationContext()).getNewestStatus(timelineParams.slug, timelineParams.instance, timelineParams.userId);
|
||||||
|
@ -426,7 +426,7 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
try {
|
try {
|
||||||
statuses = statusCacheDAO.geStatuses(timelineParams.slug, timelineParams.instance, timelineParams.userId, timelineParams.maxId, timelineParams.minId, timelineParams.sinceId);
|
statuses = statusCacheDAO.geStatuses(timelineParams.slug, timelineParams.instance, timelineParams.userId, timelineParams.maxId, timelineParams.minId, timelineParams.sinceId);
|
||||||
if (statuses != null) {
|
if (statuses != null) {
|
||||||
TimelineHelper.filterStatus(getApplication().getApplicationContext(), statuses.statuses, TimelineHelper.FilterTimeLineType.HOME);
|
TimelineHelper.filterStatus(getApplication().getApplicationContext(), statuses.statuses, timelineParams.type, true);
|
||||||
if (statuses.statuses != null && statuses.statuses.size() > 0) {
|
if (statuses.statuses != null && statuses.statuses.size() > 0) {
|
||||||
statuses.pagination = new Pagination();
|
statuses.pagination = new Pagination();
|
||||||
statuses.pagination.min_id = statuses.statuses.get(0).id;
|
statuses.pagination.min_id = statuses.statuses.get(0).id;
|
||||||
|
@ -480,6 +480,23 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
}
|
}
|
||||||
slug = key;
|
slug = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "direction: " + direction + "\n" +
|
||||||
|
"instance: " + instance + "\n" +
|
||||||
|
"token: " + token + "\n" +
|
||||||
|
"type: " + type + "\n" +
|
||||||
|
"slug: " + slug + "\n" +
|
||||||
|
"userId: " + userId + "\n" +
|
||||||
|
"remote: " + remote + "\n" +
|
||||||
|
"onlyMedia: " + onlyMedia + "\n" +
|
||||||
|
"local: " + local + "\n" +
|
||||||
|
"maxId: " + maxId + "\n" +
|
||||||
|
"sinceId: " + sinceId + "\n" +
|
||||||
|
"minId: " + minId + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -594,6 +594,14 @@
|
||||||
app:sparkbutton_primaryColor="@color/marked_icon"
|
app:sparkbutton_primaryColor="@color/marked_icon"
|
||||||
app:sparkbutton_secondaryColor="@color/marked_icon" />
|
app:sparkbutton_secondaryColor="@color/marked_icon" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/cache_indicator"
|
||||||
|
android:layout_width="28dp"
|
||||||
|
android:layout_height="28dp"
|
||||||
|
android:src="@drawable/ic_baseline_cached_24"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
Loading…
Reference in New Issue