Merge pull request #6649 from thundernest/change_messagetopview_to_kotlin

Changed `MessageTopView` to Kotlin
This commit is contained in:
Wolf-Martell Montwé 2023-02-10 09:02:32 +00:00 committed by GitHub
commit 6224d40a4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 371 additions and 397 deletions

View file

@ -1,396 +0,0 @@
package com.fsck.k9.ui.messageview;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.fsck.k9.Account;
import com.fsck.k9.Account.ShowPictures;
import com.fsck.k9.mailstore.AttachmentViewInfo;
import com.fsck.k9.ui.R;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mailstore.MessageViewInfo;
import com.fsck.k9.ui.messageview.MessageContainerView.OnRenderingFinishedListener;
import com.fsck.k9.view.MessageHeader;
import com.fsck.k9.view.ThemeUtils;
import com.fsck.k9.view.ToolableViewAnimator;
import org.openintents.openpgp.OpenPgpError;
public class MessageTopView extends LinearLayout {
public static final int PROGRESS_MAX = 1000;
public static final int PROGRESS_MAX_WITH_MARGIN = 950;
public static final int PROGRESS_STEP_DURATION = 180;
private ToolableViewAnimator viewAnimator;
private ProgressBar progressBar;
private TextView progressText;
private MessageHeader mHeaderContainer;
private LayoutInflater mInflater;
private ViewGroup containerView;
private Button mDownloadRemainder;
private AttachmentViewCallback attachmentCallback;
private View extraHeaderContainer;
private Button showPicturesButton;
private boolean isShowingProgress;
private boolean showPicturesButtonClicked;
private boolean showAccountChip;
private MessageCryptoPresenter messageCryptoPresenter;
public MessageTopView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onFinishInflate() {
super.onFinishInflate();
mHeaderContainer = findViewById(R.id.header_container);
mInflater = LayoutInflater.from(getContext());
viewAnimator = findViewById(R.id.message_layout_animator);
progressBar = findViewById(R.id.message_progress);
progressText = findViewById(R.id.message_progress_text);
mDownloadRemainder = findViewById(R.id.download_remainder);
mDownloadRemainder.setVisibility(View.GONE);
extraHeaderContainer = findViewById(R.id.extra_header_container);
showPicturesButton = findViewById(R.id.show_pictures);
setShowPicturesButtonListener();
containerView = findViewById(R.id.message_container);
hideHeaderView();
}
public void setShowAccountChip(boolean showAccountChip) {
this.showAccountChip = showAccountChip;
}
private void setShowPicturesButtonListener() {
showPicturesButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showPicturesInAllContainerViews();
showPicturesButtonClicked = true;
}
});
}
private void showPicturesInAllContainerViews() {
View messageContainerViewCandidate = containerView.getChildAt(0);
if (messageContainerViewCandidate instanceof MessageContainerView) {
((MessageContainerView) messageContainerViewCandidate).showPictures();
}
hideShowPicturesButton();
}
private void resetAndPrepareMessageView(MessageViewInfo messageViewInfo) {
mDownloadRemainder.setVisibility(View.GONE);
containerView.removeAllViews();
setShowDownloadButton(messageViewInfo);
}
public void showMessage(Account account, MessageViewInfo messageViewInfo) {
resetAndPrepareMessageView(messageViewInfo);
ShowPictures showPicturesSetting = account.getShowPictures();
boolean loadPictures = shouldAutomaticallyLoadPictures(showPicturesSetting, messageViewInfo.message) ||
showPicturesButtonClicked;
MessageContainerView view = (MessageContainerView) mInflater.inflate(R.layout.message_container,
containerView, false);
containerView.addView(view);
boolean hideUnsignedTextDivider = account.isOpenPgpHideSignOnly();
view.displayMessageViewContainer(messageViewInfo, new OnRenderingFinishedListener() {
@Override
public void onLoadFinished() {
displayViewOnLoadFinished(true);
}
}, loadPictures, hideUnsignedTextDivider, attachmentCallback);
if (view.hasHiddenExternalImages() && !showPicturesButtonClicked) {
showShowPicturesButton();
}
}
public void showMessageEncryptedButIncomplete(MessageViewInfo messageViewInfo, Drawable providerIcon) {
resetAndPrepareMessageView(messageViewInfo);
View view = mInflater.inflate(R.layout.message_content_crypto_incomplete, containerView, false);
setCryptoProviderIcon(providerIcon, view);
containerView.addView(view);
displayViewOnLoadFinished(false);
}
public void showMessageCryptoErrorView(MessageViewInfo messageViewInfo, Drawable providerIcon) {
resetAndPrepareMessageView(messageViewInfo);
View view = mInflater.inflate(R.layout.message_content_crypto_error, containerView, false);
setCryptoProviderIcon(providerIcon, view);
TextView cryptoErrorText = view.findViewById(R.id.crypto_error_text);
OpenPgpError openPgpError = messageViewInfo.cryptoResultAnnotation.getOpenPgpError();
if (openPgpError != null) {
String errorText = openPgpError.getMessage();
cryptoErrorText.setText(errorText);
}
containerView.addView(view);
displayViewOnLoadFinished(false);
}
public void showMessageCryptoCancelledView(MessageViewInfo messageViewInfo, Drawable providerIcon) {
resetAndPrepareMessageView(messageViewInfo);
View view = mInflater.inflate(R.layout.message_content_crypto_cancelled, containerView, false);
setCryptoProviderIcon(providerIcon, view);
view.findViewById(R.id.crypto_cancelled_retry).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
messageCryptoPresenter.onClickRetryCryptoOperation();
}
});
containerView.addView(view);
displayViewOnLoadFinished(false);
}
public void showCryptoProviderNotConfigured(final MessageViewInfo messageViewInfo) {
resetAndPrepareMessageView(messageViewInfo);
View view = mInflater.inflate(R.layout.message_content_crypto_no_provider, containerView, false);
view.findViewById(R.id.crypto_settings).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
messageCryptoPresenter.onClickConfigureProvider();
}
});
containerView.addView(view);
displayViewOnLoadFinished(false);
}
private void setCryptoProviderIcon(Drawable openPgpApiProviderIcon, View view) {
ImageView cryptoProviderIcon = view.findViewById(R.id.crypto_error_icon);
if (openPgpApiProviderIcon != null) {
cryptoProviderIcon.setImageDrawable(openPgpApiProviderIcon);
} else {
cryptoProviderIcon.setImageResource(R.drawable.status_lock_error);
cryptoProviderIcon.setColorFilter(ThemeUtils.getStyledColor(getContext(), R.attr.openpgp_red));
}
}
/**
* Fetch the message header view. This is not the same as the message headers; this is the View shown at the top
* of messages.
* @return MessageHeader View.
*/
public MessageHeader getMessageHeaderView() {
return mHeaderContainer;
}
public void setHeaders(Message message, Account account, boolean showStar) {
mHeaderContainer.populate(message, account, showStar, showAccountChip);
mHeaderContainer.setVisibility(View.VISIBLE);
}
public void setSubject(@NonNull String subject) {
mHeaderContainer.setSubject(subject);
}
public void setOnToggleFlagClickListener(OnClickListener listener) {
mHeaderContainer.setOnFlagListener(listener);
}
public void setMessageHeaderClickListener(MessageHeaderClickListener listener) {
mHeaderContainer.setMessageHeaderClickListener(listener);
}
private void hideHeaderView() {
mHeaderContainer.setVisibility(View.GONE);
}
public void setOnDownloadButtonClickListener(OnClickListener listener) {
mDownloadRemainder.setOnClickListener(listener);
}
public void setAttachmentCallback(AttachmentViewCallback callback) {
attachmentCallback = callback;
}
public void setMessageCryptoPresenter(MessageCryptoPresenter messageCryptoPresenter) {
this.messageCryptoPresenter = messageCryptoPresenter;
}
public void enableDownloadButton() {
mDownloadRemainder.setEnabled(true);
}
public void disableDownloadButton() {
mDownloadRemainder.setEnabled(false);
}
private void setShowDownloadButton(MessageViewInfo messageViewInfo) {
if (messageViewInfo.isMessageIncomplete) {
mDownloadRemainder.setEnabled(true);
mDownloadRemainder.setVisibility(View.VISIBLE);
} else {
mDownloadRemainder.setVisibility(View.GONE);
}
}
private void showShowPicturesButton() {
extraHeaderContainer.setVisibility(View.VISIBLE);
}
private void hideShowPicturesButton() {
extraHeaderContainer.setVisibility(View.GONE);
}
private boolean shouldAutomaticallyLoadPictures(ShowPictures showPicturesSetting, Message message) {
return showPicturesSetting == ShowPictures.ALWAYS || shouldShowPicturesFromSender(showPicturesSetting, message);
}
private boolean shouldShowPicturesFromSender(ShowPictures showPicturesSetting, Message message) {
if (showPicturesSetting != ShowPictures.ONLY_FROM_CONTACTS) {
return false;
}
String senderEmailAddress = getSenderEmailAddress(message);
if (senderEmailAddress == null) {
return false;
}
Contacts contacts = Contacts.getInstance(getContext());
return contacts.isInContacts(senderEmailAddress);
}
private String getSenderEmailAddress(Message message) {
Address[] from = message.getFrom();
if (from == null || from.length == 0) {
return null;
}
return from[0].getAddress();
}
public void displayViewOnLoadFinished(boolean finishProgressBar) {
if (!finishProgressBar || !isShowingProgress) {
viewAnimator.setDisplayedChild(2);
return;
}
ObjectAnimator animator = ObjectAnimator.ofInt(
progressBar, "progress", progressBar.getProgress(), PROGRESS_MAX);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator) {
viewAnimator.setDisplayedChild(2);
}
});
animator.setDuration(PROGRESS_STEP_DURATION);
animator.start();
}
public void setToLoadingState() {
viewAnimator.setDisplayedChild(0);
progressBar.setProgress(0);
isShowingProgress = false;
}
public void setLoadingProgress(int progress, int max) {
if (!isShowingProgress) {
viewAnimator.setDisplayedChild(1);
isShowingProgress = true;
return;
}
int newPosition = (int) (progress / (float) max * PROGRESS_MAX_WITH_MARGIN);
int currentPosition = progressBar.getProgress();
if (newPosition > currentPosition) {
ObjectAnimator.ofInt(progressBar, "progress", currentPosition, newPosition)
.setDuration(PROGRESS_STEP_DURATION).start();
} else {
progressBar.setProgress(newPosition);
}
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.showPicturesButtonClicked = showPicturesButtonClicked;
return savedState;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
showPicturesButtonClicked = savedState.showPicturesButtonClicked;
}
public void refreshAttachmentThumbnail(AttachmentViewInfo attachment) {
View messageContainerViewCandidate = containerView.getChildAt(0);
if (messageContainerViewCandidate instanceof MessageContainerView) {
((MessageContainerView) messageContainerViewCandidate).refreshAttachmentThumbnail(attachment);
}
}
private static class SavedState extends BaseSavedState {
boolean showPicturesButtonClicked;
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
this.showPicturesButtonClicked = (in.readInt() != 0);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt((this.showPicturesButtonClicked) ? 1 : 0);
}
}
}

