1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-12-23 00:20:32 +00:00

feat: prettier channel info page

This commit is contained in:
ThetaDev 2022-10-23 17:01:39 +02:00 committed by Stypox
parent 6d84d19520
commit 4859ab67d4
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
6 changed files with 160 additions and 16 deletions

View File

@ -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");
} }
} }
} }

View File

@ -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;
}
} }

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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>