Merge pull request #3511 from wb9688/ktlint

Ktlint
This commit is contained in:
wb9688 2020-05-04 15:13:07 +02:00 committed by GitHub
commit b630f269c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 402 additions and 290 deletions

View file

@ -116,25 +116,40 @@ task runCheckstyle(type: Checkstyle) {
} }
} }
tasks.withType(Checkstyle).each { runCheckstyle.doLast {
checkstyleTask -> checkstyleTask.doLast {
reports.all { report -> reports.all { report ->
def outputFile = report.destination def outputFile = report.destination
if (outputFile.exists() && outputFile.text.contains("severity=\"error\"")) { if (outputFile.exists() && outputFile.text.contains("severity=\"error\"")) {
throw new GradleException("There were checkstyle errors! For more info check $outputFile") throw new GradleException("There were checkstyle errors! For more info check $outputFile")
} }
} }
} }
configurations {
ktlint
}
task runKtlint(type: JavaExec) {
main = "com.pinterest.ktlint.Main"
classpath = configurations.ktlint
args "src/**/*.kt"
}
task formatKtlint(type: JavaExec) {
main = "com.pinterest.ktlint.Main"
classpath = configurations.ktlint
args "-F", "src/**/*.kt"
} }
afterEvaluate { afterEvaluate {
preDebugBuild.dependsOn runCheckstyle preDebugBuild.dependsOn runCheckstyle, runKtlint
} }
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
debugImplementation "com.puppycrawl.tools:checkstyle:${checkstyleVersion}" debugImplementation "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
ktlint "com.pinterest:ktlint:0.35.0"
androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation "android.arch.persistence.room:testing:1.1.1" androidTestImplementation "android.arch.persistence.room:testing:1.1.1"

View file

