This commit is contained in:
Thomas 2022-09-26 10:17:25 +02:00
parent 29b3107889
commit 70c581ba21
9 changed files with 78 additions and 37 deletions

View File

@ -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) {

View File

@ -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
*/ */

View File

@ -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")

View File

@ -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;
}
}
} }

View File

@ -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);

View File

@ -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;

View File

@ -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);
} }
} }

View File

@ -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";
}
} }

View File

@ -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"