Merge pull request #638 from Bnyro/master

New animations + kill notifications on app closure + Chapters UI Rework
This commit is contained in:
Bnyro 2022-06-28 16:56:50 +02:00 committed by GitHub
commit 48a1f4710e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 128 additions and 130 deletions

View File

@ -272,9 +272,15 @@
</activity> </activity>
<service <service
android:name=".DownloadService" android:name=".services.DownloadService"
android:enabled="true" android:enabled="true"
android:exported="false" /> android:exported="false" />
<service
android:name=".services.ClosingService"
android:stopWithTask="false"
android:enabled="true"
android:exported="false"/>
</application> </application>
</manifest> </manifest>

View File

@ -34,6 +34,7 @@ import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import com.github.libretube.fragments.PlayerFragment import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.fragments.isFullScreen import com.github.libretube.fragments.isFullScreen
import com.github.libretube.services.ClosingService
import com.github.libretube.util.CronetHelper import com.github.libretube.util.CronetHelper
import com.github.libretube.util.LocaleHelper import com.github.libretube.util.LocaleHelper
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
@ -52,6 +53,10 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
DynamicColors.applyToActivityIfAvailable(this) DynamicColors.applyToActivityIfAvailable(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// start service that gets called on closure
startService(Intent(this, ClosingService::class.java))
CronetHelper.initCronet(this.applicationContext) CronetHelper.initCronet(this.applicationContext)
RetrofitInstance.url = RetrofitInstance.url =

View File

@ -17,10 +17,10 @@ import android.widget.TextView
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import com.github.libretube.DownloadService
import com.github.libretube.MainActivity import com.github.libretube.MainActivity
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.obj.Streams import com.github.libretube.obj.Streams
import com.github.libretube.services.DownloadService
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
class DownloadDialog : DialogFragment() { class DownloadDialog : DialogFragment() {

View File

@ -38,7 +38,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.IS_DOWNLOAD_RUNNING
import com.github.libretube.MainActivity import com.github.libretube.MainActivity
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.adapters.ChaptersAdapter import com.github.libretube.adapters.ChaptersAdapter
@ -56,6 +55,7 @@ import com.github.libretube.obj.SponsorBlockPrefs
import com.github.libretube.obj.StreamItem import com.github.libretube.obj.StreamItem
import com.github.libretube.obj.Streams import com.github.libretube.obj.Streams
import com.github.libretube.obj.Subscribe import com.github.libretube.obj.Subscribe
import com.github.libretube.services.IS_DOWNLOAD_RUNNING
import com.github.libretube.util.CronetHelper import com.github.libretube.util.CronetHelper
import com.github.libretube.util.DescriptionAdapter import com.github.libretube.util.DescriptionAdapter
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
@ -252,14 +252,12 @@ class PlayerFragment : Fragment() {
} }
} }
// video description and chapters toggle
val descLinLayout = view.findViewById<LinearLayout>(R.id.desc_linLayout)
view.findViewById<RelativeLayout>(R.id.player_title_layout).setOnClickListener { view.findViewById<RelativeLayout>(R.id.player_title_layout).setOnClickListener {
val arrowImageView = view.findViewById<ImageView>(R.id.player_description_arrow) val arrowImageView = view.findViewById<ImageView>(R.id.player_description_arrow)
arrowImageView.animate().rotationBy(180F).setDuration(100).start() arrowImageView.animate().rotationBy(180F).setDuration(100).start()
if (playerDescription.isVisible) { descLinLayout.visibility = if (descLinLayout.isVisible) View.GONE else View.VISIBLE
playerDescription.visibility = View.GONE
} else {
playerDescription.visibility = View.VISIBLE
}
} }
view.findViewById<MaterialCardView>(R.id.comments_toggle) view.findViewById<MaterialCardView>(R.id.comments_toggle)
@ -447,11 +445,11 @@ class PlayerFragment : Fragment() {
relatedStreams = response.relatedStreams relatedStreams = response.relatedStreams
runOnUiThread { runOnUiThread {
createExoPlayer(view) createExoPlayer(view)
prepareExoPlayerView()
if (response.chapters != null) initializeChapters(response.chapters) if (response.chapters != null) initializeChapters(response.chapters)
// set media sources for the player // set media sources for the player
setResolutionAndSubtitles(view, response) setResolutionAndSubtitles(view, response)
exoPlayer.prepare() exoPlayer.prepare()
prepareExoPlayerView()
initializePlayerView(view, response) initializePlayerView(view, response)
// support for time stamped links // support for time stamped links
if (arguments?.getLong("timeStamp") != null) { if (arguments?.getLong("timeStamp") != null) {
@ -717,28 +715,13 @@ class PlayerFragment : Fragment() {
} }
private fun initializeChapters(chapters: List<ChapterSegment>) { private fun initializeChapters(chapters: List<ChapterSegment>) {
val chaptersToggle = view?.findViewById<LinearLayout>(R.id.chapters_toggle)
val chaptersRecView = view?.findViewById<RecyclerView>(R.id.chapters_recView) val chaptersRecView = view?.findViewById<RecyclerView>(R.id.chapters_recView)
val chaptersToggleText = view?.findViewById<TextView>(R.id.chapters_toggle_text)
val chaptersToggleArrow = view?.findViewById<ImageView>(R.id.chapters_toggle_arrow)
if (chapters.isNotEmpty()) { if (chapters.isNotEmpty()) {
chaptersToggle?.visibility = View.VISIBLE
chaptersToggle?.setOnClickListener {
if (chaptersRecView?.isVisible!!) {
chaptersRecView?.visibility = View.GONE
chaptersToggleText?.text = getString(R.string.show_chapters)
} else {
chaptersRecView?.visibility = View.VISIBLE
chaptersToggleText?.text = getString(R.string.hide_chapters)
}
chaptersToggleArrow!!.animate().setDuration(100).rotationBy(180F).start()
}
chaptersRecView?.layoutManager = chaptersRecView?.layoutManager =
LinearLayoutManager(this.context, LinearLayoutManager.HORIZONTAL, false) LinearLayoutManager(this.context, LinearLayoutManager.HORIZONTAL, false)
chaptersRecView?.adapter = ChaptersAdapter(chapters, exoPlayer) chaptersRecView?.adapter = ChaptersAdapter(chapters, exoPlayer)
chaptersRecView?.visibility = View.VISIBLE
} }
} }
@ -1121,7 +1104,7 @@ class PlayerFragment : Fragment() {
enableTransition(R.id.yt_transition, false) enableTransition(R.id.yt_transition, false)
} }
view?.findViewById<ConstraintLayout>(R.id.main_container)?.isClickable = true view?.findViewById<ConstraintLayout>(R.id.main_container)?.isClickable = true
view?.findViewById<FrameLayout>(R.id.top_bar)?.visibility = View.GONE view?.findViewById<LinearLayout>(R.id.top_bar)?.visibility = View.GONE
val mainActivity = activity as MainActivity val mainActivity = activity as MainActivity
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
isFullScreen = false isFullScreen = false
@ -1133,7 +1116,7 @@ class PlayerFragment : Fragment() {
exoPlayerView.showController() exoPlayerView.showController()
exoPlayerView.useController = true exoPlayerView.useController = true
view?.findViewById<ConstraintLayout>(R.id.main_container)?.isClickable = false view?.findViewById<ConstraintLayout>(R.id.main_container)?.isClickable = false
view?.findViewById<FrameLayout>(R.id.top_bar)?.visibility = View.VISIBLE view?.findViewById<LinearLayout>(R.id.top_bar)?.visibility = View.VISIBLE
} }
} }

