XPipe:- Black version of NewPipe

This commit is contained in:
Sreejith 2023-09-19 17:21:39 +05:30
parent 70dc29b216
commit 6f553421e8
11 changed files with 83 additions and 20 deletions

2
.gitignore vendored
View File

@ -18,3 +18,5 @@ app/release/
bin/ bin/
.vscode/ .vscode/
*.code-workspace *.code-workspace
/key.properties
/upload-keystore

View File

@ -1,5 +1,5 @@
<p align="center"><a href="https://newpipe.net"><img src="assets/new_pipe_icon_5.png" width="150"></a></p> <p align="center"><a href="https://newpipe.net"><img src="assets/new_pipe_icon_5.png" width="150"></a></p>
<h2 align="center"><b>Extended NewPipe</b></h2> <h2 align="center"><b>XPipe (Extended NewPipe)</b></h2>
<h4 align="center">A libre lightweight streaming front-end for Android.</h4> <h4 align="center">A libre lightweight streaming front-end for Android.</h4>
<p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-en.svg" alt="Get it on F-Droid" height=80/></a></p> <p align="center"><a href="https://f-droid.org/packages/org.schabi.newpipe/"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on-en.svg" alt="Get it on F-Droid" height=80/></a></p>

View File

@ -11,13 +11,19 @@ plugins {
id "org.sonarqube" version "4.0.0.2929" id "org.sonarqube" version "4.0.0.2929"
} }
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android { android {
compileSdk 33 compileSdk 33
namespace 'org.schabi.newpipe' namespace 'org.schabi.newpipe'
defaultConfig { defaultConfig {
applicationId "org.schabi.newpipe" applicationId "org.schabi.xnewpipe"
resValue "string", "app_name", "NewPipe" resValue "string", "app_name", "XPipe"
minSdk 21 minSdk 21
targetSdk 33 targetSdk 33
versionCode 994 versionCode 994
@ -32,6 +38,15 @@ android {
} }
} }
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
buildTypes { buildTypes {
debug { debug {
debuggable true debuggable true
@ -60,6 +75,7 @@ android {
shrinkResources false // disabled to fix F-Droid's reproducible build shrinkResources false // disabled to fix F-Droid's reproducible build
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
archivesBaseName = 'app' archivesBaseName = 'app'
signingConfig = signingConfigs.release
} }
} }

View File

@ -484,6 +484,8 @@ public final class VideoDetailFragment
binding.detailControlsShare.setOnClickListener(makeOnClickListener(info -> binding.detailControlsShare.setOnClickListener(makeOnClickListener(info ->
ShareUtils.shareText(requireContext(), info.getName(), info.getUrl(), ShareUtils.shareText(requireContext(), info.getName(), info.getUrl(),
info.getThumbnailUrl()))); info.getThumbnailUrl())));
binding.detailControlsOpenInYoutube.setOnClickListener(makeOnClickListener(info ->
ShareUtils.openUrlInYoutube(requireContext(), info.getUrl())));
binding.detailControlsOpenInBrowser.setOnClickListener(makeOnClickListener(info -> binding.detailControlsOpenInBrowser.setOnClickListener(makeOnClickListener(info ->
ShareUtils.openUrlInBrowser(requireContext(), info.getUrl()))); ShareUtils.openUrlInBrowser(requireContext(), info.getUrl())));
binding.detailControlsPlayWithKodi.setOnClickListener(makeOnClickListener(info -> binding.detailControlsPlayWithKodi.setOnClickListener(makeOnClickListener(info ->

View File

@ -92,7 +92,10 @@ class FeedFragment : BaseStateFragment<FeedState>() {
private val disposables = CompositeDisposable() private val disposables = CompositeDisposable()
private lateinit var viewModel: FeedViewModel private lateinit var viewModel: FeedViewModel
@State @JvmField var listState: Parcelable? = null
@State
@JvmField
var listState: Parcelable? = null
private var groupId = FeedGroupEntity.GROUP_ALL_ID private var groupId = FeedGroupEntity.GROUP_ALL_ID
private var groupName = "" private var groupName = ""
@ -126,7 +129,11 @@ class FeedFragment : BaseStateFragment<FeedState>() {
.registerOnSharedPreferenceChangeListener(onSettingsChangeListener) .registerOnSharedPreferenceChangeListener(onSettingsChangeListener)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_feed, container, false) return inflater.inflate(R.layout.fragment_feed, container, false)
} }
@ -183,10 +190,12 @@ class FeedFragment : BaseStateFragment<FeedState>() {
private fun setupListViewMode() { private fun setupListViewMode() {
// does everything needed to setup the layouts for grid or list modes // does everything needed to setup the layouts for grid or list modes
groupAdapter.spanCount = if (shouldUseGridLayout(context)) getGridSpanCountStreams(context) else 1 groupAdapter.spanCount =
feedBinding.itemsList.layoutManager = GridLayoutManager(requireContext(), groupAdapter.spanCount).apply { if (shouldUseGridLayout(context)) getGridSpanCountStreams(context) else 1
spanSizeLookup = groupAdapter.spanSizeLookup feedBinding.itemsList.layoutManager =
} GridLayoutManager(requireContext(), groupAdapter.spanCount).apply {
spanSizeLookup = groupAdapter.spanSizeLookup
}
} }
override fun initListeners() { override fun initListeners() {
@ -228,7 +237,10 @@ class FeedFragment : BaseStateFragment<FeedState>() {
.setMessage(R.string.feed_use_dedicated_fetch_method_help_text) .setMessage(R.string.feed_use_dedicated_fetch_method_help_text)
.setNeutralButton(enableDisableButtonText) { _, _ -> .setNeutralButton(enableDisableButtonText) { _, _ ->
sharedPreferences.edit { sharedPreferences.edit {
putBoolean(getString(R.string.feed_use_dedicated_fetch_method_key), !usingDedicatedMethod) putBoolean(
getString(R.string.feed_use_dedicated_fetch_method_key),
!usingDedicatedMethod
)
} }
} }
.setPositiveButton(resources.getString(R.string.ok), null) .setPositiveButton(resources.getString(R.string.ok), null)
@ -436,6 +448,11 @@ class FeedFragment : BaseStateFragment<FeedState>() {
showEmptyState() showEmptyState()
} else { } else {
hideLoading() hideLoading()
if (oldestSubscriptionUpdate == null || OffsetDateTime.now().minusHours(1)
.isAfter(oldestSubscriptionUpdate)
) {
reloadContent()
}
} }
} }
@ -665,7 +682,10 @@ class FeedFragment : BaseStateFragment<FeedState>() {
const val KEY_GROUP_NAME = "ARG_GROUP_NAME" const val KEY_GROUP_NAME = "ARG_GROUP_NAME"
@JvmStatic @JvmStatic
fun newInstance(groupId: Long = FeedGroupEntity.GROUP_ALL_ID, groupName: String? = null): FeedFragment { fun newInstance(
groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
groupName: String? = null
): FeedFragment {
val feedFragment = FeedFragment() val feedFragment = FeedFragment()
feedFragment.arguments = bundleOf(KEY_GROUP_ID to groupId, KEY_GROUP_NAME to groupName) feedFragment.arguments = bundleOf(KEY_GROUP_ID to groupId, KEY_GROUP_NAME to groupName)
return feedFragment return feedFragment

View File

@ -58,6 +58,11 @@ public final class ShareUtils {
} }
} }
public static void openUrlInYoutube(@NonNull final Context context, @NonNull final String url) {
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
tryOpenIntentInApp(context, intent);
}
/** /**
* Open the url with the system default browser. If no browser is set as default, falls back to * Open the url with the system default browser. If no browser is set as default, falls back to
* {@link #openAppChooser(Context, Intent, boolean)}. * {@link #openAppChooser(Context, Intent, boolean)}.
@ -198,9 +203,9 @@ public final class ShareUtils {
final ClipData.Item item = new ClipData.Item(intent.getData()); final ClipData.Item item = new ClipData.Item(intent.getData());
final String[] mimeTypes; final String[] mimeTypes;
if (intent.getType() != null) { if (intent.getType() != null) {
mimeTypes = new String[] {intent.getType()}; mimeTypes = new String[]{intent.getType()};
} else { } else {
mimeTypes = new String[] {}; mimeTypes = new String[]{};
} }
targetClipData = new ClipData(null, mimeTypes, item); targetClipData = new ClipData(null, mimeTypes, item);
} }
@ -370,9 +375,9 @@ public final class ShareUtils {
fileOutputStream.close(); fileOutputStream.close();
final ClipData clipData = ClipData.newUri(applicationContext.getContentResolver(), "", final ClipData clipData = ClipData.newUri(applicationContext.getContentResolver(), "",
FileProvider.getUriForFile(applicationContext, FileProvider.getUriForFile(applicationContext,
BuildConfig.APPLICATION_ID + ".provider", BuildConfig.APPLICATION_ID + ".provider",
thumbnailPreviewFile)); thumbnailPreviewFile));
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "ClipData successfully generated for Android share sheet: " + clipData); Log.d(TAG, "ClipData successfully generated for Android share sheet: " + clipData);

View File

@ -482,6 +482,7 @@
android:paddingHorizontal="@dimen/detail_control_padding" android:paddingHorizontal="@dimen/detail_control_padding"
android:paddingBottom="@dimen/detail_control_padding" android:paddingBottom="@dimen/detail_control_padding"
android:visibility="gone" android:visibility="gone"
tools:background="@color/white"
tools:visibility="visible"> tools:visibility="visible">
<org.schabi.newpipe.views.NewPipeTextView <org.schabi.newpipe.views.NewPipeTextView
@ -500,6 +501,22 @@
android:text="@string/share" android:text="@string/share"
android:textSize="@dimen/detail_control_text_size" /> android:textSize="@dimen/detail_control_text_size" />
<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/detail_controls_open_in_youtube"
android:layout_width="@dimen/detail_control_width"
android:layout_height="@dimen/detail_control_height"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:contentDescription="@string/open_in_youtube"
android:drawableTop="@drawable/ic_smart_display"
android:focusable="true"
android:gravity="center"
android:paddingVertical="@dimen/detail_control_padding"
android:text="@string/open_in_youtube"
android:textSize="@dimen/detail_control_text_size" />
<org.schabi.newpipe.views.NewPipeTextView <org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/detail_controls_open_in_browser" android:id="@+id/detail_controls_open_in_browser"
android:layout_width="@dimen/detail_control_width" android:layout_width="@dimen/detail_control_width"

View File

@ -4,7 +4,7 @@
<color name="contrastColor">@color/black</color> <color name="contrastColor">@color/black</color>
<color name="defaultIconTint">@color/black</color> <color name="defaultIconTint">@color/black</color>
<color name="ic_launcher_background">#CD201F</color> <color name="ic_launcher_background">#000000</color>
<color name="placeholder_background">#999999</color> <color name="placeholder_background">#999999</color>
<color name="placeholder_foreground">#6C6C6C</color> <color name="placeholder_foreground">#6C6C6C</color>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- YouTube --> <!-- YouTube -->
<color name="light_youtube_primary_color">#e53935</color> <color name="light_youtube_primary_color">#000000</color>
<color name="light_youtube_accent_color">#000000</color> <color name="light_youtube_accent_color">#000000</color>
<color name="dark_youtube_primary_color">#992722</color> <color name="dark_youtube_primary_color">#000000</color>
<color name="dark_youtube_accent_color">#FFFFFF</color> <color name="dark_youtube_accent_color">#FFFFFF</color>
<!-- SoundCloud --> <!-- SoundCloud -->

View File

@ -811,4 +811,5 @@
<string name="channel_tab_about">About</string> <string name="channel_tab_about">About</string>
<string name="show_channel_tabs">Channel tabs</string> <string name="show_channel_tabs">Channel tabs</string>
<string name="show_channel_tabs_summary">What tabs are shown on the channel pages</string> <string name="show_channel_tabs_summary">What tabs are shown on the channel pages</string>
<string name="open_in_youtube">Open in Youtube</string>
</resources> </resources>

View File

@ -3,5 +3,5 @@ android.enableJetifier=false
android.nonFinalResIds=false android.nonFinalResIds=false
android.nonTransitiveRClass=false android.nonTransitiveRClass=false
android.useAndroidX=true android.useAndroidX=true
org.gradle.jvmargs=-Xmx2048M --add-opens jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED org.gradle.jvmargs=-Xmx2048M --illegal-access=permit --add-opens jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
systemProp.file.encoding=utf-8 systemProp.file.encoding=utf-8