Skip to content

Commit

Permalink
Check for update done
Browse files Browse the repository at this point in the history
  • Loading branch information
maxrave-dev committed Sep 7, 2023
1 parent cc17a4e commit b1fb07f
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import android.util.Log
import com.maxrave.kotlinytmusicscraper.YouTube
import com.maxrave.kotlinytmusicscraper.models.MusicShelfRenderer
import com.maxrave.kotlinytmusicscraper.models.response.PipedResponse
import com.maxrave.kotlinytmusicscraper.models.simpmusic.GithubResponse
import com.maxrave.kotlinytmusicscraper.models.sponsorblock.SkipSegments
import com.maxrave.simpmusic.data.dataStore.DataStoreManager
import com.maxrave.simpmusic.data.db.LocalDataSource
import com.maxrave.simpmusic.data.db.entities.AlbumEntity
Expand Down Expand Up @@ -637,7 +639,7 @@ class MainRepository @Inject constructor(private val localDataSource: LocalDataS
runCatching {
val q = query.replace(Regex("\\([^)]*?(feat.|ft.|cùng với|con)[^)]*?\\)"), "").replace(" ", " ")
Log.d("Lyrics", "query: $q")
YouTube.authencation().onSuccess {token ->
YouTube.authentication().onSuccess { token ->
if (token.accessToken != null) {
YouTube.getSongId(token.accessToken!!, q).onSuccess { spotifyResult ->
Log.d("SongId", "id: ${spotifyResult.tracks?.items?.get(0)?.id}")
Expand Down Expand Up @@ -675,7 +677,7 @@ class MainRepository @Inject constructor(private val localDataSource: LocalDataS
suspend fun getStream(videoId: String, itag: Int): Flow<String?> = flow{
val instance = runBlocking { dataStoreManager.pipedInstance.first() }
YouTube.player(videoId, instance).onSuccess { response ->
val format = response.streamingData?.formats?.find { it.itag == itag}
val format = response.streamingData?.formats?.find { it.itag == itag}
runBlocking {
insertFormat(
FormatEntity(
Expand All @@ -699,11 +701,27 @@ class MainRepository @Inject constructor(private val localDataSource: LocalDataS
emit(null)
}
}.flowOn(Dispatchers.IO)
suspend fun getSkipSegments(videoId: String): Flow<List<SkipSegments>?> = flow {
YouTube.getSkipSegments(videoId).onSuccess {
emit(it)
}.onFailure {
emit(null)
}
}.flowOn(Dispatchers.IO)

fun getSongFull(videoId: String): Flow<PipedResponse> = flow {
val instance = runBlocking { dataStoreManager.pipedInstance.first() }
YouTube.pipeStream(videoId, instance).onSuccess {
emit(it)
}
}.flowOn(Dispatchers.IO)

fun checkForUpdate(): Flow<GithubResponse?> = flow {
YouTube.checkForUpdate().onSuccess {
emit(it)
}
.onFailure {
emit(null)
}
}
}
38 changes: 35 additions & 3 deletions app/src/main/java/com/maxrave/simpmusic/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import android.graphics.drawable.GradientDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.ContactsContract.Data
import android.text.Html
import android.util.Log
import android.view.View
import android.view.animation.AnimationUtils
Expand All @@ -27,7 +27,6 @@ import androidx.lifecycle.repeatOnLifecycle
import androidx.lifecycle.switchMap
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.offline.DownloadService
import androidx.navigation.NavController
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.setupWithNavController
import androidx.palette.graphics.Palette
Expand All @@ -36,6 +35,7 @@ import coil.request.ImageRequest
import coil.size.Size
import coil.transform.Transformation
import com.daimajia.swipe.SwipeLayout
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.maxrave.kotlinytmusicscraper.YouTube
import com.maxrave.kotlinytmusicscraper.models.YouTubeLocale
import com.maxrave.simpmusic.R
Expand All @@ -50,7 +50,6 @@ import com.maxrave.simpmusic.data.dataStore.DataStoreManager.Settings.RESTORE_LA
import com.maxrave.simpmusic.data.model.browse.album.Track
import com.maxrave.simpmusic.data.queue.Queue
import com.maxrave.simpmusic.databinding.ActivityMainBinding
import com.maxrave.simpmusic.extension.dataStore
import com.maxrave.simpmusic.extension.isMyServiceRunning
import com.maxrave.simpmusic.extension.toTrack
import com.maxrave.simpmusic.service.SimpleMediaService
Expand All @@ -65,6 +64,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import pub.devrel.easypermissions.EasyPermissions
import java.text.SimpleDateFormat
import java.util.Locale
import javax.inject.Inject

Expand Down Expand Up @@ -473,9 +473,13 @@ class MainActivity : AppCompatActivity() {
)
)
}
checkForUpdate()
}
}
}
else {
checkForUpdate()
}
}

override fun onDestroy() {
Expand Down Expand Up @@ -559,6 +563,34 @@ class MainActivity : AppCompatActivity() {
binding.miniPlayerContainer.visibility = View.VISIBLE
}

private fun checkForUpdate() {
viewModel.checkForUpdate()
viewModel.githubResponse.observe(this) {response ->
if (response != null) {
if (response.tagName != getString(R.string.version_name)) {
val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault())
val outputFormat = SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.getDefault())
val formatted = response.publishedAt?.let { input ->
inputFormat.parse(input)
?.let { outputFormat.format(it) }
}

MaterialAlertDialogBuilder(this)
.setTitle(getString(R.string.update_available))
.setMessage(getString(R.string.update_message, response.tagName, formatted, Html.fromHtml(response.body, Html.FROM_HTML_MODE_COMPACT)))
.setPositiveButton(getString(R.string.download)) { _, _ ->
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(response.assets?.firstOrNull()?.browserDownloadUrl))
startActivity(browserIntent)
}
.setNegativeButton(getString(R.string.cancel)) { dialog, _ ->
dialog.dismiss()
}
.show()
}
}
}
}

private fun putString(key: String, value: String) {
viewModel.putString(key, value)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Intent
import android.media.audiofx.AudioEffect
import android.net.Uri
import android.os.Bundle
import android.text.Html
import android.util.Log
import android.view.LayoutInflater
import android.view.View
Expand All @@ -30,8 +31,12 @@ import com.maxrave.simpmusic.databinding.FragmentSettingsBinding
import com.maxrave.simpmusic.viewModel.SettingsViewModel
import dagger.hilt.android.AndroidEntryPoint
import dev.chrisbanes.insetter.applyInsetter
import java.text.SimpleDateFormat
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Locale
import javax.inject.Inject

@UnstableApi
Expand Down Expand Up @@ -101,6 +106,7 @@ class SettingsFragment : Fragment() {
viewModel.getSavedPlaybackState()
viewModel.getPipedInstance()
viewModel.getSaveRecentSongAndQueue()
viewModel.getLastCheckForUpdate()

val diskCache = context?.imageLoader?.diskCache

Expand Down Expand Up @@ -152,6 +158,39 @@ class SettingsFragment : Fragment() {
viewModel.pipedInstance.observe(viewLifecycleOwner) {
binding.tvPipedInstance.text = it
}
viewModel.lastCheckForUpdate.observe(viewLifecycleOwner) {
binding.tvCheckForUpdate.text = getString(R.string.last_checked_at, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneId.systemDefault())
.format(Instant.ofEpochMilli(it.toLong())))
}
binding.btCheckForUpdate.setOnClickListener {
binding.tvCheckForUpdate.text = getString(R.string.checking)
viewModel.checkForUpdate()
viewModel.githubResponse.observe(viewLifecycleOwner) {response ->
if (it != null) {
binding.tvCheckForUpdate.text = getString(R.string.last_checked_at, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneId.systemDefault())
.format(Instant.ofEpochMilli(System.currentTimeMillis())))
val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault())
val outputFormat = SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.getDefault())
val formatted = response.publishedAt?.let { input ->
inputFormat.parse(input)
?.let { outputFormat.format(it) }
}
MaterialAlertDialogBuilder(requireContext())
.setTitle(getString(R.string.update_available))
.setMessage(getString(R.string.update_message, response.tagName, formatted, Html.fromHtml(response.body, Html.FROM_HTML_MODE_COMPACT)))
.setPositiveButton(getString(R.string.download)) { _, _ ->
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(response.assets?.firstOrNull()?.browserDownloadUrl))
startActivity(browserIntent)
}
.setNegativeButton(getString(R.string.cancel)) { dialog, _ ->
dialog.dismiss()
}
.show()
}
}
}

