forked from mirrors/Fedilab
Fix issue #472 - Allow to browse Mastodon instances before registering
This commit is contained in:
parent
5b164d60da
commit
2593d08d20
8 changed files with 68 additions and 38 deletions
|
@ -55,7 +55,10 @@ public interface MastodonTimelinesService {
|
||||||
|
|
||||||
|
|
||||||
@GET("trends/statuses")
|
@GET("trends/statuses")
|
||||||
Call<List<Status>> getStatusTrends(@Header("Authorization") String token);
|
Call<List<Status>> getStatusTrends(
|
||||||
|
@Header("Authorization") String token,
|
||||||
|
@Query("offset") String offset,
|
||||||
|
@Query("limit") Integer limit);
|
||||||
|
|
||||||
|
|
||||||
@GET("trends/tags")
|
@GET("trends/tags")
|
||||||
|
|
|
@ -379,7 +379,7 @@ public class Timeline {
|
||||||
@SerializedName("TREND_MESSAGE")
|
@SerializedName("TREND_MESSAGE")
|
||||||
TREND_MESSAGE("TREND_MESSAGE"),
|
TREND_MESSAGE("TREND_MESSAGE"),
|
||||||
@SerializedName("PUBLIC_TREND_MESSAGE")
|
@SerializedName("PUBLIC_TREND_MESSAGE")
|
||||||
PUBLIC_TREND_MESSAGE("PUBLIC_TREND_MESSAGE"),
|
TREND_MESSAGE_PUBLIC("TREND_MESSAGE_PUBLIC"),
|
||||||
@SerializedName("STATUS_HISTORY")
|
@SerializedName("STATUS_HISTORY")
|
||||||
STATUS_HISTORY("STATUS_HISTORY"),
|
STATUS_HISTORY("STATUS_HISTORY"),
|
||||||
@SerializedName("ACCOUNT_TIMELINE")
|
@SerializedName("ACCOUNT_TIMELINE")
|
||||||
|
@ -394,6 +394,8 @@ public class Timeline {
|
||||||
FAVOURITE_TIMELINE("FAVOURITE_TIMELINE"),
|
FAVOURITE_TIMELINE("FAVOURITE_TIMELINE"),
|
||||||
@SerializedName("REBLOG_TIMELINE")
|
@SerializedName("REBLOG_TIMELINE")
|
||||||
REBLOG_TIMELINE("REBLOG_TIMELINE"),
|
REBLOG_TIMELINE("REBLOG_TIMELINE"),
|
||||||
|
@SerializedName("STATUS_REPORT")
|
||||||
|
STATUS_REPORT("STATUS_REPORT"),
|
||||||
@SerializedName("SCHEDULED_TOOT_SERVER")
|
@SerializedName("SCHEDULED_TOOT_SERVER")
|
||||||
SCHEDULED_TOOT_SERVER("SCHEDULED_TOOT_SERVER"),
|
SCHEDULED_TOOT_SERVER("SCHEDULED_TOOT_SERVER"),
|
||||||
@SerializedName("SCHEDULED_TOOT_CLIENT")
|
@SerializedName("SCHEDULED_TOOT_CLIENT")
|
||||||
|
|
|
@ -147,6 +147,26 @@ public class MastodonHelper {
|
||||||
return pagination;
|
return pagination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve pagination from header
|
||||||
|
*
|
||||||
|
* @param headers Headers
|
||||||
|
* @return Pagination
|
||||||
|
*/
|
||||||
|
public static Pagination getOffSetPagination(Headers headers) {
|
||||||
|
String link = headers.get("Link");
|
||||||
|
Pagination pagination = new Pagination();
|
||||||
|
if (link != null) {
|
||||||
|
Pattern patternMaxId = Pattern.compile("offset=([0-9a-zA-Z]+)\\s?>\\s?;\\s?rel=\"next\"");
|
||||||
|
Matcher matcherMaxId = patternMaxId.matcher(link);
|
||||||
|
if (matcherMaxId.find()) {
|
||||||
|
pagination.max_id = matcherMaxId.group(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pagination;
|
||||||
|
}
|
||||||
|
|
||||||
/*public static Pagination getPaginationNotification(List<Notification> notificationList) {
|
/*public static Pagination getPaginationNotification(List<Notification> notificationList) {
|
||||||
Pagination pagination = new Pagination();
|
Pagination pagination = new Pagination();
|
||||||
if (notificationList == null || notificationList.size() == 0) {
|
if (notificationList == null || notificationList.size() == 0) {
|
||||||
|
|
|
@ -641,7 +641,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
||||||
} else {
|
} else {
|
||||||
holder.binding.card.setVisibility(View.GONE);
|
holder.binding.card.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
if (!canBeFederated) {
|
if (!canBeFederated && timelineType != Timeline.TimeLineEnum.TREND_MESSAGE_PUBLIC) {
|
||||||
holder.binding.actionShareContainer.setVisibility(View.VISIBLE);
|
holder.binding.actionShareContainer.setVisibility(View.VISIBLE);
|
||||||
holder.binding.actionShare.setOnClickListener(v -> {
|
holder.binding.actionShare.setOnClickListener(v -> {
|
||||||
Intent sendIntent = new Intent(Intent.ACTION_SEND);
|
Intent sendIntent = new Intent(Intent.ACTION_SEND);
|
||||||
|
|
|
@ -140,9 +140,8 @@ public class FragmentLoginPickInstanceMastodon extends Fragment implements Insta
|
||||||
if (joinMastodonInstanceList != null) {
|
if (joinMastodonInstanceList != null) {
|
||||||
JoinMastodonInstance clickedInstance = joinMastodonInstanceList.get(position);
|
JoinMastodonInstance clickedInstance = joinMastodonInstanceList.get(position);
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putBoolean(Helper.ARG_MINIFIED, true);
|
|
||||||
args.putSerializable(Helper.ARG_REMOTE_INSTANCE_STRING, clickedInstance.domain);
|
args.putSerializable(Helper.ARG_REMOTE_INSTANCE_STRING, clickedInstance.domain);
|
||||||
args.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TREND_MESSAGE);
|
args.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TREND_MESSAGE_PUBLIC);
|
||||||
|
|
||||||
Helper.addFragment(
|
Helper.addFragment(
|
||||||
getParentFragmentManager(), android.R.id.content, new FragmentMastodonTimeline(),
|
getParentFragmentManager(), android.R.id.content, new FragmentMastodonTimeline(),
|
||||||
|
|
|
@ -299,6 +299,9 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
canBeFederated = false;
|
canBeFederated = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (timelineType == Timeline.TimeLineEnum.TREND_MESSAGE_PUBLIC) {
|
||||||
|
canBeFederated = false;
|
||||||
|
}
|
||||||
publicTrendsDomain = getArguments().getString(Helper.ARG_REMOTE_INSTANCE_STRING, null);
|
publicTrendsDomain = getArguments().getString(Helper.ARG_REMOTE_INSTANCE_STRING, null);
|
||||||
isViewInitialized = getArguments().getBoolean(Helper.ARG_INITIALIZE_VIEW, true);
|
isViewInitialized = getArguments().getBoolean(Helper.ARG_INITIALIZE_VIEW, true);
|
||||||
tagTimeline = (TagTimeline) getArguments().getSerializable(Helper.ARG_TAG_TIMELINE);
|
tagTimeline = (TagTimeline) getArguments().getSerializable(Helper.ARG_TAG_TIMELINE);
|
||||||
|
@ -360,7 +363,6 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
binding.loadingNextElements.setVisibility(View.GONE);
|
binding.loadingNextElements.setVisibility(View.GONE);
|
||||||
flagLoading = false;
|
flagLoading = false;
|
||||||
|
|
||||||
|
|
||||||
if (timelineStatuses != null && fetched_statuses != null && fetched_statuses.statuses != null && fetched_statuses.statuses.size() > 0) {
|
if (timelineStatuses != null && fetched_statuses != null && fetched_statuses.statuses != null && fetched_statuses.statuses.size() > 0) {
|
||||||
try {
|
try {
|
||||||
if (statusToUpdate != null) {
|
if (statusToUpdate != null) {
|
||||||
|
@ -407,7 +409,15 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Update the timeline with new statuses
|
//Update the timeline with new statuses
|
||||||
int insertedStatus = updateStatusListWith(fetched_statuses.statuses);
|
int insertedStatus;
|
||||||
|
if (timelineType != Timeline.TimeLineEnum.TREND_MESSAGE_PUBLIC && timelineType != Timeline.TimeLineEnum.TREND_MESSAGE) {
|
||||||
|
insertedStatus = updateStatusListWith(fetched_statuses.statuses);
|
||||||
|
} else { //Trends cannot be ordered by id
|
||||||
|
insertedStatus = fetched_statuses.statuses.size();
|
||||||
|
int fromPosition = timelineStatuses.size();
|
||||||
|
timelineStatuses.addAll(fetched_statuses.statuses);
|
||||||
|
statusAdapter.notifyItemRangeInserted(fromPosition, insertedStatus);
|
||||||
|
}
|
||||||
//For these directions, the app will display counters for new messages
|
//For these directions, the app will display counters for new messages
|
||||||
if (insertedStatus >= 0 && update != null && direction != DIRECTION.FETCH_NEW && !fetchingMissing) {
|
if (insertedStatus >= 0 && update != null && direction != DIRECTION.FETCH_NEW && !fetchingMissing) {
|
||||||
update.onUpdate(insertedStatus, timelineType, slug);
|
update.onUpdate(insertedStatus, timelineType, slug);
|
||||||
|
@ -420,7 +430,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
if (!fetchingMissing) {
|
if (!fetchingMissing) {
|
||||||
if (fetched_statuses.pagination.max_id == null) {
|
if (fetched_statuses.pagination.max_id == null) {
|
||||||
flagLoading = true;
|
flagLoading = true;
|
||||||
} else if (max_id == null || Helper.compareTo(fetched_statuses.pagination.max_id, max_id) < 0) {
|
} else if (max_id == null || Helper.compareTo(fetched_statuses.pagination.max_id, max_id) < 0 || timelineType.getValue().startsWith("TREND_")) {
|
||||||
max_id = fetched_statuses.pagination.max_id;
|
max_id = fetched_statuses.pagination.max_id;
|
||||||
}
|
}
|
||||||
if (min_id == null || (fetched_statuses.pagination.min_id != null && Helper.compareTo(fetched_statuses.pagination.min_id, min_id) > 0)) {
|
if (min_id == null || (fetched_statuses.pagination.min_id != null && Helper.compareTo(fetched_statuses.pagination.min_id, min_id) > 0)) {
|
||||||
|
@ -501,7 +511,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
timelineStatuses.add(statusReport);
|
timelineStatuses.add(statusReport);
|
||||||
}
|
}
|
||||||
timelineStatuses.addAll(statuses.statuses);
|
timelineStatuses.addAll(statuses.statuses);
|
||||||
if (max_id == null || (statuses.pagination.max_id != null && Helper.compareTo(statuses.pagination.max_id, max_id) < 0)) {
|
if (max_id == null || (statuses.pagination.max_id != null && Helper.compareTo(statuses.pagination.max_id, max_id) < 0) || timelineType.getValue().startsWith("TREND_")) {
|
||||||
max_id = statuses.pagination.max_id;
|
max_id = statuses.pagination.max_id;
|
||||||
}
|
}
|
||||||
if (min_id == null || (statuses.pagination.min_id != null && Helper.compareTo(statuses.pagination.min_id, min_id) > 0)) {
|
if (min_id == null || (statuses.pagination.min_id != null && Helper.compareTo(statuses.pagination.min_id, min_id) > 0)) {
|
||||||
|
@ -977,29 +987,23 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
||||||
}
|
}
|
||||||
} else if (timelineType == Timeline.TimeLineEnum.TREND_MESSAGE) {
|
} else if (timelineType == Timeline.TimeLineEnum.TREND_MESSAGE) {
|
||||||
if (direction == null) {
|
if (direction == null) {
|
||||||
timelinesVM.getStatusTrends(BaseMainActivity.currentToken, BaseMainActivity.currentInstance)
|
timelinesVM.getStatusTrends(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, null, MastodonHelper.statusesPerCall(requireActivity()))
|
||||||
.observe(getViewLifecycleOwner(), statusesTrends -> {
|
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
|
||||||
Statuses statuses = new Statuses();
|
} else if (direction == DIRECTION.BOTTOM) {
|
||||||
statuses.statuses = new ArrayList<>();
|
timelinesVM.getStatusTrends(BaseMainActivity.currentToken, BaseMainActivity.currentInstance, max_id, MastodonHelper.statusesPerCall(requireActivity()))
|
||||||
if (statusesTrends != null) {
|
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
|
||||||
statuses.statuses.addAll(statusesTrends);
|
} else {
|
||||||
}
|
flagLoading = false;
|
||||||
statuses.pagination = new Pagination();
|
|
||||||
initializeStatusesCommonView(statuses);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else if (timelineType == Timeline.TimeLineEnum.PUBLIC_TREND_MESSAGE) {
|
} else if (timelineType == Timeline.TimeLineEnum.TREND_MESSAGE_PUBLIC) {
|
||||||
if (direction == null) {
|
if (direction == null) {
|
||||||
timelinesVM.getStatusTrends(null, publicTrendsDomain)
|
timelinesVM.getStatusTrends(null, publicTrendsDomain, null, MastodonHelper.statusesPerCall(requireActivity()))
|
||||||
.observe(getViewLifecycleOwner(), statusesTrends -> {
|
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
|
||||||
Statuses statuses = new Statuses();
|
} else if (direction == DIRECTION.BOTTOM) {
|
||||||
statuses.statuses = new ArrayList<>();
|
timelinesVM.getStatusTrends(null, publicTrendsDomain, max_id, MastodonHelper.statusesPerCall(requireActivity()))
|
||||||
if (statusesTrends != null) {
|
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false));
|
||||||
statuses.statuses.addAll(statusesTrends);
|
} else {
|
||||||
}
|
flagLoading = false;
|
||||||
statuses.pagination = new Pagination();
|
|
||||||
initializeStatusesCommonView(statuses);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,28 +160,29 @@ public class TimelinesVM extends AndroidViewModel {
|
||||||
return retrofit.create(MastodonTimelinesService.class);
|
return retrofit.create(MastodonTimelinesService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Status>> getStatusTrends(String token, @NonNull String instance) {
|
public LiveData<Statuses> getStatusTrends(String token, @NonNull String instance, String max_id, Integer limit) {
|
||||||
MastodonTimelinesService mastodonTimelinesService = init(instance);
|
MastodonTimelinesService mastodonTimelinesService = init(instance);
|
||||||
statusListMutableLiveData = new MutableLiveData<>();
|
statusesMutableLiveData = new MutableLiveData<>();
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
Call<List<Status>> publicTlCall = mastodonTimelinesService.getStatusTrends(token);
|
Call<List<Status>> publicTlCall = mastodonTimelinesService.getStatusTrends(token, max_id, limit);
|
||||||
List<Status> statusList = null;
|
Statuses statuses = new Statuses();
|
||||||
if (publicTlCall != null) {
|
if (publicTlCall != null) {
|
||||||
try {
|
try {
|
||||||
Response<List<Status>> publicTlResponse = publicTlCall.execute();
|
Response<List<Status>> publicTlResponse = publicTlCall.execute();
|
||||||
if (publicTlResponse.isSuccessful()) {
|
if (publicTlResponse.isSuccessful()) {
|
||||||
statusList = publicTlResponse.body();
|
List<Status> statusList = publicTlResponse.body();
|
||||||
|
statuses.statuses = TimelineHelper.filterStatus(getApplication().getApplicationContext(), statusList, Timeline.TimeLineEnum.TREND_MESSAGE);
|
||||||
|
statuses.pagination = MastodonHelper.getOffSetPagination(publicTlResponse.headers());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
List<Status> finalStatusList = statusList;
|
Runnable myRunnable = () -> statusesMutableLiveData.setValue(statuses);
|
||||||
Runnable myRunnable = () -> statusListMutableLiveData.setValue(finalStatusList);
|
|
||||||
mainHandler.post(myRunnable);
|
mainHandler.post(myRunnable);
|
||||||
}).start();
|
}).start();
|
||||||
return statusListMutableLiveData;
|
return statusesMutableLiveData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Tag>> getTagsTrends(String token, @NonNull String instance) {
|
public LiveData<List<Tag>> getTagsTrends(String token, @NonNull String instance) {
|
||||||
|
|
|
@ -91,6 +91,7 @@
|
||||||
android:text="@string/watch_trends_for_instance"
|
android:text="@string/watch_trends_for_instance"
|
||||||
android:textColor="@color/cyanea_accent_dark_reference"
|
android:textColor="@color/cyanea_accent_dark_reference"
|
||||||
app:icon="@drawable/ic_baseline_remove_red_eye_24"
|
app:icon="@drawable/ic_baseline_remove_red_eye_24"
|
||||||
|
app:iconTint="@color/cyanea_accent_dark_reference"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/instance_description"
|
app:layout_constraintTop_toBottomOf="@+id/instance_description"
|
||||||
app:strokeColor="@color/cyanea_accent_dark_reference" />
|
app:strokeColor="@color/cyanea_accent_dark_reference" />
|
||||||
|
|
Loading…
Reference in a new issue