mirror of
https://github.com/badaix/snapcast.git
synced 2025-04-30 10:47:12 +02:00
undo delete client
This commit is contained in:
parent
d014e79ad0
commit
dd020b0b6d
8 changed files with 133 additions and 85 deletions
|
@ -41,10 +41,7 @@ public class ClientInfoItem extends LinearLayout implements SeekBar.OnSeekBarCha
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
if (!clientInfo.getName().isEmpty())
|
title.setText(clientInfo.getVisibleName());
|
||||||
title.setText(clientInfo.getName());
|
|
||||||
else
|
|
||||||
title.setText(clientInfo.getHost());
|
|
||||||
title.setEnabled(clientInfo.isConnected());
|
title.setEnabled(clientInfo.isConnected());
|
||||||
volumeSeekBar.setProgress(clientInfo.getVolume().getPercent());
|
volumeSeekBar.setProgress(clientInfo.getVolume().getPercent());
|
||||||
if (clientInfo.getVolume().isMuted())
|
if (clientInfo.getVolume().isMuted())
|
||||||
|
|
|
@ -5,8 +5,6 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.nsd.NsdManager;
|
import android.net.nsd.NsdManager;
|
||||||
|
@ -14,6 +12,9 @@ import android.net.nsd.NsdServiceInfo;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.support.design.widget.Snackbar;
|
||||||
|
import android.support.design.widget.Snackbar.Callback;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
@ -26,7 +27,6 @@ import android.widget.CheckBox;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.google.android.gms.appindexing.Action;
|
import com.google.android.gms.appindexing.Action;
|
||||||
import com.google.android.gms.appindexing.AppIndex;
|
import com.google.android.gms.appindexing.AppIndex;
|
||||||
|
@ -40,9 +40,6 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
|
|
||||||
private static final String TAG = "Main";
|
private static final String TAG = "Main";
|
||||||
boolean bound = false;
|
boolean bound = false;
|
||||||
private TextView tvInfo;
|
|
||||||
private CheckBox cbScreenWakelock;
|
|
||||||
private ListView lvClient;
|
|
||||||
private MenuItem miStartStop = null;
|
private MenuItem miStartStop = null;
|
||||||
private NsdManager.DiscoveryListener mDiscoveryListener;
|
private NsdManager.DiscoveryListener mDiscoveryListener;
|
||||||
private NsdManager mNsdManager = null;
|
private NsdManager mNsdManager = null;
|
||||||
|
@ -82,8 +79,8 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
tvInfo = (TextView) findViewById(R.id.tvInfo);
|
TextView tvInfo = (TextView) findViewById(R.id.tvInfo);
|
||||||
cbScreenWakelock = (CheckBox) findViewById(R.id.cbScreenWakelock);
|
CheckBox cbScreenWakelock = (CheckBox) findViewById(R.id.cbScreenWakelock);
|
||||||
cbScreenWakelock.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
cbScreenWakelock.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||||
|
@ -94,8 +91,6 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
lvClient = (ListView) findViewById(R.id.lvClient);
|
|
||||||
|
|
||||||
AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
|
AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
String rate = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
|
String rate = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
|
||||||
|
@ -104,6 +99,7 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
}
|
}
|
||||||
|
|
||||||
clientInfoAdapter = new ClientInfoAdapter(this, this);
|
clientInfoAdapter = new ClientInfoAdapter(this, this);
|
||||||
|
ListView lvClient = (ListView) findViewById(R.id.lvClient);
|
||||||
lvClient.setAdapter(clientInfoAdapter);
|
lvClient.setAdapter(clientInfoAdapter);
|
||||||
getSupportActionBar().setSubtitle("Host: no Snapserver found");
|
getSupportActionBar().setSubtitle("Host: no Snapserver found");
|
||||||
|
|
||||||
|
@ -175,6 +171,7 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
i.putExtra(SnapclientService.EXTRA_HOST, host);
|
i.putExtra(SnapclientService.EXTRA_HOST, host);
|
||||||
i.putExtra(SnapclientService.EXTRA_PORT, port);
|
i.putExtra(SnapclientService.EXTRA_PORT, port);
|
||||||
|
i.setAction(SnapclientService.ACTION_START);
|
||||||
|
|
||||||
startService(i);
|
startService(i);
|
||||||
}
|
}
|
||||||
|
@ -209,7 +206,9 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
MainActivity.this.runOnUiThread(new Runnable() {
|
MainActivity.this.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
getSupportActionBar().setSubtitle(text);
|
ActionBar actionBar = getSupportActionBar();
|
||||||
|
if (actionBar != null)
|
||||||
|
actionBar.setSubtitle(text);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -361,9 +360,31 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeleteClicked(ClientInfoItem clientInfoItem) {
|
public void onDeleteClicked(final ClientInfoItem clientInfoItem) {
|
||||||
remoteControl.delete(clientInfoItem.getClientInfo());
|
final ClientInfo clientInfo = clientInfoItem.getClientInfo();
|
||||||
clientInfoAdapter.removeClient(clientInfoItem.getClientInfo());
|
clientInfo.setDeleted(true);
|
||||||
|
clientInfoAdapter.update();
|
||||||
|
Snackbar mySnackbar = Snackbar.make(findViewById(R.id.myCoordinatorLayout),
|
||||||
|
getString(R.string.client_deleted, clientInfo.getVisibleName()),
|
||||||
|
Snackbar.LENGTH_SHORT);
|
||||||
|
mySnackbar.setAction(R.string.undo_string, new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
clientInfo.setDeleted(false);
|
||||||
|
clientInfoAdapter.update();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mySnackbar.setCallback(new Callback() {
|
||||||
|
@Override
|
||||||
|
public void onDismissed(Snackbar snackbar, int event) {
|
||||||
|
super.onDismissed(snackbar, event);
|
||||||
|
if (event != DISMISS_EVENT_ACTION) {
|
||||||
|
remoteControl.delete(clientInfo);
|
||||||
|
clientInfoAdapter.removeClient(clientInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mySnackbar.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -409,7 +430,7 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServerInfo(RemoteControl remoteControl, ServerInfo serverInfo) {
|
public void onServerInfo(RemoteControl remoteControl, ServerInfo serverInfo) {
|
||||||
clientInfoAdapter.update(serverInfo);
|
clientInfoAdapter.updateServer(serverInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ClientInfoAdapter extends ArrayAdapter<ClientInfo> {
|
private class ClientInfoAdapter extends ArrayAdapter<ClientInfo> {
|
||||||
|
@ -440,29 +461,36 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
return clientInfoItem;
|
return clientInfoItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateClient(final ClientInfo clientInfo) {
|
|
||||||
if (serverInfo.addClient(clientInfo))
|
|
||||||
update(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeClient(final ClientInfo clientInfo) {
|
public void removeClient(final ClientInfo clientInfo) {
|
||||||
Log.d(TAG, "removeClient: " + clientInfo.getMac());
|
if ((clientInfo != null) && serverInfo.removeClient(clientInfo)) {
|
||||||
if (serverInfo.removeClient(clientInfo)) {
|
|
||||||
Log.d(TAG, "removeClient 1: " + clientInfo.getMac());
|
Log.d(TAG, "removeClient 1: " + clientInfo.getMac());
|
||||||
update(null);
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(final ServerInfo serverInfo) {
|
public void updateClient(final ClientInfo clientInfo) {
|
||||||
if (serverInfo != null)
|
Log.d(TAG, "updateClient: " + clientInfo.getHost() + " " + clientInfo.isDeleted());
|
||||||
|
if (serverInfo.updateClient(clientInfo)) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateServer(final ServerInfo serverInfo) {
|
||||||
|
if (serverInfo != null) {
|
||||||
ClientInfoAdapter.this.serverInfo = serverInfo;
|
ClientInfoAdapter.this.serverInfo = serverInfo;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
|
||||||
MainActivity.this.runOnUiThread(new Runnable() {
|
MainActivity.this.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
clear();
|
clear();
|
||||||
for (ClientInfo clientInfo : ClientInfoAdapter.this.serverInfo.getClientInfos()) {
|
for (ClientInfo clientInfo : ClientInfoAdapter.this.serverInfo.getClientInfos()) {
|
||||||
if ((clientInfo != null) && (!hideOffline || clientInfo.isConnected()))
|
if ((clientInfo != null) && (!hideOffline || clientInfo.isConnected()) && !clientInfo.isDeleted())
|
||||||
add(clientInfo);
|
add(clientInfo);
|
||||||
}
|
}
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
|
@ -478,7 +506,7 @@ public class MainActivity extends AppCompatActivity implements ClientInfoItem.Cl
|
||||||
if (this.hideOffline == hideOffline)
|
if (this.hideOffline == hideOffline)
|
||||||
return;
|
return;
|
||||||
this.hideOffline = hideOffline;
|
this.hideOffline = hideOffline;
|
||||||
update(null);
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -32,6 +31,8 @@ public class SnapclientService extends Service {
|
||||||
|
|
||||||
public static final String EXTRA_HOST = "EXTRA_HOST";
|
public static final String EXTRA_HOST = "EXTRA_HOST";
|
||||||
public static final String EXTRA_PORT = "EXTRA_PORT";
|
public static final String EXTRA_PORT = "EXTRA_PORT";
|
||||||
|
public static final String ACTION_START = "ACTION_START";
|
||||||
|
public static final String ACTION_STOP = "ACTION_STOP";
|
||||||
private final IBinder mBinder = new LocalBinder();
|
private final IBinder mBinder = new LocalBinder();
|
||||||
private java.lang.Process process = null;
|
private java.lang.Process process = null;
|
||||||
private PowerManager.WakeLock wakeLock = null;
|
private PowerManager.WakeLock wakeLock = null;
|
||||||
|
@ -50,14 +51,15 @@ public class SnapclientService extends Service {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
if (intent.getAction() == "ACTION_STOP") {
|
if (intent == null)
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
|
||||||
|
if (intent.getAction() == ACTION_STOP) {
|
||||||
stopService();
|
stopService();
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
} else if (intent.getAction() == ACTION_START) {
|
||||||
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
|
|
||||||
|
|
||||||
Intent stopIntent = new Intent(this, SnapclientService.class);
|
Intent stopIntent = new Intent(this, SnapclientService.class);
|
||||||
stopIntent.setAction("ACTION_STOP");
|
stopIntent.setAction(ACTION_STOP);
|
||||||
PendingIntent piStop = PendingIntent.getService(this, 0, stopIntent, 0);
|
PendingIntent piStop = PendingIntent.getService(this, 0, stopIntent, 0);
|
||||||
|
|
||||||
NotificationCompat.Builder builder =
|
NotificationCompat.Builder builder =
|
||||||
|
@ -94,14 +96,13 @@ public class SnapclientService extends Service {
|
||||||
// mNotificationManager.notify(123, notification);
|
// mNotificationManager.notify(123, notification);
|
||||||
startForeground(123, notification);
|
startForeground(123, notification);
|
||||||
|
|
||||||
|
|
||||||
String host = intent.getStringExtra(EXTRA_HOST);
|
String host = intent.getStringExtra(EXTRA_HOST);
|
||||||
int port = intent.getIntExtra(EXTRA_PORT, 1704);
|
int port = intent.getIntExtra(EXTRA_PORT, 1704);
|
||||||
start(host, port);
|
start(host, port);
|
||||||
|
|
||||||
// If we get killed, after returning from here, restart
|
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
}
|
}
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
|
|
|
@ -29,6 +29,7 @@ public class ClientInfo implements JsonSerialisable {
|
||||||
private Time_t lastSeen;
|
private Time_t lastSeen;
|
||||||
private boolean connected;
|
private boolean connected;
|
||||||
private int latency = 0;
|
private int latency = 0;
|
||||||
|
private boolean deleted = false;
|
||||||
|
|
||||||
public ClientInfo(JSONObject json) {
|
public ClientInfo(JSONObject json) {
|
||||||
fromJson(json);
|
fromJson(json);
|
||||||
|
@ -114,6 +115,12 @@ public class ClientInfo implements JsonSerialisable {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getVisibleName() {
|
||||||
|
if ((name != null) && !name.isEmpty())
|
||||||
|
return name;
|
||||||
|
return getHost();
|
||||||
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +141,14 @@ public class ClientInfo implements JsonSerialisable {
|
||||||
this.connected = connected;
|
this.connected = connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleted(boolean deleted) {
|
||||||
|
this.deleted = deleted;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ClientInfo{" +
|
return "ClientInfo{" +
|
||||||
|
@ -157,6 +172,7 @@ public class ClientInfo implements JsonSerialisable {
|
||||||
ClientInfo that = (ClientInfo) o;
|
ClientInfo that = (ClientInfo) o;
|
||||||
|
|
||||||
if (connected != that.connected) return false;
|
if (connected != that.connected) return false;
|
||||||
|
if (deleted != that.deleted) return false;
|
||||||
if (latency != that.latency) return false;
|
if (latency != that.latency) return false;
|
||||||
if (mac != null ? !mac.equals(that.mac) : that.mac != null) return false;
|
if (mac != null ? !mac.equals(that.mac) : that.mac != null) return false;
|
||||||
if (ip != null ? !ip.equals(that.ip) : that.ip != null) return false;
|
if (ip != null ? !ip.equals(that.ip) : that.ip != null) return false;
|
||||||
|
@ -176,6 +192,7 @@ public class ClientInfo implements JsonSerialisable {
|
||||||
result = 31 * result + (name != null ? name.hashCode() : 0);
|
result = 31 * result + (name != null ? name.hashCode() : 0);
|
||||||
result = 31 * result + (volume != null ? volume.hashCode() : 0);
|
result = 31 * result + (volume != null ? volume.hashCode() : 0);
|
||||||
result = 31 * result + (connected ? 1 : 0);
|
result = 31 * result + (connected ? 1 : 0);
|
||||||
|
result = 31 * result + (deleted ? 1 : 0);
|
||||||
result = 31 * result + latency;
|
result = 31 * result + latency;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class RemoteControl implements TcpClient.TcpClientListener {
|
||||||
JSONArray clients = json.getJSONObject("result").getJSONArray("clients");
|
JSONArray clients = json.getJSONObject("result").getJSONArray("clients");
|
||||||
for (int i = 0; i < clients.length(); i++) {
|
for (int i = 0; i < clients.length(); i++) {
|
||||||
final ClientInfo clientInfo = new ClientInfo(clients.getJSONObject(i));
|
final ClientInfo clientInfo = new ClientInfo(clients.getJSONObject(i));
|
||||||
serverInfo.addClient(clientInfo);
|
serverInfo.updateClient(clientInfo);
|
||||||
}
|
}
|
||||||
if (listener != null)
|
if (listener != null)
|
||||||
listener.onServerInfo(this, serverInfo);
|
listener.onServerInfo(this, serverInfo);
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class ServerInfo {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addClient(ClientInfo client) {
|
public boolean updateClient(ClientInfo client) {
|
||||||
if (client == null)
|
if (client == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.design.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/myCoordinatorLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
|
||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
|
||||||
tools:context="de.badaix.snapcast.MainActivity">
|
tools:context="de.badaix.snapcast.MainActivity">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -14,7 +12,11 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_centerHorizontal="true">
|
android:layout_centerHorizontal="true"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingTop="@dimen/activity_vertical_margin">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -48,4 +50,5 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
|
|
@ -26,5 +26,7 @@
|
||||||
<string name="client_latency">Latency</string>
|
<string name="client_latency">Latency</string>
|
||||||
<string name="online">online</string>
|
<string name="online">online</string>
|
||||||
<string name="action_play_stop">Play/Stop</string>
|
<string name="action_play_stop">Play/Stop</string>
|
||||||
|
<string name="client_deleted">Client %1$s deleted</string>
|
||||||
|
<string name="undo_string">undo</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue