Support Mastodon notification bell and status notification type

This commit is contained in:
Alibek Omarov 2020-12-06 01:12:25 +03:00
parent 7808f122e0
commit 68d6a4ab25
11 changed files with 137 additions and 66 deletions

View File

@ -327,7 +327,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
* Subscribe to data loaded at the view model * Subscribe to data loaded at the view model
*/ */
private fun subscribeObservables() { private fun subscribeObservables() {
viewModel.accountData.observe(this, Observer<Resource<Account>> { viewModel.accountData.observe(this) {
when (it) { when (it) {
is Success -> onAccountChanged(it.data) is Success -> onAccountChanged(it.data)
is Error -> { is Error -> {
@ -336,8 +336,8 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
.show() .show()
} }
} }
}) }
viewModel.relationshipData.observe(this, Observer<Resource<Relationship>> { viewModel.relationshipData.observe(this) {
val relation = it?.data val relation = it?.data
if (relation != null) { if (relation != null) {
onRelationshipChanged(relation) onRelationshipChanged(relation)
@ -349,11 +349,11 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
.show() .show()
} }
}) }
viewModel.accountFieldData.observe(this, Observer<List<Either<IdentityProof, Field>>> { viewModel.accountFieldData.observe(this) {
accountFieldAdapter.fields = it accountFieldAdapter.fields = it
accountFieldAdapter.notifyDataSetChanged() accountFieldAdapter.notifyDataSetChanged()
}) }
viewModel.noteSaved.observe(this) { viewModel.noteSaved.observe(this) {
saveNoteInfo.visible(it, View.INVISIBLE) saveNoteInfo.visible(it, View.INVISIBLE)
} }
@ -367,9 +367,9 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
viewModel.refresh() viewModel.refresh()
adapter.refreshContent() adapter.refreshContent()
} }
viewModel.isRefreshing.observe(this, Observer { isRefreshing -> viewModel.isRefreshing.observe(this) { isRefreshing ->
swipeToRefreshLayout.isRefreshing = isRefreshing == true swipeToRefreshLayout.isRefreshing = isRefreshing == true
}) }
swipeToRefreshLayout.setColorSchemeResources(R.color.tusky_blue) swipeToRefreshLayout.setColorSchemeResources(R.color.tusky_blue)
} }
@ -436,7 +436,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
accountAvatarImageView.setOnClickListener { avatarView -> accountAvatarImageView.setOnClickListener { avatarView ->
val intent = ViewMediaActivity.newAvatarIntent(avatarView.context, account.avatar) val intent = ViewMediaActivity.newSingleImageIntent(avatarView.context, account.avatar)
avatarView.transitionName = account.avatar avatarView.transitionName = account.avatar
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, avatarView, account.avatar) val options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, avatarView, account.avatar)
@ -635,12 +635,17 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
accountFollowsYouTextView.visible(relation.followedBy) accountFollowsYouTextView.visible(relation.followedBy)
// because subscribing is Pleroma extension, enable it __only__ when we have non-null subscribing field // because subscribing is Pleroma extension, enable it __only__ when we have non-null subscribing field
if(!viewModel.isSelf && followState == FollowState.FOLLOWING && relation.subscribing != null) { // it's also now supported in Mastodon 3.3.0rc but called notifying and use different API call
if(!viewModel.isSelf && followState == FollowState.FOLLOWING
&& (relation.subscribing != null || relation.notifying != null)) {
accountSubscribeButton.show() accountSubscribeButton.show()
accountSubscribeButton.setOnClickListener { accountSubscribeButton.setOnClickListener {
viewModel.changeSubscribingState() viewModel.changeSubscribingState()
} }
subscribing = relation.subscribing if(relation.notifying != null)
subscribing = relation.notifying
else if(relation.subscribing != null)
subscribing = relation.subscribing
} }
accountNoteTextInputLayout.visible(relation.note != null) accountNoteTextInputLayout.visible(relation.note != null)

View File

