From 87a4b6a91ba285164dbf93f6c43863ef2ddc4f17 Mon Sep 17 00:00:00 2001 From: tarsin Date: Sun, 30 Apr 2023 15:45:34 +0800 Subject: [PATCH] Initial compose GalleryInfoBottomSheet implementation --- .../ehviewer/ui/GalleryInfoBottomSheet.kt | 253 +++++++----------- .../ehviewer/ui/scene/GalleryDetailScene.kt | 12 +- .../res/layout/item_gallery_info_data.xml | 41 --- .../res/layout/item_gallery_info_header.xml | 38 --- .../main/res/layout/scene_gallery_info.xml | 42 --- 5 files changed, 110 insertions(+), 276 deletions(-) delete mode 100644 app/src/main/res/layout/item_gallery_info_data.xml delete mode 100644 app/src/main/res/layout/item_gallery_info_header.xml delete mode 100644 app/src/main/res/layout/scene_gallery_info.xml diff --git a/app/src/main/java/com/hippo/ehviewer/ui/GalleryInfoBottomSheet.kt b/app/src/main/java/com/hippo/ehviewer/ui/GalleryInfoBottomSheet.kt index 697439a7a..e19f17819 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/GalleryInfoBottomSheet.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/GalleryInfoBottomSheet.kt @@ -15,14 +15,26 @@ */ package com.hippo.ehviewer.ui -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.hippo.ehviewer.EhApplication import com.hippo.ehviewer.R import com.hippo.ehviewer.Settings import com.hippo.ehviewer.UrlOpener @@ -31,152 +43,95 @@ import com.hippo.ehviewer.client.EhUtils import com.hippo.ehviewer.client.data.GalleryDetail import com.hippo.util.tellClipboardWithToast -class GalleryInfoBottomSheet(detail: GalleryDetail) : BottomSheetDialogFragment() { - private var mKeys: ArrayList = arrayListOf() - private var mValues: ArrayList = arrayListOf() - private var mRecyclerView: RecyclerView? = null - private val mDetail: GalleryDetail = detail +private const val INDEX_URL = 2 +private const val INDEX_PARENT = 9 - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View? { - parseDetail() - val view = inflater.inflate(R.layout.scene_gallery_info, container, false) - val recyclerView = view.findViewById(R.id.recycler_view) as RecyclerView - val adapter = InfoAdapter() - recyclerView.adapter = adapter - recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false) - recyclerView.clipToPadding = false - recyclerView.setHasFixedSize(true) - mRecyclerView = recyclerView - return view - } +private val keys = arrayOf( + R.string.key_gid, + R.string.key_token, + R.string.key_url, + R.string.key_title, + R.string.key_title_jpn, + R.string.key_thumb, + R.string.key_category, + R.string.key_uploader, + R.string.key_posted, + R.string.key_parent, + R.string.key_visible, + R.string.key_language, + R.string.key_pages, + R.string.key_size, + R.string.key_favorite_count, + R.string.key_favorited, + R.string.key_rating_count, + R.string.key_rating, + R.string.key_torrents, + R.string.key_torrent_url, + R.string.favorite_name, +) - private fun parseDetail() { - mKeys.add(getString(R.string.header_key)) - mValues.add(getString(R.string.header_value)) - mKeys.add(getString(R.string.key_gid)) - mValues.add(mDetail.gid.toString()) - mKeys.add(getString(R.string.key_token)) - mValues.add(mDetail.token) - mKeys.add(getString(R.string.key_url)) - mValues.add(EhUrl.getGalleryDetailUrl(mDetail.gid, mDetail.token)) - mKeys.add(getString(R.string.key_title)) - mValues.add(mDetail.title) - mKeys.add(getString(R.string.key_title_jpn)) - mValues.add(mDetail.titleJpn) - mKeys.add(getString(R.string.key_thumb)) - mValues.add(mDetail.thumb) - mKeys.add(getString(R.string.key_category)) - mValues.add(EhUtils.getCategory(mDetail.category)) - mKeys.add(getString(R.string.key_uploader)) - mValues.add(mDetail.uploader) - mKeys.add(getString(R.string.key_posted)) - mValues.add(mDetail.posted) - mKeys.add(getString(R.string.key_parent)) - mValues.add(mDetail.parent) - mKeys.add(getString(R.string.key_visible)) - mValues.add(mDetail.visible) - mKeys.add(getString(R.string.key_language)) - mValues.add(mDetail.language) - mKeys.add(getString(R.string.key_pages)) - mValues.add(mDetail.pages.toString()) - mKeys.add(getString(R.string.key_size)) - mValues.add(mDetail.size) - mKeys.add(getString(R.string.key_favorite_count)) - mValues.add(mDetail.favoriteCount.toString()) - mKeys.add(getString(R.string.key_favorited)) - mValues.add(java.lang.Boolean.toString(mDetail.isFavorited)) - mKeys.add(getString(R.string.key_rating_count)) - mValues.add(mDetail.ratingCount.toString()) - mKeys.add(getString(R.string.key_rating)) - mValues.add(mDetail.rating.toString()) - mKeys.add(getString(R.string.key_torrents)) - mValues.add(mDetail.torrentCount.toString()) - mKeys.add(getString(R.string.key_torrent_url)) - mValues.add(mDetail.torrentUrl) - mKeys.add(getString(R.string.favorite_name)) - mValues.add(mDetail.favoriteName) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - (view.findViewById(R.id.title) as TextView).setText(R.string.gallery_info) - } - - override fun onDestroyView() { - super.onDestroyView() - mRecyclerView?.stopScroll() - } - - fun onItemClick(position: Int): Boolean { - val context = context - return if (null != context && 0 != position) { - if (position == INDEX_PARENT) { - UrlOpener.openUrl(context, mValues[position], true) - } else { - requireActivity() tellClipboardWithToast mValues[position] - if (position == INDEX_URL) { - // Save it to avoid detect the gallery - Settings.putClipboardTextHashCode(mValues[position].hashCode()) - } - } - true - } else { - false - } - } - - private class InfoHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - val key: TextView - val value: TextView - - init { - key = itemView.findViewById(R.id.key) - value = itemView.findViewById(R.id.value) - } - } - - private inner class InfoAdapter : RecyclerView.Adapter() { - private val mInflater: LayoutInflater = layoutInflater - - override fun getItemViewType(position: Int): Int { - return if (position == 0) { - TYPE_HEADER - } else { - TYPE_DATA - } - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): InfoHolder { - return InfoHolder( - mInflater.inflate( - if (viewType == TYPE_HEADER) R.layout.item_gallery_info_header else R.layout.item_gallery_info_data, - parent, - false, - ), +@Composable +fun GalleryInfoBottomSheet( + galleryDetail: GalleryDetail, + onDismissRequest: () -> Unit, +) { + val data = remember(galleryDetail) { + galleryDetail.run { + arrayOf( + gid.toString(), + token, + EhUrl.getGalleryDetailUrl(gid, token), + title, + titleJpn, + thumb, + EhUtils.getCategory(category), + uploader, + posted, + parent, + visible, + language, + pages.toString(), + size, + favoriteCount.toString(), + isFavorited.toString(), + ratingCount.toString(), + rating.toString(), + torrentCount.toString(), + torrentUrl, + favoriteName, ) } - - override fun onBindViewHolder(holder: InfoHolder, position: Int) { - holder.key.text = mKeys[position] - holder.value.text = mValues[position] - holder.itemView.isEnabled = position != 0 - holder.itemView.setOnClickListener { onItemClick(position) } - } - - override fun getItemCount(): Int { - return mKeys.size.coerceAtMost(mValues.size) - } } - companion object { - const val TAG = "GalleryInfoBottomSheet" - private const val INDEX_URL = 3 - private const val INDEX_PARENT = 10 - private const val TYPE_HEADER = 0 - private const val TYPE_DATA = 1 + ModalBottomSheet(onDismissRequest) { + check(data.size == keys.size) + val context = LocalContext.current + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.Center, + ) { + Text(text = stringResource(id = R.string.gallery_info), style = MaterialTheme.typography.titleLarge) + } + CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.labelLarge) { + keys.forEachIndexed { index, i -> + val key = stringResource(i) + Row( + modifier = Modifier.padding(horizontal = dimensionResource(id = R.dimen.keyline_margin)).clickable { + if (index == INDEX_PARENT) { + UrlOpener.openUrl(context, data[index], true) + } else { + EhApplication.application.topActivity!! tellClipboardWithToast data[index] + if (index == INDEX_URL) { + // Save it to avoid detect the gallery + Settings.putClipboardTextHashCode(data[index].hashCode()) + } + } + }.fillMaxWidth(), + ) { + Text(key, modifier = Modifier.width(90.dp).padding(8.dp)) + Text(data[index].orEmpty(), modifier = Modifier.padding(8.dp)) + } + } + } } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.kt index 798bac8ee..d9a2e8fa6 100755 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.kt @@ -377,6 +377,8 @@ class GalleryDetailScene : BaseScene(), DownloadInfoListener { } } + private var showSheet by mutableStateOf(false) + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -409,6 +411,9 @@ class GalleryDetailScene : BaseScene(), DownloadInfoListener { setContent { Mdc3Theme { val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior() + + composeBindingGD?.let { if (showSheet) GalleryInfoBottomSheet(galleryDetail = it) { showSheet = false } } + Scaffold( topBar = { LargeTopAppBar( @@ -837,12 +842,7 @@ class GalleryDetailScene : BaseScene(), DownloadInfoListener { } private fun onGalleryInfoCardClick() { - val gd = composeBindingGD ?: return - val galleryInfoBottomSheet = GalleryInfoBottomSheet(gd) - galleryInfoBottomSheet.show( - requireActivity().supportFragmentManager, - GalleryInfoBottomSheet.TAG, - ) + showSheet = true } private fun onCategoryChipClick() { diff --git a/app/src/main/res/layout/item_gallery_info_data.xml b/app/src/main/res/layout/item_gallery_info_data.xml deleted file mode 100644 index 42d07ca4d..000000000 --- a/app/src/main/res/layout/item_gallery_info_data.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/layout/item_gallery_info_header.xml b/app/src/main/res/layout/item_gallery_info_header.xml deleted file mode 100644 index c24f1377e..000000000 --- a/app/src/main/res/layout/item_gallery_info_header.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/layout/scene_gallery_info.xml b/app/src/main/res/layout/scene_gallery_info.xml deleted file mode 100644 index b16598e0d..000000000 --- a/app/src/main/res/layout/scene_gallery_info.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - -