diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Result.java b/app/src/main/java/com/fongmi/android/tv/bean/Result.java index 254dfbbf2..b544791ff 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Result.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Result.java @@ -64,7 +64,7 @@ public class Result implements Parcelable { private String format; @SerializedName("url") @JsonAdapter(UrlAdapter.class) - private String url; + private Url url; @SerializedName("key") private String key; @SerializedName("subs") @@ -207,11 +207,11 @@ public class Result implements Parcelable { this.flag = flag; } - public String getUrl() { - return TextUtils.isEmpty(url) ? "" : url; + public Url getUrl() { + return url == null ? new Url() : url; } - public void setUrl(String url) { + public void setUrl(Url url) { this.url = url; } @@ -248,7 +248,7 @@ public class Result implements Parcelable { } public String getRealUrl() { - return getPlayUrl() + getUrl(); + return getPlayUrl() + getUrl().v(); } public Map getHeaders() { @@ -290,8 +290,8 @@ public class Result implements Parcelable { this.types = new ArrayList<>(); in.readList(this.types, Class.class.getClassLoader()); this.list = in.createTypedArrayList(Vod.CREATOR); - Type type = new TypeToken>>() {}.getType(); - this.filters = App.gson().fromJson(in.readString(), type); + Type listType = new TypeToken>>() {}.getType(); + this.filters = App.gson().fromJson(in.readString(), listType); } public static final Creator CREATOR = new Creator<>() { diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Url.java b/app/src/main/java/com/fongmi/android/tv/bean/Url.java new file mode 100644 index 000000000..e6c5d119e --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/bean/Url.java @@ -0,0 +1,49 @@ +package com.fongmi.android.tv.bean; + +import android.text.TextUtils; + +import java.util.ArrayList; +import java.util.List; + +public class Url { + + private List values; + private int position; + + public List getValues() { + return values = values == null ? new ArrayList<>() : values; + } + + public int getPosition() { + return position; + } + + public String v() { + return v(getPosition()); + } + + public String n() { + return n(getPosition()); + } + + public String v(int position) { + return position >= getValues().size() ? "" : getValues().get(position).getV(); + } + + public String n(int position) { + return position >= getValues().size() ? "" : getValues().get(position).getN(); + } + + public Url set(int position) { + this.position = Math.min(position, getValues().size() - 1); + return this; + } + + public boolean isEmpty() { + return getValues().isEmpty() || TextUtils.isEmpty(v()); + } + + public boolean isOnly() { + return getValues().size() == 1; + } +} diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Value.java b/app/src/main/java/com/fongmi/android/tv/bean/Value.java index c9e35a1be..8b108cee9 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Value.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Value.java @@ -19,6 +19,11 @@ public class Value implements Parcelable { public Value() { } + public Value(String n, String v) { + this.n = Trans.s2t(n); + this.v = v; + } + public String getN() { return TextUtils.isEmpty(n) ? "" : n; } diff --git a/app/src/main/java/com/fongmi/android/tv/player/ParseJob.java b/app/src/main/java/com/fongmi/android/tv/player/ParseJob.java index 2800ae76c..36132f9ca 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/ParseJob.java +++ b/app/src/main/java/com/fongmi/android/tv/player/ParseJob.java @@ -70,7 +70,7 @@ public class ParseJob implements ParseCallback { private Runnable getTask(Result result) { return () -> { try { - doInBackground(result.getKey(), result.getUrl(), result.getFlag()); + doInBackground(result.getKey(), result.getUrl().v(), result.getFlag()); } catch (Throwable e) { onParseError(); } @@ -148,8 +148,8 @@ public class ParseJob implements ParseCallback { private void checkResult(Result result) { if (result.getUrl().isEmpty()) onParseError(); - else if (result.getParse() == 1) startWeb(result.getHeaders(), Utils.convert(result.getUrl())); - else onParseSuccess(result.getHeaders(), result.getUrl(), result.getJxFrom()); + else if (result.getParse() == 1) startWeb(result.getHeaders(), Utils.convert(result.getUrl().v())); + else onParseSuccess(result.getHeaders(), result.getUrl().v(), result.getJxFrom()); } private boolean isPass(Map headers, String url) { diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/DetailActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/DetailActivity.java index 2d404edf0..35732be1e 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/DetailActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/DetailActivity.java @@ -64,6 +64,7 @@ import com.fongmi.android.tv.ui.adapter.EpisodeAdapter; import com.fongmi.android.tv.ui.adapter.FlagAdapter; import com.fongmi.android.tv.ui.adapter.ParseAdapter; import com.fongmi.android.tv.ui.adapter.QuickAdapter; +import com.fongmi.android.tv.ui.adapter.UrlAdapter; import com.fongmi.android.tv.ui.base.BaseActivity; import com.fongmi.android.tv.ui.base.ViewType; import com.fongmi.android.tv.ui.custom.CustomKeyDownVod; @@ -98,7 +99,7 @@ import java.util.concurrent.Executors; import tv.danmaku.ijk.media.player.ui.IjkVideoView; -public class DetailActivity extends BaseActivity implements Clock.Callback, CustomKeyDownVod.Listener, CastDialog.Listener, PiPReceiver.Listener, TrackDialog.Listener, ControlDialog.Listener, FlagAdapter.OnClickListener, EpisodeAdapter.OnClickListener, ParseAdapter.OnClickListener { +public class DetailActivity extends BaseActivity implements Clock.Callback, CustomKeyDownVod.Listener, CastDialog.Listener, PiPReceiver.Listener, TrackDialog.Listener, ControlDialog.Listener, FlagAdapter.OnClickListener, EpisodeAdapter.OnClickListener, UrlAdapter.OnClickListener, QuickAdapter.OnClickListener, ParseAdapter.OnClickListener { private ViewGroup.LayoutParams mFrameParams; private Observer mObserveDetail; @@ -113,6 +114,7 @@ public class DetailActivity extends BaseActivity implements Clock.Callback, Cust private ExecutorService mExecutor; private SiteViewModel mViewModel; private FlagAdapter mFlagAdapter; + private UrlAdapter mUrlAdapter; private PiPReceiver mReceiver; private List mDialogs; private List mBroken; @@ -313,15 +315,19 @@ public class DetailActivity extends BaseActivity implements Clock.Callback, Cust } private void setRecyclerView() { + mBinding.url.setHasFixedSize(true); + mBinding.url.setItemAnimator(null); + mBinding.url.addItemDecoration(new SpaceItemDecoration(8)); + mBinding.url.setAdapter(mUrlAdapter = new UrlAdapter(this)); mBinding.flag.setHasFixedSize(true); mBinding.flag.setItemAnimator(null); mBinding.flag.addItemDecoration(new SpaceItemDecoration(8)); mBinding.flag.setAdapter(mFlagAdapter = new FlagAdapter(this)); + mBinding.quick.setAdapter(mQuickAdapter = new QuickAdapter(this)); mBinding.episode.setHasFixedSize(true); mBinding.episode.setItemAnimator(null); mBinding.episode.addItemDecoration(new SpaceItemDecoration(8)); mBinding.episode.setAdapter(mEpisodeAdapter = new EpisodeAdapter(this, ViewType.LIST)); - mBinding.quick.setAdapter(mQuickAdapter = new QuickAdapter(this::setSearch)); mBinding.control.parse.setHasFixedSize(true); mBinding.control.parse.setItemAnimator(null); mBinding.control.parse.addItemDecoration(new SpaceItemDecoration(8)); @@ -458,12 +464,14 @@ public class DetailActivity extends BaseActivity implements Clock.Callback, Cust } private void setPlayer(Result result) { + result.getUrl().set(mUrlAdapter.getPosition()); setUseParse(ApiConfig.hasParse() && ((result.getPlayUrl().isEmpty() && ApiConfig.get().getFlags().contains(result.getFlag())) || result.getJx() == 1)); if (mControlDialog != null && mControlDialog.isVisible()) mControlDialog.setParseVisible(isUseParse()); mBinding.control.parse.setVisibility(isFullscreen() && isUseParse() ? View.VISIBLE : View.GONE); - int timeout = getSite().isChangeable() ? getSite().getTimeout() : -1; - mPlayers.start(result, isUseParse(), timeout); + mPlayers.start(result, isUseParse(), getSite().isChangeable() ? getSite().getTimeout() : -1); + mBinding.url.setVisibility(result.getUrl().isOnly() ? View.GONE : View.VISIBLE); mBinding.swipeLayout.setRefreshing(false); + mUrlAdapter.addAll(result); } @Override @@ -484,6 +492,17 @@ public class DetailActivity extends BaseActivity implements Clock.Callback, Cust onRefresh(); } + @Override + public void onItemClick(Result result) { + mPlayers.start(result, isUseParse(), getSite().isChangeable() ? getSite().getTimeout() : -1); + } + + @Override + public void onItemClick(Vod item) { + setAutoMode(false); + getDetail(item); + } + @Override public void onItemClick(Parse item) { setParse(item); @@ -1131,11 +1150,6 @@ public class DetailActivity extends BaseActivity implements Clock.Callback, Cust App.removeCallbacks(mR4); } - private void setSearch(Vod item) { - setAutoMode(false); - getDetail(item); - } - private boolean mismatch(Vod item) { String keyword = mBinding.name.getText().toString(); if (mBroken.contains(item.getVodId())) return true; diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/UrlAdapter.java b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/UrlAdapter.java new file mode 100644 index 000000000..5d2207296 --- /dev/null +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/UrlAdapter.java @@ -0,0 +1,71 @@ +package com.fongmi.android.tv.ui.adapter; + +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.fongmi.android.tv.bean.Result; +import com.fongmi.android.tv.databinding.AdapterUrlBinding; + +public class UrlAdapter extends RecyclerView.Adapter { + + private final OnClickListener mListener; + private Result mResult; + private int position; + + public UrlAdapter(OnClickListener listener) { + this.mListener = listener; + this.mResult = Result.empty(); + } + + public interface OnClickListener { + + void onItemClick(Result result); + } + + public void addAll(Result result) { + mResult = result; + notifyDataSetChanged(); + } + + public int getPosition() { + return position; + } + + @Override + public int getItemCount() { + return mResult.getUrl().getValues().size(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(AdapterUrlBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + holder.binding.text.setText(mResult.getUrl().n(position)); + holder.binding.text.setOnClickListener(v -> onItemClick(position)); + holder.binding.text.setActivated(mResult.getUrl().getPosition() == position); + } + + private void onItemClick(int position) { + this.position = position; + mResult.getUrl().set(position); + mListener.onItemClick(mResult); + notifyItemRangeChanged(0, getItemCount()); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + + private final AdapterUrlBinding binding; + + ViewHolder(@NonNull AdapterUrlBinding binding) { + super(binding.getRoot()); + this.binding = binding; + } + } +} \ No newline at end of file diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/holder/VodRectHolder.java b/app/src/mobile/java/com/fongmi/android/tv/ui/holder/VodRectHolder.java index 0f0baa9b5..c9bf96760 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/holder/VodRectHolder.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/holder/VodRectHolder.java @@ -20,8 +20,8 @@ public class VodRectHolder extends BaseVodHolder { } public VodRectHolder size(int[] size) { - itemView.getLayoutParams().width = size[0]; - itemView.getLayoutParams().height = size[1]; + binding.image.getLayoutParams().width = size[0]; + binding.image.getLayoutParams().height = size[1]; return this; } diff --git a/app/src/mobile/res/layout/activity_detail.xml b/app/src/mobile/res/layout/activity_detail.xml index 2146f1e43..4bea61fba 100644 --- a/app/src/mobile/res/layout/activity_detail.xml +++ b/app/src/mobile/res/layout/activity_detail.xml @@ -238,6 +238,19 @@ android:paddingEnd="16dp" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> + + + \ No newline at end of file diff --git a/catvod/src/main/java/com/github/catvod/net/OkHttp.java b/catvod/src/main/java/com/github/catvod/net/OkHttp.java index 0b45f1314..35a620f4d 100644 --- a/catvod/src/main/java/com/github/catvod/net/OkHttp.java +++ b/catvod/src/main/java/com/github/catvod/net/OkHttp.java @@ -77,6 +77,10 @@ public class OkHttp { return client().newCall(new Request.Builder().url(buildUrl(url, params)).build()); } + public static Call newCall(String url, ArrayMap params, RequestBody body) { + return client().newCall(new Request.Builder().url(buildUrl(url, params)).post(body).build()); + } + public static Call newCall(String url, ArrayMap params, Headers headers) { return client().newCall(new Request.Builder().url(buildUrl(url, params)).headers(headers).build()); }