LyricsDialog displays lyrics without timestamps
Refactoring
This commit is contained in:
parent
3122923d5f
commit
c047ea96a7
7 changed files with 142 additions and 112 deletions
|
|
@ -2,22 +2,21 @@ package com.kabouzeid.gramophone.dialogs;
|
|||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.kabouzeid.gramophone.model.lyrics.Lyrics;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public class LyricsDialog extends DialogFragment {
|
||||
|
||||
public static LyricsDialog create(@NonNull LyricInfo lyricInfo) {
|
||||
public static LyricsDialog create(@NonNull Lyrics lyrics) {
|
||||
LyricsDialog dialog = new LyricsDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable("LyricInfo", lyricInfo);
|
||||
args.putString("title", lyrics.song.title);
|
||||
args.putString("lyrics", lyrics.getText());
|
||||
dialog.setArguments(args);
|
||||
return dialog;
|
||||
}
|
||||
|
|
@ -25,49 +24,10 @@ public class LyricsDialog extends DialogFragment {
|
|||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
LyricInfo lyricInfo = getArguments().getParcelable("LyricInfo");
|
||||
//noinspection ConstantConditions
|
||||
return new MaterialDialog.Builder(getActivity())
|
||||
.title(lyricInfo.title)
|
||||
.content(lyricInfo.lyrics)
|
||||
.title(getArguments().getString("title"))
|
||||
.content(getArguments().getString("lyrics"))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static class LyricInfo implements Parcelable {
|
||||
public final String title;
|
||||
public final String lyrics;
|
||||
|
||||
public LyricInfo(String title, String lyrics) {
|
||||
this.title = title;
|
||||
this.lyrics = lyrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(this.title);
|
||||
dest.writeString(this.lyrics);
|
||||
}
|
||||
|
||||
protected LyricInfo(Parcel in) {
|
||||
this.title = in.readString();
|
||||
this.lyrics = in.readString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<LyricInfo> CREATOR = new Parcelable.Creator<LyricInfo>() {
|
||||
@Override
|
||||
public LyricInfo createFromParcel(Parcel source) {
|
||||
return new LyricInfo(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LyricInfo[] newArray(int size) {
|
||||
return new LyricInfo[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,29 +2,16 @@ package com.kabouzeid.gramophone.model.lyrics;
|
|||
|
||||
import android.util.SparseArray;
|
||||
|
||||
public abstract class AbsSynchronizedLyrics {
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
|
||||
public abstract class AbsSynchronizedLyrics extends Lyrics {
|
||||
private static final int TIME_OFFSET_MS = 500; // time adjustment to display line before it actually starts
|
||||
|
||||
public final SparseArray<String> lines = new SparseArray<>();
|
||||
public boolean isValid = false;
|
||||
public int offset = 0;
|
||||
|
||||
/**
|
||||
* @param data Lyrics string
|
||||
* @param justCheck Set isValid = true and stop parsing if lyrics appears to be valid
|
||||
* and has at least 1 line
|
||||
*/
|
||||
public static AbsSynchronizedLyrics parse(String data, boolean justCheck) {
|
||||
return new SynchronizedLyricsLRC(data, justCheck); // no another formats at the moment
|
||||
}
|
||||
|
||||
public static AbsSynchronizedLyrics parse(String data) {
|
||||
return parse(data, false);
|
||||
}
|
||||
|
||||
public static boolean isSynchronized(String data) {
|
||||
AbsSynchronizedLyrics lyrics = parse(data, true);
|
||||
return lyrics.isValid;
|
||||
AbsSynchronizedLyrics(Song song, String data) {
|
||||
super(song, data);
|
||||
}
|
||||
|
||||
public String getLine(int time) {
|
||||
|
|
@ -44,4 +31,31 @@ public abstract class AbsSynchronizedLyrics {
|
|||
|
||||
return lines.get(lastLineTime);
|
||||
}
|
||||
|
||||
public boolean isSynchronized() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
this.parse(true);
|
||||
return this.valid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
if (isValid()) {
|
||||
parse(false);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
String line = lines.valueAt(i);
|
||||
sb.append(line).append('\n');
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
return super.getText();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
package com.kabouzeid.gramophone.model.lyrics;
|
||||
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
|
||||
public class Lyrics {
|
||||
public Song song;
|
||||
public String data;
|
||||
|
||||
boolean parsed = false;
|
||||
boolean valid = false;
|
||||
|
||||
public Lyrics(Song song, String data) {
|
||||
this.song = song;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static Lyrics parse(Song song, String data) {
|
||||
Lyrics lyrics = new SynchronizedLyricsLRC(song, data);
|
||||
if (lyrics.isValid()) {
|
||||
return lyrics.parse(false);
|
||||
} else {
|
||||
return new Lyrics(song, data).parse(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSynchronized(String data) {
|
||||
Lyrics lyrics = new SynchronizedLyricsLRC(null, data);
|
||||
return lyrics.isValid();
|
||||
}
|
||||
|
||||
public Lyrics parse(boolean check) {
|
||||
this.valid = true;
|
||||
this.parsed = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSynchronized() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
this.parse(true);
|
||||
return this.valid;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return this.data;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
package com.kabouzeid.gramophone.model.lyrics;
|
||||
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SynchronizedLyricsLRC extends AbsSynchronizedLyrics {
|
||||
class SynchronizedLyricsLRC extends AbsSynchronizedLyrics {
|
||||
private static final Pattern LRC_LINE_PATTERN = Pattern.compile("((?:\\[.*?\\])+)(.*)");
|
||||
private static final Pattern LRC_TIME_PATTERN = Pattern.compile("\\[(\\d+):(\\d{2}(?:\\.\\d+)?)\\]");
|
||||
private static final Pattern LRC_ATTRIBUTE_PATTERN = Pattern.compile("\\[(\\D+):(.+)\\]");
|
||||
|
|
@ -11,17 +13,17 @@ public class SynchronizedLyricsLRC extends AbsSynchronizedLyrics {
|
|||
private static final float LRC_SECONDS_TO_MS_MULTIPLIER = 1000f;
|
||||
private static final int LRC_MINUTES_TO_MS_MULTIPLIER = 60000;
|
||||
|
||||
/**
|
||||
* @param data Lyrics string
|
||||
* @param justCheck Set isValid = true and stop parsing if lyrics appears to be valid
|
||||
* and has at least 1 line
|
||||
*/
|
||||
public SynchronizedLyricsLRC(String data, boolean justCheck) {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return;
|
||||
SynchronizedLyricsLRC(Song song, String data) {
|
||||
super(song, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SynchronizedLyricsLRC parse(boolean check) {
|
||||
if (this.parsed || this.data == null || this.data.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
String[] lines = data.split("\r?\n");
|
||||
String[] lines = this.data.split("\r?\n");
|
||||
|
||||
for (String line : lines) {
|
||||
line = line.trim();
|
||||
|
|
@ -60,14 +62,17 @@ public class SynchronizedLyricsLRC extends AbsSynchronizedLyrics {
|
|||
}
|
||||
int ms = (int) (s * LRC_SECONDS_TO_MS_MULTIPLIER) + m * LRC_MINUTES_TO_MS_MULTIPLIER;
|
||||
|
||||
this.isValid = true;
|
||||
if (justCheck) return;
|
||||
this.valid = true;
|
||||
if (check) return this;
|
||||
|
||||
this.lines.append(ms, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.parsed = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
|||
import com.kabouzeid.gramophone.helper.MusicProgressViewUpdateHelper;
|
||||
import com.kabouzeid.gramophone.misc.SimpleAnimatorListener;
|
||||
import com.kabouzeid.gramophone.model.lyrics.AbsSynchronizedLyrics;
|
||||
import com.kabouzeid.gramophone.model.lyrics.Lyrics;
|
||||
import com.kabouzeid.gramophone.ui.fragments.AbsMusicServiceFragment;
|
||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||
|
|
@ -42,7 +43,7 @@ public class PlayerAlbumCoverFragment extends AbsMusicServiceFragment implements
|
|||
ImageView favoriteIcon;
|
||||
|
||||
@BindView(R.id.player_lyrics)
|
||||
FrameLayout lyrics;
|
||||
FrameLayout lyricsLayout;
|
||||
@BindView(R.id.player_lyrics_line1)
|
||||
TextView lyricsLine1;
|
||||
@BindView(R.id.player_lyrics_line2)
|
||||
|
|
@ -51,7 +52,7 @@ public class PlayerAlbumCoverFragment extends AbsMusicServiceFragment implements
|
|||
private Callbacks callbacks;
|
||||
private int currentPosition;
|
||||
|
||||
private AbsSynchronizedLyrics synchronizedLyrics;
|
||||
private Lyrics lyrics;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@Override
|
||||
|
|
@ -181,18 +182,18 @@ public class PlayerAlbumCoverFragment extends AbsMusicServiceFragment implements
|
|||
.start();
|
||||
}
|
||||
|
||||
public void setSynchronizedLyrics(AbsSynchronizedLyrics sLyrics) {
|
||||
if (sLyrics == null || sLyrics.lines.size() == 0) {
|
||||
synchronizedLyrics = null;
|
||||
lyrics.setVisibility(View.GONE);
|
||||
public void setLyrics(Lyrics l) {
|
||||
if (l == null || !l.isSynchronized() || !l.isValid()) {
|
||||
lyrics = null;
|
||||
lyricsLayout.setVisibility(View.GONE);
|
||||
lyricsLine1.setText(null);
|
||||
lyricsLine2.setText(null);
|
||||
return;
|
||||
}
|
||||
|
||||
synchronizedLyrics = sLyrics;
|
||||
lyrics = l;
|
||||
|
||||
lyrics.setVisibility(View.VISIBLE);
|
||||
lyricsLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void notifyColorChange(int color) {
|
||||
|
|
@ -205,14 +206,17 @@ public class PlayerAlbumCoverFragment extends AbsMusicServiceFragment implements
|
|||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
if (synchronizedLyrics == null || synchronizedLyrics.lines.size() == 0 || !PreferenceUtil.getInstance(getActivity()).synchronizedLyricsShow()) {
|
||||
lyrics.setVisibility(View.GONE);
|
||||
if (lyrics == null || !lyrics.isSynchronized() || !lyrics.isValid() || !PreferenceUtil.getInstance(getActivity()).synchronizedLyricsShow()) {
|
||||
lyricsLayout.setVisibility(View.GONE);
|
||||
lyricsLine1.setText(null);
|
||||
lyricsLine2.setText(null);
|
||||
return;
|
||||
}
|
||||
|
||||
lyrics.setVisibility(View.VISIBLE);
|
||||
if (!(lyrics instanceof AbsSynchronizedLyrics)) return;
|
||||
AbsSynchronizedLyrics synchronizedLyrics = (AbsSynchronizedLyrics) lyrics;
|
||||
|
||||
lyricsLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
String oldLine = lyricsLine2.getText().toString();
|
||||
String line = synchronizedLyrics.getLine(progress);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import com.kabouzeid.gramophone.dialogs.SongShareDialog;
|
|||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.helper.menu.SongMenuHelper;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.model.lyrics.AbsSynchronizedLyrics;
|
||||
import com.kabouzeid.gramophone.model.lyrics.Lyrics;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import com.kabouzeid.gramophone.ui.fragments.player.AbsPlayerFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
|
|
@ -89,7 +89,7 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
private AsyncTask updateIsFavoriteTask;
|
||||
private AsyncTask updateLyricsAsyncTask;
|
||||
|
||||
private LyricsDialog.LyricInfo lyricsInfo;
|
||||
private Lyrics lyrics;
|
||||
|
||||
private Impl impl;
|
||||
|
||||
|
|
@ -236,8 +236,8 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_show_lyrics:
|
||||
if (lyricsInfo != null)
|
||||
LyricsDialog.create(lyricsInfo).show(getFragmentManager(), "LYRICS");
|
||||
if (lyrics != null)
|
||||
LyricsDialog.create(lyrics).show(getFragmentManager(), "LYRICS");
|
||||
return true;
|
||||
}
|
||||
return super.onMenuItemClick(item);
|
||||
|
|
@ -304,8 +304,8 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
lyricsInfo = null;
|
||||
playerAlbumCoverFragment.setSynchronizedLyrics(null);
|
||||
lyrics = null;
|
||||
playerAlbumCoverFragment.setLyrics(null);
|
||||
toolbar.getMenu().removeItem(R.id.action_show_lyrics);
|
||||
}
|
||||
|
||||
|
|
@ -315,16 +315,15 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String lyrics) {
|
||||
super.onPostExecute(lyrics);
|
||||
if (TextUtils.isEmpty(lyrics)) {
|
||||
lyricsInfo = null;
|
||||
protected void onPostExecute(String data) {
|
||||
if (TextUtils.isEmpty(data)) {
|
||||
lyrics = null;
|
||||
if (toolbar != null) {
|
||||
toolbar.getMenu().removeItem(R.id.action_show_lyrics);
|
||||
}
|
||||
} else {
|
||||
lyricsInfo = new LyricsDialog.LyricInfo(song.title, lyrics);
|
||||
playerAlbumCoverFragment.setSynchronizedLyrics(AbsSynchronizedLyrics.parse(lyrics));
|
||||
lyrics = Lyrics.parse(song, data);
|
||||
playerAlbumCoverFragment.setLyrics(lyrics);
|
||||
Activity activity = getActivity();
|
||||
if (toolbar != null && activity != null)
|
||||
if (toolbar.getMenu().findItem(R.id.action_show_lyrics) == null) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import com.kabouzeid.gramophone.dialogs.SongShareDialog;
|
|||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||
import com.kabouzeid.gramophone.helper.menu.SongMenuHelper;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.model.lyrics.AbsSynchronizedLyrics;
|
||||
import com.kabouzeid.gramophone.model.lyrics.Lyrics;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import com.kabouzeid.gramophone.ui.fragments.player.AbsPlayerFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
|
|
@ -86,7 +86,7 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
private AsyncTask updateIsFavoriteTask;
|
||||
private AsyncTask updateLyricsAsyncTask;
|
||||
|
||||
private LyricsDialog.LyricInfo lyricsInfo;
|
||||
private Lyrics lyrics;
|
||||
|
||||
private Impl impl;
|
||||
|
||||
|
|
@ -232,8 +232,8 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_show_lyrics:
|
||||
if (lyricsInfo != null)
|
||||
LyricsDialog.create(lyricsInfo).show(getFragmentManager(), "LYRICS");
|
||||
if (lyrics != null)
|
||||
LyricsDialog.create(lyrics).show(getFragmentManager(), "LYRICS");
|
||||
return true;
|
||||
}
|
||||
return super.onMenuItemClick(item);
|
||||
|
|
@ -300,8 +300,8 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
lyricsInfo = null;
|
||||
playerAlbumCoverFragment.setSynchronizedLyrics(null);
|
||||
lyrics = null;
|
||||
playerAlbumCoverFragment.setLyrics(null);
|
||||
toolbar.getMenu().removeItem(R.id.action_show_lyrics);
|
||||
}
|
||||
|
||||
|
|
@ -311,16 +311,15 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String lyrics) {
|
||||
super.onPostExecute(lyrics);
|
||||
if (TextUtils.isEmpty(lyrics)) {
|
||||
lyricsInfo = null;
|
||||
protected void onPostExecute(String data) {
|
||||
if (TextUtils.isEmpty(data)) {
|
||||
lyrics = null;
|
||||
if (toolbar != null) {
|
||||
toolbar.getMenu().removeItem(R.id.action_show_lyrics);
|
||||
}
|
||||
} else {
|
||||
lyricsInfo = new LyricsDialog.LyricInfo(song.title, lyrics);
|
||||
playerAlbumCoverFragment.setSynchronizedLyrics(AbsSynchronizedLyrics.parse(lyrics));
|
||||
lyrics = Lyrics.parse(song, data);
|
||||
playerAlbumCoverFragment.setLyrics(lyrics);
|
||||
Activity activity = getActivity();
|
||||
if (toolbar != null && activity != null)
|
||||
if (toolbar.getMenu().findItem(R.id.action_show_lyrics) == null) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue