Code cleanups (#3264)

* Kotlin 1.8.10

https://github.com/JetBrains/kotlin/releases/tag/v1.8.10

* Migrate onActivityCreated to onViewCreated

* More final modifiers

* Java Cleanups

* Kotlin cleanups

* More final modifiers

* Const value TOOLBAR_HIDE_DELAY_MS

* Revert
This commit is contained in:
Goooler 2023-02-21 02:58:37 +08:00 committed by GitHub
parent 0baf3fe467
commit cfea5700b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 123 additions and 133 deletions

View File

@ -239,8 +239,6 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab
} }
if (permissionsToRequest.isEmpty()) { if (permissionsToRequest.isEmpty()) {
int[] permissionsAlreadyGranted = new int[permissions.length]; int[] permissionsAlreadyGranted = new int[permissions.length];
for (int i = 0; i < permissionsAlreadyGranted.length; ++i)
permissionsAlreadyGranted[i] = PackageManager.PERMISSION_GRANTED;
requester.onRequestPermissionsResult(permissions, permissionsAlreadyGranted); requester.onRequestPermissionsResult(permissions, permissionsAlreadyGranted);
return; return;
} }

View File

@ -113,7 +113,6 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector {
lifecycleScope.launch { lifecycleScope.launch {
viewModel.events.collect { event -> viewModel.events.collect { event ->
@Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA")
when (event) { when (event) {
Event.CREATE_ERROR -> showMessage(R.string.error_create_list) Event.CREATE_ERROR -> showMessage(R.string.error_create_list)
Event.RENAME_ERROR -> showMessage(R.string.error_rename_list) Event.RENAME_ERROR -> showMessage(R.string.error_rename_list)

View File

@ -67,7 +67,7 @@ import java.util.List;
import at.connyduck.sparkbutton.helpers.Utils; import at.connyduck.sparkbutton.helpers.Utils;
public class NotificationsAdapter extends RecyclerView.Adapter { public class NotificationsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public interface AdapterDataSource<T> { public interface AdapterDataSource<T> {
int getItemCount(); int getItemCount();
@ -87,12 +87,12 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
private static final InputFilter[] COLLAPSE_INPUT_FILTER = new InputFilter[]{SmartLengthInputFilter.INSTANCE}; private static final InputFilter[] COLLAPSE_INPUT_FILTER = new InputFilter[]{SmartLengthInputFilter.INSTANCE};
private static final InputFilter[] NO_INPUT_FILTER = new InputFilter[0]; private static final InputFilter[] NO_INPUT_FILTER = new InputFilter[0];
private String accountId; private final String accountId;
private StatusDisplayOptions statusDisplayOptions; private StatusDisplayOptions statusDisplayOptions;
private StatusActionListener statusListener; private final StatusActionListener statusListener;
private NotificationActionListener notificationActionListener; private final NotificationActionListener notificationActionListener;
private AccountActionListener accountActionListener; private final AccountActionListener accountActionListener;
private AdapterDataSource<NotificationViewData> dataSource; private final AdapterDataSource<NotificationViewData> dataSource;
private final AbsoluteTimeFormatter absoluteTimeFormatter = new AbsoluteTimeFormatter(); private final AbsoluteTimeFormatter absoluteTimeFormatter = new AbsoluteTimeFormatter();
public NotificationsAdapter(String accountId, public NotificationsAdapter(String accountId,
@ -164,11 +164,11 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
} }
@Override @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @NonNull List payloads) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @NonNull List<Object> payloads) {
bindViewHolder(viewHolder, position, payloads); bindViewHolder(viewHolder, position, payloads);
} }
private void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @Nullable List payloads) { private void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @Nullable List<Object> payloads) {
Object payloadForHolder = payloads != null && !payloads.isEmpty() ? payloads.get(0) : null; Object payloadForHolder = payloads != null && !payloads.isEmpty() ? payloads.get(0) : null;
if (position < this.dataSource.getItemCount()) { if (position < this.dataSource.getItemCount()) {
NotificationViewData notification = dataSource.getItemAt(position); NotificationViewData notification = dataSource.getItemAt(position);
@ -234,7 +234,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
concreteNotification.getId()); concreteNotification.getId());
} else { } else {
if (payloadForHolder instanceof List) if (payloadForHolder instanceof List)
for (Object item : (List) payloadForHolder) { for (Object item : (List<?>) payloadForHolder) {
if (StatusBaseViewHolder.Key.KEY_CREATED.equals(item) && statusViewData != null) { if (StatusBaseViewHolder.Key.KEY_CREATED.equals(item) && statusViewData != null) {
holder.setCreatedAt(statusViewData.getStatus().getActionableStatus().getCreatedAt()); holder.setCreatedAt(statusViewData.getStatus().getActionableStatus().getCreatedAt());
} }
@ -353,11 +353,11 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
} }
private static class FollowViewHolder extends RecyclerView.ViewHolder { private static class FollowViewHolder extends RecyclerView.ViewHolder {
private TextView message; private final TextView message;
private TextView usernameView; private final TextView usernameView;
private TextView displayNameView; private final TextView displayNameView;
private ImageView avatar; private final ImageView avatar;
private StatusDisplayOptions statusDisplayOptions; private final StatusDisplayOptions statusDisplayOptions;
FollowViewHolder(View itemView, StatusDisplayOptions statusDisplayOptions) { FollowViewHolder(View itemView, StatusDisplayOptions statusDisplayOptions) {
super(itemView); super(itemView);
@ -414,7 +414,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
private final TextView contentWarningDescriptionTextView; private final TextView contentWarningDescriptionTextView;
private final Button contentWarningButton; private final Button contentWarningButton;
private final Button contentCollapseButton; // TODO: This code SHOULD be based on StatusBaseViewHolder private final Button contentCollapseButton; // TODO: This code SHOULD be based on StatusBaseViewHolder
private StatusDisplayOptions statusDisplayOptions; private final StatusDisplayOptions statusDisplayOptions;
private final AbsoluteTimeFormatter absoluteTimeFormatter; private final AbsoluteTimeFormatter absoluteTimeFormatter;
private String accountId; private String accountId;
@ -422,9 +422,9 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
private NotificationActionListener notificationActionListener; private NotificationActionListener notificationActionListener;
private StatusViewData.Concrete statusViewData; private StatusViewData.Concrete statusViewData;
private int avatarRadius48dp; private final int avatarRadius48dp;
private int avatarRadius36dp; private final int avatarRadius36dp;
private int avatarRadius24dp; private final int avatarRadius24dp;
StatusNotificationViewHolder( StatusNotificationViewHolder(
View itemView, View itemView,

View File

@ -25,7 +25,6 @@ import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.text.HtmlCompat; import androidx.core.text.HtmlCompat;
import androidx.core.view.ViewKt;
import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -76,46 +75,46 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
public static final String KEY_CREATED = "created"; public static final String KEY_CREATED = "created";
} }
private TextView displayName; private final TextView displayName;
private TextView username; private final TextView username;
private ImageButton replyButton; private final ImageButton replyButton;
private TextView replyCountLabel; private final TextView replyCountLabel;
private SparkButton reblogButton; private final SparkButton reblogButton;
private SparkButton favouriteButton; private final SparkButton favouriteButton;
private SparkButton bookmarkButton; private final SparkButton bookmarkButton;
private ImageButton moreButton; private final ImageButton moreButton;
private ConstraintLayout mediaContainer; private final ConstraintLayout mediaContainer;
protected MediaPreviewLayout mediaPreview; protected final MediaPreviewLayout mediaPreview;
private TextView sensitiveMediaWarning; private final TextView sensitiveMediaWarning;
private View sensitiveMediaShow; private final View sensitiveMediaShow;
protected TextView[] mediaLabels; protected final TextView[] mediaLabels;
protected CharSequence[] mediaDescriptions; protected final CharSequence[] mediaDescriptions;
private MaterialButton contentWarningButton; private final MaterialButton contentWarningButton;
private ImageView avatarInset; private final ImageView avatarInset;
public ImageView avatar; public final ImageView avatar;
public TextView metaInfo; public final TextView metaInfo;
public TextView content; public final TextView content;
public TextView contentWarningDescription; public final TextView contentWarningDescription;
private RecyclerView pollOptions; private final RecyclerView pollOptions;
private TextView pollDescription; private final TextView pollDescription;
private Button pollButton; private final Button pollButton;
private LinearLayout cardView; private final LinearLayout cardView;
private LinearLayout cardInfo; private final LinearLayout cardInfo;
private ShapeableImageView cardImage; private final ShapeableImageView cardImage;
private TextView cardTitle; private final TextView cardTitle;
private TextView cardDescription; private final TextView cardDescription;
private TextView cardUrl; private final TextView cardUrl;
private PollAdapter pollAdapter; private final PollAdapter pollAdapter;
private final NumberFormat numberFormat = NumberFormat.getNumberInstance(); private final NumberFormat numberFormat = NumberFormat.getNumberInstance();
private final AbsoluteTimeFormatter absoluteTimeFormatter = new AbsoluteTimeFormatter(); private final AbsoluteTimeFormatter absoluteTimeFormatter = new AbsoluteTimeFormatter();
protected int avatarRadius48dp; protected final int avatarRadius48dp;
private int avatarRadius36dp; private final int avatarRadius36dp;
private int avatarRadius24dp; private final int avatarRadius24dp;
private final Drawable mediaPreviewUnloaded; private final Drawable mediaPreviewUnloaded;
@ -325,8 +324,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} else { } else {
long then = createdAt.getTime(); long then = createdAt.getTime();
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
String readout = TimestampUtils.getRelativeTimeSpanString(metaInfo.getContext(), then, now); timestampText = TimestampUtils.getRelativeTimeSpanString(metaInfo.getContext(), then, now);
timestampText = readout;
} }
} }
@ -598,9 +596,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
final String accountId, final String accountId,
final String statusContent, final String statusContent,
StatusDisplayOptions statusDisplayOptions) { StatusDisplayOptions statusDisplayOptions) {
View.OnClickListener profileButtonClickListener = button -> { View.OnClickListener profileButtonClickListener = button -> listener.onViewAccount(accountId);
listener.onViewAccount(accountId);
};
avatar.setOnClickListener(profileButtonClickListener); avatar.setOnClickListener(profileButtonClickListener);
displayName.setOnClickListener(profileButtonClickListener); displayName.setOnClickListener(profileButtonClickListener);

View File

@ -44,8 +44,8 @@ public class StatusViewHolder extends StatusBaseViewHolder {
private static final InputFilter[] COLLAPSE_INPUT_FILTER = new InputFilter[]{SmartLengthInputFilter.INSTANCE}; private static final InputFilter[] COLLAPSE_INPUT_FILTER = new InputFilter[]{SmartLengthInputFilter.INSTANCE};
private static final InputFilter[] NO_INPUT_FILTER = new InputFilter[0]; private static final InputFilter[] NO_INPUT_FILTER = new InputFilter[0];
private TextView statusInfo; private final TextView statusInfo;
private Button contentCollapseButton; private final Button contentCollapseButton;
public StatusViewHolder(View itemView) { public StatusViewHolder(View itemView) {
super(itemView); super(itemView);

View File

@ -941,13 +941,13 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
} }
private fun getFullUsername(account: Account): String { private fun getFullUsername(account: Account): String {
if (account.isRemote()) { return if (account.isRemote()) {
return "@" + account.username "@" + account.username
} else { } else {
val localUsername = account.localUsername val localUsername = account.localUsername
// Note: !! here will crash if this pane is ever shown to a logged-out user. With AccountActivity this is believed to be impossible. // Note: !! here will crash if this pane is ever shown to a logged-out user. With AccountActivity this is believed to be impossible.
val domain = accountManager.activeAccount!!.domain val domain = accountManager.activeAccount!!.domain
return "@$localUsername@$domain" "@$localUsername@$domain"
} }
} }

View File

@ -697,7 +697,7 @@ class ComposeActivity :
var oneMediaWithoutDescription = false var oneMediaWithoutDescription = false
for (media in viewModel.media.value) { for (media in viewModel.media.value) {
if (media.description == null || media.description.isEmpty()) { if (media.description.isNullOrEmpty()) {
oneMediaWithoutDescription = true oneMediaWithoutDescription = true
break break
} }

View File

@ -70,9 +70,7 @@ class FocusIndicatorView
if (event.actionMasked == MotionEvent.ACTION_CANCEL) if (event.actionMasked == MotionEvent.ACTION_CANCEL)
return false return false
val imageSize = this.imageSize val imageSize = this.imageSize ?: return false
if (imageSize == null)
return false
// Convert touch xy to point inside image // Convert touch xy to point inside image
focus = Attachment.Focus(axisToFocus(event.x, imageSize.x, this.width), -axisToFocus(event.y, imageSize.y, this.height)) focus = Attachment.Focus(axisToFocus(event.x, imageSize.x, this.width), -axisToFocus(event.y, imageSize.y, this.height))

View File

@ -44,7 +44,7 @@ import javax.inject.Inject
class DraftHelper @Inject constructor( class DraftHelper @Inject constructor(
val context: Context, val context: Context,
val okHttpClient: OkHttpClient, private val okHttpClient: OkHttpClient,
db: AppDatabase db: AppDatabase
) { ) {
@ -140,7 +140,7 @@ class DraftHelper @Inject constructor(
} }
} }
suspend fun deleteDraftAndAttachments(draft: DraftEntity) { private suspend fun deleteDraftAndAttachments(draft: DraftEntity) {
deleteAttachments(draft) deleteAttachments(draft)
draftDao.delete(draft.id) draftDao.delete(draft.id)
} }

View File

@ -33,7 +33,7 @@ class DraftsViewModel @Inject constructor(
val database: AppDatabase, val database: AppDatabase,
val accountManager: AccountManager, val accountManager: AccountManager,
val api: MastodonApi, val api: MastodonApi,
val draftHelper: DraftHelper private val draftHelper: DraftHelper
) : ViewModel() { ) : ViewModel() {
val drafts = Pager( val drafts = Pager(

View File

@ -55,8 +55,8 @@ class ProxyPreferencesFragment : PreferenceFragmentCompat() {
val portErrorMessage = getString( val portErrorMessage = getString(
R.string.pref_title_http_proxy_port_message, R.string.pref_title_http_proxy_port_message,
ProxyConfiguration.MIN_PROXY_PORT, MIN_PROXY_PORT,
ProxyConfiguration.MAX_PROXY_PORT MAX_PROXY_PORT
) )
validatedEditTextPreference(portErrorMessage, ProxyConfiguration::isValidProxyPort) { validatedEditTextPreference(portErrorMessage, ProxyConfiguration::isValidProxyPort) {

View File

@ -55,7 +55,7 @@ abstract class TimelineViewModel(
private val api: MastodonApi, private val api: MastodonApi,
private val eventHub: EventHub, private val eventHub: EventHub,
protected val accountManager: AccountManager, protected val accountManager: AccountManager,
protected val sharedPreferences: SharedPreferences, private val sharedPreferences: SharedPreferences,
private val filterModel: FilterModel private val filterModel: FilterModel
) : ViewModel() { ) : ViewModel() {
@ -69,7 +69,7 @@ abstract class TimelineViewModel(
private set private set
protected var alwaysShowSensitiveMedia = false protected var alwaysShowSensitiveMedia = false
protected var alwaysOpenSpoilers = false private var alwaysOpenSpoilers = false
private var filterRemoveReplies = false private var filterRemoveReplies = false
private var filterRemoveReblogs = false private var filterRemoveReblogs = false
protected var readingOrder: ReadingOrder = ReadingOrder.OLDEST_FIRST protected var readingOrder: ReadingOrder = ReadingOrder.OLDEST_FIRST

View File

@ -256,7 +256,7 @@ class ViewThreadFragment : SFragment(), OnRefreshListener, StatusActionListener,
* When started the job will wait `delayMs` then show `view`. If the job is cancelled at * When started the job will wait `delayMs` then show `view`. If the job is cancelled at
* any time `view` is hidden. * any time `view` is hidden.
*/ */
@CheckResult() @CheckResult
private fun getProgressBarJob(view: View, delayMs: Long) = viewLifecycleOwner.lifecycleScope.launch( private fun getProgressBarJob(view: View, delayMs: Long) = viewLifecycleOwner.lifecycleScope.launch(
start = CoroutineStart.LAZY start = CoroutineStart.LAZY
) { ) {

View File

@ -44,7 +44,7 @@ class DraftsAlert @Inject constructor(db: AppDatabase) {
@Inject @Inject
lateinit var accountManager: AccountManager lateinit var accountManager: AccountManager
public fun <T> observeInContext(context: T, showAlert: Boolean) where T : Context, T : LifecycleOwner { fun <T> observeInContext(context: T, showAlert: Boolean) where T : Context, T : LifecycleOwner {
accountManager.activeAccount?.let { activeAccount -> accountManager.activeAccount?.let { activeAccount ->
val coroutineScope = context.lifecycleScope val coroutineScope = context.lifecycleScope
@ -63,7 +63,7 @@ class DraftsAlert @Inject constructor(db: AppDatabase) {
AlertDialog.Builder(context) AlertDialog.Builder(context)
.setTitle(R.string.action_post_failed) .setTitle(R.string.action_post_failed)
.setMessage( .setMessage(
context.getResources().getQuantityString(R.plurals.action_post_failed_detail, count) context.resources.getQuantityString(R.plurals.action_post_failed_detail, count)
) )
.setPositiveButton(R.string.action_post_failed_show_drafts) { _: DialogInterface?, _: Int -> .setPositiveButton(R.string.action_post_failed_show_drafts) { _: DialogInterface?, _: Int ->
clearDraftsAlert(coroutineScope, activeAccountId) // User looked at drafts clearDraftsAlert(coroutineScope, activeAccountId) // User looked at drafts
@ -78,7 +78,7 @@ class DraftsAlert @Inject constructor(db: AppDatabase) {
} }
} }
} else { } else {
draftsNeedUserAlert.observe(context) { _ -> draftsNeedUserAlert.observe(context) {
Log.d(TAG, "User id $activeAccountId: Clean out notification-worthy drafts") Log.d(TAG, "User id $activeAccountId: Clean out notification-worthy drafts")
clearDraftsAlert(coroutineScope, activeAccountId) clearDraftsAlert(coroutineScope, activeAccountId)
} }
@ -91,7 +91,7 @@ class DraftsAlert @Inject constructor(db: AppDatabase) {
/** /**
* Clear drafts alert for specified user * Clear drafts alert for specified user
*/ */
fun clearDraftsAlert(coroutineScope: LifecycleCoroutineScope, id: Long) { private fun clearDraftsAlert(coroutineScope: LifecycleCoroutineScope, id: Long) {
coroutineScope.launch { coroutineScope.launch {
draftDao.draftsClearNeedUserAlert(id) draftDao.draftsClearNeedUserAlert(id)
} }

View File

@ -40,7 +40,7 @@ class ViewModelFactory @Inject constructor(private val viewModels: MutableMap<Cl
} }
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
@MapKey @MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>) internal annotation class ViewModelKey(val value: KClass<out ViewModel>)

View File

@ -137,7 +137,7 @@ data class Status(
) )
} }
fun getEditableText(): String { private fun getEditableText(): String {
val contentSpanned = content.parseAsMastodonHtml() val contentSpanned = content.parseAsMastodonHtml()
val builder = SpannableStringBuilder(content.parseAsMastodonHtml()) val builder = SpannableStringBuilder(content.parseAsMastodonHtml())
for (span in contentSpanned.getSpans(0, content.length, URLSpan::class.java)) { for (span in contentSpanned.getSpans(0, content.length, URLSpan::class.java)) {

View File

@ -172,20 +172,20 @@ public class NotificationsFragment extends SFragment implements
// Each element is either a Notification for loading data or a Placeholder // Each element is either a Notification for loading data or a Placeholder
private final PairedList<Either<Placeholder, Notification>, NotificationViewData> notifications private final PairedList<Either<Placeholder, Notification>, NotificationViewData> notifications
= new PairedList<>(new Function<Either<Placeholder, Notification>, NotificationViewData>() { = new PairedList<>(new Function<>() {
@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 = input.asRight()
.rewriteToStatusTypeIfNeeded(accountManager.getActiveAccount().getAccountId()); .rewriteToStatusTypeIfNeeded(accountManager.getActiveAccount().getAccountId());
boolean sensitiveStatus = notification.getStatus() != null && notification.getStatus().getActionableStatus().getSensitive(); boolean sensitiveStatus = notification.getStatus() != null && notification.getStatus().getActionableStatus().getSensitive();
return ViewDataUtils.notificationToViewData( return ViewDataUtils.notificationToViewData(
notification, notification,
alwaysShowSensitiveMedia || !sensitiveStatus, alwaysShowSensitiveMedia || !sensitiveStatus,
alwaysOpenSpoiler, alwaysOpenSpoiler,
true true
); );
} else { } else {
return new NotificationViewData.Placeholder(input.asLeft().id, false); return new NotificationViewData.Placeholder(input.asLeft().id, false);
@ -311,8 +311,8 @@ public class NotificationsFragment extends SFragment implements
} }
@Override @Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onViewCreated(view, savedInstanceState);
Activity activity = getActivity(); Activity activity = getActivity();
if (activity == null) throw new AssertionError("Activity is null"); if (activity == null) throw new AssertionError("Activity is null");
@ -344,7 +344,7 @@ public class NotificationsFragment extends SFragment implements
} }
@Override @Override
public void onLoadMore(int totalItemsCount, RecyclerView view) { public void onLoadMore(int totalItemsCount, @NonNull RecyclerView view) {
NotificationsFragment.this.onLoadMore(); NotificationsFragment.this.onLoadMore();
} }
}; };
@ -352,23 +352,23 @@ public class NotificationsFragment extends SFragment implements
binding.recyclerView.addOnScrollListener(scrollListener); binding.recyclerView.addOnScrollListener(scrollListener);
eventHub.getEvents() eventHub.getEvents()
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.to(autoDisposable(from(this, Lifecycle.Event.ON_DESTROY))) .to(autoDisposable(from(this, Lifecycle.Event.ON_DESTROY)))
.subscribe(event -> { .subscribe(event -> {
if (event instanceof FavoriteEvent) { if (event instanceof FavoriteEvent) {
setFavouriteForStatus(((FavoriteEvent) event).getStatusId(), ((FavoriteEvent) event).getFavourite()); setFavouriteForStatus(((FavoriteEvent) event).getStatusId(), ((FavoriteEvent) event).getFavourite());
} else if (event instanceof BookmarkEvent) { } else if (event instanceof BookmarkEvent) {
setBookmarkForStatus(((BookmarkEvent) event).getStatusId(), ((BookmarkEvent) event).getBookmark()); setBookmarkForStatus(((BookmarkEvent) event).getStatusId(), ((BookmarkEvent) event).getBookmark());
} else if (event instanceof ReblogEvent) { } else if (event instanceof ReblogEvent) {
setReblogForStatus(((ReblogEvent) event).getStatusId(), ((ReblogEvent) event).getReblog()); setReblogForStatus(((ReblogEvent) event).getStatusId(), ((ReblogEvent) event).getReblog());
} else if (event instanceof PinEvent) { } else if (event instanceof PinEvent) {
setPinForStatus(((PinEvent) event).getStatusId(), ((PinEvent) event).getPinned()); setPinForStatus(((PinEvent) event).getStatusId(), ((PinEvent) event).getPinned());
} else if (event instanceof BlockEvent) { } else if (event instanceof BlockEvent) {
removeAllByAccountId(((BlockEvent) event).getAccountId()); removeAllByAccountId(((BlockEvent) event).getAccountId());
} else if (event instanceof PreferenceChangedEvent) { } else if (event instanceof PreferenceChangedEvent) {
onPreferenceChanged(((PreferenceChangedEvent) event).getPreferenceKey()); onPreferenceChanged(((PreferenceChangedEvent) event).getPreferenceKey());
} }
}); });
} }
@Override @Override
@ -483,7 +483,6 @@ public class NotificationsFragment extends SFragment implements
Notification notification = notifications.get(position).asRight(); Notification notification = notifications.get(position).asRight();
Status status = notification.getStatus(); Status status = notification.getStatus();
if (status == null) return; if (status == null) return;
;
super.viewThread(status.getActionableId(), status.getActionableStatus().getUrl()); super.viewThread(status.getActionableId(), status.getActionableStatus().getUrl());
} }
@ -1171,20 +1170,20 @@ public class NotificationsFragment extends SFragment implements
new AsyncDifferConfig.Builder<>(diffCallback).build()); new AsyncDifferConfig.Builder<>(diffCallback).build());
private final NotificationsAdapter.AdapterDataSource<NotificationViewData> dataSource = private final NotificationsAdapter.AdapterDataSource<NotificationViewData> dataSource =
new NotificationsAdapter.AdapterDataSource<NotificationViewData>() { new NotificationsAdapter.AdapterDataSource<>() {
@Override @Override
public int getItemCount() { public int getItemCount() {
return differ.getCurrentList().size(); return differ.getCurrentList().size();
} }
@Override @Override
public NotificationViewData getItemAt(int pos) { public NotificationViewData getItemAt(int pos) {
return differ.getCurrentList().get(pos); return differ.getCurrentList().get(pos);
} }
}; };
private static final DiffUtil.ItemCallback<NotificationViewData> diffCallback private static final DiffUtil.ItemCallback<NotificationViewData> diffCallback
= new DiffUtil.ItemCallback<NotificationViewData>() { = new DiffUtil.ItemCallback<>() {
@Override @Override
public boolean areItemsTheSame(NotificationViewData oldItem, NotificationViewData newItem) { public boolean areItemsTheSame(NotificationViewData oldItem, NotificationViewData newItem) {

View File

@ -57,10 +57,13 @@ class ViewVideoFragment : ViewMediaFragment() {
mediaController.hide() mediaController.hide()
} }
private lateinit var mediaActivity: ViewMediaActivity private lateinit var mediaActivity: ViewMediaActivity
private val TOOLBAR_HIDE_DELAY_MS = 3000L
private lateinit var mediaController: MediaController private lateinit var mediaController: MediaController
private var isAudio = false private var isAudio = false
companion object {
private const val TOOLBAR_HIDE_DELAY_MS = 3000L
}
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
super.onAttach(context) super.onAttach(context)
videoActionsListener = context as VideoActionsListener videoActionsListener = context as VideoActionsListener
@ -188,10 +191,8 @@ class ViewVideoFragment : ViewMediaFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val attachment = arguments?.getParcelable<Attachment>(ARG_ATTACHMENT) val attachment = arguments?.getParcelable<Attachment>(ARG_ATTACHMENT)
?: throw IllegalArgumentException("attachment has to be set")
if (attachment == null) {
throw IllegalArgumentException("attachment has to be set")
}
val url = attachment.url val url = attachment.url
isAudio = attachment.type == Attachment.Type.AUDIO isAudio = attachment.type == Attachment.Type.AUDIO

View File

@ -38,7 +38,7 @@ class ListStatusAccessibilityDelegate(
private val context: Context get() = recyclerView.context private val context: Context get() = recyclerView.context
private val itemDelegate = object : RecyclerViewAccessibilityDelegate.ItemDelegate(this) { private val itemDelegate = object : ItemDelegate(this) {
override fun onInitializeAccessibilityNodeInfo( override fun onInitializeAccessibilityNodeInfo(
host: View, host: View,
info: AccessibilityNodeInfoCompat info: AccessibilityNodeInfoCompat

View File

@ -30,7 +30,7 @@ val Locale.modernLanguageCode: String
fun Locale.getTuskyDisplayName(context: Context): String { fun Locale.getTuskyDisplayName(context: Context): String {
return context.getString( return context.getString(
R.string.language_display_name_format, R.string.language_display_name_format,
this?.displayLanguage, displayLanguage,
this?.getDisplayLanguage(this) getDisplayLanguage(this)
) )
} }

View File

@ -6,7 +6,7 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.disposables.Disposable
open class RxAwareViewModel : ViewModel() { open class RxAwareViewModel : ViewModel() {
val disposables = CompositeDisposable() private val disposables = CompositeDisposable()
fun Disposable.autoDispose() = disposables.add(this) fun Disposable.autoDispose() = disposables.add(this)

View File

@ -147,12 +147,12 @@ fun highlightSpans(text: Spannable, colour: Int) {
val length = text.length val length = text.length
var start = 0 var start = 0
var end = 0 var end = 0
while (end >= 0 && end < length && start >= 0) { while (end in 0 until length && start >= 0) {
// Search for url first because it can contain the other characters // Search for url first because it can contain the other characters
val found = findPattern(string, end) val found = findPattern(string, end)
start = found.start start = found.start
end = found.end end = found.end
if (start >= 0 && end > start) { if (start in 0 until end) {
text.setSpan(getSpan(found.matchType, string, colour, start, end), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE) text.setSpan(getSpan(found.matchType, string, colour, start, end), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
start += finders[found.matchType]!!.searchPrefixWidth start += finders[found.matchType]!!.searchPrefixWidth
} }

View File

@ -237,7 +237,6 @@ class BottomSheetActivityTest {
init { init {
mastodonApi = api mastodonApi = api
@Suppress("UNCHECKED_CAST")
bottomSheet = mock() bottomSheet = mock()
} }

View File

@ -30,7 +30,7 @@ filemoji-compat = "3.2.7"
glide = "4.13.2" glide = "4.13.2"
glide-animation-plugin = "2.23.0" glide-animation-plugin = "2.23.0"
gson = "2.9.0" gson = "2.9.0"
kotlin = "1.7.10" kotlin = "1.8.10"
image-cropper = "4.3.1" image-cropper = "4.3.1"
lifecycle = "2.5.1" lifecycle = "2.5.1"
material = "1.6.1" material = "1.6.1"