Files
plexamp-lite/src/com/minamp/NowPlayingActivity.java
T
xockoandClaude Opus 5.5 fa67e95fde Minamp 1.5: Galician interface
- Interface in Galician by default regardless of the phone's language, with
  English selectable under Axustes -> Idioma; switching rebuilds the screens
- All text in tools/strings.py (key -> English, Galician), generating
  res/values/strings.xml (gl) and res/values-en/strings.xml; layouts now use
  string resources
- util/Tr.java: translations for the network and Plex layers, which can't
  read Android resources (falls back to English in desktop tests)
- net/RefusedException: distinguish "server answered but refused" from
  connection failures
- The connection log stays in English for troubleshooting

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 00:11:41 +02:00

231 lines
10 KiB
Java

package com.minamp;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import com.minamp.plex.Item;
public class NowPlayingActivity extends BaseActivity {
private ImageView art;
private TextView title, sub, from, elapsed, remaining, status, sleepText, albumLink;
private SeekBar seek;
private ImageButton playBtn, shuffleBtn, repeatBtn, loveBtn;
private Glyph playGlyph, shuffleGlyph, repeatGlyph, loveGlyph;
private View root;
private boolean dragging;
private String shownThumb;
private int white, dim, accent;
@Override
protected void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.activity_now_playing);
white = getResources().getColor(R.color.text);
dim = 0x99FFFFFF;
accent = getResources().getColor(R.color.accent);
root = findViewById(R.id.np_root);
art = (ImageView) findViewById(R.id.np_art);
title = (TextView) findViewById(R.id.np_title);
sub = (TextView) findViewById(R.id.np_sub);
from = (TextView) findViewById(R.id.np_from);
elapsed = (TextView) findViewById(R.id.np_elapsed);
remaining = (TextView) findViewById(R.id.np_remaining);
status = (TextView) findViewById(R.id.np_status);
sleepText = (TextView) findViewById(R.id.np_sleep_text);
albumLink = (TextView) findViewById(R.id.np_artist_link);
seek = (SeekBar) findViewById(R.id.np_seek);
playBtn = (ImageButton) findViewById(R.id.np_play);
shuffleBtn = (ImageButton) findViewById(R.id.np_shuffle);
repeatBtn = (ImageButton) findViewById(R.id.np_repeat);
loveBtn = (ImageButton) findViewById(R.id.np_love);
ImageButton down = (ImageButton) findViewById(R.id.np_down);
Ui.icon(down, Glyph.BACK, white);
down.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { finish(); } });
ImageButton queue = (ImageButton) findViewById(R.id.np_queue);
Ui.icon(queue, Glyph.QUEUE, white);
queue.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { startActivity(new Intent(NowPlayingActivity.this, QueueActivity.class)); }
});
playGlyph = Ui.glyph(this, Glyph.PLAY, getResources().getColor(R.color.on_accent), 24);
playGlyph.scale(1f);
playBtn.setImageDrawable(playGlyph);
playBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { PlayerService.send(NowPlayingActivity.this, PlayerService.ACTION_TOGGLE); }
});
ImageButton prev = (ImageButton) findViewById(R.id.np_prev);
ImageButton next = (ImageButton) findViewById(R.id.np_next);
Ui.icon(prev, Glyph.PREV, white, 22);
Ui.icon(next, Glyph.NEXT, white, 22);
prev.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { PlayerService.send(NowPlayingActivity.this, PlayerService.ACTION_PREV); }
});
next.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { PlayerService.send(NowPlayingActivity.this, PlayerService.ACTION_NEXT); }
});
shuffleGlyph = Ui.glyph(this, Glyph.SHUFFLE, dim, 20); shuffleGlyph.scale(1f);
shuffleBtn.setImageDrawable(shuffleGlyph);
shuffleBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { PlayQueue.get().setShuffle(!PlayQueue.get().shuffle()); }
});
repeatGlyph = Ui.glyph(this, Glyph.REPEAT, dim, 20); repeatGlyph.scale(1f);
repeatBtn.setImageDrawable(repeatGlyph);
repeatBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
PlayQueue.get().cycleRepeat();
int r = PlayQueue.get().repeat();
toast(str(r == PlayQueue.REPEAT_ALL ? R.string.repeat_queue : r == PlayQueue.REPEAT_ONE ? R.string.repeat_track : R.string.repeat_off));
}
});
loveGlyph = Ui.glyph(this, Glyph.HEART_OUTLINE, white, 20); loveGlyph.scale(1f);
loveBtn.setImageDrawable(loveGlyph);
loveBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Item it = PlayQueue.get().current();
if (it != null) toggleLove(it, new Runnable() { public void run() { update(); } });
}
});
Ui.icon((ImageView) findViewById(R.id.np_sleep_icon), Glyph.MOON, 0xB3FFFFFF, 16);
findViewById(R.id.np_sleep).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { sleepDialog(); }
});
albumLink.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Item it = PlayQueue.get().current();
if (it != null && it.albumKey.length() > 0) openKey(it.albumKey, Item.ALBUM, it.album);
}
});
art.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
Item it = PlayQueue.get().current();
if (it != null) itemMenu(it);
return true;
}
});
seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar s, int p, boolean user) {
if (user) {
long d = PlayerService.duration();
elapsed.setText(Ui.time(d * p / 1000));
}
}
public void onStartTrackingTouch(SeekBar s) { dragging = true; }
public void onStopTrackingTouch(SeekBar s) {
dragging = false;
long d = PlayerService.duration();
if (d > 0) PlayerService.seekTo(NowPlayingActivity.this, d * s.getProgress() / 1000);
}
});
setBackdrop(0xFF1D1D22);
}
@Override
protected void onResume() {
super.onResume();
update();
}
@Override
public void onPlayerChanged() { super.onPlayerChanged(); update(); }
@Override
public void onQueueChanged() { super.onQueueChanged(); update(); }
@Override
protected void onTick() { super.onTick(); updateTime(); }
private void update() {
Item it = PlayQueue.get().current();
PlayQueue q = PlayQueue.get();
if (it == null) {
title.setText(R.string.nothing_playing);
sub.setText(R.string.pick_something);
from.setText("");
art.setImageResource(R.drawable.art_placeholder);
shownThumb = null;
return;
}
title.setText(it.title);
sub.setText(it.artist + (it.album.length() > 0 ? " — " + it.album : ""));
from.setText(q.title().length() > 0 ? q.title() : it.album);
playGlyph.setType(PlayerService.isPlaying() ? Glyph.PAUSE : Glyph.PLAY);
shuffleGlyph.setColor(q.shuffle() ? accent : dim);
repeatGlyph.setType(q.repeat() == PlayQueue.REPEAT_ONE ? Glyph.REPEAT_ONE : Glyph.REPEAT);
repeatGlyph.setColor(q.repeat() != PlayQueue.REPEAT_OFF ? accent : dim);
loveGlyph.setType(it.loved() ? Glyph.HEART : Glyph.HEART_OUTLINE);
loveGlyph.setColor(it.loved() ? accent : white);
albumLink.setVisibility(it.albumKey.length() > 0 ? View.VISIBLE : View.INVISIBLE);
albumLink.setText(R.string.album_link);
if (!it.thumb.equals(shownThumb)) {
shownThumb = it.thumb;
final String want = it.thumb;
int size = Math.min(getResources().getDisplayMetrics().widthPixels, 480);
art.setImageResource(R.drawable.art_placeholder);
app.images.load(it.thumb, size, new ImageLoader.Callback() {
public void onBitmap(Bitmap bm) {
if (destroyed || !want.equals(shownThumb)) return;
if (bm != null) { art.setImageBitmap(bm); setBackdrop(Ui.backdropColor(bm)); }
}
});
}
updateSleep();
updateTime();
}
private void updateTime() {
long d = PlayerService.duration();
long p = PlayerService.position();
if (!dragging) {
seek.setProgress(d > 0 ? (int) (p * 1000 / d) : 0);
elapsed.setText(Ui.time(p));
}
remaining.setText("-" + Ui.time(Math.max(0, d - p)));
String st = PlayerService.status();
status.setText(st.length() > 0 ? st : PlayerService.sourceLabel());
if (PlayerService.sleepAt() > 0) updateSleep();
}
private void updateSleep() {
long at = PlayerService.sleepAt();
if (PlayerService.sleepEndOfTrack()) sleepText.setText(R.string.end_of_track);
else if (at > 0) sleepText.setText(Ui.time(at - System.currentTimeMillis()));
else sleepText.setText(R.string.sleep);
}
private void setBackdrop(int color) {
GradientDrawable g = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
new int[] { color, getResources().getColor(R.color.bg) });
root.setBackgroundDrawable(g);
}
private void sleepDialog() {
final int[] mins = {0, 15, 30, 45, 60, 90, -1};
String[] labels = {str(R.string.sleep_off), str(R.string.sleep_15), str(R.string.sleep_30), str(R.string.sleep_45),
str(R.string.sleep_60), str(R.string.sleep_90), str(R.string.sleep_eot)};
new AlertDialog.Builder(this).setTitle(R.string.sleep_timer)
.setItems(labels, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int which) {
startService(new Intent(NowPlayingActivity.this, PlayerService.class)
.setAction(PlayerService.ACTION_SLEEP).putExtra(PlayerService.EXTRA_MINUTES, mins[which]));
app.handler.postDelayed(new Runnable() { public void run() { if (!destroyed) updateSleep(); } }, 300);
}
}).show();
}
}