Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3086a8b9f9 | ||
|
|
10c2172be0 | ||
|
|
918bf6928e | ||
|
|
c9cf86acb5 | ||
|
|
0487f3bb9b | ||
|
|
c7f2524085 |
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
## [4.12.4](https://github.com/eddyizm/tempo/releases/tag/v4.12.4) (2026-03-01)
|
||||||
|
* feat: advertise existing long press to refresh per section on library page by @tvillega in https://github.com/eddyizm/tempus/pull/467
|
||||||
|
* fix: playlist filter returns properly filtered list and reset correctly by @eddyizm in https://github.com/eddyizm/tempus/pull/476
|
||||||
|
* feat: toggle player bitrate visibility on touch by @tvillega in https://github.com/eddyizm/tempus/pull/466
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/eddyizm/tempus/compare/v4.12.0...v4.12.3
|
||||||
|
|
||||||
## What's Changed
|
## What's Changed
|
||||||
## [4.12.0](https://github.com/eddyizm/tempo/releases/tag/v4.12.0) (2026-02-28)
|
## [4.12.0](https://github.com/eddyizm/tempo/releases/tag/v4.12.0) (2026-02-28)
|
||||||
* chore(i18n): Update Polish translation by @skajmer in https://github.com/eddyizm/tempus/pull/441
|
* chore(i18n): Update Polish translation by @skajmer in https://github.com/eddyizm/tempus/pull/441
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ android {
|
|||||||
minSdkVersion 24
|
minSdkVersion 24
|
||||||
targetSdk 35
|
targetSdk 35
|
||||||
|
|
||||||
versionCode 21
|
versionCode 22
|
||||||
versionName '4.12.0'
|
versionName '4.12.4'
|
||||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||||
|
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
@@ -101,6 +101,7 @@ dependencies {
|
|||||||
implementation 'androidx.room:room-runtime:2.6.1'
|
implementation 'androidx.room:room-runtime:2.6.1'
|
||||||
implementation 'androidx.core:core-splashscreen:1.0.1'
|
implementation 'androidx.core:core-splashscreen:1.0.1'
|
||||||
implementation 'androidx.appcompat:appcompat:1.7.0'
|
implementation 'androidx.appcompat:appcompat:1.7.0'
|
||||||
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.2.0"
|
||||||
|
|
||||||
// Android Material
|
// Android Material
|
||||||
implementation 'com.google.android.material:material:1.10.0'
|
implementation 'com.google.android.material:material:1.10.0'
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ public class PlaylistHorizontalAdapter extends RecyclerView.Adapter<PlaylistHori
|
|||||||
|
|
||||||
FilterResults results = new FilterResults();
|
FilterResults results = new FilterResults();
|
||||||
results.values = filteredList;
|
results.values = filteredList;
|
||||||
|
results.count = filteredList.size();
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
@@ -54,7 +55,9 @@ public class PlaylistHorizontalAdapter extends RecyclerView.Adapter<PlaylistHori
|
|||||||
@Override
|
@Override
|
||||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||||
playlists.clear();
|
playlists.clear();
|
||||||
if (results.count > 0) playlists.addAll((List) results.values);
|
if (results.values != null) {
|
||||||
|
playlists.addAll((List<Playlist>) results.values);
|
||||||
|
}
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import android.view.ViewGroup;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.session.MediaBrowser;
|
import androidx.media3.session.MediaBrowser;
|
||||||
@@ -16,8 +18,11 @@ import androidx.media3.session.SessionToken;
|
|||||||
import androidx.navigation.Navigation;
|
import androidx.navigation.Navigation;
|
||||||
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
|
|
||||||
import com.cappielloantonio.tempo.R;
|
import com.cappielloantonio.tempo.R;
|
||||||
import com.cappielloantonio.tempo.databinding.FragmentLibraryBinding;
|
import com.cappielloantonio.tempo.databinding.FragmentLibraryBinding;
|
||||||
@@ -43,6 +48,7 @@ import java.util.Objects;
|
|||||||
@UnstableApi
|
@UnstableApi
|
||||||
public class LibraryFragment extends Fragment implements ClickCallback {
|
public class LibraryFragment extends Fragment implements ClickCallback {
|
||||||
private static final String TAG = "LibraryFragment";
|
private static final String TAG = "LibraryFragment";
|
||||||
|
private static final String TOAST_MSG = "Long press to refresh" ;
|
||||||
|
|
||||||
private FragmentLibraryBinding bind;
|
private FragmentLibraryBinding bind;
|
||||||
private MainActivity activity;
|
private MainActivity activity;
|
||||||
@@ -81,6 +87,7 @@ public class LibraryFragment extends Fragment implements ClickCallback {
|
|||||||
initArtistView();
|
initArtistView();
|
||||||
initGenreView();
|
initGenreView();
|
||||||
initPlaylistView();
|
initPlaylistView();
|
||||||
|
initSwipeToRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -112,22 +119,41 @@ public class LibraryFragment extends Fragment implements ClickCallback {
|
|||||||
activity.navController.navigate(R.id.action_libraryFragment_to_playlistCatalogueFragment, bundle);
|
activity.navController.navigate(R.id.action_libraryFragment_to_playlistCatalogueFragment, bundle);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Album
|
||||||
bind.albumCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> {
|
bind.albumCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> {
|
||||||
libraryViewModel.refreshAlbumSample(getViewLifecycleOwner());
|
libraryViewModel.refreshAlbumSample(getViewLifecycleOwner());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
bind.albumCatalogueSampleTextViewRefreshable.setOnClickListener( v ->
|
||||||
|
Toast.makeText(requireContext(), TOAST_MSG, Toast.LENGTH_SHORT).show()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Artist
|
||||||
bind.artistCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> {
|
bind.artistCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> {
|
||||||
libraryViewModel.refreshArtistSample(getViewLifecycleOwner());
|
libraryViewModel.refreshArtistSample(getViewLifecycleOwner());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
bind.artistCatalogueSampleTextViewRefreshable.setOnClickListener( v ->
|
||||||
|
Toast.makeText(requireContext(), TOAST_MSG, Toast.LENGTH_SHORT).show()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Genre
|
||||||
bind.genreCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> {
|
bind.genreCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> {
|
||||||
libraryViewModel.refreshGenreSample(getViewLifecycleOwner());
|
libraryViewModel.refreshGenreSample(getViewLifecycleOwner());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
bind.genreCatalogueSampleTextViewRefreshable.setOnClickListener(v ->
|
||||||
|
Toast.makeText(requireContext(), TOAST_MSG, Toast.LENGTH_SHORT).show()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Playlist
|
||||||
bind.playlistCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> {
|
bind.playlistCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> {
|
||||||
libraryViewModel.refreshPlaylistSample(getViewLifecycleOwner());
|
libraryViewModel.refreshPlaylistSample(getViewLifecycleOwner());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
bind.playlistCatalogueSampleTextViewRefreshable.setOnClickListener( v ->
|
||||||
|
Toast.makeText(requireContext(), TOAST_MSG, Toast.LENGTH_SHORT).show()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initAppBar() {
|
private void initAppBar() {
|
||||||
@@ -304,4 +330,20 @@ public class LibraryFragment extends Fragment implements ClickCallback {
|
|||||||
private void initializeMediaBrowser() {
|
private void initializeMediaBrowser() {
|
||||||
mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync();
|
mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initSwipeToRefresh() {
|
||||||
|
bind.swipeLibraryToRefresh.setOnRefreshListener(() -> {
|
||||||
|
pullToRefresh();
|
||||||
|
bind.swipeLibraryToRefresh.setRefreshing(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pullToRefresh() {
|
||||||
|
LifecycleOwner lifecycleOwner = getViewLifecycleOwner();
|
||||||
|
libraryViewModel.refreshAlbumSample(lifecycleOwner);
|
||||||
|
libraryViewModel.refreshGenreSample(lifecycleOwner);
|
||||||
|
libraryViewModel.refreshArtistSample(lifecycleOwner);
|
||||||
|
libraryViewModel.refreshPlaylistSample(lifecycleOwner);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import android.os.Bundle;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
@@ -33,6 +35,10 @@ import androidx.media3.session.SessionToken;
|
|||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
import androidx.navigation.NavOptions;
|
import androidx.navigation.NavOptions;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
|
import androidx.transition.ChangeBounds;
|
||||||
|
import androidx.transition.Slide;
|
||||||
|
import androidx.transition.TransitionManager;
|
||||||
|
import androidx.transition.TransitionSet;
|
||||||
import androidx.viewpager2.widget.ViewPager2;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
import com.cappielloantonio.tempo.R;
|
import com.cappielloantonio.tempo.R;
|
||||||
@@ -56,7 +62,6 @@ import com.google.android.material.elevation.SurfaceColors;
|
|||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -314,7 +319,7 @@ public class PlayerControllerFragment extends Fragment {
|
|||||||
if (!samplingRate.trim().isEmpty()) items.add(samplingRate);
|
if (!samplingRate.trim().isEmpty()) items.add(samplingRate);
|
||||||
String mediaQuality = TextUtils.join(" • ", items);
|
String mediaQuality = TextUtils.join(" • ", items);
|
||||||
|
|
||||||
playerMediaBitrate.setVisibility(View.VISIBLE);
|
playerMediaBitrate.setVisibility(Preferences.getBitrateVisible() ? View.VISIBLE : View.GONE);
|
||||||
playerMediaBitrate.setText(isLocal ? mediaQuality : mediaQuality);
|
playerMediaBitrate.setText(isLocal ? mediaQuality : mediaQuality);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,7 +340,25 @@ public class PlayerControllerFragment extends Fragment {
|
|||||||
TrackInfoDialog dialog = new TrackInfoDialog(mediaMetadata);
|
TrackInfoDialog dialog = new TrackInfoDialog(mediaMetadata);
|
||||||
dialog.show(activity.getSupportFragmentManager(), null);
|
dialog.show(activity.getSupportFragmentManager(), null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
playerMediaExtension.setOnClickListener( v -> toggleBitrateVisibility() );
|
||||||
|
playerMediaBitrate.setOnClickListener(v -> toggleBitrateVisibility() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void toggleBitrateVisibility() {
|
||||||
|
ViewGroup parent = (ViewGroup) playerMediaBitrate.getParent();
|
||||||
|
|
||||||
|
TransitionSet transition = new TransitionSet()
|
||||||
|
.addTransition(new Slide(Gravity.START))
|
||||||
|
.addTransition(new ChangeBounds())
|
||||||
|
.setDuration(500)
|
||||||
|
.setInterpolator(new AccelerateDecelerateInterpolator());
|
||||||
|
TransitionManager.beginDelayedTransition(parent, transition);
|
||||||
|
|
||||||
|
playerMediaBitrate.setVisibility(Preferences.getBitrateVisible() ? View.GONE : View.VISIBLE);
|
||||||
|
Preferences.setBitrateVisible(!Preferences.getBitrateVisible());
|
||||||
|
}
|
||||||
|
|
||||||
private void updateAssetLinkChips(MediaMetadata mediaMetadata) {
|
private void updateAssetLinkChips(MediaMetadata mediaMetadata) {
|
||||||
if (assetLinkChipGroup == null) return;
|
if (assetLinkChipGroup == null) return;
|
||||||
String mediaType = mediaMetadata.extras != null ? mediaMetadata.extras.getString("type", Constants.MEDIA_TYPE_MUSIC) : Constants.MEDIA_TYPE_MUSIC;
|
String mediaType = mediaMetadata.extras != null ? mediaMetadata.extras.getString("type", Constants.MEDIA_TYPE_MUSIC) : Constants.MEDIA_TYPE_MUSIC;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ object Preferences {
|
|||||||
private const val IN_USE_SERVER_ADDRESS = "in_use_server_address"
|
private const val IN_USE_SERVER_ADDRESS = "in_use_server_address"
|
||||||
private const val NEXT_SERVER_SWITCH = "next_server_switch"
|
private const val NEXT_SERVER_SWITCH = "next_server_switch"
|
||||||
private const val PLAYBACK_SPEED = "playback_speed"
|
private const val PLAYBACK_SPEED = "playback_speed"
|
||||||
|
private const val BITRATE_VISIBLE = "bitrate_visible"
|
||||||
private const val SKIP_SILENCE = "skip_silence"
|
private const val SKIP_SILENCE = "skip_silence"
|
||||||
private const val SHUFFLE_MODE = "shuffle_mode"
|
private const val SHUFFLE_MODE = "shuffle_mode"
|
||||||
private const val REPEAT_MODE = "repeat_mode"
|
private const val REPEAT_MODE = "repeat_mode"
|
||||||
@@ -292,6 +293,16 @@ object Preferences {
|
|||||||
App.getInstance().preferences.edit().putFloat(PLAYBACK_SPEED, playbackSpeed).apply()
|
App.getInstance().preferences.edit().putFloat(PLAYBACK_SPEED, playbackSpeed).apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getBitrateVisible(): Boolean {
|
||||||
|
return App.getInstance().preferences.getBoolean(BITRATE_VISIBLE, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun setBitrateVisible(bitrateVisible: Boolean) {
|
||||||
|
App.getInstance().preferences.edit().putBoolean(BITRATE_VISIBLE, bitrateVisible).apply()
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isSkipSilenceMode(): Boolean {
|
fun isSkipSilenceMode(): Boolean {
|
||||||
return App.getInstance().preferences.getBoolean(SKIP_SILENCE, false)
|
return App.getInstance().preferences.getBoolean(SKIP_SILENCE, false)
|
||||||
|
|||||||
@@ -24,30 +24,42 @@
|
|||||||
app:layout_constraintStart_toEndOf="@+id/vertical_guideline"
|
app:layout_constraintStart_toEndOf="@+id/vertical_guideline"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/player_media_extension"
|
android:id="@+id/player_media_quality_sector_center"
|
||||||
style="@style/Widget.Material3.Chip.Suggestion"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:checked="true"
|
android:layout_marginVertical="8dp"
|
||||||
android:clickable="false"
|
|
||||||
android:text="Unknown"
|
|
||||||
app:chipStrokeWidth="0dp"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/player_media_bitrate"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"/>
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/player_media_bitrate"
|
android:id="@+id/player_media_bitrate"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
app:layout_constraintTop_toTopOf="@id/player_media_extension"
|
app:layout_constraintTop_toTopOf="@id/player_media_extension"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/player_media_extension"
|
app:layout_constraintBottom_toBottomOf="@id/player_media_extension"
|
||||||
app:layout_constraintStart_toEndOf="@id/player_media_extension"
|
app:layout_constraintStart_toEndOf="@id/player_media_extension"
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:id="@+id/player_media_extension"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clickable="true"
|
||||||
|
android:checked="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:text="Unknown"
|
||||||
|
app:chipStrokeWidth="0dp"
|
||||||
|
app:chipBackgroundColor="@color/material_dynamic_secondary40"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/player_media_bitrate"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="packed"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/player_info_track"
|
android:id="@+id/player_info_track"
|
||||||
@@ -58,8 +70,8 @@
|
|||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/player_media_extension"
|
app:layout_constraintTop_toTopOf="@id/player_media_quality_sector_center"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/player_media_extension"
|
app:layout_constraintBottom_toBottomOf="@id/player_media_quality_sector_center"
|
||||||
app:srcCompat="@drawable/ic_info_stream"
|
app:srcCompat="@drawable/ic_info_stream"
|
||||||
app:tint="?attr/colorOnPrimaryContainer" />
|
app:tint="?attr/colorOnPrimaryContainer" />
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,12 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipe_library_to_refresh"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
android:id="@+id/fragment_library_nested_scroll_view"
|
android:id="@+id/fragment_library_nested_scroll_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -77,21 +83,41 @@
|
|||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:paddingBottom="8dp">
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
<TextView
|
<!-- Refreshable area -->
|
||||||
|
<LinearLayout
|
||||||
android:id="@+id/album_catalogue_sample_text_view_refreshable"
|
android:id="@+id/album_catalogue_sample_text_view_refreshable"
|
||||||
style="@style/TitleLarge"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/TitleLarge"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:text="@string/library_title_album" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="28dp"
|
||||||
|
android:layout_height="28dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:alpha="0.4"
|
||||||
|
android:src="@drawable/ic_refresh"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1" />
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:text="@string/library_title_album" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/album_catalogue_text_view_clickable"
|
android:id="@+id/album_catalogue_text_view_clickable"
|
||||||
style="@style/TitleMedium"
|
style="@style/TitleMedium"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
android:paddingStart="8dp"
|
android:paddingStart="8dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:text="@string/library_title_album_see_all_button" />
|
android:text="@string/library_title_album_see_all_button" />
|
||||||
@@ -130,22 +156,41 @@
|
|||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:paddingBottom="8dp">
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
<TextView
|
<!-- Refreshable area -->
|
||||||
|
<LinearLayout
|
||||||
android:id="@+id/artist_catalogue_sample_text_view_refreshable"
|
android:id="@+id/artist_catalogue_sample_text_view_refreshable"
|
||||||
style="@style/TitleLarge"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="0dp"
|
android:layout_height="wrap_content" >
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:text="@string/library_title_artist" />
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/TitleLarge"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:text="@string/library_title_artist" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="28dp"
|
||||||
|
android:layout_height="28dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:alpha="0.4"
|
||||||
|
android:src="@drawable/ic_refresh"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/artist_catalogue_text_view_clickable"
|
android:id="@+id/artist_catalogue_text_view_clickable"
|
||||||
style="@style/TitleMedium"
|
style="@style/TitleMedium"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
android:paddingStart="8dp"
|
android:paddingStart="8dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:text="@string/library_title_artist_see_all_button" />
|
android:text="@string/library_title_artist_see_all_button" />
|
||||||
@@ -184,25 +229,45 @@
|
|||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:paddingBottom="8dp">
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
<TextView
|
<!-- Refreshable area -->
|
||||||
|
<LinearLayout
|
||||||
android:id="@+id/genre_catalogue_sample_text_view_refreshable"
|
android:id="@+id/genre_catalogue_sample_text_view_refreshable"
|
||||||
style="@style/TitleLarge"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="0dp"
|
android:layout_height="wrap_content" >
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:text="@string/library_title_genre" />
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/TitleLarge"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:text="@string/library_title_genre" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="28dp"
|
||||||
|
android:layout_height="28dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:alpha="0.4"
|
||||||
|
android:src="@drawable/ic_refresh"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/genre_catalogue_text_view_clickable"
|
android:id="@+id/genre_catalogue_text_view_clickable"
|
||||||
style="@style/TitleMedium"
|
style="@style/TitleMedium"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
android:paddingStart="8dp"
|
android:paddingStart="8dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:text="@string/library_title_genre_see_all_button" />
|
android:text="@string/library_title_genre_see_all_button" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
@@ -236,21 +301,41 @@
|
|||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:paddingBottom="8dp">
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
<TextView
|
<!-- Refreshable area -->
|
||||||
|
<LinearLayout
|
||||||
android:id="@+id/playlist_catalogue_sample_text_view_refreshable"
|
android:id="@+id/playlist_catalogue_sample_text_view_refreshable"
|
||||||
style="@style/TitleLarge"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/TitleLarge"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:text="@string/library_title_playlist" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="28dp"
|
||||||
|
android:layout_height="28dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:alpha="0.4"
|
||||||
|
android:src="@drawable/ic_refresh"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1" />
|
||||||
android:paddingStart="8dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:text="@string/library_title_playlist" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/playlist_catalogue_text_view_clickable"
|
android:id="@+id/playlist_catalogue_text_view_clickable"
|
||||||
style="@style/TitleMedium"
|
style="@style/TitleMedium"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
android:paddingStart="8dp"
|
android:paddingStart="8dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
android:text="@string/library_title_playlist_see_all_button" />
|
android:text="@string/library_title_playlist_see_all_button" />
|
||||||
@@ -270,4 +355,5 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
@@ -33,30 +33,42 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:tint="?attr/colorOnPrimaryContainer" />
|
app:tint="?attr/colorOnPrimaryContainer" />
|
||||||
|
|
||||||
<com.google.android.material.chip.Chip
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/player_media_extension"
|
android:id="@+id/player_media_quality_sector_center"
|
||||||
style="@style/Widget.Material3.Chip.Suggestion"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:checked="true"
|
android:layout_marginVertical="8dp"
|
||||||
android:clickable="false"
|
|
||||||
android:text="Unknown"
|
|
||||||
app:chipStrokeWidth="0dp"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/player_media_bitrate"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"/>
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/player_media_bitrate"
|
android:id="@+id/player_media_bitrate"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
app:layout_constraintTop_toTopOf="@id/player_media_extension"
|
app:layout_constraintTop_toTopOf="@id/player_media_extension"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/player_media_extension"
|
app:layout_constraintBottom_toBottomOf="@id/player_media_extension"
|
||||||
app:layout_constraintStart_toEndOf="@id/player_media_extension"
|
app:layout_constraintStart_toEndOf="@id/player_media_extension"
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
|
<com.google.android.material.chip.Chip
|
||||||
|
android:id="@+id/player_media_extension"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clickable="true"
|
||||||
|
android:checked="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:text="Unknown"
|
||||||
|
app:chipStrokeWidth="0dp"
|
||||||
|
app:chipBackgroundColor="@color/material_dynamic_secondary40"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/player_media_bitrate"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="packed"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/player_info_track"
|
android:id="@+id/player_info_track"
|
||||||
@@ -67,8 +79,8 @@
|
|||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/player_media_extension"
|
app:layout_constraintTop_toTopOf="@id/player_media_quality_sector_center"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/player_media_extension"
|
app:layout_constraintBottom_toBottomOf="@id/player_media_quality_sector_center"
|
||||||
app:srcCompat="@drawable/ic_info_stream"
|
app:srcCompat="@drawable/ic_info_stream"
|
||||||
app:tint="?attr/colorOnPrimaryContainer" />
|
app:tint="?attr/colorOnPrimaryContainer" />
|
||||||
|
|
||||||
|
|||||||
3
fastlane/metadata/android/en-US/changelogs/22.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/22.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
feat: advertise existing long press to refresh per section on library page
|
||||||
|
fix: playlist filter returns properly filtered list and reset correctly
|
||||||
|
feat: toggle player bitrate visibility on touch
|
||||||
Reference in New Issue
Block a user