mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-04-20 03:24:50 +00:00
Progress bars subscription groups, Various notification permission requests, improved notification experience, Settings activity open to specific settings, refs
This commit is contained in:
parent
f42b14e95a
commit
b7c4047f1d
8 changed files with 134 additions and 13 deletions
|
@ -277,7 +277,7 @@ class Settings : FragmentedStorageFileJson() {
|
|||
@FormField(R.string.fetch_on_tab_opened, FieldForm.TOGGLE, R.string.fetch_on_tab_opened_description, 9)
|
||||
var fetchOnTabOpen: Boolean = true;
|
||||
|
||||
@FormField(R.string.background_update, FieldForm.DROPDOWN, R.string.experimental_background_update_for_subscriptions_cache, 10)
|
||||
@FormField(R.string.background_update, FieldForm.DROPDOWN, R.string.experimental_background_update_for_subscriptions_cache, 10, "background_update")
|
||||
@DropdownFieldOptionsId(R.array.background_interval)
|
||||
var subscriptionsBackgroundUpdateInterval: Int = 0;
|
||||
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
package com.futo.platformplayer
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.NotificationManager
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.futo.platformplayer.activities.MainActivity
|
||||
import com.futo.platformplayer.activities.SettingsActivity
|
||||
import com.futo.platformplayer.api.http.ManagedHttpClient
|
||||
import com.futo.platformplayer.api.media.models.ResultCapabilities
|
||||
import com.futo.platformplayer.api.media.models.channels.IPlatformChannel
|
||||
|
@ -131,8 +136,29 @@ class UISlideOverlays {
|
|||
subscription.save();
|
||||
menu.hide(true);
|
||||
|
||||
if(subscription.doNotifications && !originalNotif && Settings.instance.subscriptions.subscriptionsBackgroundUpdateInterval == 0) {
|
||||
UIDialogs.toast(container.context, "Enable 'Background Update' in settings for notifications to work");
|
||||
if(subscription.doNotifications && !originalNotif) {
|
||||
val mainContext = StateApp.instance.contextOrNull;
|
||||
if(Settings.instance.subscriptions.subscriptionsBackgroundUpdateInterval == 0) {
|
||||
UIDialogs.toast(container.context, "Enable 'Background Update' in settings for notifications to work");
|
||||
|
||||
if(mainContext is MainActivity) {
|
||||
UIDialogs.showDialog(mainContext, R.drawable.ic_settings, "Background Updating Required",
|
||||
"You need to set a Background Updating interval for notifications", null, 0,
|
||||
UIDialogs.Action("Cancel", {}),
|
||||
UIDialogs.Action("Configure", {
|
||||
val intent = Intent(mainContext, SettingsActivity::class.java);
|
||||
intent.putExtra("query", mainContext.getString(R.string.background_update));
|
||||
mainContext.startActivity(intent);
|
||||
}, UIDialogs.ActionStyle.PRIMARY));
|
||||
}
|
||||
return@subscribe;
|
||||
}
|
||||
else if(!(mainContext?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).areNotificationsEnabled()) {
|
||||
UIDialogs.toast(container.context, "Android notifications are disabled");
|
||||
if(mainContext is MainActivity) {
|
||||
mainContext.requestNotificationPermissions("Notifications are required for subscription updating and notifications to work");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
menu.onCancel.subscribe {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package com.futo.platformplayer.activities
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
|
@ -17,6 +19,8 @@ import androidx.activity.result.ActivityResultLauncher
|
|||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
|
@ -1009,6 +1013,33 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
|
|||
}
|
||||
|
||||
|
||||
val notifPermission = "android.permission.POST_NOTIFICATIONS";
|
||||
val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
|
||||
if (isGranted)
|
||||
UIDialogs.toast(this, "Notification permission granted");
|
||||
else
|
||||
UIDialogs.toast(this, "Notification permission denied");
|
||||
}
|
||||
fun requestNotificationPermissions(reason: String) {
|
||||
when {
|
||||
ContextCompat.checkSelfPermission(this, notifPermission) == PackageManager.PERMISSION_GRANTED -> {
|
||||
|
||||
}
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(this, notifPermission) -> {
|
||||
UIDialogs.showDialog(this, R.drawable.ic_notifications, "Notifications Required",
|
||||
reason, null, 0,
|
||||
UIDialogs.Action("Cancel", {}),
|
||||
UIDialogs.Action("Enable", {
|
||||
requestPermissionLauncher.launch(notifPermission);
|
||||
}, UIDialogs.ActionStyle.PRIMARY));
|
||||
}
|
||||
else -> {
|
||||
requestPermissionLauncher.launch(notifPermission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TODO: Only calls last handler due to missing request codes on ActivityResultLaunchers.
|
||||
private var resultLauncherMap = mutableMapOf<Int, (ActivityResult)->Unit>();
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package com.futo.platformplayer.activities
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
|
@ -12,6 +14,8 @@ import androidx.activity.result.ActivityResult
|
|||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.futo.platformplayer.*
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
|
@ -33,6 +37,14 @@ class SettingsActivity : AppCompatActivity(), IWithResultLauncher {
|
|||
|
||||
lateinit var overlay: FrameLayout;
|
||||
|
||||
val notifPermission = "android.permission.POST_NOTIFICATIONS";
|
||||
val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
|
||||
if (isGranted)
|
||||
UIDialogs.toast(this, "Notification permission granted");
|
||||
else
|
||||
UIDialogs.toast(this, "Notification permission denied");
|
||||
}
|
||||
|
||||
override fun attachBaseContext(newBase: Context?) {
|
||||
Logger.i("SettingsActivity", "SettingsActivity.attachBaseContext")
|
||||
super.attachBaseContext(StateApp.instance.getLocaleContext(newBase))
|
||||
|
@ -58,6 +70,33 @@ class SettingsActivity : AppCompatActivity(), IWithResultLauncher {
|
|||
Logger.i("SettingsActivity", "App language change detected, propogating to shared preferences");
|
||||
StateApp.instance.setLocaleSetting(this, Settings.instance.language.getAppLanguageLocaleString());
|
||||
}
|
||||
|
||||
if(field.descriptor?.id == "background_update") {
|
||||
Logger.i("SettingsActivity", "Detected change in background work ${field.value}");
|
||||
if(Settings.instance.subscriptions.subscriptionsBackgroundUpdateInterval > 0) {
|
||||
val notifManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager;
|
||||
if(!notifManager.areNotificationsEnabled()) {
|
||||
UIDialogs.toast(this, "Notifications aren't enabled");
|
||||
|
||||
when {
|
||||
ContextCompat.checkSelfPermission(this, notifPermission) == PackageManager.PERMISSION_GRANTED -> {
|
||||
|
||||
}
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(this, notifPermission) -> {
|
||||
UIDialogs.showDialog(this, R.drawable.ic_notifications, "Notifications Required",
|
||||
"Notifications need to be enabled for background updating to function", null, 0,
|
||||
UIDialogs.Action("Cancel", {}),
|
||||
UIDialogs.Action("Enable", {
|
||||
requestPermissionLauncher.launch(notifPermission);
|
||||
}, UIDialogs.ActionStyle.PRIMARY));
|
||||
}
|
||||
else -> {
|
||||
requestPermissionLauncher.launch(notifPermission);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
_buttonBack.setOnClickListener {
|
||||
finish();
|
||||
|
@ -72,7 +111,10 @@ class SettingsActivity : AppCompatActivity(), IWithResultLauncher {
|
|||
reloadSettings();
|
||||
}
|
||||
|
||||
var isFirstLoad = true;
|
||||
fun reloadSettings() {
|
||||
val firstLoad = isFirstLoad;
|
||||
isFirstLoad = false;
|
||||
_form.setSearchVisible(false);
|
||||
_loaderView.start();
|
||||
_form.fromObject(lifecycleScope, Settings.instance) {
|
||||
|
@ -90,6 +132,13 @@ class SettingsActivity : AppCompatActivity(), IWithResultLauncher {
|
|||
UIDialogs.toast(this, getString(R.string.you_are_now_in_developer_mode));
|
||||
}
|
||||
};
|
||||
|
||||
if(firstLoad) {
|
||||
val query = intent.getStringExtra("query");
|
||||
if(!query.isNullOrEmpty()) {
|
||||
_form.setSearchQuery(query);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -135,6 +184,7 @@ class SettingsActivity : AppCompatActivity(), IWithResultLauncher {
|
|||
resultLauncher.launch(intent);
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
//TODO: Temporary for solving Settings issues
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
|
|
|
@ -104,14 +104,17 @@ class SubscriptionsFeedFragment : MainFragment() {
|
|||
|
||||
constructor(fragment: SubscriptionsFeedFragment, inflater: LayoutInflater, cachedRecyclerData: RecyclerData<InsertedViewAdapterWithLoader<ContentPreviewViewHolder>, LinearLayoutManager, IPager<IPlatformContent>, IPlatformContent, IPlatformContent, InsertedViewHolder<ContentPreviewViewHolder>>? = null) : super(fragment, inflater, cachedRecyclerData) {
|
||||
Logger.i(TAG, "SubscriptionsFeedFragment constructor()");
|
||||
StateSubscriptions.instance.global.onUpdateProgress.subscribe(this) { progress, total ->
|
||||
fragment.lifecycleScope.launch(Dispatchers.Main) {
|
||||
try {
|
||||
setProgress(progress, total);
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to set progress", e);
|
||||
StateSubscriptions.instance.onFeedProgress.subscribe(this) { id, progress, total ->
|
||||
if(_subGroup?.id == id)
|
||||
fragment.lifecycleScope.launch(Dispatchers.Main) {
|
||||
try {
|
||||
setProgress(progress, total);
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to set progress", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
StateSubscriptions.instance.global.onUpdateProgress.subscribe(this) { progress, total ->
|
||||
};
|
||||
|
||||
StateSubscriptions.instance.onSubscriptionsChanged.subscribe(this) { _, added ->
|
||||
|
@ -264,7 +267,10 @@ class SubscriptionsFeedFragment : MainFragment() {
|
|||
UISlideOverlays.showCreateSubscriptionGroup(_overlayContainer);
|
||||
else {
|
||||
_subGroup = g;
|
||||
loadCache(); //TODO: Proper subset update
|
||||
setProgress(0, 0);
|
||||
if(Settings.instance.subscriptions.fetchOnTabOpen)
|
||||
loadResults(false);
|
||||
else loadCache();
|
||||
}
|
||||
};
|
||||
_subscriptionBar?.onHoldGroup?.subscribe { g ->
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.futo.platformplayer.api.media.platforms.js.JSClient
|
|||
import com.futo.platformplayer.api.media.structures.*
|
||||
import com.futo.platformplayer.api.media.structures.ReusablePager.Companion.asReusable
|
||||
import com.futo.platformplayer.constructs.Event2
|
||||
import com.futo.platformplayer.constructs.Event3
|
||||
import com.futo.platformplayer.functional.CentralizedFeed
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.models.Subscription
|
||||
|
@ -50,7 +51,7 @@ class StateSubscriptions {
|
|||
|
||||
val global: CentralizedFeed = CentralizedFeed();
|
||||
val feeds: HashMap<String, CentralizedFeed> = hashMapOf();
|
||||
|
||||
val onFeedProgress = Event3<String, Int, Int>();
|
||||
|
||||
val onSubscriptionsChanged = Event2<List<Subscription>, Boolean>();
|
||||
|
||||
|
@ -70,6 +71,9 @@ class StateSubscriptions {
|
|||
var f = feeds[id];
|
||||
if(f == null && createIfNew) {
|
||||
f = CentralizedFeed();
|
||||
f.onUpdateProgress.subscribe { progress, total ->
|
||||
onFeedProgress.emit(id, progress, total)
|
||||
};
|
||||
feeds[id] = f;
|
||||
}
|
||||
return@synchronized f;
|
||||
|
|
|
@ -71,6 +71,10 @@ class FieldForm : LinearLayout {
|
|||
}
|
||||
}
|
||||
|
||||
fun setSearchQuery(query: String) {
|
||||
_editSearch.setText(query);
|
||||
updateSettingsVisibility();
|
||||
}
|
||||
fun setSearchVisible(visible: Boolean) {
|
||||
_containerSearch.visibility = if(visible) View.VISIBLE else View.GONE;
|
||||
_editSearch.setText("");
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 863d0be1322660c99e4d0cdae0b45d0a5918542d
|
||||
Subproject commit 01270edbb4b6b4fb004e22fc529bf787c7f5be81
|
Loading…
Add table
Reference in a new issue