View File

@ -0,0 +1,31 @@
package com.github.libretube.services
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.util.Log
import androidx.annotation.Nullable
class ClosingService : Service() {
private val TAG = "ClosingService"
@Nullable
override fun onBind(intent: Intent?): IBinder? {
return null
}
// Handle application closing
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
// destroy all notifications (especially the player notification)
val nManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
nManager.cancelAll()
Log.e(TAG, "closed")
// Destroy the service
stopSelf()
}
}

View File

@ -1,4 +1,4 @@
package com.github.libretube package com.github.libretube.services
import android.app.DownloadManager import android.app.DownloadManager
import android.app.PendingIntent import android.app.PendingIntent
@ -18,6 +18,7 @@ import android.util.Log
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import com.arthenica.ffmpegkit.FFmpegKit import com.arthenica.ffmpegkit.FFmpegKit
import com.github.libretube.R
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
import java.io.File import java.io.File

View File

@ -10,8 +10,8 @@
<ImageButton <ImageButton
android:id="@+id/back_imageButton" android:id="@+id/back_imageButton"
android:layout_width="wrap_content" android:layout_width="27dp"
android:layout_height="wrap_content" android:layout_height="27dp"
android:layout_marginVertical="10dp" android:layout_marginVertical="10dp"
android:layout_marginLeft="15dp" android:layout_marginLeft="15dp"
android:background="?android:selectableItemBackgroundBorderless" android:background="?android:selectableItemBackgroundBorderless"

View File

