Fixed retryDialog button ordering. Fixed default action on confirmation dialog. Set notifications to be silent. AddToQueue button implemented on channel fragment. Added confirmation for deleting downloaded playlist videos. Separately handled UnknownHostException to prevent the dialog from showing when offline.

This commit is contained in:
Koen 2023-09-26 17:15:25 +02:00
commit a51cdcd6ec
10 changed files with 38 additions and 8 deletions

View file

@ -190,7 +190,9 @@ class UIDialogs {
"\nPlugin [${ex.config.name}]" else ""; "\nPlugin [${ex.config.name}]" else "";
showDialog(context, showDialog(context,
R.drawable.ic_error_pred, R.drawable.ic_error_pred,
"${msg}${pluginInfo}", (if(ex != null ) "${ex.message}" else ""), if(ex is PluginException) ex.code else null, "${msg}${pluginInfo}",
(if(ex != null ) "${ex.message}" else ""),
if(ex is PluginException) ex.code else null,
0, 0,
UIDialogs.Action("Retry", { UIDialogs.Action("Retry", {
retryAction?.invoke(); retryAction?.invoke();
@ -209,14 +211,14 @@ class UIDialogs {
fun showDataRetryDialog(context: Context, reason: String? = null, retryAction: (() -> Unit)? = null, closeAction: (() -> Unit)? = null) { fun showDataRetryDialog(context: Context, reason: String? = null, retryAction: (() -> Unit)? = null, closeAction: (() -> Unit)? = null) {
val retryButtonAction = Action("Retry", retryAction ?: {}, ActionStyle.PRIMARY) val retryButtonAction = Action("Retry", retryAction ?: {}, ActionStyle.PRIMARY)
val closeButtonAction = Action("Close", closeAction ?: {}, ActionStyle.ACCENT) val closeButtonAction = Action("Close", closeAction ?: {}, ActionStyle.ACCENT)
showDialog(context, R.drawable.ic_no_internet_86dp, "Data Retry", reason, null, 0, retryButtonAction, closeButtonAction) showDialog(context, R.drawable.ic_no_internet_86dp, "Data Retry", reason, null, 0, closeButtonAction, retryButtonAction)
} }
fun showConfirmationDialog(context: Context, text: String, action: () -> Unit, cancelAction: (() -> Unit)? = null) { fun showConfirmationDialog(context: Context, text: String, action: () -> Unit, cancelAction: (() -> Unit)? = null) {
val confirmButtonAction = Action("Confirm", action, ActionStyle.PRIMARY) val confirmButtonAction = Action("Confirm", action, ActionStyle.PRIMARY)
val cancelButtonAction = Action("Cancel", cancelAction ?: {}, ActionStyle.ACCENT) val cancelButtonAction = Action("Cancel", cancelAction ?: {}, ActionStyle.ACCENT)
showDialog(context, R.drawable.ic_error, text, null, null, 1, cancelButtonAction, confirmButtonAction) showDialog(context, R.drawable.ic_error, text, null, null, 0, cancelButtonAction, confirmButtonAction)
} }
fun showUpdateAvailableDialog(context: Context, lastVersion: Int) { fun showUpdateAvailableDialog(context: Context, lastVersion: Int) {

View file

@ -55,6 +55,7 @@ class BackgroundWorker(private val appContext: Context, workerParams: WorkerPara
.setSmallIcon(com.futo.platformplayer.R.drawable.foreground) .setSmallIcon(com.futo.platformplayer.R.drawable.foreground)
.setContentTitle("Grayjay") .setContentTitle("Grayjay")
.setContentText("Failed subscriptions update\n${ex.message}") .setContentText("Failed subscriptions update\n${ex.message}")
.setSilent(true)
.setChannelId(notificationChannel.id).build()); .setChannelId(notificationChannel.id).build());
} }
@ -72,6 +73,7 @@ class BackgroundWorker(private val appContext: Context, workerParams: WorkerPara
.setSmallIcon(com.futo.platformplayer.R.drawable.foreground) .setSmallIcon(com.futo.platformplayer.R.drawable.foreground)
.setContentTitle("Grayjay") .setContentTitle("Grayjay")
.setContentText("Updating subscriptions...") .setContentText("Updating subscriptions...")
.setSilent(true)
.setChannelId(notificationChannel.id) .setChannelId(notificationChannel.id)
.setProgress(1, 0, true); .setProgress(1, 0, true);
@ -109,6 +111,7 @@ class BackgroundWorker(private val appContext: Context, workerParams: WorkerPara
.setSmallIcon(com.futo.platformplayer.R.drawable.foreground) .setSmallIcon(com.futo.platformplayer.R.drawable.foreground)
.setContentTitle("Grayjay") .setContentTitle("Grayjay")
.setContentText("${newItems.size} new content from ${newSubChanges.size} creators") .setContentText("${newItems.size} new content from ${newSubChanges.size} creators")
.setSilent(true)
.setChannelId(notificationChannel.id).build()); .setChannelId(notificationChannel.id).build());
} }
} }

View file

@ -55,6 +55,7 @@ class ChannelContentsFragment : Fragment(), IChannelTabFragment {
val onContentUrlClicked = Event2<String, ContentType>(); val onContentUrlClicked = Event2<String, ContentType>();
val onChannelClicked = Event1<PlatformAuthorLink>(); val onChannelClicked = Event1<PlatformAuthorLink>();
val onAddToClicked = Event1<IPlatformContent>(); val onAddToClicked = Event1<IPlatformContent>();
val onAddToQueueClicked = Event1<IPlatformContent>();
private fun getContentPager(channel: IPlatformChannel): IPager<IPlatformContent> { private fun getContentPager(channel: IPlatformChannel): IPager<IPlatformContent> {
Logger.i(TAG, "getContentPager"); Logger.i(TAG, "getContentPager");
@ -147,6 +148,7 @@ class ChannelContentsFragment : Fragment(), IChannelTabFragment {
this.onContentClicked.subscribe(this@ChannelContentsFragment.onContentClicked::emit); this.onContentClicked.subscribe(this@ChannelContentsFragment.onContentClicked::emit);
this.onChannelClicked.subscribe(this@ChannelContentsFragment.onChannelClicked::emit); this.onChannelClicked.subscribe(this@ChannelContentsFragment.onChannelClicked::emit);
this.onAddToClicked.subscribe(this@ChannelContentsFragment.onAddToClicked::emit); this.onAddToClicked.subscribe(this@ChannelContentsFragment.onAddToClicked::emit);
this.onAddToQueueClicked.subscribe(this@ChannelContentsFragment.onAddToQueueClicked::emit);
} }
_llmVideo = LinearLayoutManager(view.context); _llmVideo = LinearLayoutManager(view.context);

View file

@ -38,6 +38,7 @@ import com.futo.platformplayer.models.SearchType
import com.futo.platformplayer.models.Subscription import com.futo.platformplayer.models.Subscription
import com.futo.platformplayer.polycentric.PolycentricCache import com.futo.platformplayer.polycentric.PolycentricCache
import com.futo.platformplayer.states.StatePlatform import com.futo.platformplayer.states.StatePlatform
import com.futo.platformplayer.states.StatePlayer
import com.futo.platformplayer.states.StatePlaylists import com.futo.platformplayer.states.StatePlaylists
import com.futo.platformplayer.views.others.CreatorThumbnail import com.futo.platformplayer.views.others.CreatorThumbnail
import com.futo.platformplayer.views.subscriptions.SubscribeButton import com.futo.platformplayer.views.subscriptions.SubscribeButton
@ -182,6 +183,13 @@ class ChannelFragment : MainFragment() {
_slideUpOverlay = UISlideOverlays.showVideoOptionsOverlay(content, it); _slideUpOverlay = UISlideOverlays.showVideoOptionsOverlay(content, it);
} }
} }
adapter.onAddToQueueClicked.subscribe { content ->
if(content is IPlatformVideo) {
StatePlayer.instance.addToQueue(content);
val name = if (content.name.length > 20) (content.name.subSequence(0, 20).toString() + "...") else content.name;
UIDialogs.toast(context, "Queued [$name]", false);
}
}
adapter.onContentUrlClicked.subscribe { url, contentType -> adapter.onContentUrlClicked.subscribe { url, contentType ->
when(contentType) { when(contentType) {
ContentType.MEDIA -> fragment.navigate<VideoDetailFragment>(url).maximizeVideoDetail(); ContentType.MEDIA -> fragment.navigate<VideoDetailFragment>(url).maximizeVideoDetail();

View file

@ -284,13 +284,17 @@ class PlaylistFragment : MainFragment() {
_buttonDownload.setImageResource(R.drawable.ic_loader_animated); _buttonDownload.setImageResource(R.drawable.ic_loader_animated);
_buttonDownload.drawable.assume<Animatable, Unit> { it.start() }; _buttonDownload.drawable.assume<Animatable, Unit> { it.start() };
_buttonDownload.setOnClickListener { _buttonDownload.setOnClickListener {
UIDialogs.showConfirmationDialog(context, "Are you sure you want to delete the downloaded videos?", {
StateDownloads.instance.deleteCachedPlaylist(playlist.id); StateDownloads.instance.deleteCachedPlaylist(playlist.id);
});
} }
} }
else if(isDownloaded) { else if(isDownloaded) {
_buttonDownload.setImageResource(R.drawable.ic_download_off); _buttonDownload.setImageResource(R.drawable.ic_download_off);
_buttonDownload.setOnClickListener { _buttonDownload.setOnClickListener {
UIDialogs.showConfirmationDialog(context, "Are you sure you want to delete the downloaded videos?", {
StateDownloads.instance.deleteCachedPlaylist(playlist.id); StateDownloads.instance.deleteCachedPlaylist(playlist.id);
});
} }
} }
else { else {

View file

@ -221,6 +221,7 @@ class DownloadService : Service() {
NotificationCompat.Builder(this, DOWNLOAD_NOTIF_TAG) NotificationCompat.Builder(this, DOWNLOAD_NOTIF_TAG)
.setSmallIcon(R.drawable.ic_download) .setSmallIcon(R.drawable.ic_download)
.setOngoing(true) .setOngoing(true)
.setSilent(true)
.setContentIntent(PendingIntent.getActivity(this, 5, bringUpIntent, PendingIntent.FLAG_IMMUTABLE)) .setContentIntent(PendingIntent.getActivity(this, 5, bringUpIntent, PendingIntent.FLAG_IMMUTABLE))
.setContentTitle("${download.state}: ${download.name}") .setContentTitle("${download.state}: ${download.name}")
.setContentText(download.getDownloadInfo()) .setContentText(download.getDownloadInfo())
@ -230,6 +231,7 @@ class DownloadService : Service() {
NotificationCompat.Builder(this, DOWNLOAD_NOTIF_TAG) NotificationCompat.Builder(this, DOWNLOAD_NOTIF_TAG)
.setSmallIcon(R.drawable.ic_download) .setSmallIcon(R.drawable.ic_download)
.setOngoing(true) .setOngoing(true)
.setSilent(true)
.setContentIntent(PendingIntent.getActivity(this, 5, bringUpIntent, PendingIntent.FLAG_IMMUTABLE)) .setContentIntent(PendingIntent.getActivity(this, 5, bringUpIntent, PendingIntent.FLAG_IMMUTABLE))
.setContentTitle("Preparing for download...") .setContentTitle("Preparing for download...")
.setContentText("Initializing download process...") .setContentText("Initializing download process...")

View file

@ -163,6 +163,7 @@ class ExportingService : Service() {
var builder = NotificationCompat.Builder(this, EXPORT_NOTIF_TAG) var builder = NotificationCompat.Builder(this, EXPORT_NOTIF_TAG)
.setSmallIcon(R.drawable.ic_export) .setSmallIcon(R.drawable.ic_export)
.setOngoing(true) .setOngoing(true)
.setSilent(true)
.setContentIntent(PendingIntent.getActivity(this, 5, bringUpIntent, PendingIntent.FLAG_IMMUTABLE)) .setContentIntent(PendingIntent.getActivity(this, 5, bringUpIntent, PendingIntent.FLAG_IMMUTABLE))
.setContentTitle("${export.state}: ${export.videoLocal.name}") .setContentTitle("${export.state}: ${export.videoLocal.name}")
.setContentText(export.getExportInfo()) .setContentText(export.getExportInfo())

View file

@ -60,7 +60,6 @@ class MediaPlaybackService : Service() {
} }
try { try {
setupNotificationRequirements(); setupNotificationRequirements();
notifyMediaSession(null, null); notifyMediaSession(null, null);
@ -235,6 +234,7 @@ class MediaPlaybackService : Service() {
var builder = NotificationCompat.Builder(this, MEDIA_NOTIF_TAG) var builder = NotificationCompat.Builder(this, MEDIA_NOTIF_TAG)
.setSmallIcon(icon) .setSmallIcon(icon)
.setOngoing(true) .setOngoing(true)
.setSilent(true)
.setContentIntent(PendingIntent.getActivity(this, 5, bringUpIntent, PendingIntent.FLAG_IMMUTABLE)) .setContentIntent(PendingIntent.getActivity(this, 5, bringUpIntent, PendingIntent.FLAG_IMMUTABLE))
.setStyle(if(hasQueue) .setStyle(if(hasQueue)
androidx.media.app.NotificationCompat.MediaStyle() androidx.media.app.NotificationCompat.MediaStyle()

View file

@ -18,6 +18,7 @@ class ChannelViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifec
val onContentClicked = Event2<IPlatformContent, Long>(); val onContentClicked = Event2<IPlatformContent, Long>();
val onChannelClicked = Event1<PlatformAuthorLink>(); val onChannelClicked = Event1<PlatformAuthorLink>();
val onAddToClicked = Event1<IPlatformContent>(); val onAddToClicked = Event1<IPlatformContent>();
val onAddToQueueClicked = Event1<IPlatformContent>();
override fun getItemCount(): Int { override fun getItemCount(): Int {
return _cache.size; return _cache.size;
@ -51,6 +52,7 @@ class ChannelViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifec
onContentUrlClicked.subscribe(this@ChannelViewPagerAdapter.onContentUrlClicked::emit); onContentUrlClicked.subscribe(this@ChannelViewPagerAdapter.onContentUrlClicked::emit);
onChannelClicked.subscribe(this@ChannelViewPagerAdapter.onChannelClicked::emit); onChannelClicked.subscribe(this@ChannelViewPagerAdapter.onChannelClicked::emit);
onAddToClicked.subscribe(this@ChannelViewPagerAdapter.onAddToClicked::emit); onAddToClicked.subscribe(this@ChannelViewPagerAdapter.onAddToClicked::emit);
onAddToQueueClicked.subscribe(this@ChannelViewPagerAdapter.onAddToQueueClicked::emit);
}; };
1 -> ChannelListFragment.newInstance().apply { onClickChannel.subscribe(onChannelClicked::emit) }; 1 -> ChannelListFragment.newInstance().apply { onClickChannel.subscribe(onChannelClicked::emit) };
//2 -> ChannelStoreFragment.newInstance(); //2 -> ChannelStoreFragment.newInstance();

View file

@ -22,14 +22,20 @@ import com.futo.platformplayer.constructs.TaskHandler
import com.futo.platformplayer.fragment.mainactivity.main.ChannelFragment import com.futo.platformplayer.fragment.mainactivity.main.ChannelFragment
import com.futo.platformplayer.views.adapters.CommentViewHolder import com.futo.platformplayer.views.adapters.CommentViewHolder
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
import java.net.UnknownHostException
class CommentsList : ConstraintLayout { class CommentsList : ConstraintLayout {
private val _llmReplies: LinearLayoutManager; private val _llmReplies: LinearLayoutManager;
private val _taskLoadComments = if(!isInEditMode) TaskHandler<suspend () -> IPager<IPlatformComment>, IPager<IPlatformComment>>(StateApp.instance.scopeGetter, { it(); }) private val _taskLoadComments = if(!isInEditMode) TaskHandler<suspend () -> IPager<IPlatformComment>, IPager<IPlatformComment>>(StateApp.instance.scopeGetter, { it(); })
.success { pager -> onCommentsLoaded(pager); } .success { pager -> onCommentsLoaded(pager); }
.exception<UnknownHostException> {
UIDialogs.toast("Failed to load comments");
setLoading(false);
}
.exception<Throwable> { .exception<Throwable> {
Logger.w(ChannelFragment.TAG, "Failed to load comments.", it); Logger.e(TAG, "Failed to load comments.", it);
UIDialogs.showGeneralRetryErrorDialog(context, it.message ?: "", it, ::fetchComments); UIDialogs.showGeneralRetryErrorDialog(context, "Failed to load comments. " + (it.message ?: ""), it, ::fetchComments);
setLoading(false);
} else TaskHandler(IPlatformVideoDetails::class.java, StateApp.instance.scopeGetter); } else TaskHandler(IPlatformVideoDetails::class.java, StateApp.instance.scopeGetter);
private var _nextPageHandler: TaskHandler<IPager<IPlatformComment>, List<IPlatformComment>> = TaskHandler<IPager<IPlatformComment>, List<IPlatformComment>>(StateApp.instance.scopeGetter, { private var _nextPageHandler: TaskHandler<IPager<IPlatformComment>, List<IPlatformComment>> = TaskHandler<IPager<IPlatformComment>, List<IPlatformComment>>(StateApp.instance.scopeGetter, {