/*
* Copyright (c) 2015 OpenSilk Productions LLC
*
* 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 syncthing.android.ui.session;
import android.databinding.Bindable;
import android.databinding.BindingAdapter;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.widget.TextView;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.joda.time.DateTime;
import syncthing.android.R;
import syncthing.android.service.SyncthingUtils;
import syncthing.android.ui.common.ExpandableCard;
import syncthing.api.model.Compression;
import syncthing.api.model.ConnectionInfo;
import syncthing.api.model.ConnectionType;
import syncthing.api.model.DeviceConfig;
import syncthing.api.model.DeviceStats;
import timber.log.Timber;
/**
* Created by drew on 3/10/15.
*/
public class DeviceCard extends ExpandableCard {
private final SessionPresenter presenter;
protected DeviceConfig device;
protected DeviceStats stats;
protected int completion = -1;
private long inbps = -1;
private long inBytesTotal = -1;
private long outbps = -1;
private long outBytesTotal = -1;
private String address;
private String clientVersion = "?";
private boolean connected;
private boolean paused;
private boolean relayed;
public DeviceCard(
SessionPresenter presenter,
DeviceConfig device,
ConnectionInfo connection,
DeviceStats stats,
int completion
) {
this.presenter = presenter;
this.device = device;
this.stats = stats;
this.completion = completion;
setConnectionInfo(connection);
}
public void setDevice(DeviceConfig device) {
if (!StringUtils.equals(this.device.deviceID, device.deviceID)) {
throw new IllegalArgumentException("Tried binding a different device to this card " +
device.deviceID +" != " + this.device.deviceID);
}
this.device = device;
notifyChange(syncthing.android.BR._all);//TODO only notify changed fields
}
public void setConnectionInfo(ConnectionInfo connection) {
Timber.d("setConnectionInfo(%s)", ReflectionToStringBuilder.toString(connection));
if (connection == null) {
connected = false;
notifyChange(syncthing.android.BR.inbps);
notifyChange(syncthing.android.BR.inBytesTotal);
notifyChange(syncthing.android.BR.outbps);
notifyChange(syncthing.android.BR.outBytesTotal);
notifyChange(syncthing.android.BR.address);
notifyChange(syncthing.android.BR.clientVersion);
notifyChange(syncthing.android.BR.connected);
notifyChange(syncthing.android.BR.paused);
} else {
if (inbps != connection.inbps) {
inbps = connection.inbps;
notifyChange(syncthing.android.BR.inbps);
}
if (inBytesTotal != connection.inBytesTotal) {
inBytesTotal = connection.inBytesTotal;
notifyChange(syncthing.android.BR.inBytesTotal);
}
if (outbps != connection.outbps) {
outbps = connection.outbps;
notifyChange(syncthing.android.BR.outbps);
}
if (outBytesTotal != connection.outBytesTotal) {
outBytesTotal = connection.outBytesTotal;
notifyChange(syncthing.android.BR.outBytesTotal);
}
if (!StringUtils.equals(address, connection.address)) {
address = connection.address;
notifyChange(syncthing.android.BR.address);
}
if (!StringUtils.equals(clientVersion, connection.clientVersion)) {
clientVersion = connection.clientVersion;
notifyChange(syncthing.android.BR.clientVersion);
}
if (connected != connection.connected) {
connected = connection.connected;
notifyChange(syncthing.android.BR.connected);
}
if (paused != connection.paused) {
paused = connection.paused;
notifyChange(syncthing.android.BR.paused);
}
boolean rlyd = (connection.type == ConnectionType.RELAY_ACCEPT ||
connection.type == ConnectionType.RELAY_DIAL);
if (relayed != rlyd) {
relayed = rlyd;
notifyChange(syncthing.android.BR.relayed);
}
}
}
public void setDeviceStats(DeviceStats stats) {
this.stats = stats;
notifyChange(syncthing.android.BR.lastSeen);
}
public void setCompletion(int completion) {
this.completion = completion;
notifyChange(syncthing.android.BR.completion);
}
@Override
public int getLayout() {
return R.layout.session_device;
}
@Bindable
public String getDeviceID() {
return device.deviceID;
}
@Bindable
public String getName() {
return SyncthingUtils.getDisplayName(device);
}
@Bindable
public DateTime getLastSeen() {
return stats != null ? stats.lastSeen : null;
}
@Bindable
public int getCompletion() {
return completion;
}
@Bindable
public Compression getCompression() {
return device.compression;
}
@Bindable
public boolean getIntroducer() {
return device.introducer;
}
@Bindable
public long getInbps() {
return inbps;
}
@Bindable
public long getInBytesTotal(){
return inBytesTotal;
}
@Bindable
public long getOutbps() {
return outbps;
}
@Bindable
public long getOutBytesTotal() {
return outBytesTotal;
}
@Bindable
public String getAddress() {
return address;
}
@Bindable
public String getClientVersion() {
return clientVersion;
}
@Bindable
public boolean isConnected() {
return connected;
}
@Bindable
public boolean isPaused() {
return paused;
}
static final DateTime epoch = new DateTime(1969);
@BindingAdapter("deviceLastSeenText")
public static void deviceLastSeenText(TextView view, DateTime lastSeen) {
if (lastSeen == null) {
view.setText(R.string.unknown);
} else {
if (lastSeen.year().equals(epoch.year())) {
view.setText(R.string.never);
} else {
view.setText(lastSeen.toString("yyyy-MM-dd HH:mm"));
}
}
}
@BindingAdapter({"deviceCompletion", "deviceConnected"})
public static void deviceCompletion(TextView view, int completion, boolean connected) {
if (!connected || completion < 1) {
view.setText(R.string.disconnected);
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.device_disconnected));
} else if (completion == 100) {
view.setText(R.string.up_to_date);
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.device_idle));
} else {
view.setText(R.string.syncing);
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.device_syncing));
}
}
@Bindable
public boolean isRelayed() {
return relayed;
}
public void editDevice(View btn) {
presenter.openEditDeviceScreen(device.deviceID);
}
public void pauseResumeDevice(View btn) {
if (isPaused()) {
presenter.controller.resumeDevice(getDeviceID());
} else {
presenter.controller.pauseDevice(getDeviceID());
}
}
}