LyricsDialog displays lyrics without timestamps

Refactoring
This commit is contained in:
tkashkin 2017-07-08 16:29:50 +03:00
commit c047ea96a7
7 changed files with 142 additions and 112 deletions

View file

@ -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];
}
};
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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) {

View file

@ -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) {