diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerLyricsFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerLyricsFragment.java index 5fe15e4f..58e7a7c5 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerLyricsFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/PlayerLyricsFragment.java @@ -50,8 +50,11 @@ public class PlayerLyricsFragment extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { bind = InnerFragmentPlayerLyricsBinding.inflate(inflater, container, false); View view = bind.getRoot(); + playerBottomSheetViewModel = new ViewModelProvider(requireActivity()).get(PlayerBottomSheetViewModel.class); + initOverlay(); + return view; } @@ -93,6 +96,12 @@ public class PlayerLyricsFragment extends Fragment { bind = null; } + private void initOverlay() { + bind.syncLyricsTapButton.setOnClickListener(view -> { + playerBottomSheetViewModel.changeSyncLyricsState(); + }); + } + private void initializeBrowser() { mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync(); } @@ -134,25 +143,31 @@ public class PlayerLyricsFragment extends Fragment { private void setPanelContent(String lyrics, LyricsList lyricsList) { playerBottomSheetViewModel.getLiveDescription().observe(getViewLifecycleOwner(), description -> { if (bind != null) { + bind.nowPlayingSongLyricsSrollView.smoothScrollTo(0, 0); + if (lyrics != null && !lyrics.trim().equals("")) { bind.nowPlayingSongLyricsTextView.setText(MusicUtil.getReadableLyrics(lyrics)); bind.nowPlayingSongLyricsTextView.setVisibility(View.VISIBLE); bind.emptyDescriptionImageView.setVisibility(View.GONE); bind.titleEmptyDescriptionLabel.setVisibility(View.GONE); + bind.syncLyricsTapButton.setVisibility(View.GONE); } else if (lyricsList != null && lyricsList.getStructuredLyrics() != null) { setSyncLirics(lyricsList); bind.nowPlayingSongLyricsTextView.setVisibility(View.VISIBLE); bind.emptyDescriptionImageView.setVisibility(View.GONE); bind.titleEmptyDescriptionLabel.setVisibility(View.GONE); + bind.syncLyricsTapButton.setVisibility(View.VISIBLE); } else if (description != null && !description.trim().equals("")) { bind.nowPlayingSongLyricsTextView.setText(MusicUtil.getReadableLyrics(description)); bind.nowPlayingSongLyricsTextView.setVisibility(View.VISIBLE); bind.emptyDescriptionImageView.setVisibility(View.GONE); bind.titleEmptyDescriptionLabel.setVisibility(View.GONE); + bind.syncLyricsTapButton.setVisibility(View.GONE); } else { bind.nowPlayingSongLyricsTextView.setVisibility(View.GONE); bind.emptyDescriptionImageView.setVisibility(View.VISIBLE); bind.titleEmptyDescriptionLabel.setVisibility(View.VISIBLE); + bind.syncLyricsTapButton.setVisibility(View.GONE); } } }); @@ -228,6 +243,10 @@ public class PlayerLyricsFragment extends Fragment { spannableString.setSpan(new ForegroundColorSpan(requireContext().getResources().getColor(R.color.lyricsTextColor, null)), startingPosition, endingPosition, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); bind.nowPlayingSongLyricsTextView.setText(spannableString); + + if (playerBottomSheetViewModel.getSyncLyricsState()) { + bind.nowPlayingSongLyricsSrollView.smoothScrollTo(0, getScroll(lines, toHighlight)); + } } } } @@ -245,4 +264,27 @@ public class PlayerLyricsFragment extends Fragment { return start; } + + private int getLineCount(List lines, Line toHighlight) { + int start = 0; + + for (Line line : lines) { + if (line != toHighlight) { + bind.tempLyricsLineTextView.setText(line.getValue()); + start = start + bind.tempLyricsLineTextView.getLineCount(); + } else { + break; + } + } + + return start; + } + + private int getScroll(List lines, Line toHighlight) { + int lineHeight = bind.nowPlayingSongLyricsTextView.getLineHeight(); + int lineCount = getLineCount(lines, toHighlight); + int scrollViewHeight = bind.nowPlayingSongLyricsSrollView.getHeight(); + + return lineHeight * lineCount < scrollViewHeight / 2 ? 0 : lineHeight * lineCount - scrollViewHeight / 2 + lineHeight; + } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java index b2a7a88f..eb7c7f8f 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java +++ b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/PlayerBottomSheetViewModel.java @@ -50,6 +50,7 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel { private final MutableLiveData liveMedia = new MutableLiveData<>(null); private final MutableLiveData liveArtist = new MutableLiveData<>(null); private final MutableLiveData> instantMix = new MutableLiveData<>(null); + private boolean lyricsSyncState = true; public PlayerBottomSheetViewModel(@NonNull Application application) { @@ -210,4 +211,12 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel { return false; } + + public void changeSyncLyricsState() { + lyricsSyncState = !lyricsSyncState; + } + + public boolean getSyncLyricsState() { + return lyricsSyncState; + } } diff --git a/app/src/main/res/drawable/ic_lyrics_sync_lock.xml b/app/src/main/res/drawable/ic_lyrics_sync_lock.xml new file mode 100644 index 00000000..5576242d --- /dev/null +++ b/app/src/main/res/drawable/ic_lyrics_sync_lock.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/inner_fragment_player_lyrics.xml b/app/src/main/res/layout/inner_fragment_player_lyrics.xml index dbad7863..f9b5ba48 100644 --- a/app/src/main/res/layout/inner_fragment_player_lyrics.xml +++ b/app/src/main/res/layout/inner_fragment_player_lyrics.xml @@ -50,4 +50,32 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + +