mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Unify reader error layout (#6512)
So nobody will think that the error layout is broken when they see different layout.
This commit is contained in:
		| @@ -0,0 +1,29 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer | ||||
|  | ||||
| import android.content.Context | ||||
| import android.util.AttributeSet | ||||
| import android.view.MotionEvent | ||||
| import com.google.android.material.button.MaterialButton | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer | ||||
|  | ||||
| /** | ||||
|  * A button class to be used by child views of the pager viewer. All tap gestures are handled by | ||||
|  * the pager, but this class disables that behavior to allow clickable buttons. | ||||
|  */ | ||||
| class ReaderButton @JvmOverloads constructor( | ||||
|     context: Context, | ||||
|     attrs: AttributeSet? = null, | ||||
|     defStyleAttr: Int = R.attr.materialButtonStyle | ||||
| ) : MaterialButton(context, attrs, defStyleAttr) { | ||||
|  | ||||
|     var viewer: PagerViewer? = null | ||||
|  | ||||
|     override fun onTouchEvent(event: MotionEvent): Boolean { | ||||
|         viewer?.pager?.setGestureDetectorEnabled(false) | ||||
|         if (event.actionMasked == MotionEvent.ACTION_UP) { | ||||
|             viewer?.pager?.setGestureDetectorEnabled(true) | ||||
|         } | ||||
|         return super.onTouchEvent(event) | ||||
|     } | ||||
| } | ||||
| @@ -1,24 +0,0 @@ | ||||
| package eu.kanade.tachiyomi.ui.reader.viewer.pager | ||||
|  | ||||
| import android.annotation.SuppressLint | ||||
| import android.content.Context | ||||
| import android.view.MotionEvent | ||||
| import com.google.android.material.button.MaterialButton | ||||
|  | ||||
| /** | ||||
|  * A button class to be used by child views of the pager viewer. All tap gestures are handled by | ||||
|  * the pager, but this class disables that behavior to allow clickable buttons. | ||||
|  */ | ||||
| @SuppressLint("ViewConstructor") | ||||
| class PagerButton(context: Context, viewer: PagerViewer) : MaterialButton(context) { | ||||
|  | ||||
|     init { | ||||
|         setOnTouchListener { _, event -> | ||||
|             viewer.pager.setGestureDetectorEnabled(false) | ||||
|             if (event.actionMasked == MotionEvent.ACTION_UP) { | ||||
|                 viewer.pager.setGestureDetectorEnabled(true) | ||||
|             } | ||||
|             false | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -3,14 +3,10 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager | ||||
| import android.annotation.SuppressLint | ||||
| import android.content.Context | ||||
| import android.view.Gravity | ||||
| import android.view.ViewGroup | ||||
| import android.view.ViewGroup.LayoutParams.WRAP_CONTENT | ||||
| import android.widget.LinearLayout | ||||
| import android.view.LayoutInflater | ||||
| import androidx.core.view.isVisible | ||||
| import androidx.core.view.setMargins | ||||
| import androidx.core.view.updateLayoutParams | ||||
| import com.google.android.material.textview.MaterialTextView | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.databinding.ReaderErrorBinding | ||||
| import eu.kanade.tachiyomi.source.model.Page | ||||
| import eu.kanade.tachiyomi.ui.reader.model.InsertPage | ||||
| import eu.kanade.tachiyomi.ui.reader.model.ReaderPage | ||||
| @@ -18,7 +14,6 @@ import eu.kanade.tachiyomi.ui.reader.viewer.ReaderPageImageView | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressIndicator | ||||
| import eu.kanade.tachiyomi.ui.webview.WebViewActivity | ||||
| import eu.kanade.tachiyomi.util.system.ImageUtil | ||||
| import eu.kanade.tachiyomi.util.system.dpToPx | ||||
| import eu.kanade.tachiyomi.widget.ViewPagerAdapter | ||||
| import rx.Observable | ||||
| import rx.Subscription | ||||
| @@ -54,14 +49,9 @@ class PagerPageHolder( | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Retry button used to allow retrying. | ||||
|      * Error layout to show when the image fails to load. | ||||
|      */ | ||||
|     private var retryButton: PagerButton? = null | ||||
|  | ||||
|     /** | ||||
|      * Error layout to show when the image fails to decode. | ||||
|      */ | ||||
|     private var decodeErrorLayout: ViewGroup? = null | ||||
|     private var errorLayout: ReaderErrorBinding? = null | ||||
|  | ||||
|     /** | ||||
|      * Subscription for status changes of the page. | ||||
| @@ -176,8 +166,7 @@ class PagerPageHolder( | ||||
|      */ | ||||
|     private fun setQueued() { | ||||
|         progressIndicator.show() | ||||
|         retryButton?.isVisible = false | ||||
|         decodeErrorLayout?.isVisible = false | ||||
|         errorLayout?.root?.isVisible = false | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -185,8 +174,7 @@ class PagerPageHolder( | ||||
|      */ | ||||
|     private fun setLoading() { | ||||
|         progressIndicator.show() | ||||
|         retryButton?.isVisible = false | ||||
|         decodeErrorLayout?.isVisible = false | ||||
|         errorLayout?.root?.isVisible = false | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -194,8 +182,7 @@ class PagerPageHolder( | ||||
|      */ | ||||
|     private fun setDownloading() { | ||||
|         progressIndicator.show() | ||||
|         retryButton?.isVisible = false | ||||
|         decodeErrorLayout?.isVisible = false | ||||
|         errorLayout?.root?.isVisible = false | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -203,8 +190,7 @@ class PagerPageHolder( | ||||
|      */ | ||||
|     private fun setImage() { | ||||
|         progressIndicator.setProgress(0) | ||||
|         retryButton?.isVisible = false | ||||
|         decodeErrorLayout?.isVisible = false | ||||
|         errorLayout?.root?.isVisible = false | ||||
|  | ||||
|         unsubscribeReadImageHeader() | ||||
|         val streamFn = page.stream ?: return | ||||
| @@ -299,7 +285,7 @@ class PagerPageHolder( | ||||
|      */ | ||||
|     private fun setError() { | ||||
|         progressIndicator.hide() | ||||
|         initRetryButton().isVisible = true | ||||
|         showErrorLayout(withOpenInWebView = false) | ||||
|     } | ||||
|  | ||||
|     override fun onImageLoaded() { | ||||
| @@ -313,7 +299,7 @@ class PagerPageHolder( | ||||
|     override fun onImageLoadError() { | ||||
|         super.onImageLoadError() | ||||
|         progressIndicator.hide() | ||||
|         initDecodeErrorLayout().isVisible = true | ||||
|         showErrorLayout(withOpenInWebView = true) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -324,78 +310,24 @@ class PagerPageHolder( | ||||
|         viewer.activity.hideMenu() | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Initializes a button to retry pages. | ||||
|      */ | ||||
|     private fun initRetryButton(): PagerButton { | ||||
|         if (retryButton != null) return retryButton!! | ||||
|  | ||||
|         retryButton = PagerButton(context, viewer).apply { | ||||
|             layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { | ||||
|                 gravity = Gravity.CENTER | ||||
|             } | ||||
|             setText(R.string.action_retry) | ||||
|             setOnClickListener { | ||||
|     private fun showErrorLayout(withOpenInWebView: Boolean): ReaderErrorBinding { | ||||
|         if (errorLayout == null) { | ||||
|             errorLayout = ReaderErrorBinding.inflate(LayoutInflater.from(context), this, true) | ||||
|             errorLayout?.actionRetry?.viewer = viewer | ||||
|             errorLayout?.actionRetry?.setOnClickListener { | ||||
|                 page.chapter.pageLoader?.retryPage(page) | ||||
|             } | ||||
|         } | ||||
|         addView(retryButton) | ||||
|         return retryButton!! | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Initializes a decode error layout. | ||||
|      */ | ||||
|     private fun initDecodeErrorLayout(): ViewGroup { | ||||
|         if (decodeErrorLayout != null) return decodeErrorLayout!! | ||||
|  | ||||
|         val margins = 8.dpToPx | ||||
|  | ||||
|         val decodeLayout = LinearLayout(context).apply { | ||||
|             gravity = Gravity.CENTER | ||||
|             orientation = LinearLayout.VERTICAL | ||||
|         } | ||||
|         decodeErrorLayout = decodeLayout | ||||
|  | ||||
|         MaterialTextView(context).apply { | ||||
|             layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { | ||||
|                 setMargins(margins) | ||||
|             } | ||||
|             gravity = Gravity.CENTER | ||||
|             setText(R.string.decode_image_error) | ||||
|  | ||||
|             decodeLayout.addView(this) | ||||
|         } | ||||
|  | ||||
|         PagerButton(context, viewer).apply { | ||||
|             layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { | ||||
|                 setMargins(margins) | ||||
|             } | ||||
|             setText(R.string.action_retry) | ||||
|             setOnClickListener { | ||||
|                 page.chapter.pageLoader?.retryPage(page) | ||||
|             } | ||||
|  | ||||
|             decodeLayout.addView(this) | ||||
|         } | ||||
|  | ||||
|         val imageUrl = page.imageUrl | ||||
|         if (imageUrl.orEmpty().startsWith("http", true)) { | ||||
|             PagerButton(context, viewer).apply { | ||||
|                 layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { | ||||
|                     setMargins(margins) | ||||
|                 } | ||||
|                 setText(R.string.action_open_in_web_view) | ||||
|                 setOnClickListener { | ||||
|             val imageUrl = page.imageUrl | ||||
|             if (imageUrl.orEmpty().startsWith("http", true)) { | ||||
|                 errorLayout?.actionOpenInWebView?.viewer = viewer | ||||
|                 errorLayout?.actionOpenInWebView?.setOnClickListener { | ||||
|                     val intent = WebViewActivity.newIntent(context, imageUrl!!) | ||||
|                     context.startActivity(intent) | ||||
|                 } | ||||
|  | ||||
|                 decodeLayout.addView(this) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         addView(decodeLayout) | ||||
|         return decodeLayout | ||||
|         errorLayout?.actionOpenInWebView?.isVisible = withOpenInWebView | ||||
|         errorLayout?.root?.isVisible = true | ||||
|         return errorLayout!! | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import com.google.android.material.progressindicator.CircularProgressIndicator | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition | ||||
| import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ReaderButton | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ReaderTransitionView | ||||
| import eu.kanade.tachiyomi.util.system.dpToPx | ||||
| import eu.kanade.tachiyomi.widget.ViewPagerAdapter | ||||
| @@ -126,13 +127,14 @@ class PagerTransitionHolder( | ||||
|             text = context.getString(R.string.transition_pages_error, error.message) | ||||
|         } | ||||
|  | ||||
|         val retryBtn = PagerButton(context, viewer).apply { | ||||
|         val retryBtn = ReaderButton(context).apply { | ||||
|             viewer = this@PagerTransitionHolder.viewer | ||||
|             wrapContent() | ||||
|             setText(R.string.action_retry) | ||||
|             setOnClickListener { | ||||
|                 val toChapter = transition.to | ||||
|                 if (toChapter != null) { | ||||
|                     viewer.activity.requestPreloadChapter(toChapter) | ||||
|                     this@PagerTransitionHolder.viewer.activity.requestPreloadChapter(toChapter) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -2,18 +2,16 @@ package eu.kanade.tachiyomi.ui.reader.viewer.webtoon | ||||
|  | ||||
| import android.content.res.Resources | ||||
| import android.view.Gravity | ||||
| import android.view.LayoutInflater | ||||
| import android.view.ViewGroup | ||||
| import android.view.ViewGroup.LayoutParams.MATCH_PARENT | ||||
| import android.view.ViewGroup.LayoutParams.WRAP_CONTENT | ||||
| import android.widget.FrameLayout | ||||
| import android.widget.LinearLayout | ||||
| import androidx.core.view.isVisible | ||||
| import androidx.core.view.updateLayoutParams | ||||
| import androidx.core.view.updateMargins | ||||
| import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView | ||||
| import com.google.android.material.button.MaterialButton | ||||
| import com.google.android.material.textview.MaterialTextView | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.databinding.ReaderErrorBinding | ||||
| import eu.kanade.tachiyomi.source.model.Page | ||||
| import eu.kanade.tachiyomi.ui.reader.model.ReaderPage | ||||
| import eu.kanade.tachiyomi.ui.reader.viewer.ReaderPageImageView | ||||
| @@ -52,14 +50,9 @@ class WebtoonPageHolder( | ||||
|     private lateinit var progressContainer: ViewGroup | ||||
|  | ||||
|     /** | ||||
|      * Retry button container used to allow retrying. | ||||
|      * Error layout to show when the image fails to load. | ||||
|      */ | ||||
|     private var retryContainer: ViewGroup? = null | ||||
|  | ||||
|     /** | ||||
|      * Error layout to show when the image fails to decode. | ||||
|      */ | ||||
|     private var decodeErrorLayout: ViewGroup? = null | ||||
|     private var errorLayout: ReaderErrorBinding? = null | ||||
|  | ||||
|     /** | ||||
|      * Getter to retrieve the height of the recycler view. | ||||
| @@ -125,7 +118,7 @@ class WebtoonPageHolder( | ||||
|         unsubscribeProgress() | ||||
|         unsubscribeReadImageHeader() | ||||
|  | ||||
|         removeDecodeErrorLayout() | ||||
|         removeErrorLayout() | ||||
|         frame.recycle() | ||||
|         progressIndicator.setProgress(0, animated = false) | ||||
|     } | ||||
| @@ -219,8 +212,7 @@ class WebtoonPageHolder( | ||||
|     private fun setQueued() { | ||||
|         progressContainer.isVisible = true | ||||
|         progressIndicator.show() | ||||
|         retryContainer?.isVisible = false | ||||
|         removeDecodeErrorLayout() | ||||
|         removeErrorLayout() | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -229,8 +221,7 @@ class WebtoonPageHolder( | ||||
|     private fun setLoading() { | ||||
|         progressContainer.isVisible = true | ||||
|         progressIndicator.show() | ||||
|         retryContainer?.isVisible = false | ||||
|         removeDecodeErrorLayout() | ||||
|         removeErrorLayout() | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -239,8 +230,7 @@ class WebtoonPageHolder( | ||||
|     private fun setDownloading() { | ||||
|         progressContainer.isVisible = true | ||||
|         progressIndicator.show() | ||||
|         retryContainer?.isVisible = false | ||||
|         removeDecodeErrorLayout() | ||||
|         removeErrorLayout() | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -248,8 +238,7 @@ class WebtoonPageHolder( | ||||
|      */ | ||||
|     private fun setImage() { | ||||
|         progressIndicator.setProgress(0) | ||||
|         retryContainer?.isVisible = false | ||||
|         removeDecodeErrorLayout() | ||||
|         removeErrorLayout() | ||||
|  | ||||
|         unsubscribeReadImageHeader() | ||||
|         val streamFn = page?.stream ?: return | ||||
| @@ -302,7 +291,7 @@ class WebtoonPageHolder( | ||||
|      */ | ||||
|     private fun setError() { | ||||
|         progressContainer.isVisible = false | ||||
|         initRetryLayout().isVisible = true | ||||
|         initErrorLayout(withOpenInWebView = false) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -317,7 +306,7 @@ class WebtoonPageHolder( | ||||
|      */ | ||||
|     private fun onImageDecodeError() { | ||||
|         progressContainer.isVisible = false | ||||
|         initDecodeErrorLayout().isVisible = true | ||||
|         initErrorLayout(withOpenInWebView = true) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -340,94 +329,32 @@ class WebtoonPageHolder( | ||||
|     /** | ||||
|      * Initializes a button to retry pages. | ||||
|      */ | ||||
|     private fun initRetryLayout(): ViewGroup { | ||||
|         if (retryContainer != null) return retryContainer!! | ||||
|  | ||||
|         retryContainer = FrameLayout(context) | ||||
|         frame.addView(retryContainer, MATCH_PARENT, parentHeight) | ||||
|  | ||||
|         MaterialButton(context).apply { | ||||
|             layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { | ||||
|                 gravity = Gravity.CENTER_HORIZONTAL | ||||
|                 setMargins(0, parentHeight / 4, 0, 0) | ||||
|             } | ||||
|             setText(R.string.action_retry) | ||||
|             setOnClickListener { | ||||
|     private fun initErrorLayout(withOpenInWebView: Boolean): ReaderErrorBinding { | ||||
|         if (errorLayout == null) { | ||||
|             errorLayout = ReaderErrorBinding.inflate(LayoutInflater.from(context), frame, true) | ||||
|             errorLayout?.root?.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, (parentHeight * 0.8).toInt()) | ||||
|             errorLayout?.actionRetry?.setOnClickListener { | ||||
|                 page?.let { it.chapter.pageLoader?.retryPage(it) } | ||||
|             } | ||||
|  | ||||
|             retryContainer!!.addView(this) | ||||
|         } | ||||
|         return retryContainer!! | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Initializes a decode error layout. | ||||
|      */ | ||||
|     private fun initDecodeErrorLayout(): ViewGroup { | ||||
|         if (decodeErrorLayout != null) return decodeErrorLayout!! | ||||
|  | ||||
|         val margins = 8.dpToPx | ||||
|  | ||||
|         val decodeLayout = LinearLayout(context).apply { | ||||
|             layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, parentHeight).apply { | ||||
|                 setMargins(0, parentHeight / 6, 0, 0) | ||||
|             } | ||||
|             gravity = Gravity.CENTER_HORIZONTAL | ||||
|             orientation = LinearLayout.VERTICAL | ||||
|         } | ||||
|         decodeErrorLayout = decodeLayout | ||||
|  | ||||
|         MaterialTextView(context).apply { | ||||
|             layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { | ||||
|                 setMargins(0, margins, 0, margins) | ||||
|             } | ||||
|             gravity = Gravity.CENTER | ||||
|             setText(R.string.decode_image_error) | ||||
|  | ||||
|             decodeLayout.addView(this) | ||||
|         } | ||||
|  | ||||
|         MaterialButton(context).apply { | ||||
|             layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { | ||||
|                 setMargins(0, margins, 0, margins) | ||||
|             } | ||||
|             setText(R.string.action_retry) | ||||
|             setOnClickListener { | ||||
|                 page?.let { it.chapter.pageLoader?.retryPage(it) } | ||||
|             } | ||||
|  | ||||
|             decodeLayout.addView(this) | ||||
|         } | ||||
|  | ||||
|         val imageUrl = page?.imageUrl | ||||
|         if (imageUrl.orEmpty().startsWith("http", true)) { | ||||
|             MaterialButton(context).apply { | ||||
|                 layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { | ||||
|                     setMargins(0, margins, 0, margins) | ||||
|                 } | ||||
|                 setText(R.string.action_open_in_web_view) | ||||
|                 setOnClickListener { | ||||
|             val imageUrl = page?.imageUrl | ||||
|             if (imageUrl.orEmpty().startsWith("http", true)) { | ||||
|                 errorLayout?.actionOpenInWebView?.setOnClickListener { | ||||
|                     val intent = WebViewActivity.newIntent(context, imageUrl!!) | ||||
|                     context.startActivity(intent) | ||||
|                 } | ||||
|  | ||||
|                 decodeLayout.addView(this) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         frame.addView(decodeLayout) | ||||
|         return decodeLayout | ||||
|         errorLayout?.actionOpenInWebView?.isVisible = withOpenInWebView | ||||
|         return errorLayout!! | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Removes the decode error layout from the holder, if found. | ||||
|      */ | ||||
|     private fun removeDecodeErrorLayout() { | ||||
|         val layout = decodeErrorLayout | ||||
|         if (layout != null) { | ||||
|             frame.removeView(layout) | ||||
|             decodeErrorLayout = null | ||||
|     private fun removeErrorLayout() { | ||||
|         errorLayout?.let { | ||||
|             frame.removeView(it.root) | ||||
|             errorLayout = null | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										31
									
								
								app/src/main/res/layout/reader_error.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/src/main/res/layout/reader_error.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:orientation="vertical" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content" | ||||
|     android:layout_gravity="center" | ||||
|     android:gravity="center"> | ||||
|  | ||||
|     <TextView | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_margin="8dp" | ||||
|         android:text="@string/decode_image_error" | ||||
|         android:textAppearance="?attr/textAppearanceBodyMedium" /> | ||||
|  | ||||
|     <eu.kanade.tachiyomi.ui.reader.viewer.ReaderButton | ||||
|         android:id="@+id/action_retry" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_margin="8dp" | ||||
|         android:text="@string/action_retry" /> | ||||
|  | ||||
|     <eu.kanade.tachiyomi.ui.reader.viewer.ReaderButton | ||||
|         android:id="@+id/action_open_in_web_view" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_margin="8dp" | ||||
|         android:text="@string/action_open_in_web_view" | ||||
|         android:visibility="gone" /> | ||||
|  | ||||
| </LinearLayout> | ||||
		Reference in New Issue
	
	Block a user