mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-12 08:36:43 +02:00
Groups: interims commit
This commit is contained in:
parent
22f768311d
commit
0af508f6ee
14 changed files with 555 additions and 328 deletions
|
@ -20,8 +20,8 @@ package de.badaix.snapcast;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.v7.widget.PopupMenu;
|
import android.support.v7.widget.PopupMenu;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
|
@ -36,19 +36,21 @@ import de.badaix.snapcast.control.json.Volume;
|
||||||
|
|
||||||
public class ClientItem extends LinearLayout implements SeekBar.OnSeekBarChangeListener, View.OnClickListener, PopupMenu.OnMenuItemClickListener {
|
public class ClientItem extends LinearLayout implements SeekBar.OnSeekBarChangeListener, View.OnClickListener, PopupMenu.OnMenuItemClickListener {
|
||||||
|
|
||||||
|
private static final String TAG = "ClientItem";
|
||||||
|
|
||||||
private TextView title;
|
private TextView title;
|
||||||
private SeekBar volumeSeekBar;
|
private SeekBar volumeSeekBar;
|
||||||
private ImageButton ibMute;
|
private ImageButton ibMute;
|
||||||
private ImageButton ibOverflow;
|
private ImageButton ibOverflow;
|
||||||
private Client client;
|
private Client client;
|
||||||
private ServerStatus server;
|
private ServerStatus server;
|
||||||
private ClientInfoItemListener listener = null;
|
private ClientItemListener listener = null;
|
||||||
|
|
||||||
public ClientItem(Context context, ServerStatus server, Client client) {
|
public ClientItem(Context context, ServerStatus server, Client client) {
|
||||||
super(context);
|
super(context);
|
||||||
LayoutInflater vi = (LayoutInflater) context
|
LayoutInflater vi = (LayoutInflater) context
|
||||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
vi.inflate(R.layout.client_info, this);
|
vi.inflate(R.layout.client_item, this);
|
||||||
title = (TextView) findViewById(R.id.title);
|
title = (TextView) findViewById(R.id.title);
|
||||||
volumeSeekBar = (SeekBar) findViewById(R.id.volumeSeekBar);
|
volumeSeekBar = (SeekBar) findViewById(R.id.volumeSeekBar);
|
||||||
ibMute = (ImageButton) findViewById(R.id.ibMute);
|
ibMute = (ImageButton) findViewById(R.id.ibMute);
|
||||||
|
@ -59,9 +61,11 @@ public class ClientItem extends LinearLayout implements SeekBar.OnSeekBarChangeL
|
||||||
setClient(client);
|
setClient(client);
|
||||||
volumeSeekBar.setOnSeekBarChangeListener(this);
|
volumeSeekBar.setOnSeekBarChangeListener(this);
|
||||||
this.server = server;
|
this.server = server;
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
|
Log.d(TAG, "update: " + client.getVisibleName() + ", connected: " + client.isConnected());
|
||||||
title.setText(client.getVisibleName());
|
title.setText(client.getVisibleName());
|
||||||
title.setEnabled(client.isConnected());
|
title.setEnabled(client.isConnected());
|
||||||
volumeSeekBar.setProgress(client.getConfig().getVolume().getPercent());
|
volumeSeekBar.setProgress(client.getConfig().getVolume().getPercent());
|
||||||
|
@ -80,7 +84,7 @@ public class ClientItem extends LinearLayout implements SeekBar.OnSeekBarChangeL
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setListener(ClientInfoItemListener listener) {
|
public void setListener(ClientItemListener listener) {
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +99,7 @@ public class ClientItem extends LinearLayout implements SeekBar.OnSeekBarChangeL
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (v == ibMute) {
|
/* TODO: group if (v == ibMute) {
|
||||||
Volume volume = client.getConfig().getVolume();
|
Volume volume = client.getConfig().getVolume();
|
||||||
volume.setMuted(!volume.isMuted());
|
volume.setMuted(!volume.isMuted());
|
||||||
update();
|
update();
|
||||||
|
@ -125,6 +129,7 @@ public class ClientItem extends LinearLayout implements SeekBar.OnSeekBarChangeL
|
||||||
popup.setOnMenuItemClickListener(this);
|
popup.setOnMenuItemClickListener(this);
|
||||||
popup.show();
|
popup.show();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -151,7 +156,7 @@ public class ClientItem extends LinearLayout implements SeekBar.OnSeekBarChangeL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ClientInfoItemListener {
|
public interface ClientItemListener {
|
||||||
void onVolumeChanged(ClientItem clientItem, int percent);
|
void onVolumeChanged(ClientItem clientItem, int percent);
|
||||||
|
|
||||||
void onMute(ClientItem clientItem, boolean mute);
|
void onMute(ClientItem clientItem, boolean mute);
|
||||||
|
@ -159,8 +164,6 @@ public class ClientItem extends LinearLayout implements SeekBar.OnSeekBarChangeL
|
||||||
void onDeleteClicked(ClientItem clientItem);
|
void onDeleteClicked(ClientItem clientItem);
|
||||||
|
|
||||||
void onPropertiesClicked(ClientItem clientItem);
|
void onPropertiesClicked(ClientItem clientItem);
|
||||||
|
|
||||||
void onStreamClicked(ClientItem clientItem, Stream stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,17 +27,15 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import de.badaix.snapcast.control.json.Client;
|
import de.badaix.snapcast.control.json.Group;
|
||||||
import de.badaix.snapcast.control.json.ServerStatus;
|
import de.badaix.snapcast.control.json.ServerStatus;
|
||||||
import de.badaix.snapcast.control.json.Stream;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* A simple {@link Fragment} subclass.
|
||||||
* Activities that contain this fragment must implement the
|
* Activities that contain this fragment must implement the
|
||||||
* {@link ClientItem.ClientInfoItemListener} interface
|
* {@link GroupItem.GroupItemListener} interface
|
||||||
* to handle interaction events.
|
* to handle interaction events.
|
||||||
*/
|
*/
|
||||||
public class ClientListFragment extends Fragment {
|
public class ClientListFragment extends Fragment {
|
||||||
|
@ -49,14 +47,10 @@ public class ClientListFragment extends Fragment {
|
||||||
private static final String ARG_PARAM1 = "param1";
|
private static final String ARG_PARAM1 = "param1";
|
||||||
private static final String ARG_PARAM2 = "param2";
|
private static final String ARG_PARAM2 = "param2";
|
||||||
|
|
||||||
// TODO: Rename and change types of parameters
|
private GroupItem.GroupItemListener groupItemListener;
|
||||||
private Stream stream;
|
private GroupAdapter groupAdapter;
|
||||||
|
|
||||||
private ClientItem.ClientInfoItemListener clientInfoItemListener;
|
|
||||||
private ClientInfoAdapter clientInfoAdapter;
|
|
||||||
private ServerStatus serverStatus = null;
|
private ServerStatus serverStatus = null;
|
||||||
private boolean hideOffline = false;
|
private boolean hideOffline = false;
|
||||||
private TextView tvStreamState = null;
|
|
||||||
|
|
||||||
public ClientListFragment() {
|
public ClientListFragment() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
|
@ -93,35 +87,27 @@ public class ClientListFragment extends Fragment {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
Log.d(TAG, "onCreateView: " + this.toString());
|
Log.d(TAG, "onCreateView: " + this.toString());
|
||||||
View view = inflater.inflate(R.layout.fragment_client_list, container, false);
|
View view = inflater.inflate(R.layout.fragment_client_list, container, false);
|
||||||
tvStreamState = (TextView) view.findViewById(R.id.tvStreamState);
|
ListView lvGroup = (ListView) view.findViewById(R.id.lvGroup);
|
||||||
ListView lvClient = (ListView) view.findViewById(R.id.lvClient);
|
groupAdapter = new GroupAdapter(getContext(), groupItemListener);
|
||||||
clientInfoAdapter = new ClientInfoAdapter(getContext(), clientInfoItemListener);
|
groupAdapter.setHideOffline(hideOffline);
|
||||||
clientInfoAdapter.setHideOffline(hideOffline);
|
groupAdapter.updateServer(serverStatus);
|
||||||
clientInfoAdapter.updateServer(serverStatus);
|
lvGroup.setAdapter(groupAdapter);
|
||||||
lvClient.setAdapter(clientInfoAdapter);
|
|
||||||
updateGui();
|
updateGui();
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void updateGui() {
|
private void updateGui() {
|
||||||
Log.d(TAG, "(tvStreamState == null): " + (tvStreamState == null) + " " + this.toString());
|
|
||||||
if ((tvStreamState == null) || (stream == null))
|
|
||||||
return;
|
|
||||||
String codec = stream.getUri().getQuery().get("codec");
|
|
||||||
if (codec.contains(":"))
|
|
||||||
codec = codec.split(":")[0];
|
|
||||||
tvStreamState.setText(stream.getUri().getQuery().get("sampleformat") + " - " + codec + " - " + stream.getStatus().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
if (context instanceof ClientItem.ClientInfoItemListener) {
|
if (context instanceof GroupItem.GroupItemListener) {
|
||||||
clientInfoItemListener = (ClientItem.ClientInfoItemListener) context;
|
groupItemListener = (GroupItem.GroupItemListener) context;
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException(context.toString()
|
throw new RuntimeException(context.toString()
|
||||||
+ " must implement ClientInfoItemListener");
|
+ " must implement GroupItemListener");
|
||||||
}
|
}
|
||||||
updateGui();
|
updateGui();
|
||||||
}
|
}
|
||||||
|
@ -129,39 +115,28 @@ public class ClientListFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public void onDetach() {
|
public void onDetach() {
|
||||||
super.onDetach();
|
super.onDetach();
|
||||||
clientInfoItemListener = null;
|
groupItemListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateServer(ServerStatus serverStatus) {
|
public void updateServer(ServerStatus serverStatus) {
|
||||||
this.serverStatus = serverStatus;
|
this.serverStatus = serverStatus;
|
||||||
if (clientInfoAdapter != null)
|
if (groupAdapter != null)
|
||||||
clientInfoAdapter.updateServer(this.serverStatus);
|
groupAdapter.updateServer(this.serverStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHideOffline(boolean hide) {
|
public void setHideOffline(boolean hide) {
|
||||||
this.hideOffline = hide;
|
this.hideOffline = hide;
|
||||||
if (clientInfoAdapter != null)
|
if (groupAdapter != null)
|
||||||
clientInfoAdapter.setHideOffline(hideOffline);
|
groupAdapter.setHideOffline(hideOffline);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public class GroupAdapter extends ArrayAdapter<Group> {
|
||||||
return stream.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStream(Stream stream) {
|
|
||||||
Log.d(TAG, "setStream: " + stream.getName() + ", status: " + stream.getStatus());
|
|
||||||
this.stream = stream;
|
|
||||||
updateGui();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class ClientInfoAdapter extends ArrayAdapter<Client> {
|
|
||||||
private Context context;
|
private Context context;
|
||||||
private ClientItem.ClientInfoItemListener listener;
|
private GroupItem.GroupItemListener listener;
|
||||||
private boolean hideOffline = false;
|
private boolean hideOffline = false;
|
||||||
private ServerStatus serverStatus = new ServerStatus();
|
private ServerStatus serverStatus = new ServerStatus();
|
||||||
|
|
||||||
public ClientInfoAdapter(Context context, ClientItem.ClientInfoItemListener listener) {
|
public GroupAdapter(Context context, GroupItem.GroupItemListener listener) {
|
||||||
super(context, 0);
|
super(context, 0);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
|
@ -169,22 +144,22 @@ public class ClientListFragment extends Fragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
Client client = getItem(position);
|
Group group = getItem(position);
|
||||||
final ClientItem clientItem;
|
final GroupItem groupItem;
|
||||||
|
|
||||||
if (convertView != null) {
|
if (convertView != null) {
|
||||||
clientItem = (ClientItem) convertView;
|
groupItem = (GroupItem) convertView;
|
||||||
clientItem.setClient(client);
|
groupItem.setGroup(group);
|
||||||
} else {
|
} else {
|
||||||
clientItem = new ClientItem(context, serverStatus, client);
|
groupItem = new GroupItem(context, serverStatus, group);
|
||||||
}
|
}
|
||||||
clientItem.setListener(listener);
|
groupItem.setListener(listener);
|
||||||
return clientItem;
|
return groupItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateServer(final ServerStatus serverStatus) {
|
public void updateServer(final ServerStatus serverStatus) {
|
||||||
if (serverStatus != null) {
|
if (serverStatus != null) {
|
||||||
ClientInfoAdapter.this.serverStatus = serverStatus;
|
GroupAdapter.this.serverStatus = serverStatus;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,10 +167,16 @@ public class ClientListFragment extends Fragment {
|
||||||
|
|
||||||
public void update() {
|
public void update() {
|
||||||
clear();
|
clear();
|
||||||
for (Client client : ClientInfoAdapter.this.serverStatus.getClientInfos()) {
|
// TODO: group
|
||||||
if ((client != null) && (!hideOffline || client.isConnected()) && !client.isDeleted() && client.getConfig().getStream().equals(ClientListFragment.this.stream.getId()))
|
for (Group group : GroupAdapter.this.serverStatus.getGroups()) {
|
||||||
|
add(group);
|
||||||
|
/* for (Client client : group.getClients()) {
|
||||||
|
if ((client != null) && (!hideOffline || client.isConnected()) && !client.isDeleted())// && client.getConfig().getStream().equals(ClientListFragment.this.stream.getId()))
|
||||||
add(client);
|
add(client);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
if (getActivity() != null) {
|
if (getActivity() != null) {
|
||||||
ClientListFragment.this.getActivity().runOnUiThread(new Runnable() {
|
ClientListFragment.this.getActivity().runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -94,6 +94,7 @@ public class ClientSettingsFragment extends PreferenceFragment {
|
||||||
prefStream = (ListPreference) findPreference("pref_client_stream");
|
prefStream = (ListPreference) findPreference("pref_client_stream");
|
||||||
prefStream.setEntries(streamNames);
|
prefStream.setEntries(streamNames);
|
||||||
prefStream.setEntryValues(streamIds);
|
prefStream.setEntryValues(streamIds);
|
||||||
|
/* TODO: group
|
||||||
for (int i = 0; i < streams.size(); ++i) {
|
for (int i = 0; i < streams.size(); ++i) {
|
||||||
if (streamIds[i].equals(client.getConfig().getStream())) {
|
if (streamIds[i].equals(client.getConfig().getStream())) {
|
||||||
prefStream.setSummary(streamNames[i]);
|
prefStream.setSummary(streamNames[i]);
|
||||||
|
@ -116,6 +117,7 @@ public class ClientSettingsFragment extends PreferenceFragment {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
prefMac = (Preference) findPreference("pref_client_mac");
|
prefMac = (Preference) findPreference("pref_client_mac");
|
||||||
prefId = (Preference) findPreference("pref_client_id");
|
prefId = (Preference) findPreference("pref_client_id");
|
||||||
prefIp = (Preference) findPreference("pref_client_ip");
|
prefIp = (Preference) findPreference("pref_client_ip");
|
||||||
|
|
237
android/Snapcast/src/main/java/de/badaix/snapcast/GroupItem.java
Normal file
237
android/Snapcast/src/main/java/de/badaix/snapcast/GroupItem.java
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
/*
|
||||||
|
* This file is part of snapcast
|
||||||
|
* Copyright (C) 2014-2016 Johannes Pohl
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.badaix.snapcast;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v7.widget.PopupMenu;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import de.badaix.snapcast.control.json.Client;
|
||||||
|
import de.badaix.snapcast.control.json.Group;
|
||||||
|
import de.badaix.snapcast.control.json.ServerStatus;
|
||||||
|
import de.badaix.snapcast.control.json.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by johannes on 04.12.16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class GroupItem extends LinearLayout implements SeekBar.OnSeekBarChangeListener, View.OnClickListener, PopupMenu.OnMenuItemClickListener, ClientItem.ClientItemListener {
|
||||||
|
|
||||||
|
private static final String TAG = "GroupItem";
|
||||||
|
|
||||||
|
// private TextView title;
|
||||||
|
private SeekBar volumeSeekBar;
|
||||||
|
private ImageButton ibMute;
|
||||||
|
private ImageButton ibOverflow;
|
||||||
|
private LinearLayout llClient;
|
||||||
|
private Group group;
|
||||||
|
private ServerStatus server;
|
||||||
|
private TextView tvStreamState = null;
|
||||||
|
private GroupItemListener listener = null;
|
||||||
|
private Stream stream = null;
|
||||||
|
private LinearLayout llVolume;
|
||||||
|
|
||||||
|
public GroupItem(Context context, ServerStatus server, Group group) {
|
||||||
|
super(context);
|
||||||
|
LayoutInflater vi = (LayoutInflater) context
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
vi.inflate(R.layout.group_item, this);
|
||||||
|
// title = (TextView) findViewById(R.id.title);
|
||||||
|
volumeSeekBar = (SeekBar) findViewById(R.id.volumeSeekBar);
|
||||||
|
ibMute = (ImageButton) findViewById(R.id.ibMute);
|
||||||
|
ibMute.setImageResource(R.drawable.ic_speaker_icon);
|
||||||
|
ibMute.setOnClickListener(this);
|
||||||
|
ibOverflow = (ImageButton) findViewById(R.id.ibOverflow);
|
||||||
|
ibOverflow.setOnClickListener(this);
|
||||||
|
llVolume = (LinearLayout) findViewById(R.id.llVolume);
|
||||||
|
llVolume.setVisibility(GONE);
|
||||||
|
llClient = (LinearLayout) findViewById(R.id.llClient);
|
||||||
|
llClient.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
|
||||||
|
tvStreamState = (TextView) findViewById(R.id.tvStreamState);
|
||||||
|
setGroup(group);
|
||||||
|
volumeSeekBar.setOnSeekBarChangeListener(this);
|
||||||
|
this.server = server;
|
||||||
|
stream = server.getStream(group.getStreamId());
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update() {
|
||||||
|
// title.setText(group.getName());
|
||||||
|
llClient.removeAllViews();
|
||||||
|
for (Client client : group.getClients()) {
|
||||||
|
ClientItem clientItem = new ClientItem(this.getContext(), server, client);
|
||||||
|
clientItem.setListener(this);
|
||||||
|
llClient.addView(clientItem);
|
||||||
|
}
|
||||||
|
Log.d(TAG, "(tvStreamState == null): " + (tvStreamState == null) + " " + this.toString());
|
||||||
|
|
||||||
|
if ((tvStreamState == null) || (stream == null))
|
||||||
|
return;
|
||||||
|
tvStreamState.setText(stream.getName());
|
||||||
|
/* String codec = stream.getUri().getQuery().get("codec");
|
||||||
|
if (codec.contains(":"))
|
||||||
|
codec = codec.split(":")[0];
|
||||||
|
tvStreamState.setText(stream.getUri().getQuery().get("sampleformat") + " - " + codec + " - " + stream.getStatus().toString());
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* title.setEnabled(group.isConnected());
|
||||||
|
volumeSeekBar.setProgress(group.getConfig().getVolume().getPercent());
|
||||||
|
if (client.getConfig().getVolume().isMuted())
|
||||||
|
ibMute.setImageResource(R.drawable.ic_mute_icon);
|
||||||
|
else
|
||||||
|
ibMute.setImageResource(R.drawable.ic_speaker_icon);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public Group getGroup() {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroup(final Group group) {
|
||||||
|
this.group = group;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStream(Stream stream) {
|
||||||
|
Log.d(TAG, "setStream: " + stream.getName() + ", status: " + stream.getStatus());
|
||||||
|
this.stream = stream;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListener(GroupItemListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||||
|
/* if (fromUser && (listener != null)) {
|
||||||
|
Volume volume = new Volume(progress, false);
|
||||||
|
client.setVolume(volume);
|
||||||
|
listener.onVolumeChanged(this, volume.getPercent());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
/* TODO: group if (v == ibMute) {
|
||||||
|
Volume volume = client.getConfig().getVolume();
|
||||||
|
volume.setMuted(!volume.isMuted());
|
||||||
|
update();
|
||||||
|
listener.onMute(this, volume.isMuted());
|
||||||
|
} else if (v == ibOverflow) {
|
||||||
|
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
||||||
|
popup.getMenu().add(Menu.NONE, R.id.menu_details, 0, R.string.menu_details);
|
||||||
|
if (!client.isConnected())
|
||||||
|
popup.getMenu().add(Menu.NONE, R.id.menu_delete, 1, R.string.menu_delete);
|
||||||
|
if ((server != null) && (server.getStreams().size() > 1)) {
|
||||||
|
int pos = 2;
|
||||||
|
for (final Stream stream : server.getStreams()) {
|
||||||
|
if (client.getConfig().getStream().equals(stream.getId()))
|
||||||
|
continue;
|
||||||
|
final MenuItem menuItem = popup.getMenu().add(Menu.NONE, Menu.NONE, pos, stream.getName());
|
||||||
|
menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
listener.onStreamClicked(ClientItem.this, stream);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
popup.setOnMenuItemClickListener(this);
|
||||||
|
popup.show();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
/* switch (item.getItemId()) {
|
||||||
|
case R.id.menu_details:
|
||||||
|
listener.onPropertiesClicked(this);
|
||||||
|
return true;
|
||||||
|
case R.id.menu_delete:
|
||||||
|
listener.onDeleteClicked(this);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVolumeChanged(ClientItem clientItem, int percent) {
|
||||||
|
if (listener != null)
|
||||||
|
listener.onVolumeChanged(this, clientItem, percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMute(ClientItem clientItem, boolean mute) {
|
||||||
|
if (listener != null)
|
||||||
|
listener.onMute(this, clientItem, mute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDeleteClicked(ClientItem clientItem) {
|
||||||
|
if (listener != null)
|
||||||
|
listener.onDeleteClicked(this, clientItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPropertiesClicked(ClientItem clientItem) {
|
||||||
|
if (listener != null)
|
||||||
|
listener.onPropertiesClicked(this, clientItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface GroupItemListener {
|
||||||
|
void onVolumeChanged(GroupItem group, ClientItem clientItem, int percent);
|
||||||
|
|
||||||
|
void onMute(GroupItem group, ClientItem clientItem, boolean mute);
|
||||||
|
|
||||||
|
void onDeleteClicked(GroupItem group, ClientItem clientItem);
|
||||||
|
|
||||||
|
void onPropertiesClicked(GroupItem group, ClientItem clientItem);
|
||||||
|
|
||||||
|
void onStreamClicked(GroupItem group, Stream stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -35,11 +35,6 @@ import android.os.IBinder;
|
||||||
import android.support.design.widget.CoordinatorLayout;
|
import android.support.design.widget.CoordinatorLayout;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.design.widget.TabLayout;
|
import android.support.design.widget.TabLayout;
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.app.FragmentManager;
|
|
||||||
import android.support.v4.app.FragmentPagerAdapter;
|
|
||||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
|
||||||
import android.support.v4.view.ViewPager;
|
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
@ -48,24 +43,20 @@ import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import de.badaix.snapcast.control.RemoteControl;
|
import de.badaix.snapcast.control.RemoteControl;
|
||||||
import de.badaix.snapcast.control.json.Client;
|
import de.badaix.snapcast.control.json.Client;
|
||||||
|
import de.badaix.snapcast.control.json.Group;
|
||||||
import de.badaix.snapcast.control.json.ServerStatus;
|
import de.badaix.snapcast.control.json.ServerStatus;
|
||||||
import de.badaix.snapcast.control.json.Stream;
|
import de.badaix.snapcast.control.json.Stream;
|
||||||
import de.badaix.snapcast.utils.NsdHelper;
|
import de.badaix.snapcast.utils.NsdHelper;
|
||||||
import de.badaix.snapcast.utils.Settings;
|
import de.badaix.snapcast.utils.Settings;
|
||||||
import de.badaix.snapcast.utils.Setup;
|
import de.badaix.snapcast.utils.Setup;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity implements ClientItem.ClientInfoItemListener, RemoteControl.RemoteControlListener, SnapclientService.SnapclientListener, NsdHelper.NsdHelperListener {
|
public class MainActivity extends AppCompatActivity implements GroupItem.GroupItemListener, RemoteControl.RemoteControlListener, SnapclientService.SnapclientListener, NsdHelper.NsdHelperListener {
|
||||||
|
|
||||||
static final int CLIENT_PROPERTIES_REQUEST = 1;
|
static final int CLIENT_PROPERTIES_REQUEST = 1;
|
||||||
private static final String TAG = "Main";
|
private static final String TAG = "Main";
|
||||||
|
@ -80,17 +71,12 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
private RemoteControl remoteControl = null;
|
private RemoteControl remoteControl = null;
|
||||||
private ServerStatus serverStatus = null;
|
private ServerStatus serverStatus = null;
|
||||||
private SnapclientService snapclientService;
|
private SnapclientService snapclientService;
|
||||||
private SectionsPagerAdapter sectionsPagerAdapter;
|
private ClientListFragment clientListFragment;
|
||||||
private TabLayout tabLayout;
|
private TabLayout tabLayout;
|
||||||
private Snackbar warningSamplerateSnackbar = null;
|
private Snackbar warningSamplerateSnackbar = null;
|
||||||
private int nativeSampleRate = 0;
|
private int nativeSampleRate = 0;
|
||||||
private CoordinatorLayout coordinatorLayout;
|
private CoordinatorLayout coordinatorLayout;
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link ViewPager} that will host the section contents.
|
|
||||||
*/
|
|
||||||
private ViewPager mViewPager;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines callbacks for service binding, passed to bindService()
|
* Defines callbacks for service binding, passed to bindService()
|
||||||
|
@ -139,15 +125,8 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
// Create the adapter that will return a fragment for each of the three
|
// Create the adapter that will return a fragment for each of the three
|
||||||
// primary sections of the activity.
|
// primary sections of the activity.
|
||||||
sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
|
|
||||||
|
|
||||||
// Set up the ViewPager with the sections adapter.
|
clientListFragment = (ClientListFragment) getSupportFragmentManager().findFragmentById(R.id.clientListFragment);
|
||||||
mViewPager = (ViewPager) findViewById(R.id.container);
|
|
||||||
mViewPager.setAdapter(sectionsPagerAdapter);
|
|
||||||
|
|
||||||
tabLayout = (TabLayout) findViewById(R.id.tabs);
|
|
||||||
tabLayout.setupWithViewPager(mViewPager);
|
|
||||||
mViewPager.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
setActionbarSubtitle("Host: no Snapserver found");
|
setActionbarSubtitle("Host: no Snapserver found");
|
||||||
|
|
||||||
|
@ -159,8 +138,6 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
Log.d(TAG, "done copying snapclient");
|
Log.d(TAG, "done copying snapclient");
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
sectionsPagerAdapter.setHideOffline(Settings.getInstance(this).getBoolean("hide_offline", false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkFirstRun() {
|
public void checkFirstRun() {
|
||||||
|
@ -195,7 +172,6 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
boolean isChecked = Settings.getInstance(this).getBoolean("hide_offline", false);
|
boolean isChecked = Settings.getInstance(this).getBoolean("hide_offline", false);
|
||||||
MenuItem menuItem = menu.findItem(R.id.action_hide_offline);
|
MenuItem menuItem = menu.findItem(R.id.action_hide_offline);
|
||||||
menuItem.setChecked(isChecked);
|
menuItem.setChecked(isChecked);
|
||||||
sectionsPagerAdapter.setHideOffline(isChecked);
|
|
||||||
// setHost(host, port, controlPort);
|
// setHost(host, port, controlPort);
|
||||||
if (remoteControl != null) {
|
if (remoteControl != null) {
|
||||||
updateMenuItems(remoteControl.isConnected());
|
updateMenuItems(remoteControl.isConnected());
|
||||||
|
@ -241,7 +217,7 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
} else if (id == R.id.action_hide_offline) {
|
} else if (id == R.id.action_hide_offline) {
|
||||||
item.setChecked(!item.isChecked());
|
item.setChecked(!item.isChecked());
|
||||||
Settings.getInstance(this).put("hide_offline", item.isChecked());
|
Settings.getInstance(this).put("hide_offline", item.isChecked());
|
||||||
sectionsPagerAdapter.setHideOffline(item.isChecked());
|
//TODO: group sectionsPagerAdapter.setHideOffline(item.isChecked());
|
||||||
return true;
|
return true;
|
||||||
} else if (id == R.id.action_refresh) {
|
} else if (id == R.id.action_refresh) {
|
||||||
startRemoteControl();
|
startRemoteControl();
|
||||||
|
@ -407,7 +383,7 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (requestCode == CLIENT_PROPERTIES_REQUEST) {
|
if (requestCode == CLIENT_PROPERTIES_REQUEST) {
|
||||||
Client client = null;
|
/* TODO: group Client client = null;
|
||||||
try {
|
try {
|
||||||
client = new Client(new JSONObject(data.getStringExtra("client")));
|
client = new Client(new JSONObject(data.getStringExtra("client")));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -432,17 +408,12 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
remoteControl.setLatency(client, client.getConfig().getLatency());
|
remoteControl.setLatency(client, client.getConfig().getLatency());
|
||||||
serverStatus.updateClient(client);
|
serverStatus.updateClient(client);
|
||||||
sectionsPagerAdapter.updateServer(serverStatus);
|
sectionsPagerAdapter.updateServer(serverStatus);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnected(RemoteControl remoteControl) {
|
public void onConnected(RemoteControl remoteControl) {
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mViewPager.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setActionbarSubtitle(remoteControl.getHost());
|
setActionbarSubtitle(remoteControl.getHost());
|
||||||
remoteControl.getServerStatus();
|
remoteControl.getServerStatus();
|
||||||
updateMenuItems(true);
|
updateMenuItems(true);
|
||||||
|
@ -457,7 +428,7 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
public void onDisconnected(RemoteControl remoteControl, Exception e) {
|
public void onDisconnected(RemoteControl remoteControl, Exception e) {
|
||||||
Log.d(TAG, "onDisconnected");
|
Log.d(TAG, "onDisconnected");
|
||||||
serverStatus = new ServerStatus();
|
serverStatus = new ServerStatus();
|
||||||
sectionsPagerAdapter.updateServer(serverStatus);
|
//TODO: group sectionsPagerAdapter.updateServer(serverStatus);
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
if (e instanceof UnknownHostException)
|
if (e instanceof UnknownHostException)
|
||||||
setActionbarSubtitle("error: unknown host");
|
setActionbarSubtitle("error: unknown host");
|
||||||
|
@ -466,38 +437,38 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
} else {
|
} else {
|
||||||
setActionbarSubtitle("not connected");
|
setActionbarSubtitle("not connected");
|
||||||
}
|
}
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mViewPager.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateMenuItems(false);
|
updateMenuItems(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClientEvent(RemoteControl remoteControl, Client client, RemoteControl.ClientEvent event) {
|
public void onClientEvent(RemoteControl remoteControl, Client client, RemoteControl.ClientEvent event) {
|
||||||
Log.d(TAG, "onClientEvent: " + event.toString());
|
Log.d(TAG, "onClientEvent: " + event.toString());
|
||||||
|
remoteControl.getServerStatus();
|
||||||
|
/* TODO: group
|
||||||
if (event == RemoteControl.ClientEvent.deleted)
|
if (event == RemoteControl.ClientEvent.deleted)
|
||||||
serverStatus.removeClient(client);
|
serverStatus.removeClient(client);
|
||||||
else
|
else
|
||||||
serverStatus.updateClient(client);
|
serverStatus.updateClient(client);
|
||||||
|
|
||||||
sectionsPagerAdapter.updateServer(serverStatus);
|
sectionsPagerAdapter.updateServer(serverStatus);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServerStatus(RemoteControl remoteControl, ServerStatus serverStatus) {
|
public void onServerStatus(RemoteControl remoteControl, ServerStatus serverStatus) {
|
||||||
this.serverStatus = serverStatus;
|
this.serverStatus = serverStatus;
|
||||||
for (Stream s : serverStatus.getStreams())
|
MainActivity.this.runOnUiThread(new Runnable() {
|
||||||
Log.d(TAG, s.toString());
|
@Override
|
||||||
sectionsPagerAdapter.updateServer(serverStatus);
|
public void run() {
|
||||||
|
clientListFragment.updateServer(MainActivity.this.serverStatus);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// TODO: group sectionsPagerAdapter.updateServer(serverStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStreamUpdate(RemoteControl remoteControl, Stream stream) {
|
public void onStreamUpdate(RemoteControl remoteControl, Stream stream) {
|
||||||
serverStatus.updateStream(stream);
|
serverStatus.updateStream(stream);
|
||||||
sectionsPagerAdapter.updateServer(serverStatus);
|
// TODO: group sectionsPagerAdapter.updateServer(serverStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -558,19 +529,20 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVolumeChanged(ClientItem clientItem, int percent) {
|
public void onVolumeChanged(GroupItem groupItem, ClientItem clientItem, int percent) {
|
||||||
remoteControl.setVolume(clientItem.getClient(), percent);
|
remoteControl.setVolume(clientItem.getClient(), percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMute(ClientItem clientItem, boolean mute) {
|
public void onMute(GroupItem groupItem, ClientItem clientItem, boolean mute) {
|
||||||
remoteControl.setMute(clientItem.getClient(), mute);
|
remoteControl.setMute(clientItem.getClient(), mute);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeleteClicked(final ClientItem clientItem) {
|
public void onDeleteClicked(GroupItem groupItem, final ClientItem clientItem) {
|
||||||
final Client client = clientItem.getClient();
|
final Client client = clientItem.getClient();
|
||||||
client.setDeleted(true);
|
client.setDeleted(true);
|
||||||
|
/* TODO: group
|
||||||
serverStatus.updateClient(client);
|
serverStatus.updateClient(client);
|
||||||
sectionsPagerAdapter.updateServer(serverStatus);
|
sectionsPagerAdapter.updateServer(serverStatus);
|
||||||
Snackbar mySnackbar = Snackbar.make(findViewById(R.id.myCoordinatorLayout),
|
Snackbar mySnackbar = Snackbar.make(findViewById(R.id.myCoordinatorLayout),
|
||||||
|
@ -595,10 +567,11 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mySnackbar.show();
|
mySnackbar.show();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPropertiesClicked(ClientItem clientItem) {
|
public void onPropertiesClicked(GroupItem groupItem, ClientItem clientItem) {
|
||||||
Intent intent = new Intent(this, ClientSettingsActivity.class);
|
Intent intent = new Intent(this, ClientSettingsActivity.class);
|
||||||
intent.putExtra("client", clientItem.getClient().toJson().toString());
|
intent.putExtra("client", clientItem.getClient().toJson().toString());
|
||||||
intent.putExtra("streams", serverStatus.getJsonStreams().toString());
|
intent.putExtra("streams", serverStatus.getJsonStreams().toString());
|
||||||
|
@ -607,78 +580,15 @@ public class MainActivity extends AppCompatActivity implements ClientItem.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStreamClicked(ClientItem clientItem, Stream stream) {
|
public void onStreamClicked(GroupItem groupItem, Stream stream) {
|
||||||
|
/* TODO: group
|
||||||
Client client = clientItem.getClient();
|
Client client = clientItem.getClient();
|
||||||
client.getConfig().setStream(stream.getId());
|
client.getConfig().setStream(stream.getId());
|
||||||
remoteControl.setStream(client, client.getConfig().getStream());
|
remoteControl.setStream(client, client.getConfig().getStream());
|
||||||
serverStatus.updateClient(client);
|
serverStatus.updateClient(client);
|
||||||
sectionsPagerAdapter.updateServer(serverStatus);
|
sectionsPagerAdapter.updateServer(serverStatus);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
|
|
||||||
* one of the sections/tabs/pages.
|
|
||||||
*/
|
|
||||||
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
|
|
||||||
|
|
||||||
private Vector<ClientListFragment> fragments = new Vector<>();
|
|
||||||
private int streamCount = 0;
|
|
||||||
private boolean hideOffline = false;
|
|
||||||
|
|
||||||
public SectionsPagerAdapter(FragmentManager fm) {
|
|
||||||
super(fm);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateServer(final ServerStatus serverStatus) {
|
|
||||||
MainActivity.this.runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Log.d(TAG, "updateServer: " + serverStatus.getStreams().size());
|
|
||||||
boolean changed = (serverStatus.getStreams().size() != streamCount);
|
|
||||||
|
|
||||||
while (serverStatus.getStreams().size() > fragments.size())
|
|
||||||
fragments.add(new ClientListFragment());
|
|
||||||
|
|
||||||
for (int i = 0; i < serverStatus.getStreams().size(); ++i) {
|
|
||||||
fragments.get(i).setStream(serverStatus.getStreams().get(i));
|
|
||||||
fragments.get(i).updateServer(serverStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
streamCount = serverStatus.getStreams().size();
|
|
||||||
notifyDataSetChanged();
|
|
||||||
tabLayout.setTabsFromPagerAdapter(SectionsPagerAdapter.this);
|
|
||||||
}
|
|
||||||
setHideOffline(hideOffline);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHideOffline(boolean hide) {
|
|
||||||
this.hideOffline = hide;
|
|
||||||
for (ClientListFragment clientListFragment : fragments)
|
|
||||||
clientListFragment.setHideOffline(hide);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fragment getItem(int position) {
|
|
||||||
return fragments.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return streamCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getPageTitle(int position) {
|
|
||||||
return fragments.get(position).getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -88,27 +88,28 @@ public class ServerStatus implements JsonSerialisable {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
public boolean updateClient(Client client) {
|
public boolean updateClient(Client client) {
|
||||||
if (client == null)
|
if (client == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (int i = 0; i < clients.size(); ++i) {
|
for (Group group : groups) {
|
||||||
Client clientInfo = clients.get(i);
|
for (int i = 0; i < group.getClients().size(); ++i) {
|
||||||
if (clientInfo == null)
|
Client c = group.getClients().get(i);
|
||||||
|
if (c == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (client.getId().equals(clientInfo.getId())) {
|
if (client.getId().equals(c.getId())) {
|
||||||
if (clientInfo.equals(client))
|
if (client.equals(c))
|
||||||
|
return true;
|
||||||
|
group.getClients().set(i, client);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
clients.set(i, client);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
clients.add(client);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
public boolean updateStream(Stream stream) {
|
public boolean updateStream(Stream stream) {
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -137,6 +138,13 @@ public class ServerStatus implements JsonSerialisable {
|
||||||
return streams;
|
return streams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Stream getStream(String id) {
|
||||||
|
for (Stream s : streams)
|
||||||
|
if ((s != null) && (s.getId().equals(id)))
|
||||||
|
return s;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public JSONArray getJsonStreams() {
|
public JSONArray getJsonStreams() {
|
||||||
JSONArray jsonArray = new JSONArray();
|
JSONArray jsonArray = new JSONArray();
|
||||||
for (Stream stream : streams)
|
for (Stream stream : streams)
|
||||||
|
|
|
@ -44,53 +44,15 @@
|
||||||
|
|
||||||
</android.support.v7.widget.Toolbar>
|
</android.support.v7.widget.Toolbar>
|
||||||
|
|
||||||
<android.support.design.widget.TabLayout
|
|
||||||
android:id="@+id/tabs"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
<android.support.v4.view.ViewPager
|
<fragment
|
||||||
android:id="@+id/container"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
|
android:layout_marginTop="?attr/actionBarSize"
|
||||||
|
android:name="de.badaix.snapcast.ClientListFragment"
|
||||||
<LinearLayout
|
android:id="@+id/clientListFragment"
|
||||||
android:layout_width="match_parent"
|
tools:layout="@layout/fragment_client_list"/>
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:orientation="vertical"
|
|
||||||
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
|
|
||||||
android:id="@+id/tvInfo"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="3dp"
|
|
||||||
android:text="Info: this is a prototype"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/cbScreenWakelock"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Keep screen on"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="New Button"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
-->
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
|
86
android/Snapcast/src/main/res/layout/client_item.xml
Normal file
86
android/Snapcast/src/main/res/layout/client_item.xml
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ This file is part of snapcast
|
||||||
|
~ Copyright (C) 2014-2016 Johannes Pohl
|
||||||
|
~
|
||||||
|
~ This program is free software: you can redistribute it and/or modify
|
||||||
|
~ it under the terms of the GNU General Public License as published by
|
||||||
|
~ the Free Software Foundation, either version 3 of the License, or
|
||||||
|
~ (at your option) any later version.
|
||||||
|
~
|
||||||
|
~ This program is distributed in the hope that it will be useful,
|
||||||
|
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
~ GNU General Public License for more details.
|
||||||
|
~
|
||||||
|
~ You should have received a copy of the GNU General Public License
|
||||||
|
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<!-- android:descendantFocusability="afterDescendants"-->
|
||||||
|
<!-- android:paddingRight="?android:attr/scrollbarSize"-->
|
||||||
|
<!-- android:background="@drawable/big_card"-->
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/ibOverflow"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:background="@null"
|
||||||
|
android:src="@drawable/abc_ic_menu_moreoverflow_mtrl_alpha"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_toLeftOf="@id/ibOverflow"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:fadingEdge="horizontal"
|
||||||
|
android:paddingBottom="1dp"
|
||||||
|
android:paddingLeft="5dp"
|
||||||
|
android:paddingTop="2dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:text="Title"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingBottom="4dp"
|
||||||
|
android:paddingLeft="3dp">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/ibMute"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@null"
|
||||||
|
android:src="@drawable/ic_speaker_icon"/>
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/volumeSeekBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:max="100"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
|
|
@ -23,13 +23,8 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="de.badaix.snapcast.ClientListFragment">
|
tools:context="de.badaix.snapcast.ClientListFragment">
|
||||||
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/lvClient"
|
android:id="@+id/lvGroup"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_above="@+id/tvStreamState"
|
android:layout_above="@+id/tvStreamState"
|
||||||
|
@ -43,18 +38,4 @@
|
||||||
android:dividerHeight="1dp"
|
android:dividerHeight="1dp"
|
||||||
android:listSelector="@android:color/transparent"/>
|
android:listSelector="@android:color/transparent"/>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvStreamState"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:padding="5dp"
|
|
||||||
android:text="Stream state"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
>
|
||||||
<!-- android:descendantFocusability="afterDescendants"-->
|
<!-- android:descendantFocusability="afterDescendants"-->
|
||||||
<!-- android:paddingRight="?android:attr/scrollbarSize"-->
|
<!-- android:paddingRight="?android:attr/scrollbarSize"-->
|
||||||
<!-- android:background="@drawable/big_card"-->
|
<!-- android:background="@drawable/big_card"-->
|
||||||
|
@ -32,21 +33,20 @@
|
||||||
card_view:cardUseCompatPadding="true"
|
card_view:cardUseCompatPadding="true"
|
||||||
card_view:contentPadding="2dp">
|
card_view:contentPadding="2dp">
|
||||||
|
|
||||||
<RelativeLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/ibOverflow"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentEnd="true"
|
android:orientation="vertical">
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:background="@null"
|
|
||||||
android:src="@drawable/abc_ic_menu_moreoverflow_mtrl_alpha"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/llClient"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"/>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/llVolume"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
|
@ -54,6 +54,7 @@
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -66,7 +67,7 @@
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="Title"
|
android:text="Title"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||||
|
-->
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -90,7 +91,33 @@
|
||||||
android:max="100"/>
|
android:max="100"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/ibOverflow"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:background="@null"
|
||||||
|
android:src="@drawable/abc_ic_menu_moreoverflow_mtrl_alpha"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvStreamState"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:text="Stream state"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
</android.support.v7.widget.CardView>
|
</android.support.v7.widget.CardView>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
|
@ -93,11 +93,14 @@ ClientInfoPtr Config::getClientInfo(const std::string& clientId) const
|
||||||
if (clientId.empty())
|
if (clientId.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
for (auto client: clients)
|
for (auto group: groups)
|
||||||
|
{
|
||||||
|
for (auto client: group->clients)
|
||||||
{
|
{
|
||||||
if (client->id == clientId)
|
if (client->id == clientId)
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -109,13 +112,26 @@ ClientInfoPtr Config::addClientInfo(const std::string& clientId)
|
||||||
if (!client)
|
if (!client)
|
||||||
{
|
{
|
||||||
client = make_shared<ClientInfo>(clientId);
|
client = make_shared<ClientInfo>(clientId);
|
||||||
clients.push_back(client);
|
//TODO: strange contruct
|
||||||
|
getGroup(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GroupPtr Config::getGroup(const std::string& groupId) const
|
||||||
|
{
|
||||||
|
for (auto group: groups)
|
||||||
|
{
|
||||||
|
if (group->id == groupId)
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GroupPtr Config::getGroup(ClientInfoPtr client)
|
GroupPtr Config::getGroup(ClientInfoPtr client)
|
||||||
{
|
{
|
||||||
for (auto group: groups)
|
for (auto group: groups)
|
||||||
|
@ -127,8 +143,7 @@ GroupPtr Config::getGroup(ClientInfoPtr client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupPtr group = std::make_shared<Group>();
|
GroupPtr group = std::make_shared<Group>();//client);
|
||||||
group->id = generateUUID();
|
|
||||||
group->clients.push_back(client);
|
group->clients.push_back(client);
|
||||||
groups.push_back(group);
|
groups.push_back(group);
|
||||||
|
|
||||||
|
@ -136,9 +151,9 @@ GroupPtr Config::getGroup(ClientInfoPtr client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
json Config::getServerStatus(const std::string& clientId, const json& streams) const
|
json Config::getServerStatus(const json& streams) const
|
||||||
{
|
{
|
||||||
json jClient = json::array();
|
/* json jClient = json::array();
|
||||||
if (clientId != "")
|
if (clientId != "")
|
||||||
{
|
{
|
||||||
ClientInfoPtr client = getClientInfo(clientId);
|
ClientInfoPtr client = getClientInfo(clientId);
|
||||||
|
@ -147,7 +162,7 @@ json Config::getServerStatus(const std::string& clientId, const json& streams) c
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
jClient = getClientInfos();
|
jClient = getClientInfos();
|
||||||
|
*/
|
||||||
Host host;
|
Host host;
|
||||||
host.update();
|
host.update();
|
||||||
//TODO: Set MAC and IP
|
//TODO: Set MAC and IP
|
||||||
|
@ -157,7 +172,7 @@ json Config::getServerStatus(const std::string& clientId, const json& streams) c
|
||||||
{"host", host.toJson()},//getHostName()},
|
{"host", host.toJson()},//getHostName()},
|
||||||
{"snapserver", snapserver.toJson()}
|
{"snapserver", snapserver.toJson()}
|
||||||
}},
|
}},
|
||||||
{"clients", jClient},
|
{"groups", getGroups()},
|
||||||
{"streams", streams}
|
{"streams", streams}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -165,14 +180,14 @@ json Config::getServerStatus(const std::string& clientId, const json& streams) c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
json Config::getClientInfos() const
|
/*json Config::getClientInfos() const
|
||||||
{
|
{
|
||||||
json result = json::array();
|
json result = json::array();
|
||||||
for (auto client: clients)
|
for (auto client: clients)
|
||||||
result.push_back(client->toJson());
|
result.push_back(client->toJson());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
json Config::getGroups() const
|
json Config::getGroups() const
|
||||||
{
|
{
|
||||||
|
@ -186,9 +201,9 @@ json Config::getGroups() const
|
||||||
void Config::remove(ClientInfoPtr client)
|
void Config::remove(ClientInfoPtr client)
|
||||||
{
|
{
|
||||||
auto group = getGroup(client);
|
auto group = getGroup(client);
|
||||||
if (group->clients.size() == 1)
|
auto clients = group->clients;
|
||||||
groups.erase(std::remove(groups.begin(), groups.end(), group), groups.end());
|
|
||||||
|
|
||||||
clients.erase(std::remove(clients.begin(), clients.end(), client), clients.end());
|
clients.erase(std::remove(clients.begin(), clients.end(), client), clients.end());
|
||||||
|
if (group->clients.empty())
|
||||||
|
groups.erase(std::remove(groups.begin(), groups.end(), group), groups.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,8 +257,11 @@ struct ClientInfo
|
||||||
|
|
||||||
struct Group
|
struct Group
|
||||||
{
|
{
|
||||||
Group()
|
Group(const ClientInfoPtr client = nullptr)
|
||||||
{
|
{
|
||||||
|
if (client)
|
||||||
|
id = client->id;
|
||||||
|
id = generateUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fromJson(const json& j)
|
void fromJson(const json& j)
|
||||||
|
@ -314,15 +317,16 @@ public:
|
||||||
void remove(ClientInfoPtr client);
|
void remove(ClientInfoPtr client);
|
||||||
|
|
||||||
GroupPtr getGroup(ClientInfoPtr client);
|
GroupPtr getGroup(ClientInfoPtr client);
|
||||||
|
GroupPtr getGroup(const std::string& groupId) const;
|
||||||
|
|
||||||
json getClientInfos() const;
|
// json getClientInfos() const;
|
||||||
json getGroups() const;
|
json getGroups() const;
|
||||||
json getServerStatus(const std::string& clientId, const json& streams) const;
|
json getServerStatus(const json& streams) const;
|
||||||
|
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
std::vector<GroupPtr> groups;
|
std::vector<GroupPtr> groups;
|
||||||
std::vector<ClientInfoPtr> clients;
|
// std::vector<ClientInfoPtr> clients;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Config();
|
Config();
|
||||||
|
|
|
@ -115,9 +115,17 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
|
||||||
|
|
||||||
json response;
|
json response;
|
||||||
ClientInfoPtr clientInfo = nullptr;
|
ClientInfoPtr clientInfo = nullptr;
|
||||||
|
GroupPtr group = nullptr;
|
||||||
msg::ServerSettings serverSettings;
|
msg::ServerSettings serverSettings;
|
||||||
serverSettings.setBufferMs(settings_.bufferMs);
|
serverSettings.setBufferMs(settings_.bufferMs);
|
||||||
|
|
||||||
|
if (request.method.find("Group.Set") == 0)
|
||||||
|
{
|
||||||
|
group = Config::instance().getGroup(request.getParam("group").get<string>());
|
||||||
|
if (group == nullptr)
|
||||||
|
throw JsonInternalErrorException("Group not found", request.id);
|
||||||
|
}
|
||||||
|
|
||||||
if (request.method.find("Client.Set") == 0)
|
if (request.method.find("Client.Set") == 0)
|
||||||
{
|
{
|
||||||
clientInfo = Config::instance().getClientInfo(request.getParam("client").get<string>());
|
clientInfo = Config::instance().getClientInfo(request.getParam("client").get<string>());
|
||||||
|
@ -127,8 +135,9 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
|
||||||
|
|
||||||
if (request.method == "Server.GetStatus")
|
if (request.method == "Server.GetStatus")
|
||||||
{
|
{
|
||||||
|
/// TODO: rpc
|
||||||
string clientId = request.hasParam("client") ? request.getParam("client").get<string>() : "";
|
string clientId = request.hasParam("client") ? request.getParam("client").get<string>() : "";
|
||||||
response = Config::instance().getServerStatus(clientId, streamManager_->toJson());
|
response = Config::instance().getServerStatus(/*clientId,*/ streamManager_->toJson());
|
||||||
// logO << response.dump(4);
|
// logO << response.dump(4);
|
||||||
}
|
}
|
||||||
else if (request.method == "Server.DeleteClient")
|
else if (request.method == "Server.DeleteClient")
|
||||||
|
@ -153,24 +162,25 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
|
||||||
clientInfo->config.volume.muted = request.getParam<bool>("mute", false, true);
|
clientInfo->config.volume.muted = request.getParam<bool>("mute", false, true);
|
||||||
response = clientInfo->config.volume.muted;
|
response = clientInfo->config.volume.muted;
|
||||||
}
|
}
|
||||||
else if (request.method == "Client.SetStream")
|
else if (request.method == "Group.SetStream")
|
||||||
{
|
{
|
||||||
/* TODO: Group.SetStream
|
|
||||||
string streamId = request.getParam("id").get<string>();
|
string streamId = request.getParam("id").get<string>();
|
||||||
PcmStreamPtr stream = streamManager_->getStream(streamId);
|
PcmStreamPtr stream = streamManager_->getStream(streamId);
|
||||||
if (stream == nullptr)
|
if (stream == nullptr)
|
||||||
throw JsonInternalErrorException("Stream not found", request.id);
|
throw JsonInternalErrorException("Stream not found", request.id);
|
||||||
|
|
||||||
clientInfo->config.streamId = streamId;
|
group->streamId = streamId;
|
||||||
response = clientInfo->config.streamId;
|
response = group->streamId;
|
||||||
|
|
||||||
session_ptr session = getStreamSession(request.getParam("client").get<string>());
|
for (auto client: group->clients)
|
||||||
|
{
|
||||||
|
session_ptr session = getStreamSession(client->id);
|
||||||
if (session != nullptr)
|
if (session != nullptr)
|
||||||
{
|
{
|
||||||
session->sendAsync(stream->getHeader());
|
session->sendAsync(stream->getHeader());
|
||||||
session->setPcmStream(stream);
|
session->setPcmStream(stream);
|
||||||
}
|
}
|
||||||
*/
|
}
|
||||||
}
|
}
|
||||||
else if (request.method == "Client.SetLatency")
|
else if (request.method == "Client.SetLatency")
|
||||||
{
|
{
|
||||||
|
@ -247,7 +257,6 @@ void StreamServer::onMessageReceived(StreamSession* connection, const msg::BaseM
|
||||||
logD << "request kServerSettings: " << connection->clientId << "\n";
|
logD << "request kServerSettings: " << connection->clientId << "\n";
|
||||||
// std::lock_guard<std::mutex> mlock(mutex_);
|
// std::lock_guard<std::mutex> mlock(mutex_);
|
||||||
ClientInfoPtr client = Config::instance().addClientInfo(connection->clientId);
|
ClientInfoPtr client = Config::instance().addClientInfo(connection->clientId);
|
||||||
|
|
||||||
GroupPtr group = Config::instance().getGroup(client);
|
GroupPtr group = Config::instance().getGroup(client);
|
||||||
|
|
||||||
logD << "request kServerSettings\n";
|
logD << "request kServerSettings\n";
|
||||||
|
@ -289,6 +298,8 @@ void StreamServer::onMessageReceived(StreamSession* connection, const msg::BaseM
|
||||||
json notification = JsonNotification::getJson("Client.OnConnect", client->toJson());
|
json notification = JsonNotification::getJson("Client.OnConnect", client->toJson());
|
||||||
// logO << notification.dump(4) << "\n";
|
// logO << notification.dump(4) << "\n";
|
||||||
controlServer_->send(notification.dump());
|
controlServer_->send(notification.dump());
|
||||||
|
// cout << Config::instance().getServerStatus(streamManager_->toJson()).dump(4) << "\n";
|
||||||
|
// cout << group->toJson().dump(4) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue