mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Remove legacy settings sheet
The per-series settings aren't quite functional yet, but they're also accessible outside of the sheet.
This commit is contained in:
		@@ -2,13 +2,17 @@ package eu.kanade.presentation.reader.settings
 | 
			
		||||
 | 
			
		||||
import androidx.compose.foundation.layout.ColumnScope
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.collectAsState
 | 
			
		||||
import androidx.compose.runtime.getValue
 | 
			
		||||
import androidx.compose.runtime.remember
 | 
			
		||||
import androidx.compose.ui.res.stringResource
 | 
			
		||||
import eu.kanade.presentation.util.collectAsState
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
 | 
			
		||||
import tachiyomi.presentation.core.components.CheckboxItem
 | 
			
		||||
import tachiyomi.presentation.core.components.HeadingItem
 | 
			
		||||
@@ -22,16 +26,32 @@ internal fun ColumnScope.ReadingModePage(screenModel: ReaderSettingsScreenModel)
 | 
			
		||||
 | 
			
		||||
    HeadingItem(R.string.pref_category_for_this_series)
 | 
			
		||||
 | 
			
		||||
    // TODO: Reading mode
 | 
			
		||||
    HeadingItem(R.string.pref_category_reading_mode)
 | 
			
		||||
    ReadingModeType.values().map {
 | 
			
		||||
        RadioItem(
 | 
			
		||||
            label = stringResource(it.stringRes),
 | 
			
		||||
            // TODO: Reading mode
 | 
			
		||||
            selected = false,
 | 
			
		||||
            onClick = { screenModel.onChangeReadingMode(it) },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: Rotation type
 | 
			
		||||
    HeadingItem(R.string.rotation_type)
 | 
			
		||||
    OrientationType.values().map {
 | 
			
		||||
        RadioItem(
 | 
			
		||||
            label = stringResource(it.stringRes),
 | 
			
		||||
            // TODO: Rotation type
 | 
			
		||||
            selected = false,
 | 
			
		||||
            onClick = { screenModel.onChangeOrientation(it) },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: if (pager)
 | 
			
		||||
    PagerViewerSettings(screenModel)
 | 
			
		||||
 | 
			
		||||
    WebtoonViewerSettings(screenModel)
 | 
			
		||||
    val viewer by screenModel.viewerFlow.collectAsState()
 | 
			
		||||
    if (viewer is WebtoonViewer) {
 | 
			
		||||
        WebtoonViewerSettings(screenModel)
 | 
			
		||||
    } else {
 | 
			
		||||
        PagerViewerSettings(screenModel)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,6 @@ import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsSheet
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressIndicator
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
 | 
			
		||||
@@ -391,7 +390,13 @@ class ReaderActivity : BaseActivity() {
 | 
			
		||||
 | 
			
		||||
        binding.dialogRoot.setComposeContent {
 | 
			
		||||
            val state by viewModel.state.collectAsState()
 | 
			
		||||
            val settingsScreenModel = remember { ReaderSettingsScreenModel() }
 | 
			
		||||
            val settingsScreenModel = remember {
 | 
			
		||||
                ReaderSettingsScreenModel(
 | 
			
		||||
                    readerState = viewModel.state,
 | 
			
		||||
                    onChangeReadingMode = viewModel::setMangaReadingMode,
 | 
			
		||||
                    onChangeOrientation = viewModel::setMangaOrientationType,
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val onDismissRequest = viewModel::closeDialog
 | 
			
		||||
            when (state.dialog) {
 | 
			
		||||
@@ -485,7 +490,7 @@ class ReaderActivity : BaseActivity() {
 | 
			
		||||
                ) {
 | 
			
		||||
                    val newReadingMode = ReadingModeType.fromPreference(itemId)
 | 
			
		||||
 | 
			
		||||
                    viewModel.setMangaReadingMode(newReadingMode.flagValue)
 | 
			
		||||
                    viewModel.setMangaReadingMode(newReadingMode)
 | 
			
		||||
 | 
			
		||||
                    menuToggleToast?.cancel()
 | 
			
		||||
                    if (!readerPreferences.showReadingMode().get()) {
 | 
			
		||||
@@ -539,7 +544,7 @@ class ReaderActivity : BaseActivity() {
 | 
			
		||||
                ) {
 | 
			
		||||
                    val newOrientation = OrientationType.fromPreference(itemId)
 | 
			
		||||
 | 
			
		||||
                    viewModel.setMangaOrientationType(newOrientation.flagValue)
 | 
			
		||||
                    viewModel.setMangaOrientationType(newOrientation)
 | 
			
		||||
 | 
			
		||||
                    menuToggleToast?.cancel()
 | 
			
		||||
                    menuToggleToast = toast(newOrientation.stringRes)
 | 
			
		||||
@@ -548,16 +553,6 @@ class ReaderActivity : BaseActivity() {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Settings sheet
 | 
			
		||||
        with(binding.actionSettingsLegacy) {
 | 
			
		||||
            setTooltip(R.string.action_settings)
 | 
			
		||||
 | 
			
		||||
            var readerSettingSheet: ReaderSettingsSheet? = null
 | 
			
		||||
 | 
			
		||||
            setOnClickListener {
 | 
			
		||||
                if (readerSettingSheet?.isShowing == true) return@setOnClickListener
 | 
			
		||||
                readerSettingSheet = ReaderSettingsSheet(this@ReaderActivity).apply { show() }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        with(binding.actionSettings) {
 | 
			
		||||
            setTooltip(R.string.action_settings)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -602,10 +602,10 @@ class ReaderViewModel(
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the viewer position for the open manga.
 | 
			
		||||
     */
 | 
			
		||||
    fun setMangaReadingMode(readingModeType: Int) {
 | 
			
		||||
    fun setMangaReadingMode(readingModeType: ReadingModeType) {
 | 
			
		||||
        val manga = manga ?: return
 | 
			
		||||
        runBlocking(Dispatchers.IO) {
 | 
			
		||||
            setMangaViewerFlags.awaitSetMangaReadingMode(manga.id, readingModeType.toLong())
 | 
			
		||||
            setMangaViewerFlags.awaitSetMangaReadingMode(manga.id, readingModeType.flagValue.toLong())
 | 
			
		||||
            val currChapters = state.value.viewerChapters
 | 
			
		||||
            if (currChapters != null) {
 | 
			
		||||
                // Save current page
 | 
			
		||||
@@ -638,10 +638,10 @@ class ReaderViewModel(
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the orientation type for the open manga.
 | 
			
		||||
     */
 | 
			
		||||
    fun setMangaOrientationType(rotationType: Int) {
 | 
			
		||||
    fun setMangaOrientationType(rotationType: OrientationType) {
 | 
			
		||||
        val manga = manga ?: return
 | 
			
		||||
        viewModelScope.launchIO {
 | 
			
		||||
            setMangaViewerFlags.awaitSetOrientationType(manga.id, rotationType.toLong())
 | 
			
		||||
            setMangaViewerFlags.awaitSetOrientationType(manga.id, rotationType.flagValue.toLong())
 | 
			
		||||
            val currChapters = state.value.viewerChapters
 | 
			
		||||
            if (currChapters != null) {
 | 
			
		||||
                // Save current page
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,30 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.reader.setting
 | 
			
		||||
 | 
			
		||||
import cafe.adriel.voyager.core.model.ScreenModel
 | 
			
		||||
import eu.kanade.presentation.util.ioCoroutineScope
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.ReaderViewModel
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.toggle
 | 
			
		||||
import kotlinx.coroutines.flow.SharingStarted
 | 
			
		||||
import kotlinx.coroutines.flow.StateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.distinctUntilChanged
 | 
			
		||||
import kotlinx.coroutines.flow.map
 | 
			
		||||
import kotlinx.coroutines.flow.stateIn
 | 
			
		||||
import tachiyomi.core.preference.Preference
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
 | 
			
		||||
class ReaderSettingsScreenModel(
 | 
			
		||||
    readerState: StateFlow<ReaderViewModel.State>,
 | 
			
		||||
    val onChangeReadingMode: (ReadingModeType) -> Unit,
 | 
			
		||||
    val onChangeOrientation: (OrientationType) -> Unit,
 | 
			
		||||
    val preferences: ReaderPreferences = Injekt.get(),
 | 
			
		||||
) : ScreenModel {
 | 
			
		||||
 | 
			
		||||
    val viewerFlow = readerState
 | 
			
		||||
        .map { it.viewer }
 | 
			
		||||
        .distinctUntilChanged()
 | 
			
		||||
        .stateIn(ioCoroutineScope, SharingStarted.Lazily, null)
 | 
			
		||||
 | 
			
		||||
    fun togglePreference(preference: (ReaderPreferences) -> Preference<Boolean>) {
 | 
			
		||||
        preference(preferences).toggle()
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.reader.setting
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import com.google.android.material.bottomsheet.BottomSheetDialog
 | 
			
		||||
import eu.kanade.domain.manga.model.orientationType
 | 
			
		||||
import eu.kanade.domain.manga.model.readingModeType
 | 
			
		||||
import eu.kanade.tachiyomi.databinding.ReaderReadingModeSettingsBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
 | 
			
		||||
 | 
			
		||||
class ReaderSettingsSheet(
 | 
			
		||||
    private val activity: ReaderActivity,
 | 
			
		||||
) : BottomSheetDialog(activity) {
 | 
			
		||||
 | 
			
		||||
    private lateinit var binding: ReaderReadingModeSettingsBinding
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        binding = ReaderReadingModeSettingsBinding.inflate(activity.layoutInflater)
 | 
			
		||||
        setContentView(binding.root)
 | 
			
		||||
 | 
			
		||||
        initGeneralPreferences()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun initGeneralPreferences() {
 | 
			
		||||
        binding.viewer.onItemSelectedListener = { position ->
 | 
			
		||||
            val readingModeType = ReadingModeType.fromSpinner(position)
 | 
			
		||||
            activity.viewModel.setMangaReadingMode(readingModeType.flagValue)
 | 
			
		||||
        }
 | 
			
		||||
        binding.viewer.setSelection(activity.viewModel.manga?.readingModeType?.let { ReadingModeType.fromPreference(it.toInt()).prefValue } ?: ReadingModeType.DEFAULT.prefValue)
 | 
			
		||||
 | 
			
		||||
        binding.rotationMode.onItemSelectedListener = { position ->
 | 
			
		||||
            val rotationType = OrientationType.fromSpinner(position)
 | 
			
		||||
            activity.viewModel.setMangaOrientationType(rotationType.flagValue)
 | 
			
		||||
        }
 | 
			
		||||
        binding.rotationMode.setSelection(activity.viewModel.manga?.orientationType?.let { OrientationType.fromPreference(it.toInt()).prefValue } ?: OrientationType.DEFAULT.prefValue)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +1,7 @@
 | 
			
		||||
package eu.kanade.tachiyomi.util.preference
 | 
			
		||||
 | 
			
		||||
import android.widget.CompoundButton
 | 
			
		||||
import tachiyomi.core.preference.Preference
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Binds a checkbox or switch view with a boolean preference.
 | 
			
		||||
 */
 | 
			
		||||
fun CompoundButton.bindToPreference(pref: Preference<Boolean>) {
 | 
			
		||||
    isChecked = pref.get()
 | 
			
		||||
    setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
operator fun <T> Preference<Set<T>>.plusAssign(item: T) {
 | 
			
		||||
    set(get() + item)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
@file:Suppress("PackageDirectoryMismatch")
 | 
			
		||||
 | 
			
		||||
package com.google.android.material.bottomsheet
 | 
			
		||||
 | 
			
		||||
import android.view.View
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns package-private elevation value
 | 
			
		||||
 */
 | 
			
		||||
fun <T : View> BottomSheetBehavior<T>.getElevation(): Float {
 | 
			
		||||
    return elevation.takeIf { it >= 0F } ?: 0F
 | 
			
		||||
}
 | 
			
		||||
@@ -1,30 +1,7 @@
 | 
			
		||||
package eu.kanade.tachiyomi.util.view
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.graphics.Color
 | 
			
		||||
import android.view.Window
 | 
			
		||||
import android.view.WindowManager
 | 
			
		||||
import com.google.android.material.elevation.ElevationOverlayProvider
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.getResourceColor
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.isNavigationBarNeedsScrim
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sets navigation bar color to transparent if system's config_navBarNeedsScrim is false,
 | 
			
		||||
 * otherwise it will use the theme navigationBarColor with 70% opacity.
 | 
			
		||||
 *
 | 
			
		||||
 * @see isNavigationBarNeedsScrim
 | 
			
		||||
 */
 | 
			
		||||
fun Window.setNavigationBarTransparentCompat(context: Context, elevation: Float = 0F) {
 | 
			
		||||
    navigationBarColor = if (context.isNavigationBarNeedsScrim()) {
 | 
			
		||||
        // Set navbar scrim 70% of navigationBarColor
 | 
			
		||||
        ElevationOverlayProvider(context).compositeOverlayIfNeeded(
 | 
			
		||||
            context.getResourceColor(android.R.attr.navigationBarColor, 0.7F),
 | 
			
		||||
            elevation,
 | 
			
		||||
        )
 | 
			
		||||
    } else {
 | 
			
		||||
        Color.TRANSPARENT
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun Window.setSecureScreen(enabled: Boolean) {
 | 
			
		||||
    if (enabled) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,117 +0,0 @@
 | 
			
		||||
package eu.kanade.tachiyomi.widget
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.util.AttributeSet
 | 
			
		||||
import android.view.Gravity
 | 
			
		||||
import android.view.LayoutInflater
 | 
			
		||||
import android.view.MenuItem
 | 
			
		||||
import android.widget.FrameLayout
 | 
			
		||||
import androidx.appcompat.content.res.AppCompatResources
 | 
			
		||||
import androidx.appcompat.view.menu.MenuBuilder
 | 
			
		||||
import androidx.appcompat.widget.PopupMenu
 | 
			
		||||
import androidx.core.content.withStyledAttributes
 | 
			
		||||
import androidx.core.view.forEach
 | 
			
		||||
import androidx.core.view.get
 | 
			
		||||
import androidx.core.view.size
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.databinding.PrefSpinnerBinding
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.getResourceColor
 | 
			
		||||
import tachiyomi.core.preference.Preference
 | 
			
		||||
 | 
			
		||||
class MaterialSpinnerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
 | 
			
		||||
    FrameLayout(context, attrs) {
 | 
			
		||||
 | 
			
		||||
    private var entries = emptyList<String>()
 | 
			
		||||
    private var selectedPosition = 0
 | 
			
		||||
    private var popup: PopupMenu? = null
 | 
			
		||||
 | 
			
		||||
    var onItemSelectedListener: ((Int) -> Unit)? = null
 | 
			
		||||
        set(value) {
 | 
			
		||||
            field = value
 | 
			
		||||
            if (value != null) {
 | 
			
		||||
                popup = makeSettingsPopup()
 | 
			
		||||
                setOnTouchListener(popup?.dragToOpenListener)
 | 
			
		||||
                setOnClickListener {
 | 
			
		||||
                    popup?.show()
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private val emptyIcon by lazy {
 | 
			
		||||
        AppCompatResources.getDrawable(context, R.drawable.ic_blank_24dp)
 | 
			
		||||
    }
 | 
			
		||||
    private val checkmarkIcon by lazy {
 | 
			
		||||
        AppCompatResources.getDrawable(context, R.drawable.ic_check_24dp)?.mutate()?.apply {
 | 
			
		||||
            setTint(context.getResourceColor(android.R.attr.textColorPrimary))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val binding = PrefSpinnerBinding.inflate(LayoutInflater.from(context), this, false)
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        addView(binding.root)
 | 
			
		||||
 | 
			
		||||
        context.withStyledAttributes(set = attrs, attrs = R.styleable.MaterialSpinnerView) {
 | 
			
		||||
            val title = getString(R.styleable.MaterialSpinnerView_title).orEmpty()
 | 
			
		||||
            binding.title.text = title
 | 
			
		||||
 | 
			
		||||
            val viewEntries = getTextArray(R.styleable.MaterialSpinnerView_android_entries)
 | 
			
		||||
                .orEmpty()
 | 
			
		||||
                .map { it.toString() }
 | 
			
		||||
            entries = viewEntries
 | 
			
		||||
            binding.details.text = viewEntries.firstOrNull().orEmpty()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun setSelection(selection: Int) {
 | 
			
		||||
        if (selectedPosition < (popup?.menu?.size ?: 0)) {
 | 
			
		||||
            popup?.menu?.getItem(selectedPosition)?.let {
 | 
			
		||||
                it.icon = emptyIcon
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        selectedPosition = selection
 | 
			
		||||
        popup?.menu?.getItem(selectedPosition)?.let {
 | 
			
		||||
            it.icon = checkmarkIcon
 | 
			
		||||
        }
 | 
			
		||||
        binding.details.text = entries.getOrNull(selection).orEmpty()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun makeSettingsPopup(preference: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null): PopupMenu {
 | 
			
		||||
        return createPopupMenu { pos ->
 | 
			
		||||
            preference.set(pos + offset)
 | 
			
		||||
            block?.invoke(pos)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun makeSettingsPopup(): PopupMenu {
 | 
			
		||||
        return createPopupMenu { pos ->
 | 
			
		||||
            onItemSelectedListener?.invoke(pos)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun menuClicked(menuItem: MenuItem): Int {
 | 
			
		||||
        val pos = menuItem.itemId
 | 
			
		||||
        setSelection(pos)
 | 
			
		||||
        return pos
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("RestrictedApi")
 | 
			
		||||
    fun createPopupMenu(onItemClick: (Int) -> Unit): PopupMenu {
 | 
			
		||||
        val popup = PopupMenu(context, this, Gravity.END, R.attr.actionOverflowMenuStyle, 0)
 | 
			
		||||
        entries.forEachIndexed { index, entry ->
 | 
			
		||||
            popup.menu.add(0, index, 0, entry)
 | 
			
		||||
        }
 | 
			
		||||
        (popup.menu as? MenuBuilder)?.setOptionalIconsVisible(true)
 | 
			
		||||
        popup.menu.forEach {
 | 
			
		||||
            it.icon = emptyIcon
 | 
			
		||||
        }
 | 
			
		||||
        popup.menu[selectedPosition].icon = checkmarkIcon
 | 
			
		||||
        popup.setOnMenuItemClickListener { menuItem ->
 | 
			
		||||
            val pos = menuClicked(menuItem)
 | 
			
		||||
            onItemClick(pos)
 | 
			
		||||
            true
 | 
			
		||||
        }
 | 
			
		||||
        return popup
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user