mirror of
https://github.com/antebudimir/tempus.git
synced 2026-04-15 16:27:26 +00:00
fix: updated song bottom sheet to match album/artist bottom sheets
This commit is contained in:
parent
6110a9c8e7
commit
431014adc4
2 changed files with 102 additions and 25 deletions
|
|
@ -7,6 +7,7 @@ import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
@ -25,6 +26,7 @@ import androidx.navigation.fragment.NavHostFragment;
|
||||||
|
|
||||||
import com.cappielloantonio.tempo.R;
|
import com.cappielloantonio.tempo.R;
|
||||||
import com.cappielloantonio.tempo.glide.CustomGlideRequest;
|
import com.cappielloantonio.tempo.glide.CustomGlideRequest;
|
||||||
|
import com.cappielloantonio.tempo.interfaces.MediaCallback;
|
||||||
import com.cappielloantonio.tempo.model.Download;
|
import com.cappielloantonio.tempo.model.Download;
|
||||||
import com.cappielloantonio.tempo.service.MediaManager;
|
import com.cappielloantonio.tempo.service.MediaManager;
|
||||||
import com.cappielloantonio.tempo.service.MediaService;
|
import com.cappielloantonio.tempo.service.MediaService;
|
||||||
|
|
@ -52,6 +54,7 @@ import com.cappielloantonio.tempo.util.ExternalAudioWriter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public class SongBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener {
|
public class SongBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener {
|
||||||
|
|
@ -69,7 +72,11 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
|
||||||
private AssetLinkUtil.AssetLink currentAlbumLink;
|
private AssetLinkUtil.AssetLink currentAlbumLink;
|
||||||
private AssetLinkUtil.AssetLink currentArtistLink;
|
private AssetLinkUtil.AssetLink currentArtistLink;
|
||||||
|
|
||||||
|
private boolean playbackStarted = false;
|
||||||
|
private boolean dismissalScheduled = false;
|
||||||
|
|
||||||
private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture;
|
private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture;
|
||||||
|
private static final String TAG = "SongBottomSheetDialog";
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -145,37 +152,68 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
|
||||||
|
|
||||||
TextView playRadio = view.findViewById(R.id.play_radio_text_view);
|
TextView playRadio = view.findViewById(R.id.play_radio_text_view);
|
||||||
playRadio.setOnClickListener(v -> {
|
playRadio.setOnClickListener(v -> {
|
||||||
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
playbackStarted = false;
|
||||||
|
dismissalScheduled = false;
|
||||||
|
Toast.makeText(requireContext(), R.string.bottom_sheet_generating_instant_mix, Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
final boolean[] playbackStarted = {false};
|
final Runnable failsafeTimeout = () -> {
|
||||||
|
if (!playbackStarted && !dismissalScheduled) {
|
||||||
songBottomSheetViewModel.getInstantMix(getViewLifecycleOwner(), song).observe(getViewLifecycleOwner(), songs -> {
|
Log.w(TAG, "No response received within 3 seconds");
|
||||||
if (playbackStarted[0] || songs == null || songs.isEmpty()) return;
|
if (isAdded() && getActivity() != null) {
|
||||||
|
Toast.makeText(getContext(),
|
||||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
R.string.bottom_sheet_problem_generating_instant_mix,
|
||||||
if (playbackStarted[0]) return;
|
Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
MusicUtil.ratingFilter(songs);
|
|
||||||
|
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
|
||||||
playbackStarted[0] = true;
|
|
||||||
|
|
||||||
view.postDelayed(() -> {
|
|
||||||
try {
|
|
||||||
if (mediaBrowserListenableFuture.isDone()) {
|
|
||||||
MediaBrowser browser = mediaBrowserListenableFuture.get();
|
|
||||||
if (browser != null && browser.isPlaying()) {
|
|
||||||
dismissBottomSheet();
|
dismissBottomSheet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
view.postDelayed(failsafeTimeout, 3000);
|
||||||
|
songBottomSheetViewModel.getInstantMix(song, 20, new MediaCallback() {
|
||||||
|
@Override
|
||||||
|
public void onError(Exception exception) {
|
||||||
|
view.removeCallbacks(failsafeTimeout);
|
||||||
|
Log.e(TAG, "Error: " + exception.getMessage());
|
||||||
|
if (isAdded() && getActivity() != null) {
|
||||||
|
String message = isOffline(exception) ?
|
||||||
|
"You're offline" : "Network error";
|
||||||
|
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
if (!playbackStarted && !dismissalScheduled) {
|
||||||
|
scheduleDelayedDismissal(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadMedia(List<?> media) {
|
||||||
|
view.removeCallbacks(failsafeTimeout);
|
||||||
|
if (!isAdded() || getActivity() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MusicUtil.ratingFilter((ArrayList<Child>) media);
|
||||||
|
|
||||||
|
if (!media.isEmpty()) {
|
||||||
|
boolean isFirstBatch = !playbackStarted;
|
||||||
|
MediaManager.startQueue(mediaBrowserListenableFuture, (ArrayList<Child>) media, 0);
|
||||||
|
playbackStarted = true;
|
||||||
|
|
||||||
|
if (getActivity() instanceof MainActivity) {
|
||||||
|
((MainActivity) getActivity()).setBottomSheetInPeek(true);
|
||||||
|
}
|
||||||
|
if (isFirstBatch && !dismissalScheduled) {
|
||||||
|
scheduleDelayedDismissal(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getContext(),
|
||||||
|
R.string.bottom_sheet_problem_generating_instant_mix,
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
if (!playbackStarted && !dismissalScheduled) {
|
||||||
|
scheduleDelayedDismissal(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
}
|
||||||
view.postDelayed(() -> dismissBottomSheet(), 200);
|
|
||||||
}, 300);
|
|
||||||
}, 300);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
TextView playNext = view.findViewById(R.id.play_next_text_view);
|
TextView playNext = view.findViewById(R.id.play_next_text_view);
|
||||||
|
|
@ -414,4 +452,31 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
|
||||||
private void refreshShares() {
|
private void refreshShares() {
|
||||||
homeViewModel.refreshShares(requireActivity());
|
homeViewModel.refreshShares(requireActivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void scheduleDelayedDismissal(View view) {
|
||||||
|
if (dismissalScheduled) return;
|
||||||
|
dismissalScheduled = true;
|
||||||
|
|
||||||
|
view.postDelayed(() -> {
|
||||||
|
try {
|
||||||
|
if (mediaBrowserListenableFuture.isDone()) {
|
||||||
|
MediaBrowser browser = mediaBrowserListenableFuture.get();
|
||||||
|
if (browser != null && browser.isPlaying()) {
|
||||||
|
dismissBottomSheet();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Error checking playback: " + e.getMessage());
|
||||||
|
}
|
||||||
|
view.postDelayed(() -> dismissBottomSheet(), 200);
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOffline(Exception exception) {
|
||||||
|
return exception != null && exception.getMessage() != null &&
|
||||||
|
(exception.getMessage().contains("Network") ||
|
||||||
|
exception.getMessage().contains("timeout") ||
|
||||||
|
exception.getMessage().contains("offline"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
|
||||||
|
import com.cappielloantonio.tempo.interfaces.MediaCallback;
|
||||||
import com.cappielloantonio.tempo.interfaces.StarCallback;
|
import com.cappielloantonio.tempo.interfaces.StarCallback;
|
||||||
import com.cappielloantonio.tempo.model.Download;
|
import com.cappielloantonio.tempo.model.Download;
|
||||||
import com.cappielloantonio.tempo.repository.AlbumRepository;
|
import com.cappielloantonio.tempo.repository.AlbumRepository;
|
||||||
|
|
@ -134,6 +135,17 @@ public class SongBottomSheetViewModel extends AndroidViewModel {
|
||||||
return instantMix;
|
return instantMix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getInstantMix(Child media, int count, MediaCallback callback) {
|
||||||
|
|
||||||
|
songRepository.getInstantMix(media.getId(), SeedType.TRACK, count, songs -> {
|
||||||
|
if (songs != null && !songs.isEmpty()) {
|
||||||
|
callback.onLoadMedia(songs);
|
||||||
|
} else {
|
||||||
|
callback.onLoadMedia(Collections.emptyList());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public MutableLiveData<Share> shareTrack() {
|
public MutableLiveData<Share> shareTrack() {
|
||||||
return sharingRepository.createShare(song.getId(), song.getTitle(), null);
|
return sharingRepository.createShare(song.getId(), song.getTitle(), null);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue