Issue#12 Add UserPreferences to always open the app when saving a video

This commit is contained in:
Gergely Hegedus 2022-09-19 21:52:37 +03:00
parent eda8b95c89
commit 6b849b06bd
22 changed files with 255 additions and 11 deletions

View file

@ -21,7 +21,7 @@ android {
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 31 targetSdkVersion 31
versionCode 1 versionCode 1
versionName "1.0.0" versionName "1.3.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@ -43,7 +43,7 @@ android {
} }
release { release {
signingConfig signingConfigs.release signingConfig signingConfigs.release
debuggable false debuggable true
shrinkResources true shrinkResources true
minifyEnabled true minifyEnabled true
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"

View file

@ -0,0 +1,24 @@
package org.fnives.tiktokdownloader.data.local
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.map
import org.fnives.tiktokdownloader.data.local.persistent.UserPreferencesStorage
import org.fnives.tiktokdownloader.data.model.UserPreferences
class UserPreferencesLocalSource(private val userPreferencesStorage: UserPreferencesStorage) {
private val signal = MutableSharedFlow<Unit>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST).apply { tryEmit(Unit) }
fun get(): Flow<UserPreferences> = signal
.map { getSync() }
fun getSync() = UserPreferences(alwaysOpenApp = userPreferencesStorage.openAppToIntent)
suspend fun set(userPreferences: UserPreferences) {
if (userPreferences.alwaysOpenApp == userPreferencesStorage.openAppToIntent) return
userPreferencesStorage.openAppToIntent = userPreferences.alwaysOpenApp
signal.emit(Unit)
}
}

View file

@ -9,13 +9,14 @@ import kotlin.properties.ReadOnlyProperty
import kotlin.properties.ReadWriteProperty import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
class SharedPreferencesManagerImpl private constructor(private val sharedPreferences: SharedPreferences) : SharedPreferencesManager { class SharedPreferencesManagerImpl private constructor(private val sharedPreferences: SharedPreferences) : SharedPreferencesManager, UserPreferencesStorage {
override var captchaTimeoutUntil: Long by LongDelegate(CAPTCHA_TIMEOUT_KEY) override var captchaTimeoutUntil: Long by LongDelegate(CAPTCHA_TIMEOUT_KEY)
override var pendingVideos: Set<String> by StringSetDelegate(PENDING_VIDEO_KEY) override var pendingVideos: Set<String> by StringSetDelegate(PENDING_VIDEO_KEY)
override val pendingVideosFlow by StringSetFlowDelegate(PENDING_VIDEO_KEY) override val pendingVideosFlow by StringSetFlowDelegate(PENDING_VIDEO_KEY)
override var downloadedVideos: Set<String> by StringSetDelegate(DOWNLOADED_VIDEO_KEY) override var downloadedVideos: Set<String> by StringSetDelegate(DOWNLOADED_VIDEO_KEY)
override val downloadedVideosFlow by StringSetFlowDelegate(DOWNLOADED_VIDEO_KEY) override val downloadedVideosFlow by StringSetFlowDelegate(DOWNLOADED_VIDEO_KEY)
override var openAppToIntent: Boolean by BooleanDelegate(USER_PREFERENCE_ALWAYS_OPEN_APP)
class LongDelegate(private val key: String) : ReadWriteProperty<SharedPreferencesManagerImpl, Long> { class LongDelegate(private val key: String) : ReadWriteProperty<SharedPreferencesManagerImpl, Long> {
override fun setValue(thisRef: SharedPreferencesManagerImpl, property: KProperty<*>, value: Long) { override fun setValue(thisRef: SharedPreferencesManagerImpl, property: KProperty<*>, value: Long) {
@ -26,6 +27,15 @@ class SharedPreferencesManagerImpl private constructor(private val sharedPrefere
thisRef.sharedPreferences.getLong(key, 0) thisRef.sharedPreferences.getLong(key, 0)
} }
class BooleanDelegate(private val key: String) : ReadWriteProperty<SharedPreferencesManagerImpl, Boolean> {
override fun setValue(thisRef: SharedPreferencesManagerImpl, property: KProperty<*>, value: Boolean) {
thisRef.sharedPreferences.edit().putBoolean(key, value).apply()
}
override fun getValue(thisRef: SharedPreferencesManagerImpl, property: KProperty<*>): Boolean =
thisRef.sharedPreferences.getBoolean(key, false)
}
class StringSetDelegate(private val key: String) : ReadWriteProperty<SharedPreferencesManagerImpl, Set<String>> { class StringSetDelegate(private val key: String) : ReadWriteProperty<SharedPreferencesManagerImpl, Set<String>> {
override fun setValue(thisRef: SharedPreferencesManagerImpl, property: KProperty<*>, value: Set<String>) { override fun setValue(thisRef: SharedPreferencesManagerImpl, property: KProperty<*>, value: Set<String>) {
thisRef.sharedPreferences.edit().putStringSet(key, value).apply() thisRef.sharedPreferences.edit().putStringSet(key, value).apply()
@ -60,6 +70,7 @@ class SharedPreferencesManagerImpl private constructor(private val sharedPrefere
private const val CAPTCHA_TIMEOUT_KEY = "CAPTCHA_TIMEOUT_KEY" private const val CAPTCHA_TIMEOUT_KEY = "CAPTCHA_TIMEOUT_KEY"
private const val PENDING_VIDEO_KEY = "PENDING_VIDEO_KEY" private const val PENDING_VIDEO_KEY = "PENDING_VIDEO_KEY"
private const val DOWNLOADED_VIDEO_KEY = "DOWNLOADED_VIDEO_KEY" private const val DOWNLOADED_VIDEO_KEY = "DOWNLOADED_VIDEO_KEY"
private const val USER_PREFERENCE_ALWAYS_OPEN_APP = "USER_PREFERENCE_ALWAYS_OPEN_APP"
fun create(context: Context): SharedPreferencesManagerImpl = fun create(context: Context): SharedPreferencesManagerImpl =
SharedPreferencesManagerImpl( SharedPreferencesManagerImpl(

View file

@ -0,0 +1,6 @@
package org.fnives.tiktokdownloader.data.local.persistent
interface UserPreferencesStorage {
var openAppToIntent: Boolean
}

View file

@ -0,0 +1,3 @@
package org.fnives.tiktokdownloader.data.model
data class UserPreferences(val alwaysOpenApp: Boolean)

View file

@ -0,0 +1,9 @@
package org.fnives.tiktokdownloader.data.usecase
import org.fnives.tiktokdownloader.data.local.UserPreferencesLocalSource
import org.fnives.tiktokdownloader.data.model.UserPreferences
class GetUserPreferences(private val userPreferencesLocalSource: UserPreferencesLocalSource) {
operator fun invoke(): UserPreferences = userPreferencesLocalSource.getSync()
}

View file

@ -0,0 +1,10 @@
package org.fnives.tiktokdownloader.data.usecase
import kotlinx.coroutines.flow.Flow
import org.fnives.tiktokdownloader.data.local.UserPreferencesLocalSource
import org.fnives.tiktokdownloader.data.model.UserPreferences
class ObserveUserPreferences(private val userPreferencesLocalSource: UserPreferencesLocalSource) {
operator fun invoke(): Flow<UserPreferences> = userPreferencesLocalSource.get()
}

View file

@ -0,0 +1,11 @@
package org.fnives.tiktokdownloader.data.usecase
import org.fnives.tiktokdownloader.data.local.UserPreferencesLocalSource
import org.fnives.tiktokdownloader.data.model.UserPreferences
class SetUserPreferences(private val userPreferencesLocalSource: UserPreferencesLocalSource) {
suspend operator fun invoke(userPreferences: UserPreferences) {
userPreferencesLocalSource.set(userPreferences)
}
}

View file

@ -25,6 +25,10 @@ object ServiceLocator {
val permissionModule: PermissionModule val permissionModule: PermissionModule
get() = _permissionModule ?: throw IllegalStateException("$this.start has not been called!") get() = _permissionModule ?: throw IllegalStateException("$this.start has not been called!")
private var _useCaseModule: UseCaseModule? = null
val useCaseModule: UseCaseModule
get() = _useCaseModule ?: throw IllegalStateException("$this.start has not been called!")
fun viewModelFactory( fun viewModelFactory(
savedStateRegistryOwner: SavedStateRegistryOwner, savedStateRegistryOwner: SavedStateRegistryOwner,
defaultArgs: Bundle defaultArgs: Bundle
@ -36,9 +40,13 @@ object ServiceLocator {
fun start(context: Context) { fun start(context: Context) {
val androidFileManagementModule = AndroidFileManagementModule(context) val androidFileManagementModule = AndroidFileManagementModule(context)
val localSourceModule = LocalSourceModule(androidFileManagementModule) val localSourceModule = LocalSourceModule(androidFileManagementModule = androidFileManagementModule)
val networkModule = NetworkModule(DEFAULT_DELAY_BEFORE_REQUEST) val networkModule = NetworkModule(delayBeforeRequest = DEFAULT_DELAY_BEFORE_REQUEST)
val useCaseModule = UseCaseModule(localSourceModule, networkModule) val useCaseModule = UseCaseModule(
localSourceModule = localSourceModule,
networkModule = networkModule
)
_useCaseModule = useCaseModule
_permissionModule = PermissionModule() _permissionModule = PermissionModule()
_viewModelModule = ViewModelModule(useCaseModule) _viewModelModule = ViewModelModule(useCaseModule)
} }

View file

@ -8,6 +8,7 @@ import androidx.savedstate.SavedStateRegistryOwner
import org.fnives.tiktokdownloader.di.module.ViewModelModule import org.fnives.tiktokdownloader.di.module.ViewModelModule
import org.fnives.tiktokdownloader.ui.main.MainViewModel import org.fnives.tiktokdownloader.ui.main.MainViewModel
import org.fnives.tiktokdownloader.ui.main.queue.QueueViewModel import org.fnives.tiktokdownloader.ui.main.queue.QueueViewModel
import org.fnives.tiktokdownloader.ui.main.settings.SettingsViewModel
class ViewModelFactory( class ViewModelFactory(
savedStateRegistryOwner: SavedStateRegistryOwner, savedStateRegistryOwner: SavedStateRegistryOwner,
@ -20,6 +21,7 @@ class ViewModelFactory(
val viewModel = when (modelClass) { val viewModel = when (modelClass) {
MainViewModel::class.java -> viewModelModule.mainViewModel(handle) MainViewModel::class.java -> viewModelModule.mainViewModel(handle)
QueueViewModel::class.java -> viewModelModule.queueViewModel QueueViewModel::class.java -> viewModelModule.queueViewModel
SettingsViewModel::class.java -> viewModelModule.settignsViewModel
else -> throw IllegalArgumentException("Can't create viewModel for $modelClass ") else -> throw IllegalArgumentException("Can't create viewModel for $modelClass ")
} }
return viewModel as T return viewModel as T

View file

@ -4,10 +4,10 @@ import android.content.ContentResolver
import android.content.Context import android.content.Context
import org.fnives.tiktokdownloader.data.local.persistent.SharedPreferencesManager import org.fnives.tiktokdownloader.data.local.persistent.SharedPreferencesManager
import org.fnives.tiktokdownloader.data.local.persistent.SharedPreferencesManagerImpl import org.fnives.tiktokdownloader.data.local.persistent.SharedPreferencesManagerImpl
import org.fnives.tiktokdownloader.data.local.persistent.UserPreferencesStorage
import org.fnives.tiktokdownloader.data.local.save.video.SaveVideoFile import org.fnives.tiktokdownloader.data.local.save.video.SaveVideoFile
import org.fnives.tiktokdownloader.data.local.verify.exists.VerifyFileForUriExists import org.fnives.tiktokdownloader.data.local.verify.exists.VerifyFileForUriExists
import org.fnives.tiktokdownloader.data.local.verify.exists.VerifyFileForUriExistsImpl import org.fnives.tiktokdownloader.data.local.verify.exists.VerifyFileForUriExistsImpl
import org.fnives.tiktokdownloader.di.ServiceLocator
class AndroidFileManagementModule(private val context: Context) { class AndroidFileManagementModule(private val context: Context) {
private val contentResolver: ContentResolver private val contentResolver: ContentResolver
@ -16,10 +16,14 @@ class AndroidFileManagementModule(private val context: Context) {
val verifyFileForUriExists: VerifyFileForUriExists val verifyFileForUriExists: VerifyFileForUriExists
get() = VerifyFileForUriExistsImpl(contentResolver) get() = VerifyFileForUriExistsImpl(contentResolver)
val sharedPreferencesManager: SharedPreferencesManager by lazy { private val sharedPreferencesManagerImpl by lazy {
SharedPreferencesManagerImpl.create(context) SharedPreferencesManagerImpl.create(context)
} }
val sharedPreferencesManager: SharedPreferencesManager get() = sharedPreferencesManagerImpl
val userPreferencesStorage: UserPreferencesStorage get() = sharedPreferencesManagerImpl
private val saveVideoFileFactory: SaveVideoFile.Factory private val saveVideoFileFactory: SaveVideoFile.Factory
get() = SaveVideoFile.Factory(contentResolver) get() = SaveVideoFile.Factory(contentResolver)

View file

@ -1,6 +1,7 @@
package org.fnives.tiktokdownloader.di.module package org.fnives.tiktokdownloader.di.module
import org.fnives.tiktokdownloader.data.local.CaptchaTimeoutLocalSource import org.fnives.tiktokdownloader.data.local.CaptchaTimeoutLocalSource
import org.fnives.tiktokdownloader.data.local.UserPreferencesLocalSource
import org.fnives.tiktokdownloader.data.local.VideoDownloadedLocalSource import org.fnives.tiktokdownloader.data.local.VideoDownloadedLocalSource
import org.fnives.tiktokdownloader.data.local.VideoInPendingLocalSource import org.fnives.tiktokdownloader.data.local.VideoInPendingLocalSource
import org.fnives.tiktokdownloader.data.local.VideoInProgressLocalSource import org.fnives.tiktokdownloader.data.local.VideoInProgressLocalSource
@ -22,6 +23,8 @@ class LocalSourceModule(private val androidFileManagementModule: AndroidFileMana
val videoInProgressLocalSource: VideoInProgressLocalSource by lazy { VideoInProgressLocalSource() } val videoInProgressLocalSource: VideoInProgressLocalSource by lazy { VideoInProgressLocalSource() }
val userPreferencesLocalSource: UserPreferencesLocalSource by lazy{ UserPreferencesLocalSource(androidFileManagementModule.userPreferencesStorage)}
val captchaTimeoutLocalSource: CaptchaTimeoutLocalSource val captchaTimeoutLocalSource: CaptchaTimeoutLocalSource
get() = CaptchaTimeoutLocalSource( get() = CaptchaTimeoutLocalSource(
androidFileManagementModule.sharedPreferencesManager, androidFileManagementModule.sharedPreferencesManager,

View file

@ -1,9 +1,13 @@
package org.fnives.tiktokdownloader.di.module package org.fnives.tiktokdownloader.di.module
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import org.fnives.tiktokdownloader.data.local.persistent.UserPreferencesStorage
import org.fnives.tiktokdownloader.data.usecase.AddVideoToQueueUseCase import org.fnives.tiktokdownloader.data.usecase.AddVideoToQueueUseCase
import org.fnives.tiktokdownloader.data.usecase.GetUserPreferences
import org.fnives.tiktokdownloader.data.usecase.ObserveUserPreferences
import org.fnives.tiktokdownloader.data.usecase.MoveVideoInQueueUseCase import org.fnives.tiktokdownloader.data.usecase.MoveVideoInQueueUseCase
import org.fnives.tiktokdownloader.data.usecase.RemoveVideoFromQueueUseCase import org.fnives.tiktokdownloader.data.usecase.RemoveVideoFromQueueUseCase
import org.fnives.tiktokdownloader.data.usecase.SetUserPreferences
import org.fnives.tiktokdownloader.data.usecase.StateOfVideosObservableUseCase import org.fnives.tiktokdownloader.data.usecase.StateOfVideosObservableUseCase
import org.fnives.tiktokdownloader.data.usecase.UrlVerificationUseCase import org.fnives.tiktokdownloader.data.usecase.UrlVerificationUseCase
import org.fnives.tiktokdownloader.data.usecase.VideoDownloadingProcessorUseCase import org.fnives.tiktokdownloader.data.usecase.VideoDownloadingProcessorUseCase
@ -41,6 +45,10 @@ class UseCaseModule(
localSourceModule.videoInPendingLocalSource localSourceModule.videoInPendingLocalSource
) )
val getUserPreferences: GetUserPreferences get() = GetUserPreferences(localSourceModule.userPreferencesLocalSource)
val observeUserPreferences: ObserveUserPreferences get() = ObserveUserPreferences(localSourceModule.userPreferencesLocalSource)
val setUserPreferences: SetUserPreferences get() = SetUserPreferences(localSourceModule.userPreferencesLocalSource)
val videoDownloadingProcessorUseCase: VideoDownloadingProcessorUseCase by lazy { val videoDownloadingProcessorUseCase: VideoDownloadingProcessorUseCase by lazy {
VideoDownloadingProcessorUseCase( VideoDownloadingProcessorUseCase(
tikTokDownloadRemoteSource = networkModule.tikTokDownloadRemoteSource, tikTokDownloadRemoteSource = networkModule.tikTokDownloadRemoteSource,

View file

@ -3,6 +3,7 @@ package org.fnives.tiktokdownloader.di.module
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import org.fnives.tiktokdownloader.ui.main.MainViewModel import org.fnives.tiktokdownloader.ui.main.MainViewModel
import org.fnives.tiktokdownloader.ui.main.queue.QueueViewModel import org.fnives.tiktokdownloader.ui.main.queue.QueueViewModel
import org.fnives.tiktokdownloader.ui.main.settings.SettingsViewModel
import org.fnives.tiktokdownloader.ui.service.QueueServiceViewModel import org.fnives.tiktokdownloader.ui.service.QueueServiceViewModel
class ViewModelModule(private val useCaseModule: UseCaseModule) { class ViewModelModule(private val useCaseModule: UseCaseModule) {
@ -28,4 +29,10 @@ class ViewModelModule(private val useCaseModule: UseCaseModule) {
useCaseModule.videoDownloadingProcessorUseCase, useCaseModule.videoDownloadingProcessorUseCase,
useCaseModule.moveVideoInQueueUseCase useCaseModule.moveVideoInQueueUseCase
) )
val settignsViewModel: SettingsViewModel get() =
SettingsViewModel(
useCaseModule.observeUserPreferences,
useCaseModule.setUserPreferences
)
} }

View file

@ -19,6 +19,7 @@ import org.fnives.tiktokdownloader.di.ServiceLocator
import org.fnives.tiktokdownloader.di.provideViewModels import org.fnives.tiktokdownloader.di.provideViewModels
import org.fnives.tiktokdownloader.ui.main.help.HelpFragment import org.fnives.tiktokdownloader.ui.main.help.HelpFragment
import org.fnives.tiktokdownloader.ui.main.queue.QueueFragment import org.fnives.tiktokdownloader.ui.main.queue.QueueFragment
import org.fnives.tiktokdownloader.ui.main.settings.SettingsFragment
import org.fnives.tiktokdownloader.ui.permission.PermissionRequester import org.fnives.tiktokdownloader.ui.permission.PermissionRequester
import org.fnives.tiktokdownloader.ui.service.QueueService import org.fnives.tiktokdownloader.ui.service.QueueService
@ -57,6 +58,7 @@ class MainActivity : AppCompatActivity() {
bottomNavigationView.setOnItemSelectedListener { item -> bottomNavigationView.setOnItemSelectedListener { item ->
val fragment = when (item.itemId) { val fragment = when (item.itemId) {
R.id.help_menu_item -> HelpFragment.newInstance() R.id.help_menu_item -> HelpFragment.newInstance()
R.id.settings_menu_item -> SettingsFragment.newInstance()
R.id.queue_menu_item -> QueueFragment.newInstance() R.id.queue_menu_item -> QueueFragment.newInstance()
else -> return@setOnItemSelectedListener false else -> return@setOnItemSelectedListener false
} }

View file

@ -0,0 +1,33 @@
package org.fnives.tiktokdownloader.ui.main.settings
import android.os.Bundle
import android.view.View
import androidx.appcompat.widget.SwitchCompat
import androidx.fragment.app.Fragment
import org.fnives.tiktokdownloader.R
import org.fnives.tiktokdownloader.di.provideViewModels
class SettingsFragment : Fragment(R.layout.fragment_settings) {
private val viewModel by provideViewModels<SettingsViewModel>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val alwaysOpenAppHolder = view.findViewById<View>(R.id.always_open_app_holder)
val alwaysOpenAppSwitch = view.findViewById<SwitchCompat>(R.id.always_open_app)
viewModel.userPreferences.observe(viewLifecycleOwner) {
alwaysOpenAppSwitch.isChecked = it.alwaysOpenApp
}
alwaysOpenAppSwitch.setOnCheckedChangeListener { _, isChecked ->
viewModel.setAlwaysOpenApp(isChecked)
}
alwaysOpenAppHolder.setOnClickListener {
viewModel.setAlwaysOpenApp(!alwaysOpenAppSwitch.isChecked)
}
}
companion object {
fun newInstance(): SettingsFragment = SettingsFragment()
}
}

View file

@ -0,0 +1,26 @@
package org.fnives.tiktokdownloader.ui.main.settings
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import org.fnives.tiktokdownloader.data.usecase.ObserveUserPreferences
import org.fnives.tiktokdownloader.data.usecase.SetUserPreferences
import org.fnives.tiktokdownloader.ui.shared.asLiveData
class SettingsViewModel(
private val getUserPreferences: ObserveUserPreferences,
private val setUserPreferences: SetUserPreferences
) : ViewModel() {
val userPreferences = asLiveData(getUserPreferences.invoke())
fun setAlwaysOpenApp(alwaysOpenApp: Boolean) {
val userPreferences = userPreferences.value ?: return
if (userPreferences.alwaysOpenApp == alwaysOpenApp) return
viewModelScope.launch {
setUserPreferences(userPreferences.copy(alwaysOpenApp = alwaysOpenApp))
}
}
}

View file

@ -3,6 +3,7 @@ package org.fnives.tiktokdownloader.ui.service
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import org.fnives.tiktokdownloader.data.usecase.GetUserPreferences
import org.fnives.tiktokdownloader.di.ServiceLocator import org.fnives.tiktokdownloader.di.ServiceLocator
import org.fnives.tiktokdownloader.ui.main.MainActivity import org.fnives.tiktokdownloader.ui.main.MainActivity
import org.fnives.tiktokdownloader.ui.permission.PermissionRequester import org.fnives.tiktokdownloader.ui.permission.PermissionRequester
@ -12,16 +13,31 @@ class DownloadIntentReceiverActivity : AppCompatActivity() {
private val permissionRequester: PermissionRequester by lazy { private val permissionRequester: PermissionRequester by lazy {
ServiceLocator.permissionModule.permissionRequester ServiceLocator.permissionModule.permissionRequester
} }
private val getUserPreferences: GetUserPreferences by lazy {
ServiceLocator.useCaseModule.getUserPreferences
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
intent.getStringExtra(Intent.EXTRA_TEXT)?.let { url -> intent.getStringExtra(Intent.EXTRA_TEXT)?.let { url ->
if (permissionRequester.isGranted(this)) { if (getUserPreferences().alwaysOpenApp) {
startService(QueueService.buildIntent(this, url)) alwaysOpen(url)
} else { } else {
startActivity(MainActivity.buildIntent(this, url)) openOnlyIfNeeded(url)
} }
} }
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
finish() finish()
} }
private fun alwaysOpen(url: String) {
startActivity(MainActivity.buildIntent(this, url))
}
private fun openOnlyIfNeeded(url: String) {
if (permissionRequester.isGranted(this)) {
startService(QueueService.buildIntent(this, url))
} else {
startActivity(MainActivity.buildIntent(this, url))
}
}
} }

View file

@ -0,0 +1,8 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="0.3"
android:fillColor="@android:color/white"
android:pathData="M19.28,8.6l-0.7,-1.21 -1.27,0.51 -1.06,0.43 -0.91,-0.7c-0.39,-0.3 -0.8,-0.54 -1.23,-0.71l-1.06,-0.43 -0.16,-1.13L12.7,4h-1.4l-0.19,1.35 -0.16,1.13 -1.06,0.44c-0.41,0.17 -0.82,0.41 -1.25,0.73l-0.9,0.68 -1.05,-0.42 -1.27,-0.52 -0.7,1.21 1.08,0.84 0.89,0.7 -0.14,1.13c-0.03,0.3 -0.05,0.53 -0.05,0.73s0.02,0.43 0.05,0.73l0.14,1.13 -0.89,0.7 -1.08,0.84 0.7,1.21 1.27,-0.51 1.06,-0.43 0.91,0.7c0.39,0.3 0.8,0.54 1.23,0.71l1.06,0.43 0.16,1.13 0.19,1.36h1.39l0.19,-1.35 0.16,-1.13 1.06,-0.43c0.41,-0.17 0.82,-0.41 1.25,-0.73l0.9,-0.68 1.04,0.42 1.27,0.51 0.7,-1.21 -1.08,-0.84 -0.89,-0.7 0.14,-1.13c0.04,-0.31 0.05,-0.52 0.05,-0.73 0,-0.21 -0.02,-0.43 -0.05,-0.73l-0.14,-1.13 0.89,-0.7 1.1,-0.84zM12,16c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z" android:strokeAlpha="0.3"/>
<path android:fillColor="@android:color/white" android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98 0,-0.34 -0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.09,-0.16 -0.26,-0.25 -0.44,-0.25 -0.06,0 -0.12,0.01 -0.17,0.03l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.06,-0.02 -0.12,-0.03 -0.18,-0.03 -0.17,0 -0.34,0.09 -0.43,0.25l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.09,0.16 0.26,0.25 0.44,0.25 0.06,0 0.12,-0.01 0.17,-0.03l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.06,0.02 0.12,0.03 0.18,0.03 0.17,0 0.34,-0.09 0.43,-0.25l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM17.45,11.27c0.04,0.31 0.05,0.52 0.05,0.73 0,0.21 -0.02,0.43 -0.05,0.73l-0.14,1.13 0.89,0.7 1.08,0.84 -0.7,1.21 -1.27,-0.51 -1.04,-0.42 -0.9,0.68c-0.43,0.32 -0.84,0.56 -1.25,0.73l-1.06,0.43 -0.16,1.13 -0.2,1.35h-1.4l-0.19,-1.35 -0.16,-1.13 -1.06,-0.43c-0.43,-0.18 -0.83,-0.41 -1.23,-0.71l-0.91,-0.7 -1.06,0.43 -1.27,0.51 -0.7,-1.21 1.08,-0.84 0.89,-0.7 -0.14,-1.13c-0.03,-0.31 -0.05,-0.54 -0.05,-0.74s0.02,-0.43 0.05,-0.73l0.14,-1.13 -0.89,-0.7 -1.08,-0.84 0.7,-1.21 1.27,0.51 1.04,0.42 0.9,-0.68c0.43,-0.32 0.84,-0.56 1.25,-0.73l1.06,-0.43 0.16,-1.13 0.2,-1.35h1.39l0.19,1.35 0.16,1.13 1.06,0.43c0.43,0.18 0.83,0.41 1.23,0.71l0.91,0.7 1.06,-0.43 1.27,-0.51 0.7,1.21 -1.07,0.85 -0.89,0.7 0.14,1.13zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/>
</vector>

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/activity_horizontal_margin">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/settings"
android:textAppearance="?attr/textAppearanceHeadline5" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_padding"
app:cardCornerRadius="@dimen/card_corner_radius"
app:cardElevation="@dimen/card_elevation">
<LinearLayout
android:id="@+id/always_open_app_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:orientation="horizontal"
android:padding="@dimen/default_padding">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:text="@string/user_preference_always_open_app"
android:textAppearance="?attr/textAppearanceSubtitle1" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/always_open_app"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>

View file

@ -6,6 +6,11 @@
android:icon="@drawable/ic_download" android:icon="@drawable/ic_download"
android:title="@string/queue" /> android:title="@string/queue" />
<item
android:id="@+id/settings_menu_item"
android:icon="@drawable/ic_twotone_settings"
android:title="@string/settings" />
<item <item
android:id="@+id/help_menu_item" android:id="@+id/help_menu_item"
android:icon="@drawable/ic_twotone_help" android:icon="@drawable/ic_twotone_help"

View file

@ -47,4 +47,6 @@
<string name="captcha_handling">It\'s possible if you try to download too many videos at the same time <b>captcha</b> will be triggered. Since we don\'t want to overload the server, in such case you will need to wait a couple hours to properly retry the download. If that still doesn\'t work you may need to verify a captcha on the same network.</string> <string name="captcha_handling">It\'s possible if you try to download too many videos at the same time <b>captcha</b> will be triggered. Since we don\'t want to overload the server, in such case you will need to wait a couple hours to properly retry the download. If that still doesn\'t work you may need to verify a captcha on the same network.</string>
<string name="link_to_repository">This is an open source project. You can see the repository clicking <u>here.</u></string> <string name="link_to_repository">This is an open source project. You can see the repository clicking <u>here.</u></string>
<string name="could_not_open">Couldn\'t open!</string> <string name="could_not_open">Couldn\'t open!</string>
<string name="settings">Settings</string>
<string name="user_preference_always_open_app">Always open app when sharing video</string>
</resources> </resources>