@ -1,14 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="80dp" android:layout_width="100dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginHorizontal="5dp"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <com.google.android.material.imageview.ShapeableImageView
app:shapeAppearanceOverlay="@style/roundedImageViewRounded"
android:id="@+id/chapter_image" android:id="@+id/chapter_image"
android:layout_width="80dp" android:layout_width="match_parent"
android:layout_height="45dp" android:layout_height="55dp"
android:src="@mipmap/ic_launcher" /> android:src="@mipmap/ic_launcher" />
<TextView <TextView

View File

@ -23,7 +23,8 @@
android:id="@+id/linLayout" android:id="@+id/linLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical"
android:animateLayoutChanges="true" >
<RelativeLayout <RelativeLayout
android:id="@+id/player_title_layout" android:id="@+id/player_title_layout"
@ -55,108 +56,84 @@
</RelativeLayout> </RelativeLayout>
<RelativeLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" android:layout_marginHorizontal="10dp"
android:layout_marginTop="5dp"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView
android:id="@+id/player_views_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="10M views 2 days ago " />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:layout_marginLeft="3dp"
android:layout_marginTop="2dp">
<TextView
android:id="@+id/player_views_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="10M views 2 days ago " />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginTop="2dp">
<ImageView
android:layout_gravity="center"
android:layout_width="15dp"
android:layout_height="15dp"
android:src="@drawable/ic_like" />
<TextView
android:id="@+id/textLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:text="4.2K" />
<ImageView
android:layout_gravity="center"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginLeft="5dp"
android:src="@drawable/ic_like"
android:rotation="180"/>
<TextView
android:id="@+id/textDislike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:text="1.3K" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/chapters_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:orientation="horizontal"
android:visibility="gone">
<TextView
android:id="@+id/chapters_toggle_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/show_chapters" />
<ImageView <ImageView
android:id="@+id/chapters_toggle_arrow" android:layout_width="12dp"
android:layout_width="16dp" android:layout_height="12dp"
android:layout_height="16dp" android:layout_gravity="center"
android:layout_gravity="bottom" android:src="@drawable/ic_like" />
android:src="@drawable/ic_arrow_down" />
<TextView
android:id="@+id/textLike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:text="4.2K" />
<ImageView
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:rotation="180"
android:src="@drawable/ic_like" />
<TextView
android:id="@+id/textDislike"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:text="1.3K" />
</LinearLayout> </LinearLayout>
</RelativeLayout> </LinearLayout>
<androidx.recyclerview.widget.RecyclerView <LinearLayout
android:id="@+id/chapters_recView" android:id="@+id/desc_linLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/comments_toggle" android:orientation="vertical"
android:layout_marginLeft="10dp" android:visibility="gone">
android:layout_marginTop="20dp"
android:layout_marginRight="10dp"
android:nestedScrollingEnabled="false"
android:visibility="gone" />
<TextView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/player_description" android:id="@+id/chapters_recView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:autoLink="web" android:layout_below="@id/comments_toggle"
android:padding="8dp" android:layout_marginHorizontal="3dp"
android:textIsSelectable="true" android:layout_marginTop="20dp"
android:textSize="14sp" android:nestedScrollingEnabled="false"
android:visibility="gone" /> android:visibility="gone" />
<TextView
android:id="@+id/player_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:padding="8dp"
android:textIsSelectable="true"
android:textSize="14sp" />
</LinearLayout>
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
style="@style/Widget.Material3.CardView.Elevated" style="@style/Widget.Material3.CardView.Elevated"
@ -315,6 +292,7 @@
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:descendantFocusability="blocksDescendants"> android:descendantFocusability="blocksDescendants">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView

View File

@ -30,20 +30,12 @@
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
<item name="android:paddingLeft">20dp</item> <item name="android:paddingLeft">20dp</item>
<item name="android:paddingRight">20dp</item> <item name="android:paddingRight">20dp</item>
<item name="android:paddingTop">15dp</item> <item name="android:paddingTop">12dp</item>
<item name="android:paddingBottom">15dp</item> <item name="android:paddingBottom">12dp</item>
<item name="android:background">?android:attr/selectableItemBackground</item> <item name="android:background">?android:attr/selectableItemBackground</item>
</style> </style>
<style name="HorizontalLine">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">0.8dp</item>
<item name="android:background">@android:color/darker_gray</item>
</style>
<style name="CustomDialogButton" parent="@style/Widget.Material3.Button.TextButton"> <style name="CustomDialogButton" parent="@style/Widget.Material3.Button.TextButton">
<item name="android:layout_width">wrap_content</item> <item name="android:layout_width">wrap_content</item>