Compare commits

..
Author SHA1 Message Date
txyyh 884d460b52 Rel 1.8.3.0-alpha03
Releases / Build (push) Has been cancelled
2022-11-05 09:50:13 +00:00
tarsin beb97270a0 Initial support for predictive back gesture
https://developer.android.com/guide/navigation/predictive-back-gesture
2022-11-05 12:48:03 +08:00
小白-白 52681bd386 Fix favorite page load (#368)
修复收藏页面按发布时间排序时无法翻页问题
2022-11-04 11:40:30 +08:00
renovate[bot] d772a737fc Update plugin com.google.devtools.ksp to v1.7.20-1.0.8 (1.8.x.x) (#367)
Update plugin com.google.devtools.ksp to v1.7.20-1.0.8

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-04 11:15:20 +08:00
tarsin 638fcfea12 Do not cancel a sent call
Should fix slow load speed
2022-11-04 00:22:25 +08:00
tarsin cae32cca5a Rel 1.8.3.0-alpha02
Releases / Build (push) Has been cancelled
2022-11-03 23:19:06 +08:00
tarsin c429e7054a Don't parse found in common path 2022-11-03 23:11:33 +08:00
tarsin f526f11c73 Fix tag search page load 2022-11-03 22:59:27 +08:00
tarsin 892016368f Fix favourite scene data restore 2022-11-03 22:54:28 +08:00
tarsin d9464ac278 Fix uploader page request 2022-11-03 16:20:47 +08:00
tarsin a68a9995a1 Rel 1.8.3.0-alpha01
Releases / Build (push) Has been cancelled
2022-11-03 16:07:16 +08:00
tarsin 1a0c2cb180 Relax founds limit
We will calculate accurately later
2022-11-03 16:01:50 +08:00
tarsin d7572f5a79 Fix restore state 2022-11-03 15:48:35 +08:00
tarsin a208651e13 Code clean and allow refresh pages 2022-11-03 15:31:31 +08:00
15 changed files with 165 additions and 136 deletions

No files matched your search

+2 -2
View File
@@ -31,8 +31,8 @@ android {
applicationId "moe.tarsin.ehviewer"
minSdkVersion 31
targetSdkVersion 33
versionCode 180014
versionName "1.8.3.0-alpha"
versionCode 180017
versionName "1.8.3.0-alpha03"
resConfigs 'zh', 'zh-rCN', 'zh-rHK', 'zh-rTW', 'es', 'ja', 'ko', 'fr', 'de', 'th'
}
+1
View File
@@ -37,6 +37,7 @@
android:allowBackup="true"
android:appCategory="image"
android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="true"
android:fullBackupContent="@xml/backup_scheme"
android:hasFragileUserData="true"
android:icon="@mipmap/ic_launcher"
@@ -156,7 +156,6 @@ public final class ConacoTask<V> {
} else if (mNetworkLoadTask != null) { // Getting from network
mNetworkLoadTask.cancel(false);
if (mCall != null) {
mCall.cancel();
mCall = null;
}
}
@@ -108,6 +108,7 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
public void reset() {
mMode = MODE_NORMAL;
mNextGid = 0;
mPrevGid = 0;
mCategory = EhUtils.NONE;
mKeyword = null;
mAdvanceSearch = -1;
@@ -576,7 +577,7 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
// Empty
}
if (mNextGid != 0) {
sb.append('/').append(mNextGid);
sb.append("?next=").append(mNextGid);
}
return sb.toString();
}
@@ -589,7 +590,7 @@ public class ListUrlBuilder implements Cloneable, Parcelable {
// Empty
}
if (mNextGid != 0) {
sb.append('/').append(mNextGid);
sb.append("?next=").append(mNextGid);
}
return sb.toString();
}
@@ -34,7 +34,7 @@ import java.util.List;
import java.util.regex.Pattern;
public class FavoritesParser {
private static final Pattern PATTERN_NEXT_PAGE = Pattern.compile("next=(\\d+-\\d+)");
private static final Pattern PATTERN_NEXT_PAGE = Pattern.compile("next=(\\d+(-\\d+)?)");
public static Result parse(String body) throws Exception {
if (body.contains("This page requires you to log on.</p>")) {
@@ -307,22 +307,12 @@ public class GalleryListParser {
Result result = new Result();
Document d = Jsoup.parse(body);
try {
Element stt = d.getElementsByClass("searchtext").first();
assert stt != null;
result.founds = getInt(stt.text());
} catch (Throwable e) {
ExceptionUtils.throwIfFatal(e);
result.noWatchedTags = body.contains("<p>You do not have any watched tags");
if (body.contains("No hits found</p>")) {
result.founds = 0;
//noinspection unchecked
result.galleryInfoList = Collections.EMPTY_LIST;
return result;
} else {
result.founds = Integer.MAX_VALUE;
}
result.founds = Integer.MAX_VALUE;
result.noWatchedTags = body.contains("<p>You do not have any watched tags");
if (body.contains("No hits found</p>")) {
result.founds = 0;
result.galleryInfoList = Collections.EMPTY_LIST;
return result;
}
try {
@@ -57,7 +57,7 @@ class SettingsActivity : EhActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
onBackPressedDispatcher.onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.InputType;
import android.text.TextUtils;
import android.util.SparseBooleanArray;
@@ -1177,7 +1178,7 @@ public class FavoritesScene extends BaseScene implements
private class FavoritesHelper extends GalleryInfoContentHelper {
public int pgCounter = 0;
public String nextPg = "";
public String nextPg = null;
@Override
protected void getPageData(final int taskId, int type, int page) {
@@ -1301,5 +1302,25 @@ public class FavoritesScene extends BaseScene implements
}
}
}
@Override
protected void onClearData() {
super.onClearData();
nextPg = null;
}
@Override
protected Parcelable saveInstanceState(Parcelable superState) {
Bundle bundle = (Bundle) super.saveInstanceState(superState);
bundle.putString(KEY_NEXT_PAGE, nextPg);
return bundle;
}
@Override
protected Parcelable restoreInstanceState(Parcelable state) {
Bundle bundle = (Bundle) state;
nextPg = bundle.getString(KEY_NEXT_PAGE);
return super.restoreInstanceState(state);
}
}
}
@@ -91,6 +91,7 @@ import com.hippo.ehviewer.widget.SearchBar;
import com.hippo.ehviewer.widget.SearchLayout;
import com.hippo.scene.Announcer;
import com.hippo.scene.SceneFragment;
import com.hippo.scene.StageActivity;
import com.hippo.util.ExceptionUtils;
import com.hippo.view.BringOutTransition;
import com.hippo.view.ViewTransition;
@@ -778,6 +779,21 @@ public final class GalleryListScene extends BaseScene
return view;
}
public boolean isBackpressCanPreviewLauncherStatus() {
if (null != mFabLayout && mFabLayout.isExpanded()) {
return false;
}
switch (mState) {
case STATE_NORMAL:
return getStackIndex() == 0;
case STATE_SIMPLE_SEARCH:
case STATE_SEARCH:
case STATE_SEARCH_SHOW_LIST:
return false;
}
return false;
}
@Override
public void onBackPressed() {
if (null != mFabLayout && mFabLayout.isExpanded()) {
@@ -1184,6 +1200,7 @@ public final class GalleryListScene extends BaseScene
break;
}
}
((StageActivity)requireActivity()).updateBackPressCallBackStatus();
}
@Override
@@ -1706,6 +1723,8 @@ public final class GalleryListScene extends BaseScene
if (page != 0)
mUrlBuilder.setNextGid(minGid);
else
mUrlBuilder.setNextGid(0);
if (ListUrlBuilder.MODE_IMAGE_SEARCH == mUrlBuilder.getMode()) {
EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_IMAGE_SEARCH);
@@ -35,6 +35,10 @@ public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelp
public int minGid = -1;
private static final String KEY_DATA_MAP = "data_map";
private static final String KEY_MAX_GID = "max_gid";
private static final String KEY_MIN_GID = "min_gid";
public static final String KEY_NEXT_PAGE = "next_page";
private final FavouriteStatusRouter.Listener listener;
@SuppressLint("UseSparseArrays")
private Map<Long, GalleryInfo> map = new HashMap<>();
@@ -86,6 +90,8 @@ public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelp
@Override
protected void onClearData() {
map.clear();
maxGid = -1;
minGid = -1;
}
@Override
@@ -96,6 +102,8 @@ public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelp
FavouriteStatusRouter router = EhApplication.getFavouriteStatusRouter();
int id = router.saveDataMap(map);
bundle.putInt(KEY_DATA_MAP, id);
bundle.putInt(KEY_MIN_GID, minGid);
bundle.putInt(KEY_MAX_GID, maxGid);
return bundle;
}
@@ -112,6 +120,8 @@ public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelp
this.map = map;
}
}
minGid = bundle.getInt(KEY_MIN_GID);
maxGid = bundle.getInt(KEY_MAX_GID);
return super.restoreInstanceState(state);
}
@@ -61,6 +61,7 @@ public class SceneFragment extends Fragment {
FragmentActivity activity = getActivity();
if (activity instanceof StageActivity) {
((StageActivity) activity).startScene(announcer, horizontal);
((StageActivity) activity).updateBackPressCallBackStatus();
}
}
@@ -23,6 +23,7 @@ import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
@@ -31,6 +32,7 @@ import androidx.fragment.app.FragmentTransaction;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ui.EhActivity;
import com.hippo.ehviewer.ui.scene.GalleryListScene;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.IntIdGenerator;
@@ -58,6 +60,8 @@ public abstract class StageActivity extends EhActivity {
private final SceneViewComparator mSceneViewComparator = new SceneViewComparator();
private int mStageId = IntIdGenerator.INVALID_ID;
private OnBackPressedCallback callback;
public static void registerLaunchMode(Class<?> clazz, @SceneFragment.LaunchMode int launchMode) {
if (launchMode != SceneFragment.LAUNCH_MODE_STANDARD &&
launchMode != SceneFragment.LAUNCH_MODE_SINGLE_TOP &&
@@ -140,6 +144,8 @@ public abstract class StageActivity extends EhActivity {
protected final void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
callback = new BackPressCallBack(false);
getOnBackPressedDispatcher().addCallback(callback);
if (savedInstanceState != null) {
mStageId = savedInstanceState.getInt(KEY_STAGE_ID, IntIdGenerator.INVALID_ID);
ArrayList<String> list = savedInstanceState.getStringArrayList(KEY_SCENE_TAG_LIST);
@@ -247,6 +253,7 @@ public abstract class StageActivity extends EhActivity {
public void startScene(Announcer announcer) {
startScene(announcer, false);
updateBackPressCallBackStatus();
}
public void startScene(Announcer announcer, boolean horizontal) {
@@ -461,6 +468,7 @@ public abstract class StageActivity extends EhActivity {
// TODO Call onNewArguments when view created ?
scene.onNewArguments(args);
}
updateBackPressCallBackStatus();
}
int getSceneIndex(SceneFragment scene) {
@@ -477,6 +485,7 @@ public abstract class StageActivity extends EhActivity {
public void finishScene(SceneFragment scene) {
finishScene(scene.getTag());
updateBackPressCallBackStatus();
}
private void finishScene(String tag) {
@@ -558,25 +567,51 @@ public abstract class StageActivity extends EhActivity {
} else {
fragmentManager.beginTransaction().detach(fragment).attach(fragment).commitAllowingStateLoss();
}
updateBackPressCallBackStatus();
}
@Override
public void onBackPressed() {
int size = mSceneTagList.size();
String tag = mSceneTagList.get(size - 1);
SceneFragment scene;
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
if (fragment == null) {
Log.e(TAG, "onBackPressed: Can't find scene by tag: " + tag);
return;
}
if (!(fragment instanceof SceneFragment)) {
Log.e(TAG, "onBackPressed: The fragment is not SceneFragment");
return;
private boolean shouldEnableBackPressCallBack() {
if (mSceneTagList.size() > 1)
return true;
if (mSceneTagList.size() == 0)
return false;
String tag = mSceneTagList.get(0);
GalleryListScene fragment = (GalleryListScene) getSupportFragmentManager().findFragmentByTag(tag);
if (fragment == null)
return false;
return !fragment.isBackpressCanPreviewLauncherStatus();
}
public void updateBackPressCallBackStatus() {
var isEnabled = callback.isEnabled();
var shouldEnable = shouldEnableBackPressCallBack();
if (isEnabled != shouldEnable)
callback.setEnabled(shouldEnable);
}
class BackPressCallBack extends OnBackPressedCallback {
public BackPressCallBack(boolean enabled) {
super(enabled);
}
scene = (SceneFragment) fragment;
scene.onBackPressed();
@Override
public void handleOnBackPressed() {
int size = mSceneTagList.size();
String tag = mSceneTagList.get(size - 1);
SceneFragment scene;
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
if (fragment == null) {
Log.e(TAG, "onBackPressed: Can't find scene by tag: " + tag);
return;
}
if (!(fragment instanceof SceneFragment)) {
Log.e(TAG, "onBackPressed: The fragment is not SceneFragment");
return;
}
scene = (SceneFragment) fragment;
scene.onBackPressed();
}
}
@Override
@@ -451,48 +451,22 @@ public class ContentLayout extends FrameLayout {
switch (mCurrentTaskType) {
case TYPE_REFRESH:
mStartPage = 0;
mEndPage = 1;
mPages = pages;
mNextPage = nextPage;
mPageDivider.clear();
mPageDivider.add(data.size());
if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) { // Not found
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
mData.clear();
onClearData();
mData.addAll(data);
onAddData(data);
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
// RecyclerView scroll
if (mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
@@ -513,33 +487,24 @@ public class ContentLayout extends FrameLayout {
// assert mStartPage >= 0
if (data.isEmpty()) {
if (true || mStartPage <= 0) { // OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mCurrentTaskType == TYPE_PRE_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll, to top
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Keep UI
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
// Get previous
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mStartPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
if (mCurrentTaskType == TYPE_PRE_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll, to top
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
} else {
mData.addAll(0, data);
@@ -576,33 +541,24 @@ public class ContentLayout extends FrameLayout {
mPages = Math.max(mEndPage, pages);
if (data.isEmpty()) {
if (true || mEndPage >= mPages) { // OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mCurrentTaskType == TYPE_NEXT_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Keep UI
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
if (mCurrentTaskType == TYPE_NEXT_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
} else {
mData.addAll(data);
@@ -639,23 +595,11 @@ public class ContentLayout extends FrameLayout {
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) { // Not found
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
// Not found
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
mData.clear();
onClearData();
@@ -804,6 +748,12 @@ public class ContentLayout extends FrameLayout {
}
private void doRefresh() {
mStartPage = 0;
mEndPage = 1;
mPages = 0;
mPageDivider.clear();
mData.clear();
onClearData();
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH;
mCurrentTaskPage = 0;
@@ -29,6 +29,7 @@ import androidx.annotation.NonNull;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.hippo.ehviewer.R;
import com.hippo.scene.StageActivity;
import com.hippo.yorozuya.AnimationUtils;
import com.hippo.yorozuya.SimpleAnimatorListener;
@@ -298,6 +299,7 @@ public class FabLayout extends ViewGroup implements View.OnClickListener {
mOnExpandListener.onExpand(expanded);
}
}
((StageActivity)getContext()).updateBackPressCallBackStatus();
}
+1 -1
View File
@@ -1,7 +1,7 @@
plugins {
id 'com.android.application' version '8.0.0-alpha07' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
id 'com.google.devtools.ksp' version '1.7.20-1.0.7' apply false
id 'com.google.devtools.ksp' version '1.7.20-1.0.8' apply false
}
task clean(type: Delete) {