diff --git a/app/src/main/java/com/hippo/ehviewer/FavouriteStatusRouter.java b/app/src/main/java/com/hippo/ehviewer/FavouriteStatusRouter.java index fa543bb96..e7bc4b9ad 100644 --- a/app/src/main/java/com/hippo/ehviewer/FavouriteStatusRouter.java +++ b/app/src/main/java/com/hippo/ehviewer/FavouriteStatusRouter.java @@ -16,14 +16,43 @@ package com.hippo.ehviewer; +import android.annotation.SuppressLint; +import com.hippo.ehviewer.client.data.GalleryInfo; +import com.hippo.yorozuya.IntIdGenerator; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class FavouriteStatusRouter { + private static final String KEY_DATA_MAP_NEXT_ID = "data_map_next_id"; + + private final IntIdGenerator idGenerator = new IntIdGenerator(Settings.getInt(KEY_DATA_MAP_NEXT_ID, 0)); + @SuppressLint("UseSparseArrays") + private final HashMap> maps = new HashMap<>(); + private List listeners = new ArrayList<>(); + public int saveDataMap(Map map) { + int id = idGenerator.nextId(); + maps.put(id, map); + Settings.putInt(KEY_DATA_MAP_NEXT_ID, idGenerator.nextId()); + return id; + } + + public Map restoreDataMap(int id) { + return maps.remove(id); + } + public void modifyFavourites(long gid, int slot) { + for (Map map : maps.values()) { + GalleryInfo info = map.get(gid); + if (info != null) { + info.favoriteSlot = slot; + } + } + for (Listener listener : listeners) { listener.onModifyFavourites(gid, slot); } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java index b2c37836d..57e3812ca 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java @@ -72,6 +72,7 @@ import com.hippo.ehviewer.ui.annotation.DrawerLifeCircle; import com.hippo.ehviewer.ui.annotation.ViewLifeCircle; import com.hippo.ehviewer.ui.annotation.WholeLifeCircle; import com.hippo.ehviewer.widget.EhDrawerLayout; +import com.hippo.ehviewer.widget.GalleryInfoContentHelper; import com.hippo.ehviewer.widget.SearchBar; import com.hippo.refreshlayout.RefreshLayout; import com.hippo.ripple.Ripple; @@ -395,6 +396,7 @@ public class FavoritesScene extends BaseScene implements } if (null != mHelper) { + mHelper.destroy(); if (1 == mHelper.getShownViewIndex()) { mHasFirstRefresh = false; } @@ -1028,7 +1030,7 @@ public class FavoritesScene extends BaseScene implements } } - private class FavoritesHelper extends ContentLayout.ContentHelper { + private class FavoritesHelper extends GalleryInfoContentHelper { @Override protected void getPageData(final int taskId, int type, int page) { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java index fa8683b66..d44a35c67 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java @@ -83,6 +83,7 @@ import com.hippo.ehviewer.download.DownloadManager; import com.hippo.ehviewer.ui.CommonOperations; import com.hippo.ehviewer.ui.GalleryActivity; import com.hippo.ehviewer.ui.MainActivity; +import com.hippo.ehviewer.widget.GalleryInfoContentHelper; import com.hippo.ehviewer.widget.SearchBar; import com.hippo.ehviewer.widget.SearchLayout; import com.hippo.refreshlayout.RefreshLayout; @@ -683,6 +684,7 @@ public final class GalleryListScene extends BaseScene mSearchBarMover = null; } if (null != mHelper) { + mHelper.destroy(); if (1 == mHelper.getShownViewIndex()) { mHasFirstRefresh = false; } @@ -1473,7 +1475,7 @@ public final class GalleryListScene extends BaseScene } } - private class GalleryListHelper extends ContentLayout.ContentHelper { + private class GalleryListHelper extends GalleryInfoContentHelper { @Override protected void getPageData(int taskId, int type, int page) { diff --git a/app/src/main/java/com/hippo/ehviewer/widget/GalleryInfoContentHelper.java b/app/src/main/java/com/hippo/ehviewer/widget/GalleryInfoContentHelper.java new file mode 100644 index 000000000..06bb92cf1 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/widget/GalleryInfoContentHelper.java @@ -0,0 +1,106 @@ +/* + * Copyright 2019 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.annotation.SuppressLint; +import android.os.Bundle; +import android.os.Parcelable; +import com.hippo.ehviewer.EhApplication; +import com.hippo.ehviewer.FavouriteStatusRouter; +import com.hippo.ehviewer.client.data.GalleryInfo; +import com.hippo.widget.ContentLayout; +import com.hippo.yorozuya.IntIdGenerator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class GalleryInfoContentHelper extends ContentLayout.ContentHelper { + + private static final String KEY_DATA_MAP = "data_map"; + + @SuppressLint("UseSparseArrays") + private Map map = new HashMap<>(); + private FavouriteStatusRouter.Listener listener; + + public GalleryInfoContentHelper() { + listener = (gid, slot) -> { + GalleryInfo info = map.get(gid); + if (info != null) { + info.favoriteSlot = slot; + } + }; + EhApplication.getFavouriteStatusRouter().addListener(listener); + } + + public void destroy() { + EhApplication.getFavouriteStatusRouter().removeListener(listener); + } + + @Override + protected void onAddData(GalleryInfo data) { + map.put(data.gid, data); + } + + @Override + protected void onAddData(List data) { + for (GalleryInfo info : data) { + map.put(info.gid, info); + } + } + + @Override + protected void onRemoveData(GalleryInfo data) { + map.remove(data.gid); + } + + @Override + protected void onRemoveData(List data) { + for (GalleryInfo info : data) { + map.remove(info.gid); + } + } + + @Override + protected void onClearData() { + map.clear(); + } + + @Override + protected Parcelable saveInstanceState(Parcelable superState) { + Bundle bundle = (Bundle) super.saveInstanceState(superState); + + // TODO It's a bad design + FavouriteStatusRouter router = EhApplication.getFavouriteStatusRouter(); + int id = router.saveDataMap(map); + bundle.putInt(KEY_DATA_MAP, id); + + return bundle; + } + + @Override + protected Parcelable restoreInstanceState(Parcelable state) { + Bundle bundle = (Bundle) state; + + int id = bundle.getInt(KEY_DATA_MAP, IntIdGenerator.INVALID_ID); + if (id != IntIdGenerator.INVALID_ID) { + FavouriteStatusRouter router = EhApplication.getFavouriteStatusRouter(); + map = router.restoreDataMap(id); + } + + return super.restoreInstanceState(state); + } +} diff --git a/app/src/main/java/com/hippo/widget/ContentLayout.java b/app/src/main/java/com/hippo/widget/ContentLayout.java index 6d338f009..3ff230a8b 100644 --- a/app/src/main/java/com/hippo/widget/ContentLayout.java +++ b/app/src/main/java/com/hippo/widget/ContentLayout.java @@ -412,6 +412,7 @@ public class ContentLayout extends FrameLayout { public void addAt(int index, E data) { mData.add(index, data); + onAddData(data); for (int i = 0, n = mPageDivider.size(); i < n; i++) { int divider = mPageDivider.get(i); @@ -424,7 +425,8 @@ public class ContentLayout extends FrameLayout { } public void removeAt(int index) { - mData.remove(index); + E data = mData.remove(index); + onRemoveData(data); for (int i = 0, n = mPageDivider.size(); i < n; i++) { int divider = mPageDivider.get(i); @@ -452,6 +454,16 @@ public class ContentLayout extends FrameLayout { } } + protected void onAddData(E data) { } + + protected void onAddData(List data) { } + + protected void onRemoveData(E data) { } + + protected void onRemoveData(List data) { } + + protected void onClearData() { } + public void onGetPageData(int taskId, int nextPage, List data) { if (mCurrentTaskId == taskId) { int dataSize; @@ -466,6 +478,7 @@ public class ContentLayout extends FrameLayout { if (data.isEmpty()) { mData.clear(); + onClearData(); notifyDataSetChanged(); if (true || mEndPage >= mPages) { // Not found @@ -487,7 +500,9 @@ public class ContentLayout extends FrameLayout { } } else { mData.clear(); + onClearData(); mData.addAll(data); + onAddData(data); notifyDataSetChanged(); // Ui change, show content @@ -545,6 +560,7 @@ public class ContentLayout extends FrameLayout { } } else { mData.addAll(0, data); + onAddData(data); notifyItemRangeInserted(0, data.size()); // Ui change, show content @@ -606,6 +622,7 @@ public class ContentLayout extends FrameLayout { } } else { mData.addAll(data); + onAddData(data); notifyItemRangeInserted(oldDataSize, dataSize); // Ui change, show content @@ -634,6 +651,7 @@ public class ContentLayout extends FrameLayout { if (data.isEmpty()) { mData.clear(); + onClearData(); notifyDataSetChanged(); if (true || mEndPage >= mPages) { // Not found @@ -655,7 +673,9 @@ public class ContentLayout extends FrameLayout { } } else { mData.clear(); + onClearData(); mData.addAll(data); + onAddData(data); notifyDataSetChanged(); // Ui change, show content @@ -684,11 +704,14 @@ public class ContentLayout extends FrameLayout { int oldIndexStart = mCurrentTaskPage == mStartPage ? 0 : mPageDivider.get(mCurrentTaskPage - mStartPage - 1); int oldIndexEnd = mPageDivider.get(mCurrentTaskPage - mStartPage); - mData.subList(oldIndexStart, oldIndexEnd).clear(); + List toRemove = mData.subList(oldIndexStart, oldIndexEnd); + onRemoveData(toRemove); + toRemove.clear(); removeDuplicateData(data, oldIndexStart - CHECK_DUPLICATE_RANGE, oldIndexStart + CHECK_DUPLICATE_RANGE); int newIndexStart = oldIndexStart; int newIndexEnd = newIndexStart + data.size(); mData.addAll(oldIndexStart, data); + onAddData(data); notifyDataSetChanged(); for (int i = mCurrentTaskPage - mStartPage, n = mPageDivider.size(); i < n; i++) { @@ -906,7 +929,7 @@ public class ContentLayout extends FrameLayout { private int mSavedDataId = IntIdGenerator.INVALID_ID; - private Parcelable saveInstanceState(Parcelable superState) { + protected Parcelable saveInstanceState(Parcelable superState) { Bundle bundle = new Bundle(); bundle.putParcelable(KEY_SUPER, superState); int shownView = mViewTransition.getShownViewIndex(); @@ -930,7 +953,7 @@ public class ContentLayout extends FrameLayout { return bundle; } - private Parcelable restoreInstanceState(Parcelable state) { + protected Parcelable restoreInstanceState(Parcelable state) { if (state instanceof Bundle) { Bundle bundle = (Bundle) state; mViewTransition.showView(bundle.getInt(KEY_SHOWN_VIEW), false);