mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 09:33:33 +00:00
commit
74cce9c867
43 changed files with 1166 additions and 142 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -14,3 +14,4 @@
|
|||
.cxx
|
||||
/.idea/
|
||||
.env
|
||||
.vscode/settings.json
|
||||
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
|
|
@ -192,6 +192,7 @@
|
|||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
|
|
|
|||
23
README.md
23
README.md
|
|
@ -7,12 +7,12 @@
|
|||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/CappielloAntonio/tempo/releases"><img src="https://i.ibb.co/q0mdc4Z/get-it-on-github.png" width="200"></a>
|
||||
<a href="https://github.com/eddyizm/tempo/releases"><img src="https://i.ibb.co/q0mdc4Z/get-it-on-github.png" width="200"></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<!-- <p align="center">
|
||||
<a href="https://f-droid.org/packages/com.cappielloantonio.notquitemy.tempo"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" width="200"></a>
|
||||
<a href="https://apt.izzysoft.de/fdroid/index/apk/com.cappielloantonio.tempo"><img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" width="200"></a>
|
||||
</p>
|
||||
</p> -->
|
||||
|
||||
**Tempo** is an open-source and lightweight music client for Subsonic, designed and built natively for Android. It provides a seamless and intuitive music streaming experience, allowing you to access and play your Subsonic music library directly from your Android device.
|
||||
|
||||
|
|
@ -22,6 +22,21 @@ Tempo does not rely on magic algorithms to decide what you should listen to. Ins
|
|||
|
||||
**Use the Github version of the app for full Android Auto and Chromecast support.**
|
||||
|
||||
## Fork
|
||||
|
||||
This fork is my attempt to keep development moving forward and merge in PR's that have been sitting for a while in the main repo. Thankful to @CappielloAntonio for the amazing app and hopefully we can continue to build on top of it. I will only be releasing on github and if I am not able to merge back to the main repo, I plan to rename the app to be able to publish it to fdroid and possibly google play? We will see.
|
||||
|
||||
v3.10.0 applies the following PR's (fix/feat/chore):
|
||||
fix: [379](https://github.com/CappielloAntonio/tempo/pull/379) -Fix: redirection to artist fragment on artist label click
|
||||
fix: [385](https://github.com/CappielloAntonio/tempo/pull/385) -Player queue lag, limits
|
||||
fix: [389](https://github.com/CappielloAntonio/tempo/pull/389) -Fix crash when sorting albums with a null artist
|
||||
feat: [371](https://github.com/CappielloAntonio/tempo/pull/371) -Display toast message after adding a song to a playlist
|
||||
feat: [367](https://github.com/CappielloAntonio/tempo/pull/367) -Album add to playlist context menu item
|
||||
chore: [374](https://github.com/CappielloAntonio/tempo/pull/374) -Spanish translation
|
||||
feat: [397](https://github.com/CappielloAntonio/tempo/pull/397) -Store and retrieve replay and shuffle states in preferences
|
||||
feat:[400](https://github.com/CappielloAntonio/tempo/pull/400) - enhance Android media player notification window
|
||||
chore: [378](https://github.com/CappielloAntonio/tempo/pull/378) Polish translation
|
||||
|
||||
## 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,7 +57,7 @@ Tempo does not rely on magic algorithms to decide what you should listen to. Ins
|
|||
<img src="mockup/feat/4_screenshot.png" width=200>
|
||||
<img src="mockup/feat/5_screenshot.png" width=200>
|
||||
<img src="mockup/feat/6_screenshot.png" width=200>
|
||||
<img src="mockup/feat/7_screenshot.png" width=200>
|
||||
<img src="mockup/feat/7_scregetRecentSearchSuggestionenshot.png" width=200>
|
||||
<img src="mockup/feat/8_screenshot.png" width=200>
|
||||
</p>
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ android {
|
|||
targetSdk 35
|
||||
|
||||
versionCode 26
|
||||
versionName '3.9.0'
|
||||
versionName '3.10.0-alpha.1'
|
||||
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
|
|
@ -107,4 +107,9 @@ dependencies {
|
|||
implementation 'com.squareup.retrofit2:retrofit:2.11.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.14'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.11.0'
|
||||
}
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(17)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@
|
|||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
package com.cappielloantonio.tempo.repository;
|
||||
|
||||
import static android.provider.Settings.System.getString;
|
||||
|
||||
import android.provider.Settings;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.cappielloantonio.tempo.App;
|
||||
import com.cappielloantonio.tempo.R;
|
||||
import com.cappielloantonio.tempo.database.AppDatabase;
|
||||
import com.cappielloantonio.tempo.database.dao.PlaylistDao;
|
||||
import com.cappielloantonio.tempo.subsonic.base.ApiResponse;
|
||||
|
|
@ -20,6 +26,7 @@ import retrofit2.Callback;
|
|||
import retrofit2.Response;
|
||||
|
||||
public class PlaylistRepository {
|
||||
@androidx.media3.common.util.UnstableApi
|
||||
private final PlaylistDao playlistDao = AppDatabase.getInstance().playlistDao();
|
||||
public MutableLiveData<List<Playlist>> getPlaylists(boolean random, int size) {
|
||||
MutableLiveData<List<Playlist>> listLivePlaylists = new MutableLiveData<>(new ArrayList<>());
|
||||
|
|
@ -80,12 +87,12 @@ public class PlaylistRepository {
|
|||
.enqueue(new Callback<ApiResponse>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
|
||||
|
||||
Toast.makeText(App.getContext(), App.getContext().getString(R.string.playlist_chooser_dialog_toast_add_success), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
|
||||
|
||||
Toast.makeText(App.getContext(), App.getContext().getString(R.string.playlist_chooser_dialog_toast_add_failure), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -157,17 +164,19 @@ public class PlaylistRepository {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
@androidx.media3.common.util.UnstableApi
|
||||
public LiveData<List<Playlist>> getPinnedPlaylists() {
|
||||
return playlistDao.getAll();
|
||||
}
|
||||
|
||||
@androidx.media3.common.util.UnstableApi
|
||||
public void insert(Playlist playlist) {
|
||||
InsertThreadSafe insert = new InsertThreadSafe(playlistDao, playlist);
|
||||
Thread thread = new Thread(insert);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
@androidx.media3.common.util.UnstableApi
|
||||
public void delete(Playlist playlist) {
|
||||
DeleteThreadSafe delete = new DeleteThreadSafe(playlistDao, playlist);
|
||||
Thread thread = new Thread(delete);
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ public class AlbumCatalogueAdapter extends RecyclerView.Adapter<AlbumCatalogueAd
|
|||
albums.sort(Comparator.comparing(AlbumID3::getName));
|
||||
break;
|
||||
case Constants.ALBUM_ORDER_BY_ARTIST:
|
||||
albums.sort(Comparator.comparing(AlbumID3::getArtist));
|
||||
albums.sort(Comparator.comparing(AlbumID3::getArtist, Comparator.nullsLast(Comparator.naturalOrder())));
|
||||
break;
|
||||
case Constants.ALBUM_ORDER_BY_YEAR:
|
||||
albums.sort(Comparator.comparing(AlbumID3::getYear));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.cappielloantonio.tempo.ui.adapter;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
|
@ -10,6 +11,7 @@ import androidx.appcompat.content.res.AppCompatResources;
|
|||
import androidx.media3.session.MediaBrowser;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.bumptech.glide.RequestBuilder;
|
||||
import com.cappielloantonio.tempo.R;
|
||||
import com.cappielloantonio.tempo.databinding.ItemPlayerQueueSongBinding;
|
||||
import com.cappielloantonio.tempo.glide.CustomGlideRequest;
|
||||
|
|
@ -46,7 +48,7 @@ public class PlayerSongQueueAdapter extends RecyclerView.Adapter<PlayerSongQueue
|
|||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
Child song = songs.get(position);
|
||||
Child song = songs.get(holder.getLayoutPosition());
|
||||
|
||||
holder.item.queueSongTitleTextView.setText(song.getTitle());
|
||||
holder.item.queueSongSubtitleTextView.setText(
|
||||
|
|
@ -58,15 +60,21 @@ public class PlayerSongQueueAdapter extends RecyclerView.Adapter<PlayerSongQueue
|
|||
)
|
||||
);
|
||||
|
||||
RequestBuilder<Drawable> thumbnail = CustomGlideRequest.Builder
|
||||
.from(holder.itemView.getContext(), song.getCoverArtId(), CustomGlideRequest.ResourceType.Song)
|
||||
.build()
|
||||
.sizeMultiplier(0.1f);
|
||||
|
||||
CustomGlideRequest.Builder
|
||||
.from(holder.itemView.getContext(), song.getCoverArtId(), CustomGlideRequest.ResourceType.Song)
|
||||
.build()
|
||||
.thumbnail(thumbnail)
|
||||
.into(holder.item.queueSongCoverImageView);
|
||||
|
||||
MediaManager.getCurrentIndex(mediaBrowserListenableFuture, new MediaIndexCallback() {
|
||||
@Override
|
||||
public void onRecovery(int index) {
|
||||
if (position < index) {
|
||||
if (holder.getLayoutPosition() < index) {
|
||||
holder.item.queueSongTitleTextView.setAlpha(0.2f);
|
||||
holder.item.queueSongSubtitleTextView.setAlpha(0.2f);
|
||||
holder.item.ratingIndicatorImageView.setAlpha(0.2f);
|
||||
|
|
|
|||
|
|
@ -57,14 +57,14 @@ public class PlaylistChooserDialog extends DialogFragment implements ClickCallba
|
|||
}
|
||||
|
||||
private void setSongInfo() {
|
||||
playlistChooserViewModel.setSongToAdd(requireArguments().getParcelable(Constants.TRACK_OBJECT));
|
||||
playlistChooserViewModel.setSongsToAdd(requireArguments().getParcelableArrayList(Constants.TRACKS_OBJECT));
|
||||
}
|
||||
|
||||
private void setButtonAction() {
|
||||
androidx.appcompat.app.AlertDialog alertDialog = (androidx.appcompat.app.AlertDialog) Objects.requireNonNull(getDialog());
|
||||
alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_NEUTRAL).setOnClickListener(v -> {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(Constants.TRACK_OBJECT, playlistChooserViewModel.getSongToAdd());
|
||||
bundle.putParcelableArrayList(Constants.TRACKS_OBJECT, playlistChooserViewModel.getSongsToAdd());
|
||||
|
||||
PlaylistEditorDialog dialog = new PlaylistEditorDialog(null);
|
||||
dialog.setArguments(bundle);
|
||||
|
|
@ -98,7 +98,7 @@ public class PlaylistChooserDialog extends DialogFragment implements ClickCallba
|
|||
@Override
|
||||
public void onPlaylistClick(Bundle bundle) {
|
||||
Playlist playlist = bundle.getParcelable(Constants.PLAYLIST_OBJECT);
|
||||
playlistChooserViewModel.addSongToPlaylist(playlist.getId());
|
||||
playlistChooserViewModel.addSongsToPlaylist(playlist.getId());
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,11 +74,11 @@ public class PlaylistEditorDialog extends DialogFragment {
|
|||
}
|
||||
|
||||
private void setParameterInfo() {
|
||||
if (requireArguments().getParcelable(Constants.TRACK_OBJECT) != null) {
|
||||
playlistEditorViewModel.setSongToAdd(requireArguments().getParcelable(Constants.TRACK_OBJECT));
|
||||
if (requireArguments().getParcelableArrayList(Constants.TRACKS_OBJECT) != null) {
|
||||
playlistEditorViewModel.setSongsToAdd(requireArguments().getParcelableArrayList(Constants.TRACKS_OBJECT));
|
||||
playlistEditorViewModel.setPlaylistToEdit(null);
|
||||
} else if (requireArguments().getParcelable(Constants.PLAYLIST_OBJECT) != null) {
|
||||
playlistEditorViewModel.setSongToAdd(null);
|
||||
playlistEditorViewModel.setSongsToAdd(null);
|
||||
playlistEditorViewModel.setPlaylistToEdit(requireArguments().getParcelable(Constants.PLAYLIST_OBJECT));
|
||||
|
||||
if (playlistEditorViewModel.getPlaylistToEdit() != null) {
|
||||
|
|
@ -92,7 +92,7 @@ public class PlaylistEditorDialog extends DialogFragment {
|
|||
|
||||
alertDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
|
||||
if (validateInput()) {
|
||||
if (playlistEditorViewModel.getSongToAdd() != null) {
|
||||
if (playlistEditorViewModel.getSongsToAdd() != null) {
|
||||
playlistEditorViewModel.createPlaylist(playlistName);
|
||||
} else if (playlistEditorViewModel.getPlaylistToEdit() != null) {
|
||||
playlistEditorViewModel.updatePlaylist(playlistName);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ 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.util.Constants;
|
||||
import com.cappielloantonio.tempo.util.DownloadUtil;
|
||||
import com.cappielloantonio.tempo.util.MappingUtil;
|
||||
|
|
@ -38,6 +39,7 @@ import com.cappielloantonio.tempo.util.MusicUtil;
|
|||
import com.cappielloantonio.tempo.viewmodel.AlbumPageViewModel;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -108,6 +110,17 @@ public class AlbumPageFragment extends Fragment implements ClickCallback {
|
|||
});
|
||||
return true;
|
||||
}
|
||||
if (item.getItemId() == R.id.action_add_to_playlist) {
|
||||
albumPageViewModel.getAlbumSongLiveList().observe(getViewLifecycleOwner(), songs -> {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelableArrayList(Constants.TRACKS_OBJECT, new ArrayList<>(songs));
|
||||
|
||||
PlaylistChooserDialog dialog = new PlaylistChooserDialog();
|
||||
dialog.setArguments(bundle);
|
||||
dialog.show(requireActivity().getSupportFragmentManager(), null);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,9 @@ public class PlayerBottomSheetFragment extends Fragment {
|
|||
try {
|
||||
MediaBrowser mediaBrowser = mediaBrowserListenableFuture.get();
|
||||
|
||||
mediaBrowser.setShuffleModeEnabled(Preferences.isShuffleModeEnabled());
|
||||
mediaBrowser.setRepeatMode(Preferences.getRepeatMode());
|
||||
|
||||
setMediaControllerListener(mediaBrowser);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
@ -150,6 +153,16 @@ public class PlayerBottomSheetFragment extends Fragment {
|
|||
public void onEvents(Player player, Player.Events events) {
|
||||
setHeaderNextButtonState(mediaBrowser.hasNextMediaItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
|
||||
Preferences.setShuffleModeEnabled(shuffleModeEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged(int repeatMode) {
|
||||
Preferences.setRepeatMode(repeatMode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ public class PlayerControllerFragment extends Fragment {
|
|||
MediaBrowser mediaBrowser = mediaBrowserListenableFuture.get();
|
||||
|
||||
bind.nowPlayingMediaControllerView.setPlayer(mediaBrowser);
|
||||
mediaBrowser.setShuffleModeEnabled(Preferences.isShuffleModeEnabled());
|
||||
mediaBrowser.setRepeatMode(Preferences.getRepeatMode());
|
||||
|
||||
setMediaControllerListener(mediaBrowser);
|
||||
} catch (Exception e) {
|
||||
|
|
@ -160,6 +162,16 @@ public class PlayerControllerFragment extends Fragment {
|
|||
setMetadata(mediaMetadata);
|
||||
setMediaInfo(mediaMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
|
||||
Preferences.setShuffleModeEnabled(shuffleModeEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged(int repeatMode) {
|
||||
Preferences.setRepeatMode(repeatMode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,13 +193,13 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
|
|||
playlistPageViewModel.getPlaylistSongLiveList().observe(getViewLifecycleOwner(), songs -> {
|
||||
if (bind != null) {
|
||||
bind.playlistPagePlayButton.setOnClickListener(v -> {
|
||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs.subList(0, Math.min(100, songs.size())), 0);
|
||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
||||
activity.setBottomSheetInPeek(true);
|
||||
});
|
||||
|
||||
bind.playlistPageShuffleButton.setOnClickListener(v -> {
|
||||
Collections.shuffle(songs);
|
||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs.subList(0, Math.min(100, songs.size())), 0);
|
||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
||||
activity.setBottomSheetInPeek(true);
|
||||
});
|
||||
}
|
||||
|
|
@ -270,4 +270,4 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
|
|||
public void onMediaLongClick(Bundle bundle) {
|
||||
Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import com.cappielloantonio.tempo.service.MediaService;
|
|||
import com.cappielloantonio.tempo.subsonic.models.AlbumID3;
|
||||
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||||
import com.cappielloantonio.tempo.ui.activity.MainActivity;
|
||||
import com.cappielloantonio.tempo.ui.dialog.PlaylistChooserDialog;
|
||||
import com.cappielloantonio.tempo.util.Constants;
|
||||
import com.cappielloantonio.tempo.util.DownloadUtil;
|
||||
import com.cappielloantonio.tempo.util.MappingUtil;
|
||||
|
|
@ -167,6 +168,20 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements
|
|||
});
|
||||
});
|
||||
|
||||
TextView addToPlaylist = view.findViewById(R.id.add_to_playlist_text_view);
|
||||
addToPlaylist.setOnClickListener(v -> {
|
||||
albumBottomSheetViewModel.getAlbumTracks().observe(getViewLifecycleOwner(), songs -> {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelableArrayList(Constants.TRACKS_OBJECT, new ArrayList<>(songs));
|
||||
|
||||
PlaylistChooserDialog dialog = new PlaylistChooserDialog();
|
||||
dialog.setArguments(bundle);
|
||||
dialog.show(requireActivity().getSupportFragmentManager(), null);
|
||||
|
||||
dismissBottomSheet();
|
||||
});
|
||||
});
|
||||
|
||||
TextView removeAll = view.findViewById(R.id.remove_all_text_view);
|
||||
albumBottomSheetViewModel.getAlbumTracks().observe(getViewLifecycleOwner(), songs -> {
|
||||
List<MediaItem> mediaItems = MappingUtil.mapDownloads(songs);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ import com.cappielloantonio.tempo.viewmodel.SongBottomSheetViewModel;
|
|||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
@UnstableApi
|
||||
public class SongBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener {
|
||||
private HomeViewModel homeViewModel;
|
||||
|
|
@ -177,7 +180,7 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
|
|||
TextView addToPlaylist = view.findViewById(R.id.add_to_playlist_text_view);
|
||||
addToPlaylist.setOnClickListener(v -> {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(Constants.TRACK_OBJECT, song);
|
||||
bundle.putParcelableArrayList(Constants.TRACKS_OBJECT, new ArrayList<>(Collections.singletonList(song)));
|
||||
|
||||
PlaylistChooserDialog dialog = new PlaylistChooserDialog();
|
||||
dialog.setArguments(bundle);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.cappielloantonio.tempo.util
|
||||
|
||||
import android.util.Log
|
||||
import androidx.media3.common.Player
|
||||
import com.cappielloantonio.tempo.App
|
||||
import com.cappielloantonio.tempo.model.HomeSector
|
||||
import com.cappielloantonio.tempo.subsonic.models.OpenSubsonicExtension
|
||||
|
|
@ -24,6 +25,8 @@ object Preferences {
|
|||
private const val NEXT_SERVER_SWITCH = "next_server_switch"
|
||||
private const val PLAYBACK_SPEED = "playback_speed"
|
||||
private const val SKIP_SILENCE = "skip_silence"
|
||||
private const val SHUFFLE_MODE = "shuffle_mode"
|
||||
private const val REPEAT_MODE = "repeat_mode"
|
||||
private const val IMAGE_CACHE_SIZE = "image_cache_size"
|
||||
private const val STREAMING_CACHE_SIZE = "streaming_cache_size"
|
||||
private const val IMAGE_SIZE = "image_size"
|
||||
|
|
@ -226,6 +229,26 @@ object Preferences {
|
|||
App.getInstance().preferences.edit().putBoolean(SKIP_SILENCE, isSkipSilenceMode).apply()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isShuffleModeEnabled(): Boolean {
|
||||
return App.getInstance().preferences.getBoolean(SHUFFLE_MODE, false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setShuffleModeEnabled(shuffleModeEnabled: Boolean) {
|
||||
App.getInstance().preferences.edit().putBoolean(SHUFFLE_MODE, shuffleModeEnabled).apply()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getRepeatMode(): Int {
|
||||
return App.getInstance().preferences.getInt(REPEAT_MODE, Player.REPEAT_MODE_OFF)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setRepeatMode(repeatMode: Int) {
|
||||
App.getInstance().preferences.edit().putInt(REPEAT_MODE, repeatMode).apply()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getImageCacheSize(): Int {
|
||||
return App.getInstance().preferences.getString(IMAGE_CACHE_SIZE, "500")!!.toInt()
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public class AlbumPageViewModel extends AndroidViewModel {
|
|||
private final AlbumRepository albumRepository;
|
||||
private final ArtistRepository artistRepository;
|
||||
private String albumId;
|
||||
private String artistId;
|
||||
private final MutableLiveData<AlbumID3> album = new MutableLiveData<>(null);
|
||||
|
||||
public AlbumPageViewModel(@NonNull Application application) {
|
||||
|
|
@ -41,6 +42,7 @@ public class AlbumPageViewModel extends AndroidViewModel {
|
|||
public void setAlbum(LifecycleOwner owner, AlbumID3 album) {
|
||||
this.albumId = album.getId();
|
||||
this.album.postValue(album);
|
||||
this.artistId = album.getArtistId();
|
||||
|
||||
albumRepository.getAlbum(album.getId()).observe(owner, albums -> {
|
||||
if (albums != null) this.album.setValue(albums);
|
||||
|
|
@ -48,7 +50,7 @@ public class AlbumPageViewModel extends AndroidViewModel {
|
|||
}
|
||||
|
||||
public LiveData<ArtistID3> getArtist() {
|
||||
return artistRepository.getArtistInfo(albumId);
|
||||
return artistRepository.getArtistInfo(artistId);
|
||||
}
|
||||
|
||||
public LiveData<AlbumInfo> getAlbumInfo() {
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public class HomeViewModel extends AndroidViewModel {
|
|||
}
|
||||
|
||||
public LiveData<List<Child>> getRandomShuffleSample() {
|
||||
return songRepository.getRandomSample(100, null, null);
|
||||
return songRepository.getRandomSample(1000, null, null);
|
||||
}
|
||||
|
||||
public LiveData<List<Chronology>> getChronologySample(LifecycleOwner owner) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.lifecycle.MutableLiveData;
|
|||
import com.cappielloantonio.tempo.repository.PlaylistRepository;
|
||||
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||||
import com.cappielloantonio.tempo.subsonic.models.Playlist;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
|
@ -20,7 +21,7 @@ public class PlaylistChooserViewModel extends AndroidViewModel {
|
|||
private final PlaylistRepository playlistRepository;
|
||||
|
||||
private final MutableLiveData<List<Playlist>> playlists = new MutableLiveData<>(null);
|
||||
private Child toAdd;
|
||||
private ArrayList<Child> toAdd;
|
||||
|
||||
public PlaylistChooserViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
|
|
@ -33,15 +34,15 @@ public class PlaylistChooserViewModel extends AndroidViewModel {
|
|||
return playlists;
|
||||
}
|
||||
|
||||
public void addSongToPlaylist(String playlistId) {
|
||||
playlistRepository.addSongToPlaylist(playlistId, new ArrayList(Collections.singletonList(toAdd.getId())));
|
||||
public void addSongsToPlaylist(String playlistId) {
|
||||
playlistRepository.addSongToPlaylist(playlistId, new ArrayList<>(Lists.transform(toAdd, Child::getId)));
|
||||
}
|
||||
|
||||
public void setSongToAdd(Child song) {
|
||||
toAdd = song;
|
||||
public void setSongsToAdd(ArrayList<Child> songs) {
|
||||
toAdd = songs;
|
||||
}
|
||||
|
||||
public Child getSongToAdd() {
|
||||
public ArrayList<Child> getSongsToAdd() {
|
||||
return toAdd;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.cappielloantonio.tempo.repository.SharingRepository;
|
|||
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||||
import com.cappielloantonio.tempo.subsonic.models.Playlist;
|
||||
import com.cappielloantonio.tempo.subsonic.models.Share;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
|
@ -24,7 +25,7 @@ public class PlaylistEditorViewModel extends AndroidViewModel {
|
|||
private final PlaylistRepository playlistRepository;
|
||||
private final SharingRepository sharingRepository;
|
||||
|
||||
private Child toAdd;
|
||||
private ArrayList<Child> toAdd;
|
||||
private Playlist toEdit;
|
||||
|
||||
private MutableLiveData<List<Child>> songLiveList = new MutableLiveData<>();
|
||||
|
|
@ -37,7 +38,7 @@ public class PlaylistEditorViewModel extends AndroidViewModel {
|
|||
}
|
||||
|
||||
public void createPlaylist(String name) {
|
||||
playlistRepository.createPlaylist(null, name, new ArrayList(Collections.singletonList(toAdd.getId())));
|
||||
playlistRepository.createPlaylist(null, name, new ArrayList(Lists.transform(toAdd, Child::getId)));
|
||||
}
|
||||
|
||||
public void updatePlaylist(String name) {
|
||||
|
|
@ -48,12 +49,12 @@ public class PlaylistEditorViewModel extends AndroidViewModel {
|
|||
if (toEdit != null) playlistRepository.deletePlaylist(toEdit.getId());
|
||||
}
|
||||
|
||||
public Child getSongToAdd() {
|
||||
return toAdd;
|
||||
public void setSongsToAdd(ArrayList<Child> songs) {
|
||||
toAdd = songs;
|
||||
}
|
||||
|
||||
public void setSongToAdd(Child song) {
|
||||
this.toAdd = song;
|
||||
public ArrayList<Child> getSongsToAdd() {
|
||||
return toAdd;
|
||||
}
|
||||
|
||||
public Playlist getPlaylistToEdit() {
|
||||
|
|
|
|||
|
|
@ -146,6 +146,19 @@
|
|||
android:paddingBottom="12dp"
|
||||
android:text="@string/album_bottom_sheet_download_all" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/add_to_playlist_text_view"
|
||||
style="@style/LabelMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:text="@string/album_bottom_sheet_add_to_playlist" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove_all_text_view"
|
||||
style="@style/LabelMedium"
|
||||
|
|
|
|||
|
|
@ -4,39 +4,27 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_clean_queue_button"
|
||||
style="@style/TitleMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/player_queue_clean_all_button" />
|
||||
|
||||
<com.cappielloantonio.tempo.helper.recyclerview.NestedScrollableHost
|
||||
android:id="@+id/player_queue_nested_scrollable_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/player_queue_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="40dp"
|
||||
android:paddingTop="8dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="@dimen/global_padding_bottom">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/player_queue_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_clean_queue_button"
|
||||
style="@style/TitleMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="@string/player_queue_clean_all_button"/>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</com.cappielloantonio.tempo.helper.recyclerview.NestedScrollableHost>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
|
|
|
|||
|
|
@ -6,4 +6,9 @@
|
|||
android:icon="@drawable/ic_file_download"
|
||||
android:title="@string/menu_download_all_button"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_add_to_playlist"
|
||||
android:icon="@drawable/ic_add"
|
||||
android:title="@string/menu_add_to_playlist_button"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
<string name="activity_battery_optimizations_summary">Bitte deaktiviere die Batterieoptimierung, damit die Medienwiedergabe bei ausgeschaltetem Bildschirm richtig funktioniert.</string>
|
||||
<string name="activity_battery_optimizations_title">Batterie Optimierung</string>
|
||||
<string name="activity_info_offline_mode">Offlinebetrieb</string>
|
||||
<string name="album_bottom_sheet_add_to_playlist">Zu Playliste hinzufügen</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">Zur Warteschlange hinzufügen</string>
|
||||
<string name="album_bottom_sheet_download_all">Alle herunterladen</string>
|
||||
<string name="album_bottom_sheet_go_to_artist">Gehe zu Künstler</string>
|
||||
|
|
@ -154,6 +155,7 @@
|
|||
<string name="login_title_expanded">Subsonic Server</string>
|
||||
<string name="media_route_menu_title">Cast</string>
|
||||
<string name="menu_add_button">Hinzufügen</string>
|
||||
<string name="menu_add_to_playlist_button">Zu Playliste hinzufügen</string>
|
||||
<string name="menu_download_all_button">Alle Herunterladen</string>
|
||||
<string name="menu_download_label">Downloads</string>
|
||||
<string name="menu_filter_all">Alle</string>
|
||||
|
|
@ -186,6 +188,8 @@
|
|||
<string name="playlist_chooser_dialog_negative_button">Abbrechen</string>
|
||||
<string name="playlist_chooser_dialog_neutral_button">Erstellen</string>
|
||||
<string name="playlist_chooser_dialog_title">Zu einer Playliste hinzufügen</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_success">Lied zu Playlist hinzugefügt</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_failure">Titel kann nicht zur Playlist hinzugefügt werden</string>
|
||||
<string name="playlist_counted_tracks">%1$d Tracks • %2$s</string>
|
||||
<string name="playlist_duration">Länge • %1$s</string>
|
||||
<string name="playlist_editor_dialog_action_delete_toast">Zum Löschen lange drücken</string>
|
||||
|
|
@ -277,7 +281,7 @@
|
|||
<string name="settings_download_storage_title">Download storage</string>
|
||||
<string name="settings_equalizer_summary">Audio Einstellungen anpassen</string>
|
||||
<string name="settings_equalizer_title">Equalizer</string>
|
||||
<string name="settings_github_link">https://github.com/CappielloAntonio/tempo</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">Verfolge die Entwicklung</string>
|
||||
<string name="settings_github_title">Github</string>
|
||||
<string name="settings_image_size">Bilder Auflösung anpassen</string>
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@
|
|||
<string name="settings_image_size">Resolución de la imagen</string>
|
||||
<string name="settings_language">Idioma</string>
|
||||
<string name="settings_logout_title">Cerrar sesión</string>
|
||||
<string name="settings_github_link">https://github.com/CappielloAntonio/tempo</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">Siga el desarrollo</string>
|
||||
<string name="settings_github_title">Github</string>
|
||||
<string name="menu_group_by_genre">Género</string>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<string name="activity_battery_optimizations_summary">Veuillez désactiver les optimisations de la batterie pour permettre la lecture des médias lorsque l\'écran est éteint.</string>
|
||||
<string name="activity_battery_optimizations_title">Optimisations de la batterie</string>
|
||||
<string name="activity_info_offline_mode">Mode hors-ligne</string>
|
||||
<string name="album_bottom_sheet_add_to_playlist">Ajouter à une playlist</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">Ajouter à la file d\'attente</string>
|
||||
<string name="album_bottom_sheet_download_all">Télécharger tout</string>
|
||||
<string name="album_bottom_sheet_go_to_artist">Aller à l\'artiste</string>
|
||||
|
|
@ -133,6 +134,7 @@
|
|||
<string name="login_title_expanded">Serveurs Subsonic</string>
|
||||
<string name="media_route_menu_title">Cast</string>
|
||||
<string name="menu_add_button">Ajouter</string>
|
||||
<string name="menu_add_to_playlist_button">Ajouter à une playlist</string>
|
||||
<string name="menu_download_all_button">Télécharger tout</string>
|
||||
<string name="menu_download_label">Téléchargé</string>
|
||||
<string name="menu_filter_all">Tout</string>
|
||||
|
|
@ -244,7 +246,7 @@
|
|||
<string name="settings_download_storage_title">Stockage des téléchargements</string>
|
||||
<string name="settings_equalizer_summary">Ajuster les paramètres audios</string>
|
||||
<string name="settings_equalizer_title">Égaliseur</string>
|
||||
<string name="settings_github_link">https://github.com/CappielloAntonio/tempo</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">Suivre le développement</string>
|
||||
<string name="settings_github_title">Github</string>
|
||||
<string name="settings_image_size">Définir la résolution des images</string>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
<string name="activity_battery_optimizations_summary">Per favore, disabilita le ottimizzazioni della batteria per la riproduzione multimediale quando lo schermo è spento.</string>
|
||||
<string name="activity_battery_optimizations_title">Ottimizzazioni della Batteria</string>
|
||||
<string name="activity_info_offline_mode">Modalità offline</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">Aggiungi alla coda</string>
|
||||
<string name="album_bottom_sheet_add_to_playlist">Aggiungi alla playlist</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">Aggiungi alla coda</string>
|
||||
<string name="album_bottom_sheet_download_all">Scarica tutto</string>
|
||||
<string name="album_bottom_sheet_go_to_artist">Vai all\'artista</string>
|
||||
<string name="album_bottom_sheet_instant_mix">Mix istantaneo</string>
|
||||
|
|
@ -156,7 +157,8 @@
|
|||
<string name="login_title_expanded">Server Subsonic</string>
|
||||
<string name="media_route_menu_title">Trasmetti</string>
|
||||
<string name="menu_add_button">Aggiungi</string>
|
||||
<string name="menu_download_all_button">Scarica tutto</string>
|
||||
<string name="menu_add_to_playlist_button">Aggiungi alla playlist</string>
|
||||
<string name="menu_download_all_button">Scarica tutto</string>
|
||||
<string name="menu_download_label">Scarica</string>
|
||||
<string name="menu_filter_all">Tutti</string>
|
||||
<string name="menu_filter_download">Scaricati</string>
|
||||
|
|
@ -188,6 +190,8 @@
|
|||
<string name="playlist_chooser_dialog_negative_button">Annulla</string>
|
||||
<string name="playlist_chooser_dialog_neutral_button">Crea</string>
|
||||
<string name="playlist_chooser_dialog_title">Aggiungi a una playlist</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_success">Aggiunta di un brano alla playlist</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_failure">Impossibile aggiungere un brano alla playlist</string>
|
||||
<string name="playlist_counted_tracks">%1$d brani • %2$s</string>
|
||||
<string name="playlist_duration">Durata • %1$s</string>
|
||||
<string name="playlist_editor_dialog_action_delete_toast">Premi a lungo per eliminare</string>
|
||||
|
|
@ -279,7 +283,7 @@
|
|||
<string name="settings_download_storage_title">Archivio download</string>
|
||||
<string name="settings_equalizer_summary">Regola le impostazioni audio</string>
|
||||
<string name="settings_equalizer_title">Equalizzatore</string>
|
||||
<string name="settings_github_link">https://github.com/CappielloAntonio/tempo</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">Segui lo sviluppo</string>
|
||||
<string name="settings_github_title">Github</string>
|
||||
<string name="settings_image_size">Imposta risoluzione delle immagini</string>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<string name="activity_battery_optimizations_summary">화면이 꺼진 상태에서 음악 재생을 하기 위해서는 배터리 최적화를 비활성화 해주세요.</string>
|
||||
<string name="activity_battery_optimizations_title">배터리 최적화</string>
|
||||
<string name="activity_info_offline_mode">오프라인 모드</string>
|
||||
<string name="album_bottom_sheet_add_to_playlist">플레이리스트에 추가</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">재생목록에 추가</string>
|
||||
<string name="album_bottom_sheet_download_all">모두 다운로드</string>
|
||||
<string name="album_bottom_sheet_go_to_artist">아티스트로 이동</string>
|
||||
|
|
@ -135,6 +136,7 @@
|
|||
<string name="login_title_expanded">Subsonic 서버</string>
|
||||
<string name="media_route_menu_title">Cast</string>
|
||||
<string name="menu_add_button">추가</string>
|
||||
<string name="menu_add_to_playlist_button">플레이리스트에 추가</string>
|
||||
<string name="menu_download_all_button">모두 다운로드</string>
|
||||
<string name="menu_download_label">다운로드</string>
|
||||
<string name="menu_filter_all">모두</string>
|
||||
|
|
@ -161,6 +163,8 @@
|
|||
<string name="playlist_chooser_dialog_negative_button">취소</string>
|
||||
<string name="playlist_chooser_dialog_neutral_button">생성</string>
|
||||
<string name="playlist_chooser_dialog_title">플레이리스트 추가</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_success">재생 목록에 노래 추가</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_failure">재생 목록에 노래를 추가하지 못했습니다.</string>
|
||||
<string name="playlist_counted_tracks">%1$d 트랙 • %2$s</string>
|
||||
<string name="playlist_duration">재생시간 • %1$s</string>
|
||||
<string name="playlist_editor_dialog_hint_name">플레이리스트 이름</string>
|
||||
|
|
@ -246,7 +250,7 @@
|
|||
<string name="settings_download_storage_title">스토리지 다운로드</string>
|
||||
<string name="settings_equalizer_summary">오디오 설정 적용</string>
|
||||
<string name="settings_equalizer_title">이퀄라이저</string>
|
||||
<string name="settings_github_link">https://github.com/CappielloAntonio/tempo</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">Follow the development</string>
|
||||
<string name="settings_github_title">Github</string>
|
||||
<string name="settings_image_size">이미지 해상도 설정</string>
|
||||
|
|
|
|||
257
app/src/main/res/values-pl/arrays.xml
Normal file
257
app/src/main/res/values-pl/arrays.xml
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
<resources>
|
||||
<string-array name="theme_list_titles">
|
||||
<item>Jasny</item>
|
||||
<item>Ciemny</item>
|
||||
<item>Domyślny systemu</item>
|
||||
</string-array>
|
||||
<string-array name="theme_list_values">
|
||||
<item>jasny</item>
|
||||
<item>ciemny</item>
|
||||
<item>domyślny</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_cache_size_titles">
|
||||
<item>Duży</item>
|
||||
<item>Średni</item>
|
||||
<item>Mały</item>
|
||||
</string-array>
|
||||
<string-array name="pref_cache_size_values">
|
||||
<item>500</item>
|
||||
<item>250</item>
|
||||
<item>125</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_image_size_titles">
|
||||
<item>Duża</item>
|
||||
<item>Średnia</item>
|
||||
<item>Mała</item>
|
||||
</string-array>
|
||||
<string-array name="pref_image_size_values">
|
||||
<item>-1</item>
|
||||
<item>500</item>
|
||||
<item>300</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="streaming_cache_size_titles">
|
||||
<item>Wyłączone</item>
|
||||
<item>128 MiB</item>
|
||||
<item>256 MiB</item>
|
||||
<item>512 MiB</item>
|
||||
<item>1024 MiB</item>
|
||||
</string-array>
|
||||
<string-array name="streaming_cache_size_values">
|
||||
<item>0</item>
|
||||
<item>128</item>
|
||||
<item>256</item>
|
||||
<item>512</item>
|
||||
<item>1024</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="max_bitrate_wifi_list_titles">
|
||||
<item>Oryginalny</item>
|
||||
<item>32 kbps</item>
|
||||
<item>48 kbps</item>
|
||||
<item>64 kbps</item>
|
||||
<item>80 kbps</item>
|
||||
<item>96 kbps</item>
|
||||
<item>112 kbps</item>
|
||||
<item>128 kbps</item>
|
||||
<item>160 kbps</item>
|
||||
<item>192 kbps</item>
|
||||
<item>256 kbps</item>
|
||||
<item>320 kbps</item>
|
||||
</string-array>
|
||||
<string-array name="max_bitrate_wifi_list_values">
|
||||
<item>0</item>
|
||||
<item>32</item>
|
||||
<item>48</item>
|
||||
<item>64</item>
|
||||
<item>80</item>
|
||||
<item>96</item>
|
||||
<item>112</item>
|
||||
<item>128</item>
|
||||
<item>160</item>
|
||||
<item>192</item>
|
||||
<item>256</item>
|
||||
<item>320</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="max_bitrate_mobile_list_titles">
|
||||
<item>Oryginalny</item>
|
||||
<item>32 kbps</item>
|
||||
<item>48 kbps</item>
|
||||
<item>64 kbps</item>
|
||||
<item>80 kbps</item>
|
||||
<item>96 kbps</item>
|
||||
<item>112 kbps</item>
|
||||
<item>128 kbps</item>
|
||||
<item>160 kbps</item>
|
||||
<item>192 kbps</item>
|
||||
<item>256 kbps</item>
|
||||
<item>320 kbps</item>
|
||||
</string-array>
|
||||
<string-array name="max_bitrate_mobile_list_values">
|
||||
<item>0</item>
|
||||
<item>32</item>
|
||||
<item>48</item>
|
||||
<item>64</item>
|
||||
<item>80</item>
|
||||
<item>96</item>
|
||||
<item>112</item>
|
||||
<item>128</item>
|
||||
<item>160</item>
|
||||
<item>192</item>
|
||||
<item>256</item>
|
||||
<item>320</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="max_bitrate_download_list_titles">
|
||||
<item>Oryginalny</item>
|
||||
<item>32 kbps</item>
|
||||
<item>48 kbps</item>
|
||||
<item>64 kbps</item>
|
||||
<item>80 kbps</item>
|
||||
<item>96 kbps</item>
|
||||
<item>112 kbps</item>
|
||||
<item>128 kbps</item>
|
||||
<item>160 kbps</item>
|
||||
<item>192 kbps</item>
|
||||
<item>256 kbps</item>
|
||||
<item>320 kbps</item>
|
||||
</string-array>
|
||||
<string-array name="max_bitrate_download_list_values">
|
||||
<item>0</item>
|
||||
<item>32</item>
|
||||
<item>48</item>
|
||||
<item>64</item>
|
||||
<item>80</item>
|
||||
<item>96</item>
|
||||
<item>112</item>
|
||||
<item>128</item>
|
||||
<item>160</item>
|
||||
<item>192</item>
|
||||
<item>256</item>
|
||||
<item>320</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="audio_transcode_format_wifi_list_titles">
|
||||
<item>Odtwarzanie bezpośrednie</item>
|
||||
<item>Opus</item>
|
||||
<item>AAC</item>
|
||||
<item>Mp3</item>
|
||||
<item>Flac</item>
|
||||
</string-array>
|
||||
<string-array name="audio_transcode_format_wifi_list_values">
|
||||
<item>raw</item>
|
||||
<item>opus</item>
|
||||
<item>aac</item>
|
||||
<item>mp3</item>
|
||||
<item>flac</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="audio_transcode_format_mobile_list_titles">
|
||||
<item>Odtwarzanie bezpośrednie</item>
|
||||
<item>Opus</item>
|
||||
<item>AAC</item>
|
||||
<item>Mp3</item>
|
||||
<item>Flac</item>
|
||||
</string-array>
|
||||
<string-array name="audio_transcode_format_mobile_list_values">
|
||||
<item>raw</item>
|
||||
<item>opus</item>
|
||||
<item>aac</item>
|
||||
<item>mp3</item>
|
||||
<item>flac</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="audio_transcode_format_download_list_titles">
|
||||
<item>Pobieranie bezpośrednie</item>
|
||||
<item>Opus</item>
|
||||
<item>AAC</item>
|
||||
<item>Mp3</item>
|
||||
<item>Flac</item>
|
||||
</string-array>
|
||||
<string-array name="audio_transcode_format_download_list_values">
|
||||
<item>raw</item>
|
||||
<item>opus</item>
|
||||
<item>aac</item>
|
||||
<item>mp3</item>
|
||||
<item>flac</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="queue_syncing_countdown_titles">
|
||||
<item>Dziesięć sekund</item>
|
||||
<item>Pięć sekund</item>
|
||||
<item>Dwie sekundy</item>
|
||||
</string-array>
|
||||
<string-array name="queue_syncing_countdown_values">
|
||||
<item>10</item>
|
||||
<item>5</item>
|
||||
<item>2</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="rounded_corner_size_titles">
|
||||
<item>Duży</item>
|
||||
<item>Średni</item>
|
||||
<item>Mały</item>
|
||||
</string-array>
|
||||
<string-array name="rounded_corner_size_values">
|
||||
<item>18</item>
|
||||
<item>12</item>
|
||||
<item>6</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="replay_gain_titles">
|
||||
<item>Wyłączony</item>
|
||||
<item>Utwór</item>
|
||||
<item>Album</item>
|
||||
<item>Auto</item>
|
||||
</string-array>
|
||||
<string-array name="replay_gain_values">
|
||||
<item>wyłączony</item>
|
||||
<item>utwór</item>
|
||||
<item>album</item>
|
||||
<item>auto</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="transcoded_download_option_list_titles">
|
||||
<item>Nie transkoduj</item>
|
||||
<item>Ustawienia serwera</item>
|
||||
<item>Format transkodowania Wi-FI</item>
|
||||
<item>Format transkodowania sieci komórkowej</item>
|
||||
</string-array>
|
||||
<string-array name="transcoded_download_option_list_values">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="buffering_strategy_titles">
|
||||
<item>Minimalna</item>
|
||||
<item>Średnia</item>
|
||||
<item>Agresywna</item>
|
||||
<item>Ekstremalna</item>
|
||||
</string-array>
|
||||
<string-array name="buffering_strategy_values">
|
||||
<item>.1</item>
|
||||
<item>1</item>
|
||||
<item>4</item>
|
||||
<item>8</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="skip_min_star_rating_titles">
|
||||
<item>Minimum 0 gwiazdek</item>
|
||||
<item>Minimum 1 gwiazdka</item>
|
||||
<item>Minimum 2 gwiazdki</item>
|
||||
<item>Minimum 3 gwiazdki</item>
|
||||
<item>Minimum 4 gwiazdki</item>
|
||||
</string-array>
|
||||
<string-array name="skip_min_star_rating_values">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
418
app/src/main/res/values-pl/strings.xml
Normal file
418
app/src/main/res/values-pl/strings.xml
Normal file
|
|
@ -0,0 +1,418 @@
|
|||
<resources>
|
||||
<string name="activity_battery_optimizations_conclusion">Jeżeli masz problemy odwiedź stronę https://dontkillmyapp.com. Podaje ona dokładne instrukcje na temat tego jak wyłączyć funkcje oszczędzania energii które mogą wpływać na wydajność aplikacji.</string>
|
||||
<string name="activity_battery_optimizations_summary">Wyłącz optymalizacje baterii aby odtwarzać media przy wyłączonym ekranie.</string>
|
||||
<string name="activity_battery_optimizations_title">Optymalizcje Baterii</string>
|
||||
<string name="activity_info_offline_mode">Tryb offline</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">Dodaj do kolejki</string>
|
||||
<string name="album_bottom_sheet_download_all">Pobierz wszystkie</string>
|
||||
<string name="album_bottom_sheet_go_to_artist">Przejdź do wykonawcy</string>
|
||||
<string name="album_bottom_sheet_instant_mix">Natychmiastowy mix</string>
|
||||
<string name="album_bottom_sheet_play_next">Odtwórz jako następne</string>
|
||||
<string name="album_bottom_sheet_remove_all">Usuń wszystkie</string>
|
||||
<string name="album_bottom_sheet_share">Udostępnij</string>
|
||||
<string name="album_bottom_sheet_shuffle">Odtwórz losowo</string>
|
||||
<string name="album_catalogue_title">Albumy</string>
|
||||
<string name="album_catalogue_title_expanded">Przeglądaj Albumy</string>
|
||||
<string name="album_error_retrieving_artist">Błąd podczas pobierania wykonawcy</string>
|
||||
<string name="album_list_page_downloaded">Pobrane albumy</string>
|
||||
<string name="album_list_page_most_played">Najczęściej odtwarzane albumy</string>
|
||||
<string name="album_list_page_new_releases">Nowe wydania</string>
|
||||
<string name="album_list_page_recently_added">Albumy dodane niedawno</string>
|
||||
<string name="album_list_page_recently_played">Albumy odtwarzane niedawno</string>
|
||||
<string name="album_list_page_starred">Albumy oznaczone gwiazdką</string>
|
||||
<string name="album_list_page_title">Albumy</string>
|
||||
<string name="album_page_extra_info_button">Więcej podobnych</string>
|
||||
<string name="album_page_play_button">Odtwarzaj</string>
|
||||
<string name="album_page_release_date_label">Wydane %1$s</string>
|
||||
<string name="album_page_release_dates_label">Wydane %1$s, oryginalnie %2$s</string>
|
||||
<string name="album_page_shuffle_button">Odtwarzaj losowo</string>
|
||||
<string name="album_page_tracks_count_and_duration">%1$d utworów • %2$d minut</string>
|
||||
<string name="app_name">Tempo</string>
|
||||
<string name="artist_adapter_radio_station_starting">Szukanie…</string>
|
||||
<string name="artist_bottom_sheet_instant_mix">Natychmiastowy mix mix</string>
|
||||
<string name="artist_bottom_sheet_shuffle">Odtwórz losowo</string>
|
||||
<string name="artist_catalogue_title">Wykonawcy</string>
|
||||
<string name="artist_catalogue_title_expanded">Przeglądaj wykonawców</string>
|
||||
<string name="artist_error_retrieving_radio">Błąd podczas pobierania radia wykonawcy</string>
|
||||
<string name="artist_error_retrieving_tracks">Błąd podczas pobierania utworów wykonawcy</string>
|
||||
<string name="artist_list_page_downloaded">Pobrani wykonawcy</string>
|
||||
<string name="artist_list_page_starred">Wykonawcy oznaczeni gwiazdką</string>
|
||||
<string name="artist_list_page_title">Wykonawcy</string>
|
||||
<string name="artist_page_radio_button">Radio</string>
|
||||
<string name="artist_page_shuffle_button">Odtwarzanie losowe</string>
|
||||
<string name="artist_page_switch_layout_button">Zmień układ</string>
|
||||
<string name="artist_page_title_album_more_like_this_button">Więcej podobnych</string>
|
||||
<string name="artist_page_title_album_section">Albumy</string>
|
||||
<string name="artist_page_title_biography_more_button">Więcej</string>
|
||||
<string name="artist_page_title_biography_section">Biografia</string>
|
||||
<string name="artist_page_title_most_streamed_song_section">Najczęsciej słuchane utwory</string>
|
||||
<string name="artist_page_title_most_streamed_song_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="battery_optimization_negative_button">Ignoruj</string>
|
||||
<string name="battery_optimization_neutral_button">Nie pytaj ponownie</string>
|
||||
<string name="battery_optimization_positive_button">Wyłącz</string>
|
||||
<string name="connection_alert_dialog_negative_button">Anuluj</string>
|
||||
<string name="connection_alert_dialog_neutral_button">Włącz oszczędzanie danych</string>
|
||||
<string name="connection_alert_dialog_positive_button">OK</string>
|
||||
<string name="connection_alert_dialog_summary">Dostęp do serwera Subsonic na połaczeniach innych niż Wi-Fi został ograniczony. Aby zapobiec ponownemu pojawieniu się tej informacji, wyłącz sprawdzanie połączenia w ustawieniach aplikacji.</string>
|
||||
<string name="connection_alert_dialog_title">Nie połączono z Wi-Fi</string>
|
||||
<string name="content_description_shuffle_button">Odtwarzanie losowe</string>
|
||||
<string name="delete_download_storage_dialog_negative_button">Anuluj</string>
|
||||
<string name="delete_download_storage_dialog_positive_button">Kontynuuj</string>
|
||||
<string name="delete_download_storage_dialog_summary">Miej na uwadze to że kontynuowanie tej operacji spowoduje usunięcie wszystkich pobranych plików z wszystkich serwerów.</string>
|
||||
<string name="delete_download_storage_dialog_title">Usuwanie zapisanych plików</string>
|
||||
<string name="description_empty_title">Brak opisu</string>
|
||||
<string name="disc_titlefull">Płyta %1$s - %2$s</string>
|
||||
<string name="disc_titleless">Płyta %1$s</string>
|
||||
<string name="download_directory_dialog_negative_button">Anuluj</string>
|
||||
<string name="download_directory_dialog_positive_button">Pobierz</string>
|
||||
<string name="download_directory_dialog_summary">Wszystkie utwory w tym folderze zostaną pobrane. Utwory dostępne w subfolderach nie zostaną pobrane.</string>
|
||||
<string name="download_directory_dialog_title">Pobierz utwory</string>
|
||||
<string name="download_info_empty_subtitle">Gdy pobierzesz piosenkę, znajdziesz ją tutaj</string>
|
||||
<string name="download_info_empty_title">Narazie brak pobranych!</string>
|
||||
<string name="download_item_multiple_subtitle_formatter">%1$s • %2$s elementów</string>
|
||||
<string name="download_item_single_subtitle_formatter">%1$s element</string>
|
||||
<string name="download_shuffle_all_subtitle">Odtwórz losowo wszystkie</string>
|
||||
<string name="download_storage_dialog_sub_summary">Aby zmiany przyniosły efekt, zrestartuj aplikację.</string>
|
||||
<string name="download_storage_dialog_summary">Zmiana lokalizacji pobieranych plików z jednej na drugą spowoduje natychmiastowe usunięcie wcześniej pobranych plików w drugiej lokalizacji</string>
|
||||
<string name="download_storage_dialog_title">Wybieranie pamięci</string>
|
||||
<string name="download_storage_external_dialog_positive_button">Zewnętrzna</string>
|
||||
<string name="download_storage_internal_dialog_negative_button">Wewnętrzna</string>
|
||||
<string name="download_title_section">Pobrane</string>
|
||||
<string name="downloaded_bottom_sheet_add_to_queue">Dodaj do kolejki</string>
|
||||
<string name="downloaded_bottom_sheet_play_next">Odtwarzaj jako następne</string>
|
||||
<string name="downloaded_bottom_sheet_remove">Usuń</string>
|
||||
<string name="downloaded_bottom_sheet_remove_all">Usuń wszystkie</string>
|
||||
<string name="downloaded_bottom_sheet_shuffle">Odtwarzaj losowo</string>
|
||||
<string name="empty_string" />
|
||||
<string name="error_required">Wymagane</string>
|
||||
<string name="error_server_prefix">wymagany jest prefiks http lub https</string>
|
||||
<string name="exo_download_notification_channel_name">Pobieranie</string>
|
||||
<string name="filter_info_selection">Wybierz dwa lub więcej filtrów</string>
|
||||
<string name="filter_title">Filtry</string>
|
||||
<string name="filter_title_expanded">Filtruj Gatunki</string>
|
||||
<string name="generic_list_page_count">(%1$d)</string>
|
||||
<string name="generic_list_page_count_unknown">(+%1$d)</string>
|
||||
<string name="genre_catalogue_title">Katalog Gatunków</string>
|
||||
<string name="genre_catalogue_title_expanded">Przeglądaj Gatunki</string>
|
||||
<string name="github_update_dialog_negative_button">Przypomnij mi później</string>
|
||||
<string name="github_update_dialog_neutral_button">Wesprzyj mnie</string>
|
||||
<string name="github_update_dialog_positive_button">Pobierz teraz</string>
|
||||
<string name="github_update_dialog_summary">Nowa wersja aplikacji jest dostępna na GitHubie.</string>
|
||||
<string name="github_update_dialog_title">Dostępna aktualizacja</string>
|
||||
<string name="home_rearrangement_dialog_negative_button">Anuluj</string>
|
||||
<string name="home_rearrangement_dialog_neutral_button">Reset</string>
|
||||
<string name="home_rearrangement_dialog_positive_button">Zapisz</string>
|
||||
<string name="home_rearrangement_dialog_title">Zmień układ strony głównej</string>
|
||||
<string name="home_rearrangement_dialog_subtitle">Weź pod uwagę to że, żeby zmiany nastąpiły, musisz zrestartować aplikację.</string>
|
||||
<string name="home_subtitle_best_of">Top piosenki od twoich ulubionych wykonawców</string>
|
||||
<string name="home_subtitle_made_for_you">Stwórz miks z piosenki którą lubisz</string>
|
||||
<string name="home_subtitle_new_internet_radio_station">Dodaj nowe radio</string>
|
||||
<string name="home_subtitle_new_podcast_channel">Dodaj nowy kanał podcastów</string>
|
||||
<string name="home_sync_starred_cancel">Anuluj</string>
|
||||
<string name="home_sync_starred_download">Pobierz</string>
|
||||
<string name="home_sync_starred_subtitle">Pobieranie tych utworów może zużyć dużo danych</string>
|
||||
<string name="home_sync_starred_title">Wygląda na to że, są utwory oznaczone gwiazdką</string>
|
||||
<string name="home_title_best_of">Najlepsze</string>
|
||||
<string name="home_title_discovery">Odkrywanie</string>
|
||||
<string name="home_title_discovery_shuffle_all_button">Odtwórz wszystkie losowo</string>
|
||||
<string name="home_title_flashback">Podróż w czasie</string>
|
||||
<string name="home_title_internet_radio_station">Internetowe stacje radiowe</string>
|
||||
<string name="home_title_last_played">Ostatnio odtwarzane</string>
|
||||
<string name="home_title_last_played_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="home_title_last_week">Ostatni tydzień</string>
|
||||
<string name="home_title_last_month">Ostatni miesiąc</string>
|
||||
<string name="home_title_last_year">Ostatni rok</string>
|
||||
<string name="home_title_made_for_you">Stworzone dla ciebie</string>
|
||||
<string name="home_title_most_played">Najczęściej odtwarzane</string>
|
||||
<string name="home_title_most_played_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="home_title_new_releases">Nowe wydania</string>
|
||||
<string name="home_title_newest_podcasts">Najnowsze podcasty</string>
|
||||
<string name="home_title_pinned_playlists">Playlisty</string>
|
||||
<string name="home_title_podcast_channels">Kanały</string>
|
||||
<string name="home_title_podcast_channels_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="home_title_radio_station">Stacje radiowe</string>
|
||||
<string name="home_title_recently_added">Ostatnio dodane</string>
|
||||
<string name="home_title_recently_added_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="home_title_shares">Udostępnienia</string>
|
||||
<string name="home_title_starred_albums">★ Albumy oznaczone gwiazdką</string>
|
||||
<string name="home_title_starred_albums_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="home_title_starred_artists">★ Wykonawcy oznaczeni gwiazdką</string>
|
||||
<string name="home_title_starred_artists_see_all_button">Zobacz wszystkich</string>
|
||||
<string name="home_title_starred_tracks">★ Utwory oznaczone gwiazdką</string>
|
||||
<string name="home_title_starred_tracks_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="home_title_top_songs">Twoje top piosenki</string>
|
||||
<string name="home_option_reorganize">Zmiana układu</string>
|
||||
<string name="label_dot_separator" translatable="false">•</string>
|
||||
<string name="label_placeholder" translatable="false">--</string>
|
||||
<string name="library_title_album">Albumy</string>
|
||||
<string name="library_title_album_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="library_title_artist">Wykonawcy</string>
|
||||
<string name="library_title_artist_see_all_button">Zobacz wszystkich</string>
|
||||
<string name="library_title_genre">Gatunki</string>
|
||||
<string name="library_title_genre_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="library_title_music_folder">Foldery z muzyką</string>
|
||||
<string name="library_title_playlist">Playlisty</string>
|
||||
<string name="library_title_playlist_see_all_button">Zobacz wszystkie</string>
|
||||
<string name="login_empty">Brak dodanych serwerów</string>
|
||||
<string name="login_title">Serwery Subsonic</string>
|
||||
<string name="login_title_expanded">Serwery Subsonic</string>
|
||||
<string name="media_route_menu_title">Przesyłanie</string>
|
||||
<string name="menu_add_button">Dodaj</string>
|
||||
<string name="menu_download_all_button">Pobierz wszystko</string>
|
||||
<string name="menu_download_label">Pobrane</string>
|
||||
<string name="menu_filter_all">Wszystko</string>
|
||||
<string name="menu_filter_download">Pobrane</string>
|
||||
<string name="menu_group_by_album">Albumy</string>
|
||||
<string name="menu_group_by_artist">Wykonawcy</string>
|
||||
<string name="menu_group_by_genre">Gatkunki</string>
|
||||
<string name="menu_group_by_track">Utwory</string>
|
||||
<string name="menu_group_by_year">Rok</string>
|
||||
<string name="menu_home_label">Strona główna</string>
|
||||
<string name="menu_last_week_name">Ostatni tydzień</string>
|
||||
<string name="menu_last_month_name">Ostatni miesiąc</string>
|
||||
<string name="menu_last_year_name">Ostatni rok</string>
|
||||
<string name="menu_library_label">Biblioteka</string>
|
||||
<string name="menu_search_button">Szukaj</string>
|
||||
<string name="menu_settings_button">Ustawienia</string>
|
||||
<string name="menu_sort_artist">Wykonawca</string>
|
||||
<string name="menu_sort_name">Nazwa</string>
|
||||
<string name="menu_sort_random">Losowo</string>
|
||||
<string name="menu_sort_recently_added">Ostatnio dodane</string>
|
||||
<string name="menu_sort_recently_played">Ostatnio odtwarzane</string>
|
||||
<string name="menu_sort_most_played">Najczęściej odtwarzane</string>
|
||||
<string name="menu_sort_most_recently_starred">Ostatnio oznaczone największą liczbą gwiazdek</string>
|
||||
<string name="menu_sort_least_recently_starred">Ostatnio oznaczone najniższą liczbą gwiazdek</string>
|
||||
<string name="menu_pin_button">Dodaj do ekranu głównego</string>
|
||||
<string name="menu_unpin_button">Usuń z ekranu głównego</string>
|
||||
<string name="menu_sort_year">Rok</string>
|
||||
<string name="player_playback_speed">%1$.2fx</string>
|
||||
<string name="player_queue_clean_all_button">Wyczyść kolejkę odtwarzania</string>
|
||||
<string name="player_server_priority">Priorytet Serwerów</string>
|
||||
<string name="playlist_catalogue_title">Katalog Playlist</string>
|
||||
<string name="playlist_catalogue_title_expanded">Przeglądaj Playlisty</string>
|
||||
<string name="playlist_chooser_dialog_empty">Nie utworzono playlist</string>
|
||||
<string name="playlist_chooser_dialog_negative_button">Anuluj</string>
|
||||
<string name="playlist_chooser_dialog_neutral_button">Utwórz</string>
|
||||
<string name="playlist_chooser_dialog_title">Dodaj do playlisty</string>
|
||||
<string name="playlist_counted_tracks">%1$d utworów • %2$s</string>
|
||||
<string name="playlist_duration">Długość • %1$s</string>
|
||||
<string name="playlist_editor_dialog_action_delete_toast">Przytrzymaj aby usunąć</string>
|
||||
<string name="playlist_editor_dialog_hint_name">Nazwa Playlisty</string>
|
||||
<string name="playlist_editor_dialog_negative_button">Anuluj</string>
|
||||
<string name="playlist_editor_dialog_neutral_button">Usuń</string>
|
||||
<string name="playlist_editor_dialog_positive_button">Zapisz</string>
|
||||
<string name="playlist_editor_dialog_title">Edytuj playlistę</string>
|
||||
<string name="playlist_page_play_button">Odtwórz</string>
|
||||
<string name="playlist_page_shuffle_button">Odtwarzaj losowo</string>
|
||||
<string name="playlist_song_count">Playlista • %1$d piosenek</string>
|
||||
<string name="podcast_bottom_sheet_add_to_queue">Dodaj do kolejki</string>
|
||||
<string name="podcast_bottom_sheet_delete">Usuń</string>
|
||||
<string name="podcast_bottom_sheet_download">Pobierz</string>
|
||||
<string name="podcast_bottom_sheet_go_to_channel">Przejdź do kanału</string>
|
||||
<string name="podcast_bottom_sheet_play_next">Odtwórz jako następny</string>
|
||||
<string name="podcast_bottom_sheet_remove">Usuń</string>
|
||||
<string name="podcast_channel_catalogue_title">Kanały</string>
|
||||
<string name="podcast_channel_catalogue_title_expanded">Przeglądaj Kanały</string>
|
||||
<string name="podcast_channel_editor_dialog_hint_rss_url">Url RSS</string>
|
||||
<string name="podcast_channel_editor_dialog_title">Kanał Podcastu</string>
|
||||
<string name="podcast_channel_page_title_description_section">Opis</string>
|
||||
<string name="podcast_channel_page_title_episode_section">Odcinki</string>
|
||||
<string name="podcast_channel_page_title_no_episode_available">Brak dostępnych odcinków</string>
|
||||
<string name="podcast_episode_download_request_snackbar">Twoje zapytanie zostało wysłane do serwera</string>
|
||||
<string name="podcast_info_empty_button">Naciśnij aby ukryć tę sekcję\nEfekty będą widoczne po restarcie</string>
|
||||
<string name="podcast_info_empty_subtitle">Gdy dodasz kanał, znajdziesz go tutaj</string>
|
||||
<string name="podcast_info_empty_title">Nie znaleziono podcastów!</string>
|
||||
<string name="podcast_release_date_duration_formatter">%1$s • %2$s</string>
|
||||
<string name="radio_editor_dialog_hint_homepage_url">URL Strony Radia</string>
|
||||
<string name="radio_editor_dialog_hint_name">Nazwa Radia</string>
|
||||
<string name="radio_editor_dialog_hint_stream_url">URL Z Strumieniem Radia</string>
|
||||
<string name="radio_editor_dialog_negative_button">Anuluj</string>
|
||||
<string name="radio_editor_dialog_neutral_button">Usuń</string>
|
||||
<string name="radio_editor_dialog_positive_button">Zapisz</string>
|
||||
<string name="radio_editor_dialog_title">Internetowa Stacja Radiowa</string>
|
||||
<string name="radio_station_info_empty_button">Naciśnij aby ukryć tę sekcję\nEfekty będą widoczne po restarcie</string>
|
||||
<string name="radio_station_info_empty_subtitle">Gdy dodasz stację radiową, znajdziesz ją tutaj</string>
|
||||
<string name="radio_station_info_empty_title">Nie znaleziono stacji!</string>
|
||||
<string name="rating_dialog_negative_button">Anuluj</string>
|
||||
<string name="rating_dialog_positive_button">Zapisz</string>
|
||||
<string name="rating_dialog_title">Oceń</string>
|
||||
<string name="search_hint">Wyszukaj tytuł, wykonawców lub albumy</string>
|
||||
<string name="search_info_minimum_characters">Wpisz co najmniej trzy znaki</string>
|
||||
<string name="search_title_album">Albumy</string>
|
||||
<string name="search_title_artist">Wykonawcy</string>
|
||||
<string name="search_title_song">Piosenki</string>
|
||||
<string name="server_signup_dialog_action_low_security">Niskie bezpieczeństwo</string>
|
||||
<string name="server_signup_dialog_action_delete_toast">Przytrzymaj aby usunąć</string>
|
||||
<string name="server_signup_dialog_hint_local_address">Lokalny URL</string>
|
||||
<string name="server_signup_dialog_hint_name">Nazwa Serwera</string>
|
||||
<string name="server_signup_dialog_hint_password">Hasło</string>
|
||||
<string name="server_signup_dialog_hint_url">URL Serwera</string>
|
||||
<string name="server_signup_dialog_hint_username">Nazwa użytkownika</string>
|
||||
<string name="server_signup_dialog_negative_button">Anuluj</string>
|
||||
<string name="server_signup_dialog_neutral_button">Usuń</string>
|
||||
<string name="server_signup_dialog_positive_button">Zapisz</string>
|
||||
<string name="server_signup_dialog_title">Dodaj serwer</string>
|
||||
<string name="server_unreachable_dialog_negative_button">Anuluj</string>
|
||||
<string name="server_unreachable_dialog_neutral_button">Przejdź do logowania</string>
|
||||
<string name="server_unreachable_dialog_positive_button">Kontynuuj mimo wszystko</string>
|
||||
<string name="server_unreachable_dialog_summary">Wybrany serwer jest niedostępny. Jeżeli wybierzesz żeby kontynuować ta informacja nie będzie się wyświetlać przez następną godzinę.</string>
|
||||
<string name="server_unreachable_dialog_title">Serwer jest niedostępny</string>
|
||||
<string name="settings_about_summary">Tempo jest otwarto-źródłowym i lekkim klientem muzycznym dla Subsonic, stworzonym i zbudowanym natywnie dla Androida.</string>
|
||||
<string name="settings_about_title">O aplikacji</string>
|
||||
<string name="settings_always_on_display">Always on display</string>
|
||||
<string name="settings_audio_transcode_download_format">Format transkodowania</string>
|
||||
<string name="settings_audio_transcode_download_priority_summary">Jeżeli włączone, Tempo nie będzię wymuszał pobierania utworu z ustawieniami transkodowania wybranymi poniżej.</string>
|
||||
<string name="settings_audio_transcode_download_priority_title">Priorytetyzuj ustawienia serwera używanego do strumieniowania w pobieraniach</string>
|
||||
<string name="settings_audio_transcode_download_summary">Jeżeli włączone, Tempo będzie pobierał transkodowane utwory.</string>
|
||||
<string name="settings_audio_transcode_download_title">Pobieraj transkodowane utwory</string>
|
||||
<string name="settings_audio_transcode_estimate_content_length_summary">Jeżeli włączone, serwer bedzię odpytywany o przybliżoną długość utworu.</string>
|
||||
<string name="settings_audio_transcode_estimate_content_length_title">Szacuj długość treści</string>
|
||||
<string name="settings_audio_transcode_format_download">Format transkodowania dla pobierania</string>
|
||||
<string name="settings_audio_transcode_format_mobile">Format transkodowania w sieci komórkowej</string>
|
||||
<string name="settings_audio_transcode_format_wifi">Format transkodowania w sieci Wi-Fi</string>
|
||||
<string name="settings_audio_transcode_priority_summary">Jeżeli włączone, Tempo nie będzie wymuszał strumieniowania utworu z ustawieniami transkodowania wybranymi poniżej.</string>
|
||||
<string name="settings_audio_transcode_priority_title">Priorytetyzuj ustawienia transkodowania serwera</string>
|
||||
<string name="settings_audio_transcode_priority_toast">Priorytet przy transkodowaniu utworu danego serwerowi</string>
|
||||
<string name="settings_buffering_strategy">Strategia buforowania</string>
|
||||
<string name="settings_buffering_strategy_summary">Aby zmiany przyniosły efekt, musisz ręcznie zrestartować aplikację.</string>
|
||||
<string name="settings_continuous_play_summary">Pozwala muzyce odtwarzać się dalej po końcu playlisty, odtwarza podobne piosenki</string>
|
||||
<string name="settings_continuous_play_title">Odtwarzanie bez przerwy</string>
|
||||
<string name="settings_covers_cache">Rozmiar cache dla okładek</string>
|
||||
<string name="settings_data_saving_mode_summary">Aby zmniejszyć zużycie danych, unikaj pobierania okładek.</string>
|
||||
<string name="settings_data_saving_mode_title">Ogranicz zużycie danych komórkowych</string>
|
||||
<string name="settings_delete_download_storage_summary">Zatwierdzenie nieodwracalnie usunie wszystkie zapisane elementy</string>
|
||||
<string name="settings_delete_download_storage_title">Usuń zapisane elementy</string>
|
||||
<string name="settings_download_storage_title">Pamięć do pobierania</string>
|
||||
<string name="settings_equalizer_summary">Zmień ustawienia audio</string>
|
||||
<string name="settings_equalizer_title">Equalizer</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">Śledź tworzenie aplikacji</string>
|
||||
<string name="settings_github_title">GitHub</string>
|
||||
<string name="settings_image_size">Rozdzielczość obrazów</string>
|
||||
<string name="settings_language">Język</string>
|
||||
<string name="settings_logout_title">Wyloguj</string>
|
||||
<string name="settings_max_bitrate_download">Bitrate dla pobierania</string>
|
||||
<string name="settings_max_bitrate_mobile">Bitrate dla danych komórkowych</string>
|
||||
<string name="settings_max_bitrate_wifi">Bitrate dla Wi-Fi</string>
|
||||
<string name="settings_media_cache">Rozmiar plików cache dla mediów</string>
|
||||
<string name="settings_music_directory">Pokaż foldery z muzyką</string>
|
||||
<string name="settings_music_directory_summary">Jeżeli włączone, widoczna będzie sekcja z folderami z muzyką. Weź pod uwagę że żeby funkcja nawigacji po folderach działała poprawnie, serwer musi wspierać tę funkcję.</string>
|
||||
<string name="settings_podcast">Pokazuj podcasty</string>
|
||||
<string name="settings_podcast_summary">Jeżeli włączone, widoczna będzie sekcja z podcastami. Zrestartuj aplikację aby, zmiany przyniosły pełny efekt.</string>
|
||||
<string name="settings_audio_quality">Pokaż jakość audio</string>
|
||||
<string name="settings_audio_quality_summary">Bitrate i format audio będzie pokazywany dla każdego utworu.</string>
|
||||
<string name="settings_item_rating">Pokaż oceny elementów</string>
|
||||
<string name="settings_item_rating_summary">Jeżeli włączone, ocena elementów oraz czy jest oznaczony jako ulubiony będą pokazywane.</string>
|
||||
<string name="settings_queue_syncing_countdown">Timer synchronizacji</string>
|
||||
<string name="settings_queue_syncing_summary">Jeżeli włączone, użytkownik będzie miał możliwość zapisania kolejki i będzie miał możliwość załadowania jej stanu przy otwarciu aplikacji.</string>
|
||||
<string name="settings_queue_syncing_title">Synchronizuj kolejkę odtwarzania dla tego użytkownika</string>
|
||||
<string name="settings_radio">Pokaż radio</string>
|
||||
<string name="settings_radio_summary">Jeżeli włączone, widoczna będzie sekcja radia. Zrestartuj aplikację aby, zmiany przyniosły pełny efekt.</string>
|
||||
<string name="settings_replay_gain">Tryb wzmocnienia głośności przy ponownym odtwarzaniu</string>
|
||||
<string name="settings_rounded_corner">Zaokrąglone rogi</string>
|
||||
<string name="settings_rounded_corner_size">Rozmiar rogów</string>
|
||||
<string name="settings_rounded_corner_size_summary">Ustawia wielkość krzywizny kąta.</string>
|
||||
<string name="settings_rounded_corner_summary">Jeżeli włączone, ustawia kąt krzywizny dla wszystkich renderowanych okładek. Zmiany przyniosą efekt po restarcie.</string>
|
||||
<string name="settings_scan_title">Skanuj bibliotekę</string>
|
||||
<string name="settings_scrobble_title">Włącz scrobbling muzyki</string>
|
||||
<string name="settings_share_title">Włącz udostępnianie muzyki</string>
|
||||
<string name="settings_streaming_cache_size">Rozmiar cache dla strumieniowania</string>
|
||||
<string name="settings_streaming_cache_storage_title">Pamięć cache dla strumieniowania</string>
|
||||
<string name="settings_sub_summary_scrobble">Ważne jest to że scrobbling polega też na byciu włączonym na serwerze aby otrzymywać te dane.</string>
|
||||
<string name="settings_summary_skip_min_star_rating">Podczas słuchania radia wykonawcy, natychmiastowego miksu albo podczas odtwarzania losowego, utwory poniżej określonej oceny użytkownika będą ignorowane.</string>
|
||||
<string name="settings_summary_replay_gain">Wzmocnienie głośności jest funkcją która pozwala tobie na ustawienia poziomu głośności dla utworów aby słuchanie brzmiało cały czas tak samo. To ustawienia działa tylko wtedy kiedy utwór zawiera potrzebne metadane.</string>
|
||||
<string name="settings_summary_scrobble">Scrobbling jest funkcją która pozwala twojemu urządzeniu na wysyłanie informacji na temat piosenek których słuchasz do serwera muzyki. Te informacje pomagają tworzyć spersonalizowane rekomendacje na podstawie twojego gustu muzycznego.</string>
|
||||
<string name="settings_summary_share">Pozwala udostępnić użytkownikowi muzykę przez link. Ta funkcjonalność musi być wspierana i włączona na serwerze i jest ograniczona do pojedyńczych utworów, albumów i playlist.</string>
|
||||
<string name="settings_summary_syncing">Przywraca stan kolejki odtwarzania dla tego użytkownika. Zawiera utwory w kolejce, aktualnie odtwarzany utwór i pozycję w nim. Serwer musi wspierać tę funkcję.</string>
|
||||
<string name="settings_summary_streaming_cache_size">%1$s \nAktualnie w użyciu: %2$s MiB</string>
|
||||
<string name="settings_summary_transcoding">Priorytet dawany trybowi transkodowania. Jeżeli ustawiony na \"Odtwarzanie bezpośrednie\" bitrate pliku nie zostanie zmieniony.</string>
|
||||
<string name="settings_summary_transcoding_download">Pobieraj transkdowane media. Jeżeli włączone, endpoint pobierania nie będzie używnany, poza następującymi ustawieniami. \n\n Jeżeli \"Format transkodowania dla pobierania\" jest ustawiony na \"Pobieranie bezpośrednie\" bitrate pliku nie zostanie zmieniony.</string>
|
||||
<string name="settings_summary_transcoding_estimate_content_length">Kiedy plik jest transkodowany w locie, klient nie pokazuje zwykle długości utworu.Jest możliwe odpytanie serwera który wspiera tą funkcjonalność aby oszacował długość odtwarzanego utworu, ale czasy odpowiedzi mogą być dłuższe.</string>
|
||||
<string name="settings_sync_starred_tracks_for_offline_use_summary">Jeżeli włączone, utwory oznaczone gwiazdką będą pobrane do użycia offline.</string>
|
||||
<string name="settings_sync_starred_tracks_for_offline_use_title">Zsynchronizuj utwory oznaczone gwiazdką do użycia offline</string>
|
||||
<string name="settings_theme">Motyw</string>
|
||||
<string name="settings_title_data">Dane</string>
|
||||
<string name="settings_title_general">Ogólne</string>
|
||||
<string name="settings_title_rating">Oceny</string>
|
||||
<string name="settings_title_replay_gain">Wzmocnienie głośności przy ponownym odtwarzaniu</string>
|
||||
<string name="settings_title_scrobble">Scrobble</string>
|
||||
<string name="settings_title_skip_min_star_rating">Ignoruj utwory na podstawie oceny</string>
|
||||
<string name="settings_title_skip_min_star_rating_dialog">Piosenki z oceną:</string>
|
||||
<string name="settings_title_share">Udostępnianie</string>
|
||||
<string name="settings_title_syncing">Synchronizacja</string>
|
||||
<string name="settings_title_transcoding">Transkodowanie</string>
|
||||
<string name="settings_title_transcoding_download">Transkodowanie Pobrań</string>
|
||||
<string name="settings_title_ui">Interfejs</string>
|
||||
<string name="settings_transcoded_download">Transkodowane pobieranie</string>
|
||||
<string name="settings_version_summary" translatable="false">3.1.0</string>
|
||||
<string name="settings_version_title">Wersja</string>
|
||||
<string name="settings_wifi_only_summary">Pytaj o potwierdzenie od użytkownika przed strumieniowaniem przez sieć komórkową.</string>
|
||||
<string name="settings_wifi_only_title">Alert o strumieniowaniu tylko przez Wi-Fi</string>
|
||||
<string name="share_bottom_sheet_copy_link">Kopiuj link</string>
|
||||
<string name="share_bottom_sheet_delete">Usuń udostępnianie</string>
|
||||
<string name="share_bottom_sheet_update">Zaktualizuj udostępnianie</string>
|
||||
<string name="share_subtitle_item">Data wygaśnięcia: %1$s</string>
|
||||
<string name="share_unsupported_error">Udostępnianie nie jest wspierane lub włączone</string>
|
||||
<string name="share_update_dialog_hint_description">Opis</string>
|
||||
<string name="share_update_dialog_hint_expiration_date">Data wygaśnięcia</string>
|
||||
<string name="share_update_dialog_negative_button">Anuluj</string>
|
||||
<string name="share_update_dialog_positive_button">Zapisz</string>
|
||||
<string name="share_update_dialog_title">Udostępnij</string>
|
||||
<string name="song_bottom_sheet_add_to_playlist">Dodaj do playlisty</string>
|
||||
<string name="song_bottom_sheet_add_to_queue">Dodaj do kolejki</string>
|
||||
<string name="song_bottom_sheet_download">Pobierz</string>
|
||||
<string name="song_bottom_sheet_error_retrieving_album">Błąd podczas pobierania albumu</string>
|
||||
<string name="song_bottom_sheet_error_retrieving_artist">Błąd podczas pobierania wykonawcy</string>
|
||||
<string name="song_bottom_sheet_go_to_album">Przejdź do albumu</string>
|
||||
<string name="song_bottom_sheet_go_to_artist">Przejdź do wykonawcy</string>
|
||||
<string name="song_bottom_sheet_instant_mix">Natychmiastowy miks</string>
|
||||
<string name="song_bottom_sheet_play_next">Odtwarzaj jako następne</string>
|
||||
<string name="song_bottom_sheet_rate">Oceń</string>
|
||||
<string name="song_bottom_sheet_remove">Usuń</string>
|
||||
<string name="song_bottom_sheet_share">Udostępnij</string>
|
||||
<string name="song_list_page_downloaded">Pobrane</string>
|
||||
<string name="song_list_page_most_played">Najczęściej odtwarzane utwory</string>
|
||||
<string name="song_list_page_recently_added">Utwory dodane ostatnio</string>
|
||||
<string name="song_list_page_recently_played">Utwory odtwarzane ostatnio</string>
|
||||
<string name="song_list_page_starred">Utwory oznaczone gwiazdką</string>
|
||||
<string name="song_list_page_top">%1$s\ top utwory</string>
|
||||
<string name="song_list_page_year">Rok %1$d</string>
|
||||
<string name="song_subtitle_formatter">%1$s • %2$s %3$s</string>
|
||||
<string name="starred_sync_dialog_negative_button">Anuluj</string>
|
||||
<string name="starred_sync_dialog_neutral_button">Kontynuuj</string>
|
||||
<string name="starred_sync_dialog_positive_button">Kontynuuj i pobierz</string>
|
||||
<string name="starred_sync_dialog_summary">Pobieranie utworów oznaczonych gwiazdką może wymagać dużej ilośći danych.</string>
|
||||
<string name="starred_sync_dialog_title">Synchronizuj utwory oznaczone gwiazdką</string>
|
||||
<string name="streaming_cache_storage_dialog_sub_summary">Aby zmiany przyniosły efekt, zrestartuj aplikację.</string>
|
||||
<string name="streaming_cache_storage_dialog_summary">Zmiana lokalizacji plików cache z jednej na drugą spowoduje natychmiastowe usunięcie wcześniej pobranych plików cache w drugiej lokalizacji.</string>
|
||||
<string name="streaming_cache_storage_dialog_title">Wybieranie pamięci</string>
|
||||
<string name="streaming_cache_storage_external_dialog_positive_button">Zewnętrzna</string>
|
||||
<string name="streaming_cache_storage_internal_dialog_negative_button">Wewnętrzna</string>
|
||||
<string name="support_url">https://buymeacoffee.com/a.cappiello</string>
|
||||
<string name="track_info_album">Album</string>
|
||||
<string name="track_info_artist">Wykonawca</string>
|
||||
<string name="track_info_bitrate">Bitrate</string>
|
||||
<string name="track_info_content_type">Typ Treści</string>
|
||||
<string name="track_info_dialog_positive_button">OK</string>
|
||||
<string name="track_info_dialog_title">Informacje o utworze</string>
|
||||
<string name="track_info_disc_number">Numer płyty</string>
|
||||
<string name="track_info_duration">Długość</string>
|
||||
<string name="track_info_genre">Gatunek</string>
|
||||
<string name="track_info_path">Ścieżka</string>
|
||||
<string name="track_info_size">Rozmiar</string>
|
||||
<string name="track_info_suffix">Sufiks</string>
|
||||
<string name="track_info_summary_downloaded_file">Plik został pobrany przy użyciu API Subsonic. Kodek i bitrate pliku pozostaje nie zmieniony względem pliku źródłowego.</string>
|
||||
<string name="track_info_summary_full_transcode">Aplikacja poprosi serwer żeby transkodować plik i zmienić jego bitrate. Użytkownik poprosił o kodek %1$s, z bitratem %2$s. Wszystkie potencjalne zmiany w kodeku i bitratecie pliku w wybranym formacie będą wykonywane przez serwer, który może ale nie musi obsługiwać tych operacji.</string>
|
||||
<string name="track_info_summary_original_file">Aplikacja będzie tylko odczytywać oryginalne pliki jakie daje serwer. Aplikacja będzie wyłącznie prosić serwer o pliki bez transkodowania z bitratem oryginalnego źródła.</string>
|
||||
<string name="track_info_summary_server_prioritized">\Jakość odtwarzanego pliku zależy od decyzji serwera. Aplikacja nie będzie monitorować wyboru kodeku i bitrateu dla jakiegokolwiek potencjalnego transkodowania.</string>
|
||||
<string name="track_info_summary_transcoding_bitrate">Aplikacja poprosi serwer o zmodyfikowanie bitrateu pliku. Użytkownik poprosił o bitrate %1$s, ale kodek pliku źródłowego pozostanie ten sam. Wszystkie potencjalne zmiany w bitracie pliku w wybranym formacie będą wykonywane przez serwer, który może ale nie musi obsługiwać tych operacji.</string>
|
||||
<string name="track_info_summary_transcoding_codec">Aplikacja poprosi serwer żeby transkodować plik. Kodek wybrany przez użytkownika to %1$s, ale bitrate pliku źródłowego pozostanie ten sam. Wszystkie potencjalne zmiany w kodeku pliku w wybranym formacie będą wykonywane przez serwer, który może ale nie musi obsługiwać tych operacji</string>
|
||||
<string name="track_info_title">Tytuł</string>
|
||||
<string name="track_info_track_number">Numer utworu</string>
|
||||
<string name="track_info_transcoded_content_type">Typ transkodowanej treści</string>
|
||||
<string name="track_info_transcoded_suffix">Sufiks transkodowania</string>
|
||||
<string name="track_info_year">Rok</string>
|
||||
<string name="undraw_page">unDraw</string>
|
||||
<string name="undraw_thanks">Specjalne podziękowania dla unDraw bez którego ilustracji nie mogliśmy uczynić tej aplikacji jeszcze piękniejszą.</string>
|
||||
<string name="undraw_url">https://undraw.co/</string>
|
||||
</resources>
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
<string name="activity_battery_optimizations_summary">Por favor, desative as otimizações de bateria para a reprodução de mídia enquanto a tela estiver desligada.</string>
|
||||
<string name="activity_battery_optimizations_title">Otimizações de bateria</string>
|
||||
<string name="activity_info_offline_mode">Modo offline</string>
|
||||
<string name="album_bottom_sheet_add_to_playlist">Adicionar a uma playlist</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">Adicionar à fila</string>
|
||||
<string name="album_bottom_sheet_download_all">Baixar todos</string>
|
||||
<string name="album_bottom_sheet_go_to_artist">Ir para o(a) artista</string>
|
||||
|
|
@ -134,6 +135,7 @@
|
|||
<string name="login_title_expanded">Servidores Subsonic</string>
|
||||
<string name="media_route_menu_title">Transmitir</string>
|
||||
<string name="menu_add_button">Adicionar</string>
|
||||
<string name="menu_add_to_playlist_button">Adicionar a uma playlist</string>
|
||||
<string name="menu_download_all_button">Baixar todos</string>
|
||||
<string name="menu_download_label">Download</string>
|
||||
<string name="menu_filter_all">Todos</string>
|
||||
|
|
@ -160,6 +162,8 @@
|
|||
<string name="playlist_chooser_dialog_negative_button">Cancelar</string>
|
||||
<string name="playlist_chooser_dialog_neutral_button">Criar</string>
|
||||
<string name="playlist_chooser_dialog_title">Adicionar a uma playlist</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_success">Adicionada playlist de reprodução</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_failure">Falha ao adicionar uma playlist de reprodução</string>
|
||||
<string name="playlist_counted_tracks">%1$d faixas • %2$s</string>
|
||||
<string name="playlist_duration">Duração • %1$s</string>
|
||||
<string name="playlist_editor_dialog_hint_name">Nome da playlist</string>
|
||||
|
|
@ -246,7 +250,7 @@
|
|||
<string name="settings_download_storage_title">Armazenamento dos downloads</string>
|
||||
<string name="settings_equalizer_summary">Ajustar configurações de áudio</string>
|
||||
<string name="settings_equalizer_title">Equalizador</string>
|
||||
<string name="settings_github_link">https://github.com/CappielloAntonio/tempo</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">Acompanhe o desenvolvimento</string>
|
||||
<string name="settings_github_title">Github</string>
|
||||
<string name="settings_image_size">Definir resolução da imagem</string>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<string name="activity_battery_optimizations_summary">Пожалуйста, отключите оптимизацию батареи для воспроизведения мультимедиа при выключенном экране.</string>
|
||||
<string name="activity_battery_optimizations_title">Оптимизация батареи</string>
|
||||
<string name="activity_info_offline_mode">Офлайн-режим</string>
|
||||
<string name="album_bottom_sheet_add_to_playlist">Добавить в плейлист</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">Добавить в очередь</string>
|
||||
<string name="album_bottom_sheet_download_all">Скачать все</string>
|
||||
<string name="album_bottom_sheet_go_to_artist">Перейти к исполнителю</string>
|
||||
|
|
@ -153,6 +154,7 @@
|
|||
<string name="login_title_expanded">Subsonic серверы</string>
|
||||
<string name="media_route_menu_title">Cast</string>
|
||||
<string name="menu_add_button">Добавить</string>
|
||||
<string name="menu_add_to_playlist_button">Добавить в плейлист</string>
|
||||
<string name="menu_download_all_button">Скачать все</string>
|
||||
<string name="menu_download_label">Скачать</string>
|
||||
<string name="menu_filter_all">Все</string>
|
||||
|
|
@ -186,6 +188,8 @@
|
|||
<string name="playlist_chooser_dialog_negative_button">Отмена</string>
|
||||
<string name="playlist_chooser_dialog_neutral_button">Создать</string>
|
||||
<string name="playlist_chooser_dialog_title">Добавить в плейлист</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_success">Добавьте песню в плейлист</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_failure">Не удалось добавить песню в список воспроизведения</string>
|
||||
<string name="playlist_counted_tracks">%1$d треков • %2$s</string>
|
||||
<string name="playlist_duration">Продолжительность • %1$s</string>
|
||||
<string name="playlist_editor_dialog_action_delete_toast">Долгое нажатие для удаления</string>
|
||||
|
|
@ -275,7 +279,7 @@
|
|||
<string name="settings_download_storage_title">Загрузить хранилище</string>
|
||||
<string name="settings_equalizer_summary">Отрегулируйте настройки звука</string>
|
||||
<string name="settings_equalizer_title">Эквалайзер</string>
|
||||
<string name="settings_github_link">https://github.com/CappielloAntonio/tempo</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">Следите за развитием</string>
|
||||
<string name="settings_github_title">Github</string>
|
||||
<string name="settings_image_size">Установить разрешение изображения</string>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<string name="activity_battery_optimizations_summary">请禁用针对媒体锁屏播放的电池优化。</string>
|
||||
<string name="activity_battery_optimizations_title">电池优化</string>
|
||||
<string name="activity_info_offline_mode">离线模式</string>
|
||||
<string name="album_bottom_sheet_add_to_playlist">添加到播放列表</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">添加到队列</string>
|
||||
<string name="album_bottom_sheet_download_all">全部下载</string>
|
||||
<string name="album_bottom_sheet_go_to_artist">查看该艺术家</string>
|
||||
|
|
@ -137,6 +138,7 @@
|
|||
<string name="login_title_expanded">Subsonic 服务器</string>
|
||||
<string name="media_route_menu_title">投送</string>
|
||||
<string name="menu_add_button">添加</string>
|
||||
<string name="menu_add_to_playlist_button">添加到播放列表</string>
|
||||
<string name="menu_download_all_button">全部下载</string>
|
||||
<string name="menu_download_label">下载</string>
|
||||
<string name="menu_filter_all">全部</string>
|
||||
|
|
@ -165,6 +167,8 @@
|
|||
<string name="playlist_chooser_dialog_negative_button">取消</string>
|
||||
<string name="playlist_chooser_dialog_neutral_button">新建</string>
|
||||
<string name="playlist_chooser_dialog_title">添加到播放列表</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_success">将歌曲添加到播放列表</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_failure">未能将歌曲添加到播放列表</string>
|
||||
<string name="playlist_counted_tracks">%1$d 首曲目 • %2$s</string>
|
||||
<string name="playlist_duration">持续时间 • %1$s</string>
|
||||
<string name="playlist_editor_dialog_hint_name">播放列表名称</string>
|
||||
|
|
@ -253,7 +257,7 @@
|
|||
<string name="settings_download_storage_title">下载存储</string>
|
||||
<string name="settings_equalizer_summary">调整音频设置</string>
|
||||
<string name="settings_equalizer_title">均衡器</string>
|
||||
<string name="settings_github_link">https://github.com/CappielloAntonio/tempo</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">关注开发进展</string>
|
||||
<string name="settings_github_title">Github</string>
|
||||
<string name="settings_image_size">设置图像分辨率</string>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
<string name="activity_battery_optimizations_summary">Please disable battery optimizations for media playback while the screen is off.</string>
|
||||
<string name="activity_battery_optimizations_title">Battery Optimizations</string>
|
||||
<string name="activity_info_offline_mode">Offline mode</string>
|
||||
<string name="album_bottom_sheet_add_to_playlist">Add to playlist</string>
|
||||
<string name="album_bottom_sheet_add_to_queue">Add to queue</string>
|
||||
<string name="album_bottom_sheet_download_all">Download all</string>
|
||||
<string name="album_bottom_sheet_go_to_artist">Go to artist</string>
|
||||
|
|
@ -158,6 +159,7 @@
|
|||
<string name="login_title_expanded">Subsonic servers</string>
|
||||
<string name="media_route_menu_title">Cast</string>
|
||||
<string name="menu_add_button">Add</string>
|
||||
<string name="menu_add_to_playlist_button">Add to playlist</string>
|
||||
<string name="menu_download_all_button">Download all</string>
|
||||
<string name="menu_download_label">Download</string>
|
||||
<string name="menu_filter_all">All</string>
|
||||
|
|
@ -194,6 +196,8 @@
|
|||
<string name="playlist_chooser_dialog_negative_button">Cancel</string>
|
||||
<string name="playlist_chooser_dialog_neutral_button">Create</string>
|
||||
<string name="playlist_chooser_dialog_title">Add to a playlist</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_success">Added song to playlist</string>
|
||||
<string name="playlist_chooser_dialog_toast_add_failure">Failed to add song to playlist</string>
|
||||
<string name="playlist_counted_tracks">%1$d tracks • %2$s</string>
|
||||
<string name="playlist_duration">Duration • %1$s</string>
|
||||
<string name="playlist_editor_dialog_action_delete_toast">Long press to delete</string>
|
||||
|
|
@ -285,7 +289,7 @@
|
|||
<string name="settings_download_storage_title">Download storage</string>
|
||||
<string name="settings_equalizer_summary">Adjust audio settings</string>
|
||||
<string name="settings_equalizer_title">Equalizer</string>
|
||||
<string name="settings_github_link">https://github.com/CappielloAntonio/tempo</string>
|
||||
<string name="settings_github_link">https://github.com/eddyizm/tempo</string>
|
||||
<string name="settings_github_summary">Follow the development</string>
|
||||
<string name="settings_github_title">Github</string>
|
||||
<string name="settings_image_size">Set image resolution</string>
|
||||
|
|
|
|||
|
|
@ -9,4 +9,5 @@
|
|||
<locale android:name="it-IT"/> <!-- Italian -->
|
||||
<locale android:name="ru-RU"/> <!-- Russian -->
|
||||
<locale android:name="es-ES"/> <!-- Spanish (Spain) -->
|
||||
<locale android:name="pl-PL"/> <!-- Polish -->
|
||||
</locale-config>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ class MediaService : MediaLibraryService() {
|
|||
|
||||
private lateinit var player: ExoPlayer
|
||||
private lateinit var mediaLibrarySession: MediaLibrarySession
|
||||
private lateinit var customCommands: List<CommandButton>
|
||||
private lateinit var shuffleCommands: List<CommandButton>
|
||||
private lateinit var repeatCommands: List<CommandButton>
|
||||
|
||||
private var customLayout = ImmutableList.of<CommandButton>()
|
||||
|
||||
|
|
@ -41,6 +42,12 @@ class MediaService : MediaLibraryService() {
|
|||
"android.media3.session.demo.SHUFFLE_ON"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF =
|
||||
"android.media3.session.demo.SHUFFLE_OFF"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF =
|
||||
"android.media3.session.demo.REPEAT_OFF"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE =
|
||||
"android.media3.session.demo.REPEAT_ONE"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL =
|
||||
"android.media3.session.demo.REPEAT_ALL"
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
|
|
@ -72,7 +79,7 @@ class MediaService : MediaLibraryService() {
|
|||
val connectionResult = super.onConnect(session, controller)
|
||||
val availableSessionCommands = connectionResult.availableSessionCommands.buildUpon()
|
||||
|
||||
customCommands.forEach { commandButton ->
|
||||
shuffleCommands.forEach { commandButton ->
|
||||
// TODO: Aggiungere i comandi personalizzati
|
||||
// commandButton.sessionCommand?.let { availableSessionCommands.add(it) }
|
||||
}
|
||||
|
|
@ -89,22 +96,40 @@ class MediaService : MediaLibraryService() {
|
|||
}
|
||||
}
|
||||
|
||||
fun buildCustomLayout(player: Player): ImmutableList<CommandButton> {
|
||||
val shuffle = shuffleCommands[if (player.shuffleModeEnabled) 1 else 0]
|
||||
val repeat = when (player.repeatMode) {
|
||||
Player.REPEAT_MODE_ONE -> repeatCommands[1]
|
||||
Player.REPEAT_MODE_ALL -> repeatCommands[2]
|
||||
else -> repeatCommands[0]
|
||||
}
|
||||
return ImmutableList.of(shuffle, repeat)
|
||||
}
|
||||
|
||||
override fun onCustomCommand(
|
||||
session: MediaSession,
|
||||
controller: ControllerInfo,
|
||||
customCommand: SessionCommand,
|
||||
args: Bundle
|
||||
): ListenableFuture<SessionResult> {
|
||||
if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) {
|
||||
player.shuffleModeEnabled = true
|
||||
customLayout = ImmutableList.of(customCommands[1])
|
||||
session.setCustomLayout(customLayout)
|
||||
} else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) {
|
||||
player.shuffleModeEnabled = false
|
||||
customLayout = ImmutableList.of(customCommands[0])
|
||||
session.setCustomLayout(customLayout)
|
||||
when (customCommand.customAction) {
|
||||
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> player.shuffleModeEnabled = true
|
||||
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> player.shuffleModeEnabled = false
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF,
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL,
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> {
|
||||
val nextMode = when (player.repeatMode) {
|
||||
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
|
||||
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ONE
|
||||
else -> Player.REPEAT_MODE_OFF
|
||||
}
|
||||
player.repeatMode = nextMode
|
||||
}
|
||||
}
|
||||
|
||||
customLayout = librarySessionCallback.buildCustomLayout(player)
|
||||
session.setCustomLayout(customLayout)
|
||||
|
||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||
}
|
||||
|
||||
|
|
@ -125,17 +150,28 @@ class MediaService : MediaLibraryService() {
|
|||
}
|
||||
|
||||
private fun initializeCustomCommands() {
|
||||
customCommands =
|
||||
listOf(
|
||||
getShuffleCommandButton(
|
||||
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON, Bundle.EMPTY)
|
||||
),
|
||||
getShuffleCommandButton(
|
||||
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF, Bundle.EMPTY)
|
||||
)
|
||||
shuffleCommands = listOf(
|
||||
getShuffleCommandButton(
|
||||
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON, Bundle.EMPTY)
|
||||
),
|
||||
getShuffleCommandButton(
|
||||
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF, Bundle.EMPTY)
|
||||
)
|
||||
)
|
||||
|
||||
customLayout = ImmutableList.of(customCommands[0])
|
||||
repeatCommands = listOf(
|
||||
getRepeatCommandButton(
|
||||
SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, Bundle.EMPTY)
|
||||
),
|
||||
getRepeatCommandButton(
|
||||
SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE, Bundle.EMPTY)
|
||||
),
|
||||
getRepeatCommandButton(
|
||||
SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, Bundle.EMPTY)
|
||||
)
|
||||
)
|
||||
|
||||
customLayout = ImmutableList.of(shuffleCommands[0], repeatCommands[0])
|
||||
}
|
||||
|
||||
private fun initializePlayer() {
|
||||
|
|
@ -147,6 +183,9 @@ class MediaService : MediaLibraryService() {
|
|||
.setWakeMode(C.WAKE_MODE_NETWORK)
|
||||
.setLoadControl(initializeLoadControl())
|
||||
.build()
|
||||
|
||||
player.shuffleModeEnabled = Preferences.isShuffleModeEnabled()
|
||||
player.repeatMode = Preferences.getRepeatMode()
|
||||
}
|
||||
|
||||
private fun initializeMediaLibrarySession() {
|
||||
|
|
@ -224,6 +263,18 @@ class MediaService : MediaLibraryService() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
|
||||
Preferences.setShuffleModeEnabled(shuffleModeEnabled)
|
||||
customLayout = librarySessionCallback.buildCustomLayout(player)
|
||||
mediaLibrarySession.setCustomLayout(customLayout)
|
||||
}
|
||||
|
||||
override fun onRepeatModeChanged(repeatMode: Int) {
|
||||
Preferences.setRepeatMode(repeatMode)
|
||||
customLayout = librarySessionCallback.buildCustomLayout(player)
|
||||
mediaLibrarySession.setCustomLayout(customLayout)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -251,6 +302,25 @@ class MediaService : MediaLibraryService() {
|
|||
.build()
|
||||
}
|
||||
|
||||
@SuppressLint("PrivateResource")
|
||||
private fun getRepeatCommandButton(sessionCommand: SessionCommand): CommandButton {
|
||||
val icon = when (sessionCommand.customAction) {
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> R.drawable.exo_icon_repeat_one
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL -> R.drawable.exo_icon_repeat_all
|
||||
else -> R.drawable.exo_icon_repeat_off
|
||||
}
|
||||
val description = when (sessionCommand.customAction) {
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> R.string.exo_controls_repeat_one_description
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL -> R.string.exo_controls_repeat_all_description
|
||||
else -> R.string.exo_controls_repeat_off_description
|
||||
}
|
||||
return CommandButton.Builder()
|
||||
.setDisplayName(getString(description))
|
||||
.setSessionCommand(sessionCommand)
|
||||
.setIconResId(icon)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun ignoreFuture(customLayout: ListenableFuture<SessionResult>) {
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import android.os.Bundle
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.session.CommandButton
|
||||
import androidx.media3.session.LibraryResult
|
||||
|
|
@ -27,7 +28,7 @@ open class MediaLibrarySessionCallback(
|
|||
MediaBrowserTree.initialize(automotiveRepository)
|
||||
}
|
||||
|
||||
private val customLayoutCommandButtons: List<CommandButton> = listOf(
|
||||
private val shuffleCommandButtons: List<CommandButton> = listOf(
|
||||
CommandButton.Builder()
|
||||
.setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description))
|
||||
.setSessionCommand(
|
||||
|
|
@ -45,15 +46,46 @@ open class MediaLibrarySessionCallback(
|
|||
).setIconResId(R.drawable.exo_icon_shuffle_on).build()
|
||||
)
|
||||
|
||||
private val repeatCommandButtons: List<CommandButton> = listOf(
|
||||
CommandButton.Builder()
|
||||
.setDisplayName(context.getString(R.string.exo_controls_repeat_off_description))
|
||||
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, Bundle.EMPTY))
|
||||
.setIconResId(R.drawable.exo_icon_repeat_off)
|
||||
.build(),
|
||||
CommandButton.Builder()
|
||||
.setDisplayName(context.getString(R.string.exo_controls_repeat_one_description))
|
||||
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE, Bundle.EMPTY))
|
||||
.setIconResId(R.drawable.exo_icon_repeat_one)
|
||||
.build(),
|
||||
CommandButton.Builder()
|
||||
.setDisplayName(context.getString(R.string.exo_controls_repeat_all_description))
|
||||
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, Bundle.EMPTY))
|
||||
.setIconResId(R.drawable.exo_icon_repeat_all)
|
||||
.build()
|
||||
)
|
||||
|
||||
private val customLayoutCommandButtons: List<CommandButton> =
|
||||
shuffleCommandButtons + repeatCommandButtons
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
val mediaNotificationSessionCommands =
|
||||
MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
|
||||
.also { builder ->
|
||||
customLayoutCommandButtons.forEach { commandButton ->
|
||||
(shuffleCommandButtons + repeatCommandButtons).forEach { commandButton ->
|
||||
commandButton.sessionCommand?.let { builder.add(it) }
|
||||
}
|
||||
}.build()
|
||||
|
||||
fun buildCustomLayout(player: Player): ImmutableList<CommandButton> {
|
||||
val shuffle = shuffleCommandButtons[if (player.shuffleModeEnabled) 1 else 0]
|
||||
val repeat = when (player.repeatMode) {
|
||||
Player.REPEAT_MODE_ONE -> repeatCommandButtons[1]
|
||||
Player.REPEAT_MODE_ALL -> repeatCommandButtons[2]
|
||||
else -> repeatCommandButtons[0]
|
||||
}
|
||||
return ImmutableList.of(shuffle, repeat)
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
override fun onConnect(
|
||||
session: MediaSession, controller: MediaSession.ControllerInfo
|
||||
|
|
@ -62,12 +94,11 @@ open class MediaLibrarySessionCallback(
|
|||
controller
|
||||
) || session.isAutoCompanionController(controller)
|
||||
) {
|
||||
val customLayout =
|
||||
customLayoutCommandButtons[if (session.player.shuffleModeEnabled) 1 else 0]
|
||||
val customLayout = buildCustomLayout(session.player)
|
||||
|
||||
return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
|
||||
.setAvailableSessionCommands(mediaNotificationSessionCommands)
|
||||
.setCustomLayout(ImmutableList.of(customLayout)).build()
|
||||
.setCustomLayout(customLayout).build()
|
||||
}
|
||||
|
||||
return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build()
|
||||
|
|
@ -80,25 +111,28 @@ open class MediaLibrarySessionCallback(
|
|||
customCommand: SessionCommand,
|
||||
args: Bundle
|
||||
): ListenableFuture<SessionResult> {
|
||||
if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) {
|
||||
session.player.shuffleModeEnabled = true
|
||||
session.setCustomLayout(
|
||||
session.mediaNotificationControllerInfo!!,
|
||||
ImmutableList.of(customLayoutCommandButtons[1])
|
||||
)
|
||||
|
||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||
} else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) {
|
||||
session.player.shuffleModeEnabled = false
|
||||
session.setCustomLayout(
|
||||
session.mediaNotificationControllerInfo!!,
|
||||
ImmutableList.of(customLayoutCommandButtons[0])
|
||||
)
|
||||
|
||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||
when (customCommand.customAction) {
|
||||
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> session.player.shuffleModeEnabled = true
|
||||
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> session.player.shuffleModeEnabled = false
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF,
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL,
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> {
|
||||
val nextMode = when (session.player.repeatMode) {
|
||||
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
|
||||
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ONE
|
||||
else -> Player.REPEAT_MODE_OFF
|
||||
}
|
||||
session.player.repeatMode = nextMode
|
||||
}
|
||||
else -> return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
|
||||
}
|
||||
|
||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
|
||||
session.setCustomLayout(
|
||||
session.mediaNotificationControllerInfo!!,
|
||||
buildCustomLayout(session.player)
|
||||
)
|
||||
|
||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||
}
|
||||
|
||||
override fun onGetLibraryRoot(
|
||||
|
|
@ -158,5 +192,11 @@ open class MediaLibrarySessionCallback(
|
|||
"android.media3.session.demo.SHUFFLE_ON"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF =
|
||||
"android.media3.session.demo.SHUFFLE_OFF"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF =
|
||||
"android.media3.session.demo.REPEAT_OFF"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE =
|
||||
"android.media3.session.demo.REPEAT_ONE"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL =
|
||||
"android.media3.session.demo.REPEAT_ALL"
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
private lateinit var player: ExoPlayer
|
||||
private lateinit var castPlayer: CastPlayer
|
||||
private lateinit var mediaLibrarySession: MediaLibrarySession
|
||||
private lateinit var librarySessionCallback: MediaLibrarySessionCallback
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
|
@ -79,6 +80,9 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
.setWakeMode(C.WAKE_MODE_NETWORK)
|
||||
.setLoadControl(initializeLoadControl())
|
||||
.build()
|
||||
|
||||
player.shuffleModeEnabled = Preferences.isShuffleModeEnabled()
|
||||
player.repeatMode = Preferences.getRepeatMode()
|
||||
}
|
||||
|
||||
private fun initializeCastPlayer() {
|
||||
|
|
@ -97,13 +101,14 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
librarySessionCallback = createLibrarySessionCallback()
|
||||
mediaLibrarySession =
|
||||
MediaLibrarySession.Builder(this, player, createLibrarySessionCallback())
|
||||
MediaLibrarySession.Builder(this, player, librarySessionCallback)
|
||||
.setSessionActivity(sessionActivityPendingIntent)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun createLibrarySessionCallback(): MediaLibrarySession.Callback {
|
||||
private fun createLibrarySessionCallback(): MediaLibrarySessionCallback {
|
||||
return MediaLibrarySessionCallback(this, automotiveRepository)
|
||||
}
|
||||
|
||||
|
|
@ -166,6 +171,20 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
|
||||
Preferences.setShuffleModeEnabled(shuffleModeEnabled)
|
||||
mediaLibrarySession.setCustomLayout(
|
||||
librarySessionCallback.buildCustomLayout(player)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRepeatModeChanged(repeatMode: Int) {
|
||||
Preferences.setRepeatMode(repeatMode)
|
||||
mediaLibrarySession.setCustomLayout(
|
||||
librarySessionCallback.buildCustomLayout(player)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import android.os.Bundle
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.session.CommandButton
|
||||
import androidx.media3.session.LibraryResult
|
||||
|
|
@ -27,7 +28,7 @@ open class MediaLibrarySessionCallback(
|
|||
MediaBrowserTree.initialize(automotiveRepository)
|
||||
}
|
||||
|
||||
private val customLayoutCommandButtons: List<CommandButton> = listOf(
|
||||
private val shuffleCommandButtons: List<CommandButton> = listOf(
|
||||
CommandButton.Builder()
|
||||
.setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description))
|
||||
.setSessionCommand(
|
||||
|
|
@ -45,15 +46,46 @@ open class MediaLibrarySessionCallback(
|
|||
).setIconResId(R.drawable.exo_icon_shuffle_on).build()
|
||||
)
|
||||
|
||||
private val repeatCommandButtons: List<CommandButton> = listOf(
|
||||
CommandButton.Builder()
|
||||
.setDisplayName(context.getString(R.string.exo_controls_repeat_off_description))
|
||||
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, Bundle.EMPTY))
|
||||
.setIconResId(R.drawable.exo_icon_repeat_off)
|
||||
.build(),
|
||||
CommandButton.Builder()
|
||||
.setDisplayName(context.getString(R.string.exo_controls_repeat_one_description))
|
||||
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE, Bundle.EMPTY))
|
||||
.setIconResId(R.drawable.exo_icon_repeat_one)
|
||||
.build(),
|
||||
CommandButton.Builder()
|
||||
.setDisplayName(context.getString(R.string.exo_controls_repeat_all_description))
|
||||
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, Bundle.EMPTY))
|
||||
.setIconResId(R.drawable.exo_icon_repeat_all)
|
||||
.build()
|
||||
)
|
||||
|
||||
private val customLayoutCommandButtons: List<CommandButton> =
|
||||
shuffleCommandButtons + repeatCommandButtons
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
val mediaNotificationSessionCommands =
|
||||
MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
|
||||
.also { builder ->
|
||||
customLayoutCommandButtons.forEach { commandButton ->
|
||||
(shuffleCommandButtons + repeatCommandButtons).forEach { commandButton ->
|
||||
commandButton.sessionCommand?.let { builder.add(it) }
|
||||
}
|
||||
}.build()
|
||||
|
||||
fun buildCustomLayout(player: Player): ImmutableList<CommandButton> {
|
||||
val shuffle = shuffleCommandButtons[if (player.shuffleModeEnabled) 1 else 0]
|
||||
val repeat = when (player.repeatMode) {
|
||||
Player.REPEAT_MODE_ONE -> repeatCommandButtons[1]
|
||||
Player.REPEAT_MODE_ALL -> repeatCommandButtons[2]
|
||||
else -> repeatCommandButtons[0]
|
||||
}
|
||||
return ImmutableList.of(shuffle, repeat)
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
override fun onConnect(
|
||||
session: MediaSession, controller: MediaSession.ControllerInfo
|
||||
|
|
@ -62,12 +94,11 @@ open class MediaLibrarySessionCallback(
|
|||
controller
|
||||
) || session.isAutoCompanionController(controller)
|
||||
) {
|
||||
val customLayout =
|
||||
customLayoutCommandButtons[if (session.player.shuffleModeEnabled) 1 else 0]
|
||||
val customLayout = buildCustomLayout(session.player)
|
||||
|
||||
return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
|
||||
.setAvailableSessionCommands(mediaNotificationSessionCommands)
|
||||
.setCustomLayout(ImmutableList.of(customLayout)).build()
|
||||
.setCustomLayout(customLayout).build()
|
||||
}
|
||||
|
||||
return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build()
|
||||
|
|
@ -80,25 +111,28 @@ open class MediaLibrarySessionCallback(
|
|||
customCommand: SessionCommand,
|
||||
args: Bundle
|
||||
): ListenableFuture<SessionResult> {
|
||||
if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) {
|
||||
session.player.shuffleModeEnabled = true
|
||||
session.setCustomLayout(
|
||||
session.mediaNotificationControllerInfo!!,
|
||||
ImmutableList.of(customLayoutCommandButtons[1])
|
||||
)
|
||||
|
||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||
} else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) {
|
||||
session.player.shuffleModeEnabled = false
|
||||
session.setCustomLayout(
|
||||
session.mediaNotificationControllerInfo!!,
|
||||
ImmutableList.of(customLayoutCommandButtons[0])
|
||||
)
|
||||
|
||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||
when (customCommand.customAction) {
|
||||
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> session.player.shuffleModeEnabled = true
|
||||
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> session.player.shuffleModeEnabled = false
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF,
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL,
|
||||
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> {
|
||||
val nextMode = when (session.player.repeatMode) {
|
||||
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
|
||||
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ONE
|
||||
else -> Player.REPEAT_MODE_OFF
|
||||
}
|
||||
session.player.repeatMode = nextMode
|
||||
}
|
||||
else -> return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
|
||||
}
|
||||
|
||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
|
||||
session.setCustomLayout(
|
||||
session.mediaNotificationControllerInfo!!,
|
||||
buildCustomLayout(session.player)
|
||||
)
|
||||
|
||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||
}
|
||||
|
||||
override fun onGetLibraryRoot(
|
||||
|
|
@ -158,5 +192,11 @@ open class MediaLibrarySessionCallback(
|
|||
"android.media3.session.demo.SHUFFLE_ON"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF =
|
||||
"android.media3.session.demo.SHUFFLE_OFF"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF =
|
||||
"android.media3.session.demo.REPEAT_OFF"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE =
|
||||
"android.media3.session.demo.REPEAT_ONE"
|
||||
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL =
|
||||
"android.media3.session.demo.REPEAT_ALL"
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
private lateinit var player: ExoPlayer
|
||||
private lateinit var castPlayer: CastPlayer
|
||||
private lateinit var mediaLibrarySession: MediaLibrarySession
|
||||
private lateinit var librarySessionCallback: MediaLibrarySessionCallback
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
|
@ -79,6 +80,9 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
.setWakeMode(C.WAKE_MODE_NETWORK)
|
||||
.setLoadControl(initializeLoadControl())
|
||||
.build()
|
||||
|
||||
player.shuffleModeEnabled = Preferences.isShuffleModeEnabled()
|
||||
player.repeatMode = Preferences.getRepeatMode()
|
||||
}
|
||||
|
||||
private fun initializeCastPlayer() {
|
||||
|
|
@ -97,13 +101,14 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
librarySessionCallback = createLibrarySessionCallback()
|
||||
mediaLibrarySession =
|
||||
MediaLibrarySession.Builder(this, player, createLibrarySessionCallback())
|
||||
MediaLibrarySession.Builder(this, player, librarySessionCallback)
|
||||
.setSessionActivity(sessionActivityPendingIntent)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun createLibrarySessionCallback(): MediaLibrarySession.Callback {
|
||||
private fun createLibrarySessionCallback(): MediaLibrarySessionCallback {
|
||||
return MediaLibrarySessionCallback(this, automotiveRepository)
|
||||
}
|
||||
|
||||
|
|
@ -166,6 +171,20 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
|
||||
Preferences.setShuffleModeEnabled(shuffleModeEnabled)
|
||||
mediaLibrarySession.setCustomLayout(
|
||||
librarySessionCallback.buildCustomLayout(player)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRepeatModeChanged(repeatMode: Int) {
|
||||
Preferences.setRepeatMode(repeatMode)
|
||||
mediaLibrarySession.setCustomLayout(
|
||||
librarySessionCallback.buildCustomLayout(player)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
0
gradlew
vendored
Normal file → Executable file
0
gradlew
vendored
Normal file → Executable file
|
|
@ -1,2 +1,5 @@
|
|||
plugins {
|
||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
|
||||
}
|
||||
include ':app'
|
||||
rootProject.name = "Tempo"
|
||||
Loading…
Add table
Add a link
Reference in a new issue