Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.schabi.newpipe.local.subscription

import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
Expand All @@ -14,8 +13,6 @@ import android.view.View
import android.view.ViewGroup
import android.webkit.MimeTypeMap
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.ViewModelProvider
Expand All @@ -26,9 +23,6 @@ import com.xwray.groupie.GroupAdapter
import com.xwray.groupie.Section
import com.xwray.groupie.viewbinding.GroupieViewHolder
import io.reactivex.rxjava3.disposables.CompositeDisposable
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity.Companion.GROUP_ALL_ID
import org.schabi.newpipe.databinding.DialogTitleBinding
Expand All @@ -52,10 +46,6 @@ 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.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
import org.schabi.newpipe.util.NavigationHelper
import org.schabi.newpipe.util.OnClickGesture
Expand All @@ -69,6 +59,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {

private lateinit var viewModel: SubscriptionViewModel
private lateinit var subscriptionManager: SubscriptionManager
private lateinit var importExportHelper: SubscriptionsImportExportHelper
private val disposables: CompositeDisposable = CompositeDisposable()

private val groupAdapter = GroupAdapter<GroupieViewHolder<FeedItemCarouselBinding>>()
Expand All @@ -77,11 +68,6 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
private lateinit var feedGroupsSortMenuItem: GroupsHeader
private val subscriptionsSection = Section()

private val requestExportLauncher =
registerForActivityResult(StartActivityForResult(), this::requestExportResult)
private val requestImportLauncher =
registerForActivityResult(StartActivityForResult(), this::requestImportResult)

@State
@JvmField
var itemsListState: Parcelable? = null
Expand All @@ -101,6 +87,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
override fun onAttach(context: Context) {
super.onAttach(context)
subscriptionManager = SubscriptionManager(requireContext())
importExportHelper = SubscriptionsImportExportHelper(this)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
Expand Down Expand Up @@ -141,7 +128,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
// -- Import --
val importSubMenu = menu.addSubMenu(R.string.import_from)

addMenuItemToSubmenu(importSubMenu, R.string.previous_export) { onImportPreviousSelected() }
addMenuItemToSubmenu(importSubMenu, R.string.previous_export) { importExportHelper.onImportPreviousSelected() }
.setIcon(R.drawable.ic_backup)

for (service in ServiceList.all()) {
Expand All @@ -159,7 +146,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
// -- Export --
val exportSubMenu = menu.addSubMenu(R.string.export_to)

addMenuItemToSubmenu(exportSubMenu, R.string.file) { onExportSelected() }
addMenuItemToSubmenu(exportSubMenu, R.string.file) { importExportHelper.onExportSelected() }
.setIcon(R.drawable.ic_save)
}

Expand Down Expand Up @@ -195,48 +182,10 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
NavigationHelper.openSubscriptionsImportFragment(fragmentManager, serviceId)
}

private fun onImportPreviousSelected() {
NoFileManagerSafeGuard.launchSafe(
requestImportLauncher,
StoredFileHelper.getPicker(activity, JSON_MIME_TYPE),
TAG,
requireContext()
)
}

private fun onExportSelected() {
val date = SimpleDateFormat("yyyyMMddHHmm", Locale.ENGLISH).format(Date())
val exportName = "newpipe_subscriptions_$date.json"

NoFileManagerSafeGuard.launchSafe(
requestExportLauncher,
StoredFileHelper.getNewPicker(activity, exportName, JSON_MIME_TYPE, null),
TAG,
requireContext()
)
}

private fun openReorderDialog() {
FeedGroupReorderDialog().show(parentFragmentManager, null)
}

private fun requestExportResult(result: ActivityResult) {
val data = result.data?.data
if (data != null && result.resultCode == Activity.RESULT_OK) {
SubscriptionExportWorker.schedule(activity, data)
}
}

private fun requestImportResult(result: ActivityResult) {
val data = result.data?.dataString
if (data != null && result.resultCode == Activity.RESULT_OK) {
ImportConfirmationDialog.show(
this,
SubscriptionImportInput.PreviousExportMode(data)
)
}
}

// ////////////////////////////////////////////////////////////////////////
// Fragment Views
// ////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package org.schabi.newpipe.local.subscription

import android.app.Activity
import android.content.Context
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.fragment.app.Fragment
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import org.schabi.newpipe.local.subscription.SubscriptionFragment.Companion.JSON_MIME_TYPE
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

/**
* This class has to be created in onAttach() or onCreate().
*
* It contains registerForActivityResult calls and those
* calls are only allowed before a fragment/activity is created.
*/
class SubscriptionsImportExportHelper(
val fragment: Fragment
) {
val context: Context = fragment.requireContext()

companion object {
val TAG: String =
SubscriptionsImportExportHelper::class.java.simpleName + "@" + Integer.toHexString(
hashCode()
)
}

private val requestExportLauncher =
fragment.registerForActivityResult(StartActivityForResult(), this::requestExportResult)
private val requestImportLauncher =
fragment.registerForActivityResult(StartActivityForResult(), this::requestImportResult)

private fun requestExportResult(result: ActivityResult) {
val data = result.data?.data
if (data != null && result.resultCode == Activity.RESULT_OK) {
SubscriptionExportWorker.schedule(context, data)
}
}

private fun requestImportResult(result: ActivityResult) {
val data = result.data?.dataString
if (data != null && result.resultCode == Activity.RESULT_OK) {
ImportConfirmationDialog.show(
fragment,
SubscriptionImportInput.PreviousExportMode(data)
)
}
}

fun onExportSelected() {
val date = SimpleDateFormat("yyyyMMddHHmm", Locale.ENGLISH).format(Date())
val exportName = "newpipe_subscriptions_$date.json"

NoFileManagerSafeGuard.launchSafe(
requestExportLauncher,
StoredFileHelper.getNewPicker(
context,
exportName,
JSON_MIME_TYPE,
null
),
TAG,
context
)
}

fun onImportPreviousSelected() {
NoFileManagerSafeGuard.launchSafe(
requestImportLauncher,
StoredFileHelper.getPicker(context, JSON_MIME_TYPE),
TAG,
context
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.local.subscription.SubscriptionsImportExportHelper;
import org.schabi.newpipe.settings.export.BackupFileLocator;
import org.schabi.newpipe.settings.export.ImportExportManager;
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
Expand Down Expand Up @@ -54,8 +55,15 @@ public class BackupRestoreSettingsFragment extends BasePreferenceFragment {
private final ActivityResultLauncher<Intent> requestExportPathLauncher =
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
this::requestExportPathResult);
private SubscriptionsImportExportHelper importExportHelper;


@Override
public void onAttach(@NonNull final Context context) {
super.onAttach(context);
importExportHelper = new SubscriptionsImportExportHelper(this);
}

@Override
public void onCreatePreferences(@Nullable final Bundle savedInstanceState,
@Nullable final String rootKey) {
Expand Down Expand Up @@ -117,6 +125,21 @@ ZIP_MIME_TYPE, getImportExportDataUri()),
alertDialog.show();
return true;
});

final Preference exportSubsPreference =
requirePreference(R.string.export_subscriptions_key);
exportSubsPreference.setOnPreferenceClickListener(reference -> {
importExportHelper.onExportSelected();
return true;
});

final Preference importSubsPreference =
requirePreference(R.string.import_subscriptions_key);
importSubsPreference.setOnPreferenceClickListener(preference -> {
importExportHelper.onImportPreviousSelected();
return true;
});

}

private void requestExportPathResult(final ActivityResult result) {
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/settings_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,8 @@
<string name="import_export_data_path">import_export_data_path</string>
<string name="import_data">import_data</string>
<string name="export_data">export_data</string>
<string name="import_subscriptions_key">import_subscriptions_key</string>
<string name="export_subscriptions_key">export_subscriptions_key</string>

<string name="clear_cookie_key">clear_cookie</string>

Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,11 @@
<string name="export_ongoing">Exporting…</string>
<string name="import_file_title">Import file</string>
<string name="previous_export">Previous export</string>
<string name="import_subscriptions_title">Import subscriptions"</string>
<string name="export_subscriptions_title">Export subscriptions</string>
<string name="import_subscriptions_summary">Import subscriptions from a previous .json export"</string>
<string name="export_subscriptions_summary">Export your subscriptions to a .json file</string>
<string name="import_from_previous_export">Import from previous export</string>
<string name="subscriptions_import_unsuccessful">Could not import subscriptions</string>
<string name="subscriptions_export_unsuccessful">Could not export subscriptions</string>
<string name="import_youtube_instructions">Import YouTube subscriptions from Google takeout:
Expand Down
14 changes: 14 additions & 0 deletions app/src/main/res/xml/backup_restore_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,18 @@
android:summary="@string/reset_settings_summary"
app:singleLineTitle="false"
app:iconSpaceReserved="false" />

<Preference
android:key="@string/export_subscriptions_key"
android:title="@string/export_subscriptions_title"
android:summary="@string/export_subscriptions_summary"
app:singleLineTitle="false"
app:iconSpaceReserved="false" />

<Preference
android:key="@string/import_subscriptions_key"
android:title="@string/import_subscriptions_title"
android:summary="@string/import_subscriptions_summary"
app:singleLineTitle="false"
app:iconSpaceReserved="false" />
</PreferenceScreen>
Loading