@ -88,7 +88,7 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener
return intent return intent
} }
fun newAvatarIntent(context: Context?, url: String): Intent { fun newSingleImageIntent(context: Context?, url: String): Intent {
val intent = Intent(context, ViewMediaActivity::class.java) val intent = Intent(context, ViewMediaActivity::class.java)
intent.putExtra(EXTRA_AVATAR_URL, url) intent.putExtra(EXTRA_AVATAR_URL, url)
return intent return intent

View File

@ -39,6 +39,7 @@ import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.R;
import com.keylesspalace.tusky.entity.Account; import com.keylesspalace.tusky.entity.Account;
import com.keylesspalace.tusky.entity.Emoji; import com.keylesspalace.tusky.entity.Emoji;
@ -216,8 +217,12 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
holder.setUsername(statusViewData.getNickname()); holder.setUsername(statusViewData.getNickname());
holder.setCreatedAt(statusViewData.getCreatedAt()); holder.setCreatedAt(statusViewData.getCreatedAt());
holder.setAvatars(concreteNotificaton.getStatusViewData().getAvatar(), if(concreteNotificaton.getType() == Notification.Type.STATUS) {
concreteNotificaton.getAccount().getAvatar()); holder.setAvatar(statusViewData.getAvatar(), statusViewData.isBot());
} else {
holder.setAvatars(statusViewData.getAvatar(),
concreteNotificaton.getAccount().getAvatar());
}
} }
holder.setMessage(concreteNotificaton, statusListener); holder.setMessage(concreteNotificaton, statusListener);
@ -291,10 +296,11 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
switch (concrete.getType()) { switch (concrete.getType()) {
case MENTION: case MENTION:
case POLL: { case POLL: {
if(concrete.getStatusViewData() != null && concrete.getStatusViewData().isMuted()) if (concrete.getStatusViewData() != null && concrete.getStatusViewData().isMuted())
return VIEW_TYPE_MUTED_STATUS; return VIEW_TYPE_MUTED_STATUS;
return VIEW_TYPE_STATUS; return VIEW_TYPE_STATUS;
} }
case STATUS:
case FAVOURITE: case FAVOURITE:
case REBLOG: case REBLOG:
case EMOJI_REACTION: { case EMOJI_REACTION: {
@ -426,7 +432,11 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
private StatusViewData.Concrete statusViewData; private StatusViewData.Concrete statusViewData;
private SimpleDateFormat shortSdf; private SimpleDateFormat shortSdf;
private SimpleDateFormat longSdf; private SimpleDateFormat longSdf;
private int avatarRadius48dp;
private int avatarRadius36dp;
private int avatarRadius24dp;
StatusNotificationViewHolder(View itemView, StatusDisplayOptions statusDisplayOptions) { StatusNotificationViewHolder(View itemView, StatusDisplayOptions statusDisplayOptions) {
super(itemView); super(itemView);
message = itemView.findViewById(R.id.notification_top_text); message = itemView.findViewById(R.id.notification_top_text);
@ -452,6 +462,10 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
statusContent.setOnClickListener(this); statusContent.setOnClickListener(this);
shortSdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()); shortSdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
longSdf = new SimpleDateFormat("MM/dd HH:mm:ss", Locale.getDefault()); longSdf = new SimpleDateFormat("MM/dd HH:mm:ss", Locale.getDefault());
this.avatarRadius48dp = itemView.getContext().getResources().getDimensionPixelSize(R.dimen.avatar_radius_48dp);
this.avatarRadius36dp = itemView.getContext().getResources().getDimensionPixelSize(R.dimen.avatar_radius_36dp);
this.avatarRadius24dp = itemView.getContext().getResources().getDimensionPixelSize(R.dimen.avatar_radius_24dp);
} }
private void showNotificationContent(boolean show) { private void showNotificationContent(boolean show) {
@ -460,7 +474,6 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
contentWarningButton.setVisibility(show ? View.VISIBLE : View.GONE); contentWarningButton.setVisibility(show ? View.VISIBLE : View.GONE);
statusContent.setVisibility(show ? View.VISIBLE : View.GONE); statusContent.setVisibility(show ? View.VISIBLE : View.GONE);
statusAvatar.setVisibility(show ? View.VISIBLE : View.GONE); statusAvatar.setVisibility(show ? View.VISIBLE : View.GONE);
notificationAvatar.setVisibility(show ? View.VISIBLE : View.GONE);
replyInfo.setVisibility(show ? View.VISIBLE : View.GONE); replyInfo.setVisibility(show ? View.VISIBLE : View.GONE);
} }
@ -545,6 +558,17 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
wholeMessage = String.format(format, displayName); wholeMessage = String.format(format, displayName);
break; break;
} }
case STATUS: {
icon = ContextCompat.getDrawable(context, R.drawable.ic_home_24dp);
if (icon != null) {
icon.setColorFilter(ContextCompat.getColor(context,
R.color.tusky_blue), PorterDuff.Mode.SRC_ATOP);
}
String format = context.getString(R.string.notification_subscription_format);
wholeMessage = String.format(format, displayName);
break;
}
case EMOJI_REACTION: { case EMOJI_REACTION: {
icon = ContextCompat.getDrawable(context, R.drawable.ic_emoji_24dp); icon = ContextCompat.getDrawable(context, R.drawable.ic_emoji_24dp);
if(icon != null) { if(icon != null) {
@ -595,19 +619,34 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
this.notificationId = notificationId; this.notificationId = notificationId;
} }
void setAvatars(@Nullable String statusAvatarUrl, @Nullable String notificationAvatarUrl) { void setAvatar(@Nullable String statusAvatarUrl, boolean isBot) {
statusAvatar.setPaddingRelative(0, 0, 0, 0);
int statusAvatarRadius = statusAvatar.getContext().getResources()
.getDimensionPixelSize(R.dimen.avatar_radius_36dp);
ImageLoadingHelper.loadAvatar(statusAvatarUrl, ImageLoadingHelper.loadAvatar(statusAvatarUrl,
statusAvatar, statusAvatarRadius, statusDisplayOptions.animateAvatars()); statusAvatar, avatarRadius48dp, statusDisplayOptions.animateAvatars());
int notificationAvatarRadius = statusAvatar.getContext().getResources() if (statusDisplayOptions.showBotOverlay() && isBot) {
.getDimensionPixelSize(R.dimen.avatar_radius_24dp); notificationAvatar.setVisibility(View.VISIBLE);
notificationAvatar.setBackgroundColor(0x50ffffff);
Glide.with(notificationAvatar)
.load(R.drawable.ic_bot_24dp)
.into(notificationAvatar);
} else {
notificationAvatar.setVisibility(View.GONE);
}
}
void setAvatars(@Nullable String statusAvatarUrl, @Nullable String notificationAvatarUrl) {
int padding = Utils.dpToPx(statusAvatar.getContext(), 12);
statusAvatar.setPaddingRelative(0, 0, padding, padding);
ImageLoadingHelper.loadAvatar(statusAvatarUrl,
statusAvatar, avatarRadius36dp, statusDisplayOptions.animateAvatars());
notificationAvatar.setVisibility(View.VISIBLE);
ImageLoadingHelper.loadAvatar(notificationAvatarUrl, notificationAvatar, ImageLoadingHelper.loadAvatar(notificationAvatarUrl, notificationAvatar,
notificationAvatarRadius, statusDisplayOptions.animateAvatars()); avatarRadius24dp, statusDisplayOptions.animateAvatars());
} }
@Override @Override

View File

@ -82,7 +82,7 @@ class PollAdapter: RecyclerView.Adapter<PollViewHolder>() {
val percent = calculatePercent(option.votesCount, votersCount, voteCount) val percent = calculatePercent(option.votesCount, votersCount, voteCount)
val emojifiedPollOptionText = buildDescription(option.title, percent, holder.resultTextView.context) val emojifiedPollOptionText = buildDescription(option.title, percent, holder.resultTextView.context)
.emojify(emojis, holder.resultTextView) .emojify(emojis, holder.resultTextView)
holder.resultTextView.text = EmojiCompat.get().process(emojifiedPollOptionText) holder.resultTextView.text = EmojiCompat.get().process(emojifiedPollOptionText)
val level = percent * 100 val level = percent * 100

View File

@ -152,6 +152,7 @@ public class NotificationHelper {
*/ */
public static void make(final Context context, Notification body, AccountEntity account, boolean isFirstOfBatch) { public static void make(final Context context, Notification body, AccountEntity account, boolean isFirstOfBatch) {
body = Notification.rewriteToStatusTypeIfNeeded(body, account.getAccountId());
if (!filterNotification(account, body, context)) { if (!filterNotification(account, body, context)) {
return; return;
@ -572,9 +573,9 @@ public class NotificationHelper {
switch (notification.getType()) { switch (notification.getType()) {
case MENTION: case MENTION:
if(isMentionedInNotification(notification, account.getAccountId())) return account.getNotificationsMentioned();
return account.getNotificationsMentioned(); case STATUS:
else return account.getNotificationsSubscriptions(); return account.getNotificationsSubscriptions();
case FOLLOW: case FOLLOW:
return account.getNotificationsFollowed(); return account.getNotificationsFollowed();
case FOLLOW_REQUEST: case FOLLOW_REQUEST:
@ -600,9 +601,9 @@ public class NotificationHelper {
private static String getChannelId(AccountEntity account, Notification notification) { private static String getChannelId(AccountEntity account, Notification notification) {
switch (notification.getType()) { switch (notification.getType()) {
case MENTION: case MENTION:
if(isMentionedInNotification(notification, account.getAccountId())) return CHANNEL_MENTION + account.getIdentifier();
return CHANNEL_MENTION + account.getIdentifier(); case STATUS:
else return CHANNEL_SUBSCRIPTIONS + account.getIdentifier(); return CHANNEL_SUBSCRIPTIONS + account.getIdentifier();
case FOLLOW: case FOLLOW:
return CHANNEL_FOLLOW + account.getIdentifier(); return CHANNEL_FOLLOW + account.getIdentifier();
case FOLLOW_REQUEST: case FOLLOW_REQUEST:
@ -671,32 +672,17 @@ public class NotificationHelper {
return null; return null;
} }
private static boolean isMentionedInNotification(Notification not, String id) {
if(not.getStatus() != null) {
for(int i = 0; i < not.getStatus().getMentions().length; i++) {
if(not.getStatus().getMentions()[i].getId().equals(id)) {
return true;
}
}
return false;
}
return true; // actually should never happen, true just in case someone breaks API again
}
@Nullable @Nullable
private static String titleForType(Context context, Notification notification, AccountEntity account) { private static String titleForType(Context context, Notification notification, AccountEntity account) {
String accountName = StringUtils.unicodeWrap(notification.getAccount().getName()); String accountName = StringUtils.unicodeWrap(notification.getAccount().getName());
switch (notification.getType()) { switch (notification.getType()) {
case MENTION: case MENTION:
if(isMentionedInNotification(notification, account.getAccountId())) { return String.format(context.getString(R.string.notification_mention_format),
return String.format(context.getString(R.string.notification_mention_format), accountName);
accountName); case STATUS:
} else { return String.format(context.getString(R.string.notification_subscription_format),
return String.format(context.getString(R.string.notification_subscription_format), accountName); accountName);
}
case FOLLOW: case FOLLOW:
return String.format(context.getString(R.string.notification_follow_format), return String.format(context.getString(R.string.notification_follow_format),
accountName); accountName);
@ -739,6 +725,7 @@ public class NotificationHelper {
case FAVOURITE: case FAVOURITE:
case REBLOG: case REBLOG:
case EMOJI_REACTION: case EMOJI_REACTION:
case STATUS:
if (!TextUtils.isEmpty(notification.getStatus().getSpoilerText())) { if (!TextUtils.isEmpty(notification.getStatus().getSpoilerText())) {
return notification.getStatus().getSpoilerText(); return notification.getStatus().getSpoilerText();
} else { } else {

View File

@ -46,7 +46,8 @@ data class Notification(
EMOJI_REACTION("pleroma:emoji_reaction"), EMOJI_REACTION("pleroma:emoji_reaction"),
FOLLOW_REQUEST("follow_request"), FOLLOW_REQUEST("follow_request"),
CHAT_MESSAGE("pleroma:chat_mention"), CHAT_MESSAGE("pleroma:chat_mention"),
MOVE("move"); MOVE("move"),
STATUS("status"); /* Mastodon 3.3.0rc1 */
companion object { companion object {
@ -58,7 +59,7 @@ data class Notification(
} }
return UNKNOWN return UNKNOWN
} }
val asList = listOf(MENTION, REBLOG, FAVOURITE, FOLLOW, POLL, EMOJI_REACTION, FOLLOW_REQUEST, CHAT_MESSAGE, MOVE) val asList = listOf(MENTION, REBLOG, FAVOURITE, FOLLOW, POLL, EMOJI_REACTION, FOLLOW_REQUEST, CHAT_MESSAGE, MOVE, STATUS)
val asStringList = asList.map { it.presentation } val asStringList = asList.map { it.presentation }
} }
@ -88,4 +89,19 @@ data class Notification(
} }
} }
companion object {
// for Pleroma compatibility that uses Mention type
@JvmStatic
fun rewriteToStatusTypeIfNeeded(body: Notification, accountId: String) : Notification {
if (body.type == Type.MENTION
&& body.status != null) {
return if (body.status.mentions.any {
it.id == accountId
}) body else body.copy(type = Type.STATUS)
}
return body
}
}
} }

View File

@ -28,5 +28,6 @@ data class Relationship (
@SerializedName("showing_reblogs") val showingReblogs: Boolean, @SerializedName("showing_reblogs") val showingReblogs: Boolean,
val subscribing: Boolean? = null, // Pleroma extension val subscribing: Boolean? = null, // Pleroma extension
@SerializedName("domain_blocking") val blockingDomain: Boolean, @SerializedName("domain_blocking") val blockingDomain: Boolean,
val note: String? // nullable for backward compatibility / feature detection val note: String?, // nullable for backward compatibility / feature detection
val notifying: Boolean? // since 3.3.0rc
) )

View File

@ -177,7 +177,10 @@ public class NotificationsFragment extends SFragment implements
@Override @Override
public NotificationViewData apply(Either<Placeholder, Notification> input) { public NotificationViewData apply(Either<Placeholder, Notification> input) {
if (input.isRight()) { if (input.isRight()) {
Notification notification = input.asRight(); Notification notification = Notification.rewriteToStatusTypeIfNeeded(
input.asRight(), accountManager.getActiveAccount().getAccountId()
);
return ViewDataUtils.notificationToViewData( return ViewDataUtils.notificationToViewData(
notification, notification,
alwaysShowSensitiveMedia, alwaysShowSensitiveMedia,
@ -874,6 +877,8 @@ public class NotificationsFragment extends SFragment implements
return getString(R.string.notification_emoji_name); return getString(R.string.notification_emoji_name);
case MOVE: case MOVE:
return getString(R.string.notification_move_name); return getString(R.string.notification_move_name);
case STATUS:
return getString(R.string.notification_subscription_name);
default: default:
return "Unknown"; return "Unknown";
} }

View File

@ -309,7 +309,8 @@ interface MastodonApi {
@POST("api/v1/accounts/{id}/follow") @POST("api/v1/accounts/{id}/follow")
fun followAccount( fun followAccount(
@Path("id") accountId: String, @Path("id") accountId: String,
@Field("reblogs") showReblogs: Boolean @Field("reblogs") showReblogs: Boolean? = null,
@Field("notify") notify: Boolean? = null
): Single<Relationship> ): Single<Relationship>
@POST("api/v1/accounts/{id}/unfollow") @POST("api/v1/accounts/{id}/unfollow")

View File

@ -33,7 +33,7 @@ class AccountViewModel @Inject constructor(
val accountFieldData = combineOptionalLiveData(accountData, identityProofData) { accountRes, identityProofs -> val accountFieldData = combineOptionalLiveData(accountData, identityProofData) { accountRes, identityProofs ->
identityProofs.orEmpty().map { Either.Left<IdentityProof, Field>(it) } identityProofs.orEmpty().map { Either.Left<IdentityProof, Field>(it) }
.plus(accountRes?.data?.fields.orEmpty().map { Either.Right<IdentityProof, Field>(it) }) .plus(accountRes?.data?.fields.orEmpty().map { Either.Right(it) })
} }
val isRefreshing = MutableLiveData<Boolean>().apply { value = false } val isRefreshing = MutableLiveData<Boolean>().apply { value = false }
@ -128,7 +128,9 @@ class AccountViewModel @Inject constructor(
} }
fun changeSubscribingState() { fun changeSubscribingState() {
if (relationshipData.value?.data?.subscribing == true) { val relationship = relationshipData.value?.data
if(relationship?.notifying == true /* Mastodon 3.3.0rc1 */
|| relationship?.subscribing == true /* Pleroma */ ) {
changeRelationship(RelationShipAction.UNSUBSCRIBE) changeRelationship(RelationShipAction.UNSUBSCRIBE)
} else { } else {
changeRelationship(RelationShipAction.SUBSCRIBE) changeRelationship(RelationShipAction.SUBSCRIBE)
@ -188,6 +190,7 @@ class AccountViewModel @Inject constructor(
private fun changeRelationship(relationshipAction: RelationShipAction, parameter: Boolean? = null) { private fun changeRelationship(relationshipAction: RelationShipAction, parameter: Boolean? = null) {
val relation = relationshipData.value?.data val relation = relationshipData.value?.data
val account = accountData.value?.data val account = accountData.value?.data
val isMastodon = relationshipData.value?.data?.notifying != null
if (relation != null && account != null) { if (relation != null && account != null) {
// optimistically post new state for faster response // optimistically post new state for faster response
@ -205,21 +208,37 @@ class AccountViewModel @Inject constructor(
RelationShipAction.UNBLOCK -> relation.copy(blocking = false) RelationShipAction.UNBLOCK -> relation.copy(blocking = false)
RelationShipAction.MUTE -> relation.copy(muting = true) RelationShipAction.MUTE -> relation.copy(muting = true)
RelationShipAction.UNMUTE -> relation.copy(muting = false) RelationShipAction.UNMUTE -> relation.copy(muting = false)
RelationShipAction.SUBSCRIBE -> relation.copy(subscribing = true) RelationShipAction.SUBSCRIBE -> {
RelationShipAction.UNSUBSCRIBE -> relation.copy(subscribing = false) if(isMastodon)
relation.copy(notifying = true)
else relation.copy(subscribing = true)
}
RelationShipAction.UNSUBSCRIBE -> {
if(isMastodon)
relation.copy(notifying = false)
else relation.copy(subscribing = false)
}
} }
relationshipData.postValue(Loading(newRelation)) relationshipData.postValue(Loading(newRelation))
} }
when (relationshipAction) { when (relationshipAction) {
RelationShipAction.FOLLOW -> mastodonApi.followAccount(accountId, parameter ?: true) RelationShipAction.FOLLOW -> mastodonApi.followAccount(accountId, showReblogs = parameter ?: true)
RelationShipAction.UNFOLLOW -> mastodonApi.unfollowAccount(accountId) RelationShipAction.UNFOLLOW -> mastodonApi.unfollowAccount(accountId)
RelationShipAction.BLOCK -> mastodonApi.blockAccount(accountId) RelationShipAction.BLOCK -> mastodonApi.blockAccount(accountId)
RelationShipAction.UNBLOCK -> mastodonApi.unblockAccount(accountId) RelationShipAction.UNBLOCK -> mastodonApi.unblockAccount(accountId)
RelationShipAction.MUTE -> mastodonApi.muteAccount(accountId, parameter ?: true) RelationShipAction.MUTE -> mastodonApi.muteAccount(accountId, parameter ?: true)
RelationShipAction.UNMUTE -> mastodonApi.unmuteAccount(accountId) RelationShipAction.UNMUTE -> mastodonApi.unmuteAccount(accountId)
RelationShipAction.SUBSCRIBE -> mastodonApi.subscribeAccount(accountId) RelationShipAction.SUBSCRIBE -> {
RelationShipAction.UNSUBSCRIBE -> mastodonApi.unsubscribeAccount(accountId) if(isMastodon)
mastodonApi.followAccount(accountId, notify = true)
else mastodonApi.subscribeAccount(accountId)
}
RelationShipAction.UNSUBSCRIBE -> {
if(isMastodon)
mastodonApi.followAccount(accountId, notify = false)
else mastodonApi.unsubscribeAccount(accountId)
}
}.subscribe( }.subscribe(
{ relationship -> { relationship ->
relationshipData.postValue(Success(relationship)) relationshipData.postValue(Success(relationship))

View File

@ -164,8 +164,6 @@
android:layout_marginRight="14dp" android:layout_marginRight="14dp"
android:layout_marginBottom="14dp" android:layout_marginBottom="14dp"
android:contentDescription="@string/action_view_profile" android:contentDescription="@string/action_view_profile"
android:paddingRight="12dp"
android:paddingBottom="12dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
tools:ignore="RtlHardcoded,RtlSymmetry" tools:ignore="RtlHardcoded,RtlSymmetry"
tools:src="@drawable/avatar_default" /> tools:src="@drawable/avatar_default" />