11 Commits
3.4.5 ... 3.4.7

Author SHA1 Message Date
antonio
fcbe4377aa gradle: bump up code version 2023-07-20 17:46:49 +02:00
antonio
84db4060e6 feat: added server-side track transcoding settings option 2023-07-20 17:20:57 +02:00
antonio
b73a1c532b fix: checking for the presence of a system equalizer 2023-07-20 12:33:10 +02:00
antonio
4fe27067e9 fix: null checking 2023-07-20 09:48:12 +02:00
antonio
9c6981ed19 gradle: bump up code version 2023-07-18 12:45:03 +02:00
antonio
560ac2df68 fix: fixed search functionality 2023-07-18 10:37:17 +02:00
antonio
260e6e9daa style: temp - icon splash 2023-07-17 11:11:12 +02:00
antonio
38a1368c76 style: icon toolbar 2023-07-17 11:10:56 +02:00
antonio
9bf3139bd2 style: icon launcher 2023-07-17 11:10:44 +02:00
antonio
d389d1d62a style: icon launcher 2023-07-17 11:10:06 +02:00
antonio
e60c0e312c fix: null checking 2023-07-17 10:55:40 +02:00
38 changed files with 534 additions and 31 deletions

View File

@@ -28,8 +28,8 @@ android {
tempo {
dimension "default"
applicationId 'com.cappielloantonio.tempo'
versionCode 12
versionName '3.4.5'
versionCode 14
versionName '3.4.7'
}
notquitemy {

View File

@@ -12,7 +12,7 @@ import java.util.List;
@Dao
public interface RecentSearchDao {
@Query("SELECT * FROM recent_search ORDER BY search ASC")
@Query("SELECT * FROM recent_search ORDER BY search DESC")
List<String> getRecent();
@Insert(onConflict = OnConflictStrategy.REPLACE)

View File

@@ -24,9 +24,14 @@ public class GenreRepository {
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getGenres() != null) {
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse() != null && response.body().getSubsonicResponse().getGenres() != null) {
List<Genre> genreList = response.body().getSubsonicResponse().getGenres().getGenres();
if (genreList == null || genreList.isEmpty()) {
genres.setValue(Collections.emptyList());
return;
}
if (random) {
Collections.shuffle(genreList);
}

View File

@@ -1,5 +1,7 @@
package com.cappielloantonio.tempo.repository;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
@@ -100,6 +102,8 @@ public class SearchingRepository {
LinkedHashSet<String> hashSet = new LinkedHashSet<>(newSuggestions);
ArrayList<String> suggestionsWithoutDuplicates = new ArrayList<>(hashSet);
Log.d("suggestionsWithoutDuplicates", suggestionsWithoutDuplicates.toString());
suggestions.setValue(suggestionsWithoutDuplicates);
}
}

View File

@@ -76,7 +76,7 @@ public class SongHorizontalAdapter extends RecyclerView.Adapter<SongHorizontalAd
}
public void setItems(List<Child> songs) {
this.songs = songs;
this.songs = songs != null ? songs : Collections.emptyList();
notifyDataSetChanged();
}

View File

@@ -8,6 +8,7 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import androidx.annotation.NonNull;
@@ -51,6 +52,7 @@ public class PlayerControllerFragment extends Fragment {
private Chip playerMediaExtension;
private TextView playerMediaBitrate;
private ImageView playerMediaTranscodingIcon;
private ImageView playerMediaTranscodingPriorityIcon;
private Chip playerMediaTranscodedExtension;
private TextView playerMediaTranscodedBitrate;
@@ -71,6 +73,7 @@ public class PlayerControllerFragment extends Fragment {
initCoverLyricsSlideView();
initMediaListenable();
initArtistLabelButton();
initTranscodingInfo();
return view;
}
@@ -104,6 +107,7 @@ public class PlayerControllerFragment extends Fragment {
playerMediaExtension = bind.getRoot().findViewById(R.id.player_media_extension);
playerMediaBitrate = bind.getRoot().findViewById(R.id.player_media_bitrate);
playerMediaTranscodingIcon = bind.getRoot().findViewById(R.id.player_media_transcoding_audio);
playerMediaTranscodingPriorityIcon = bind.getRoot().findViewById(R.id.player_media_server_transcode_priority);
playerMediaTranscodedExtension = bind.getRoot().findViewById(R.id.player_media_transcoded_extension);
playerMediaTranscodedBitrate = bind.getRoot().findViewById(R.id.player_media_transcoded_bitrate);
}
@@ -166,7 +170,6 @@ public class PlayerControllerFragment extends Fragment {
playerMediaBitrate.setVisibility(View.GONE);
} else {
playerMediaBitrate.setVisibility(View.VISIBLE);
playerMediaBitrate.setText(bitrate);
}
}
@@ -177,19 +180,28 @@ public class PlayerControllerFragment extends Fragment {
: "Original";
if (transcodingExtension.equals("raw") && transcodingBitrate.equals("Original")) {
playerMediaTranscodingPriorityIcon.setVisibility(View.GONE);
playerMediaTranscodingIcon.setVisibility(View.GONE);
playerMediaTranscodedBitrate.setVisibility(View.GONE);
playerMediaTranscodedExtension.setVisibility(View.GONE);
} else {
playerMediaTranscodingPriorityIcon.setVisibility(View.GONE);
playerMediaTranscodingIcon.setVisibility(View.VISIBLE);
playerMediaTranscodedBitrate.setVisibility(View.VISIBLE);
playerMediaTranscodedExtension.setVisibility(View.VISIBLE);
playerMediaTranscodedExtension.setText(transcodingExtension);
playerMediaTranscodedBitrate.setText(transcodingBitrate);
}
if (mediaMetadata.extras != null && mediaMetadata.extras.getString("uri", "").contains(Constants.DOWNLOAD_URI)) {
playerMediaTranscodingPriorityIcon.setVisibility(View.GONE);
playerMediaTranscodingIcon.setVisibility(View.GONE);
playerMediaTranscodedBitrate.setVisibility(View.GONE);
playerMediaTranscodedExtension.setVisibility(View.GONE);
}
if (Preferences.isServerPrioritized() && mediaMetadata.extras != null && !mediaMetadata.extras.getString("uri", "").contains(Constants.DOWNLOAD_URI)) {
playerMediaTranscodingPriorityIcon.setVisibility(View.VISIBLE);
playerMediaTranscodingIcon.setVisibility(View.GONE);
playerMediaTranscodedBitrate.setVisibility(View.GONE);
playerMediaTranscodedExtension.setVisibility(View.GONE);
@@ -293,6 +305,13 @@ public class PlayerControllerFragment extends Fragment {
});
}
private void initTranscodingInfo() {
playerMediaTranscodingPriorityIcon.setOnLongClickListener(view -> {
Toast.makeText(requireActivity(), R.string.settings_audio_transcode_priority_toast, Toast.LENGTH_SHORT).show();
return true;
});
}
private void initPlaybackSpeedButton(MediaBrowser mediaBrowser) {
playbackSpeedButton.setOnClickListener(view -> {
float currentSpeed = Preferences.getPlaybackSpeed();

View File

@@ -4,6 +4,7 @@ import android.content.ComponentName;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -121,17 +122,11 @@ public class SearchFragment extends Fragment implements ClickCallback {
bind.searchView
.getEditText()
.setOnEditorActionListener((textView, actionId, keyEvent) -> {
String query = bind.searchView.getText().toString();
if (actionId == EditorInfo.IME_ACTION_DONE) {
if (isQueryValid(query)) {
search(bind.searchView.getText().toString());
return true;
} else {
Toast.makeText(requireContext(), getString(R.string.search_info_minimum_characters), Toast.LENGTH_SHORT).show();
return false;
}
if (isQueryValid(query)) {
search(query);
return true;
}
return false;
@@ -147,7 +142,7 @@ public class SearchFragment extends Fragment implements ClickCallback {
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (count > 1) {
if (start + count > 1) {
setSearchSuggestions(charSequence.toString());
} else {
setRecentSuggestions();
@@ -247,6 +242,7 @@ public class SearchFragment extends Fragment implements ClickCallback {
}
private boolean isQueryValid(String query) {
Log.d(TAG, "isQueryValid()");
return !query.equals("") && query.trim().length() > 2;
}

View File

@@ -15,6 +15,7 @@ import androidx.annotation.OptIn;
import androidx.lifecycle.ViewModelProvider;
import androidx.media3.common.util.UnstableApi;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import com.cappielloantonio.tempo.BuildConfig;
@@ -70,6 +71,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
public void onResume() {
super.onResume();
checkEqualizer();
findPreference("version").setSummary(BuildConfig.VERSION_NAME);
findPreference("logout").setOnPreferenceClickListener(preference -> {
@@ -93,12 +96,6 @@ public class SettingsFragment extends PreferenceFragmentCompat {
return true;
});
findPreference("equalizer").setOnPreferenceClickListener(preference -> {
Intent intent = new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL);
someActivityResultLauncher.launch(intent);
return true;
});
findPreference("sync_starred_tracks_for_offline_use").setOnPreferenceChangeListener((preference, newValue) -> {
if (newValue instanceof Boolean) {
if ((Boolean) newValue) {
@@ -130,6 +127,23 @@ public class SettingsFragment extends PreferenceFragmentCompat {
}
}
private void checkEqualizer() {
Preference equalizer = findPreference("equalizer");
if (equalizer == null) return;
Intent intent = new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL);
if ((intent.resolveActivity(requireActivity().getPackageManager()) != null)) {
equalizer.setOnPreferenceClickListener(preference -> {
someActivityResultLauncher.launch(intent);
return true;
});
} else {
equalizer.setVisible(false);
}
}
private void getScanStatus() {
settingViewModel.getScanStatus(new ScanCallback() {
@Override

View File

@@ -41,8 +41,11 @@ public class MusicUtil {
if (params.containsKey("c") && params.get("c") != null)
uri.append("&c=").append(params.get("c"));
uri.append("&maxBitRate=").append(getBitratePreference());
uri.append("&format=").append(getTranscodingFormatPreference());
if (!Preferences.isServerPrioritized())
uri.append("&maxBitRate=").append(getBitratePreference());
if (!Preferences.isServerPrioritized())
uri.append("&format=").append(getTranscodingFormatPreference());
uri.append("&id=").append(id);
Log.d(TAG, "getStreamUri: " + uri);

View File

@@ -32,6 +32,7 @@ object Preferences {
private const val RADIO_SECTION_VISIBILITY = "radio_section_visibility"
private const val MUSIC_DIRECTORY_SECTION_VISIBILITY = "music_directory_section_visibility"
private const val REPLAY_GAIN_MODE = "replay_gain_mode"
private const val AUDIO_TRANSCODE_PRIORITY = "audio_transcode_priority"
@JvmStatic
fun getServer(): String? {
@@ -252,4 +253,9 @@ object Preferences {
fun getReplayGainMode(): String? {
return App.getInstance().preferences.getString(REPLAY_GAIN_MODE, "disabled")
}
@JvmStatic
fun isServerPrioritized(): Boolean {
return App.getInstance().preferences.getBoolean(AUDIO_TRANSCODE_PRIORITY, false)
}
}

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@color/titleTextColor"
android:pathData="M480,796.92Q455.25,796.92 437.63,779.29Q420,761.67 420,736.92Q420,712.17 437.63,694.55Q455.25,676.92 480,676.92Q504.75,676.92 522.37,694.55Q540,712.17 540,736.92Q540,761.67 522.37,779.29Q504.75,796.92 480,796.92ZM425.39,600.77L425.39,143.08L534.61,143.08L534.61,600.77L425.39,600.77Z"/>
</vector>

View File

@@ -41,6 +41,13 @@
android:src="@drawable/ic_transcode"
android:visibility="gone" />
<ImageView
android:id="@+id/player_media_server_transcode_priority"
android:layout_width="24dp"
android:layout_height="20dp"
android:src="@drawable/ic_server_transcode_priority"
android:visibility="gone" />
<com.google.android.material.chip.Chip
android:id="@+id/player_media_transcoded_extension"
style="@style/Widget.Material3.Chip.Suggestion"

View File

@@ -36,8 +36,8 @@
<ImageView
android:id="@+id/search_suggestion_delete_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_close"
app:layout_constraintBottom_toBottomOf="@id/search_suggestion_icon"

View File

@@ -109,6 +109,7 @@
<string name="menu_search_button">Search</string>
<string name="menu_settings_button">Settings</string>
<string name="player_playback_speed">%1$.2fx</string>
<string name="player_server_priority">Server Priority</string>
<string name="playlist_catalogue_title">Playlist Catalogue</string>
<string name="playlist_catalogue_title_expanded">Browse Playlists</string>
<string name="playlist_chooser_dialog_empty">No playlists created</string>
@@ -170,10 +171,13 @@
<string name="server_unreachable_dialog_summary">The requested server is unavailable. If you choose to continue this dialog will not appear for the next hour.</string>
<string name="settings_about_summary">Tempo is an open source and lightweight music client for Subsonic, designed and built natively for Android.</string>
<string name="settings_about_title">About</string>
<string name="settings_audio_transcode_priority_summary">If enabled, Tempo will not force stream the track with the transcode settings below.</string>
<string name="settings_audio_transcode_priority_title">Prioritize server transcode settings</string>
<string name="settings_audio_transcode_priority_toast">Priority on transcoding of track given to server</string>
<string name="settings_audio_transcode_format_mobile">Transcode format in mobile</string>
<string name="settings_audio_transcode_format_wifi">Transcode format in Wi-Fi</string>
<string name="settings_covers_cache">Size of artwork cache</string>
<string name="settings_data_saving_mode_summary">In order to reduce data consumption, avoid downloading covers</string>
<string name="settings_data_saving_mode_summary">In order to reduce data consumption, avoid downloading covers.</string>
<string name="settings_data_saving_mode_title">Limit mobile data usage</string>
<string name="settings_equalizer_summary">Adjust audio settings</string>
<string name="settings_equalizer_title">Equalizer</string>
@@ -242,7 +246,7 @@
<string name="starred_sync_dialog_title">Sync starred tracks</string>
<string name="undraw_url">https://undraw.co/</string>
<string name="undraw_page">unDraw</string>
<string name="undraw_thanks">A special thanks goes to unDraw without whose illustrations we could not have made this application more beautiful</string>
<string name="undraw_thanks">A special thanks goes to unDraw without whose illustrations we could not have made this application more beautiful.</string>
<string name="home_title_radio_station">Radio stations</string>
<string name="home_title_new_releases">New releases</string>
<string name="home_title_best_of">Best of</string>
@@ -261,6 +265,4 @@
<string name="menu_sort_name">Name</string>
<string name="menu_sort_random">Random</string>
<string name="description_empty_title">No description available</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>

View File

@@ -102,6 +102,12 @@
app:selectable="false"
app:summary="@string/settings_summary_transcoding" />
<SwitchPreference
android:title="@string/settings_audio_transcode_priority_title"
android:defaultValue="false"
android:summary="@string/settings_audio_transcode_priority_summary"
android:key="audio_transcode_priority" />
<ListPreference
app:defaultValue="raw"
app:dialogTitle="@string/settings_audio_transcode_format_wifi"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB