From d21bd475a10a48975e7cdab8dcb90f0319e94ec6 Mon Sep 17 00:00:00 2001 From: eddyizm Date: Sun, 10 Aug 2025 12:54:05 -0700 Subject: [PATCH 01/16] wip: initial new rating on song layout --- ...nner_fragment_player_controller_layout.xml | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/inner_fragment_player_controller_layout.xml b/app/src/main/res/layout/inner_fragment_player_controller_layout.xml index ac318326..024b14d8 100644 --- a/app/src/main/res/layout/inner_fragment_player_controller_layout.xml +++ b/app/src/main/res/layout/inner_fragment_player_controller_layout.xml @@ -104,6 +104,39 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/player_media_title_label" /> + + + + + + + + From 5fa46cc49bc445370dd6612a7ba48de4a1c48576 Mon Sep 17 00:00:00 2001 From: eddyizm Date: Thu, 14 Aug 2025 21:46:33 -0700 Subject: [PATCH 02/16] feat:show rating on song view and allow setting/updating. #17 fixed a fr string error --- app/build.gradle | 2 +- .../ui/fragment/PlayerControllerFragment.java | 28 +++++++++++++++++++ .../viewmodel/PlayerBottomSheetViewModel.java | 6 ++-- ...nner_fragment_player_controller_layout.xml | 8 ++---- app/src/main/res/values-fr/strings.xml | 2 +- 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ea649294..fbdfbdb7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,7 +11,7 @@ android { targetSdk 35 versionCode 27 - versionName '3.11.2' + versionName '3.11.3' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java index 01d8eb7b..ae5f633b 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java @@ -10,6 +10,8 @@ import android.widget.Button; import android.widget.ImageButton; import android.widget.TextView; import android.widget.ToggleButton; +import android.widget.RatingBar; +import android.util.Log; import androidx.annotation.NonNull; import androidx.constraintlayout.widget.ConstraintLayout; @@ -36,6 +38,7 @@ import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.util.MusicUtil; import com.cappielloantonio.tempo.util.Preferences; import com.cappielloantonio.tempo.viewmodel.PlayerBottomSheetViewModel; +import com.cappielloantonio.tempo.viewmodel.RatingViewModel; import com.google.android.material.chip.Chip; import com.google.android.material.elevation.SurfaceColors; import com.google.common.util.concurrent.ListenableFuture; @@ -53,6 +56,8 @@ public class PlayerControllerFragment extends Fragment { private InnerFragmentPlayerControllerBinding bind; private ViewPager2 playerMediaCoverViewPager; private ToggleButton buttonFavorite; + private RatingViewModel ratingViewModel; + private RatingBar songRatingBar; private TextView playerMediaTitleLabel; private TextView playerArtistNameLabel; private Button playbackSpeedButton; @@ -75,6 +80,7 @@ public class PlayerControllerFragment extends Fragment { View view = bind.getRoot(); playerBottomSheetViewModel = new ViewModelProvider(requireActivity()).get(PlayerBottomSheetViewModel.class); + ratingViewModel = new ViewModelProvider(requireActivity()).get(RatingViewModel.class); init(); initQuickActionView(); @@ -117,6 +123,7 @@ public class PlayerControllerFragment extends Fragment { playerQuickActionView = bind.getRoot().findViewById(R.id.player_quick_action_view); playerOpenQueueButton = bind.getRoot().findViewById(R.id.player_open_queue_button); playerTrackInfo = bind.getRoot().findViewById(R.id.player_info_track); + songRatingBar = bind.getRoot().findViewById(R.id.song_rating_bar); } private void initQuickActionView() { @@ -313,6 +320,7 @@ public class PlayerControllerFragment extends Fragment { private void initMediaListenable() { playerBottomSheetViewModel.getLiveMedia().observe(getViewLifecycleOwner(), media -> { if (media != null) { + ratingViewModel.setSong(media); buttonFavorite.setChecked(media.getStarred() != null); buttonFavorite.setOnClickListener(v -> playerBottomSheetViewModel.setFavorite(requireContext(), media)); buttonFavorite.setOnLongClickListener(v -> { @@ -323,9 +331,29 @@ public class PlayerControllerFragment extends Fragment { dialog.setArguments(bundle); dialog.show(requireActivity().getSupportFragmentManager(), null); + return true; }); + Integer currentRating = media.getUserRating(); + + if (currentRating != null) { + songRatingBar.setRating(currentRating); + } else { + songRatingBar.setRating(0); + } + + songRatingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() { + @Override + public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) { + if (fromUser) { + ratingViewModel.rate((int) rating); + media.setUserRating((int) rating); + } + } + }); + + if (getActivity() != null) { playerBottomSheetViewModel.refreshMediaInfo(requireActivity(), media); } diff --git a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java index 3e712479..339661d8 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java +++ b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java @@ -2,6 +2,7 @@ package com.cappielloantonio.tempo.viewmodel; import android.app.Application; import android.content.Context; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.OptIn; @@ -32,6 +33,8 @@ import com.cappielloantonio.tempo.util.NetworkUtil; import com.cappielloantonio.tempo.util.OpenSubsonicExtensionsUtil; import com.cappielloantonio.tempo.util.Preferences; +import org.jetbrains.annotations.Nullable; + import java.util.Collections; import java.util.Date; import java.util.List; @@ -103,7 +106,6 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel { favoriteRepository.starLater(media.getId(), null, null, false); } }); - media.setStarred(null); } @@ -131,7 +133,7 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel { } } - public LiveData getLiveLyrics() { + public LiveData getLiveLyrics() { return lyricsLiveData; } diff --git a/app/src/main/res/layout/inner_fragment_player_controller_layout.xml b/app/src/main/res/layout/inner_fragment_player_controller_layout.xml index 024b14d8..b2bbb05e 100644 --- a/app/src/main/res/layout/inner_fragment_player_controller_layout.xml +++ b/app/src/main/res/layout/inner_fragment_player_controller_layout.xml @@ -108,12 +108,10 @@ android:id="@+id/rating_container" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="24dp" android:layout_marginTop="8dp" - android:layout_marginEnd="24dp" android:orientation="horizontal" - android:gravity="center_vertical" - app:layout_constraintEnd_toStartOf="@+id/button_favorite" + android:gravity="center" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/player_artist_name_label"> @@ -134,7 +132,7 @@ android:layout_marginStart="8dp" android:textSize="12sp" android:textColor="?attr/colorOnSurfaceVariant" - android:text="Not rated"/> + android:text=""/> Continuer Continuer et télécharger Le téléchargement des titres favoris pourrer utiliser beaucoup de données. - Synchroniser les titres favorisSync starred tracks + Synchroniser les titres favoris Veuillez redémarrer l\'app pour appliquer les changements. Modifier le chemin de stockage des fichiers mis en cache pourrait provoquer de tous les fichiers mis en cache précédemment. Sélectionner une option de stockage From 87f6db9e798fcc035de95655ffe615ca1034be50 Mon Sep 17 00:00:00 2001 From: eddyizm Date: Thu, 14 Aug 2025 21:54:25 -0700 Subject: [PATCH 03/16] chore: cleaned up dev log imports, commented code --- .../tempo/ui/fragment/PlayerControllerFragment.java | 1 - .../tempo/viewmodel/PlayerBottomSheetViewModel.java | 3 --- .../res/layout/inner_fragment_player_controller_layout.xml | 1 - 3 files changed, 5 deletions(-) diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java index ae5f633b..a07d58ec 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java @@ -11,7 +11,6 @@ import android.widget.ImageButton; import android.widget.TextView; import android.widget.ToggleButton; import android.widget.RatingBar; -import android.util.Log; import androidx.annotation.NonNull; import androidx.constraintlayout.widget.ConstraintLayout; diff --git a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java index 339661d8..bf90fa65 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java +++ b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java @@ -2,7 +2,6 @@ package com.cappielloantonio.tempo.viewmodel; import android.app.Application; import android.content.Context; -import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.OptIn; @@ -33,8 +32,6 @@ import com.cappielloantonio.tempo.util.NetworkUtil; import com.cappielloantonio.tempo.util.OpenSubsonicExtensionsUtil; import com.cappielloantonio.tempo.util.Preferences; -import org.jetbrains.annotations.Nullable; - import java.util.Collections; import java.util.Date; import java.util.List; diff --git a/app/src/main/res/layout/inner_fragment_player_controller_layout.xml b/app/src/main/res/layout/inner_fragment_player_controller_layout.xml index b2bbb05e..9063e242 100644 --- a/app/src/main/res/layout/inner_fragment_player_controller_layout.xml +++ b/app/src/main/res/layout/inner_fragment_player_controller_layout.xml @@ -162,7 +162,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/exo_progress" /> - Date: Fri, 15 Aug 2025 09:29:45 -0700 Subject: [PATCH 04/16] chore: updated readme and bumped version for release. --- README.md | 5 ++++- app/build.gradle | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e633e7cc..00680d8d 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ This fork is my attempt to keep development moving forward and merge in PR's tha Moved details to [CHANGELOG.md](https://github.com/eddyizm/tempo/blob/main/CHANGELOG.md) +Fork [**sponsorship here**](https://ko-fi.com/eddyizm). + ## Features - **Subsonic Integration**: Tempo seamlessly integrates with your Subsonic server, providing you with easy access to your entire music collection on the go. - **Sleek and Intuitive UI**: Enjoy a clean and user-friendly interface designed to enhance your music listening experience, tailored to your preferences and listening history. @@ -42,9 +44,10 @@ Moved details to [CHANGELOG.md](https://github.com/eddyizm/tempo/blob/main/CHANG - **Android Auto Support**: Enjoy your favorite music on the go with full Android Auto integration, allowing you to seamlessly control and listen to your tracks directly from your mobile device while driving. ## Sponsors +Thanks to the original repo/creator [CappielloAntonio](https://github.com/CappielloAntonio) (3.9.0) + Tempo is an open-source project developed and maintained solely by me. I would like to express my heartfelt thanks to all the users who have shown their love and support for Tempo. Your contributions and encouragement mean a lot to me, and they help drive the development and improvement of the app. -If you would like to sponsor the project and show your support, you can make a donation or contribution by visiting the [**sponsorship page**](https://www.buymeacoffee.com/a.cappiello). Your generosity will help cover the costs of development and further enhancements. ## Screenshot diff --git a/app/build.gradle b/app/build.gradle index fbdfbdb7..0aace15a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { minSdkVersion 24 targetSdk 35 - versionCode 27 - versionName '3.11.3' + versionCode 28 + versionName '3.12.0' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' From 8943faf44c17b6a540f63cd63ee509d87daf9d63 Mon Sep 17 00:00:00 2001 From: eddyizm Date: Fri, 15 Aug 2025 10:42:03 -0700 Subject: [PATCH 05/16] chore: updated change log --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c42c6bff..71c57bcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,24 @@ ***This log is for this fork to detail updates since 3.9.0 from the main repo.*** +## [3.12.0](https://github.com/eddyizm/tempo/releases/tag/v3.12.0) (2025-08-15) +### What's Changed +* [chore]: add German translations for track info and home section strings (#29) by @BreadWare92 in https://github.com/eddyizm/tempo/pull/31 +* [chore]: increased "Offline mode" text size, changed its color in dark theme by @jaime-grj in https://github.com/eddyizm/tempo/pull/33 +* [chore]: Translations for sections by @skajmer in https://github.com/eddyizm/tempo/pull/30 +* [chore]: Update French localization by @benoit-smith in https://github.com/eddyizm/tempo/pull/36 +* [fix]: Show placeholder string in TrackInfoDialog fields when there is no data by @jaime-grj in https://github.com/eddyizm/tempo/pull/37 +* [feat]: added transcoding codec and bitrate info to PlayerControllerFragment, replace hardcoded strings by @jaime-grj in https://github.com/eddyizm/tempo/pull/38 +* [chore]: Update French localization by @benoit-smith in https://github.com/eddyizm/tempo/pull/39 +* [feat]: show rating on song view by @eddyizm in https://github.com/eddyizm/tempo/pull/40 + +### New Contributors +* @BreadWare92 made their first contribution in https://github.com/eddyizm/tempo/pull/31 +* @skajmer made their first contribution in https://github.com/eddyizm/tempo/pull/30 +* @benoit-smith made their first contribution in https://github.com/eddyizm/tempo/pull/36 + +**Full Changelog**: https://github.com/eddyizm/tempo/compare/v3.11.2...v3.12.0 + ## [3.11.2](https://github.com/eddyizm/tempo/releases/tag/v3.11.2) (2025-08-09) From 469204daac13c50f3ef5a63b161b1a5c8bca2e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa?= <55400857+jaime-grj@users.noreply.github.com> Date: Sat, 16 Aug 2025 02:43:02 +0200 Subject: [PATCH 06/16] style: Change position and size of rating container --- .../inner_fragment_player_controller_layout.xml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/layout/inner_fragment_player_controller_layout.xml b/app/src/main/res/layout/inner_fragment_player_controller_layout.xml index 9063e242..b3f29424 100644 --- a/app/src/main/res/layout/inner_fragment_player_controller_layout.xml +++ b/app/src/main/res/layout/inner_fragment_player_controller_layout.xml @@ -81,14 +81,14 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="24dp" - android:layout_marginTop="24dp" + android:layout_marginTop="8dp" android:layout_marginEnd="24dp" android:ellipsize="marquee" android:singleLine="true" android:text="@string/label_placeholder" app:layout_constraintEnd_toStartOf="@+id/button_favorite" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/guideline" /> + app:layout_constraintTop_toBottomOf="@+id/rating_container" /> + app:layout_constraintTop_toBottomOf="@+id/guideline"> - + From 6cfa04d36851823f23f6d1ea85ff69c3887e9819 Mon Sep 17 00:00:00 2001 From: mucahit-kaya <54944321+mucahit-kaya@users.noreply.github.com> Date: Fri, 22 Aug 2025 17:08:08 +0200 Subject: [PATCH 07/16] Add Turkish language --- app/src/main/res/values-tr/arrays.xml | 257 +++++++++++++++ app/src/main/res/values-tr/strings.xml | 436 +++++++++++++++++++++++++ app/src/main/res/xml/locale_config.xml | 1 + 3 files changed, 694 insertions(+) create mode 100644 app/src/main/res/values-tr/arrays.xml create mode 100644 app/src/main/res/values-tr/strings.xml diff --git a/app/src/main/res/values-tr/arrays.xml b/app/src/main/res/values-tr/arrays.xml new file mode 100644 index 00000000..db3d1427 --- /dev/null +++ b/app/src/main/res/values-tr/arrays.xml @@ -0,0 +1,257 @@ + + + Açık + Koyu + Sistem varsayılanı + + + light + dark + default + + + + Yüksek + Orta + Düşük + + + 500 + 250 + 125 + + + + Yüksek + Orta + Düşük + + + -1 + 500 + 300 + + + + Kapalı + 128 MiB + 256 MiB + 512 MiB + 1024 MiB + + + 0 + 128 + 256 + 512 + 1024 + + + + Orjinal + 32 kbps + 48 kbps + 64 kbps + 80 kbps + 96 kbps + 112 kbps + 128 kbps + 160 kbps + 192 kbps + 256 kbps + 320 kbps + + + 0 + 32 + 48 + 64 + 80 + 96 + 112 + 128 + 160 + 192 + 256 + 320 + + + + Orjinal + 32 kbps + 48 kbps + 64 kbps + 80 kbps + 96 kbps + 112 kbps + 128 kbps + 160 kbps + 192 kbps + 256 kbps + 320 kbps + + + 0 + 32 + 48 + 64 + 80 + 96 + 112 + 128 + 160 + 192 + 256 + 320 + + + + Orjinal + 32 kbps + 48 kbps + 64 kbps + 80 kbps + 96 kbps + 112 kbps + 128 kbps + 160 kbps + 192 kbps + 256 kbps + 320 kbps + + + 0 + 32 + 48 + 64 + 80 + 96 + 112 + 128 + 160 + 192 + 256 + 320 + + + + Doğrudan çal + Opus + AAC + Mp3 + Flac + + + raw + opus + aac + mp3 + flac + + + + Doğrudan çal + Opus + AAC + Mp3 + Flac + + + raw + opus + aac + mp3 + flac + + + + Doğrudan indir + Opus + AAC + Mp3 + Flac + + + raw + opus + aac + mp3 + flac + + + + On saniye + Beş saniye + İki saniye + + + 10 + 5 + 2 + + + + Yüksek + Orta + Düşük + + + 18 + 12 + 6 + + + + Kapalı + Parça + Albüm + Otomatik + + + kapalı + parça + albüm + otomatik + + + + Format dönüştürme yapma + Sunucu ayarları + Wi-fi dönüştürme ayarları + Mobil dönüştürme formatı + + + 0 + 1 + 2 + 3 + + + + Minimum + Moderate + Agrasif + Aşırı + + + .1 + 1 + 4 + 8 + + + + En az 0 yıldız + En az 1 yıldız + En az 2 yıldız + En az 3 yıldız + En az 4 yıldız + + + 0 + 1 + 2 + 3 + 4 + + \ No newline at end of file diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml new file mode 100644 index 00000000..fa915fec --- /dev/null +++ b/app/src/main/res/values-tr/strings.xml @@ -0,0 +1,436 @@ + + Sorun yaşarsanız https://dontkillmyapp.com adresini ziyaret edin. Uygulamanın performansını etkileyebilecek güç tasarrufu özelliklerinin nasıl devre dışı bırakılacağına dair ayrıntılı talimatlar sağlar. + Ekran kapalıyken medya oynatma için lütfen pil optimizasyonlarını devre dışı bırakın. + Pil optimizasyonu + Çevrimdışı mod + Çalma listesine ekle + Sıraya ekle + Tümünü indir + Sanatçıya git + Anında karışım + Sıradakini çal + Tümünü kaldır + Paylaş + Karıştır + Albümler + Albümleri görüntüle + Sanatçı getirilirken hata oluştu + İndirilen albümler + En çok çalınan albümler + Yeni çıkanlar + Yakın zamanda eklenen albümler + Yakın zamanda çalınan albümler + Yıldızlı albümler + Albümler + Buna benzer daha fazla + Çal + %1$s tarihinde yayınlandı + %1$s tarihinde yayınlandı, orijinali %2$s + Karıştır + %1$d parça • %2$d dakika + Tempo + Aranıyor… + Anında karışım + Karıştır + Sanatçılar + Sanatçılara göz at + Sanatçının radyosu alınırken hata oluştu + Sanatçının parçaları alınırken hata oluştu + İndirilen sanatçılar + Yıldızlı sanatçılar + Sanatçılar + Radyo + Karıştır + Düzeni değiştir + Buna benzer daha fazla + Albümler + Daha fazla + Biyografi + En Çok Dinlenen Şarkılar + Tümünü gör + Yok say + Bir daha sorma + Devre dışı bırak + İptal + Veri tasarrufunu etkinleştir + Tamam + Wi-Fi dışındaki bağlantılarda Subsonic sunucusuna erişim kısıtlandı. Bu uyarı penceresinin tekrar görünmemesi için, uygulama ayarlarından bağlantı denetimini devre dışı bırakın. + Wi-Fi bağlı değil + Karıştır + İptal + Devam ettir + Lütfen dikkat edin, bu işleme devam etmek tüm sunuculardan indirilen kayıtlı öğelerin kalıcı olarak silinmesine yol açacaktır. + Kayıtlı öğeleri sil + Açıklama yok + Disk %1$s - %2$s + Disk %1$s + İptal + İndir + Bu klasördeki tüm parçalar indirilecektir. Alt klasörlerde bulunan parçalar indirilmeyecektir. + Parçaları indir + Bir şarkı indirdiğinde burada görünecek + Henüz indirme yok! + %1$s • %2$s öğe + %1$s öğe + Tümünü karıştır + Değişikliklerin geçerli olması için uygulamayı yeniden başlatın. + İndirilen dosyaların hedefi bir depolamadan diğerine değiştirildiğinde, önceki depolamada bulunan tüm indirilmiş dosyalar anında silinecektir. + Depolama seçeneğini seç + Harici + Dahili + İndirilenler + Sıraya ekle + Sonra çal + Kaldır + Tümünü kaldır + Karıştır + + Zorunlu + http veya https öneki gerekli + İndirilenler + İki veya daha fazla filtre seçin + Filtre + Türleri filtrele + (%1$d) + (+%1$d) + Tür Kataloğu + Türlere göz at + Bana sonra hatırlat + Destek ol + Hemen indir + Uygulamanın yeni bir sürümü Github’da mevcut. + Güncelleme mevcut + İptal + Sıfırla + Kaydet + Ana sayfayı düzenle + Yapılan değişikliklerin etkili olması için uygulamayı yeniden başlatmanız gerekir. + Müzik + Podcast + Radyo + Favori sanatçılarının en iyi şarkıları + Beğendiğin bir şarkıdan karışım başlat + Yeni radyo ekle + Yeni podcast kanalı ekle + İptal + İndir + Bu parçaların indirilmesi önemli miktarda veri kullanabilir + Eşitlenecek bazı yıldızlı parçalar var gibi görünüyor + En iyiler + Keşfet + Tümünü karıştır + Geçmişe dönüş + İnternet radyo istasyonları + Son çalınanlar + Tümünü gör + Geçen hafta + Geçen ay + Geçen yıl + Senin için + En çok çalınanlar + Tümünü gör + Yeni çıkışlar + En yeni podcastler + Çalma listeleri + Kanallar + Tümünü gör + Radyo istasyonları + Son eklenenler + Tümünü gör + Paylaşımlar + ★ Yıldızlı albümler + Tümünü gör + ★ Yıldızlı sanatçılar + Tümünü gör + ★ Yıldızlı parçalar + Tümünü gör + En iyi şarkıların + Yeniden düzenle + + -- + Albümler + Tümünü gör + Sanatçılar + Tümünü gör + Türler + Tümünü gör + Müzik klasörleri + Çalma listeleri + Tümünü gör + Sunucu eklenmedi + Subsonic sunucuları + Subsonic sunucuları + Yayınla + Ekle + Çalma listesine ekle + Tümünü indir + İndir + Tümü + İndirilenler + Albüm + Sanatçı + Tür + Parça + Yıl + Ana sayfa + Geçen hafta + Geçen ay + Geçen yıl + Kütüphane + Ara + Ayarlar + Sanatçı + Ad + Rastgele + Son eklenenler + Son çalınanlar + En çok çalınanlar + En son yıldızlananlar + En eski yıldızlananlar + Ana ekrana ekle + Ana ekrandan kaldır + Yıl + %1$.2fx + Çalma sırasını temizle + Sunucu önceliği + Bilinmeyen format + Dönüştürme + talep edildi + Çalma Listesi Kataloğu + Çalma listelerine göz at + Henüz çalma listesi oluşturulmadı + İptal + Oluştur + Çalma listesine ekle + Şarkı çalma listesine eklendi + Şarkı çalma listesine eklenemedi + %1$d parça • %2$s + Süre • %1$s + Silmek için uzun basın + Çalma listesi adı + İptal + Sil + Kaydet + Çalma listesini düzenle + Çal + Karıştır + Çalma listesi • %1$d şarkı + Sıraya ekle + Sil + İndir + Kanala git + Sonra çal + Kaldır + Kanallar + Kanallara göz at + RSS URL + Podcast Kanalı + Açıklama + Bölümler + Bölüm mevcut değil + İsteğiniz sunucuya gönderildi + Bölümü gizlemek için tıklayın\nDeğişiklikler yeniden başlatıldığında görülecek + Bir kanal eklediğinizde burada göreceksiniz + Podcast bulunamadı! + %1$s • %2$s + Radyo Anasayfa URL’si + Radyo Adı + Radyo Yayın URL’si + İptal + Sil + Kaydet + İnternet Radyo İstasyonu + Bölümü gizlemek için tıklayın\nDeğişiklikler yeniden başlatıldığında görülecek + Bir radyo istasyonu eklediğinizde burada göreceksiniz + İstasyon bulunamadı! + İptal + Kaydet + Değerlendir + Başlık, sanatçı veya albüm ara + En az üç karakter girin + Albümler + Sanatçılar + Şarkılar + Düşük güvenlik + Silmek için uzun basın + Yerel URL + Sunucu Adı + Parola + Sunucu URL’si + Kullanıcı adı + İptal + Sil + Kaydet + Sunucu ekle + İptal + Girişe git + Yine de devam et + İstenen sunucuya ulaşılamıyor. Devam etmeyi seçerseniz bu iletişim penceresi bir saat boyunca tekrar görünmez. + Sunucuya ulaşılamıyor + Tempo, Subsonic için açık kaynaklı ve hafif bir müzik istemcisidir, Android için yerel olarak tasarlanıp geliştirilmiştir. + Hakkında + Her zaman açık ekran + Dönüştürme formatı + Etkinleştirildiğinde, Tempo parçayı aşağıdaki dönüştürme ayarlarıyla indirmeye zorlamaz. + İndirmelerde yayın için kullanılan sunucu ayarlarına öncelik ver + Etkinleştirildiğinde, Tempo dönüştürülmüş parçaları indirir. + Dönüştürülmüş parçaları indir + Etkinleştirildiğinde, parçanın tahmini süresi sunucudan istenir. + İçerik uzunluğunu tahmin et + İndirmeler için dönüştürme formatı + Mobilde dönüştürme formatı + Wi-Fi’da dönüştürme formatı + Etkinleştirildiğinde, Tempo parçayı aşağıdaki dönüştürme ayarlarıyla yayınlamayacaktır. + Sunucu dönüştürme ayarlarına öncelik ver + Parçanın dönüştürülmesinde öncelik sunucuya verildi + Önbellekleme stratejisi + Değişikliğin geçerli olması için uygulamayı elle yeniden başlatmalısınız. + Bir çalma listesi bittiğinde benzer şarkılar çalarak müziğin devam etmesine izin verir + Sürekli çalma + Albüm kapağı önbelleği boyutu + Veri tüketimini azaltmak için kapak görsellerinin indirilmesinden kaçının. + Mobil veri kullanımını sınırla + Devam ederseniz tüm kayıtlı öğeler geri alınamaz şekilde silinecektir. + Kayıtlı öğeleri sil + İndirme depolaması + Ses ayarlarını düzenle + Ekolayzır + https://github.com/eddyizm/tempo + Gelişmeleri takip et + Github + Görsel çözünürlüğünü ayarla + Dil + Çıkış yap + İndirmeler için bit hızı + Mobilde bit hızı + Wi-Fi’da bit hızı + Ortam dosyası önbelleği boyutu + Müzik dizinlerini göster + Etkinleştirildiğinde müzik dizini bölümü görüntülenir. Klasörlerde gezinmenin doğru çalışması için sunucunun bu özelliği desteklemesi gerekir. + Podcast’i göster + Etkinleştirildiğinde podcast bölümü görüntülenir. Tam etkili olması için uygulamayı yeniden başlatın. + Ses kalitesini göster + Her ses parçası için bit hızı ve ses formatı gösterilecektir. + Öğe değerlemesini göster + Etkinleştirildiğinde, öğenin puanı ve favori olarak işaretlenip işaretlenmediği görüntülenir. + Eşitleme zamanlayıcısı + Etkinleştirildiğinde, kullanıcı çalma sırasını kaydedebilir ve uygulamayı açtığında bu durumu yükleyebilir. + Bu kullanıcı için çalma sırasını eşitle + Radyoyu göster + Etkinleştirildiğinde radyo bölümü görüntülenir. Tam etkili olması için uygulamayı yeniden başlatın. + Yeniden çalma kazanç modunu ayarla + Yuvarlatılmış köşeler + Köşe boyutu + Eğrilik açısının büyüklüğünü ayarlar. + Etkinleştirildiğinde, tüm kapak görselleri için bir eğme açısı uygulanır. Değişiklikler yeniden başlatıldığında geçerli olur. + Kütüphaneyi tara + Müzik scrobbling özelliğini etkinleştir + Sistem dili + Müzik paylaşımını etkinleştir + Yayın önbelleği boyutu + Yayın önbellek depolaması + Scrobbling özelliğinin çalışabilmesi için sunucunun bu verileri alacak şekilde etkinleştirilmiş olması gerekir. + Bir sanatçı radyosu dinlerken, anında karışımda veya tümünü karıştırırken belirli bir kullanıcı puanının altındaki parçalar yok sayılacaktır. + Replay gain, ses parçalarının ses seviyesini ayarlayarak tutarlı bir dinleme deneyimi sağlayan bir özelliktir. Bu ayar yalnızca parçada gerekli meta veriler varsa etkilidir. + Scrobbling, cihazınızın dinlediğiniz şarkılar hakkında bilgileri müzik sunucusuna göndermesini sağlayan bir özelliktir. Bu bilgiler müzik tercihlerinize göre kişisel öneriler oluşturulmasına yardımcı olur. + Kullanıcının müziği bir bağlantı üzerinden paylaşmasına olanak tanır. Bu işlevin sunucu tarafından desteklenmesi ve etkinleştirilmesi gerekir ve yalnızca tekil parçalar, albümler ve çalma listeleriyle sınırlıdır. + Bu kullanıcının çalma sırasının durumunu geri yükler. Buna çalma sırasındaki parçalar, o anda çalan parça ve bu parçadaki konum dahildir. Sunucunun bu özelliği desteklemesi gerekir. + %1$s \nŞu anda kullanımda: %2$s MiB + Dönüştürme moduna öncelik verilir. “Doğrudan çal” olarak ayarlanırsa dosyanın bit hızı değiştirilmez. + Dönüştürülmüş medyayı indir. Etkinleştirilirse indirme uç noktası kullanılmaz, bunun yerine aşağıdaki ayarlar geçerli olur. \n\n “İndirmeler için dönüştürme formatı” “Doğrudan indir” olarak ayarlanırsa dosyanın bit hızı değiştirilmez. + Dosya anlık olarak dönüştürüldüğünde, istemci genellikle parçanın süresini göstermez. Bu işlevi destekleyen sunuculardan çalınan parçanın süresini tahmin etmeleri istenebilir, + ancak yanıt süreleri daha uzun olabilir. + Etkinleştirildiğinde, yıldızlı parçalar çevrimdışı kullanım için indirilecektir. + Çevrimdışı kullanım için yıldızlı parçaları eşitle + Tema + Veri + Genel + Değerlendirme + Replay Gain + Scrobble + Değerlendirmeye göre parçaları yok say + Şu puana sahip şarkılar: + Paylaş + Eşitleme + Dönüştürme + Dönüştürme İndir + Arayüz + Dönüştürülmüş indirme + 3.1.0 + Sürüm + Mobil ağ üzerinden yayın yapmadan önce kullanıcı onayı iste. + Yalnızca Wi-Fi ile yayın uyarısı + Bağlantıyı kopyala + Paylaşımı sil + Paylaşımı güncelle + Bitiş tarihi: %1$s + Paylaşım desteklenmiyor veya etkin değil + Açıklama + Bitiş tarihi + İptal + Kaydet + Paylaş + Çalma listesine ekle + Sıraya ekle + İndir + Albüm alınırken hata oluştu + Sanatçı alınırken hata oluştu + Albüme git + Sanatçıya git + Anında karışım + Sonra çal + Değerlendir + Kaldır + Paylaş + İndirilenler + En çok çalınan parçalar + Son eklenen parçalar + Son çalınan parçalar + Yıldızlı parçalar + %1$s’in en iyi parçaları + %1$d yılı + %1$s • %2$s %3$s + İptal + Devam et + Devam et ve indir + Yıldızlı parçaların indirilmesi yüksek miktarda veri gerektirebilir. + Yıldızlı parçaları eşitle + Değişikliklerin geçerli olması için uygulamayı yeniden başlatın. + Önbelleğe alınmış dosyaların hedefini bir depolamadan diğerine değiştirmek, önceki depolamadaki önbellek dosyalarının silinmesine yol açabilir. + Depolama seçeneğini seç + Harici + Dahili + https://buymeacoffee.com/a.cappiello + Albüm + Sanatçı + Bit derinliği + Bit hızı + İçerik türü + Tamam + Parça bilgisi + Disk numarası + Süre + Tür + Yol + Örnekleme oranı + Boyut + Uzantı + Dosya Subsonic API’leri kullanılarak indirildi. Dosyanın dönüştürme ve bit hızı, kaynak dosyadan değişmeden kaldı. + Uygulama, sunucudan dosyayı dönüştürmesini ve bit hızını değiştirmesini talep edecektir. Kullanıcının istediği kodek %1$s ve bit hızı %2$s. Seçilen formatta kodek ve bit hızındaki olası değişiklikler + sunucu tarafından yapılır ve bu işlem sunucu tarafından desteklenebilir veya desteklenmeyebilir. + Uygulama yalnızca sunucunun sağladığı orijinal dosyayı okuyacaktır. + Uygulama, dönüştürülmemiş dosyayı orijinal kaynağın bit hızıyla sunucudan açıkça talep eder. + Çalınacak dosyanın kalitesi sunucunun kararına bırakılır. Uygulama, olası dönüştürmeler için kodek ve bit hızı seçimini zorlamaz. + Uygulama, sunucudan dosyanın bit hızını değiştirmesini talep edecektir. + Kullanıcının istediği bit hızı %1$s, kaynak dosyanın kodeği aynı kalacaktır. Seçilen formatta dosyanın bit hızındaki olası değişiklikler sunucu tarafından yapılır ve bu işlem sunucu tarafından desteklenebilir veya desteklenmeyebilir. + Uygulama, sunucudan dosyayı dönüştürmesini talep edecektir. + Kullanıcının istediği kodek %1$s, bit hızı ise kaynak dosyayla aynı kalacaktır. Dosyanın seçilen formata olası dönüştürülmesi sunucuya bağlıdır, destekleyebilir ya da desteklemeyebilir. + Başlık + Parça numarası + Dönüştürülmüş içerik türü + Dönüştürülmüş uzantı + Yıl + unDraw + İllüstrasyonlarıyla bu uygulamayı daha güzel hale getirmemize yardımcı olan unDraw’a özel teşekkürler. + https://undraw.co/ + diff --git a/app/src/main/res/xml/locale_config.xml b/app/src/main/res/xml/locale_config.xml index ac6e6d0e..2838b579 100644 --- a/app/src/main/res/xml/locale_config.xml +++ b/app/src/main/res/xml/locale_config.xml @@ -10,4 +10,5 @@ + From 8ed0a4642bd0cd637c65e3115142596331fa7ef7 Mon Sep 17 00:00:00 2001 From: eddyizm Date: Fri, 22 Aug 2025 22:12:22 -0700 Subject: [PATCH 08/16] chore: adding a note/not fully baked label to the sync user play queue setting #47 --- app/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dd2b066e..df9e0888 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -315,7 +315,7 @@ If enabled, the item\'s rating and whether it is marked as a favorite will be displayed. Sync timer If enabled, the user will have the ability to save their play queue and will have the ability to load state when opening the application. - Sync play queue for this user + Sync play queue for this user [Not Fully Baked] Show radio If enabled, show the radio section. Restart the app for it to take full effect. Set replay gain mode @@ -334,7 +334,7 @@ Replay gain is a feature that allows you to adjust the volume level of audio tracks for a consistent listening experience. This setting is only effective if the track contains the necessary metadata. Scrobbling is a feature that allows your device to send information about the songs you listen to the music server. This information helps create personalized recommendations based on your music preferences. Allows the user to share music via a link. The functionality must be supported and enabled server-side and is limited to individual tracks, albums and playlists. - Returns the state of the play queue for this user. This includes the tracks in the play queue, the currently playing track, and the position within this track. The server must support this feature. + Returns the state of the play queue for this user. This includes the tracks in the play queue, the currently playing track, and the position within this track. The server must support this feature.\n*This setting is not 100% working on all servers/devices. %1$s \nCurrently in use: %2$s MiB Priority given to the transcoding mode. If set to \"Direct play\" the bitrate of the file will not be changed. Download transcoded media. If enabled, the download endpoint will not be used, but the following settings. \n\n If \"Transcode format for donwloads\" is set to \"Direct download\" the bitrate of the file will not be changed. From 26a5fb029a07752c9c0db0d08a89afd638772579 Mon Sep 17 00:00:00 2001 From: eddyizm Date: Sat, 23 Aug 2025 13:04:17 -0700 Subject: [PATCH 09/16] fix: moved hardcoded italian save text to string template, updated with english and italian language xmls --- .../tempo/ui/fragment/PlayerCoverFragment.java | 3 ++- app/src/main/res/values-it/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerCoverFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerCoverFragment.java index f44ed41e..15f647c8 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerCoverFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerCoverFragment.java @@ -19,6 +19,7 @@ import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; +import com.cappielloantonio.tempo.R; import com.cappielloantonio.tempo.databinding.InnerFragmentPlayerCoverBinding; import com.cappielloantonio.tempo.glide.CustomGlideRequest; import com.cappielloantonio.tempo.model.Download; @@ -136,7 +137,7 @@ public class PlayerCoverFragment extends Fragment { bind.innerButtonBottomRight.setOnClickListener(view -> { if (playerBottomSheetViewModel.savePlayQueue()) { - Snackbar.make(requireView(), "Salvato", Snackbar.LENGTH_LONG).show(); + Snackbar.make(requireView(), R.string.player_queue_save_queue_success, Snackbar.LENGTH_LONG).show(); } }); diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index a5f3be74..fe9cd76a 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -183,6 +183,7 @@ Anno %1$.2fx Svuota coda di riproduzione + Salvato Priorità server Catalogo playlist Sfoglia le playlist diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index df9e0888..9b6a76d1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -192,6 +192,7 @@ Year %1$.2fx Clean play queue + Saved play queue Server Priority Unknown format Transcoding From 02eef97171a30c585bed3ec62f38131504fada9d Mon Sep 17 00:00:00 2001 From: eddyizm Date: Sat, 23 Aug 2025 13:47:19 -0700 Subject: [PATCH 10/16] chore: bumping version for release --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0aace15a..5926fa3f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { minSdkVersion 24 targetSdk 35 - versionCode 28 - versionName '3.12.0' + versionCode 29 + versionName '3.13.0' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' From 698ca3b22b38ae321a80730f12de1d0419ea82fc Mon Sep 17 00:00:00 2001 From: eddyizm Date: Sat, 23 Aug 2025 14:05:01 -0700 Subject: [PATCH 11/16] chore: changelog update --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71c57bcc..1b84b06a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ ***This log is for this fork to detail updates since 3.9.0 from the main repo.*** +## [3.13.0](https://github.com/eddyizm/tempo/releases/tag/v3.13.0) (2025-08-23) +## What's Changed +* style: Change position and size of rating container by @jaime-grj in https://github.com/eddyizm/tempo/pull/44 +* feat: Add Turkish localization (values-tr) by @mucahit-kaya in https://github.com/eddyizm/tempo/pull/50 +* chore: adding a note/not fully baked label to the sync user play queue setting by @eddyizm in https://github.com/eddyizm/tempo/commit/8ed0a4642bd0cd637c65e3115142596331fa7ef7 +* fix: moved hardcoded italian save text to string template, updated with english and italian language xmls by @eddyizm in https://github.com/eddyizm/tempo/commit/26a5fb029a07752c9c0db0d08a89afd638772579 + + +## New Contributors +* @mucahit-kaya made their first contribution in https://github.com/eddyizm/tempo/pull/50 + +**Full Changelog**: https://github.com/eddyizm/tempo/compare/v3.12.0...v3.13.0 + ## [3.12.0](https://github.com/eddyizm/tempo/releases/tag/v3.12.0) (2025-08-15) ### What's Changed * [chore]: add German translations for track info and home section strings (#29) by @BreadWare92 in https://github.com/eddyizm/tempo/pull/31 From 1bbcf6c790976201e47de0f6f30bf9f4599185c6 Mon Sep 17 00:00:00 2001 From: eddyizm Date: Sat, 23 Aug 2025 17:57:45 -0700 Subject: [PATCH 12/16] feat: rating dialog added to album page --- .../tempo/ui/dialog/RatingDialog.java | 6 +++++- .../tempo/ui/fragment/AlbumPageFragment.java | 13 +++++++++++++ app/src/main/res/menu/album_page_menu.xml | 5 +++++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/RatingDialog.java b/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/RatingDialog.java index fc829152..a2d16003 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/RatingDialog.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/RatingDialog.java @@ -63,7 +63,11 @@ public class RatingDialog extends DialogFragment { bind.ratingBar.setRating(song.getUserRating() != null ? song.getUserRating() : 0); }); } else if (ratingViewModel.getAlbum() != null) { - ratingViewModel.getLiveAlbum().observe(this, album -> bind.ratingBar.setRating(/*album.getRating()*/ 0)); + ratingViewModel.getLiveAlbum().observe(this, album -> { + if (album != null) { + bind.ratingBar.setRating(album.getUserRating() != null ? album.getUserRating() : 0); + } + }); } else if (ratingViewModel.getArtist() != null) { ratingViewModel.getLiveArtist().observe(this, artist -> bind.ratingBar.setRating(/*artist.getRating()*/ 0)); } diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumPageFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumPageFragment.java index dc02dcbe..03e71e10 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumPageFragment.java @@ -4,6 +4,7 @@ import android.content.ComponentName; import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.os.Parcelable; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -27,11 +28,13 @@ import com.cappielloantonio.tempo.databinding.FragmentAlbumPageBinding; import com.cappielloantonio.tempo.glide.CustomGlideRequest; import com.cappielloantonio.tempo.interfaces.ClickCallback; import com.cappielloantonio.tempo.model.Download; +import com.cappielloantonio.tempo.subsonic.models.AlbumID3; import com.cappielloantonio.tempo.service.MediaManager; import com.cappielloantonio.tempo.service.MediaService; import com.cappielloantonio.tempo.ui.activity.MainActivity; import com.cappielloantonio.tempo.ui.adapter.SongHorizontalAdapter; import com.cappielloantonio.tempo.ui.dialog.PlaylistChooserDialog; +import com.cappielloantonio.tempo.ui.dialog.RatingDialog; import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.util.DownloadUtil; import com.cappielloantonio.tempo.util.MappingUtil; @@ -104,6 +107,16 @@ public class AlbumPageFragment extends Fragment implements ClickCallback { @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.action_rate_album) { + Bundle bundle = new Bundle(); + AlbumID3 album = albumPageViewModel.getAlbum().getValue(); + bundle.putParcelable(Constants.ALBUM_OBJECT, (Parcelable) album); + RatingDialog dialog = new RatingDialog(); + dialog.setArguments(bundle); + dialog.show(requireActivity().getSupportFragmentManager(), null); + return true; + } + if (item.getItemId() == R.id.action_download_album) { albumPageViewModel.getAlbumSongLiveList().observe(getViewLifecycleOwner(), songs -> { DownloadUtil.getDownloadTracker(requireContext()).download(MappingUtil.mapDownloads(songs), songs.stream().map(Download::new).collect(Collectors.toList())); diff --git a/app/src/main/res/menu/album_page_menu.xml b/app/src/main/res/menu/album_page_menu.xml index 4524d32f..1e3f6d71 100644 --- a/app/src/main/res/menu/album_page_menu.xml +++ b/app/src/main/res/menu/album_page_menu.xml @@ -11,4 +11,9 @@ android:icon="@drawable/ic_add" android:title="@string/menu_add_to_playlist_button" app:showAsAction="never" /> + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9b6a76d1..16d57956 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -164,6 +164,7 @@ Add Add to playlist Download all + Rate album Download All Downloaded From 08023026b43e37bf8465ebc8b46cf186ca9625f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa?= <55400857+jaime-grj@users.noreply.github.com> Date: Sun, 24 Aug 2025 19:24:05 +0200 Subject: [PATCH 13/16] style: Add song rating bar in landscape player controller layout --- ...nner_fragment_player_controller_layout.xml | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/app/src/main/res/layout-land/inner_fragment_player_controller_layout.xml b/app/src/main/res/layout-land/inner_fragment_player_controller_layout.xml index 61112689..7ad0250e 100644 --- a/app/src/main/res/layout-land/inner_fragment_player_controller_layout.xml +++ b/app/src/main/res/layout-land/inner_fragment_player_controller_layout.xml @@ -75,6 +75,39 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + + + + + + Date: Sun, 24 Aug 2025 18:55:36 -0700 Subject: [PATCH 14/16] feat: setting to show/hide 5 star rating on playerview --- .../ui/fragment/PlayerControllerFragment.java | 15 +++++++++++++++ .../cappielloantonio/tempo/util/Preferences.kt | 6 ++++++ app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/global_preferences.xml | 6 ++++++ 4 files changed, 29 insertions(+) diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java index a07d58ec..99f3c4ca 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerControllerFragment.java @@ -8,6 +8,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageButton; +import android.widget.LinearLayout; import android.widget.TextView; import android.widget.ToggleButton; import android.widget.RatingBar; @@ -66,6 +67,7 @@ public class PlayerControllerFragment extends Fragment { private ConstraintLayout playerQuickActionView; private ImageButton playerOpenQueueButton; private ImageButton playerTrackInfo; + private LinearLayout ratingContainer; private MainActivity activity; private PlayerBottomSheetViewModel playerBottomSheetViewModel; @@ -123,6 +125,8 @@ public class PlayerControllerFragment extends Fragment { playerOpenQueueButton = bind.getRoot().findViewById(R.id.player_open_queue_button); playerTrackInfo = bind.getRoot().findViewById(R.id.player_info_track); songRatingBar = bind.getRoot().findViewById(R.id.song_rating_bar); + ratingContainer = bind.getRoot().findViewById(R.id.rating_container); + checkAndSetRatingContainerVisibility(); } private void initQuickActionView() { @@ -430,6 +434,17 @@ public class PlayerControllerFragment extends Fragment { playerMediaCoverViewPager.setCurrentItem(1, true); } + private void checkAndSetRatingContainerVisibility() { + if (ratingContainer == null) return; + + if (Preferences.showItemStarRating()) { + ratingContainer.setVisibility(View.VISIBLE); + } + else { + ratingContainer.setVisibility(View.GONE); + } + } + private void setPlaybackParameters(MediaBrowser mediaBrowser) { Button playbackSpeedButton = bind.getRoot().findViewById(R.id.player_playback_speed_button); float currentSpeed = Preferences.getPlaybackSpeed(); diff --git a/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt b/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt index e7a4c459..c7bfe993 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt +++ b/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt @@ -63,6 +63,7 @@ object Preferences { private const val ALWAYS_ON_DISPLAY = "always_on_display" private const val AUDIO_QUALITY_PER_ITEM = "audio_quality_per_item" private const val HOME_SECTOR_LIST = "home_sector_list" + private const val SONG_RATING_PER_ITEM = "song_rating_per_item" private const val RATING_PER_ITEM = "rating_per_item" private const val NEXT_UPDATE_CHECK = "next_update_check" private const val CONTINUOUS_PLAY = "continuous_play" @@ -486,6 +487,11 @@ object Preferences { App.getInstance().preferences.edit().putString(HOME_SECTOR_LIST, Gson().toJson(extension)).apply() } + @JvmStatic + fun showItemStarRating(): Boolean { + return App.getInstance().preferences.getBoolean(SONG_RATING_PER_ITEM, false) + } + @JvmStatic fun showItemRating(): Boolean { return App.getInstance().preferences.getBoolean(RATING_PER_ITEM, false) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9b6a76d1..b2b953ee 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -312,6 +312,8 @@ If enabled, show the podcast section. Restart the app for it to take full effect. Show audio quality The bitrate and audio format will be shown for each audio track. + Show song star rating + If enabled, hides 5 star rating for track on song page\n\n*Requires App restart Show item rating If enabled, the item\'s rating and whether it is marked as a favorite will be displayed. Sync timer diff --git a/app/src/main/res/xml/global_preferences.xml b/app/src/main/res/xml/global_preferences.xml index c90779b2..ddbcc1a7 100644 --- a/app/src/main/res/xml/global_preferences.xml +++ b/app/src/main/res/xml/global_preferences.xml @@ -57,6 +57,12 @@ android:summary="@string/settings_audio_quality_summary" android:key="audio_quality_per_item" /> + + Date: Tue, 26 Aug 2025 21:57:20 -0700 Subject: [PATCH 15/16] fix: catches null value and prepares bundle appropriately adding single track to expected array list. closes #58 --- .../tempo/ui/dialog/PlaylistChooserDialog.java | 11 ++++++++--- .../tempo/ui/fragment/PlayerCoverFragment.java | 6 +++++- .../tempo/viewmodel/PlaylistChooserViewModel.java | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/PlaylistChooserDialog.java b/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/PlaylistChooserDialog.java index 5c0b119c..360a5ec5 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/PlaylistChooserDialog.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/dialog/PlaylistChooserDialog.java @@ -3,6 +3,7 @@ package com.cappielloantonio.tempo.ui.dialog; import android.app.Dialog; import android.os.Bundle; import android.view.View; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.fragment.app.DialogFragment; @@ -97,8 +98,12 @@ public class PlaylistChooserDialog extends DialogFragment implements ClickCallba @Override public void onPlaylistClick(Bundle bundle) { - Playlist playlist = bundle.getParcelable(Constants.PLAYLIST_OBJECT); - playlistChooserViewModel.addSongsToPlaylist(playlist.getId()); - dismiss(); + if (playlistChooserViewModel.getSongsToAdd() != null && !playlistChooserViewModel.getSongsToAdd().isEmpty()) { + Playlist playlist = bundle.getParcelable(Constants.PLAYLIST_OBJECT); + playlistChooserViewModel.addSongsToPlaylist(playlist.getId()); + dismiss(); + } else { + Toast.makeText(requireContext(), R.string.playlist_chooser_dialog_toast_add_failure, Toast.LENGTH_SHORT).show(); + } } } diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerCoverFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerCoverFragment.java index 15f647c8..392c5786 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerCoverFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerCoverFragment.java @@ -9,6 +9,7 @@ import android.transition.TransitionManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import java.util.ArrayList; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; @@ -31,6 +32,7 @@ import com.cappielloantonio.tempo.util.DownloadUtil; import com.cappielloantonio.tempo.util.MappingUtil; import com.cappielloantonio.tempo.util.Preferences; import com.cappielloantonio.tempo.viewmodel.PlayerBottomSheetViewModel; +import com.cappielloantonio.tempo.subsonic.models.Child; import com.google.android.material.snackbar.Snackbar; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; @@ -120,8 +122,10 @@ public class PlayerCoverFragment extends Fragment { }); bind.innerButtonTopRight.setOnClickListener(view -> { + ArrayList tracks = new ArrayList<>(); + tracks.add(song); Bundle bundle = new Bundle(); - bundle.putParcelable(Constants.TRACK_OBJECT, song); + bundle.putParcelableArrayList(Constants.TRACKS_OBJECT, tracks); PlaylistChooserDialog dialog = new PlaylistChooserDialog(); dialog.setArguments(bundle); diff --git a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlaylistChooserViewModel.java b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlaylistChooserViewModel.java index fdee85c6..2ec6c21f 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlaylistChooserViewModel.java +++ b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlaylistChooserViewModel.java @@ -21,7 +21,7 @@ public class PlaylistChooserViewModel extends AndroidViewModel { private final PlaylistRepository playlistRepository; private final MutableLiveData> playlists = new MutableLiveData<>(null); - private ArrayList toAdd; + private ArrayList toAdd = new ArrayList<>(); public PlaylistChooserViewModel(@NonNull Application application) { super(application); From 1ed6ac6cffef678d03384b6859055cf7c43de39c Mon Sep 17 00:00:00 2001 From: eddyizm Date: Wed, 27 Aug 2025 18:29:14 -0700 Subject: [PATCH 16/16] fix: artist filtering in library view browse artist resolves #45 --- .../ui/fragment/AlbumListPageFragment.java | 2 +- .../ui/fragment/ArtistCatalogueFragment.java | 42 +++++++++++++++++-- app/src/main/res/menu/artist_list_menu.xml | 12 ++++++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/menu/artist_list_menu.xml diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumListPageFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumListPageFragment.java index eb5b19c5..9a1557a6 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumListPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumListPageFragment.java @@ -145,7 +145,7 @@ public class AlbumListPageFragment extends Fragment implements ClickCallback { @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - inflater.inflate(R.menu.toolbar_menu, menu); + inflater.inflate(R.menu.artist_list_menu, menu); MenuItem searchItem = menu.findItem(R.id.action_search); diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistCatalogueFragment.java index 1ad88e8e..17d01f95 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistCatalogueFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistCatalogueFragment.java @@ -13,6 +13,7 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.PopupMenu; import android.widget.SearchView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -24,6 +25,8 @@ import androidx.navigation.Navigation; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import android.util.Log; + import com.cappielloantonio.tempo.R; import com.cappielloantonio.tempo.databinding.FragmentArtistCatalogueBinding; import com.cappielloantonio.tempo.helper.recyclerview.GridItemDecoration; @@ -32,6 +35,10 @@ import com.cappielloantonio.tempo.ui.activity.MainActivity; import com.cappielloantonio.tempo.ui.adapter.ArtistCatalogueAdapter; import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.viewmodel.ArtistCatalogueViewModel; +import com.cappielloantonio.tempo.subsonic.models.ArtistID3; + +import java.util.ArrayList; +import java.util.List; @UnstableApi public class ArtistCatalogueFragment extends Fragment implements ClickCallback { @@ -125,23 +132,50 @@ public class ArtistCatalogueFragment extends Fragment implements ClickCallback { SearchView searchView = (SearchView) searchItem.getActionView(); searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); + + searchView.setQueryHint(getString(R.string.filter_artist)); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { - searchView.clearFocus(); - return false; + // this toast may be overkill... + Toast.makeText(requireContext(), "Search: " + query, Toast.LENGTH_SHORT).show(); + filterArtists(query); + return true; } @Override public boolean onQueryTextChange(String newText) { - artistAdapter.getFilter().filter(newText); - return false; + filterArtists(newText); + return true; } }); searchView.setPadding(-32, 0, 0, 0); } + private void filterArtists(String query) { + List allArtists = artistCatalogueViewModel.getArtistList().getValue(); + + if (allArtists == null || allArtists.isEmpty()) { + return; + } + + if (query == null || query.trim().isEmpty()) { + artistAdapter.setItems(allArtists); + } else { + String searchQuery = query.toLowerCase().trim(); + List filteredArtists = new ArrayList<>(); + + for (ArtistID3 artist : allArtists) { + if (artist.getName() != null && + artist.getName().toLowerCase().contains(searchQuery)) { + filteredArtists.add(artist); + } + } + artistAdapter.setItems(filteredArtists); + } + } + private void hideKeyboard(View view) { InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); diff --git a/app/src/main/res/menu/artist_list_menu.xml b/app/src/main/res/menu/artist_list_menu.xml new file mode 100644 index 00000000..7cc7d34d --- /dev/null +++ b/app/src/main/res/menu/artist_list_menu.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fbb3ebcf..ef389aeb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -90,6 +90,7 @@ Downloads Select two or more filters Filter + Filter artists Filter Genres (%1$d) (+%1$d)