binding.btVersion.setOnClickListener {
val urlIntent = Intent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.cache.SimpleCache
import com.maxrave.kotlinytmusicscraper.YouTube
import com.maxrave.kotlinytmusicscraper.models.YouTubeLocale
import com.maxrave.kotlinytmusicscraper.models.simpmusic.GithubResponse
import com.maxrave.simpmusic.R
import com.maxrave.simpmusic.common.DB_NAME
import com.maxrave.simpmusic.common.DownloadState
Expand All @@ -31,6 +32,7 @@ import com.maxrave.simpmusic.service.SimpleMediaServiceHandler
import com.maxrave.simpmusic.ui.MainActivity
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -70,6 +72,19 @@ class SettingsViewModel @Inject constructor(
val savedPlaybackState: LiveData<String> = _savedPlaybackState
private var _saveRecentSongAndQueue: MutableLiveData<String> = MutableLiveData()
val saveRecentSongAndQueue: LiveData<String> = _saveRecentSongAndQueue
private var _lastCheckForUpdate: MutableLiveData<String> = MutableLiveData()
val lastCheckForUpdate: LiveData<String> = _lastCheckForUpdate
private var _githubResponse = MutableLiveData<GithubResponse>()
val githubResponse: LiveData<GithubResponse> = _githubResponse

fun checkForUpdate() {
viewModelScope.launch {
mainRepository.checkForUpdate().collect {response ->
dataStoreManager.putString("CheckForUpdateAt", System.currentTimeMillis().toString())
_githubResponse.postValue(response)
}
}
}

fun getLocation() {
viewModelScope.launch {
Expand Down Expand Up @@ -108,6 +123,15 @@ class SettingsViewModel @Inject constructor(
}
}
}
fun getLastCheckForUpdate() {
viewModelScope.launch {
withContext(Dispatchers.Main) {
dataStoreManager.getString("CheckForUpdateAt").first().let { lastCheckForUpdate ->
_lastCheckForUpdate.postValue(lastCheckForUpdate)
}
}
}
}
private var _quality: MutableLiveData<String> = MutableLiveData()
val quality: LiveData<String> = _quality

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.media3.datasource.cache.SimpleCache
import androidx.media3.exoplayer.offline.Download
import com.maxrave.kotlinytmusicscraper.YouTube
import com.maxrave.kotlinytmusicscraper.models.response.PipedResponse
import com.maxrave.kotlinytmusicscraper.models.simpmusic.GithubResponse
import com.maxrave.simpmusic.R
import com.maxrave.simpmusic.common.Config
import com.maxrave.simpmusic.common.DownloadState
Expand Down Expand Up @@ -206,6 +207,7 @@ class SharedViewModel @Inject constructor(private var dataStoreManager: DataStor
simpleMediaServiceHandler.nowPlaying.collectLatest { nowPlaying ->
if (nowPlaying != null && getCurrentMediaItemIndex() > 0) {
_nowPlayingMediaItem.postValue(nowPlaying)
getSkipSegments(nowPlaying.mediaId)
var downloaded = false
val tempSong = musicSource.catalogMetadata[getCurrentMediaItemIndex()]
Log.d("Check tempSong", tempSong.toString())
Expand Down Expand Up @@ -371,6 +373,15 @@ class SharedViewModel @Inject constructor(private var dataStoreManager: DataStor
mainRepository.insertLyrics(lyrics)
}
}
fun getSkipSegments(videoId: String) {
viewModelScope.launch {
mainRepository.getSkipSegments(videoId).collect { segments ->
if (segments != null) {
Log.w("Check segments ${videoId}", segments.toString())
}
}
}
}
fun getSavedLyrics(videoId: String, query: String) {
viewModelScope.launch {
resetLyrics()
Expand Down Expand Up @@ -900,6 +911,17 @@ class SharedViewModel @Inject constructor(private var dataStoreManager: DataStor
mainRepository.removeQueue()
}
}
private var _githubResponse = MutableLiveData<GithubResponse>()
val githubResponse: LiveData<GithubResponse> = _githubResponse

fun checkForUpdate() {
viewModelScope.launch {
mainRepository.checkForUpdate().collect {response ->
dataStoreManager.putString("CheckForUpdateAt", System.currentTimeMillis().toString())
_githubResponse.postValue(response)
}
}
}
}
sealed class UIEvent {
data object PlayPause : UIEvent()
Expand Down
27 changes: 27 additions & 0 deletions app/src/main/res/layout/fragment_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,33 @@

</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginVertical="5sp"
android:layout_marginStart="15sp"
android:id="@+id/btCheckForUpdate"
android:focusable="true"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground">
<TextView
android:textSize = "16sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:text = "@string/check_for_update">

</TextView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:id="@+id/tvCheckForUpdate"
android:text="@string/last_checked_at">

</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@
<string name="time_out_check_internet_connection_or_change_piped_instance_in_settings">Time out, check internet connection or change Piped instance in Settings</string>
<string name="save_last_played">Save Last Played</string>
<string name="save_last_played_track_and_queue">Save last played track and queue</string>
<string name="update_available">New update available</string>
<string name="update_message">"Version %1$s available\nRelease: %2$s\nChange logs:\n%3$s "</string>
<string name="check_for_update">Check for update</string>
<string name="last_checked_at">Last checked at %1$s</string>
<string name="checking">Checking</string>
<plurals name="n_song">
<item quantity="one">%d song</item>
<item quantity="other">%d songs</item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ import com.maxrave.kotlinytmusicscraper.models.response.NextResponse
import com.maxrave.kotlinytmusicscraper.models.response.PipedResponse
import com.maxrave.kotlinytmusicscraper.models.response.PlayerResponse
import com.maxrave.kotlinytmusicscraper.models.response.SearchResponse
import com.maxrave.kotlinytmusicscraper.models.simpmusic.GithubResponse
import com.maxrave.kotlinytmusicscraper.models.splitBySeparator
import com.maxrave.kotlinytmusicscraper.models.sponsorblock.SkipSegments
import com.maxrave.kotlinytmusicscraper.models.spotify.SpotifyResult
import com.maxrave.kotlinytmusicscraper.models.spotify.Token
import com.maxrave.kotlinytmusicscraper.pages.AlbumPage
Expand Down Expand Up @@ -225,7 +227,7 @@ object YouTube {
suspend fun getLyrics(songId: String) = runCatching {
ytMusic.getLyrics(songId).body<Lyrics>()
}
suspend fun authencation() = runCatching {
suspend fun authentication() = runCatching {
ytMusic.authorizationSpotify().body<Token>()
}
suspend fun getSongId(authorization: String, query: String) = runCatching {
Expand All @@ -246,6 +248,14 @@ object YouTube {
return@runCatching listSuggest
}

suspend fun getSkipSegments(videoId: String) = runCatching {
ytMusic.getSkipSegments(videoId).body<List<SkipSegments>>()
}

suspend fun checkForUpdate() = runCatching {
ytMusic.checkForUpdate().body<GithubResponse>()
}

suspend fun explore(): Result<ExplorePage> = runCatching {
val response = ytMusic.browse(WEB_REMIX, browseId = "FEmusic_explore").body<BrowseResponse>()
ExplorePage(
Expand Down
Loading

0 comments on commit b1fb07f

Please sign in to comment.