cleanup entity classes and ViewThreadFragment (#1302)

* cleanup entity classes and ViewThreadFragment

* fix tests
This commit is contained in:
Konrad Pozniak 2019-06-02 21:23:18 +02:00 committed by GitHub
parent d863bc50e4
commit 2b2212e951
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 52 additions and 132 deletions

View file

@ -155,7 +155,8 @@ data class ConversationStatusEntity(
mentions = mentions, mentions = mentions,
application = null, application = null,
pinned = false, pinned = false,
poll = poll) poll = poll,
card = null)
} }
} }

View file

@ -26,13 +26,12 @@ import kotlinx.android.parcel.Parcelize
@Parcelize @Parcelize
data class Attachment( data class Attachment(
var id: String, val id: String,
var url: String, val url: String,
@SerializedName("preview_url") val previewUrl: String, @SerializedName("preview_url") val previewUrl: String,
@SerializedName("text_url") val textUrl: String?,
val meta: MetaData?, val meta: MetaData?,
var type: Type, val type: Type,
var description: String? val description: String?
) : Parcelable { ) : Parcelable {
@JsonAdapter(MediaTypeDeserializer::class) @JsonAdapter(MediaTypeDeserializer::class)

View file

@ -20,4 +20,7 @@ package com.keylesspalace.tusky.entity
* Created by charlag on 1/4/18. * Created by charlag on 1/4/18.
*/ */
data class MastoList(val id: String, val title: String) data class MastoList(
val id: String,
val title: String
)

View file

@ -31,8 +31,8 @@ data class Status(
val emojis: List<Emoji>, val emojis: List<Emoji>,
@SerializedName("reblogs_count") val reblogsCount: Int, @SerializedName("reblogs_count") val reblogsCount: Int,
@SerializedName("favourites_count") val favouritesCount: Int, @SerializedName("favourites_count") val favouritesCount: Int,
var reblogged: Boolean = false, var reblogged: Boolean,
var favourited: Boolean = false, var favourited: Boolean,
var sensitive: Boolean, var sensitive: Boolean,
@SerializedName("spoiler_text") val spoilerText: String, @SerializedName("spoiler_text") val spoilerText: String,
val visibility: Visibility, val visibility: Visibility,
@ -40,7 +40,8 @@ data class Status(
val mentions: Array<Mention>, val mentions: Array<Mention>,
val application: Application?, val application: Application?,
var pinned: Boolean?, var pinned: Boolean?,
val poll: Poll? val poll: Poll?,
val card: Card?
) { ) {
val actionableId: String val actionableId: String
@ -120,45 +121,17 @@ data class Status(
} }
class Mention { data class Mention (
var id: String? = null val id: String,
val url: String,
@SerializedName("acct") val username: String,
@SerializedName("username") val localUsername: String
)
var url: String? = null data class Application (
val name: String,
@SerializedName("acct") val website: String
var username: String? = null )
@SerializedName("username")
var localUsername: String? = null
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Mention
if (id != other.id) return false
if (url != other.url) return false
if (username != other.username) return false
if (localUsername != other.localUsername) return false
return true
}
override fun hashCode(): Int {
var result = id?.hashCode() ?: 0
result = 31 * result + (url?.hashCode() ?: 0)
result = 31 * result + (username?.hashCode() ?: 0)
result = 31 * result + (localUsername?.hashCode() ?: 0)
return result
}
}
class Application {
var name: String? = null
var website: String? = null
}
companion object { companion object {
const val MAX_MEDIA_ATTACHMENTS = 4 const val MAX_MEDIA_ATTACHMENTS = 4

View file

@ -18,7 +18,6 @@ package com.keylesspalace.tusky.fragment;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.text.TextUtils; import android.text.TextUtils;
@ -41,7 +40,6 @@ import com.keylesspalace.tusky.appstore.ReblogEvent;
import com.keylesspalace.tusky.appstore.StatusComposedEvent; import com.keylesspalace.tusky.appstore.StatusComposedEvent;
import com.keylesspalace.tusky.appstore.StatusDeletedEvent; import com.keylesspalace.tusky.appstore.StatusDeletedEvent;
import com.keylesspalace.tusky.di.Injectable; import com.keylesspalace.tusky.di.Injectable;
import com.keylesspalace.tusky.entity.Card;
import com.keylesspalace.tusky.entity.Poll; import com.keylesspalace.tusky.entity.Poll;
import com.keylesspalace.tusky.entity.Status; import com.keylesspalace.tusky.entity.Status;
import com.keylesspalace.tusky.entity.StatusContext; import com.keylesspalace.tusky.entity.StatusContext;
@ -92,7 +90,6 @@ public final class ViewThreadFragment extends SFragment implements
private RecyclerView recyclerView; private RecyclerView recyclerView;
private ThreadAdapter adapter; private ThreadAdapter adapter;
private String thisThreadsStatusId; private String thisThreadsStatusId;
private Card card;
private boolean alwaysShowSensitiveMedia; private boolean alwaysShowSensitiveMedia;
private int statusIndex = 0; private int statusIndex = 0;
@ -109,7 +106,7 @@ public final class ViewThreadFragment extends SFragment implements
}); });
public static ViewThreadFragment newInstance(String id) { public static ViewThreadFragment newInstance(String id) {
Bundle arguments = new Bundle(); Bundle arguments = new Bundle(1);
ViewThreadFragment fragment = new ViewThreadFragment(); ViewThreadFragment fragment = new ViewThreadFragment();
arguments.putString("id", id); arguments.putString("id", id);
fragment.setArguments(arguments); fragment.setArguments(arguments);
@ -147,10 +144,7 @@ public final class ViewThreadFragment extends SFragment implements
context, layoutManager.getOrientation()); context, layoutManager.getOrientation());
recyclerView.addItemDecoration(divider); recyclerView.addItemDecoration(divider);
Drawable threadLineDrawable = ThemeUtils.getDrawable(context, R.attr.conversation_thread_line_drawable, recyclerView.addItemDecoration(new ConversationLineItemDecoration(context));
R.drawable.conversation_thread_line_dark);
recyclerView.addItemDecoration(new ConversationLineItemDecoration(context,
threadLineDrawable));
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences( SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(
getActivity()); getActivity());
alwaysShowSensitiveMedia = accountManager.getActiveAccount().getAlwaysShowSensitiveMedia(); alwaysShowSensitiveMedia = accountManager.getActiveAccount().getAlwaysShowSensitiveMedia();
@ -158,6 +152,9 @@ public final class ViewThreadFragment extends SFragment implements
adapter.setMediaPreviewEnabled(mediaPreviewEnabled); adapter.setMediaPreviewEnabled(mediaPreviewEnabled);
boolean useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false); boolean useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false);
adapter.setUseAbsoluteTime(useAbsoluteTime); adapter.setUseAbsoluteTime(useAbsoluteTime);
boolean animateAvatars = preferences.getBoolean("animateGifAvatars", false);
adapter.setAnimateAvatar(animateAvatars);
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
statuses.clear(); statuses.clear();
@ -218,7 +215,6 @@ public final class ViewThreadFragment extends SFragment implements
public void onRefresh() { public void onRefresh() {
sendStatusRequest(thisThreadsStatusId); sendStatusRequest(thisThreadsStatusId);
sendThreadRequest(thisThreadsStatusId); sendThreadRequest(thisThreadsStatusId);
sendCardRequest(thisThreadsStatusId);
} }
@Override @Override
@ -235,11 +231,8 @@ public final class ViewThreadFragment extends SFragment implements
.as(autoDisposable(from(this))) .as(autoDisposable(from(this)))
.subscribe( .subscribe(
(newStatus) -> updateStatus(position, newStatus), (newStatus) -> updateStatus(position, newStatus),
(t) -> { (t) -> Log.d(getClass().getSimpleName(),
Log.d(getClass().getSimpleName(), "Failed to reblog status: " + status.getId(), t)
"Failed to reblog status: " + status.getId());
t.printStackTrace();
}
); );
} }
@ -252,10 +245,8 @@ public final class ViewThreadFragment extends SFragment implements
.as(autoDisposable(from(this))) .as(autoDisposable(from(this)))
.subscribe( .subscribe(
(newStatus) -> updateStatus(position, newStatus), (newStatus) -> updateStatus(position, newStatus),
(t) -> { (t) -> Log.d(getClass().getSimpleName(),
Log.d(getClass().getSimpleName(), "Failed to favourite status: " + status.getId()); "Failed to favourite status: " + status.getId(), t)
t.printStackTrace();
}
); );
} }
@ -487,26 +478,6 @@ public final class ViewThreadFragment extends SFragment implements
callList.add(call); callList.add(call);
} }
private void sendCardRequest(final String id) {
Call<Card> call = mastodonApi.statusCard(id);
call.enqueue(new Callback<Card>() {
@Override
public void onResponse(@NonNull Call<Card> call, @NonNull Response<Card> response) {
if (response.isSuccessful()) {
showCard(response.body());
} else {
onThreadRequestFailure(id);
}
}
@Override
public void onFailure(@NonNull Call<Card> call, @NonNull Throwable t) {
Log.e(TAG, "Error fetching status card");
}
});
callList.add(call);
}
private void onThreadRequestFailure(final String id) { private void onThreadRequestFailure(final String id) {
View view = getView(); View view = getView();
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
@ -515,7 +486,6 @@ public final class ViewThreadFragment extends SFragment implements
.setAction(R.string.action_retry, v -> { .setAction(R.string.action_retry, v -> {
sendThreadRequest(id); sendThreadRequest(id);
sendStatusRequest(id); sendStatusRequest(id);
sendCardRequest(id);
}) })
.show(); .show();
} else { } else {
@ -534,14 +504,7 @@ public final class ViewThreadFragment extends SFragment implements
int i = statusIndex; int i = statusIndex;
statuses.add(i, status); statuses.add(i, status);
adapter.setDetailedStatusPosition(i); adapter.setDetailedStatusPosition(i);
StatusViewData.Concrete viewData = statuses.getPairedItem(i); adapter.addItem(i, statuses.getPairedItem(i));
if (viewData.getCard() == null && card != null) {
viewData = new StatusViewData.Builder(viewData)
.setCard(card)
.createStatusViewData();
}
statuses.setPairedItem(i, viewData);
adapter.addItem(i, viewData);
updateRevealIcon(); updateRevealIcon();
return i; return i;
} }
@ -578,13 +541,7 @@ public final class ViewThreadFragment extends SFragment implements
// everything except one), re-insert the remaining status here. // everything except one), re-insert the remaining status here.
statuses.add(statusIndex, mainStatus); statuses.add(statusIndex, mainStatus);
StatusViewData.Concrete viewData = statuses.getPairedItem(statusIndex); StatusViewData.Concrete viewData = statuses.getPairedItem(statusIndex);
if (viewData.getCard() == null && card != null) {
viewData = new StatusViewData.Builder(viewData)
.setCard(card)
.createStatusViewData();
statuses.setPairedItem(statusIndex, viewData);
}
adapter.addItem(statusIndex, viewData); adapter.addItem(statusIndex, viewData);
} }
@ -605,28 +562,10 @@ public final class ViewThreadFragment extends SFragment implements
updateRevealIcon(); updateRevealIcon();
} }
private void showCard(Card card) {
this.card = card;
if (statusIndex >= 0 && statusIndex < statuses.size()) {
StatusViewData.Concrete newViewData =
new StatusViewData.Builder(statuses.getPairedItem(statusIndex))
.setCard(card)
.createStatusViewData();
statuses.setPairedItem(statusIndex, newViewData);
adapter.setItem(statusIndex, newViewData, true);
}
}
public void clear() {
statuses.clear();
adapter.clear();
}
private void handleFavEvent(FavoriteEvent event) { private void handleFavEvent(FavoriteEvent event) {
Pair<Integer, Status> posAndStatus = findStatusAndPos(event.getStatusId()); Pair<Integer, Status> posAndStatus = findStatusAndPos(event.getStatusId());
if (posAndStatus == null) return; if (posAndStatus == null) return;
//noinspection ConstantConditions
boolean favourite = event.getFavourite(); boolean favourite = event.getFavourite();
posAndStatus.second.setFavourited(favourite); posAndStatus.second.setFavourited(favourite);
@ -648,7 +587,7 @@ public final class ViewThreadFragment extends SFragment implements
private void handleReblogEvent(ReblogEvent event) { private void handleReblogEvent(ReblogEvent event) {
Pair<Integer, Status> posAndStatus = findStatusAndPos(event.getStatusId()); Pair<Integer, Status> posAndStatus = findStatusAndPos(event.getStatusId());
if (posAndStatus == null) return; if (posAndStatus == null) return;
//noinspection ConstantConditions
boolean reblog = event.getReblog(); boolean reblog = event.getReblog();
posAndStatus.second.setReblogged(reblog); posAndStatus.second.setReblogged(reblog);

View file

@ -312,11 +312,6 @@ public interface MastodonApi {
@Field("grant_type") String grantType @Field("grant_type") String grantType
); );
@GET("/api/v1/statuses/{id}/card")
Call<Card> statusCard(
@Path("id") String statusId
);
@GET("/api/v1/lists") @GET("/api/v1/lists")
Single<List<MastoList>> getLists(); Single<List<MastoList>> getLists();

View file

@ -229,7 +229,8 @@ class TimelineRepositoryImpl(
mentions = mentions, mentions = mentions,
application = application, application = application,
pinned = false, pinned = false,
poll = poll poll = poll,
card = null
) )
} }
val status = if (reblog != null) { val status = if (reblog != null) {
@ -254,7 +255,8 @@ class TimelineRepositoryImpl(
mentions = arrayOf(), mentions = arrayOf(),
application = null, application = null,
pinned = false, pinned = false,
poll = null poll = null,
card = null
) )
} else { } else {
Status( Status(
@ -278,7 +280,8 @@ class TimelineRepositoryImpl(
mentions = mentions, mentions = mentions,
application = application, application = application,
pinned = false, pinned = false,
poll = poll poll = poll,
card = null
) )
} }
return Either.Right(status) return Either.Right(status)

