diff --git a/app/src/main/java/com/hippo/ehviewer/widget/ImageSearchLayout.java b/app/src/main/java/com/hippo/ehviewer/widget/ImageSearchLayout.java deleted file mode 100644 index 3deeabbc4..000000000 --- a/app/src/main/java/com/hippo/ehviewer/widget/ImageSearchLayout.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2016 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.ehviewer.widget; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.ImageDecoder; -import android.net.Uri; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.view.AbsSavedState; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.CheckBox; -import android.widget.ImageView; -import android.widget.LinearLayout; - -import androidx.annotation.Nullable; - -import com.hippo.ehviewer.AppConfig; -import com.hippo.ehviewer.R; -import com.hippo.ehviewer.client.data.ListUrlBuilder; -import com.hippo.ehviewer.client.exception.EhException; -import com.hippo.image.Image; -import com.hippo.unifile.UniFile; -import com.hippo.yorozuya.IOUtils; -import com.hippo.yorozuya.ViewUtils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public final class ImageSearchLayout extends LinearLayout implements View.OnClickListener { - - private static final String TAG = ImageSearchLayout.class.getSimpleName(); - - private ImageView mPreview; - private View mSelectImage; - private CheckBox mSearchUSS; - private CheckBox mSearchOSC; - - private Helper mHelper; - - @Nullable - private String mImagePath; - - public ImageSearchLayout(Context context) { - super(context); - init(context); - } - - public ImageSearchLayout(Context context, AttributeSet attrs) { - super(context, attrs); - init(context); - } - - public ImageSearchLayout(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(context); - } - - @SuppressWarnings("deprecation") - public void init(Context context) { - setOrientation(VERTICAL); - setDividerDrawable(context.getResources().getDrawable(R.drawable.spacer_keyline)); - setShowDividers(SHOW_DIVIDER_MIDDLE); - setClipChildren(false); - setClipToPadding(false); - LayoutInflater.from(context).inflate(R.layout.widget_image_search, this); - - mPreview = (ImageView) ViewUtils.$$(this, R.id.preview); - mSelectImage = ViewUtils.$$(this, R.id.select_image); - mSearchUSS = (CheckBox) ViewUtils.$$(this, R.id.search_uss); - mSearchOSC = (CheckBox) ViewUtils.$$(this, R.id.search_osc); - - mSelectImage.setOnClickListener(this); - } - - public void setHelper(Helper helper) { - mHelper = helper; - } - - @Override - public void onClick(View v) { - if (v == mSelectImage) { - if (null != mHelper) { - mHelper.onSelectImage(); - } - } - } - - public void setImageUri(@Nullable Uri imageUri) { - if (null == imageUri) { - return; - } - - Context context = getContext(); - UniFile file = UniFile.fromUri(context, imageUri); - if (null == file) { - return; - } - - try { - var src = ImageDecoder.createSource(context.getContentResolver(), imageUri); - Bitmap bitmap = ImageDecoder.decodeBitmap(src, Image.getImageSearchDecoderSampleListener()); - File temp = AppConfig.createTempFile(); - if (null == temp) { - return; - } - - // TODO ehentai image search is bad when I'm writing this line. - // Re-compress image will make image search failed. - OutputStream os = null; - try { - os = new FileOutputStream(temp); - bitmap.compress(Bitmap.CompressFormat.JPEG, 90, os); - mImagePath = temp.getPath(); - mPreview.setImageBitmap(bitmap); - ((View) mPreview.getParent()).setVisibility(VISIBLE); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } finally { - IOUtils.closeQuietly(os); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void setImagePath(@Nullable String imagePath) { - if (null == imagePath) { - return; - } - - InputStream is = null; - try { - is = new FileInputStream(imagePath); - Bitmap bitmap = BitmapFactory.decodeStream(is); - if (null == bitmap) { - return; - } - mImagePath = imagePath; - mPreview.setImageBitmap(bitmap); - ((View) mPreview.getParent()).setVisibility(VISIBLE); - } catch (FileNotFoundException e) { - // Ignore - } finally { - IOUtils.closeQuietly(is); - } - } - - public void formatListUrlBuilder(ListUrlBuilder builder) throws EhException { - if (null == mImagePath) { - throw new EhException(getContext().getString(R.string.select_image_first)); - } - - builder.setImagePath(mImagePath); - builder.setUseSimilarityScan(mSearchUSS.isChecked()); - builder.setOnlySearchCovers(mSearchOSC.isChecked()); - } - - @Override - protected Parcelable onSaveInstanceState() { - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.imagePath = mImagePath; - return ss; - } - - @Override - protected void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; - super.onRestoreInstanceState(ss.getSuperState()); - setImagePath(ss.imagePath); - } - - public interface Helper { - void onSelectImage(); - } - - private static class SavedState extends AbsSavedState { - - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { - @Override - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - @Override - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - String imagePath; - - /** - * Constructor called from {@link ImageSearchLayout#onSaveInstanceState()} - */ - protected SavedState(Parcelable superState) { - super(superState); - } - - /** - * Constructor called from {@link #CREATOR} - */ - protected SavedState(Parcel source) { - super(source); - imagePath = source.readString(); - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeString(imagePath); - } - } -} diff --git a/app/src/main/java/com/hippo/ehviewer/widget/ImageSearchLayout.kt b/app/src/main/java/com/hippo/ehviewer/widget/ImageSearchLayout.kt new file mode 100644 index 000000000..433671a5d --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/widget/ImageSearchLayout.kt @@ -0,0 +1,88 @@ +package com.hippo.ehviewer.widget + +import android.content.Context +import android.util.AttributeSet +import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageOnly +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.sizeIn +import androidx.compose.material3.Card +import androidx.compose.material3.Checkbox +import androidx.compose.material3.FilledTonalButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ProvideTextStyle +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.AbstractComposeView +import androidx.compose.ui.res.dimensionResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import coil.compose.AsyncImage +import com.google.accompanist.themeadapter.material3.Mdc3Theme +import com.hippo.ehviewer.R +import com.hippo.ehviewer.client.data.ListUrlBuilder +import com.hippo.util.pickVisualMedia +import kotlinx.coroutines.launch + +class ImageSearchLayout @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, +) : AbstractComposeView(context, attrs, defStyle) { + @Composable + override fun Content() { + Mdc3Theme { + val coroutineScope = rememberCoroutineScope() + var uss by rememberSaveable { mutableStateOf(false) } + var osc by rememberSaveable { mutableStateOf(false) } + var path by rememberSaveable { mutableStateOf("") } + + fun selectImage() = coroutineScope.launch { + path = pickVisualMedia(ImageOnly).toString() + } + + Column(modifier = Modifier.fillMaxWidth()) { + Card(modifier = Modifier.align(Alignment.CenterHorizontally)) { + val maxSize = dimensionResource(id = R.dimen.image_search_max_size) + if (path.isNotBlank()) { + AsyncImage( + model = path, + contentDescription = null, + modifier = Modifier.sizeIn(maxWidth = maxSize, maxHeight = maxSize), + ) + } + } + FilledTonalButton( + onClick = ::selectImage, + modifier = Modifier.fillMaxWidth().padding(8.dp), + ) { + Text(text = stringResource(id = R.string.select_image)) + } + ProvideTextStyle(MaterialTheme.typography.bodyMedium) { + Row { + Row(modifier = Modifier.weight(1f)) { + Checkbox(checked = uss, onCheckedChange = { uss = it }) + Text(text = stringResource(id = R.string.search_uss), modifier = Modifier.align(Alignment.CenterVertically)) + } + Row(modifier = Modifier.weight(1f)) { + Checkbox(checked = osc, onCheckedChange = { osc = it }) + Text(text = stringResource(id = R.string.search_osc), modifier = Modifier.align(Alignment.CenterVertically)) + } + } + } + } + } + } + + fun formatListUrlBuilder(lub: ListUrlBuilder) { + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/widget/SearchLayout.kt b/app/src/main/java/com/hippo/ehviewer/widget/SearchLayout.kt index 172cd2855..629594d6f 100644 --- a/app/src/main/java/com/hippo/ehviewer/widget/SearchLayout.kt +++ b/app/src/main/java/com/hippo/ehviewer/widget/SearchLayout.kt @@ -30,12 +30,9 @@ import android.widget.CompoundButton import android.widget.FrameLayout import android.widget.ImageView import android.widget.TextView -import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageOnly import androidx.annotation.IntDef import androidx.core.content.edit import androidx.core.view.forEach -import androidx.lifecycle.findViewTreeLifecycleOwner -import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager @@ -51,11 +48,9 @@ import com.hippo.ehviewer.R import com.hippo.ehviewer.client.EhUtils import com.hippo.ehviewer.client.data.ListUrlBuilder import com.hippo.ehviewer.client.exception.EhException -import com.hippo.util.pickVisualMedia import com.hippo.widget.RadioGridGroup import com.hippo.yorozuya.NumberUtils import com.hippo.yorozuya.ViewUtils -import kotlinx.coroutines.launch @SuppressLint("InflateParams") class SearchLayout @JvmOverloads constructor( @@ -148,12 +143,6 @@ class SearchLayout @JvmOverloads constructor( mTableAdvanceSearch = mAdvanceView.findViewById(R.id.search_advance_search_table) // Create image view mImageView = mInflater.inflate(R.layout.search_image, null) as ImageSearchLayout - mImageView.setHelper { - findViewTreeLifecycleOwner()!!.lifecycleScope.launch { - val uri = pickVisualMedia(ImageOnly) - mImageView.setImageUri(uri) - } - } // Create action view mActionView = mInflater.inflate(R.layout.search_action, null) mActionView.layoutParams = LayoutParams( diff --git a/app/src/main/res/drawable/spacer_keyline.xml b/app/src/main/res/drawable/spacer_keyline.xml deleted file mode 100644 index cd4b75f26..000000000 --- a/app/src/main/res/drawable/spacer_keyline.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/layout/widget_image_search.xml b/app/src/main/res/layout/widget_image_search.xml deleted file mode 100644 index 25d99e340..000000000 --- a/app/src/main/res/layout/widget_image_search.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - -