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;
@SerializedName("pleroma")
public Pleroma pleroma;
@SerializedName("cached")
public boolean cached = false;
@Override
public boolean equals(@Nullable Object obj) {

View File

@ -194,8 +194,9 @@ public class StatusCache {
ContentValues values = new ContentValues();
values.put(Sqlite.COL_USER_ID, statusCache.user_id);
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_TYPE, statusCache.type.getValue());
values.put(Sqlite.COL_STATUS, mastodonStatusToStringStorage(statusCache.status));
values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(new Date()));
//Inserts token
@ -415,7 +416,6 @@ public class StatusCache {
/**
* Get statuses from db
*
* @param statusCache StatusCache - status in cache to compare
* @return Statuses
* @throws DBException - throws a db exception
*/

View File

@ -362,6 +362,8 @@ public class Timeline {
LOCAL("LOCAL"),
@SerializedName("PUBLIC")
PUBLIC("PUBLIC"),
@SerializedName("CONTEXT")
CONTEXT("CONTEXT"),
@SerializedName("TAG")
TAG("TAG"),
@SerializedName("ART")

View File

@ -22,8 +22,6 @@ import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;
import com.google.gson.annotations.SerializedName;
import java.io.IOException;
import java.util.ArrayList;
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.Notification;
import app.fedilab.android.client.entities.api.Status;
import app.fedilab.android.client.entities.app.Timeline;
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
import okhttp3.OkHttpClient;
import retrofit2.Call;
@ -64,10 +63,22 @@ public class TimelineHelper {
*
* @param context - Context
* @param statuses - List of {@link Status}
* @param filterTimeLineType - {@link FilterTimeLineType}
* @param filterTimeLineType - {@link Timeline.TimeLineEnum}
* @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
List<Status> statusesToRemove = new ArrayList<>();
if (!BaseMainActivity.filterFetched) {
@ -95,11 +106,12 @@ public class TimelineHelper {
continue;
}
for (String filterContext : filter.context) {
if (filterTimeLineType.value.equalsIgnoreCase(filterContext)) {
if (filterTimeLineType.getValue().equalsIgnoreCase(filterContext)) {
if (filter.whole_word) {
Pattern p = Pattern.compile("(^" + Pattern.quote(filter.phrase) + "\\b|\\b" + Pattern.quote(filter.phrase) + "$)");
for (Status status : statuses) {
String content;
status.cached = cached;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
content = Html.fromHtml(status.content, Html.FROM_HTML_MODE_LEGACY).toString();
else
@ -124,6 +136,7 @@ public class TimelineHelper {
} else {
for (Status status : statuses) {
String content;
status.cached = cached;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
content = Html.fromHtml(status.content, Html.FROM_HTML_MODE_LEGACY).toString();
else
@ -183,7 +196,7 @@ public class TimelineHelper {
continue;
}
for (String filterContext : filter.context) {
if (FilterTimeLineType.NOTIFICATION.value.equalsIgnoreCase(filterContext)) {
if (Timeline.TimeLineEnum.NOTIFICATION.getValue().equalsIgnoreCase(filterContext)) {
if (filter.whole_word) {
Pattern p = Pattern.compile("(^" + Pattern.quote(filter.phrase) + "\\b|\\b" + Pattern.quote(filter.phrase) + "$)");
for (Notification notification : notifications) {
@ -219,23 +232,4 @@ public class TimelineHelper {
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.actionButtonBookmark.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 {
holder.binding.actionButtonFavorite.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.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) {
holder.binding.statusPinned.setVisibility(View.VISIBLE);

View File

@ -574,9 +574,19 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
//Initialize with default params
TimelinesVM.TimelineParams timelineParams = new TimelinesVM.TimelineParams(timelineType, direction, ident);
timelineParams.limit = MastodonHelper.statusesPerCall(requireActivity());
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;
switch (timelineType) {
case LOCAL:
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.app.BaseAccount;
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.helper.Helper;
import app.fedilab.android.helper.MastodonHelper;
@ -352,8 +353,8 @@ public class StatusesVM extends AndroidViewModel {
if (contextResponse.isSuccessful()) {
context = contextResponse.body();
if (context != null) {
TimelineHelper.filterStatus(getApplication().getApplicationContext(), context.descendants, TimelineHelper.FilterTimeLineType.CONTEXT);
TimelineHelper.filterStatus(getApplication().getApplicationContext(), context.ancestors, TimelineHelper.FilterTimeLineType.CONTEXT);
TimelineHelper.filterStatus(getApplication().getApplicationContext(), context.descendants, Timeline.TimeLineEnum.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();
if (publicTlResponse.isSuccessful()) {
statusList = publicTlResponse.body();
statusList = statusList;
}
} catch (Exception e) {
e.printStackTrace();
@ -248,7 +247,7 @@ public class TimelinesVM extends AndroidViewModel {
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();
if (statusList.size() > 0) {
statuses.pagination.min_id = statusList.get(0).id;
@ -294,7 +293,7 @@ public class TimelinesVM extends AndroidViewModel {
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();
if (statusList.size() > 0) {
//These values are not used.
@ -371,8 +370,9 @@ public class TimelinesVM extends AndroidViewModel {
Response<List<Status>> timelineResponse = timelineCall.execute();
if (timelineResponse.isSuccessful()) {
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());
if (statusList != null && statusList.size() > 0) {
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);
@ -426,7 +426,7 @@ public class TimelinesVM extends AndroidViewModel {
try {
statuses = statusCacheDAO.geStatuses(timelineParams.slug, timelineParams.instance, timelineParams.userId, timelineParams.maxId, timelineParams.minId, timelineParams.sinceId);
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) {
statuses.pagination = new Pagination();
statuses.pagination.min_id = statuses.statuses.get(0).id;
@ -480,6 +480,23 @@ public class TimelinesVM extends AndroidViewModel {
}
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_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
android:layout_width="0dp"
android:layout_height="wrap_content"