diff --git a/app/build.gradle b/app/build.gradle index 5b953e41e..715f56fa6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -88,11 +88,7 @@ dependencies { implementation "androidx.core:core-splashscreen:1.0.0-beta02" implementation "com.google.android.material:material:$mdc_version" - - def retrofit_version = '2.9.0' - implementation "com.squareup.retrofit2:retrofit:$retrofit_version" - implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" - implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.7' + implementation 'com.google.code.gson:gson:2.9.0' def material_dialog_version = "3.3.0" implementation "com.afollestad.material-dialogs:core:$material_dialog_version" @@ -114,7 +110,6 @@ dependencies { def glide_version = '4.13.2' implementation "com.github.bumptech.glide:glide:$glide_version" kapt "com.github.bumptech.glide:compiler:$glide_version" - implementation "com.github.bumptech.glide:okhttp3-integration:$glide_version" implementation 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:1.0.0' @@ -125,7 +120,6 @@ dependencies { implementation "dev.chrisbanes.insetter:insetter:0.6.1" - implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5' implementation 'com.github.Adonai:jaudiotagger:2.3.15' implementation 'com.r0adkll:slidableactivity:2.1.0' implementation 'com.heinrichreimersoftware:material-intro:2.0.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index aecd3aea2..ee4c85ccf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,8 +15,6 @@ - - - if (actionId == EditorInfo.IME_ACTION_SEND) { - reportIssue() - return@setOnEditorActionListener true - } - false - } binding.cardDeviceInfo.airTextDeviceInfo.setOnClickListener { copyDeviceInfoToClipBoard() } TintHelper.setTintAuto(binding.sendFab, accentColor, true) binding.sendFab.setOnClickListener { reportIssue() } - - MaterialUtil.setTint(binding.cardReport.inputLayoutTitle, false) - MaterialUtil.setTint(binding.cardReport.inputLayoutDescription, false) - MaterialUtil.setTint(binding.cardReport.inputLayoutUsername, false) - MaterialUtil.setTint(binding.cardReport.inputLayoutPassword, false) } private fun reportIssue() { - if (binding.cardReport.optionUseAccount.isChecked) { - if (!validateInput()) return - val username = binding.cardReport.inputUsername.text.toString() - val password = binding.cardReport.inputPassword.text.toString() - sendBugReport(GithubLogin(username, password)) - } else { - copyDeviceInfoToClipBoard() + copyDeviceInfoToClipBoard() - val i = Intent(Intent.ACTION_VIEW) - i.data = ISSUE_TRACKER_LINK.toUri() - i.flags = Intent.FLAG_ACTIVITY_NEW_TASK - startActivity(i) - } + val i = Intent(Intent.ACTION_VIEW) + i.data = ISSUE_TRACKER_LINK.toUri() + i.flags = Intent.FLAG_ACTIVITY_NEW_TASK + startActivity(i) } private fun copyDeviceInfoToClipBoard() { @@ -166,67 +78,6 @@ open class BugReportActivity : AbsThemeActivity() { showToast(R.string.copied_device_info_to_clipboard) } - private fun validateInput(): Boolean { - var hasErrors = false - - if (binding.cardReport.optionUseAccount.isChecked) { - if (binding.cardReport.inputUsername.text.isNullOrEmpty()) { - setError(binding.cardReport.inputLayoutUsername, R.string.bug_report_no_username) - hasErrors = true - } else { - removeError(binding.cardReport.inputLayoutUsername) - } - - if (binding.cardReport.inputPassword.text.isNullOrEmpty()) { - setError(binding.cardReport.inputLayoutPassword, R.string.bug_report_no_password) - hasErrors = true - } else { - removeError(binding.cardReport.inputLayoutPassword) - } - } - - if (binding.cardReport.inputTitle.text.isNullOrEmpty()) { - setError(binding.cardReport.inputLayoutTitle, R.string.bug_report_no_title) - hasErrors = true - } else { - removeError(binding.cardReport.inputLayoutTitle) - } - - if (binding.cardReport.inputDescription.text.isNullOrEmpty()) { - setError(binding.cardReport.inputLayoutDescription, R.string.bug_report_no_description) - hasErrors = true - } else { - removeError(binding.cardReport.inputLayoutDescription) - } - - return !hasErrors - } - - private fun setError(editTextLayout: TextInputLayout, @StringRes errorRes: Int) { - editTextLayout.error = getString(errorRes) - } - - private fun removeError(editTextLayout: TextInputLayout) { - editTextLayout.error = null - } - - private fun sendBugReport(login: GithubLogin) { - if (!validateInput()) return - - val bugTitle = binding.cardReport.inputTitle.text.toString() - val bugDescription = binding.cardReport.inputDescription.text.toString() - - val extraInfo = ExtraInfo() - onSaveExtraInfo() - - val report = Report(bugTitle, bugDescription, deviceInfo, extraInfo) - val target = GithubTarget("RetroMusicPlayer", "RetroMusicPlayer") - - reportIssue(report, target, login) - } - - private fun onSaveExtraInfo() {} - override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == android.R.id.home) { onBackPressed() @@ -234,72 +85,6 @@ open class BugReportActivity : AbsThemeActivity() { return super.onOptionsItemSelected(item) } - private fun reportIssue( - report: Report, - target: GithubTarget, - login: GithubLogin - ) { - val client: GitHubClient = if (login.shouldUseApiToken()) { - GitHubClient().setOAuth2Token(login.apiToken) - } else { - GitHubClient().setCredentials(login.username, login.password) - } - - val issue = Issue().setTitle(report.title).setBody(report.getDescription()) - - lifecycleScope.launch(Dispatchers.IO) { - val result = try { - IssueService(client).createIssue(target.username, target.repository, issue) - RESULT_SUCCESS - } catch (e: RequestException) { - when (e.status) { - STATUS_BAD_CREDENTIALS -> { - if (login.shouldUseApiToken()) RESULT_INVALID_TOKEN else RESULT_BAD_CREDENTIALS - } - STATUS_ISSUES_NOT_ENABLED -> RESULT_ISSUES_NOT_ENABLED - else -> { - RESULT_UNKNOWN - throw e - } - } - } catch (e: IOException) { - e.printStackTrace() - RESULT_UNKNOWN - } - - withContext(Dispatchers.Main) { - val activity = this@BugReportActivity - when (result) { - RESULT_SUCCESS -> MaterialAlertDialogBuilder(activity) - .setTitle(R.string.bug_report_success) - .setPositiveButton(android.R.string.ok) { _, _ -> tryToFinishActivity() } - .show() - RESULT_BAD_CREDENTIALS -> MaterialAlertDialogBuilder(activity) - .setTitle(R.string.bug_report_failed) - .setMessage(R.string.bug_report_failed_wrong_credentials) - .setPositiveButton(android.R.string.ok, null) - .show() - RESULT_INVALID_TOKEN -> MaterialAlertDialogBuilder(activity) - .setTitle(R.string.bug_report_failed) - .setMessage(R.string.bug_report_failed_invalid_token) - .setPositiveButton(android.R.string.ok, null) - .show() - RESULT_ISSUES_NOT_ENABLED -> MaterialAlertDialogBuilder(activity) - .setTitle(R.string.bug_report_failed) - .setMessage(R.string.bug_report_failed_issues_not_available) - .setPositiveButton(android.R.string.ok, null) - .show() - else -> MaterialAlertDialogBuilder(activity) - .setTitle(R.string.bug_report_failed) - .setMessage(R.string.bug_report_failed_unknown) - .setPositiveButton(android.R.string.ok) { _, _ -> tryToFinishActivity() } - .setNegativeButton(android.R.string.cancel) { _, _ -> tryToFinishActivity() } - .show() - } - } - } - } - private fun tryToFinishActivity() { if (!isFinishing) { finish() @@ -307,10 +92,7 @@ open class BugReportActivity : AbsThemeActivity() { } companion object { - - private const val STATUS_BAD_CREDENTIALS = 401 - private const val STATUS_ISSUES_NOT_ENABLED = 410 private const val ISSUE_TRACKER_LINK = - "https://github.com/RetroMusicPlayer/RetroMusicPlayer" + "https://github.com/MuntashirAkon/Metro/issues/new" } } diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/Report.kt b/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/Report.kt deleted file mode 100644 index 4de47bdd7..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/Report.kt +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.muntashirakon.music.activities.bugreport.model - -import io.github.muntashirakon.music.activities.bugreport.model.github.ExtraInfo - -class Report( - val title: String, - private val description: String, - private val deviceInfo: DeviceInfo?, - private val extraInfo: ExtraInfo -) { - fun getDescription(): String { - return """ - $description - - - - - ${deviceInfo?.toMarkdown()} - - ${extraInfo.toMarkdown()} - """.trimIndent() - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/github/ExtraInfo.kt b/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/github/ExtraInfo.kt deleted file mode 100644 index 90a50a229..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/github/ExtraInfo.kt +++ /dev/null @@ -1,61 +0,0 @@ -package io.github.muntashirakon.music.activities.bugreport.model.github - -class ExtraInfo { - private val extraInfo: MutableMap = LinkedHashMap() - fun put(key: String, value: String) { - extraInfo[key] = value - } - - fun put(key: String, value: Boolean) { - extraInfo[key] = value.toString() - } - - fun put(key: String, value: Double) { - extraInfo[key] = value.toString() - } - - fun put(key: String, value: Float) { - extraInfo[key] = value.toString() - } - - fun put(key: String, value: Long) { - extraInfo[key] = value.toString() - } - - fun put(key: String, value: Int) { - extraInfo[key] = value.toString() - } - - fun put(key: String, value: Any) { - extraInfo[key] = value.toString() - } - - fun remove(key: String) { - extraInfo.remove(key) - } - - fun toMarkdown(): String { - if (extraInfo.isEmpty()) { - return "" - } - val output = StringBuilder() - output.append( - """ - Extra info: - --- - - - """.trimIndent() - ) - for (key in extraInfo.keys) { - output - .append("") - .append(key) - .append("") - .append(extraInfo[key]) - .append("\n") - } - output.append("\n") - return output.toString() - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/github/GithubLogin.kt b/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/github/GithubLogin.kt deleted file mode 100644 index 3bac9ce56..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/github/GithubLogin.kt +++ /dev/null @@ -1,25 +0,0 @@ -package io.github.muntashirakon.music.activities.bugreport.model.github - -import android.text.TextUtils - -class GithubLogin { - val apiToken: String? - val password: String? - val username: String? - - constructor(username: String?, password: String?) { - this.username = username - this.password = password - apiToken = null - } - - constructor(apiToken: String?) { - username = null - password = null - this.apiToken = apiToken - } - - fun shouldUseApiToken(): Boolean { - return TextUtils.isEmpty(username) || TextUtils.isEmpty(password) - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/github/GithubTarget.kt b/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/github/GithubTarget.kt deleted file mode 100644 index 3e1db581b..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/activities/bugreport/model/github/GithubTarget.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.github.muntashirakon.music.activities.bugreport.model.github - -class GithubTarget(val username: String, val repository: String) \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsFragment.kt index c1d552a19..972caadb9 100644 --- a/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsFragment.kt +++ b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsFragment.kt @@ -22,7 +22,6 @@ import android.view.* import androidx.activity.addCallback import androidx.appcompat.app.AppCompatActivity import androidx.core.os.bundleOf -import androidx.core.text.parseAsHtml import androidx.core.view.doOnPreDraw import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.FragmentNavigatorExtras @@ -59,13 +58,10 @@ import io.github.muntashirakon.music.interfaces.ICabCallback import io.github.muntashirakon.music.interfaces.ICabHolder import io.github.muntashirakon.music.model.Album import io.github.muntashirakon.music.model.Artist -import io.github.muntashirakon.music.network.Result -import io.github.muntashirakon.music.network.model.LastFmAlbum import io.github.muntashirakon.music.repository.RealRepository import io.github.muntashirakon.music.util.MusicUtil import io.github.muntashirakon.music.util.PreferenceUtil import io.github.muntashirakon.music.util.RetroColorUtil -import io.github.muntashirakon.music.util.RetroUtil import com.afollestad.materialcab.attached.AttachedCab import com.afollestad.materialcab.attached.destroy import com.afollestad.materialcab.attached.isActive @@ -162,14 +158,6 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det ) } - binding.fragmentAlbumContent.aboutAlbumText.setOnClickListener { - if (binding.fragmentAlbumContent.aboutAlbumText.maxLines == 4) { - binding.fragmentAlbumContent.aboutAlbumText.maxLines = Integer.MAX_VALUE - } else { - binding.fragmentAlbumContent.aboutAlbumText.maxLines = 4 - } - } - requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { if (!handleBackPress()) { remove() @@ -240,21 +228,6 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det loadArtistImage(it) } } - - - detailsViewModel.getAlbumInfo(album).observe(viewLifecycleOwner) { result -> - when (result) { - is Result.Loading -> { - println("Loading") - } - is Result.Error -> { - println("Error") - } - is Result.Success -> { - aboutAlbum(result.data) - } - } - } } private fun moreAlbums(albums: List) { @@ -274,41 +247,13 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det binding.fragmentAlbumContent.moreRecyclerView.adapter = albumAdapter } - private fun aboutAlbum(lastFmAlbum: LastFmAlbum) { - if (lastFmAlbum.album != null) { - if (lastFmAlbum.album.wiki != null) { - binding.fragmentAlbumContent.aboutAlbumText.show() - binding.fragmentAlbumContent.aboutAlbumTitle.show() - binding.fragmentAlbumContent.aboutAlbumTitle.text = - String.format(getString(R.string.about_album_label), lastFmAlbum.album.name) - binding.fragmentAlbumContent.aboutAlbumText.text = - lastFmAlbum.album.wiki.content.parseAsHtml() - } - if (lastFmAlbum.album.listeners.isNotEmpty()) { - binding.fragmentAlbumContent.listeners.show() - binding.fragmentAlbumContent.listenersLabel.show() - binding.fragmentAlbumContent.scrobbles.show() - binding.fragmentAlbumContent.scrobblesLabel.show() - - binding.fragmentAlbumContent.listeners.text = - RetroUtil.formatValue(lastFmAlbum.album.listeners.toFloat()) - binding.fragmentAlbumContent.scrobbles.text = - RetroUtil.formatValue(lastFmAlbum.album.playcount.toFloat()) - } - } - } - private fun loadArtistImage(artist: Artist) { detailsViewModel.getMoreAlbums(artist).observe(viewLifecycleOwner) { moreAlbums(it) } GlideApp.with(requireContext()) - //.forceDownload(PreferenceUtil.isAllowedToDownloadMetadata()) .load( - RetroGlideExtension.getArtistModel( - artist, - PreferenceUtil.isAllowedToDownloadMetadata(requireContext()) - ) + RetroGlideExtension.getArtistModel(artist) ) .artistImageOptions(artist) .dontAnimate() diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsViewModel.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsViewModel.kt index 677dab835..1c371a7f8 100644 --- a/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsViewModel.kt +++ b/app/src/main/java/io/github/muntashirakon/music/fragments/albums/AlbumDetailsViewModel.kt @@ -18,8 +18,6 @@ import androidx.lifecycle.* import io.github.muntashirakon.music.interfaces.IMusicServiceEventListener import io.github.muntashirakon.music.model.Album import io.github.muntashirakon.music.model.Artist -import io.github.muntashirakon.music.network.Result -import io.github.muntashirakon.music.network.model.LastFmAlbum import io.github.muntashirakon.music.repository.RealRepository import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch @@ -52,11 +50,6 @@ class AlbumDetailsViewModel( emit(artist) } - fun getAlbumInfo(album: Album): LiveData> = liveData(IO) { - emit(Result.Loading) - emit(repository.albumInfo(album.artistName, album.title)) - } - fun getMoreAlbums(artist: Artist): LiveData> = liveData(IO) { artist.albums.filter { item -> item.id != albumId }.let { albums -> if (albums.isNotEmpty()) emit(albums) diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/artists/AbsArtistDetailsFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/AbsArtistDetailsFragment.kt index c3002a004..cca577bde 100644 --- a/app/src/main/java/io/github/muntashirakon/music/fragments/artists/AbsArtistDetailsFragment.kt +++ b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/AbsArtistDetailsFragment.kt @@ -13,9 +13,7 @@ import androidx.activity.addCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.widget.PopupMenu import androidx.core.os.bundleOf -import androidx.core.text.parseAsHtml import androidx.core.view.doOnPreDraw -import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.FragmentNavigatorExtras import androidx.navigation.fragment.findNavController @@ -39,8 +37,6 @@ import io.github.muntashirakon.music.interfaces.IAlbumClickListener import io.github.muntashirakon.music.interfaces.ICabCallback import io.github.muntashirakon.music.interfaces.ICabHolder import io.github.muntashirakon.music.model.Artist -import io.github.muntashirakon.music.network.Result -import io.github.muntashirakon.music.network.model.LastFmArtist import io.github.muntashirakon.music.repository.RealRepository import io.github.muntashirakon.music.util.* import com.afollestad.materialcab.attached.AttachedCab @@ -67,8 +63,6 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm private lateinit var songAdapter: SimpleSongAdapter private lateinit var albumAdapter: HorizontalAlbumAdapter private var forceDownload: Boolean = false - private var lang: String? = null - private var biography: Spanned? = null private val savedSongSortOrder: String get() = PreferenceUtil.artistDetailSongSortOrder @@ -105,14 +99,6 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) } } - binding.fragmentArtistContent.biographyText.setOnClickListener { - if (binding.fragmentArtistContent.biographyText.maxLines == 4) { - binding.fragmentArtistContent.biographyText.maxLines = Integer.MAX_VALUE - } else { - binding.fragmentArtistContent.biographyText.maxLines = 4 - } - } - requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { if (!handleBackPress()) { remove() @@ -146,9 +132,6 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm } this.artist = artist loadArtistImage(artist) - if (PreferenceUtil.isAllowedToDownloadMetadata(requireContext())) { - loadBiography(artist.name) - } binding.artistTitle.text = artist.name binding.text.text = String.format( "%s • %s", @@ -171,51 +154,6 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm albumAdapter.swapDataSet(artist.albums) } - private fun loadBiography( - name: String, - lang: String? = Locale.getDefault().language, - ) { - biography = null - this.lang = lang - detailsViewModel.getArtistInfo(name, lang, null) - .observe(viewLifecycleOwner) { result -> - when (result) { - is Result.Loading -> println("Loading") - is Result.Error -> println("Error") - is Result.Success -> artistInfo(result.data) - } - } - } - - private fun artistInfo(lastFmArtist: LastFmArtist?) { - if (lastFmArtist != null && lastFmArtist.artist != null && lastFmArtist.artist.bio != null) { - val bioContent = lastFmArtist.artist.bio.content - if (bioContent != null && bioContent.trim { it <= ' ' }.isNotEmpty()) { - binding.fragmentArtistContent.run { - biographyText.isVisible = true - biographyTitle.isVisible = true - biography = bioContent.parseAsHtml() - biographyText.text = biography - if (lastFmArtist.artist.stats.listeners.isNotEmpty()) { - listeners.show() - listenersLabel.show() - scrobbles.show() - scrobblesLabel.show() - listeners.text = - RetroUtil.formatValue(lastFmArtist.artist.stats.listeners.toFloat()) - scrobbles.text = - RetroUtil.formatValue(lastFmArtist.artist.stats.playcount.toFloat()) - } - } - } - } - - // If the "lang" parameter is set and no biography is given, retry with default language - if (biography == null && lang != null) { - loadBiography(artist.name, null) - } - } - private fun loadArtistImage(artist: Artist) { GlideApp.with(requireContext()).asBitmapPalette().artistImageOptions(artist) .load(RetroGlideExtension.getArtistModel(artist)) diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsViewModel.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsViewModel.kt index 1210331a5..6b57fe491 100644 --- a/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsViewModel.kt +++ b/app/src/main/java/io/github/muntashirakon/music/fragments/artists/ArtistDetailsViewModel.kt @@ -17,8 +17,6 @@ package io.github.muntashirakon.music.fragments.artists import androidx.lifecycle.* import io.github.muntashirakon.music.interfaces.IMusicServiceEventListener import io.github.muntashirakon.music.model.Artist -import io.github.muntashirakon.music.network.Result -import io.github.muntashirakon.music.network.model.LastFmArtist import io.github.muntashirakon.music.repository.RealRepository import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch @@ -44,16 +42,6 @@ class ArtistDetailsViewModel( fun getArtist(): LiveData = artistDetails - fun getArtistInfo( - name: String, - lang: String?, - cache: String? - ): LiveData> = liveData(IO) { - emit(Result.Loading) - val info = realRepository.artistInfo(name, lang, cache) - emit(info) - } - override fun onMediaStoreChanged() { fetchArtist() } diff --git a/app/src/main/java/io/github/muntashirakon/music/fragments/settings/ImageSettingFragment.kt b/app/src/main/java/io/github/muntashirakon/music/fragments/settings/ImageSettingFragment.kt index 12c59fbb9..e62283b90 100644 --- a/app/src/main/java/io/github/muntashirakon/music/fragments/settings/ImageSettingFragment.kt +++ b/app/src/main/java/io/github/muntashirakon/music/fragments/settings/ImageSettingFragment.kt @@ -15,9 +15,6 @@ package io.github.muntashirakon.music.fragments.settings import android.os.Bundle -import android.view.View -import androidx.preference.Preference -import io.github.muntashirakon.music.AUTO_DOWNLOAD_IMAGES_POLICY import io.github.muntashirakon.music.R /** @@ -25,22 +22,9 @@ import io.github.muntashirakon.music.R */ class ImageSettingFragment : AbsSettingsFragment() { - override fun invalidateSettings() { - val autoDownloadImagesPolicy: Preference = findPreference(AUTO_DOWNLOAD_IMAGES_POLICY)!! - setSummary(autoDownloadImagesPolicy) - autoDownloadImagesPolicy.setOnPreferenceChangeListener { _, o -> - setSummary(autoDownloadImagesPolicy, o) - true - } - } + override fun invalidateSettings() {} override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.pref_images) } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - val preference: Preference? = findPreference(AUTO_DOWNLOAD_IMAGES_POLICY) - preference?.let { setSummary(it) } - } } diff --git a/app/src/main/java/io/github/muntashirakon/music/glide/artistimage/ArtistImageFetcher.kt b/app/src/main/java/io/github/muntashirakon/music/glide/artistimage/ArtistImageFetcher.kt index 008fbe547..8e54d762f 100644 --- a/app/src/main/java/io/github/muntashirakon/music/glide/artistimage/ArtistImageFetcher.kt +++ b/app/src/main/java/io/github/muntashirakon/music/glide/artistimage/ArtistImageFetcher.kt @@ -1,36 +1,19 @@ package io.github.muntashirakon.music.glide.artistimage import android.content.Context -import io.github.muntashirakon.music.model.Data -import io.github.muntashirakon.music.model.DeezerResponse -import io.github.muntashirakon.music.network.DeezerService -import io.github.muntashirakon.music.util.MusicUtil -import io.github.muntashirakon.music.util.PreferenceUtil import com.bumptech.glide.Priority -import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.data.DataFetcher -import com.bumptech.glide.load.model.GlideUrl -import okhttp3.OkHttpClient -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response +import io.github.muntashirakon.music.util.MusicUtil import java.io.FileNotFoundException -import java.io.IOException import java.io.InputStream class ArtistImageFetcher( private val context: Context, - private val deezerService: DeezerService, val model: ArtistImage, - private val okhttp: OkHttpClient ) : DataFetcher { - private var streamFetcher: OkHttpStreamFetcher? = null - private var response: Call? = null - private var isCancelled: Boolean = false - override fun getDataClass(): Class { return InputStream::class.java } @@ -40,52 +23,8 @@ class ArtistImageFetcher( } override fun loadData(priority: Priority, callback: DataFetcher.DataCallback) { - try { - if (!MusicUtil.isArtistNameUnknown(model.artist.name) && - PreferenceUtil.isAllowedToDownloadMetadata(context) - ) { - val artists = model.artist.name.split(",", "&") - response = deezerService.getArtistImage(artists[0]) - response?.enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - if (!response.isSuccessful) { - throw IOException("Request failed with code: " + response.code()) - } - - if (isCancelled) { - callback.onDataReady(null) - return - } - - try { - val deezerResponse = response.body() - val imageUrl = - deezerResponse?.data?.get(0)?.let { getHighestQuality(it) } - // Fragile way to detect a place holder image returned from Deezer: - // ex: "https://e-cdns-images.dzcdn.net/images/artist//250x250-000000-80-0-0.jpg" - // the double slash implies no artist identified - val placeHolder = imageUrl?.contains("/images/artist//") ?: false - if (!placeHolder) { - streamFetcher = OkHttpStreamFetcher(okhttp, GlideUrl(imageUrl)) - streamFetcher?.loadData(priority, callback) - } else { - callback.onDataReady(getFallbackAlbumImage()) - } - } catch (e: Exception) { - callback.onDataReady(getFallbackAlbumImage()) - } - } - - override fun onFailure(call: Call, t: Throwable) { - callback.onDataReady(getFallbackAlbumImage()) - } - }) - } else callback.onDataReady(null) - } catch (e: Exception) { - callback.onLoadFailed(e) + if (!MusicUtil.isArtistNameUnknown(model.artist.name)) { + callback.onDataReady(getFallbackAlbumImage()) } } @@ -106,24 +45,9 @@ class ArtistImageFetcher( } } - private fun getHighestQuality(imageUrl: Data): String { - return when { - imageUrl.pictureXl.isNotEmpty() -> imageUrl.pictureXl - imageUrl.pictureBig.isNotEmpty() -> imageUrl.pictureBig - imageUrl.pictureMedium.isNotEmpty() -> imageUrl.pictureMedium - imageUrl.pictureSmall.isNotEmpty() -> imageUrl.pictureSmall - imageUrl.picture.isNotEmpty() -> imageUrl.picture - else -> "" - } - } - override fun cleanup() { - streamFetcher?.cleanup() } override fun cancel() { - isCancelled = true - response?.cancel() - streamFetcher?.cancel() } } diff --git a/app/src/main/java/io/github/muntashirakon/music/glide/artistimage/ArtistImageLoader.kt b/app/src/main/java/io/github/muntashirakon/music/glide/artistimage/ArtistImageLoader.kt index 32ad84214..9547386bc 100644 --- a/app/src/main/java/io/github/muntashirakon/music/glide/artistimage/ArtistImageLoader.kt +++ b/app/src/main/java/io/github/muntashirakon/music/glide/artistimage/ArtistImageLoader.kt @@ -15,23 +15,16 @@ package io.github.muntashirakon.music.glide.artistimage import android.content.Context -import io.github.muntashirakon.music.network.DeezerService import com.bumptech.glide.load.Options import com.bumptech.glide.load.model.ModelLoader import com.bumptech.glide.load.model.ModelLoader.LoadData import com.bumptech.glide.load.model.ModelLoaderFactory import com.bumptech.glide.load.model.MultiModelLoaderFactory import com.bumptech.glide.signature.ObjectKey -import okhttp3.Interceptor -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor import java.io.InputStream -import java.util.concurrent.TimeUnit class ArtistImageLoader( val context: Context, - private val deezerService: DeezerService, - private val okhttp: OkHttpClient ) : ModelLoader { override fun buildLoadData( @@ -42,7 +35,7 @@ class ArtistImageLoader( ): LoadData { return LoadData( ObjectKey(model.artist.name), - ArtistImageFetcher(context, deezerService, model, okhttp) + ArtistImageFetcher(context, model) ) } @@ -55,44 +48,9 @@ class Factory( val context: Context ) : ModelLoaderFactory { - private var deezerService: DeezerService - private var okHttp: OkHttpClient - - init { - okHttp = - OkHttpClient.Builder() - .connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS) - .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS) - .writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS) - .build() - deezerService = DeezerService.invoke( - DeezerService.createDefaultOkHttpClient(context) - .connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS) - .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS) - .writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS) - .addInterceptor(createLogInterceptor()) - .build() - ) - } - - private fun createLogInterceptor(): Interceptor { - val interceptor = HttpLoggingInterceptor() - interceptor.level = HttpLoggingInterceptor.Level.BODY - return interceptor - } - override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader { - return ArtistImageLoader( - context, - deezerService, - okHttp - ) + return ArtistImageLoader(context) } override fun teardown() {} - - companion object { - // we need these very low values to make sure our artist image loading calls doesn't block the image loading queue - private const val TIMEOUT: Long = 500 - } } diff --git a/app/src/main/java/io/github/muntashirakon/music/model/Contributor.kt b/app/src/main/java/io/github/muntashirakon/music/model/Contributor.kt deleted file mode 100644 index e41da4da6..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/model/Contributor.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2019 Hemanth Savarala. - * - * Licensed under the GNU General Public License v3 - * - * This is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by - * the Free Software Foundation either version 3 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - */ - -package io.github.muntashirakon.music.model - -import android.os.Parcelable -import com.google.gson.annotations.SerializedName -import kotlinx.parcelize.Parcelize - -@Parcelize -class Contributor( - @SerializedName("name") val name: String = "", - @SerializedName("summary") val summary: String = "", - @SerializedName("link") val link: String = "", - @SerializedName("image") val image: String = "" -) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/model/DeezerResponse.kt b/app/src/main/java/io/github/muntashirakon/music/model/DeezerResponse.kt deleted file mode 100644 index 2a853fc10..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/model/DeezerResponse.kt +++ /dev/null @@ -1,41 +0,0 @@ -package io.github.muntashirakon.music.model - -import com.google.gson.annotations.SerializedName - -data class Data( - @SerializedName("id") - val id: String, - @SerializedName("link") - val link: String, - @SerializedName("name") - val name: String, - @SerializedName("nb_album") - val nbAlbum: Int, - @SerializedName("nb_fan") - val nbFan: Int, - @SerializedName("picture") - val picture: String, - @SerializedName("picture_big") - val pictureBig: String, - @SerializedName("picture_medium") - val pictureMedium: String, - @SerializedName("picture_small") - val pictureSmall: String, - @SerializedName("picture_xl") - val pictureXl: String, - @SerializedName("radio") - val radio: Boolean, - @SerializedName("tracklist") - val tracklist: String, - @SerializedName("type") - val type: String -) - -data class DeezerResponse( - @SerializedName("data") - val data: List, - @SerializedName("next") - val next: String, - @SerializedName("total") - val total: Int -) \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/network/DeezerService.kt b/app/src/main/java/io/github/muntashirakon/music/network/DeezerService.kt deleted file mode 100644 index fe1b3a0cd..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/network/DeezerService.kt +++ /dev/null @@ -1,69 +0,0 @@ -package io.github.muntashirakon.music.network - -import android.content.Context -import io.github.muntashirakon.music.model.DeezerResponse -import okhttp3.Cache -import okhttp3.Interceptor -import okhttp3.OkHttpClient -import retrofit2.Call -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -import retrofit2.create -import retrofit2.http.GET -import retrofit2.http.Query -import java.io.File -import java.util.* - -private const val BASE_QUERY_ARTIST = "search/artist" -private const val BASE_URL = "https://api.deezer.com/" - -interface DeezerService { - - @GET("$BASE_QUERY_ARTIST&limit=1") - fun getArtistImage( - @Query("q") artistName: String - ): Call - - companion object { - operator fun invoke( - client: okhttp3.Call.Factory - ): DeezerService { - return Retrofit.Builder() - .baseUrl(BASE_URL) - .callFactory(client) - .addConverterFactory(GsonConverterFactory.create()) - .build() - .create() - } - - fun createDefaultOkHttpClient( - context: Context - ): OkHttpClient.Builder = OkHttpClient.Builder() - .cache(createDefaultCache(context)) - .addInterceptor(createCacheControlInterceptor()) - - private fun createDefaultCache( - context: Context - ): Cache? { - val cacheDir = File(context.applicationContext.cacheDir.absolutePath, "/okhttp-deezer/") - if (cacheDir.mkdir() or cacheDir.isDirectory) { - return Cache(cacheDir, 1024 * 1024 * 10) - } - return null - } - - private fun createCacheControlInterceptor(): Interceptor { - return Interceptor { chain -> - val modifiedRequest = chain.request().newBuilder() - .addHeader( - "Cache-Control", - String.format( - Locale.getDefault(), - "max-age=31536000, max-stale=31536000" - ) - ).build() - chain.proceed(modifiedRequest) - } - } - } -} diff --git a/app/src/main/java/io/github/muntashirakon/music/network/LastFMService.kt b/app/src/main/java/io/github/muntashirakon/music/network/LastFMService.kt deleted file mode 100644 index f22360338..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/network/LastFMService.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2019 Hemanth Savarala. - * - * Licensed under the GNU General Public License v3 - * - * This is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by - * the Free Software Foundation either version 3 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - */ - -package io.github.muntashirakon.music.network - -import io.github.muntashirakon.music.network.model.LastFmAlbum -import io.github.muntashirakon.music.network.model.LastFmArtist -import retrofit2.http.GET -import retrofit2.http.Header -import retrofit2.http.Query - -/** - * Created by hemanths on 2019-11-26. - */ - -interface LastFMService { - companion object { - private const val API_KEY = "c679c8d3efa84613dc7dcb2e8d42da4c" - const val BASE_QUERY_PARAMETERS = "?format=json&autocorrect=1&api_key=$API_KEY" - } - - @GET("$BASE_QUERY_PARAMETERS&method=artist.getinfo") - suspend fun artistInfo( - @Query("artist") artistName: String, - @Query("lang") language: String?, - @Header("Cache-Control") cacheControl: String? - ): LastFmArtist - - @GET("$BASE_QUERY_PARAMETERS&method=album.getinfo") - suspend fun albumInfo( - @Query("artist") artistName: String, - @Query("album") albumName: String - ): LastFmAlbum -} \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/network/LyricsService.kt b/app/src/main/java/io/github/muntashirakon/music/network/LyricsService.kt deleted file mode 100644 index 33314805f..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/network/LyricsService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.muntashirakon.music.network - -import retrofit2.http.GET -import retrofit2.http.Headers -import retrofit2.http.Query - -interface LyricsRestService { - - @Headers("Cache-Control: public") - @GET("/lyrics") - suspend fun getLyrics(@Query("artist") artist: String, @Query("title") title: String): String -} \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/network/Result.kt b/app/src/main/java/io/github/muntashirakon/music/network/Result.kt deleted file mode 100644 index a9953c66a..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/network/Result.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2020 Fatih Giris. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.muntashirakon.music.network - -/** - * Generic class that holds the network state - */ -sealed class Result { - data class Success(val data: T) : Result() - object Loading : Result() - data class Error(val error: Exception) : Result() -} \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/network/RetrofitClient.kt b/app/src/main/java/io/github/muntashirakon/music/network/RetrofitClient.kt deleted file mode 100644 index c9530636c..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/network/RetrofitClient.kt +++ /dev/null @@ -1,87 +0,0 @@ -package io.github.muntashirakon.music.network - -import android.content.Context -import io.github.muntashirakon.music.App -import io.github.muntashirakon.music.BuildConfig -import io.github.muntashirakon.music.network.conversion.LyricsConverterFactory -import com.google.gson.GsonBuilder -import okhttp3.Cache -import okhttp3.Interceptor -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -import java.io.File -import java.util.concurrent.TimeUnit - - -fun provideDefaultCache(): Cache? { - val cacheDir = File(App.getContext().cacheDir.absolutePath, "/okhttp-lastfm/") - if (cacheDir.mkdirs() || cacheDir.isDirectory) { - return Cache(cacheDir, 1024 * 1024 * 10) - } - return null -} - -fun logInterceptor(): Interceptor { - val loggingInterceptor = HttpLoggingInterceptor() - if (BuildConfig.DEBUG) { - loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY - } else { - // disable retrofit log on release - loggingInterceptor.level = HttpLoggingInterceptor.Level.NONE - } - return loggingInterceptor -} - -fun headerInterceptor(context: Context): Interceptor { - return Interceptor { - val original = it.request() - val request = original.newBuilder() - .header("User-Agent", context.packageName) - .addHeader("Content-Type", "application/json; charset=utf-8") - .method(original.method, original.body) - .build() - it.proceed(request) - } -} - -fun provideOkHttp(context: Context, cache: Cache): OkHttpClient { - return OkHttpClient.Builder() - .addNetworkInterceptor(logInterceptor()) - //.addInterceptor(headerInterceptor(context)) - .connectTimeout(1, TimeUnit.SECONDS) - .readTimeout(1, TimeUnit.SECONDS) - .cache(cache) - .build() -} - -fun provideLastFmRetrofit(client: OkHttpClient): Retrofit { - val gson = GsonBuilder() - .setLenient() - .create() - return Retrofit.Builder() - .baseUrl("https://ws.audioscrobbler.com/2.0/") - .addConverterFactory(GsonConverterFactory.create(gson)) - .callFactory { request -> client.newCall(request) } - .build() -} - -fun provideLastFmRest(retrofit: Retrofit): LastFMService { - return retrofit.create(LastFMService::class.java) -} - -fun provideDeezerRest(retrofit: Retrofit): DeezerService { - val newBuilder = retrofit.newBuilder() - .baseUrl("https://api.deezer.com/") - .build() - return newBuilder.create(DeezerService::class.java) -} - -fun provideLyrics(retrofit: Retrofit): LyricsRestService { - val newBuilder = retrofit.newBuilder() - .baseUrl("https://makeitpersonal.co") - .addConverterFactory(LyricsConverterFactory()) - .build() - return newBuilder.create(LyricsRestService::class.java) -} \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/network/conversion/LyricsConverterFactory.kt b/app/src/main/java/io/github/muntashirakon/music/network/conversion/LyricsConverterFactory.kt deleted file mode 100644 index 1b44f9c01..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/network/conversion/LyricsConverterFactory.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2019 Naman Dwivedi. - * - * Licensed under the GNU General Public License v3 - * - * This is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - */ -package io.github.muntashirakon.music.network.conversion - -import okhttp3.MediaType.Companion.toMediaTypeOrNull -import okhttp3.RequestBody -import okhttp3.RequestBody.Companion.toRequestBody -import okhttp3.ResponseBody -import retrofit2.Converter -import retrofit2.Retrofit -import java.lang.reflect.Type - -class LyricsConverterFactory : Converter.Factory() { - - override fun responseBodyConverter( - type: Type, - annotations: Array, - retrofit: Retrofit - ): Converter? { - return if (String::class.java == type) { - Converter { value -> value.string() } - } else null - } - - override fun requestBodyConverter( - type: Type, - parameterAnnotations: Array, - methodAnnotations: Array, - retrofit: Retrofit - ): Converter<*, RequestBody>? { - - return if (String::class.java == type) { - Converter { value -> value.toRequestBody(MEDIA_TYPE) } - } else null - } - - companion object { - private val MEDIA_TYPE = "text/plain".toMediaTypeOrNull() - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/network/model/LastFmAlbum.java b/app/src/main/java/io/github/muntashirakon/music/network/model/LastFmAlbum.java deleted file mode 100644 index 75e62b2d5..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/network/model/LastFmAlbum.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2019 Hemanth Savarala. - * - * Licensed under the GNU General Public License v3 - * - * This is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by - * the Free Software Foundation either version 3 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - */ - -package io.github.muntashirakon.music.network.model; - -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; - -import java.util.ArrayList; -import java.util.List; - -public class LastFmAlbum { - - @Expose private Album album; - - public Album getAlbum() { - return album; - } - - public void setAlbum(Album album) { - this.album = album; - } - - public static class Album { - - @Expose public String listeners; - @Expose public String playcount; - @Expose private List image = new ArrayList<>(); - @Expose private String name; - @Expose private Tags tags; - @Expose private Wiki wiki; - - public List getImage() { - return image; - } - - public void setImage(List image) { - this.image = image; - } - - public String getListeners() { - return listeners; - } - - public void setListeners(final String listeners) { - this.listeners = listeners; - } - - public String getName() { - return name; - } - - public void setName(final String name) { - this.name = name; - } - - public String getPlaycount() { - return playcount; - } - - public void setPlaycount(final String playcount) { - this.playcount = playcount; - } - - public Tags getTags() { - return tags; - } - - public Wiki getWiki() { - return wiki; - } - - public void setWiki(Wiki wiki) { - this.wiki = wiki; - } - - public static class Image { - - @SerializedName("#text") - @Expose - private String Text; - - @Expose private String size; - - public String getSize() { - return size; - } - - public void setSize(String size) { - this.size = size; - } - - public String getText() { - return Text; - } - - public void setText(String Text) { - this.Text = Text; - } - } - - public class Tags { - - @Expose - private final List tag = null; - - public List getTag() { - return tag; - } - } - - public class Tag { - - @Expose private String name; - - @Expose private String url; - - public String getName() { - return name; - } - - public String getUrl() { - return url; - } - } - - public class Wiki { - - @Expose private String content; - - @Expose private String published; - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getPublished() { - return published; - } - - public void setPublished(final String published) { - this.published = published; - } - } - } -} diff --git a/app/src/main/java/io/github/muntashirakon/music/network/model/LastFmArtist.java b/app/src/main/java/io/github/muntashirakon/music/network/model/LastFmArtist.java deleted file mode 100644 index 6681999dd..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/network/model/LastFmArtist.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2019 Hemanth Savarala. - * - * Licensed under the GNU General Public License v3 - * - * This is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by - * the Free Software Foundation either version 3 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - */ - -package io.github.muntashirakon.music.network.model; - -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; - -import java.util.ArrayList; -import java.util.List; - -public class LastFmArtist { - - @Expose private Artist artist; - - public Artist getArtist() { - return artist; - } - - public void setArtist(Artist artist) { - this.artist = artist; - } - - public static class Artist { - - @Expose public Stats stats; - @Expose private Bio bio; - @Expose private List image = new ArrayList<>(); - - public Bio getBio() { - return bio; - } - - public void setBio(Bio bio) { - this.bio = bio; - } - - public List getImage() { - return image; - } - - public void setImage(List image) { - this.image = image; - } - - public static class Image { - - @SerializedName("#text") - @Expose - private String Text; - - @Expose private String size; - - public String getSize() { - return size; - } - - public void setSize(String size) { - this.size = size; - } - - public String getText() { - return Text; - } - - public void setText(String Text) { - this.Text = Text; - } - } - - public static class Stats { - - @Expose public String listeners; - - @Expose public String playcount; - - public String getListeners() { - return listeners; - } - - public void setListeners(final String listeners) { - this.listeners = listeners; - } - - public String getPlaycount() { - return playcount; - } - - public void setPlaycount(final String playcount) { - this.playcount = playcount; - } - } - - public class Bio { - - @Expose private String content; - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - } - } -} diff --git a/app/src/main/java/io/github/muntashirakon/music/network/model/LastFmTrack.java b/app/src/main/java/io/github/muntashirakon/music/network/model/LastFmTrack.java deleted file mode 100644 index 324dd98bc..000000000 --- a/app/src/main/java/io/github/muntashirakon/music/network/model/LastFmTrack.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2019 Hemanth Savarala. - * - * Licensed under the GNU General Public License v3 - * - * This is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by - * the Free Software Foundation either version 3 of the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - */ - -package io.github.muntashirakon.music.network.model; - -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; - -import java.util.List; - -/** Created by hemanths on 15/06/17. */ -public class LastFmTrack { - - @Expose private Track track; - - public Track getTrack() { - return track; - } - - public void setTrack(Track track) { - this.track = track; - } - - public static class Track { - @SerializedName("name") - @Expose - private String name; - - @Expose private Album album; - @Expose private Wiki wiki; - @Expose private Toptags toptags; - @Expose private Artist artist; - - public Album getAlbum() { - return album; - } - - public Wiki getWiki() { - return wiki; - } - - public String getName() { - return name; - } - - public Toptags getToptags() { - return toptags; - } - - public static class Artist { - - @Expose private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - } - - public static class Wiki { - @Expose private String published; - - public String getPublished() { - return published; - } - - public void setPublished(String published) { - this.published = published; - } - } - - public static class Toptags { - @Expose - private final List tag = null; - - public List getTag() { - return tag; - } - - public static class Tag { - @Expose private String name; - - public String getName() { - return name; - } - } - } - - public static class Album { - @Expose private String artist; - @Expose private List image = null; - @Expose private String title; - - @SerializedName("@attr") - @Expose - private Attr attr; - - public Attr getAttr() { - return attr; - } - - public void setAttr(Attr attr) { - this.attr = attr; - } - - public String getArtist() { - return artist; - } - - public void setArtist(String artist) { - this.artist = artist; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public List getImage() { - return image; - } - - public void setImage(List image) { - this.image = image; - } - - public static class Attr { - @Expose private String position; - - public String getPosition() { - return position; - } - - public void setPosition(String position) { - this.position = position; - } - } - - public class Image { - - @SerializedName("#text") - @Expose - private String text; - - @Expose private String size; - - public String getSize() { - return size; - } - - public String getText() { - return text; - } - } - } - } -} diff --git a/app/src/main/java/io/github/muntashirakon/music/repository/Repository.kt b/app/src/main/java/io/github/muntashirakon/music/repository/Repository.kt index 727f4dc04..791657a3e 100644 --- a/app/src/main/java/io/github/muntashirakon/music/repository/Repository.kt +++ b/app/src/main/java/io/github/muntashirakon/music/repository/Repository.kt @@ -22,24 +22,9 @@ import io.github.muntashirakon.music.db.* import io.github.muntashirakon.music.fragments.search.Filter import io.github.muntashirakon.music.model.* import io.github.muntashirakon.music.model.smartplaylist.NotPlayedPlaylist -import io.github.muntashirakon.music.network.LastFMService -import io.github.muntashirakon.music.network.Result -import io.github.muntashirakon.music.network.Result.* -import io.github.muntashirakon.music.network.model.LastFmAlbum -import io.github.muntashirakon.music.network.model.LastFmArtist import io.github.muntashirakon.music.util.PreferenceUtil -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.flow interface Repository { - - fun songsFlow(): Flow>> - fun albumsFlow(): Flow>> - fun artistsFlow(): Flow>> - fun playlistsFlow(): Flow>> - fun genresFlow(): Flow>> fun historySong(): List fun favorites(): LiveData> fun observableHistorySongs(): LiveData> @@ -55,8 +40,6 @@ interface Repository { suspend fun search(query: String?, filter: Filter): MutableList suspend fun getPlaylistSongs(playlist: Playlist): List suspend fun getGenre(genreId: Long): List - suspend fun artistInfo(name: String, lang: String?, cache: String?): Result - suspend fun albumInfo(artist: String, album: String): Result suspend fun artistById(artistId: Long): Artist suspend fun albumArtistByName(name: String): Artist suspend fun recentArtists(): List @@ -74,8 +57,6 @@ interface Repository { suspend fun playlists(): Home suspend fun homeSections(): List - @ExperimentalCoroutinesApi - suspend fun homeSectionsFlow(): Flow>> suspend fun playlist(playlistId: Long): Playlist suspend fun fetchPlaylistWithSongs(): List suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs): List @@ -115,7 +96,6 @@ interface Repository { class RealRepository( private val context: Context, - private val lastFMService: LastFMService, private val songRepository: SongRepository, private val albumRepository: AlbumRepository, private val artistRepository: ArtistRepository, @@ -183,59 +163,6 @@ class RealRepository( override suspend fun getGenre(genreId: Long): List = genreRepository.songs(genreId) - override suspend fun artistInfo( - name: String, - lang: String?, - cache: String? - ): Result { - return try { - Success(lastFMService.artistInfo(name, lang, cache)) - } catch (e: Exception) { - println(e) - Error(e) - } - } - - override suspend fun albumInfo( - artist: String, - album: String - ): Result { - return try { - val lastFmAlbum = lastFMService.albumInfo(artist, album) - Success(lastFmAlbum) - } catch (e: Exception) { - println(e) - Error(e) - } - } - - @ExperimentalCoroutinesApi - override suspend fun homeSectionsFlow(): Flow>> { - val homes = MutableStateFlow>>(value = Loading) - val homeSections = mutableListOf() - val sections = listOf( - topArtistsHome(), - topAlbumsHome(), - recentArtistsHome(), - recentAlbumsHome(), - suggestionsHome(), - favoritePlaylistHome(), - genresHome() - ) - for (section in sections) { - if (section.arrayList.isNotEmpty()) { - println("${section.homeSection} -> ${section.arrayList.size}") - homeSections.add(section) - } - } - if (homeSections.isEmpty()) { - homes.value = Error(Exception(Throwable("No items"))) - } else { - homes.value = Success(homeSections) - } - return homes - } - override suspend fun homeSections(): List { val homeSections = mutableListOf() val sections: List = listOf( @@ -420,53 +347,4 @@ class RealRepository( return Home(songs, FAVOURITES, R.string.favorites) } - override fun songsFlow(): Flow>> = flow { - emit(Loading) - val data = songRepository.songs() - if (data.isEmpty()) { - emit(Error(Exception(Throwable("No items")))) - } else { - emit(Success(data)) - } - } - - override fun albumsFlow(): Flow>> = flow { - emit(Loading) - val data = albumRepository.albums() - if (data.isEmpty()) { - emit(Error(Exception(Throwable("No items")))) - } else { - emit(Success(data)) - } - } - - override fun artistsFlow(): Flow>> = flow { - emit(Loading) - val data = artistRepository.artists() - if (data.isEmpty()) { - emit(Error(Exception(Throwable("No items")))) - } else { - emit(Success(data)) - } - } - - override fun playlistsFlow(): Flow>> = flow { - emit(Loading) - val data = playlistRepository.playlists() - if (data.isEmpty()) { - emit(Error(Exception(Throwable("No items")))) - } else { - emit(Success(data)) - } - } - - override fun genresFlow(): Flow>> = flow { - emit(Loading) - val data = genreRepository.genres() - if (data.isEmpty()) { - emit(Error(Exception(Throwable("No items")))) - } else { - emit(Success(data)) - } - } } \ No newline at end of file diff --git a/app/src/main/java/io/github/muntashirakon/music/util/PreferenceUtil.kt b/app/src/main/java/io/github/muntashirakon/music/util/PreferenceUtil.kt index 73c9ae6d2..5db00ffcf 100644 --- a/app/src/main/java/io/github/muntashirakon/music/util/PreferenceUtil.kt +++ b/app/src/main/java/io/github/muntashirakon/music/util/PreferenceUtil.kt @@ -1,11 +1,7 @@ package io.github.muntashirakon.music.util -import android.content.Context import android.content.SharedPreferences.OnSharedPreferenceChangeListener -import android.net.ConnectivityManager -import android.net.NetworkCapabilities import androidx.core.content.edit -import androidx.core.content.getSystemService import androidx.core.content.res.use import androidx.fragment.app.Fragment import androidx.preference.PreferenceManager @@ -115,12 +111,6 @@ object PreferenceUtil { putString(SAF_SDCARD_URI, value) } - val autoDownloadImagesPolicy - get() = sharedPreferences.getStringOrDefault( - AUTO_DOWNLOAD_IMAGES_POLICY, - "only_wifi" - ) - var albumArtistsOnly get() = sharedPreferences.getBoolean( ALBUM_ARTISTS_ONLY, @@ -336,26 +326,6 @@ object PreferenceUtil { val isLockScreen get() = sharedPreferences.getBoolean(LOCK_SCREEN, false) - fun isAllowedToDownloadMetadata(context: Context): Boolean { - return when (autoDownloadImagesPolicy) { - "always" -> true - "only_wifi" -> { - val connectivityManager = context.getSystemService() - if (VersionUtils.hasMarshmallow()) { - val network = connectivityManager?.activeNetwork - val capabilities = connectivityManager?.getNetworkCapabilities(network) - capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) - } else { - val netInfo = connectivityManager?.activeNetworkInfo - netInfo != null && netInfo.type == ConnectivityManager.TYPE_WIFI && netInfo.isConnectedOrConnecting - } - } - "never" -> false - else -> false - } - } - - var lyricsOption get() = sharedPreferences.getInt(LYRICS_OPTIONS, 1) set(value) = sharedPreferences.edit { diff --git a/app/src/main/res/layout/activity_bug_report.xml b/app/src/main/res/layout/activity_bug_report.xml index 4028b7a06..ce2337e26 100644 --- a/app/src/main/res/layout/activity_bug_report.xml +++ b/app/src/main/res/layout/activity_bug_report.xml @@ -33,13 +33,6 @@ android:clipToPadding="false" android:orientation="vertical"> - - + app:srcCompat="@drawable/ic_open_in_browser" /> \ No newline at end of file diff --git a/app/src/main/res/layout/bug_report_card_report.xml b/app/src/main/res/layout/bug_report_card_report.xml deleted file mode 100644 index 85dc9ff93..000000000 --- a/app/src/main/res/layout/bug_report_card_report.xml +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_album_content.xml b/app/src/main/res/layout/fragment_album_content.xml index 36059d393..6aa56c367 100644 --- a/app/src/main/res/layout/fragment_album_content.xml +++ b/app/src/main/res/layout/fragment_album_content.xml @@ -97,106 +97,10 @@ tools:listitem="@layout/item_album_card" tools:visibility="visible" /> - - - - - - - - - - - - + app:layout_constraintTop_toBottomOf="@id/moreRecyclerView" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_artist_content.xml b/app/src/main/res/layout/fragment_artist_content.xml index bebd08d1a..5c1f9f8e6 100644 --- a/app/src/main/res/layout/fragment_artist_content.xml +++ b/app/src/main/res/layout/fragment_artist_content.xml @@ -107,106 +107,9 @@ app:layout_constraintTop_toBottomOf="@id/songTitle" tools:listitem="@layout/item_song" /> - - - - - - - - - - - - - - + app:layout_constraintTop_toBottomOf="@id/recyclerView" /> \ No newline at end of file diff --git a/app/src/main/res/xml/pref_images.xml b/app/src/main/res/xml/pref_images.xml index b6ad8fa2e..1318029c3 100755 --- a/app/src/main/res/xml/pref_images.xml +++ b/app/src/main/res/xml/pref_images.xml @@ -10,11 +10,4 @@ android:title="@string/pref_title_ignore_media_store_artwork" app:icon="@drawable/ic_image" /> - \ No newline at end of file