mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-22 16:10:31 +00:00
feat: prettier channel info page
This commit is contained in:
parent
6d84d19520
commit
4859ab67d4
@ -276,7 +276,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo> {
|
||||
final String description = currentInfo.getDescription();
|
||||
if (description != null && !description.isEmpty()) {
|
||||
tabAdapter.addFragment(
|
||||
ChannelInfoFragment.getInstance(description), "Info");
|
||||
ChannelInfoFragment.getInstance(currentInfo), "Info");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,47 @@
|
||||
package org.schabi.newpipe.fragments.list.channel;
|
||||
|
||||
import static org.schabi.newpipe.extractor.stream.StreamExtractor.UNKNOWN_SUBSCRIBER_COUNT;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import com.google.android.material.chip.Chip;
|
||||
|
||||
import org.schabi.newpipe.BaseFragment;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.databinding.FragmentChannelInfoBinding;
|
||||
import org.schabi.newpipe.databinding.ItemMetadataBinding;
|
||||
import org.schabi.newpipe.databinding.ItemMetadataTagsBinding;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfo;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||
import org.schabi.newpipe.util.external_communication.TextLinkifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import icepick.State;
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
|
||||
public class ChannelInfoFragment extends BaseFragment {
|
||||
private String description;
|
||||
@State
|
||||
protected ChannelInfo channelInfo;
|
||||
|
||||
public static ChannelInfoFragment getInstance(final String description) {
|
||||
private final CompositeDisposable disposables = new CompositeDisposable();
|
||||
private FragmentChannelInfoBinding binding;
|
||||
|
||||
public static ChannelInfoFragment getInstance(final ChannelInfo channelInfo) {
|
||||
final ChannelInfoFragment fragment = new ChannelInfoFragment();
|
||||
fragment.description = description;
|
||||
fragment.channelInfo = channelInfo;
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@ -28,11 +53,92 @@ public class ChannelInfoFragment extends BaseFragment {
|
||||
public View onCreateView(@NonNull final LayoutInflater inflater,
|
||||
@Nullable final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
final FragmentChannelInfoBinding binding =
|
||||
FragmentChannelInfoBinding.inflate(inflater, container, false);
|
||||
binding.descriptionText.setText(description);
|
||||
|
||||
binding = FragmentChannelInfoBinding.inflate(inflater, container, false);
|
||||
loadDescription();
|
||||
setupMetadata(inflater, binding.detailMetadataLayout);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
disposables.clear();
|
||||
}
|
||||
|
||||
private void loadDescription() {
|
||||
final String description = channelInfo.getDescription();
|
||||
|
||||
if (description == null || description.isEmpty()) {
|
||||
binding.descriptionTitle.setVisibility(View.GONE);
|
||||
binding.descriptionView.setVisibility(View.GONE);
|
||||
} else {
|
||||
TextLinkifier.createLinksFromPlainText(
|
||||
binding.descriptionView, description, null, disposables);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupMetadata(final LayoutInflater inflater,
|
||||
final LinearLayout layout) {
|
||||
Context context = getActivity();
|
||||
|
||||
if (channelInfo.getSubscriberCount() != UNKNOWN_SUBSCRIBER_COUNT) {
|
||||
addMetadataItem(inflater, layout, R.string.metadata_subscribers,
|
||||
Localization.localizeNumber(context, channelInfo.getSubscriberCount()));
|
||||
}
|
||||
|
||||
addTagsMetadataItem(inflater, layout);
|
||||
}
|
||||
|
||||
private void addMetadataItem(final LayoutInflater inflater,
|
||||
final LinearLayout layout,
|
||||
@StringRes final int type,
|
||||
@Nullable final String content) {
|
||||
if (isBlank(content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemMetadataBinding itemBinding =
|
||||
ItemMetadataBinding.inflate(inflater, layout, false);
|
||||
|
||||
itemBinding.metadataTypeView.setText(type);
|
||||
itemBinding.metadataTypeView.setOnLongClickListener(v -> {
|
||||
ShareUtils.copyToClipboard(requireContext(), content);
|
||||
return true;
|
||||
});
|
||||
|
||||
itemBinding.metadataContentView.setText(content);
|
||||
|
||||
layout.addView(itemBinding.getRoot());
|
||||
}
|
||||
|
||||
private void addTagsMetadataItem(final LayoutInflater inflater, final LinearLayout layout) {
|
||||
final List<String> tags = channelInfo.getTags();
|
||||
|
||||
if (!tags.isEmpty()) {
|
||||
final var itemBinding = ItemMetadataTagsBinding.inflate(inflater, layout, false);
|
||||
|
||||
tags.stream().sorted(String.CASE_INSENSITIVE_ORDER).forEach(tag -> {
|
||||
final Chip chip = (Chip) inflater.inflate(R.layout.chip,
|
||||
itemBinding.metadataTagsChips, false);
|
||||
chip.setText(tag);
|
||||
chip.setOnClickListener(this::onTagClick);
|
||||
chip.setOnLongClickListener(this::onTagLongClick);
|
||||
itemBinding.metadataTagsChips.addView(chip);
|
||||
});
|
||||
|
||||
layout.addView(itemBinding.getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
private void onTagClick(final View chip) {
|
||||
if (getParentFragment() != null) {
|
||||
NavigationHelper.openSearchFragment(getParentFragment().getParentFragmentManager(),
|
||||
channelInfo.getServiceId(), ((Chip) chip).getText().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onTagLongClick(final View chip) {
|
||||
ShareUtils.copyToClipboard(requireContext(), ((Chip) chip).getText().toString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,6 @@ package org.schabi.newpipe.fragments.list.channel;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
|
@ -5,6 +5,19 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/description_tab_description"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<!--
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/description_title"
|
||||
android:layout_width="match_parent"
|
||||
@ -17,20 +30,45 @@
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:layout_editor_absoluteX="16dp"
|
||||
tools:visibility="visible" />
|
||||
tools:visibility="visible" />-->
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/description_text"
|
||||
<!--<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/stats_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="Stats"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@+id/description_view"
|
||||
tools:layout_editor_absoluteX="47dp"
|
||||
tools:visibility="visible" />-->
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/description_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/description_title"
|
||||
tools:layout_editor_absoluteX="36dp"
|
||||
tools:visibility="visible"
|
||||
tools:text="Cupcake ipsum dolor sit amet I love. I love macaroon cake sweet topping jelly beans chocolate chupa chups candy canes. Marshmallow cake jelly fruitcake soufflé pie. Jelly jelly beans cupcake topping chocolate bar jelly pudding pastry sweet roll." />
|
||||
tools:layout_editor_absoluteX="0dp"
|
||||
tools:text="Cupcake ipsum dolor sit amet I love. I love macaroon cake sweet topping jelly beans chocolate chupa chups candy canes. Marshmallow cake jelly fruitcake soufflé pie. Jelly jelly beans cupcake topping chocolate bar jelly pudding pastry sweet roll."
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/detail_metadata_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/description_view" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -620,6 +620,7 @@
|
||||
<string name="metadata_thumbnail_url">Vorschaubild-URL</string>
|
||||
<string name="metadata_host">Server</string>
|
||||
<string name="metadata_support">Unterstützung</string>
|
||||
<string name="metadata_subscribers">Abonnenten</string>
|
||||
<string name="description_select_disable">Auswählen von Text in der Beschreibung deaktivieren</string>
|
||||
<string name="description_select_enable">Auswählen von Text in der Beschreibung aktivieren</string>
|
||||
<string name="description_select_note">Du kannst nun Text innerhalb der Beschreibung auswählen. Beachte, dass die Seite flackern kann und Links im Auswahlmodus möglicherweise nicht anklickbar sind.</string>
|
||||
|
@ -758,6 +758,7 @@
|
||||
<string name="metadata_privacy_unlisted">Unlisted</string>
|
||||
<string name="metadata_privacy_private">Private</string>
|
||||
<string name="metadata_privacy_internal">Internal</string>
|
||||
<string name="metadata_subscribers">Subscribers</string>
|
||||
<string name="detail_pinned_comment_view_description">Pinned comment</string>
|
||||
<string name="detail_heart_img_view_description">Hearted by creator</string>
|
||||
<string name="open_website_license">Open website</string>
|
||||
|
Loading…
Reference in New Issue
Block a user