View file

@ -64,6 +64,7 @@ public final class ViewDataUtils {
)) ))
.setCollapsed(true) .setCollapsed(true)
.setPoll(visibleStatus.getPoll()) .setPoll(visibleStatus.getPoll())
.setCard(visibleStatus.getCard())
.setIsBot(visibleStatus.getAccount().getBot()) .setIsBot(visibleStatus.getAccount().getBot())
.createStatusViewData(); .createStatusViewData();
} }

View file

@ -23,8 +23,12 @@ import android.view.View
import com.keylesspalace.tusky.R import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.adapter.ThreadAdapter import com.keylesspalace.tusky.adapter.ThreadAdapter
import com.keylesspalace.tusky.util.ThemeUtils
class ConversationLineItemDecoration(private val context: Context, private val divider: Drawable) : RecyclerView.ItemDecoration() { class ConversationLineItemDecoration(private val context: Context) : RecyclerView.ItemDecoration() {
private val divider: Drawable = ThemeUtils.getDrawable(context, R.attr.conversation_thread_line_drawable,
R.drawable.conversation_thread_line_dark)
override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
val dividerStart = parent.paddingStart + context.resources.getDimensionPixelSize(R.dimen.status_line_margin_start) val dividerStart = parent.paddingStart + context.resources.getDimensionPixelSize(R.dimen.status_line_margin_start)

View file

@ -85,7 +85,8 @@ class BottomSheetActivityTest {
arrayOf(), arrayOf(),
null, null,
pinned = false, pinned = false,
poll = null poll = null,
card = null
) )
private val statusCallback = FakeSearchResults(status) private val statusCallback = FakeSearchResults(status)

View file

@ -315,7 +315,8 @@ class TimelineRepositoryTest {
pinned = false, pinned = false,
reblog = null, reblog = null,
url = "http://example.com/statuses/$id", url = "http://example.com/statuses/$id",
poll = null poll = null,
card = null
) )
} }