Allow to see who quoted

This commit is contained in:
Thomas 2025-09-19 12:27:44 +02:00
parent 24b58e0450
commit 53ed3d4276
7 changed files with 111 additions and 3 deletions

View file

@ -15,6 +15,8 @@ package app.fedilab.android.mastodon.activities;
* see <http://www.gnu.org/licenses>. */
import static app.fedilab.android.mastodon.client.entities.app.Timeline.TimeLineEnum.QUOTE_TIMELINE;
import android.os.Bundle;
import android.view.MenuItem;
@ -60,8 +62,10 @@ public class TimelineActivity extends BaseBarActivity {
String tagged = null;
String timelineAccountId = null;
Status status = null;
String status_id = null;
if (bundle != null) {
timelineType = (Timeline.TimeLineEnum) bundle.get(Helper.ARG_TIMELINE_TYPE);
status_id = bundle.getString(Helper.ARG_STATUS_ID);
lemmy_post_id = bundle.getString(Helper.ARG_LEMMY_POST_ID, null);
pinnedTimeline = (PinnedTimeline) bundle.getSerializable(Helper.ARG_REMOTE_INSTANCE);
status = (Status) bundle.getSerializable(Helper.ARG_STATUS);
@ -74,9 +78,13 @@ public class TimelineActivity extends BaseBarActivity {
if(tagged != null) {
setTitle(String.format("#%s",tagged));
}
if(timelineType == QUOTE_TIMELINE) {
setTitle(R.string.quoting_messages);
}
FragmentMastodonTimeline fragmentMastodonTimeline = new FragmentMastodonTimeline();
Bundle args = new Bundle();
args.putSerializable(Helper.ARG_TIMELINE_TYPE, timelineType);
args.putString(Helper.ARG_STATUS_ID,status_id);
args.putSerializable(Helper.ARG_REMOTE_INSTANCE, pinnedTimeline);
args.putSerializable(Helper.ARG_LEMMY_POST_ID, lemmy_post_id);
args.putSerializable(Helper.ARG_TAGGED, tagged);

View file

@ -82,6 +82,7 @@ public interface MastodonStatusesService {
@Path("id") String id);
@Headers({"Accept: application/json"})
@PUT("statuses/{id}")
Call<Status> updateStatus(
@ -177,6 +178,18 @@ public interface MastodonStatusesService {
@Query("limit") int limit
);
@GET("statuses/{id}/quotes")
Call<List<Status>> getStatusQuotes(
@Header("Authorization") String token,
@Path("id") String id,
@Query("max_id") String max_id,
@Query("since_id") String since_id,
@Query("min_id") String min_id,
@Query("limit") int limit
);
//Add status to favourites
@POST("statuses/{id}/favourite")
Call<Status> favourites(

View file

@ -398,6 +398,8 @@ public class Timeline {
MUTED_TIMELINE_HOME("MUTED_TIMELINE_HOME"),
@SerializedName("BOOKMARK_TIMELINE")
BOOKMARK_TIMELINE("BOOKMARK_TIMELINE"),
@SerializedName("QUOTE_TIMELINE")
QUOTE_TIMELINE("QUOTE_TIMELINE"),
@SerializedName("BLOCKED_DOMAIN_TIMELINE")
BLOCKED_DOMAIN_TIMELINE("BLOCKED_DOMAIN_TIMELINE"),
@SerializedName("BLOCKED_TIMELINE")

View file

@ -60,7 +60,6 @@ import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MenuItem;
@ -2095,8 +2094,17 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
});
holder.binding.quoteInfo.setOnClickListener(v->{
if (statusToDeal.quotes_count > 0) {
if (statusToDeal.quotes_count > 0 && statusToDeal.account.id.compareTo(BaseMainActivity.currentUserID) == 0) {
Bundle args = new Bundle();
args.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.QUOTE_TIMELINE);
args.putSerializable(Helper.ARG_STATUS_ID, statusToDeal.id);
Intent intent = new Intent(context, TimelineActivity.class);
new CachedBundle(context).insertBundle(args, Helper.getCurrentAccount(context), bundleId -> {
Bundle bundle = new Bundle();
bundle.putLong(Helper.ARG_INTENT_ID, bundleId);
intent.putExtras(bundle);
context.startActivity(intent);
});
}
});

View file

@ -72,6 +72,7 @@ import app.fedilab.android.mastodon.helper.MastodonHelper;
import app.fedilab.android.mastodon.ui.drawer.StatusAdapter;
import app.fedilab.android.mastodon.viewmodel.mastodon.AccountsVM;
import app.fedilab.android.mastodon.viewmodel.mastodon.SearchVM;
import app.fedilab.android.mastodon.viewmodel.mastodon.StatusesVM;
import app.fedilab.android.mastodon.viewmodel.mastodon.TimelinesVM;
import es.dmoral.toasty.Toasty;
@ -83,6 +84,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
private boolean scrollingUp;
private FragmentPaginationBinding binding;
private TimelinesVM timelinesVM;
private StatusesVM statusesVM;
private AccountsVM accountsVM;
private boolean flagLoading;
private String search, searchCache;
@ -91,6 +93,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
private Integer offset;
private StatusAdapter statusAdapter;
private Timeline.TimeLineEnum timelineType;
private String status_id;
private String tagged;
private List<Status> timelineStatuses;
//Handle actions that can be done in other fragments
@ -418,6 +421,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
timelineType = (Timeline.TimeLineEnum) bundle.get(Helper.ARG_TIMELINE_TYPE);
lemmy_post_id = bundle.getString(Helper.ARG_LEMMY_POST_ID, null);
list_id = bundle.getString(Helper.ARG_LIST_ID, null);
status_id = bundle.getString(Helper.ARG_STATUS_ID, null);
search = bundle.getString(Helper.ARG_SEARCH_KEYWORD, null);
tagged = bundle.getString(Helper.ARG_TAGGED, null);
searchCache = bundle.getString(Helper.ARG_SEARCH_KEYWORD_CACHE, null);
@ -491,6 +495,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
timelinesVM = new ViewModelProvider(FragmentMastodonTimeline.this).get(viewModelKey, TimelinesVM.class);
accountsVM = new ViewModelProvider(FragmentMastodonTimeline.this).get(viewModelKey, AccountsVM.class);
statusesVM = new ViewModelProvider(FragmentMastodonTimeline.this).get(viewModelKey, StatusesVM.class);
initialStatuses = null;
lockForResumeCall = 0;
@ -690,6 +695,9 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
if (initialStatus != null) {
timelineStatuses.add(initialStatus);
}
if(statuses.statuses == null) {
statuses.statuses = new ArrayList<>();
}
timelineStatuses.addAll(statuses.statuses);
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;
@ -1272,6 +1280,16 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
} else {
flagLoading = false;
}
}else if (timelineType == Timeline.TimeLineEnum.QUOTE_TIMELINE) {
if (direction == null) {
statusesVM.quotedStatus(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, status_id, null, null, null)
.observe(getViewLifecycleOwner(), this::initializeStatusesCommonView);
} else if (direction == DIRECTION.BOTTOM) {
statusesVM.quotedStatus(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, status_id, max_id, null, null)
.observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, false, true, fetchStatus));
} else {
flagLoading = false;
}
}
else if (timelineType == Timeline.TimeLineEnum.TREND_MESSAGE) {
if (direction == null) {

View file

@ -26,6 +26,7 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import java.net.IDN;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -43,6 +44,7 @@ import app.fedilab.android.mastodon.client.entities.api.ScheduledStatus;
import app.fedilab.android.mastodon.client.entities.api.ScheduledStatuses;
import app.fedilab.android.mastodon.client.entities.api.Status;
import app.fedilab.android.mastodon.client.entities.api.StatusSource;
import app.fedilab.android.mastodon.client.entities.api.Statuses;
import app.fedilab.android.mastodon.client.entities.app.BaseAccount;
import app.fedilab.android.mastodon.client.entities.app.StatusCache;
import app.fedilab.android.mastodon.client.entities.app.Timeline;
@ -65,6 +67,7 @@ public class StatusesVM extends AndroidViewModel {
private MutableLiveData<Status> statusMutableLiveData;
private MutableLiveData<Statuses> statusesMutableLiveData;
private MutableLiveData<List<Status>> statusListMutableLiveData;
private MutableLiveData<StatusSource> statusSourceMutableLiveData;
private MutableLiveData<ScheduledStatus> scheduledStatusMutableLiveData;
@ -375,6 +378,8 @@ public class StatusesVM extends AndroidViewModel {
return statusListMutableLiveData;
}
/**
* Delete a status by ID
*
@ -544,6 +549,59 @@ public class StatusesVM extends AndroidViewModel {
return accountsMutableLiveData;
}
/**
* Statuses that quoted a status by ID
*
* @param instance Instance domain of the active account
* @param token Access token of the active account
* @param id String - id of the status
* @param max_id String
* @param since_id String
* @param min_id String
* @return LiveData<Statuses>
*/
public LiveData<Statuses> quotedStatus(@NonNull String instance,
String token,
@NonNull String id,
String max_id,
String since_id,
String min_id) {
MastodonStatusesService mastodonStatusesService = init(instance);
statusesMutableLiveData = new MutableLiveData<>();
new Thread(() -> {
int limit = MastodonHelper.statusesPerCall(getApplication().getApplicationContext());
Call<List<Status>> statusesCall = mastodonStatusesService.getStatusQuotes(token, id, max_id, since_id, min_id, limit);
List<Status> statuses = null;
Headers headers = null;
if (statusesCall != null) {
try {
Response<List<Status>> statusesResponse = statusesCall.execute();
if (statusesResponse.isSuccessful()) {
statuses = statusesResponse.body();
}
headers = statusesResponse.headers();
} catch (Exception e) {
e.printStackTrace();
}
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Statuses statusesPagination = new Statuses();
if(statuses == null) {
statuses = new ArrayList<>();
}
statusesPagination.statuses = statuses;
if (headers != null) {
statusesPagination.pagination = MastodonHelper.getPagination(headers);
}
Runnable myRunnable = () -> statusesMutableLiveData.setValue(statusesPagination);
mainHandler.post(myRunnable);
}).start();
return statusesMutableLiveData;
}
/**
* Add a status to favourites by ID
*

View file

@ -691,6 +691,7 @@
<string name="favourited_by">Favourited by</string>
<string name="followers_only">Followers only</string>
<string name="who_can_quote">Who can quote</string>
<string name="quoting_messages">Quoting messages</string>
<string name="no_one">No one</string>
<string name="anyone">Anyone</string>
<string name="other">Other</string>