View file

@ -0,0 +1,370 @@
package com.fsck.k9.ui.messageview
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.drawable.Drawable
import android.os.Parcel
import android.os.Parcelable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import com.fsck.k9.Account
import com.fsck.k9.Account.ShowPictures
import com.fsck.k9.helper.Contacts
import com.fsck.k9.mail.Message
import com.fsck.k9.mailstore.AttachmentViewInfo
import com.fsck.k9.mailstore.MessageViewInfo
import com.fsck.k9.ui.R
import com.fsck.k9.ui.messageview.MessageContainerView.OnRenderingFinishedListener
import com.fsck.k9.view.MessageHeader
import com.fsck.k9.view.ThemeUtils
import com.fsck.k9.view.ToolableViewAnimator
class MessageTopView(
context: Context,
attrs: AttributeSet?
) : LinearLayout(context, attrs) {
private lateinit var layoutInflater: LayoutInflater
private lateinit var viewAnimator: ToolableViewAnimator
private lateinit var progressBar: ProgressBar
private lateinit var progressText: TextView
lateinit var messageHeaderView: MessageHeader
private lateinit var containerView: ViewGroup
private lateinit var downloadRemainderButton: Button
private lateinit var attachmentCallback: AttachmentViewCallback
private lateinit var extraHeaderContainer: View
private lateinit var showPicturesButton: Button
private var isShowingProgress = false
private var showPicturesButtonClicked = false
private var showAccountChip = false
private var messageCryptoPresenter: MessageCryptoPresenter? = null
public override fun onFinishInflate() {
super.onFinishInflate()
messageHeaderView = findViewById(R.id.header_container)
layoutInflater = LayoutInflater.from(context)
viewAnimator = findViewById(R.id.message_layout_animator)
progressBar = findViewById(R.id.message_progress)
progressText = findViewById(R.id.message_progress_text)
downloadRemainderButton = findViewById(R.id.download_remainder)
downloadRemainderButton.visibility = GONE
extraHeaderContainer = findViewById(R.id.extra_header_container)
showPicturesButton = findViewById(R.id.show_pictures)
setShowPicturesButtonListener()
containerView = findViewById(R.id.message_container)
hideHeaderView()
}
fun setShowAccountChip(showAccountChip: Boolean) {
this.showAccountChip = showAccountChip
}
private fun setShowPicturesButtonListener() {
showPicturesButton.setOnClickListener {
showPicturesInAllContainerViews()
showPicturesButtonClicked = true
}
}
private fun showPicturesInAllContainerViews() {
val messageContainerViewCandidate = containerView.getChildAt(0)
if (messageContainerViewCandidate is MessageContainerView) {
messageContainerViewCandidate.showPictures()
}
hideShowPicturesButton()
}
private fun resetAndPrepareMessageView(messageViewInfo: MessageViewInfo) {
downloadRemainderButton.visibility = GONE
containerView.removeAllViews()
setShowDownloadButton(messageViewInfo)
}
fun showMessage(account: Account, messageViewInfo: MessageViewInfo) {
resetAndPrepareMessageView(messageViewInfo)
val showPicturesSetting = account.showPictures
val loadPictures = shouldAutomaticallyLoadPictures(showPicturesSetting, messageViewInfo.message) ||
showPicturesButtonClicked
val view = layoutInflater.inflate(
R.layout.message_container,
containerView,
false
) as MessageContainerView
containerView.addView(view)
val hideUnsignedTextDivider = account.isOpenPgpHideSignOnly
view.displayMessageViewContainer(
messageViewInfo,
object : OnRenderingFinishedListener {
override fun onLoadFinished() {
displayViewOnLoadFinished(true)
}
},
loadPictures,
hideUnsignedTextDivider,
attachmentCallback
)
if (view.hasHiddenExternalImages && !showPicturesButtonClicked) {
showShowPicturesButton()
}
}
fun showMessageEncryptedButIncomplete(messageViewInfo: MessageViewInfo, providerIcon: Drawable?) {
resetAndPrepareMessageView(messageViewInfo)
val view = layoutInflater.inflate(R.layout.message_content_crypto_incomplete, containerView, false)
setCryptoProviderIcon(providerIcon, view)
containerView.addView(view)
displayViewOnLoadFinished(false)
}
fun showMessageCryptoErrorView(messageViewInfo: MessageViewInfo, providerIcon: Drawable?) {
resetAndPrepareMessageView(messageViewInfo)
val view = layoutInflater.inflate(R.layout.message_content_crypto_error, containerView, false)
setCryptoProviderIcon(providerIcon, view)
val cryptoErrorText = view.findViewById<TextView>(R.id.crypto_error_text)
val openPgpError = messageViewInfo.cryptoResultAnnotation.openPgpError
if (openPgpError != null) {
val errorText = openPgpError.message
cryptoErrorText.text = errorText
}
containerView.addView(view)
displayViewOnLoadFinished(false)
}
fun showMessageCryptoCancelledView(messageViewInfo: MessageViewInfo, providerIcon: Drawable?) {
resetAndPrepareMessageView(messageViewInfo)
val view = layoutInflater.inflate(R.layout.message_content_crypto_cancelled, containerView, false)
setCryptoProviderIcon(providerIcon, view)
view.findViewById<View>(R.id.crypto_cancelled_retry)
.setOnClickListener { messageCryptoPresenter?.onClickRetryCryptoOperation() }
containerView.addView(view)
displayViewOnLoadFinished(false)
}
fun showCryptoProviderNotConfigured(messageViewInfo: MessageViewInfo) {
resetAndPrepareMessageView(messageViewInfo)
val view = layoutInflater.inflate(R.layout.message_content_crypto_no_provider, containerView, false)
view.findViewById<View>(R.id.crypto_settings)
.setOnClickListener { messageCryptoPresenter?.onClickConfigureProvider() }
containerView.addView(view)
displayViewOnLoadFinished(false)
}
private fun setCryptoProviderIcon(openPgpApiProviderIcon: Drawable?, view: View) {
val cryptoProviderIcon = view.findViewById<ImageView>(R.id.crypto_error_icon)
if (openPgpApiProviderIcon != null) {
cryptoProviderIcon.setImageDrawable(openPgpApiProviderIcon)
} else {
cryptoProviderIcon.setImageResource(R.drawable.status_lock_error)
cryptoProviderIcon.setColorFilter(ThemeUtils.getStyledColor(context, R.attr.openpgp_red))
}
}
fun setHeaders(message: Message?, account: Account?, showStar: Boolean) {
messageHeaderView.populate(message, account, showStar, showAccountChip)
messageHeaderView.visibility = VISIBLE
}
fun setSubject(subject: String) {
messageHeaderView.setSubject(subject)
}
fun setOnToggleFlagClickListener(listener: OnClickListener?) {
messageHeaderView.setOnFlagListener(listener)
}
fun setMessageHeaderClickListener(listener: MessageHeaderClickListener?) {
messageHeaderView.setMessageHeaderClickListener(listener)
}
private fun hideHeaderView() {
messageHeaderView.visibility = GONE
}
fun setOnDownloadButtonClickListener(listener: OnClickListener?) {
downloadRemainderButton.setOnClickListener(listener)
}
fun setAttachmentCallback(callback: AttachmentViewCallback) {
attachmentCallback = callback
}
fun setMessageCryptoPresenter(messageCryptoPresenter: MessageCryptoPresenter?) {
this.messageCryptoPresenter = messageCryptoPresenter
}
fun enableDownloadButton() {
downloadRemainderButton.isEnabled = true
}
fun disableDownloadButton() {
downloadRemainderButton.isEnabled = false
}
private fun setShowDownloadButton(messageViewInfo: MessageViewInfo) {
if (messageViewInfo.isMessageIncomplete) {
downloadRemainderButton.isEnabled = true
downloadRemainderButton.visibility = VISIBLE
} else {
downloadRemainderButton.visibility = GONE
}
}
private fun showShowPicturesButton() {
extraHeaderContainer.visibility = VISIBLE
}
private fun hideShowPicturesButton() {
extraHeaderContainer.visibility = GONE
}
private fun shouldAutomaticallyLoadPictures(showPicturesSetting: ShowPictures, message: Message): Boolean {
return showPicturesSetting === ShowPictures.ALWAYS || shouldShowPicturesFromSender(showPicturesSetting, message)
}
private fun shouldShowPicturesFromSender(showPicturesSetting: ShowPictures, message: Message): Boolean {
if (showPicturesSetting !== ShowPictures.ONLY_FROM_CONTACTS) {
return false
}
val senderEmailAddress = getSenderEmailAddress(message) ?: return false
val contacts = Contacts.getInstance(context)
return contacts.isInContacts(senderEmailAddress)
}
private fun getSenderEmailAddress(message: Message): String? {
val from = message.from
return if (from == null || from.isEmpty()) {
null
} else {
from[0].address
}
}
@SuppressLint("ObjectAnimatorBinding")
fun displayViewOnLoadFinished(finishProgressBar: Boolean) {
if (!finishProgressBar || !isShowingProgress) {
viewAnimator.displayedChild = 2
return
}
val animator = ObjectAnimator.ofInt(
progressBar,
"progress",
progressBar.progress,
PROGRESS_MAX
)
animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animator: Animator) {
viewAnimator.displayedChild = 2
}
})
animator.duration = PROGRESS_STEP_DURATION.toLong()
animator.start()
}
fun setToLoadingState() {
viewAnimator.displayedChild = 0
progressBar.progress = 0
isShowingProgress = false
}
@SuppressLint("ObjectAnimatorBinding")
fun setLoadingProgress(progress: Int, max: Int) {
if (!isShowingProgress) {
viewAnimator.displayedChild = 1
isShowingProgress = true
return
}
val newPosition = (progress / max.toFloat() * PROGRESS_MAX_WITH_MARGIN).toInt()
val currentPosition = progressBar.progress
if (newPosition > currentPosition) {
ObjectAnimator.ofInt(progressBar, "progress", currentPosition, newPosition)
.setDuration(PROGRESS_STEP_DURATION.toLong()).start()
} else {
progressBar.progress = newPosition
}
}
public override fun onSaveInstanceState(): Parcelable {
val superState = super.onSaveInstanceState()
val savedState = SavedState(superState)
savedState.showPicturesButtonClicked = showPicturesButtonClicked
return savedState
}
public override fun onRestoreInstanceState(state: Parcelable) {
val savedState = state as SavedState
super.onRestoreInstanceState(savedState.superState)
showPicturesButtonClicked = savedState.showPicturesButtonClicked
}
fun refreshAttachmentThumbnail(attachment: AttachmentViewInfo) {
val messageContainerViewCandidate = containerView.getChildAt(0)
if (messageContainerViewCandidate is MessageContainerView) {
messageContainerViewCandidate.refreshAttachmentThumbnail(attachment)
}
}
private class SavedState : BaseSavedState {
var showPicturesButtonClicked = false
constructor(superState: Parcelable?) : super(superState)
private constructor(`in`: Parcel) : super(`in`) {
showPicturesButtonClicked = `in`.readInt() != 0
}
override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
out.writeInt(if (showPicturesButtonClicked) 1 else 0)
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<SavedState?> = object : Parcelable.Creator<SavedState?> {
override fun createFromParcel(`in`: Parcel): SavedState {
return SavedState(`in`)
}
override fun newArray(size: Int): Array<SavedState?> {
return arrayOfNulls(size)
}
}
}
}
companion object {
const val PROGRESS_MAX = 1000
const val PROGRESS_MAX_WITH_MARGIN = 950
const val PROGRESS_STEP_DURATION = 180
}
}

View file

@ -801,7 +801,7 @@ class MessageViewFragment :
}
}
fun refreshAttachmentThumbnail(attachment: AttachmentViewInfo?) {
fun refreshAttachmentThumbnail(attachment: AttachmentViewInfo) {
messageTopView.refreshAttachmentThumbnail(attachment)
}