@ -43,15 +43,15 @@ import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue; import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper; import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.views.FocusOverlayView;
import org.schabi.newpipe.util.urlfinder.UrlFinder; import org.schabi.newpipe.util.urlfinder.UrlFinder;
import org.schabi.newpipe.views.FocusOverlayView;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -1,12 +1,17 @@
package org.schabi.newpipe.database.feed.dao package org.schabi.newpipe.database.feed.dao
import androidx.room.* import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import io.reactivex.Flowable import io.reactivex.Flowable
import java.util.Date
import org.schabi.newpipe.database.feed.model.FeedEntity import org.schabi.newpipe.database.feed.model.FeedEntity
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity
import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.database.subscription.SubscriptionEntity
import java.util.*
@Dao @Dao
abstract class FeedDAO { abstract class FeedDAO {

View file

@ -1,6 +1,11 @@
package org.schabi.newpipe.database.feed.dao package org.schabi.newpipe.database.feed.dao
import androidx.room.* import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import io.reactivex.Flowable import io.reactivex.Flowable
import io.reactivex.Maybe import io.reactivex.Maybe
import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupEntity

View file

@ -4,10 +4,10 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import java.util.Date
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.FEED_LAST_UPDATED_TABLE import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.FEED_LAST_UPDATED_TABLE
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.SUBSCRIPTION_ID import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.SUBSCRIPTION_ID
import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.database.subscription.SubscriptionEntity
import java.util.*
@Entity( @Entity(
tableName = FEED_LAST_UPDATED_TABLE, tableName = FEED_LAST_UPDATED_TABLE,

View file

@ -2,8 +2,8 @@ package org.schabi.newpipe.database.history.model
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Embedded import androidx.room.Embedded
import java.util.Date
import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity
import java.util.*
data class StreamHistoryEntry( data class StreamHistoryEntry(
@Embedded @Embedded

View file

@ -2,11 +2,11 @@ package org.schabi.newpipe.database.stream
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Embedded import androidx.room.Embedded
import java.util.Date
import org.schabi.newpipe.database.LocalItem import org.schabi.newpipe.database.LocalItem
import org.schabi.newpipe.database.history.model.StreamHistoryEntity import org.schabi.newpipe.database.history.model.StreamHistoryEntity
import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamInfoItem
import java.util.*
class StreamStatisticsEntry( class StreamStatisticsEntry(
@Embedded @Embedded

View file

@ -1,15 +1,19 @@
package org.schabi.newpipe.database.stream.dao package org.schabi.newpipe.database.stream.dao
import androidx.room.* import androidx.room.ColumnInfo
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import io.reactivex.Flowable import io.reactivex.Flowable
import java.util.Date
import org.schabi.newpipe.database.BasicDAO import org.schabi.newpipe.database.BasicDAO
import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_ID import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_ID
import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.extractor.stream.StreamType
import org.schabi.newpipe.extractor.stream.StreamType.AUDIO_LIVE_STREAM import org.schabi.newpipe.extractor.stream.StreamType.AUDIO_LIVE_STREAM
import org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM import org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM
import java.util.*
import kotlin.collections.ArrayList
@Dao @Dao
abstract class StreamDAO : BasicDAO<StreamEntity> { abstract class StreamDAO : BasicDAO<StreamEntity> {
@ -94,7 +98,6 @@ abstract class StreamDAO : BasicDAO<StreamEntity> {
if (existentMinimalStream.duration > 0 && newerStream.duration < 0) { if (existentMinimalStream.duration > 0 && newerStream.duration < 0) {
newerStream.duration = existentMinimalStream.duration newerStream.duration = existentMinimalStream.duration
} }
} }
} }
@ -132,5 +135,6 @@ abstract class StreamDAO : BasicDAO<StreamEntity> {
var isUploadDateApproximation: Boolean? = null, var isUploadDateApproximation: Boolean? = null,
@ColumnInfo(name = StreamEntity.STREAM_DURATION) @ColumnInfo(name = StreamEntity.STREAM_DURATION)
var duration: Long) var duration: Long
)
} }

View file

@ -1,6 +1,13 @@
package org.schabi.newpipe.database.stream.model package org.schabi.newpipe.database.stream.model
import androidx.room.* import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index
import androidx.room.PrimaryKey
import java.io.Serializable
import java.util.Calendar
import java.util.Date
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_SERVICE_ID import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_SERVICE_ID
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_TABLE import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_TABLE
import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_URL import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_URL
@ -9,8 +16,6 @@ import org.schabi.newpipe.extractor.stream.StreamInfo
import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.extractor.stream.StreamType
import org.schabi.newpipe.player.playqueue.PlayQueueItem import org.schabi.newpipe.player.playqueue.PlayQueueItem
import java.io.Serializable
import java.util.*
@Entity(tableName = STREAM_TABLE, @Entity(tableName = STREAM_TABLE,
indices = [ indices = [

View file

@ -1,6 +1,10 @@
package org.schabi.newpipe.database.subscription package org.schabi.newpipe.database.subscription
import androidx.room.* import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import io.reactivex.Flowable import io.reactivex.Flowable
import io.reactivex.Maybe import io.reactivex.Maybe
import org.schabi.newpipe.database.BasicDAO import org.schabi.newpipe.database.BasicDAO

View file

@ -41,12 +41,12 @@ import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.search.SearchExtractor; import org.schabi.newpipe.extractor.search.SearchExtractor;
import org.schabi.newpipe.extractor.search.SearchInfo; import org.schabi.newpipe.extractor.search.SearchInfo;
import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.fragments.BackPressable; import org.schabi.newpipe.fragments.BackPressable;
import org.schabi.newpipe.fragments.list.BaseListFragment; import org.schabi.newpipe.fragments.list.BaseListFragment;
import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.util.AnimationUtils; import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.ExtractorHelper;

View file

@ -7,6 +7,8 @@ import io.reactivex.Flowable
import io.reactivex.Maybe import io.reactivex.Maybe
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.Calendar
import java.util.Date
import org.schabi.newpipe.MainActivity.DEBUG import org.schabi.newpipe.MainActivity.DEBUG
import org.schabi.newpipe.NewPipeDatabase import org.schabi.newpipe.NewPipeDatabase
import org.schabi.newpipe.database.feed.model.FeedEntity import org.schabi.newpipe.database.feed.model.FeedEntity
@ -16,8 +18,6 @@ import org.schabi.newpipe.database.stream.model.StreamEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.extractor.stream.StreamType
import org.schabi.newpipe.local.subscription.FeedGroupIcon import org.schabi.newpipe.local.subscription.FeedGroupIcon
import java.util.*
import kotlin.collections.ArrayList
class FeedDatabaseManager(context: Context) { class FeedDatabaseManager(context: Context) {
private val database = NewPipeDatabase.getInstance(context) private val database = NewPipeDatabase.getInstance(context)
@ -70,8 +70,11 @@ class FeedDatabaseManager(context: Context) {
fun markAsOutdated(subscriptionId: Long) = feedTable fun markAsOutdated(subscriptionId: Long) = feedTable
.setLastUpdatedForSubscription(FeedLastUpdatedEntity(subscriptionId, null)) .setLastUpdatedForSubscription(FeedLastUpdatedEntity(subscriptionId, null))
fun upsertAll(subscriptionId: Long, items: List<StreamInfoItem>, fun upsertAll(
oldestAllowedDate: Date = FEED_OLDEST_ALLOWED_DATE.time) { subscriptionId: Long,
items: List<StreamInfoItem>,
oldestAllowedDate: Date = FEED_OLDEST_ALLOWED_DATE.time
) {
val itemsToInsert = ArrayList<StreamInfoItem>() val itemsToInsert = ArrayList<StreamInfoItem>()
loop@ for (streamItem in items) { loop@ for (streamItem in items) {
val uploadDate = streamItem.uploadDate val uploadDate = streamItem.uploadDate
@ -107,9 +110,9 @@ class FeedDatabaseManager(context: Context) {
if (DEBUG) Log.d(this::class.java.simpleName, "clear() → streamTable.deleteOrphans() → $deletedOrphans") if (DEBUG) Log.d(this::class.java.simpleName, "clear() → streamTable.deleteOrphans() → $deletedOrphans")
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Feed Groups // Feed Groups
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
fun subscriptionIdsForGroup(groupId: Long): Flowable<List<Long>> { fun subscriptionIdsForGroup(groupId: Long): Flowable<List<Long>> {
return feedGroupTable.getSubscriptionIdsFor(groupId) return feedGroupTable.getSubscriptionIdsFor(groupId)
@ -161,6 +164,5 @@ class FeedDatabaseManager(context: Context) {
FeedGroupEntity.GROUP_ALL_ID -> feedTable.oldestSubscriptionUpdateFromAll() FeedGroupEntity.GROUP_ALL_ID -> feedTable.oldestSubscriptionUpdateFromAll()
else -> feedTable.oldestSubscriptionUpdate(groupId) else -> feedTable.oldestSubscriptionUpdate(groupId)
} }
} }
} }

View file

@ -22,14 +22,28 @@ package org.schabi.newpipe.local.feed
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.view.* import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import icepick.State import icepick.State
import kotlinx.android.synthetic.main.error_retry.* import java.util.Calendar
import kotlinx.android.synthetic.main.fragment_feed.* import kotlinx.android.synthetic.main.error_retry.error_button_retry
import kotlinx.android.synthetic.main.error_retry.error_message_view
import kotlinx.android.synthetic.main.fragment_feed.empty_state_view
import kotlinx.android.synthetic.main.fragment_feed.error_panel
import kotlinx.android.synthetic.main.fragment_feed.items_list
import kotlinx.android.synthetic.main.fragment_feed.loading_progress_bar
import kotlinx.android.synthetic.main.fragment_feed.loading_progress_text
import kotlinx.android.synthetic.main.fragment_feed.refresh_root_view
import kotlinx.android.synthetic.main.fragment_feed.refresh_subtitle_text
import kotlinx.android.synthetic.main.fragment_feed.refresh_text
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.fragments.list.BaseListFragment import org.schabi.newpipe.fragments.list.BaseListFragment
@ -37,7 +51,6 @@ import org.schabi.newpipe.local.feed.service.FeedLoadService
import org.schabi.newpipe.report.UserAction import org.schabi.newpipe.report.UserAction
import org.schabi.newpipe.util.AnimationUtils.animateView import org.schabi.newpipe.util.AnimationUtils.animateView
import org.schabi.newpipe.util.Localization import org.schabi.newpipe.util.Localization
import java.util.*
class FeedFragment : BaseListFragment<FeedState, Unit>() { class FeedFragment : BaseListFragment<FeedState, Unit>() {
private lateinit var viewModel: FeedViewModel private lateinit var viewModel: FeedViewModel
@ -98,9 +111,9 @@ class FeedFragment : BaseListFragment<FeedState, Unit>() {
} }
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Menu // Menu
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
@ -150,9 +163,9 @@ class FeedFragment : BaseListFragment<FeedState, Unit>() {
activity?.supportActionBar?.subtitle = null activity?.supportActionBar?.subtitle = null
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Handling // Handling
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
override fun showLoading() { override fun showLoading() {
animateView(refresh_root_view, false, 0) animateView(refresh_root_view, false, 0)
@ -259,7 +272,6 @@ class FeedFragment : BaseListFragment<FeedState, Unit>() {
} }
} }
private fun handleErrorState(errorState: FeedState.ErrorState): Boolean { private fun handleErrorState(errorState: FeedState.ErrorState): Boolean {
hideLoading() hideLoading()
errorState.error?.let { errorState.error?.let {
@ -283,9 +295,9 @@ class FeedFragment : BaseListFragment<FeedState, Unit>() {
refresh_text?.text = getString(R.string.feed_oldest_subscription_update, oldestSubscriptionUpdateText) refresh_text?.text = getString(R.string.feed_oldest_subscription_update, oldestSubscriptionUpdateText)
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Load Service Handling // Load Service Handling
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
override fun doInitialLoadLogic() {} override fun doInitialLoadLogic() {}
override fun reloadContent() = triggerUpdate() override fun reloadContent() = triggerUpdate()

View file

@ -1,8 +1,8 @@
package org.schabi.newpipe.local.feed package org.schabi.newpipe.local.feed
import androidx.annotation.StringRes import androidx.annotation.StringRes
import java.util.Calendar
import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamInfoItem
import java.util.*
sealed class FeedState { sealed class FeedState {
data class ProgressState( data class ProgressState(

View file

@ -9,13 +9,17 @@ import io.reactivex.Flowable
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Function4 import io.reactivex.functions.Function4
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.Calendar
import java.util.Date
import java.util.concurrent.TimeUnit
import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.local.feed.service.FeedEventManager import org.schabi.newpipe.local.feed.service.FeedEventManager
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.* import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ErrorResultEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.IdleEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ProgressEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.SuccessResultEvent
import org.schabi.newpipe.util.DEFAULT_THROTTLE_TIMEOUT import org.schabi.newpipe.util.DEFAULT_THROTTLE_TIMEOUT
import java.util.*
import java.util.concurrent.TimeUnit
class FeedViewModel(applicationContext: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModel() { class FeedViewModel(applicationContext: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModel() {
class Factory(val context: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModelProvider.Factory { class Factory(val context: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModelProvider.Factory {

View file

@ -3,8 +3,8 @@ package org.schabi.newpipe.local.feed.service
import androidx.annotation.StringRes import androidx.annotation.StringRes
import io.reactivex.Flowable import io.reactivex.Flowable
import io.reactivex.processors.BehaviorProcessor import io.reactivex.processors.BehaviorProcessor
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.IdleEvent
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.IdleEvent
object FeedEventManager { object FeedEventManager {
private var processor: BehaviorProcessor<Event> = BehaviorProcessor.create() private var processor: BehaviorProcessor<Event> = BehaviorProcessor.create()
@ -34,5 +34,4 @@ object FeedEventManager {
data class SuccessResultEvent(val itemsErrors: List<Throwable> = emptyList()) : Event() data class SuccessResultEvent(val itemsErrors: List<Throwable> = emptyList()) : Event()
data class ErrorResultEvent(val error: Throwable) : Event() data class ErrorResultEvent(val error: Throwable) : Event()
} }
} }

View file

@ -40,6 +40,11 @@ import io.reactivex.functions.Consumer
import io.reactivex.functions.Function import io.reactivex.functions.Function
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.io.IOException
import java.util.Calendar
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import org.reactivestreams.Subscriber import org.reactivestreams.Subscriber
import org.reactivestreams.Subscription import org.reactivestreams.Subscription
import org.schabi.newpipe.MainActivity.DEBUG import org.schabi.newpipe.MainActivity.DEBUG
@ -49,17 +54,14 @@ import org.schabi.newpipe.extractor.ListInfo
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException import org.schabi.newpipe.extractor.exceptions.ReCaptchaException
import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamInfoItem
import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.local.feed.FeedDatabaseManager
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.* import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ErrorResultEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.IdleEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ProgressEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.SuccessResultEvent
import org.schabi.newpipe.local.feed.service.FeedEventManager.postEvent import org.schabi.newpipe.local.feed.service.FeedEventManager.postEvent
import org.schabi.newpipe.local.subscription.SubscriptionManager import org.schabi.newpipe.local.subscription.SubscriptionManager
import org.schabi.newpipe.util.ExceptionUtils import org.schabi.newpipe.util.ExceptionUtils
import org.schabi.newpipe.util.ExtractorHelper import org.schabi.newpipe.util.ExtractorHelper
import java.io.IOException
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import kotlin.collections.ArrayList
class FeedLoadService : Service() { class FeedLoadService : Service() {
companion object { companion object {
@ -94,9 +96,9 @@ class FeedLoadService : Service() {
private var disposables = CompositeDisposable() private var disposables = CompositeDisposable()
private var notificationUpdater = PublishProcessor.create<String>() private var notificationUpdater = PublishProcessor.create<String>()
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Lifecycle // Lifecycle
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
@ -151,9 +153,9 @@ class FeedLoadService : Service() {
return null return null
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Loading & Handling // Loading & Handling
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
private class RequestException(val subscriptionId: Long, message: String, cause: Throwable) : Exception(message, cause) { private class RequestException(val subscriptionId: Long, message: String, cause: Throwable) : Exception(message, cause) {
companion object { companion object {
@ -312,7 +314,6 @@ class FeedLoadService : Service() {
feedResultsHolder.addErrors(RequestException.wrapList(subscriptionId, info)) feedResultsHolder.addErrors(RequestException.wrapList(subscriptionId, info))
feedDatabaseManager.markAsOutdated(subscriptionId) feedDatabaseManager.markAsOutdated(subscriptionId)
} }
} else if (notification.isOnError) { } else if (notification.isOnError) {
val error = notification.error!! val error = notification.error!!
feedResultsHolder.addError(error) feedResultsHolder.addError(error)
@ -325,7 +326,6 @@ class FeedLoadService : Service() {
} }
} }
private val errorHandlingConsumer: Consumer<Notification<Pair<Long, ListInfo<StreamInfoItem>>>> private val errorHandlingConsumer: Consumer<Notification<Pair<Long, ListInfo<StreamInfoItem>>>>
get() = Consumer { get() = Consumer {
if (it.isOnError) { if (it.isOnError) {
@ -354,9 +354,9 @@ class FeedLoadService : Service() {
broadcastProgress() broadcastProgress()
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Notification // Notification
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
private lateinit var notificationManager: NotificationManagerCompat private lateinit var notificationManager: NotificationManagerCompat
private lateinit var notificationBuilder: NotificationCompat.Builder private lateinit var notificationBuilder: NotificationCompat.Builder
@ -412,9 +412,9 @@ class FeedLoadService : Service() {
notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()) notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build())
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Notification Actions // Notification Actions
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
private lateinit var broadcastReceiver: BroadcastReceiver private lateinit var broadcastReceiver: BroadcastReceiver
private val cancelSignal = AtomicBoolean() private val cancelSignal = AtomicBoolean()
@ -430,18 +430,18 @@ class FeedLoadService : Service() {
registerReceiver(broadcastReceiver, IntentFilter(ACTION_CANCEL)) registerReceiver(broadcastReceiver, IntentFilter(ACTION_CANCEL))
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Error handling // Error handling
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
private fun handleError(error: Throwable) { private fun handleError(error: Throwable) {
postEvent(ErrorResultEvent(error)) postEvent(ErrorResultEvent(error))
stopService() stopService()
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Results Holder // Results Holder
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
class ResultsHolder { class ResultsHolder {
/** /**

View file

@ -2,13 +2,21 @@ package org.schabi.newpipe.local.subscription
import android.app.Activity import android.app.Activity
import android.app.AlertDialog import android.app.AlertDialog
import android.content.* import android.content.BroadcastReceiver
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.IntentFilter
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.os.Parcelable import android.os.Parcelable
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.view.* import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
@ -21,8 +29,15 @@ import com.xwray.groupie.Section
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import icepick.State import icepick.State
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.dialog_title.view.* import java.io.File
import kotlinx.android.synthetic.main.fragment_subscription.* import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlin.math.floor
import kotlin.math.max
import kotlinx.android.synthetic.main.dialog_title.view.itemAdditionalDetails
import kotlinx.android.synthetic.main.dialog_title.view.itemTitleView
import kotlinx.android.synthetic.main.fragment_subscription.items_list
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.extractor.channel.ChannelInfoItem import org.schabi.newpipe.extractor.channel.ChannelInfoItem
@ -30,21 +45,29 @@ import org.schabi.newpipe.fragments.BaseStateFragment
import org.schabi.newpipe.local.subscription.SubscriptionViewModel.SubscriptionState import org.schabi.newpipe.local.subscription.SubscriptionViewModel.SubscriptionState
import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialog import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialog
import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialog import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialog
import org.schabi.newpipe.local.subscription.item.* import org.schabi.newpipe.local.subscription.item.ChannelItem
import org.schabi.newpipe.local.subscription.item.EmptyPlaceholderItem
import org.schabi.newpipe.local.subscription.item.FeedGroupAddItem
import org.schabi.newpipe.local.subscription.item.FeedGroupCardItem
import org.schabi.newpipe.local.subscription.item.FeedGroupCarouselItem
import org.schabi.newpipe.local.subscription.item.FeedImportExportItem
import org.schabi.newpipe.local.subscription.item.HeaderWithMenuItem
import org.schabi.newpipe.local.subscription.item.HeaderWithMenuItem.Companion.PAYLOAD_UPDATE_VISIBILITY_MENU_ITEM import org.schabi.newpipe.local.subscription.item.HeaderWithMenuItem.Companion.PAYLOAD_UPDATE_VISIBILITY_MENU_ITEM
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService.EXPORT_COMPLETE_ACTION import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService.EXPORT_COMPLETE_ACTION
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService.KEY_FILE_PATH import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService.KEY_FILE_PATH
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.* import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.IMPORT_COMPLETE_ACTION
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.report.UserAction import org.schabi.newpipe.report.UserAction
import org.schabi.newpipe.util.*
import org.schabi.newpipe.util.AnimationUtils.animateView import org.schabi.newpipe.util.AnimationUtils.animateView
import java.io.File import org.schabi.newpipe.util.FilePickerActivityHelper
import java.text.SimpleDateFormat import org.schabi.newpipe.util.NavigationHelper
import java.util.* import org.schabi.newpipe.util.OnClickGesture
import kotlin.math.floor import org.schabi.newpipe.util.ShareUtils
import kotlin.math.max import org.schabi.newpipe.util.ThemeHelper
class SubscriptionFragment : BaseStateFragment<SubscriptionState>() { class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
private lateinit var viewModel: SubscriptionViewModel private lateinit var viewModel: SubscriptionViewModel
@ -74,9 +97,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
setHasOptionsMenu(true) setHasOptionsMenu(true)
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Fragment LifeCycle // Fragment LifeCycle
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -120,9 +143,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
disposables.dispose() disposables.dispose()
} }
////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
// Menu // Menu
////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
@ -150,7 +173,6 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
importExportItem.isExpanded = false importExportItem.isExpanded = false
importExportItem.notifyChanged(FeedImportExportItem.REFRESH_EXPANDED_STATUS) importExportItem.notifyChanged(FeedImportExportItem.REFRESH_EXPANDED_STATUS)
} }
} }
} }
@ -198,9 +220,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
} }
} }
////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
// Fragment Views // Fragment Views
////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
private fun setupInitialLayout() { private fun setupInitialLayout() {
Section().apply { Section().apply {
@ -243,7 +265,6 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
{ onExportSelected() }, { onExportSelected() },
importExportItemExpandedState ?: false) importExportItemExpandedState ?: false)
groupAdapter.add(Section(importExportItem, listOf(subscriptionsSection))) groupAdapter.add(Section(importExportItem, listOf(subscriptionsSection)))
} }
override fun initViews(rootView: View, savedInstanceState: Bundle?) { override fun initViews(rootView: View, savedInstanceState: Bundle?) {
@ -366,9 +387,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
items_list.post { feedGroupsSortMenuItem.notifyChanged(PAYLOAD_UPDATE_VISIBILITY_MENU_ITEM) } items_list.post { feedGroupsSortMenuItem.notifyChanged(PAYLOAD_UPDATE_VISIBILITY_MENU_ITEM) }
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Contract // Contract
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
override fun showLoading() { override fun showLoading() {
super.showLoading() super.showLoading()
@ -380,9 +401,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
animateView(items_list, true, 200) animateView(items_list, true, 200)
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Fragment Error Handling // Fragment Error Handling
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
override fun onError(exception: Throwable): Boolean { override fun onError(exception: Throwable): Boolean {
if (super.onError(exception)) return true if (super.onError(exception)) return true
@ -391,9 +412,9 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
return true return true
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Grid Mode // Grid Mode
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// TODO: Move these out of this class, as it can be reused // TODO: Move these out of this class, as it can be reused
@ -405,8 +426,8 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
getString(R.string.list_view_mode_auto_key) -> { getString(R.string.list_view_mode_auto_key) -> {
val configuration = resources.configuration val configuration = resources.configuration
(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&
&& configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE)) configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE))
} }
getString(R.string.list_view_mode_grid_key) -> true getString(R.string.list_view_mode_grid_key) -> true
else -> false else -> false

View file

@ -6,11 +6,11 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.xwray.groupie.Group import com.xwray.groupie.Group
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit
import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.local.feed.FeedDatabaseManager
import org.schabi.newpipe.local.subscription.item.ChannelItem import org.schabi.newpipe.local.subscription.item.ChannelItem
import org.schabi.newpipe.local.subscription.item.FeedGroupCardItem import org.schabi.newpipe.local.subscription.item.FeedGroupCardItem
import org.schabi.newpipe.util.DEFAULT_THROTTLE_TIMEOUT import org.schabi.newpipe.util.DEFAULT_THROTTLE_TIMEOUT
import java.util.concurrent.TimeUnit
class SubscriptionViewModel(application: Application) : AndroidViewModel(application) { class SubscriptionViewModel(application: Application) : AndroidViewModel(application) {
private var feedDatabaseManager: FeedDatabaseManager = FeedDatabaseManager(application) private var feedDatabaseManager: FeedDatabaseManager = FeedDatabaseManager(application)

View file

@ -22,19 +22,36 @@ import com.xwray.groupie.Section
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import icepick.Icepick import icepick.Icepick
import icepick.State import icepick.State
import kotlinx.android.synthetic.main.dialog_feed_group_create.* import java.io.Serializable
import kotlinx.android.synthetic.main.dialog_feed_group_create.cancel_button
import kotlinx.android.synthetic.main.dialog_feed_group_create.confirm_button
import kotlinx.android.synthetic.main.dialog_feed_group_create.delete_button
import kotlinx.android.synthetic.main.dialog_feed_group_create.delete_screen_message
import kotlinx.android.synthetic.main.dialog_feed_group_create.group_name_input
import kotlinx.android.synthetic.main.dialog_feed_group_create.group_name_input_container
import kotlinx.android.synthetic.main.dialog_feed_group_create.icon_preview
import kotlinx.android.synthetic.main.dialog_feed_group_create.icon_selector
import kotlinx.android.synthetic.main.dialog_feed_group_create.options_root
import kotlinx.android.synthetic.main.dialog_feed_group_create.select_channel_button
import kotlinx.android.synthetic.main.dialog_feed_group_create.selected_subscription_count_view
import kotlinx.android.synthetic.main.dialog_feed_group_create.separator
import kotlinx.android.synthetic.main.dialog_feed_group_create.subscriptions_selector
import kotlinx.android.synthetic.main.dialog_feed_group_create.subscriptions_selector_header_info
import kotlinx.android.synthetic.main.dialog_feed_group_create.subscriptions_selector_list
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.database.subscription.SubscriptionEntity
import org.schabi.newpipe.local.subscription.FeedGroupIcon import org.schabi.newpipe.local.subscription.FeedGroupIcon
import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialog.ScreenState.* import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialog.ScreenState.DeleteScreen
import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialog.ScreenState.IconPickerScreen
import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialog.ScreenState.InitialScreen
import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialog.ScreenState.SubscriptionsPickerScreen
import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialogViewModel.DialogEvent.ProcessingEvent import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialogViewModel.DialogEvent.ProcessingEvent
import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialogViewModel.DialogEvent.SuccessEvent import org.schabi.newpipe.local.subscription.dialog.FeedGroupDialogViewModel.DialogEvent.SuccessEvent
import org.schabi.newpipe.local.subscription.item.EmptyPlaceholderItem import org.schabi.newpipe.local.subscription.item.EmptyPlaceholderItem
import org.schabi.newpipe.local.subscription.item.PickerIconItem import org.schabi.newpipe.local.subscription.item.PickerIconItem
import org.schabi.newpipe.local.subscription.item.PickerSubscriptionItem import org.schabi.newpipe.local.subscription.item.PickerSubscriptionItem
import org.schabi.newpipe.util.ThemeHelper import org.schabi.newpipe.util.ThemeHelper
import java.io.Serializable
class FeedGroupDialog : DialogFragment() { class FeedGroupDialog : DialogFragment() {
private lateinit var viewModel: FeedGroupDialogViewModel private lateinit var viewModel: FeedGroupDialogViewModel
@ -120,9 +137,9 @@ class FeedGroupDialog : DialogFragment() {
showScreen(currentScreen) showScreen(currentScreen)
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Setup // Setup
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
private fun setupListeners() { private fun setupListeners() {
delete_button.setOnClickListener { showScreen(DeleteScreen) } delete_button.setOnClickListener { showScreen(DeleteScreen) }
@ -294,9 +311,9 @@ class FeedGroupDialog : DialogFragment() {
} }
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Screen Selector // Screen Selector
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
private fun showScreen(screen: ScreenState) { private fun showScreen(screen: ScreenState) {
currentScreen = screen currentScreen = screen
@ -330,9 +347,9 @@ class FeedGroupDialog : DialogFragment() {
} }
} }
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
// Utils // Utils
/////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
private fun hideKeyboard() { private fun hideKeyboard() {
val inputMethodManager = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager val inputMethodManager = requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

View file

@ -16,7 +16,6 @@ import org.schabi.newpipe.local.feed.FeedDatabaseManager
import org.schabi.newpipe.local.subscription.FeedGroupIcon import org.schabi.newpipe.local.subscription.FeedGroupIcon
import org.schabi.newpipe.local.subscription.SubscriptionManager import org.schabi.newpipe.local.subscription.SubscriptionManager
class FeedGroupDialogViewModel(applicationContext: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModel() { class FeedGroupDialogViewModel(applicationContext: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModel() {
class Factory(val context: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModelProvider.Factory { class Factory(val context: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")

View file

@ -16,15 +16,15 @@ import com.xwray.groupie.TouchCallback
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import icepick.Icepick import icepick.Icepick
import icepick.State import icepick.State
import kotlinx.android.synthetic.main.dialog_feed_group_reorder.* import java.util.Collections
import kotlinx.android.synthetic.main.dialog_feed_group_reorder.confirm_button
import kotlinx.android.synthetic.main.dialog_feed_group_reorder.feed_groups_list
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialogViewModel.DialogEvent.ProcessingEvent import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialogViewModel.DialogEvent.ProcessingEvent
import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialogViewModel.DialogEvent.SuccessEvent import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialogViewModel.DialogEvent.SuccessEvent
import org.schabi.newpipe.local.subscription.item.FeedGroupReorderItem import org.schabi.newpipe.local.subscription.item.FeedGroupReorderItem
import org.schabi.newpipe.util.ThemeHelper import org.schabi.newpipe.util.ThemeHelper
import java.util.*
import kotlin.collections.ArrayList
class FeedGroupReorderDialog : DialogFragment() { class FeedGroupReorderDialog : DialogFragment() {
private lateinit var viewModel: FeedGroupReorderDialogViewModel private lateinit var viewModel: FeedGroupReorderDialogViewModel
@ -93,8 +93,11 @@ class FeedGroupReorderDialog : DialogFragment() {
private fun getItemTouchCallback(): SimpleCallback { private fun getItemTouchCallback(): SimpleCallback {
return object : TouchCallback() { return object : TouchCallback() {
override fun onMove(recyclerView: RecyclerView, source: RecyclerView.ViewHolder, override fun onMove(
target: RecyclerView.ViewHolder): Boolean { recyclerView: RecyclerView,
source: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
val sourceIndex = source.adapterPosition val sourceIndex = source.adapterPosition
val targetIndex = target.adapterPosition val targetIndex = target.adapterPosition

View file

@ -4,14 +4,16 @@ import android.content.Context
import com.nostra13.universalimageloader.core.ImageLoader import com.nostra13.universalimageloader.core.ImageLoader
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import com.xwray.groupie.kotlinandroidextensions.Item import com.xwray.groupie.kotlinandroidextensions.Item
import kotlinx.android.synthetic.main.list_channel_item.* import kotlinx.android.synthetic.main.list_channel_item.itemAdditionalDetails
import kotlinx.android.synthetic.main.list_channel_item.itemChannelDescriptionView
import kotlinx.android.synthetic.main.list_channel_item.itemThumbnailView
import kotlinx.android.synthetic.main.list_channel_item.itemTitleView
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.channel.ChannelInfoItem import org.schabi.newpipe.extractor.channel.ChannelInfoItem
import org.schabi.newpipe.util.ImageDisplayConstants import org.schabi.newpipe.util.ImageDisplayConstants
import org.schabi.newpipe.util.Localization import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.OnClickGesture import org.schabi.newpipe.util.OnClickGesture
class ChannelItem( class ChannelItem(
private val infoItem: ChannelInfoItem, private val infoItem: ChannelInfoItem,
private val subscriptionId: Long = -1L, private val subscriptionId: Long = -1L,

View file

@ -2,7 +2,8 @@ package org.schabi.newpipe.local.subscription.item
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import com.xwray.groupie.kotlinandroidextensions.Item import com.xwray.groupie.kotlinandroidextensions.Item
import kotlinx.android.synthetic.main.feed_group_card_item.* import kotlinx.android.synthetic.main.feed_group_card_item.icon
import kotlinx.android.synthetic.main.feed_group_card_item.title
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.local.subscription.FeedGroupIcon import org.schabi.newpipe.local.subscription.FeedGroupIcon

View file

@ -8,7 +8,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.xwray.groupie.GroupAdapter import com.xwray.groupie.GroupAdapter
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import com.xwray.groupie.kotlinandroidextensions.Item import com.xwray.groupie.kotlinandroidextensions.Item
import kotlinx.android.synthetic.main.feed_item_carousel.* import kotlinx.android.synthetic.main.feed_item_carousel.recycler_view
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.local.subscription.decoration.FeedGroupCarouselDecoration import org.schabi.newpipe.local.subscription.decoration.FeedGroupCarouselDecoration

View file

@ -6,7 +6,9 @@ import androidx.recyclerview.widget.ItemTouchHelper.DOWN
import androidx.recyclerview.widget.ItemTouchHelper.UP import androidx.recyclerview.widget.ItemTouchHelper.UP
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import com.xwray.groupie.kotlinandroidextensions.Item import com.xwray.groupie.kotlinandroidextensions.Item
import kotlinx.android.synthetic.main.feed_group_reorder_item.* import kotlinx.android.synthetic.main.feed_group_reorder_item.group_icon
import kotlinx.android.synthetic.main.feed_group_reorder_item.group_name
import kotlinx.android.synthetic.main.feed_group_reorder_item.handle
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.local.subscription.FeedGroupIcon import org.schabi.newpipe.local.subscription.FeedGroupIcon
@ -17,8 +19,8 @@ data class FeedGroupReorderItem(
val icon: FeedGroupIcon, val icon: FeedGroupIcon,
val dragCallback: ItemTouchHelper val dragCallback: ItemTouchHelper
) : Item() { ) : Item() {
constructor (feedGroupEntity: FeedGroupEntity, dragCallback: ItemTouchHelper) constructor (feedGroupEntity: FeedGroupEntity, dragCallback: ItemTouchHelper) :
: this(feedGroupEntity.uid, feedGroupEntity.name, feedGroupEntity.icon, dragCallback) this(feedGroupEntity.uid, feedGroupEntity.name, feedGroupEntity.icon, dragCallback)
override fun getId(): Long { override fun getId(): Long {
return when (groupId) { return when (groupId) {

View file

@ -9,7 +9,11 @@ import android.widget.TextView
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import com.xwray.groupie.kotlinandroidextensions.Item import com.xwray.groupie.kotlinandroidextensions.Item
import kotlinx.android.synthetic.main.feed_import_export_group.* import kotlinx.android.synthetic.main.feed_import_export_group.export_to_options
import kotlinx.android.synthetic.main.feed_import_export_group.import_export
import kotlinx.android.synthetic.main.feed_import_export_group.import_export_expand_icon
import kotlinx.android.synthetic.main.feed_import_export_group.import_export_options
import kotlinx.android.synthetic.main.feed_import_export_group.import_from_options
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.NewPipe import org.schabi.newpipe.extractor.NewPipe
import org.schabi.newpipe.extractor.exceptions.ExtractionException import org.schabi.newpipe.extractor.exceptions.ExtractionException
@ -104,7 +108,6 @@ class FeedImportExportItem(
} catch (e: ExtractionException) { } catch (e: ExtractionException) {
throw RuntimeException("Services array contains an entry that it's not a valid service name ($serviceName)", e) throw RuntimeException("Services array contains an entry that it's not a valid service name ($serviceName)", e)
} }
} }
} }

View file

@ -3,7 +3,7 @@ package org.schabi.newpipe.local.subscription.item
import android.view.View.OnClickListener import android.view.View.OnClickListener
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import com.xwray.groupie.kotlinandroidextensions.Item import com.xwray.groupie.kotlinandroidextensions.Item
import kotlinx.android.synthetic.main.header_item.* import kotlinx.android.synthetic.main.header_item.header_title
import org.schabi.newpipe.R import org.schabi.newpipe.R
class HeaderItem(val title: String, private val onClickListener: (() -> Unit)? = null) : Item() { class HeaderItem(val title: String, private val onClickListener: (() -> Unit)? = null) : Item() {

View file

@ -1,10 +1,13 @@
package org.schabi.newpipe.local.subscription.item package org.schabi.newpipe.local.subscription.item
import android.view.View.* import android.view.View.GONE
import android.view.View.OnClickListener
import android.view.View.VISIBLE
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import com.xwray.groupie.kotlinandroidextensions.Item import com.xwray.groupie.kotlinandroidextensions.Item
import kotlinx.android.synthetic.main.header_with_menu_item.* import kotlinx.android.synthetic.main.header_with_menu_item.header_menu_item
import kotlinx.android.synthetic.main.header_with_menu_item.header_title
import org.schabi.newpipe.R import org.schabi.newpipe.R
class HeaderWithMenuItem( class HeaderWithMenuItem(

View file

@ -4,7 +4,7 @@ import android.content.Context
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import com.xwray.groupie.kotlinandroidextensions.Item import com.xwray.groupie.kotlinandroidextensions.Item
import kotlinx.android.synthetic.main.picker_icon_item.* import kotlinx.android.synthetic.main.picker_icon_item.icon_view
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.local.subscription.FeedGroupIcon import org.schabi.newpipe.local.subscription.FeedGroupIcon

View file

@ -5,7 +5,9 @@ import com.nostra13.universalimageloader.core.DisplayImageOptions
import com.nostra13.universalimageloader.core.ImageLoader import com.nostra13.universalimageloader.core.ImageLoader
import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
import com.xwray.groupie.kotlinandroidextensions.Item import com.xwray.groupie.kotlinandroidextensions.Item
import kotlinx.android.synthetic.main.picker_subscription_item.* import kotlinx.android.synthetic.main.picker_subscription_item.selected_highlight
import kotlinx.android.synthetic.main.picker_subscription_item.thumbnail_view
import kotlinx.android.synthetic.main.picker_subscription_item.title_view
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.subscription.SubscriptionEntity import org.schabi.newpipe.database.subscription.SubscriptionEntity
import org.schabi.newpipe.util.AnimationUtils import org.schabi.newpipe.util.AnimationUtils

View file

@ -80,8 +80,8 @@ import org.schabi.newpipe.player.playqueue.PlayQueueItemHolder;
import org.schabi.newpipe.player.playqueue.PlayQueueItemTouchCallback; import org.schabi.newpipe.player.playqueue.PlayQueueItemTouchCallback;
import org.schabi.newpipe.player.resolver.MediaSourceTag; import org.schabi.newpipe.player.resolver.MediaSourceTag;
import org.schabi.newpipe.player.resolver.VideoPlaybackResolver; import org.schabi.newpipe.player.resolver.VideoPlaybackResolver;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.AndroidTvUtils; import org.schabi.newpipe.util.AndroidTvUtils;
import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.KoreUtil; import org.schabi.newpipe.util.KoreUtil;
import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;

View file

@ -5,8 +5,8 @@ import org.schabi.newpipe.streams.Mp4DashReader.Mdia;
import org.schabi.newpipe.streams.Mp4DashReader.Mp4DashChunk; import org.schabi.newpipe.streams.Mp4DashReader.Mp4DashChunk;
import org.schabi.newpipe.streams.Mp4DashReader.Mp4DashSample; import org.schabi.newpipe.streams.Mp4DashReader.Mp4DashSample;
import org.schabi.newpipe.streams.Mp4DashReader.Mp4Track; import org.schabi.newpipe.streams.Mp4DashReader.Mp4Track;
import org.schabi.newpipe.streams.Mp4DashReader.TrunEntry;
import org.schabi.newpipe.streams.Mp4DashReader.TrackKind; import org.schabi.newpipe.streams.Mp4DashReader.TrackKind;
import org.schabi.newpipe.streams.Mp4DashReader.TrunEntry;
import org.schabi.newpipe.streams.io.SharpStream; import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException; import java.io.IOException;

View file

@ -25,6 +25,7 @@ import android.view.ViewTreeObserver;
import android.widget.SeekBar; import android.widget.SeekBar;
import androidx.appcompat.widget.AppCompatSeekBar; import androidx.appcompat.widget.AppCompatSeekBar;
import org.schabi.newpipe.util.AndroidTvUtils; import org.schabi.newpipe.util.AndroidTvUtils;
/** /**

View file

@ -6,8 +6,8 @@ import android.system.ErrnoException;
import android.system.OsConstants; import android.system.OsConstants;
import android.util.Log; import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.schabi.newpipe.DownloaderImpl; import org.schabi.newpipe.DownloaderImpl;

View file

@ -6,9 +6,10 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.NonNull;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -3,9 +3,10 @@ package us.shandian.giga.io;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.net.Uri; import android.net.Uri;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import androidx.annotation.NonNull;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import org.schabi.newpipe.streams.io.SharpStream; import org.schabi.newpipe.streams.io.SharpStream;
import java.io.FileInputStream; import java.io.FileInputStream;

View file

@ -8,6 +8,7 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.DocumentsContract; import android.provider.DocumentsContract;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;

View file

@ -7,10 +7,11 @@ import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.DocumentsContract; import android.provider.DocumentsContract;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.Fragment;
import org.schabi.newpipe.streams.io.SharpStream; import org.schabi.newpipe.streams.io.SharpStream;

View file

@ -1,6 +1,7 @@
package us.shandian.giga.ui.common; package us.shandian.giga.ui.common;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;

View file

@ -17,7 +17,6 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:tools="http://schemas.android.com/tools">
<item <item
android:id="@+id/menu_item_remove_watched" android:id="@+id/menu_item_remove_watched"

View file

@ -1,14 +1,14 @@
package org.schabi.newpipe.util package org.schabi.newpipe.util
import java.io.IOException
import java.io.InterruptedIOException
import java.net.SocketException
import javax.net.ssl.SSLException
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import org.schabi.newpipe.util.ExceptionUtils.Companion.hasAssignableCause import org.schabi.newpipe.util.ExceptionUtils.Companion.hasAssignableCause
import org.schabi.newpipe.util.ExceptionUtils.Companion.hasExactCause import org.schabi.newpipe.util.ExceptionUtils.Companion.hasExactCause
import java.io.IOException
import java.io.InterruptedIOException
import java.net.SocketException
import javax.net.ssl.SSLException
class ExceptionUtilsTest { class ExceptionUtilsTest {
@Test fun `assignable causes`() { @Test fun `assignable causes`() {