diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index c1ca9c2..804885d 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/app/build.gradle b/app/build.gradle index 4a269a6..7edbfa8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,8 +47,14 @@ android { } buildTypes { + debug { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + } release { - minifyEnabled false + minifyEnabled true + shrinkResources true proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } } @@ -74,8 +80,7 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" implementation "androidx.room:room-rxjava2:$room_version" - implementation "androidx.appcompat:appcompat:1.1.0" - implementation "androidx.core:core-ktx:1.1.0" + implementation "androidx.core:core-ktx:1.2.0" implementation "androidx.preference:preference:1.1.0" testImplementation "junit:junit:4.12" androidTestImplementation "androidx.test:runner:1.2.0" diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 9f48823..29b892a 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -20,30 +20,5 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile -# Retrofit --dontwarn retrofit2.Platform$Java8 -# okhttp --dontwarn okio.** --dontwarn org.conscrypt.** --dontwarn javax.annotation.** - --dontwarn org.xmlpull.v1.XmlPullParser --dontwarn org.xmlpull.v1.XmlSerializer --keep class org.xmlpull.v1.* {*;} - -# Gson --keep class soko.ekibun.bangumi.api.**.bean.**{*;} # 自定义数据模型的bean目录 - -#不混淆Parcelable和它的子类,还有Creator成员变量 --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} - -# custom view --keep class soko.ekibun.bangumi.ui.view.NotifyActionProvider {*;} --keep class soko.ekibun.bangumi.ui.view.*View {*;} - -# glide webp --keep public class com.bumptech.glide.integration.webp.WebpImage { *; } --keep public class com.bumptech.glide.integration.webp.WebpFrame { *; } --keep public class com.bumptech.glide.integration.webp.WebpBitmapFactory { *; } \ No newline at end of file +-dontobfuscate +-keep class soko.ekibun.bangumi.**{*;} \ No newline at end of file diff --git a/app/src/main/java/com/awarmisland/android/richedittext/bean/RichImageSpan.java b/app/src/main/java/com/awarmisland/android/richedittext/bean/RichImageSpan.java deleted file mode 100644 index 5a19e41..0000000 --- a/app/src/main/java/com/awarmisland/android/richedittext/bean/RichImageSpan.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.awarmisland.android.richedittext.bean; - -import android.content.Context; -import android.graphics.Bitmap; -import android.net.Uri; -import android.text.style.ImageSpan; - -public class RichImageSpan extends ImageSpan { - private Uri mUri; - - public RichImageSpan(Context context, Bitmap b, Uri uri) { - super(context, b); - mUri = uri; - } - - @Override - public String getSource() { - return mUri.toString(); - } -} \ No newline at end of file diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/topic/ReplyDialog.kt b/app/src/main/java/soko/ekibun/bangumi/ui/topic/ReplyDialog.kt index e3dcc15..e31c3a8 100644 --- a/app/src/main/java/soko/ekibun/bangumi/ui/topic/ReplyDialog.kt +++ b/app/src/main/java/soko/ekibun/bangumi/ui/topic/ReplyDialog.kt @@ -8,7 +8,6 @@ import android.content.DialogInterface import android.content.Intent import android.provider.OpenableColumns import android.text.Spanned -import android.text.style.ImageSpan import android.view.KeyEvent import android.view.MenuItem import android.view.View @@ -31,10 +30,7 @@ import soko.ekibun.bangumi.api.bangumi.Bangumi import soko.ekibun.bangumi.ui.view.BaseDialog import soko.ekibun.bangumi.util.HtmlUtil import soko.ekibun.bangumi.util.ResourceUtil -import soko.ekibun.bangumi.util.span.ClickableImageSpan -import soko.ekibun.bangumi.util.span.ClickableUrlSpan -import soko.ekibun.bangumi.util.span.CollapseUrlDrawable -import soko.ekibun.bangumi.util.span.UploadDrawable +import soko.ekibun.bangumi.util.span.* import java.lang.ref.WeakReference /** @@ -196,7 +192,7 @@ class ReplyDialog : BaseDialog(R.layout.dialog_reply) { drawable.url = emojiList[position].second view.item_input.editableText.insert( view.item_input.selectionStart, - HtmlUtil.createImageSpan(ImageSpan(drawable, emojiList[position].first, ImageSpan.ALIGN_BASELINE)) + HtmlUtil.createImageSpan(UrlImageSpan(drawable, emojiList[position].first)) ) drawable.container = WeakReference(view.item_input) drawable.loadImage() @@ -329,7 +325,7 @@ class ReplyDialog : BaseDialog(R.layout.dialog_reply) { item_input.editableText.replace(start, end, "[img]$it[/img]") } } - val imageSpan = ImageSpan(drawable, "", ImageSpan.ALIGN_BASELINE) + val imageSpan = UrlImageSpan(drawable, "") span = ClickableImageSpan(imageSpan, collapseImageGetter.onClick) item_input.editableText.insert( item_input.selectionStart, diff --git a/app/src/main/java/soko/ekibun/bangumi/util/GlideUtil.kt b/app/src/main/java/soko/ekibun/bangumi/util/GlideUtil.kt index a502ac4..7b517f4 100644 --- a/app/src/main/java/soko/ekibun/bangumi/util/GlideUtil.kt +++ b/app/src/main/java/soko/ekibun/bangumi/util/GlideUtil.kt @@ -1,5 +1,3 @@ -@file:Suppress("DEPRECATION") - package soko.ekibun.bangumi.util import android.app.Activity @@ -15,7 +13,7 @@ import com.bumptech.glide.RequestManager import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.model.Headers import com.bumptech.glide.request.RequestOptions -import com.bumptech.glide.request.target.SimpleTarget +import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.transition.Transition @@ -63,7 +61,8 @@ object GlideUtil { Headers { mapOf("referer" to url, "user-agent" to HttpUtil.ua) }) ) } - }.apply(options).into(object : SimpleTarget() { + }.apply(options).into(object : CustomTarget() { + override fun onLoadStarted(placeholder: Drawable?) { callback(TYPE_PLACEHOLDER, placeholder) } @@ -75,7 +74,7 @@ object GlideUtil { override fun onLoadCleared(placeholder: Drawable?) { if (circularProgressDrawable.isRunning) circularProgressDrawable.stop() - callback(TYPE_PLACEHOLDER, null) + ProgressAppGlideModule.forget(url) } override fun onResourceReady(resource: Drawable, transition: Transition?) { @@ -87,7 +86,6 @@ object GlideUtil { ProgressAppGlideModule.forget(url) } }) - } fun with(context: Context): RequestManager? { diff --git a/app/src/main/java/soko/ekibun/bangumi/util/HtmlUtil.kt b/app/src/main/java/soko/ekibun/bangumi/util/HtmlUtil.kt index a04645f..e7f5ba3 100644 --- a/app/src/main/java/soko/ekibun/bangumi/util/HtmlUtil.kt +++ b/app/src/main/java/soko/ekibun/bangumi/util/HtmlUtil.kt @@ -70,13 +70,15 @@ object HtmlUtil { fun attachToTextView(span: Spanned, textView: TextView) { // 结束之前的请求 (textView.text as? Spanned)?.let { text -> - text.getSpans(0, text.length, ImageSpan::class.java).forEach { + text.getSpans(0, text.length, UrlImageSpan::class.java).filterNot { + span.getSpanFlags(it) == 0 + }.forEach { (it.drawable as? UrlDrawable)?.cancel() } } // 更新引用 val weakRef = WeakReference(textView) - span.getSpans(0, span.length, ImageSpan::class.java).forEach { imageSpan -> + span.getSpans(0, span.length, UrlImageSpan::class.java).forEach { imageSpan -> (imageSpan.drawable as? UrlDrawable)?.let { it.container = weakRef it.loadImage() @@ -124,14 +126,13 @@ object HtmlUtil { val sources = Bangumi.parseUrl(src) val alt = node.attr("alt") val isSmile = node.hasAttr("smileid") - val imageSpan = ImageSpan( + val imageSpan = UrlImageSpan( imageGetter.getDrawable(sources), - if (isSmile) alt else src, - ImageSpan.ALIGN_BASELINE + if (isSmile) alt else src ) createImageSpan(imageSpan).also { if (!isSmile) { - imageGetter.drawables.add(sources) + imageGetter.drawables.add(imageSpan.url) setSpan( ClickableImageSpan(imageSpan, imageGetter.onClick), it, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE @@ -149,7 +150,7 @@ object HtmlUtil { return span } - fun createImageSpan(imageSpan: ImageSpan): SpannableStringBuilder { + fun createImageSpan(imageSpan: UrlImageSpan): SpannableStringBuilder { return SpannableStringBuilder("").also { setSpan(imageSpan, it, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) } @@ -204,10 +205,10 @@ object HtmlUtil { ) { val drawables = ArrayList() - open val onClick: (View, ImageSpan) -> Unit = { itemView, span -> + open val onClick: (View, UrlImageSpan) -> Unit = { itemView, span -> PhotoPagerAdapter.showWindow( itemView, drawables, - index = drawables.indexOf(span.source ?: "") + index = drawables.indexOf(span.url) ) } diff --git a/app/src/main/java/soko/ekibun/bangumi/util/SpanFormatter.kt b/app/src/main/java/soko/ekibun/bangumi/util/SpanFormatter.kt index ef8591f..3aa9036 100644 --- a/app/src/main/java/soko/ekibun/bangumi/util/SpanFormatter.kt +++ b/app/src/main/java/soko/ekibun/bangumi/util/SpanFormatter.kt @@ -6,10 +6,7 @@ import android.text.TextUtils import android.text.style.* import soko.ekibun.bangumi.api.bangumi.Bangumi import soko.ekibun.bangumi.ui.topic.ReplyDialog -import soko.ekibun.bangumi.util.span.ClickableUrlSpan -import soko.ekibun.bangumi.util.span.CodeLineSpan -import soko.ekibun.bangumi.util.span.MaskSpan -import soko.ekibun.bangumi.util.span.QuoteLineSpan +import soko.ekibun.bangumi.util.span.* import kotlin.math.roundToInt abstract class SpanFormatter { @@ -73,8 +70,8 @@ abstract class SpanFormatter { is ForegroundColorSpan -> return "${ String.format("[color=#%06X]", 0xFFFFFF and span.foregroundColor)}${inner()}[/color]" is MaskSpan -> return "[mask]${inner()}[/mask]" - is ImageSpan -> return if (span.source?.startsWith("(") == true) span.source ?: "" - else "[img]${span.source}[/img]" + is UrlImageSpan -> return if (span.url.startsWith("(")) span.url + else "[img]${span.url}[/img]" } return inner() } diff --git a/app/src/main/java/soko/ekibun/bangumi/util/span/ClickableImageSpan.kt b/app/src/main/java/soko/ekibun/bangumi/util/span/ClickableImageSpan.kt index a675a05..db90c8b 100644 --- a/app/src/main/java/soko/ekibun/bangumi/util/span/ClickableImageSpan.kt +++ b/app/src/main/java/soko/ekibun/bangumi/util/span/ClickableImageSpan.kt @@ -1,7 +1,6 @@ package soko.ekibun.bangumi.util.span import android.text.style.ClickableSpan -import android.text.style.ImageSpan import android.util.Log import android.view.View @@ -9,11 +8,11 @@ import android.view.View * */ class ClickableImageSpan( - var image: ImageSpan, - private val onClick: (View, ImageSpan) -> Unit + var image: UrlImageSpan, + private val onClick: (View, UrlImageSpan) -> Unit ) : ClickableSpan() { override fun onClick(widget: View) { - Log.v("click", this.toString()) + Log.v("click", image.drawable.toString()) val drawable = image.drawable if (drawable is UrlDrawable) { if (drawable.error == true) drawable.loadImage() diff --git a/app/src/main/java/soko/ekibun/bangumi/util/span/CollapseUrlDrawable.kt b/app/src/main/java/soko/ekibun/bangumi/util/span/CollapseUrlDrawable.kt index db57bf0..27930ed 100644 --- a/app/src/main/java/soko/ekibun/bangumi/util/span/CollapseUrlDrawable.kt +++ b/app/src/main/java/soko/ekibun/bangumi/util/span/CollapseUrlDrawable.kt @@ -3,8 +3,7 @@ package soko.ekibun.bangumi.util.span import android.graphics.* import android.graphics.drawable.Animatable import android.graphics.drawable.Drawable -import android.text.style.ImageSpan -import android.util.Log +import android.text.Spannable import android.util.Size import android.view.View import android.widget.TextView @@ -21,45 +20,41 @@ open class CollapseUrlDrawable( sizeCache: HashMap ) : UrlDrawable(wrapWidth, sizeCache) { + override var drawable: Drawable? = null + set(drawable) { + (field as? Animatable)?.stop() + field?.callback = null + field = drawable + field?.callback = drawableCallback + (drawable as? Animatable)?.start() + val drawableBounds = drawable?.bounds ?: bounds + setBounds(0, 0, drawableBounds.width(), Math.min(drawableBounds.height(), 250)) + mBuffer = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888) + updateBuffer() + + container?.get()?.let { + val text = (it.text as? Spannable) ?: return@let + text.getSpans(0, text.length, UrlImageSpan::class.java)?.filter { span -> + span.drawable == this + }?.forEach { span -> + span.url = url ?: "" + val start = text.getSpanStart(span) + val end = text.getSpanEnd(span) + val flags = text.getSpanFlags(span) + text.removeSpan(span) + text.setSpan(span, start, end, flags) + } + it.invalidate() + } + } + override fun update(drawable: Drawable) { val size = { val width = wrapWidth(if (error == false) drawable.intrinsicWidth.toFloat() else -1f) Size(width.toInt(), (drawable.intrinsicHeight * width / drawable.intrinsicWidth).toInt()) }() - Log.v("update", "$drawable size: $size") - (this.drawable as? Animatable)?.stop() - this.drawable?.callback = null + drawable.setBounds(0, 0, size.width, size.height) this.drawable = drawable - this.drawable?.callback = this.drawableCallback - (drawable as? Animatable)?.start() - setBounds(0, 0, size.width, Math.min(size.height, 250)) - mBuffer = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888) - this.drawable?.setBounds(0, 0, size.width, size.height) - updateBuffer() - - container?.get()?.let { - it.editableText.getSpans(0, it.editableText.length, ClickableImageSpan::class.java).filter { span -> - span.image.drawable == this - }.forEach { span -> - val start = it.editableText.getSpanStart(span) - val end = it.editableText.getSpanEnd(span) - val flags = it.editableText.getSpanFlags(span) - - it.editableText.removeSpan(span.image) - span.image = ImageSpan(this, url ?: "", ImageSpan.ALIGN_BASELINE) - it.editableText.setSpan(span.image, start, end, flags) - } - it.editableText.getSpans(0, it.editableText.length, ImageSpan::class.java).filter { span -> - span.drawable == this - }.forEach { span -> - val start = it.editableText.getSpanStart(span) - val end = it.editableText.getSpanEnd(span) - val flags = it.editableText.getSpanFlags(span) - it.editableText.removeSpan(span) - it.editableText.setSpan(span, start, end, flags) - } - it.invalidate() - } } private val gradientPaint by lazy { @@ -87,8 +82,8 @@ open class CollapseUrlDrawable( class CollapseImageGetter(container: TextView) : HtmlUtil.ImageGetter(wrapWidth = { Math.min(container.width.toFloat(), Math.max(container.textSize, it)) }) { - override val onClick: (View, ImageSpan) -> Unit = { itemView, span -> - Toast.makeText(itemView.context, span.source, Toast.LENGTH_LONG).show() + override val onClick: (View, UrlImageSpan) -> Unit = { itemView, span -> + Toast.makeText(itemView.context, span.url, Toast.LENGTH_LONG).show() } override fun createDrawable(): UrlDrawable { diff --git a/app/src/main/java/soko/ekibun/bangumi/util/span/TextViewDrawable.kt b/app/src/main/java/soko/ekibun/bangumi/util/span/TextViewDrawable.kt new file mode 100644 index 0000000..b439024 --- /dev/null +++ b/app/src/main/java/soko/ekibun/bangumi/util/span/TextViewDrawable.kt @@ -0,0 +1,69 @@ +package soko.ekibun.bangumi.util.span + +import android.graphics.* +import android.graphics.drawable.Animatable +import android.graphics.drawable.AnimationDrawable +import android.graphics.drawable.Drawable +import android.text.Spannable +import android.widget.TextView +import java.lang.ref.WeakReference + +open class TextViewDrawable : AnimationDrawable() { + var container: WeakReference? = null + + open var drawable: Drawable? = null + set(drawable) { + (field as? Animatable)?.stop() + field?.callback = null + field = drawable + if (drawable == null) return + drawable.callback = drawableCallback + (drawable as? Animatable)?.start() + bounds = drawable.bounds + mBuffer = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888) + updateBuffer() + + container?.get()?.let { + val text = (it.text as? Spannable) ?: return@let + text.getSpans(0, text.length, UrlImageSpan::class.java)?.filter { span -> + span.drawable == this + }?.forEach { span -> + val start = text.getSpanStart(span) + val end = text.getSpanEnd(span) + val flags = text.getSpanFlags(span) + text.removeSpan(span) + text.setSpan(span, start, end, flags) + } + it.invalidate() + } + } + + internal var mBuffer: Bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888) + private val mPaint = Paint(Paint.FILTER_BITMAP_FLAG or Paint.DITHER_FLAG) + + open fun updateBuffer() { + val bufferCanvas = Canvas(mBuffer) + bufferCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR) + drawable?.draw(bufferCanvas) + invalidateSelf() + } + + internal val drawableCallback = object : Callback { + override fun invalidateDrawable(who: Drawable) { + updateBuffer() + container?.get()?.invalidate() + } + + override fun scheduleDrawable(who: Drawable, what: Runnable, `when`: Long) { + container?.get()?.postDelayed(what, `when`) + } + + override fun unscheduleDrawable(who: Drawable, what: Runnable) { + container?.get()?.removeCallbacks(what) + } + } + + override fun draw(canvas: Canvas) { + canvas.drawBitmap(mBuffer, bounds, bounds, mPaint) + } +} \ No newline at end of file diff --git a/app/src/main/java/soko/ekibun/bangumi/util/span/UrlDrawable.kt b/app/src/main/java/soko/ekibun/bangumi/util/span/UrlDrawable.kt index 06fcd03..ce26c6c 100644 --- a/app/src/main/java/soko/ekibun/bangumi/util/span/UrlDrawable.kt +++ b/app/src/main/java/soko/ekibun/bangumi/util/span/UrlDrawable.kt @@ -1,21 +1,15 @@ package soko.ekibun.bangumi.util.span -import android.graphics.* -import android.graphics.drawable.Animatable -import android.graphics.drawable.AnimationDrawable import android.graphics.drawable.Drawable import android.net.Uri -import android.text.Spannable -import android.text.style.ImageSpan +import android.util.Log import android.util.Size -import android.widget.TextView import androidx.swiperefreshlayout.widget.CircularProgressDrawable import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.target.Target import soko.ekibun.bangumi.R import soko.ekibun.bangumi.util.GlideUtil import soko.ekibun.bangumi.util.ResourceUtil -import java.lang.ref.WeakReference /** * url图片Drawable @@ -24,16 +18,15 @@ import java.lang.ref.WeakReference open class UrlDrawable( val wrapWidth: (Float) -> Float, val sizeCache: HashMap -) : AnimationDrawable() { - var container: WeakReference? = null +) : TextViewDrawable() { private var target: Target? = null fun cancel() { container?.get()?.let { GlideUtil.with(it) }?.clear(target) + error = null + drawable = null } - internal var drawable: Drawable? = null - /** * 加载状态 * - true: 加载失败 @@ -44,9 +37,6 @@ open class UrlDrawable( var url: String? = null var uri: Uri? = null - internal var mBuffer: Bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888) - internal val mPaint = Paint(Paint.FILTER_BITMAP_FLAG or Paint.DITHER_FLAG) - /** * 更新Drawable */ @@ -57,35 +47,15 @@ open class UrlDrawable( if (error == false) url?.let { sizeCache[it] = size } size }() - (this.drawable as? Animatable)?.stop() - this.drawable?.callback = null + drawable.setBounds(0, 0, size.width, size.height) this.drawable = drawable - this.drawable?.callback = drawableCallback - (drawable as? Animatable)?.start() - setBounds(0, 0, size.width, size.height) - mBuffer = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888) - this.drawable?.bounds = bounds - updateBuffer() - - container?.get()?.let { - val text = (it.text as? Spannable) ?: return@let - text.getSpans(0, text.length, ImageSpan::class.java)?.filter { span -> - span.drawable == this - }?.forEach { span -> - val start = text.getSpanStart(span) - val end = text.getSpanEnd(span) - val flags = text.getSpanFlags(span) - text.removeSpan(span) - text.setSpan(span, start, end, flags) - } - it.invalidate() - } } /** * 加载图片 */ open fun loadImage() { + if (error == false) return // 加载完成不再加载 val url = this.url ?: return val view = container?.get() view?.post { @@ -107,6 +77,7 @@ open class UrlDrawable( circularProgressDrawable, uri ) { type, drawable -> + Log.v("Type", type.toString()) error = when (type) { GlideUtil.TYPE_RESOURCE -> false GlideUtil.TYPE_ERROR -> true @@ -116,33 +87,4 @@ open class UrlDrawable( } } } - - /** - * 更新缓存 - */ - open fun updateBuffer() { - val bufferCanvas = Canvas(mBuffer) - bufferCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR) - drawable?.draw(bufferCanvas) - invalidateSelf() - } - - internal val drawableCallback = object : Callback { - override fun invalidateDrawable(who: Drawable) { - updateBuffer() - container?.get()?.invalidate() - } - - override fun scheduleDrawable(who: Drawable, what: Runnable, `when`: Long) { - container?.get()?.postDelayed(what, `when`) - } - - override fun unscheduleDrawable(who: Drawable, what: Runnable) { - container?.get()?.removeCallbacks(what) - } - } - - override fun draw(canvas: Canvas) { - canvas.drawBitmap(mBuffer, bounds, bounds, mPaint) - } } \ No newline at end of file diff --git a/app/src/main/java/soko/ekibun/bangumi/util/span/UrlImageSpan.kt b/app/src/main/java/soko/ekibun/bangumi/util/span/UrlImageSpan.kt new file mode 100644 index 0000000..5ce2302 --- /dev/null +++ b/app/src/main/java/soko/ekibun/bangumi/util/span/UrlImageSpan.kt @@ -0,0 +1,9 @@ +package soko.ekibun.bangumi.util.span + +import android.text.style.ImageSpan + +class UrlImageSpan(drawable: UrlDrawable, var url: String = "") : ImageSpan(drawable, "", ALIGN_BASELINE) { + + @Deprecated("use url instead", ReplaceWith("url")) + override fun getSource(): String? = url +} \ No newline at end of file diff --git a/app/src/main/res/drawable-xhdpi/empty.png b/app/src/main/res/drawable-xhdpi/empty.png deleted file mode 100644 index 7b580a7..0000000 Binary files a/app/src/main/res/drawable-xhdpi/empty.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/empty.webp b/app/src/main/res/drawable-xhdpi/empty.webp new file mode 100644 index 0000000..74e91f0 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/empty.webp differ diff --git a/app/src/main/res/drawable-xhdpi/err_401.png b/app/src/main/res/drawable-xhdpi/err_401.png deleted file mode 100644 index 8ac672d..0000000 Binary files a/app/src/main/res/drawable-xhdpi/err_401.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/err_401.webp b/app/src/main/res/drawable-xhdpi/err_401.webp new file mode 100644 index 0000000..bd76ad5 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/err_401.webp differ diff --git a/app/src/main/res/drawable-xhdpi/err_404.png b/app/src/main/res/drawable-xhdpi/err_404.png deleted file mode 100644 index 3643494..0000000 Binary files a/app/src/main/res/drawable-xhdpi/err_404.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/err_404.webp b/app/src/main/res/drawable-xhdpi/err_404.webp new file mode 100644 index 0000000..1078c04 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/err_404.webp differ diff --git a/app/src/main/res/drawable-xhdpi/welcome.png b/app/src/main/res/drawable-xhdpi/welcome.png deleted file mode 100644 index 6ba3c27..0000000 Binary files a/app/src/main/res/drawable-xhdpi/welcome.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/welcome.webp b/app/src/main/res/drawable-xhdpi/welcome.webp new file mode 100644 index 0000000..6f87ce8 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/welcome.webp differ