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();
|
final String description = currentInfo.getDescription();
|
||||||
if (description != null && !description.isEmpty()) {
|
if (description != null && !description.isEmpty()) {
|
||||||
tabAdapter.addFragment(
|
tabAdapter.addFragment(
|
||||||
ChannelInfoFragment.getInstance(description), "Info");
|
ChannelInfoFragment.getInstance(currentInfo), "Info");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,47 @@
|
|||||||
package org.schabi.newpipe.fragments.list.channel;
|
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.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
|
|
||||||
|
import com.google.android.material.chip.Chip;
|
||||||
|
|
||||||
import org.schabi.newpipe.BaseFragment;
|
import org.schabi.newpipe.BaseFragment;
|
||||||
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.databinding.FragmentChannelInfoBinding;
|
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 {
|
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();
|
final ChannelInfoFragment fragment = new ChannelInfoFragment();
|
||||||
fragment.description = description;
|
fragment.channelInfo = channelInfo;
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,11 +53,92 @@ public class ChannelInfoFragment extends BaseFragment {
|
|||||||
public View onCreateView(@NonNull final LayoutInflater inflater,
|
public View onCreateView(@NonNull final LayoutInflater inflater,
|
||||||
@Nullable final ViewGroup container,
|
@Nullable final ViewGroup container,
|
||||||
final Bundle savedInstanceState) {
|
final Bundle savedInstanceState) {
|
||||||
final FragmentChannelInfoBinding binding =
|
binding = FragmentChannelInfoBinding.inflate(inflater, container, false);
|
||||||
FragmentChannelInfoBinding.inflate(inflater, container, false);
|
loadDescription();
|
||||||
binding.descriptionText.setText(description);
|
setupMetadata(inflater, binding.detailMetadataLayout);
|
||||||
|
|
||||||
return binding.getRoot();
|
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.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
@ -5,6 +5,19 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="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
|
<org.schabi.newpipe.views.NewPipeTextView
|
||||||
android:id="@+id/description_title"
|
android:id="@+id/description_title"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -17,20 +30,45 @@
|
|||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:layout_editor_absoluteX="16dp"
|
tools:layout_editor_absoluteX="16dp"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />-->
|
||||||
|
|
||||||
<org.schabi.newpipe.views.NewPipeTextView
|
<!--<org.schabi.newpipe.views.NewPipeTextView
|
||||||
android:id="@+id/description_text"
|
android:id="@+id/stats_title"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="6dp"
|
android:layout_marginTop="6dp"
|
||||||
android:layout_marginEnd="8dp"
|
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:textIsSelectable="true"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/description_title"
|
app:layout_constraintTop_toBottomOf="@+id/description_title"
|
||||||
tools:layout_editor_absoluteX="36dp"
|
tools:layout_editor_absoluteX="0dp"
|
||||||
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: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>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -620,6 +620,7 @@
|
|||||||
<string name="metadata_thumbnail_url">Vorschaubild-URL</string>
|
<string name="metadata_thumbnail_url">Vorschaubild-URL</string>
|
||||||
<string name="metadata_host">Server</string>
|
<string name="metadata_host">Server</string>
|
||||||
<string name="metadata_support">Unterstützung</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_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_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>
|
<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_unlisted">Unlisted</string>
|
||||||
<string name="metadata_privacy_private">Private</string>
|
<string name="metadata_privacy_private">Private</string>
|
||||||
<string name="metadata_privacy_internal">Internal</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_pinned_comment_view_description">Pinned comment</string>
|
||||||
<string name="detail_heart_img_view_description">Hearted by creator</string>
|
<string name="detail_heart_img_view_description">Hearted by creator</string>
|
||||||
<string name="open_website_license">Open website</string>
|
<string name="open_website_license">Open website</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user