Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ plugins {
alias libs.plugins.kotlin.compose
alias libs.plugins.kotlin.kapt
alias libs.plugins.kotlin.parcelize
alias libs.plugins.kotlinx.serialization
alias libs.plugins.checkstyle
alias libs.plugins.sonarqube
alias libs.plugins.hilt
alias libs.plugins.aboutlibraries
}

android {
compileSdk 34
compileSdk 35
namespace 'org.schabi.newpipe'

defaultConfig {
Expand Down Expand Up @@ -226,7 +227,6 @@ dependencies {
implementation libs.androidx.fragment.compose
implementation libs.androidx.lifecycle.livedata
implementation libs.androidx.lifecycle.viewmodel
implementation libs.androidx.localbroadcastmanager
implementation libs.androidx.media
implementation libs.androidx.preference
implementation libs.androidx.recyclerview
Expand Down Expand Up @@ -319,6 +319,9 @@ dependencies {
// Scroll
implementation libs.lazycolumnscrollbar

// Kotlinx Serialization
implementation libs.kotlinx.serialization.json

/** Debugging **/
// Memory leak detection
debugImplementation libs.leakcanary.object.watcher
Expand Down
15 changes: 15 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,18 @@

## For some reason NotificationModeConfigFragment wasn't kept (only referenced in a preference xml)
-keep class org.schabi.newpipe.settings.notifications.** { *; }

## Keep Kotlinx Serialization classes
-keepclassmembers class kotlinx.serialization.json.** {
*** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
kotlinx.serialization.KSerializer serializer(...);
}
-keep,includedescriptorclasses class org.schabi.newpipe.**$$serializer { *; }
-keepclassmembers class org.schabi.newpipe.** {
*** Companion;
}
-keepclasseswithmembers class org.schabi.newpipe.** {
kotlinx.serialization.KSerializer serializer(...);
}
7 changes: 5 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

<!-- We need to be able to open links in the browser on API 30+ -->
Expand Down Expand Up @@ -90,8 +91,10 @@
android:exported="false"
android:label="@string/title_activity_about" />

<service android:name=".local.subscription.services.SubscriptionsImportService" />
<service android:name=".local.subscription.services.SubscriptionsExportService" />
<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
tools:node="merge" />
<service android:name=".local.feed.service.FeedLoadService" />

<activity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ abstract class SubscriptionDAO : BasicDAO<SubscriptionEntity> {
internal abstract fun silentInsertAllInternal(entities: List<SubscriptionEntity>): List<Long>

@Transaction
open fun upsertAll(entities: List<SubscriptionEntity>): List<SubscriptionEntity> {
open fun upsertAll(entities: List<SubscriptionEntity>) {
val insertUidList = silentInsertAllInternal(entities)

insertUidList.forEachIndexed { index: Int, uidFromInsert: Long ->
Expand All @@ -106,7 +106,5 @@ abstract class SubscriptionDAO : BasicDAO<SubscriptionEntity> {
update(entity)
}
}

return entities
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,64 @@
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;

import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.os.BundleCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.work.Constraints;
import androidx.work.ExistingWorkPolicy;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.OutOfQuotaPolicy;
import androidx.work.WorkManager;

import com.evernote.android.state.State;
import com.livefront.bridge.Bridge;

import org.schabi.newpipe.R;
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput;
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportWorker;

public class ImportConfirmationDialog extends DialogFragment {
@State
protected Intent resultServiceIntent;
private static final String INPUT = "input";

public static void show(@NonNull final Fragment fragment,
@NonNull final Intent resultServiceIntent) {
final ImportConfirmationDialog confirmationDialog = new ImportConfirmationDialog();
confirmationDialog.setResultServiceIntent(resultServiceIntent);
public static void show(@NonNull final Fragment fragment, final SubscriptionImportInput input) {
final var confirmationDialog = new ImportConfirmationDialog();
final var arguments = new Bundle();
arguments.putParcelable(INPUT, input);
confirmationDialog.setArguments(arguments);
confirmationDialog.show(fragment.getParentFragmentManager(), null);
}

public void setResultServiceIntent(final Intent resultServiceIntent) {
this.resultServiceIntent = resultServiceIntent;
}

@NonNull
@Override
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
assureCorrectAppLanguage(getContext());
return new AlertDialog.Builder(requireContext())
final var context = requireContext();
assureCorrectAppLanguage(context);
return new AlertDialog.Builder(context)
.setMessage(R.string.import_network_expensive_warning)
.setCancelable(true)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
if (resultServiceIntent != null && getContext() != null) {
getContext().startService(resultServiceIntent);
}
final var constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
final var input = BundleCompat.getParcelable(requireArguments(), INPUT,
SubscriptionImportInput.class);

final var req = new OneTimeWorkRequest.Builder(SubscriptionImportWorker.class)
.setInputData(input.toData())
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.setConstraints(constraints)
.build();

WorkManager.getInstance(context)
.enqueueUniqueWork(SubscriptionImportWorker.WORK_NAME,
ExistingWorkPolicy.APPEND_OR_REPLACE, req);

dismiss();
})
.create();
Expand All @@ -53,10 +70,6 @@ public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (resultServiceIntent == null) {
throw new IllegalStateException("Result intent is null");
}

Bridge.restoreInstanceState(this, savedInstanceState);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package org.schabi.newpipe.local.subscription
import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
Expand Down Expand Up @@ -49,11 +48,8 @@ import org.schabi.newpipe.local.subscription.item.FeedGroupCarouselItem
import org.schabi.newpipe.local.subscription.item.GroupsHeader
import org.schabi.newpipe.local.subscription.item.Header
import org.schabi.newpipe.local.subscription.item.ImportSubscriptionsHintPlaceholderItem
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE
import org.schabi.newpipe.local.subscription.workers.SubscriptionExportWorker
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
import org.schabi.newpipe.streams.io.StoredFileHelper
import org.schabi.newpipe.ui.emptystate.setEmptyStateComposable
Expand Down Expand Up @@ -224,21 +220,17 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
}

private fun requestExportResult(result: ActivityResult) {
if (result.data != null && result.resultCode == Activity.RESULT_OK) {
activity.startService(
Intent(activity, SubscriptionsExportService::class.java)
.putExtra(SubscriptionsExportService.KEY_FILE_PATH, result.data?.data)
)
val data = result.data?.data
if (data != null && result.resultCode == Activity.RESULT_OK) {
SubscriptionExportWorker.schedule(activity, data)
}
}

private fun requestImportResult(result: ActivityResult) {
if (result.data != null && result.resultCode == Activity.RESULT_OK) {
val data = result.data?.dataString
if (data != null && result.resultCode == Activity.RESULT_OK) {
ImportConfirmationDialog.show(
this,
Intent(activity, SubscriptionsImportService::class.java)
.putExtra(KEY_MODE, PREVIOUS_EXPORT_MODE)
.putExtra(KEY_VALUE, result.data?.data)
this, SubscriptionImportInput.PreviousExportMode(data)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.schabi.newpipe.local.subscription

import android.content.Context
import android.util.Pair
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
Expand Down Expand Up @@ -48,23 +47,16 @@ class SubscriptionManager(context: Context) {
}
}

fun upsertAll(infoList: List<Pair<ChannelInfo, List<ChannelTabInfo>>>): List<SubscriptionEntity> {
val listEntities = subscriptionTable.upsertAll(
infoList.map { SubscriptionEntity.from(it.first) }
)
fun upsertAll(infoList: List<Pair<ChannelInfo, ChannelTabInfo>>) {
val listEntities = infoList.map { SubscriptionEntity.from(it.first) }
subscriptionTable.upsertAll(listEntities)

database.runInTransaction {
infoList.forEachIndexed { index, info ->
info.second.forEach {
feedDatabaseManager.upsertAll(
listEntities[index].uid,
it.relatedItems.filterIsInstance<StreamInfoItem>()
)
}
val streams = info.second.relatedItems.filterIsInstance<StreamInfoItem>()
feedDatabaseManager.upsertAll(listEntities[index].uid, streams)
}
}

return listEntities
}

fun updateChannelInfo(info: ChannelInfo): Completable =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package org.schabi.newpipe.local.subscription;

import static org.schabi.newpipe.extractor.subscription.SubscriptionExtractor.ContentSource.CHANNEL_URL;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.CHANNEL_URL_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.INPUT_STREAM_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE;

import android.app.Activity;
import android.content.Intent;
Expand Down Expand Up @@ -37,7 +33,7 @@
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService;
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput;
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
import org.schabi.newpipe.streams.io.StoredFileHelper;
import org.schabi.newpipe.util.Constants;
Expand Down Expand Up @@ -168,10 +164,8 @@ private void onImportClicked() {
}

public void onImportUrl(final String value) {
ImportConfirmationDialog.show(this, new Intent(activity, SubscriptionsImportService.class)
.putExtra(KEY_MODE, CHANNEL_URL_MODE)
.putExtra(KEY_VALUE, value)
.putExtra(Constants.KEY_SERVICE_ID, currentServiceId));
ImportConfirmationDialog.show(this,
new SubscriptionImportInput.ChannelUrlMode(currentServiceId, value));
}

public void onImportFile() {
Expand All @@ -186,16 +180,10 @@ public void onImportFile() {
}

private void requestImportFileResult(final ActivityResult result) {
if (result.getData() == null) {
return;
}

if (result.getResultCode() == Activity.RESULT_OK && result.getData().getData() != null) {
final String data = result.getData() != null ? result.getData().getDataString() : null;
if (result.getResultCode() == Activity.RESULT_OK && data != null) {
ImportConfirmationDialog.show(this,
new Intent(activity, SubscriptionsImportService.class)
.putExtra(KEY_MODE, INPUT_STREAM_MODE)
.putExtra(KEY_VALUE, result.getData().getData())
.putExtra(Constants.KEY_SERVICE_ID, currentServiceId));
new SubscriptionImportInput.InputStreamMode(currentServiceId, data));
}
}

Expand Down
Loading