diff --git a/app/src/main/java/com/hippo/ehviewer/client/Cancellable.java b/app/src/main/java/com/hippo/ehviewer/client/Cancellable.java new file mode 100644 index 000000000..581aa02e4 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/client/Cancellable.java @@ -0,0 +1,22 @@ +/* + * Copyright 2015 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.client; + +public interface Cancellable { + + void cancel(); +} diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhClient.java b/app/src/main/java/com/hippo/ehviewer/client/EhClient.java index 5c44b7889..587f366a3 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhClient.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhClient.java @@ -40,7 +40,7 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -@SuppressWarnings("unchecked") +// TODO Make request cancle public final class EhClient { private static final String TAG = EhClient.class.getSimpleName(); diff --git a/app/src/main/java/com/hippo/ehviewer/client/data/GalleryDetail.java b/app/src/main/java/com/hippo/ehviewer/client/data/GalleryDetail.java index 0315ff963..270154aaa 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/data/GalleryDetail.java +++ b/app/src/main/java/com/hippo/ehviewer/client/data/GalleryDetail.java @@ -18,8 +18,10 @@ package com.hippo.ehviewer.client.data; import java.util.List; +// TODO not extends GalleryInfo public class GalleryDetail extends GalleryInfo { + public int gid; public String thumb; public String title; public String titleJpn; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/CommentScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/CommentScene.java index 098242544..b7560aab6 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/CommentScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/CommentScene.java @@ -60,6 +60,7 @@ public class CommentScene extends AppbarScene { mRecyclerView.addItemDecoration(decoration); mRecyclerView.setSelector(RippleSalon.generateRippleDrawable(false)); mRecyclerView.setClipToPadding(false); + mRecyclerView.setHasFixedSize(true); } @Override diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java index 98ca72ee4..46ab2df5a 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java @@ -53,6 +53,7 @@ import com.hippo.rippleold.RippleSalon; import com.hippo.scene.Announcer; import com.hippo.scene.RippleCurtain; import com.hippo.scene.Scene; +import com.hippo.scene.SimpleCurtain; import com.hippo.scene.SimpleDialog; import com.hippo.util.Log; import com.hippo.util.URLImageGetter; @@ -83,6 +84,7 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, private View mDownload; private ViewGroup mContent; + private ViewGroup mInfo; private TextView mLanguage; private TextView mPages; private TextView mSize; @@ -154,6 +156,7 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, mShare.setCompoundDrawables(null, shareDrawable, null, null); mRate.setCompoundDrawables(null, rateDrawable, null, null); + mRead.setOnClickListener(this); mDownload.setOnClickListener(this); mFavorite.setOnClickListener(this); @@ -161,6 +164,7 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, mShare.setOnClickListener(this); mRate.setOnClickListener(this); + AccurateClick.setOnAccurateClickListener(mInfo, this); AccurateClick.setOnAccurateClickListener(mComment, this); RippleSalon.addRipple(mRead, false); @@ -189,12 +193,13 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, mDownload = mActionCard.findViewById(R.id.download); mContent = (ViewGroup) findViewById(R.id.content); - mLanguage = (TextView) mContent.findViewById(R.id.language); - mPages = (TextView) mContent.findViewById(R.id.pages); - mSize = (TextView) mContent.findViewById(R.id.size); - mPosted = (TextView) mContent.findViewById(R.id.posted); - mResize = (TextView) mContent.findViewById(R.id.resize); - mFavoredTimes = (TextView) mContent.findViewById(R.id.favoredTimes); + mInfo = (ViewGroup) mContent.findViewById(R.id.info); + mLanguage = (TextView) mInfo.findViewById(R.id.language); + mPages = (TextView) mInfo.findViewById(R.id.pages); + mSize = (TextView) mInfo.findViewById(R.id.size); + mPosted = (TextView) mInfo.findViewById(R.id.posted); + mResize = (TextView) mInfo.findViewById(R.id.resize); + mFavoredTimes = (TextView) mInfo.findViewById(R.id.favoredTimes); mRatingText = (TextSwitcher) mContent.findViewById(R.id.rating_text); mRating = (RatingView) mContent.findViewById(R.id.rating); mFavorite = (TextView) mContent.findViewById(R.id.favorite); @@ -226,7 +231,12 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, return; } - if (v == mRead) { + if (v == mInfo) { + Announcer announcer = new Announcer(); + announcer.setObject(mGalleryDetail); + startScene(InfoScene.class, announcer, + new SimpleCurtain(SimpleCurtain.DIRECTION_RIGHT)); + } else if (v == mRead) { } else if (v == mDownload) { @@ -247,7 +257,14 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, return; } - if (v == mComment) { + if (v == mInfo) { + int[] position = new int[2]; + ViewUtils.getLocationInAncestor(mInfo, position, getSceneView()); + Announcer announcer = new Announcer(); + announcer.setObject(mGalleryDetail); + startScene(InfoScene.class, announcer, + new RippleCurtain((int) x + position[0], (int) y + position[1])); + } else if (v == mComment) { int[] position = new int[2]; ViewUtils.getLocationInAncestor(mComment, position, getSceneView()); Announcer announcer = new Announcer(); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/InfoScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/InfoScene.java new file mode 100644 index 000000000..a831e18ed --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/InfoScene.java @@ -0,0 +1,190 @@ +/* + * Copyright 2015 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.ui.scene; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.res.Resources; +import android.support.annotation.StringRes; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import com.hippo.ehviewer.R; +import com.hippo.ehviewer.client.data.GalleryDetail; +import com.hippo.ehviewer.util.EhUtils; +import com.hippo.rippleold.RippleSalon; +import com.hippo.scene.Announcer; +import com.hippo.scene.AppbarScene; +import com.hippo.util.UiUtils; +import com.hippo.widget.recyclerview.EasyRecyclerView; +import com.hippo.widget.recyclerview.LinearDividerItemDecoration; + +import java.util.ArrayList; +import java.util.List; + +public class InfoScene extends AppbarScene implements EasyRecyclerView.OnItemLongClickListener { + + private Resources mResources; + + private EasyRecyclerView mRecyclerView; + + private List mInfo = new ArrayList<>(); + + private int mRecyclerViewOriginalPaddingBottom; + + @Override + protected void onCreate(boolean rebirth) { + super.onCreate(rebirth); + + setContentView(R.layout.scene_info); + setTitle(R.string.info); + setIcon(R.drawable.ic_arrow_left_dark); + + Context context = getStageActivity(); + mResources = context.getResources(); + + EasyRecyclerView recyclerView = (EasyRecyclerView) findViewById(R.id.recycler_view); + InfoAdapter adapter = new InfoAdapter(); + recyclerView.setAdapter(adapter); + recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)); + LinearDividerItemDecoration decoration = new LinearDividerItemDecoration( + LinearDividerItemDecoration.VERTICAL, mResources.getColor(R.color.divider_light), + UiUtils.dp2pix(getStageActivity(), 1)); + decoration.setPadding(mResources.getDimensionPixelOffset(R.dimen.keyline_margin)); + recyclerView.addItemDecoration(decoration); + recyclerView.setSelector(RippleSalon.generateRippleDrawable(false)); + recyclerView.setClipToPadding(false); + recyclerView.setHasFixedSize(true); + recyclerView.setOnItemLongClickListener(this); + mRecyclerView = recyclerView; + mRecyclerViewOriginalPaddingBottom = recyclerView.getPaddingBottom(); + } + + @Override + protected void onBind() { + super.onBind(); + + handleAnnouncer(getAnnouncer()); + } + + @Override + protected void onGetFitPaddingBottom(int b) { + super.onGetFitPaddingBottom(b); + + View recyclerView = mRecyclerView; + recyclerView.setPadding( + recyclerView.getPaddingLeft(), + recyclerView.getPaddingTop(), + recyclerView.getPaddingRight(), + mRecyclerViewOriginalPaddingBottom + b); + } + + private void addData(@StringRes int key, String value) { + mInfo.add(new String[]{mResources.getString(key), value}); + } + + private void handleAnnouncer(Announcer announcer) { + if (announcer != null) { + GalleryDetail gd = (GalleryDetail) announcer.getObject(); + addData(R.string.header_key, mResources.getString(R.string.header_value)); + addData(R.string.key_gid, Integer.toString(gd.gid)); + addData(R.string.key_title, gd.title); + addData(R.string.key_title_jpn, gd.titleJpn); + addData(R.string.key_thumb, gd.thumb); + addData(R.string.key_category, EhUtils.getCategory(gd.category)); + addData(R.string.key_uploader, gd.uploader); + addData(R.string.key_posted, gd.posted); + addData(R.string.key_language, gd.language); + addData(R.string.key_pages, Integer.toString(gd.pageCount)); + addData(R.string.key_size, gd.size); + addData(R.string.key_resize, gd.resize); + addData(R.string.key_favorited, Integer.toString(gd.favoredTimes)); + addData(R.string.key_rated, Integer.toString(gd.ratedTimes)); + addData(R.string.key_rating, Float.toString(gd.rating)); + addData(R.string.key_torrents, Integer.toString(gd.torrentCount)); + } + } + + @Override + public void onIconClick() { + finish(); + } + + @Override + public boolean onItemLongClick(EasyRecyclerView parent, View view, int position, long id) { + if (position != 0) { + ClipboardManager cmb = (ClipboardManager) getStageActivity().getSystemService(Context.CLIPBOARD_SERVICE); + cmb.setPrimaryClip(ClipData.newPlainText(null, mInfo.get(position)[1])); + Toast.makeText(getStageActivity(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show(); + return true; + } else { + return false; + } + } + + private static class InfoHolder extends RecyclerView.ViewHolder { + + private TextView key; + private TextView value; + + public InfoHolder(View itemView) { + super(itemView); + + key = (TextView) itemView.findViewById(R.id.key); + value = (TextView) itemView.findViewById(R.id.value); + } + } + + private class InfoAdapter extends RecyclerView.Adapter { + + private static final int TYPE_HEADER = 0; + private static final int TYPE_DATA = 1; + + @Override + public int getItemViewType(int position) { + if (position == 0) { + return TYPE_HEADER; + } else { + return TYPE_DATA; + } + } + + @Override + public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) { + return new InfoHolder(getStageActivity().getLayoutInflater().inflate( + viewType == TYPE_HEADER ? R.layout.item_info_header : R.layout.item_info_data, parent, false)); + } + + @Override + public void onBindViewHolder(InfoHolder holder, int position) { + String[] strings = mInfo.get(position); + holder.key.setText(strings[0]); + holder.value.setText(strings[1]); + holder.itemView.setEnabled(position != 0); + } + + @Override + public int getItemCount() { + return mInfo.size(); + } + } +} diff --git a/app/src/main/java/com/hippo/widget/recyclerview/EasyRecyclerView.java b/app/src/main/java/com/hippo/widget/recyclerview/EasyRecyclerView.java index bfe6b544c..8ac50b576 100644 --- a/app/src/main/java/com/hippo/widget/recyclerview/EasyRecyclerView.java +++ b/app/src/main/java/com/hippo/widget/recyclerview/EasyRecyclerView.java @@ -263,16 +263,6 @@ public class EasyRecyclerView extends RecyclerView { DrawableUtils.setHotspot(selector, x, y); } } - - /* TODO handle enable - final boolean isChildViewEnabled = mIsChildViewEnabled; - if (sel.isEnabled() != isChildViewEnabled) { - mIsChildViewEnabled = !isChildViewEnabled; - if (getSelectedItemPosition() != INVALID_POSITION) { - refreshDrawableState(); - } - } - */ } @Override @@ -735,7 +725,7 @@ public class EasyRecyclerView extends RecyclerView { mMotionView = findChildViewUnder(x, y); mMotionPosition = getChildAdapterPosition(mMotionView); - if (mMotionView != null && mMotionPosition >= 0) { + if (mMotionView != null && mMotionPosition >= 0 && mMotionView.isEnabled()) { mHasPerformedLongPress = false; mPrePressed = true; diff --git a/app/src/main/res/layout-v21/scene_gallery_detail.xml b/app/src/main/res/layout-v21/scene_gallery_detail.xml index 089bf0011..f6490a7cd 100644 --- a/app/src/main/res/layout-v21/scene_gallery_detail.xml +++ b/app/src/main/res/layout-v21/scene_gallery_detail.xml @@ -36,84 +36,15 @@ android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingTop="280dp" + android:paddingTop="@dimen/gallery_detail_content_margin_top" android:orientation="vertical"> - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -254,11 +185,11 @@ diff --git a/app/src/main/res/layout/gallery_detail_info.xml b/app/src/main/res/layout/gallery_detail_info.xml new file mode 100644 index 000000000..e116fc979 --- /dev/null +++ b/app/src/main/res/layout/gallery_detail_info.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_info_data.xml b/app/src/main/res/layout/item_info_data.xml new file mode 100644 index 000000000..a1f092273 --- /dev/null +++ b/app/src/main/res/layout/item_info_data.xml @@ -0,0 +1,40 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/item_info_header.xml b/app/src/main/res/layout/item_info_header.xml new file mode 100644 index 000000000..de3f94d57 --- /dev/null +++ b/app/src/main/res/layout/item_info_header.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/scene_appbar.xml b/app/src/main/res/layout/scene_appbar.xml index c004ac296..8c848af48 100644 --- a/app/src/main/res/layout/scene_appbar.xml +++ b/app/src/main/res/layout/scene_appbar.xml @@ -29,7 +29,7 @@ android:id="@+id/appbar_icon" android:layout_width="@dimen/appbar_height" android:layout_height="@dimen/appbar_height" - android:padding="16dp" + android:padding="@dimen/appbar_icon_margin" android:visibility="gone"/> + + diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml index d492422a8..385077f65 100644 --- a/app/src/main/res/values-sw600dp/dimens.xml +++ b/app/src/main/res/values-sw600dp/dimens.xml @@ -23,6 +23,10 @@ 64dp + + 64dp + 20dp + 48dp diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index f6249ee22..7e1593cf1 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -15,6 +15,18 @@ --> + + 16dp + + + 24sp + 22sp + 20sp + 18sp + 16sp + 14sp + 12sp + 72dp 24dp @@ -26,8 +38,9 @@ 64dip 0dp - + 56dp + 16dp 24dp @@ -95,9 +108,6 @@ 48dp - - 16dp - 40dp @dimen/search_item_interval_half @@ -130,16 +140,15 @@ 20dp 2dp + + 128dp + 192dp + 40dp + 224dp + 248dp + 48dp + 96dp 128dp - - 24sp - 22sp - 20sp - 18sp - 16sp - 14sp - 12sp - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 06b3e74ff..ed2cfba6b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -87,6 +87,27 @@ No more comments More comments + + Copied to clipboard + Key + Value + Gid + Token + Title + Jpn Title + Thumb + Category + Uploader + Posted + Language + Pages + Size + Resize + Favorited + Rated + Rating + Torrents + a MASTERPIECE AMAZING @@ -152,5 +173,6 @@ Share Comments + Info