diff --git a/app/src/main/java/com/hippo/ehviewer/client/GalleryDetailParser.java b/app/src/main/java/com/hippo/ehviewer/client/GalleryDetailParser.java
index 3669aabb2..510a987ed 100644
--- a/app/src/main/java/com/hippo/ehviewer/client/GalleryDetailParser.java
+++ b/app/src/main/java/com/hippo/ehviewer/client/GalleryDetailParser.java
@@ -72,6 +72,10 @@ public class GalleryDetailParser {
public int previewPageCount;
private String sortOut(String str) {
+ // Avoid null
+ if (str == null) {
+ str = "";
+ }
return Utils.unescapeXml(str).trim();
}
@@ -137,7 +141,7 @@ public class GalleryDetailParser {
+ ".+?"
+ "
([\\d|,]+) | " // 18 ratedTimes
+ ""
- + "| ]*>Average: ([^<>]+) | " // 19 rating "Average: x.xx" or "Not Yet Rated"
+ + "
| ]*>([^<>]+) | " // 19 rating "Average: x.xx" or "Not Yet Rated"
+ ".+?"
+ "]*>(.+?)", Pattern.DOTALL); // 20 isFavored "Favorite Gallery" for favorite
m = p.matcher(body);
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 836377a37..66e7d6129 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
@@ -16,61 +16,236 @@
package com.hippo.ehviewer.ui.scene;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextSwitcher;
import android.widget.TextView;
+import android.widget.ViewSwitcher;
import com.hippo.conaco.Conaco;
+import com.hippo.effect.ViewTransition;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.EhImageKeyFactory;
import com.hippo.ehviewer.R;
+import com.hippo.ehviewer.client.EhClient;
+import com.hippo.ehviewer.data.GalleryDetail;
import com.hippo.ehviewer.data.GalleryInfo;
+import com.hippo.ehviewer.util.Config;
+import com.hippo.ehviewer.util.EhUtils;
import com.hippo.ehviewer.widget.LoadImageView;
+import com.hippo.ehviewer.widget.RatingView;
+import com.hippo.rippleold.RippleSalon;
+import com.hippo.scene.Announcer;
import com.hippo.scene.Scene;
+import com.hippo.util.Log;
-public class GalleryDetailScene extends Scene {
+public class GalleryDetailScene extends Scene implements View.OnClickListener {
public static final String KEY_GALLERY_INFO = "gallery_info";
- private LoadImageView mThumb;
- private TextView mTitle;
- private TextView mUploader;
+ private ViewGroup mHeader;
+ LoadImageView mThumb;
+ TextView mTitle;
+ TextView mUploader;
+ TextView mCategory;
+ private ViewGroup mActionCard;
+ private View mRead;
+ private View mDownload;
+
+ private ViewGroup mContent;
+ private TextView mLanguage;
+ private TextView mPages;
+ private TextView mSize;
+ private TextView mPosted;
+ private TextView mResize;
+ private TextView mFavoredTimes;
+ private TextSwitcher mRatingText;
+ private RatingView mRating;
+ private TextView mFavorite;
+ private TextView mTorrent;
+ private TextView mShare;
+ private TextView mRate;
+
+ private View mProgressBar;
+
+ private ViewTransition mViewTransition;
+
+ private void handleAnnouncer(Announcer announcer) {
+ GalleryInfo gi;
+
+ if (announcer == null) {
+ Log.e("No announcer in GalleryDetailScene, finish itself");
+ finish();
+ return;
+ } else if (null != (gi = announcer.getParcelableExtra(KEY_GALLERY_INFO))){
+ Conaco conaco = EhApplication.getConaco(getStageActivity());
+ conaco.load(mThumb, EhImageKeyFactory.getThumbKey(gi.gid), gi.thumb);
+ mTitle.setText(gi.title);
+ mUploader.setText(gi.uploader);
+ mCategory.setText(EhUtils.getCategory(gi.category));
+ mCategory.setTextColor(EhUtils.getCategoryColor(gi.category));
+
+ EhClient.getInstance().getGalleryDetail(Config.getEhSource(),
+ EhClient.getDetailUrl(Config.getEhSource(), gi.gid, gi.token, 0),
+ new EhDetailListener());
+ }
+
+ Context context = getStageActivity();
+ Resources resources = context.getResources();
+
+ mViewTransition.showView(1);
+
+ RippleSalon.addRipple(mRead, false);
+ RippleSalon.addRipple(mDownload, false);
+
+ mRead.setOnClickListener(this);
+ mDownload.setOnClickListener(this);
+
+ mRatingText.setFactory(new RatingTextViewFactory());
+
+ Drawable favoriteDrawable = resources.getDrawable(R.drawable.ic_heart_theme_primary);
+ Drawable torrentDrawable = resources.getDrawable(R.drawable.ic_water_pump_theme_primary);
+ Drawable shareDrawable = resources.getDrawable(R.drawable.ic_share_theme_primary);
+ Drawable rateDrawable = resources.getDrawable(R.drawable.ic_thumbs_up_down_theme_primary);
+
+ int drawableSize = resources.getDimensionPixelOffset(R.dimen.detail_action_size);
+ favoriteDrawable.setBounds(0, 0, drawableSize, drawableSize);
+ torrentDrawable.setBounds(0, 0, drawableSize, drawableSize);
+ shareDrawable.setBounds(0, 0, drawableSize, drawableSize);
+ rateDrawable.setBounds(0, 0, drawableSize, drawableSize);
+
+ mFavorite.setCompoundDrawables(null, favoriteDrawable, null, null);
+ mTorrent.setCompoundDrawables(null, torrentDrawable, null, null);
+ mShare.setCompoundDrawables(null, shareDrawable, null, null);
+ mRate.setCompoundDrawables(null, rateDrawable, null, null);
+ }
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scene_gallery_detail);
- GalleryInfo gi = getAnnouncer().getParcelableExtra(KEY_GALLERY_INFO);
+ mHeader = (ViewGroup) findViewById(R.id.header);
+ mThumb = (LoadImageView) mHeader.findViewById(R.id.thumb);
+ mTitle = (TextView) mHeader.findViewById(R.id.title);
+ mUploader = (TextView) mHeader.findViewById(R.id.uploader);
+ mCategory = (TextView) mHeader.findViewById(R.id.category);
- mThumb = (LoadImageView) findViewById(R.id.thumb);
- mThumb.bringToFront();
+ mActionCard = (ViewGroup) findViewById(R.id.action_card);
+ mRead = mActionCard.findViewById(R.id.read);
+ mDownload = mActionCard.findViewById(R.id.download);
- Conaco conaco = EhApplication.getConaco(getStageActivity());
- conaco.load(mThumb, EhImageKeyFactory.getThumbKey(gi.gid), gi.thumb);
+ 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);
+ mRatingText = (TextSwitcher) mContent.findViewById(R.id.rating_text);
+ mRating = (RatingView) mContent.findViewById(R.id.rating);
+ mFavorite = (TextView) mContent.findViewById(R.id.favorite);
+ mTorrent = (TextView) mContent.findViewById(R.id.torrent);
+ mShare = (TextView) mContent.findViewById(R.id.share);
+ mRate = (TextView) mContent.findViewById(R.id.rate);
- mTitle = (TextView) findViewById(R.id.title);
- mTitle.setText(gi.title);
+ mProgressBar = findViewById(R.id.progress_bar);
- mUploader = (TextView) findViewById(R.id.uploader);
- mUploader.setText(gi.uploader);
+ mViewTransition = new ViewTransition(mContent, mProgressBar);
+ handleAnnouncer(getAnnouncer());
+ }
+ @Override
+ public void onClick(View v) {
+ if (v == mRead) {
- /*
- int source = Config.getEhSource();
- EhClient.getInstance().getGalleryDetail(source, EhClient.getDetailUrl(source, gi.gid, gi.token, 0), new EhClient.OnGetGalleryDetailListener() {
- @Override
- public void onSuccess(GalleryDetail galleryDetail) {
- Log.d(galleryDetail.torrentUrl);
- }
+ } else if (v == mDownload) {
- @Override
- public void onFailure(Exception e) {
- Log.d("", e);
- }
- });
- */
+ }
+ }
+
+ private String getRatingText(float rating) {
+ String undefine = "(´_ゝ`)";
+ if (rating == Float.NaN) {
+ return undefine;
+ }
+
+ int resId = 0;
+ switch (Math.round(rating * 2)) {
+ case 0:
+ resId = R.string.rating0; break;
+ case 1:
+ resId = R.string.rating1; break;
+ case 2:
+ resId = R.string.rating2; break;
+ case 3:
+ resId = R.string.rating3; break;
+ case 4:
+ resId = R.string.rating4; break;
+ case 5:
+ resId = R.string.rating5; break;
+ case 6:
+ resId = R.string.rating6; break;
+ case 7:
+ resId = R.string.rating7; break;
+ case 8:
+ resId = R.string.rating8; break;
+ case 9:
+ resId = R.string.rating9; break;
+ case 10:
+ resId = R.string.rating10; break;
+ }
+
+ if (resId == 0) {
+ return undefine;
+ } else {
+ return getStageActivity().getString(resId);
+ }
+ }
+
+ private String getAllRatingText(float rating, int ratedTimes) {
+ return String.format(getStageActivity().getString(R.string.we_feel), getRatingText(rating)) +
+ " (" + rating + ", " + ratedTimes + ")";
+ }
+
+ private class RatingTextViewFactory implements ViewSwitcher.ViewFactory {
+ @Override
+ public View makeView() {
+ TextView tv = new TextView(getStageActivity());
+ tv.setGravity(Gravity.CENTER);
+ return tv;
+ }
+ }
+
+ private class EhDetailListener extends EhClient.OnGetGalleryDetailListener {
+
+ @Override
+ public void onSuccess(GalleryDetail galleryDetail) {
+ Resources resources = getStageActivity().getResources();
+ mLanguage.setText(galleryDetail.language);
+ mPages.setText(String.format(resources.getString(R.string.page_count),
+ galleryDetail.pageCount));
+ mSize.setText(galleryDetail.size);
+ mPosted.setText(galleryDetail.posted);
+ mResize.setText(galleryDetail.resize);
+ mFavoredTimes.setText(String.format(resources.getString(R.string.favorited_times),
+ galleryDetail.favoredTimes));
+ mRating.setRating(galleryDetail.rating);
+ mRatingText.setText(getAllRatingText(galleryDetail.rating, galleryDetail.ratedTimes));
+ mViewTransition.showView(0);
+ }
+
+ @Override
+ public void onFailure(Exception e) {
+ e.printStackTrace();
+ }
}
}
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 25c68cdf7..e76e39fcb 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
@@ -56,7 +56,7 @@ import com.hippo.ehviewer.util.EhUtils;
import com.hippo.ehviewer.widget.ContentLayout;
import com.hippo.ehviewer.widget.LoadImageView;
import com.hippo.ehviewer.widget.OffsetLayout;
-import com.hippo.ehviewer.widget.RatingView;
+import com.hippo.ehviewer.widget.SimpleRatingView;
import com.hippo.ehviewer.widget.SearchBar;
import com.hippo.ehviewer.widget.SearchDatabase;
import com.hippo.ehviewer.widget.SearchLayout;
@@ -757,25 +757,27 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper,
@Override
public View[] getFromViewSet(@NonNull Scene fromScene) {
- View[] views = new View[3];
+ View[] views = new View[4];
GalleryListScene scene = (GalleryListScene) fromScene;
RecyclerView.ViewHolder viewHolder = scene.mContentRecyclerView.findViewHolderForAdapterPosition(mPosition);
if (viewHolder != null) {
GalleryHolder gh = (GalleryHolder) viewHolder;
- views[0] = gh.thumb;
- views[1] = gh.title;
- views[2] = gh.uploader;
+ views[0] = gh.thumb;
+ views[1] = gh.title;
+ views[2] = gh.uploader;
+ views[3] = gh.category;
}
return views;
}
@Override
public View[] getToViewSet(@NonNull Scene toScene) {
- View[] views = new View[3];
- View sceneView = toScene.getSceneView();
- views[0] = sceneView.findViewById(R.id.thumb);
- views[1] = sceneView.findViewById(R.id.title);
- views[2] = sceneView.findViewById(R.id.uploader);
+ View[] views = new View[4];
+ GalleryDetailScene scene = (GalleryDetailScene) toScene;
+ views[0] = scene.mThumb;
+ views[1] = scene.mTitle;
+ views[2] = scene.mUploader;
+ views[3] = scene.mCategory;
return views;
}
}
@@ -820,7 +822,7 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper,
public LoadImageView thumb;
public TextView title;
public TextView uploader;
- public RatingView rating;
+ public SimpleRatingView rating;
public TextView category;
public TextView posted;
public TextView simpleLanguage;
@@ -830,7 +832,7 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper,
thumb = (LoadImageView) itemView.findViewById(R.id.thumb);
title = (TextView) itemView.findViewById(R.id.title);
uploader = (TextView) itemView.findViewById(R.id.uploader);
- rating = (RatingView) itemView.findViewById(R.id.rating);
+ rating = (SimpleRatingView) itemView.findViewById(R.id.rating);
category = (TextView) itemView.findViewById(R.id.category);
posted = (TextView) itemView.findViewById(R.id.posted);
simpleLanguage = (TextView) itemView.findViewById(R.id.simple_language);
diff --git a/app/src/main/java/com/hippo/ehviewer/widget/RatingView.java b/app/src/main/java/com/hippo/ehviewer/widget/RatingView.java
index 63b522b08..2ba380d85 100644
--- a/app/src/main/java/com/hippo/ehviewer/widget/RatingView.java
+++ b/app/src/main/java/com/hippo/ehviewer/widget/RatingView.java
@@ -1,95 +1,111 @@
-/*
- * Copyright (C) 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.widget;
import android.content.Context;
-import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
import android.util.AttributeSet;
+import android.view.MotionEvent;
import android.view.View;
import com.hippo.ehviewer.R;
+import com.hippo.util.ViewUtils;
public class RatingView extends View {
private Drawable mStarDrawable;
private Drawable mStarHalfDrawable;
- private int mRatingSize;
- private int mRatingInterval;
+ private Drawable mStarOutlineDrawable;
+ private float mStarSize;
+ private float mStarInterval;
+ private int mStarCount;
+ private boolean mIndicator;
+ private float mMax;
private float mRating;
- private int mRatingInt;
+
+ private int mShownStarCount;
+ private int mShownStarHalfCount;
+ private int mShownStarOutlineCount;
+
+ private OnRatingChangeListener mOnRatingChangeListener;
public RatingView(Context context) {
super(context);
- init(context);
+ init(context, null);
}
public RatingView(Context context, AttributeSet attrs) {
super(context, attrs);
- init(context);
+ init(context, attrs);
}
public RatingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- init(context);
+ init(context, attrs);
}
- private void init(Context context) {
- Resources resources = context.getResources();
- mStarDrawable = resources.getDrawable(R.drawable.ic_star);
- mStarHalfDrawable = resources.getDrawable(R.drawable.ic_star_half);
- mRatingSize = resources.getDimensionPixelOffset(R.dimen.rating_size);
- mRatingInterval = resources.getDimensionPixelOffset(R.dimen.rating_interval);
+ private void init(Context context, AttributeSet attrs) {
+ mStarDrawable = context.getResources().getDrawable(R.drawable.ic_star_theme_accent);
+ mStarHalfDrawable = context.getResources().getDrawable(R.drawable.ic_star_half_theme_accent);
+ mStarOutlineDrawable = context.getResources().getDrawable(R.drawable.ic_star_outline_theme_accent);
- mStarDrawable.setBounds(0, 0, mRatingSize, mRatingSize);
- mStarHalfDrawable.setBounds(0, 0, mRatingSize, mRatingSize);
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RatingView);
+ mStarSize = a.getDimension(R.styleable.RatingView_starSize, 10);
+ mStarInterval = a.getDimension(R.styleable.RatingView_starInterval, 10);
+ mStarCount = a.getInt(R.styleable.RatingView_starCount, 5);
+ mIndicator = a.getBoolean(R.styleable.RatingView_isIndicator, true);
+ mMax = a.getFloat(R.styleable.RatingView_max, 10f);
+ mRating = a.getFloat(R.styleable.RatingView_rating, 0f);
+
+ a.recycle();
+
+ updateBounds();
+ updateShownCount();
}
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- setMeasuredDimension(mRatingSize * 5 + mRatingInterval * 4, mRatingSize);
+ private void updateBounds() {
+ int starSize = (int) mStarSize;
+ mStarDrawable.setBounds(0, 0, starSize, starSize);
+ mStarHalfDrawable.setBounds(0, 0, starSize, starSize);
+ mStarOutlineDrawable.setBounds(0, 0, starSize, starSize);
}
- @Override
- protected void onDraw(Canvas canvas) {
- int ratingInt = mRatingInt;
- int step = mRatingSize + mRatingInterval;
- int numStar = ratingInt / 2;
- int numStarHalf = ratingInt % 2;
- int saved = canvas.save();
- while (numStar-- > 0) {
- mStarDrawable.draw(canvas);
- canvas.translate(step, 0);
+ private void updateShownCount() {
+ float step = mMax / mStarCount / 2;
+ int shown = Math.round(mRating / step);
+ if (shown >= mStarCount * 2) {
+ mShownStarCount = mStarCount;
+ mShownStarHalfCount = 0;
+ mShownStarOutlineCount = 0;
+ } else {
+ mShownStarCount = shown / 2;
+ mShownStarHalfCount = shown % 2;
+ mShownStarOutlineCount = mStarCount - mShownStarCount - mShownStarHalfCount;
}
- if (numStarHalf == 1) {
- mStarHalfDrawable.draw(canvas);
- }
- canvas.restoreToCount(saved);
+ }
+
+ public void setOnRatingChangeListener(OnRatingChangeListener listener) {
+ mOnRatingChangeListener = listener;
+ }
+
+ public void setIndicator(boolean indicator) {
+ mIndicator = indicator;
+ }
+
+ public boolean isIndicator() {
+ return mIndicator;
}
public void setRating(float rating) {
if (mRating != rating) {
+ float oldRating = mRating;
mRating = rating;
- int ratingInt = Math.round(rating * 2);
- if (mRatingInt != ratingInt) {
- mRatingInt = ratingInt;
- invalidate();
+ updateShownCount();
+ invalidate();
+ if (mOnRatingChangeListener != null) {
+ mOnRatingChangeListener.onRatingChange(oldRating, rating, false, true);
}
}
}
@@ -97,4 +113,93 @@ public class RatingView extends View {
public float getRating() {
return mRating;
}
+
+ @Override
+ protected int getSuggestedMinimumWidth() {
+ return Math.max(super.getSuggestedMinimumWidth(),
+ (int) ((mStarSize * mStarCount) + (mStarInterval * (mStarCount - 1))));
+ }
+
+ @Override
+ protected int getSuggestedMinimumHeight() {
+ return Math.max(super.getSuggestedMinimumHeight(), (int) mStarSize);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(ViewUtils.getSuitableSize(getSuggestedMinimumWidth(), widthMeasureSpec),
+ ViewUtils.getSuitableSize(getSuggestedMinimumHeight(), heightMeasureSpec));
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ int saved = canvas.save();
+
+ float moveStep = mStarSize + mStarInterval;
+ int count = mShownStarCount;
+ while (count-- > 0) {
+ mStarDrawable.draw(canvas);
+ canvas.translate(moveStep, 0);
+ }
+ count = mShownStarHalfCount;
+ while (count-- > 0) {
+ mStarHalfDrawable.draw(canvas);
+ canvas.translate(moveStep, 0);
+ }
+ count = mShownStarOutlineCount;
+ while (count-- > 0) {
+ mStarOutlineDrawable.draw(canvas);
+ canvas.translate(moveStep, 0);
+ }
+
+ canvas.restoreToCount(saved);
+ }
+
+ private float getRatingByX(float x) {
+ float step = mStarSize + mStarInterval;
+ float sum = x + mStarInterval;
+ float ratingStep = mMax / mStarCount / 2;
+ int count = (int) (sum / step) * 2;
+ float remain = sum - (count / 2 * step);
+ if (remain > mStarInterval + (mStarSize / 2)) {
+ count += 2;
+ } else if (remain > mStarInterval) {
+ count += 1;
+ }
+ count = Math.min(mStarCount * 2, count);
+ return ratingStep * count;
+ }
+
+ @Override
+ public boolean onTouchEvent(@NonNull MotionEvent event) {
+ if (!mIndicator) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_MOVE:
+ float rating = getRatingByX(event.getX());
+ if (mRating != rating) {
+ float oldRating = mRating;
+ mRating = rating;
+ updateShownCount();
+ invalidate();
+ if (mOnRatingChangeListener != null) {
+ mOnRatingChangeListener.onRatingChange(oldRating, rating, true, false);
+ }
+ }
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ if (mOnRatingChangeListener != null) {
+ mOnRatingChangeListener.onRatingChange(mRating, mRating, true, true);
+ }
+ break;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public interface OnRatingChangeListener {
+ void onRatingChange(float oldRating, float newRating, boolean byUser, boolean confirm);
+ }
}
diff --git a/app/src/main/java/com/hippo/ehviewer/widget/SimpleRatingView.java b/app/src/main/java/com/hippo/ehviewer/widget/SimpleRatingView.java
new file mode 100644
index 000000000..a5423e4cd
--- /dev/null
+++ b/app/src/main/java/com/hippo/ehviewer/widget/SimpleRatingView.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 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.widget;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.hippo.ehviewer.R;
+
+public class SimpleRatingView extends View {
+
+ private Drawable mStarDrawable;
+ private Drawable mStarHalfDrawable;
+ private Drawable mStarOutlineDrawable;
+ private int mRatingSize;
+ private int mRatingInterval;
+
+ private float mRating;
+ private int mRatingInt;
+
+ public SimpleRatingView(Context context) {
+ super(context);
+ init(context);
+ }
+
+ public SimpleRatingView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public SimpleRatingView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ private void init(Context context) {
+ Resources resources = context.getResources();
+ mStarDrawable = resources.getDrawable(R.drawable.ic_star);
+ mStarHalfDrawable = resources.getDrawable(R.drawable.ic_star_half);
+ mStarOutlineDrawable = resources.getDrawable(R.drawable.ic_star_outline);
+ mRatingSize = resources.getDimensionPixelOffset(R.dimen.rating_size);
+ mRatingInterval = resources.getDimensionPixelOffset(R.dimen.rating_interval);
+
+ mStarDrawable.setBounds(0, 0, mRatingSize, mRatingSize);
+ mStarHalfDrawable.setBounds(0, 0, mRatingSize, mRatingSize);
+ mStarOutlineDrawable.setBounds(0, 0, mRatingSize, mRatingSize);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(mRatingSize * 5 + mRatingInterval * 4, mRatingSize);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ int ratingInt = mRatingInt;
+ int step = mRatingSize + mRatingInterval;
+ int numStar = ratingInt / 2;
+ int numStarHalf = ratingInt % 2;
+ int saved = canvas.save();
+ while (numStar-- > 0) {
+ mStarDrawable.draw(canvas);
+ canvas.translate(step, 0);
+ }
+ if (numStarHalf == 1) {
+ mStarHalfDrawable.draw(canvas);
+ canvas.translate(step, 0);
+ }
+ int numOutline = 5 - numStar - numStarHalf;
+ while (numOutline-- > 0) {
+ mStarOutlineDrawable.draw(canvas);
+ canvas.translate(step, 0);
+ }
+ canvas.restoreToCount(saved);
+ }
+
+ public void setRating(float rating) {
+ if (mRating != rating) {
+ mRating = rating;
+ int ratingInt = Math.round(rating * 2);
+ if (mRatingInt != ratingInt) {
+ mRatingInt = ratingInt;
+ invalidate();
+ }
+ }
+ }
+
+ public float getRating() {
+ return mRating;
+ }
+}
diff --git a/app/src/main/java/com/hippo/util/Utils.java b/app/src/main/java/com/hippo/util/Utils.java
index 36f5415a5..0033e3586 100644
--- a/app/src/main/java/com/hippo/util/Utils.java
+++ b/app/src/main/java/com/hippo/util/Utils.java
@@ -274,21 +274,23 @@ public final class Utils {
}
private static final String[] ESCAPE_CHARATER_LIST = {
- "&",
- "<",
- ">",
- """,
- "'",
- "×"
+ "&",
+ "<",
+ ">",
+ """,
+ "'",
+ "×",
+ " "
};
private static final String[] UNESCAPE_CHARATER_LIST = {
- "&",
- "<",
- ">",
- "\"",
- "'",
- "×"
+ "&",
+ "<",
+ ">",
+ "\"",
+ "'",
+ "×",
+ " "
};
/**
diff --git a/app/src/main/java/com/hippo/widget/CardButton.java b/app/src/main/java/com/hippo/widget/CardButton.java
new file mode 100644
index 000000000..7e8b87c91
--- /dev/null
+++ b/app/src/main/java/com/hippo/widget/CardButton.java
@@ -0,0 +1,106 @@
+package com.hippo.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.Button;
+
+import com.hippo.cardsalon.CardHelper;
+import com.hippo.cardsalon.CardViewDelegate;
+
+public class CardButton extends Button implements CardViewDelegate {
+
+ private CardHelper mCardHelper;
+
+ public CardButton(Context context) {
+ super(context);
+ init(context, null);
+ }
+
+ public CardButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ public CardButton(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context, attrs);
+ }
+
+ private void init(Context context, AttributeSet attrs) {
+ mCardHelper = new CardHelper(this);
+ mCardHelper.initialize(context, attrs);
+ }
+
+ @Override
+ public void setBackgroundResource(int resid) {
+ // Empty
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setBackgroundDrawable(Drawable drawable) {
+ // Empty
+ }
+
+ @Override
+ public void setRawPadding(int left, int top, int right, int bottom) {
+ super.setPadding(left, top, right, bottom);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setRawBackgroundDrawable(Drawable drawable) {
+ super.setBackgroundDrawable(drawable);
+ }
+
+ @Override
+ public void setCardRadius(float radius) {
+ mCardHelper.setCardRadius(radius);
+ }
+
+ @Override
+ public float getCardRadius() {
+ return mCardHelper.getCardRadius();
+ }
+
+ @Override
+ public void setCardBackgroundColor(int color) {
+ mCardHelper.setCardBackgroundColor(color);
+ }
+
+ @Override
+ public int getCardBackgroundColor() {
+ return mCardHelper.getCardBackgroundColor();
+ }
+
+ @Override
+ public void setCardBoundSize(float size) {
+ mCardHelper.setCardBoundSize(size);
+ }
+
+ @Override
+ public float getCardBoundSize() {
+ return mCardHelper.getCardBoundSize();
+ }
+
+ @Override
+ public void setCardBoundColor(int color) {
+ mCardHelper.setCardBoundColor(color);
+ }
+
+ @Override
+ public int getCardBoundColor() {
+ return mCardHelper.getCardBoundColor();
+ }
+
+ @Override
+ public void setCardElevation(float elevation) {
+ mCardHelper.setCardElevation(elevation);
+ }
+
+ @Override
+ public float getCardElevation() {
+ return mCardHelper.getCardElevation();
+ }
+}
diff --git a/app/src/main/java/com/hippo/widget/CardLinearLayout.java b/app/src/main/java/com/hippo/widget/CardLinearLayout.java
new file mode 100644
index 000000000..93978f29e
--- /dev/null
+++ b/app/src/main/java/com/hippo/widget/CardLinearLayout.java
@@ -0,0 +1,111 @@
+package com.hippo.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+import com.hippo.cardsalon.CardHelper;
+import com.hippo.cardsalon.CardViewDelegate;
+
+public class CardLinearLayout extends LinearLayout implements CardViewDelegate {
+
+ private CardHelper mCardHelper;
+
+ public CardLinearLayout(Context context) {
+ super(context);
+ init(context, null);
+ }
+
+ public CardLinearLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ public CardLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context, attrs);
+ }
+
+ private void init(Context context, AttributeSet attrs) {
+ mCardHelper = new CardHelper(this);
+ mCardHelper.initialize(context, attrs);
+ }
+
+ @Override
+ public void setBackgroundResource(int resid) {
+ // Empty
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setBackgroundDrawable(Drawable drawable) {
+ // Empty
+ }
+
+ @Override
+ public void setPadding(int left, int top, int right, int bottom) {
+ mCardHelper.setPadding(left, top, right, bottom);
+ }
+
+ @Override
+ public void setRawPadding(int left, int top, int right, int bottom) {
+ super.setPadding(left, top, right, bottom);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setRawBackgroundDrawable(Drawable drawable) {
+ super.setBackgroundDrawable(drawable);
+ }
+
+ @Override
+ public void setCardRadius(float radius) {
+ mCardHelper.setCardRadius(radius);
+ }
+
+ @Override
+ public float getCardRadius() {
+ return mCardHelper.getCardRadius();
+ }
+
+ @Override
+ public void setCardBackgroundColor(int color) {
+ mCardHelper.setCardBackgroundColor(color);
+ }
+
+ @Override
+ public int getCardBackgroundColor() {
+ return mCardHelper.getCardBackgroundColor();
+ }
+
+ @Override
+ public void setCardBoundSize(float size) {
+ mCardHelper.setCardBoundSize(size);
+ }
+
+ @Override
+ public float getCardBoundSize() {
+ return mCardHelper.getCardBoundSize();
+ }
+
+ @Override
+ public void setCardBoundColor(int color) {
+ mCardHelper.setCardBoundColor(color);
+ }
+
+ @Override
+ public int getCardBoundColor() {
+ return mCardHelper.getCardBoundColor();
+ }
+
+ @Override
+ public void setCardElevation(float elevation) {
+ mCardHelper.setCardElevation(elevation);
+ }
+
+ @Override
+ public float getCardElevation() {
+ return mCardHelper.getCardElevation();
+ }
+}
diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml
new file mode 100644
index 000000000..d9353fdd4
--- /dev/null
+++ b/app/src/main/res/anim/fade_in.xml
@@ -0,0 +1,20 @@
+
+
+
diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml
new file mode 100644
index 000000000..fe4132b74
--- /dev/null
+++ b/app/src/main/res/anim/fade_out.xml
@@ -0,0 +1,20 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_heart_theme_primary.xml b/app/src/main/res/drawable/ic_heart_theme_primary.xml
new file mode 100644
index 000000000..8c6b800a3
--- /dev/null
+++ b/app/src/main/res/drawable/ic_heart_theme_primary.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_share_theme_primary.xml b/app/src/main/res/drawable/ic_share_theme_primary.xml
new file mode 100644
index 000000000..3f0084620
--- /dev/null
+++ b/app/src/main/res/drawable/ic_share_theme_primary.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_star.xml b/app/src/main/res/drawable/ic_star.xml
index 08d5731bd..20ccfbfe3 100644
--- a/app/src/main/res/drawable/ic_star.xml
+++ b/app/src/main/res/drawable/ic_star.xml
@@ -1,5 +1,4 @@
-
-
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_star_outline.xml b/app/src/main/res/drawable/ic_star_outline.xml
new file mode 100644
index 000000000..bbc03d9c4
--- /dev/null
+++ b/app/src/main/res/drawable/ic_star_outline.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_star_outline_theme_accent.xml b/app/src/main/res/drawable/ic_star_outline_theme_accent.xml
new file mode 100644
index 000000000..6b1f06246
--- /dev/null
+++ b/app/src/main/res/drawable/ic_star_outline_theme_accent.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_star_theme_accent.xml b/app/src/main/res/drawable/ic_star_theme_accent.xml
new file mode 100644
index 000000000..98529e229
--- /dev/null
+++ b/app/src/main/res/drawable/ic_star_theme_accent.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_thumbs_up_down_theme_primary.xml b/app/src/main/res/drawable/ic_thumbs_up_down_theme_primary.xml
new file mode 100644
index 000000000..fda917a3d
--- /dev/null
+++ b/app/src/main/res/drawable/ic_thumbs_up_down_theme_primary.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_water_pump_theme_primary.xml b/app/src/main/res/drawable/ic_water_pump_theme_primary.xml
new file mode 100644
index 000000000..fba2a1179
--- /dev/null
+++ b/app/src/main/res/drawable/ic_water_pump_theme_primary.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout-land/widget_select_search_image_layout.xml b/app/src/main/res/layout-land/widget_select_search_image_layout.xml
index 33f5e30ac..f377868b1 100644
--- a/app/src/main/res/layout-land/widget_select_search_image_layout.xml
+++ b/app/src/main/res/layout-land/widget_select_search_image_layout.xml
@@ -25,7 +25,7 @@
diff --git a/app/src/main/res/layout-sw600dp/widget_select_search_image_layout.xml b/app/src/main/res/layout-sw600dp/widget_select_search_image_layout.xml
index 33f5e30ac..f377868b1 100644
--- a/app/src/main/res/layout-sw600dp/widget_select_search_image_layout.xml
+++ b/app/src/main/res/layout-sw600dp/widget_select_search_image_layout.xml
@@ -25,7 +25,7 @@
-
-
-
-
-
-
-
-
+ android:layout_height="match_parent">
+ android:layout_height="wrap_content">
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:layout_height="wrap_content"
+ android:background="@color/theme_primary"
+ android:elevation="4dp">
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
diff --git a/app/src/main/res/layout/item_gallery_list_detail.xml b/app/src/main/res/layout/item_gallery_list_detail.xml
index 971acd442..a26cc6c0f 100644
--- a/app/src/main/res/layout/item_gallery_list_detail.xml
+++ b/app/src/main/res/layout/item_gallery_list_detail.xml
@@ -52,7 +52,7 @@
android:layout_marginTop="2dp"
tools:ignore="RtlHardcoded"/>
-
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index ec3286238..8066bcb69 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -52,6 +52,7 @@
#fff06292
@android:color/black
+ #ffe91e63
#ff009688
#ff00796b
#ffff5722
@@ -62,6 +63,8 @@
#ff7cb342
#fff9a825
#ffff7043
+ #ff3f51b5
+ #ff303f9f
#de000000
@@ -74,9 +77,9 @@
#ffeeeeee
#ffe1e1e0
- #ff3367d6
- #ff2451b2
- #ffd63367
+ @color/material_indigo_500
+ @color/material_indigo_700
+ @color/material_pink_500
@android:color/white
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 57231265e..cc661e167 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -93,6 +93,8 @@
8dp
+ 48dp
+
16dp
diff --git a/app/src/main/res/values/pathdata.xml b/app/src/main/res/values/pathdata.xml
index 43621cc1f..3ffa905fe 100644
--- a/app/src/main/res/values/pathdata.xml
+++ b/app/src/main/res/values/pathdata.xml
@@ -23,6 +23,7 @@
M10.5,7A6.5,6.5 0 0,0 4,13.5A6.5,6.5 0 0,0 10.5,20H14V18H10.5C8,18 6,16 6,13.5C6,11 8,9 10.5,9H16.17L13.09,12.09L14.5,13.5L20,8L14.5,2.5L13.08,3.91L16.17,7H10.5M18,18H16V20H18V18Z
M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z
M12,15.89V6.59L13.71,10.63L18.09,11L14.77,13.88L15.76,18.16M22,9.74L14.81,9.13L12,2.5L9.19,9.13L2,9.74L7.45,14.47L5.82,21.5L12,17.77L18.18,21.5L16.54,14.47L22,9.74Z
+ M12,15.39L8.24,17.66L9.23,13.38L5.91,10.5L10.29,10.13L12,6.09L13.71,10.13L18.09,10.5L14.77,13.38L15.76,17.66M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z
M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z
M11.71,19C9.93,19 8.5,17.59 8.5,15.86C8.5,14.24 9.53,13.1 11.3,12.74C13.07,12.38 14.9,11.53 15.92,10.16C16.31,11.45 16.5,12.81 16.5,14.2C16.5,16.84 14.36,19 11.71,19M13.5,0.67C13.5,0.67 14.24,3.32 14.24,5.47C14.24,7.53 12.89,9.2 10.83,9.2C8.76,9.2 7.2,7.53 7.2,5.47L7.23,5.1C5.21,7.5 4,10.61 4,14A8,8 0 0,0 12,22A8,8 0 0,0 20,14C20,8.6 17.41,3.8 13.5,0.67Z
M11,7V12.11L15.71,14.9L16.5,13.62L12.5,11.25V7M12.5,2C8.97,2 5.91,3.92 4.27,6.77L2,4.5V11H8.5L5.75,8.25C6.96,5.73 9.5,4 12.5,4A7.5,7.5 0 0,1 20,11.5A7.5,7.5 0 0,1 12.5,19C9.23,19 6.47,16.91 5.44,14H3.34C4.44,18.03 8.11,21 12.5,21C17.74,21 22,16.75 22,11.5A9.5,9.5 0 0,0 12.5,2Z
@@ -34,5 +35,8 @@
M3 10v-5a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v5l-6 2l-6 -4l-6 2M3 14v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2 -2v-5l-6 2l-6 -4l-6 2z
M10,2A2,2 0 0,1 12,4V8.5C12,8.5 14,8.25 14,9.25C14,9.25 16,9 16,10C16,10 18,9.75 18,10.75C18,10.75 20,10.5 20,11.5V15C20,16 17,21 17,22H9C9,22 7,15 4,13C4,13 3,7 8,12V4A2,2 0 0,1 10,2Z
M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12C4,14.39 5.05,16.53 6.71,18H9V12H17L19.15,15.59C19.69,14.5 20,13.29 20,12A8,8 0 0,0 12,4Z
+ M19,14.5C19,14.5 21,16.67 21,18A2,2 0 0,1 19,20A2,2 0 0,1 17,18C17,16.67 19,14.5 19,14.5M5,18V9A2,2 0 0,1 3,7A2,2 0 0,1 5,5V4A2,2 0 0,1 7,2H9A2,2 0 0,1 11,4V5H19A2,2 0 0,1 21,7V9L21,11A1,1 0 0,1 22,12A1,1 0 0,1 21,13H17A1,1 0 0,1 16,12A1,1 0 0,1 17,11V9H11V18H12A2,2 0 0,1 14,20V22H2V20A2,2 0 0,1 4,18H5Z
+ M18,16.08C17.24,16.08 16.56,16.38 16.04,16.85L8.91,12.7C8.96,12.47 9,12.24 9,12C9,11.76 8.96,11.53 8.91,11.3L15.96,7.19C16.5,7.69 17.21,8 18,8A3,3 0 0,0 21,5A3,3 0 0,0 18,2A3,3 0 0,0 15,5C15,5.24 15.04,5.47 15.09,5.7L8.04,9.81C7.5,9.31 6.79,9 6,9A3,3 0 0,0 3,12A3,3 0 0,0 6,15C6.79,15 7.5,14.69 8.04,14.19L15.16,18.34C15.11,18.55 15.08,18.77 15.08,19C15.08,20.61 16.39,21.91 18,21.91C19.61,21.91 20.92,20.61 20.92,19A2.92,2.92 0 0,0 18,16.08Z
+ M22.5,10.5H15.75C15.13,10.5 14.6,10.88 14.37,11.41L12.11,16.7C12.04,16.87 12,17.06 12,17.25V18.5A1,1 0 0,0 13,19.5H18.18L17.5,22.68V22.92C17.5,23.23 17.63,23.5 17.83,23.72L18.62,24.5L23.56,19.56C23.83,19.29 24,18.91 24,18.5V12A1.5,1.5 0 0,0 22.5,10.5M12,6.5A1,1 0 0,0 11,5.5H5.82L6.5,2.32V2.09C6.5,1.78 6.37,1.5 6.17,1.29L5.38,0.5L0.44,5.44C0.17,5.71 0,6.09 0,6.5V13A1.5,1.5 0 0,0 1.5,14.5H8.25C8.87,14.5 9.4,14.12 9.63,13.59L11.89,8.3C11.96,8.13 12,7.94 12,7.75V6.5Z
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index cfd2d43ac..a575cfd44 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -77,6 +77,24 @@
Please enter a number
The page is invaild
+
+ %d pages
+ %d \u2665
+ We feel %s
+
+
+ MASTERPIECE
+ AMAZING
+ GREAT
+ GOOD
+ OKAY
+ MEDIOCRE
+ BAD
+ AWFUL
+ PAINFUL
+ UNBEARABLE
+ DISASTER
+
Timeout
Unknown host
@@ -122,4 +140,8 @@
Username
Password
+ Read
+ Torrent
+ Share
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 2bffea35b..38c16a911 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -62,7 +62,7 @@
- @dimen/category_table_item_height
-
+
+
+
+
+
+