mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-11-23 04:41:16 +00:00
Use Gson for folder parsing
This commit is contained in:
parent
b9266ce6a9
commit
3dffc4c900
9 changed files with 175 additions and 211 deletions
|
@ -161,9 +161,11 @@ public class DrawerFragment extends Fragment implements RestApi.OnReceiveSystemI
|
||||||
percentFormat.setMaximumFractionDigits(2);
|
percentFormat.setMaximumFractionDigits(2);
|
||||||
mCpuUsage.setText(percentFormat.format(info.cpuPercent / 100));
|
mCpuUsage.setText(percentFormat.format(info.cpuPercent / 100));
|
||||||
mRamUsage.setText(RestApi.readableFileSize(mActivity, info.sys));
|
mRamUsage.setText(RestApi.readableFileSize(mActivity, info.sys));
|
||||||
|
int announceTotal = info.discoveryMethods;
|
||||||
|
int announceConnected = announceTotal - info.discoveryErrors.size();
|
||||||
mAnnounceServer.setText(String.format(Locale.getDefault(), "%1$d/%2$d",
|
mAnnounceServer.setText(String.format(Locale.getDefault(), "%1$d/%2$d",
|
||||||
info.extAnnounceConnected, info.extAnnounceTotal));
|
announceConnected, announceTotal));
|
||||||
int color = (info.extAnnounceConnected > 0)
|
int color = (announceConnected > 0)
|
||||||
? R.color.text_green
|
? R.color.text_green
|
||||||
: R.color.text_red;
|
: R.color.text_red;
|
||||||
mAnnounceServer.setTextColor(ContextCompat.getColor(getContext(), color));
|
mAnnounceServer.setTextColor(ContextCompat.getColor(getContext(), color));
|
||||||
|
|
|
@ -11,16 +11,25 @@ import android.text.Editable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.*;
|
import android.view.LayoutInflater;
|
||||||
import android.widget.*;
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
import com.nutomic.syncthingandroid.activities.FolderPickerActivity;
|
import com.nutomic.syncthingandroid.activities.FolderPickerActivity;
|
||||||
import com.nutomic.syncthingandroid.activities.SettingsActivity;
|
import com.nutomic.syncthingandroid.activities.SettingsActivity;
|
||||||
import com.nutomic.syncthingandroid.activities.SyncthingActivity;
|
import com.nutomic.syncthingandroid.activities.SyncthingActivity;
|
||||||
import com.nutomic.syncthingandroid.fragments.dialog.KeepVersionsDialogFragment;
|
import com.nutomic.syncthingandroid.fragments.dialog.KeepVersionsDialogFragment;
|
||||||
|
import com.nutomic.syncthingandroid.model.Folder;
|
||||||
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
||||||
import com.nutomic.syncthingandroid.syncthing.RestApi.SimpleVersioning;
|
|
||||||
import com.nutomic.syncthingandroid.syncthing.RestApi.Versioning;
|
|
||||||
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
|
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
|
||||||
import com.nutomic.syncthingandroid.util.TextWatcherAdapter;
|
import com.nutomic.syncthingandroid.util.TextWatcherAdapter;
|
||||||
|
|
||||||
|
@ -58,7 +67,7 @@ public class FolderFragment extends Fragment
|
||||||
|
|
||||||
private SyncthingService mSyncthingService;
|
private SyncthingService mSyncthingService;
|
||||||
|
|
||||||
private RestApi.Folder mFolder;
|
private Folder mFolder;
|
||||||
|
|
||||||
private EditText mLabelView;
|
private EditText mLabelView;
|
||||||
private EditText mIdView;
|
private EditText mIdView;
|
||||||
|
@ -88,16 +97,18 @@ public class FolderFragment extends Fragment
|
||||||
public void onCheckedChanged(CompoundButton view, boolean isChecked) {
|
public void onCheckedChanged(CompoundButton view, boolean isChecked) {
|
||||||
switch (view.getId()) {
|
switch (view.getId()) {
|
||||||
case R.id.master:
|
case R.id.master:
|
||||||
mFolder.readOnly = isChecked;
|
mFolder.type = (isChecked) ? "readonly" : "readwrite";
|
||||||
mFolderNeedsToUpdate = true;
|
mFolderNeedsToUpdate = true;
|
||||||
break;
|
break;
|
||||||
case R.id.device_toggle:
|
case R.id.device_toggle:
|
||||||
|
List<String> devicesList = mFolder.getDevices();
|
||||||
RestApi.Device device = (RestApi.Device) view.getTag();
|
RestApi.Device device = (RestApi.Device) view.getTag();
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
mFolder.deviceIds.add(device.deviceID);
|
devicesList.add(device.deviceID);
|
||||||
} else {
|
} else {
|
||||||
mFolder.deviceIds.remove(device.deviceID);
|
devicesList.remove(device.deviceID);
|
||||||
}
|
}
|
||||||
|
mFolder.setDevices(devicesList);
|
||||||
mFolderNeedsToUpdate = true;
|
mFolderNeedsToUpdate = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -109,11 +120,10 @@ public class FolderFragment extends Fragment
|
||||||
@Override
|
@Override
|
||||||
public void onValueChange(int intValue) {
|
public void onValueChange(int intValue) {
|
||||||
if (intValue == 0) {
|
if (intValue == 0) {
|
||||||
mFolder.versioning = new Versioning();
|
mFolder.versioning = new Folder.Versioning();
|
||||||
mVersioningKeepView.setText(R.string.off);
|
mVersioningKeepView.setText(R.string.off);
|
||||||
} else {
|
} else {
|
||||||
mFolder.versioning = new SimpleVersioning();
|
mFolder.versioning.params.put("keep", valueOf(intValue));
|
||||||
((SimpleVersioning) mFolder.versioning).setParams(intValue);
|
|
||||||
mVersioningKeepView.setText(valueOf(intValue));
|
mVersioningKeepView.setText(valueOf(intValue));
|
||||||
}
|
}
|
||||||
mFolderNeedsToUpdate = true;
|
mFolderNeedsToUpdate = true;
|
||||||
|
@ -143,7 +153,7 @@ public class FolderFragment extends Fragment
|
||||||
|
|
||||||
if (mIsCreateMode) {
|
if (mIsCreateMode) {
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
mFolder = (RestApi.Folder) savedInstanceState.getSerializable("folder");
|
mFolder = (Folder) savedInstanceState.getSerializable("folder");
|
||||||
}
|
}
|
||||||
if (mFolder == null) {
|
if (mFolder == null) {
|
||||||
initFolder();
|
initFolder();
|
||||||
|
@ -228,10 +238,10 @@ public class FolderFragment extends Fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mIsCreateMode) {
|
if (!mIsCreateMode) {
|
||||||
List<RestApi.Folder> folders = mSyncthingService.getApi().getFolders();
|
List<Folder> folders = mSyncthingService.getApi().getFolders();
|
||||||
String passedId = getActivity().getIntent().getStringExtra(EXTRA_FOLDER_ID);
|
String passedId = getActivity().getIntent().getStringExtra(EXTRA_FOLDER_ID);
|
||||||
mFolder = null;
|
mFolder = null;
|
||||||
for (RestApi.Folder currentFolder : folders) {
|
for (Folder currentFolder : folders) {
|
||||||
if (currentFolder.id.equals(passedId)) {
|
if (currentFolder.id.equals(passedId)) {
|
||||||
mFolder = currentFolder;
|
mFolder = currentFolder;
|
||||||
break;
|
break;
|
||||||
|
@ -258,7 +268,7 @@ public class FolderFragment extends Fragment
|
||||||
mLabelView.setText(mFolder.label);
|
mLabelView.setText(mFolder.label);
|
||||||
mIdView.setText(mFolder.id);
|
mIdView.setText(mFolder.id);
|
||||||
mPathView.setText(mFolder.path);
|
mPathView.setText(mFolder.path);
|
||||||
mFolderMasterView.setChecked(mFolder.readOnly);
|
mFolderMasterView.setChecked(mFolder.type.equals("readonly"));
|
||||||
List<RestApi.Device> devicesList = mSyncthingService.getApi().getDevices(false);
|
List<RestApi.Device> devicesList = mSyncthingService.getApi().getDevices(false);
|
||||||
|
|
||||||
mDevicesContainer.removeAllViews();
|
mDevicesContainer.removeAllViews();
|
||||||
|
@ -270,10 +280,10 @@ public class FolderFragment extends Fragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean versioningEnabled = mFolder.versioning instanceof SimpleVersioning;
|
boolean versioningEnabled = mFolder.versioning.type.equals("simple");
|
||||||
int versions = 0;
|
int versions = 0;
|
||||||
if (versioningEnabled) {
|
if (versioningEnabled) {
|
||||||
versions = Integer.valueOf(mFolder.versioning.getParams().get("keep"));
|
versions = Integer.valueOf(mFolder.versioning.params.get("keep"));
|
||||||
mVersioningKeepView.setText(valueOf(versions));
|
mVersioningKeepView.setText(valueOf(versions));
|
||||||
} else {
|
} else {
|
||||||
mVersioningKeepView.setText(R.string.off);
|
mVersioningKeepView.setText(R.string.off);
|
||||||
|
@ -342,16 +352,16 @@ public class FolderFragment extends Fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initFolder() {
|
private void initFolder() {
|
||||||
mFolder = new RestApi.Folder();
|
mFolder = new Folder();
|
||||||
mFolder.id = getActivity().getIntent().getStringExtra(EXTRA_FOLDER_ID);
|
mFolder.id = getActivity().getIntent().getStringExtra(EXTRA_FOLDER_ID);
|
||||||
mFolder.label = getActivity().getIntent().getStringExtra(EXTRA_FOLDER_LABEL);
|
mFolder.label = getActivity().getIntent().getStringExtra(EXTRA_FOLDER_LABEL);
|
||||||
mFolder.path = "";
|
mFolder.path = "";
|
||||||
mFolder.rescanIntervalS = 259200; // Scan every 3 days (in case inotify dropped some changes)
|
mFolder.rescanIntervalS = 259200; // Scan every 3 days (in case inotify dropped some changes)
|
||||||
mFolder.deviceIds = new ArrayList<>();
|
mFolder.setDevices(new ArrayList<>());
|
||||||
mFolder.versioning = new Versioning();
|
mFolder.versioning = new Folder.Versioning();
|
||||||
String deviceId = getActivity().getIntent().getStringExtra(EXTRA_DEVICE_ID);
|
String deviceId = getActivity().getIntent().getStringExtra(EXTRA_DEVICE_ID);
|
||||||
if (deviceId != null)
|
//if (deviceId != null)
|
||||||
mFolder.deviceIds.add(deviceId);
|
// TODO mFolder.devices.add(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareEditMode() {
|
private void prepareEditMode() {
|
||||||
|
@ -376,7 +386,7 @@ public class FolderFragment extends Fragment
|
||||||
private void addDeviceViewAndSetListener(RestApi.Device device, LayoutInflater inflater) {
|
private void addDeviceViewAndSetListener(RestApi.Device device, LayoutInflater inflater) {
|
||||||
inflater.inflate(R.layout.item_device_form, mDevicesContainer);
|
inflater.inflate(R.layout.item_device_form, mDevicesContainer);
|
||||||
SwitchCompat deviceView = (SwitchCompat) mDevicesContainer.getChildAt(mDevicesContainer.getChildCount()-1);
|
SwitchCompat deviceView = (SwitchCompat) mDevicesContainer.getChildAt(mDevicesContainer.getChildCount()-1);
|
||||||
deviceView.setChecked(mFolder.deviceIds.contains(device.deviceID));
|
deviceView.setChecked(mFolder.getDevices().contains(device.deviceID));
|
||||||
deviceView.setText(RestApi.getDeviceDisplayName(device));
|
deviceView.setText(RestApi.getDeviceDisplayName(device));
|
||||||
deviceView.setTag(device);
|
deviceView.setTag(device);
|
||||||
deviceView.setOnCheckedChangeListener(mCheckedListener);
|
deviceView.setOnCheckedChangeListener(mCheckedListener);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import android.widget.AdapterView;
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
import com.nutomic.syncthingandroid.activities.SettingsActivity;
|
import com.nutomic.syncthingandroid.activities.SettingsActivity;
|
||||||
import com.nutomic.syncthingandroid.activities.SyncthingActivity;
|
import com.nutomic.syncthingandroid.activities.SyncthingActivity;
|
||||||
|
import com.nutomic.syncthingandroid.model.Folder;
|
||||||
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
||||||
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
|
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
|
||||||
import com.nutomic.syncthingandroid.util.FoldersAdapter;
|
import com.nutomic.syncthingandroid.util.FoldersAdapter;
|
||||||
|
@ -32,7 +33,7 @@ public class FolderListFragment extends ListFragment implements SyncthingService
|
||||||
/**
|
/**
|
||||||
* Compares folders by labels, uses the folder ID as fallback if the label is empty
|
* Compares folders by labels, uses the folder ID as fallback if the label is empty
|
||||||
*/
|
*/
|
||||||
private final static Comparator<RestApi.Folder> FOLDERS_COMPARATOR = (lhs, rhs) -> {
|
private final static Comparator<Folder> FOLDERS_COMPARATOR = (lhs, rhs) -> {
|
||||||
String lhsLabel = lhs.label != null && !lhs.label.isEmpty() ? lhs.label : lhs.id;
|
String lhsLabel = lhs.label != null && !lhs.label.isEmpty() ? lhs.label : lhs.id;
|
||||||
String rhsLabel = rhs.label != null && !rhs.label.isEmpty() ? rhs.label : rhs.id;
|
String rhsLabel = rhs.label != null && !rhs.label.isEmpty() ? rhs.label : rhs.id;
|
||||||
|
|
||||||
|
@ -106,7 +107,7 @@ public class FolderListFragment extends ListFragment implements SyncthingService
|
||||||
// Prevent scroll position reset due to list update from clear().
|
// Prevent scroll position reset due to list update from clear().
|
||||||
mAdapter.setNotifyOnChange(false);
|
mAdapter.setNotifyOnChange(false);
|
||||||
mAdapter.clear();
|
mAdapter.clear();
|
||||||
List<RestApi.Folder> folders = activity.getApi().getFolders();
|
List<Folder> folders = activity.getApi().getFolders();
|
||||||
Collections.sort(folders, FOLDERS_COMPARATOR);
|
Collections.sort(folders, FOLDERS_COMPARATOR);
|
||||||
mAdapter.addAll(folders);
|
mAdapter.addAll(folders);
|
||||||
mAdapter.updateModel(activity.getApi());
|
mAdapter.updateModel(activity.getApi());
|
||||||
|
|
58
src/main/java/com/nutomic/syncthingandroid/model/Folder.java
Normal file
58
src/main/java/com/nutomic/syncthingandroid/model/Folder.java
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package com.nutomic.syncthingandroid.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Folder implements Serializable {
|
||||||
|
|
||||||
|
public String id;
|
||||||
|
public String label;
|
||||||
|
public String path;
|
||||||
|
public String type;
|
||||||
|
private transient List<Map<String, String>> devices;
|
||||||
|
public int rescanIntervalS;
|
||||||
|
public boolean ignorePerms;
|
||||||
|
public boolean autoNormalize;
|
||||||
|
public int minDiskFreePct;
|
||||||
|
public Versioning versioning;
|
||||||
|
public int copiers;
|
||||||
|
public int pullers;
|
||||||
|
public int hashers;
|
||||||
|
public String order;
|
||||||
|
public boolean ignoreDelete;
|
||||||
|
public int scanProgressIntervalS;
|
||||||
|
public int pullerSleepS;
|
||||||
|
public int pullerPauseS;
|
||||||
|
public int maxConflicts;
|
||||||
|
public boolean disableSparseFiles;
|
||||||
|
public boolean disableTempIndexes;
|
||||||
|
public String invalid;
|
||||||
|
|
||||||
|
public static class Versioning implements Serializable {
|
||||||
|
public String type;
|
||||||
|
public Map<String, String> params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getDevices() {
|
||||||
|
if (devices == null)
|
||||||
|
return new ArrayList<>();
|
||||||
|
|
||||||
|
List<String> devicesList = new ArrayList<>();
|
||||||
|
for (Map<String, String> map : devices) {
|
||||||
|
devicesList.addAll(map.values());
|
||||||
|
}
|
||||||
|
return devicesList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDevices(List<String> newDvices) {
|
||||||
|
devices.clear();
|
||||||
|
for (String d : newDvices) {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
map.put("deviceID", d);
|
||||||
|
devices.add(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,14 +13,12 @@ import android.preference.PreferenceManager;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
import com.nutomic.syncthingandroid.activities.SettingsActivity;
|
import com.nutomic.syncthingandroid.activities.SettingsActivity;
|
||||||
import com.nutomic.syncthingandroid.fragments.DeviceFragment;
|
import com.nutomic.syncthingandroid.fragments.DeviceFragment;
|
||||||
import com.nutomic.syncthingandroid.fragments.FolderFragment;
|
import com.nutomic.syncthingandroid.fragments.FolderFragment;
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -70,7 +68,7 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene
|
||||||
// If that's the case we've to start at zero because syncthing was restarted.
|
// If that's the case we've to start at zero because syncthing was restarted.
|
||||||
mApi.getEvents(0, 1, new RestApi.OnReceiveEventListener() {
|
mApi.getEvents(0, 1, new RestApi.OnReceiveEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(String eventType, JSONObject data) throws JSONException {
|
public void onEvent(String eventType, JsonObject data) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,10 +87,10 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene
|
||||||
* Performs the actual event handling.
|
* Performs the actual event handling.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(String type, JSONObject data) throws JSONException {
|
public void onEvent(String type, JsonObject data) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "DeviceRejected":
|
case "DeviceRejected":
|
||||||
String deviceId = data.getString("device");
|
String deviceId = data.get("device").getAsString();
|
||||||
Log.d(TAG, "Unknwon device " + deviceId + " wants to connect");
|
Log.d(TAG, "Unknwon device " + deviceId + " wants to connect");
|
||||||
|
|
||||||
Intent intent = new Intent(mContext, SettingsActivity.class)
|
Intent intent = new Intent(mContext, SettingsActivity.class)
|
||||||
|
@ -110,9 +108,9 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene
|
||||||
notify(title, pi);
|
notify(title, pi);
|
||||||
break;
|
break;
|
||||||
case "FolderRejected":
|
case "FolderRejected":
|
||||||
deviceId = data.getString("device");
|
deviceId = data.get("device").getAsString();
|
||||||
String folderId = data.getString("folder");
|
String folderId = data.get("folder").getAsString();
|
||||||
String folderLabel = data.getString("folderLabel");
|
String folderLabel = data.get("folderLabel").getAsString();
|
||||||
Log.d(TAG, "Device " + deviceId + " wants to share folder " + folderId);
|
Log.d(TAG, "Device " + deviceId + " wants to share folder " + folderId);
|
||||||
|
|
||||||
intent = new Intent(mContext, SettingsActivity.class)
|
intent = new Intent(mContext, SettingsActivity.class)
|
||||||
|
@ -137,7 +135,8 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene
|
||||||
notify(title, pi);
|
notify(title, pi);
|
||||||
break;
|
break;
|
||||||
case "ItemFinished":
|
case "ItemFinished":
|
||||||
File updatedFile = new File(data.getString("folderpath"), data.getString("item"));
|
File updatedFile = new File(data.get("folderpath").getAsString(),
|
||||||
|
data.get("item").getAsString());
|
||||||
Log.i(TAG, "Notified media scanner about " + updatedFile.toString());
|
Log.i(TAG, "Notified media scanner about " + updatedFile.toString());
|
||||||
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
|
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
|
||||||
Uri.fromFile(updatedFile)));
|
Uri.fromFile(updatedFile)));
|
||||||
|
|
|
@ -11,15 +11,21 @@ import android.support.annotation.NonNull;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
import com.nutomic.syncthingandroid.BuildConfig;
|
import com.nutomic.syncthingandroid.BuildConfig;
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
import com.nutomic.syncthingandroid.activities.RestartActivity;
|
import com.nutomic.syncthingandroid.activities.RestartActivity;
|
||||||
import com.nutomic.syncthingandroid.http.GetTask;
|
import com.nutomic.syncthingandroid.http.GetTask;
|
||||||
import com.nutomic.syncthingandroid.http.PostTask;
|
import com.nutomic.syncthingandroid.http.PostTask;
|
||||||
|
import com.nutomic.syncthingandroid.model.Folder;
|
||||||
import com.nutomic.syncthingandroid.util.FolderObserver;
|
import com.nutomic.syncthingandroid.util.FolderObserver;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
@ -27,7 +33,11 @@ import org.json.JSONObject;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,60 +86,22 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
public static class SystemInfo {
|
public static class SystemInfo {
|
||||||
public long alloc;
|
public long alloc;
|
||||||
public double cpuPercent;
|
public double cpuPercent;
|
||||||
public int extAnnounceConnected; // Number of connected announce servers.
|
|
||||||
public int extAnnounceTotal; // Total number of configured announce servers.
|
|
||||||
public int goroutines;
|
public int goroutines;
|
||||||
public String myID;
|
public String myID;
|
||||||
public long sys;
|
public long sys;
|
||||||
|
public boolean discoveryEnabled;
|
||||||
|
public int discoveryMethods;
|
||||||
|
public Map<String, String> discoveryErrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SystemVersion {
|
public static class SystemVersion {
|
||||||
@SerializedName("arch")
|
public String arch;
|
||||||
public String architecture;
|
|
||||||
@SerializedName("codename")
|
|
||||||
public String codename;
|
public String codename;
|
||||||
@SerializedName("longVersion")
|
|
||||||
public String longVersion;
|
public String longVersion;
|
||||||
@SerializedName("os")
|
|
||||||
public String os;
|
public String os;
|
||||||
@SerializedName("version")
|
|
||||||
public String version;
|
public String version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Folder implements Serializable {
|
|
||||||
public String path;
|
|
||||||
public String label;
|
|
||||||
public String id;
|
|
||||||
public String invalid;
|
|
||||||
public List<String> deviceIds;
|
|
||||||
public boolean readOnly;
|
|
||||||
public int rescanIntervalS;
|
|
||||||
public Versioning versioning;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Versioning implements Serializable {
|
|
||||||
protected final Map<String, String> mParams = new HashMap<>();
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getParams() {
|
|
||||||
return mParams;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SimpleVersioning extends Versioning {
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return "simple";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParams(int keep) {
|
|
||||||
mParams.put("keep", Integer.toString(keep));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Connection {
|
public static class Connection {
|
||||||
public String at;
|
public String at;
|
||||||
public long inBytesTotal;
|
public long inBytesTotal;
|
||||||
|
@ -240,15 +212,10 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
JsonObject json = new JsonParser().parse(s).getAsJsonObject();
|
||||||
JSONObject json = new JSONObject(s);
|
mVersion = json.get("version").getAsString();
|
||||||
mVersion = json.getString("version");
|
Log.i(TAG, "Syncthing version is " + mVersion);
|
||||||
Log.i(TAG, "Syncthing version is " + mVersion);
|
tryIsAvailable();
|
||||||
tryIsAvailable();
|
|
||||||
}
|
|
||||||
catch (JSONException e) {
|
|
||||||
Log.w(TAG, "Failed to parse config", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
new GetTask(mUrl, GetTask.URI_CONFIG, mHttpsCertPath, mApiKey) {
|
new GetTask(mUrl, GetTask.URI_CONFIG, mHttpsCertPath, mApiKey) {
|
||||||
|
@ -448,26 +415,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
listener.onReceiveSystemInfo(new Gson().fromJson(s, SystemInfo.class));
|
||||||
JSONObject system = new JSONObject(s);
|
|
||||||
SystemInfo si = new SystemInfo();
|
|
||||||
si.alloc = system.getLong("alloc");
|
|
||||||
si.cpuPercent = system.getDouble("cpuPercent");
|
|
||||||
if (system.has("discoveryEnabled")) {
|
|
||||||
si.extAnnounceTotal = system.getInt("discoveryMethods");
|
|
||||||
si.extAnnounceConnected =
|
|
||||||
si.extAnnounceTotal - system.getJSONObject("discoveryErrors").length();
|
|
||||||
} else {
|
|
||||||
si.extAnnounceTotal = 0;
|
|
||||||
si.extAnnounceConnected = 0;
|
|
||||||
}
|
|
||||||
si.goroutines = system.getInt("goroutines");
|
|
||||||
si.myID = system.getString("myID");
|
|
||||||
si.sys = system.getLong("sys");
|
|
||||||
listener.onReceiveSystemInfo(si);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.w(TAG, "Failed to read system info", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
}
|
}
|
||||||
|
@ -502,45 +450,13 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
if (mConfig == null)
|
if (mConfig == null)
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
|
|
||||||
List<Folder> ret;
|
|
||||||
try {
|
try {
|
||||||
JSONArray folders = mConfig.getJSONArray("folders");
|
String foldersJson = mConfig.getJSONArray("folders").toString();
|
||||||
ret = new ArrayList<>(folders.length());
|
return Arrays.asList(new Gson().fromJson(foldersJson, Folder[].class));
|
||||||
for (int i = 0; i < folders.length(); i++) {
|
|
||||||
JSONObject json = folders.getJSONObject(i);
|
|
||||||
Folder r = new Folder();
|
|
||||||
r.path = json.getString("path");
|
|
||||||
r.label = json.getString("label");
|
|
||||||
r.id = json.getString("id");
|
|
||||||
// TODO: Field seems to be missing sometimes.
|
|
||||||
// https://github.com/syncthing/syncthing-android/issues/291
|
|
||||||
r.invalid = json.optString("invalid");
|
|
||||||
r.deviceIds = new ArrayList<>();
|
|
||||||
JSONArray devices = json.getJSONArray("devices");
|
|
||||||
for (int j = 0; j < devices.length(); j++) {
|
|
||||||
JSONObject n = devices.getJSONObject(j);
|
|
||||||
r.deviceIds.add(n.getString("deviceID"));
|
|
||||||
}
|
|
||||||
|
|
||||||
r.readOnly = json.getString("type").equals("readonly");
|
|
||||||
r.rescanIntervalS = json.getInt("rescanIntervalS");
|
|
||||||
JSONObject versioning = json.getJSONObject("versioning");
|
|
||||||
if (versioning.getString("type").equals("simple")) {
|
|
||||||
SimpleVersioning sv = new SimpleVersioning();
|
|
||||||
JSONObject params = versioning.getJSONObject("params");
|
|
||||||
sv.setParams(params.getInt("keep"));
|
|
||||||
r.versioning = sv;
|
|
||||||
} else {
|
|
||||||
r.versioning = new Versioning();
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.add(r);
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.w(TAG, "Failed to read devices", e);
|
Log.w(TAG, "Failed to read devices", e);
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -662,12 +578,11 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
boolean isShared = false;
|
boolean isShared = false;
|
||||||
outerloop:
|
outerloop:
|
||||||
for (Folder r : getFolders()) {
|
for (Folder r : getFolders()) {
|
||||||
for (String n : r.deviceIds) {
|
for (String n : r.getDevices()) {
|
||||||
if (n.equals(deviceId)) {
|
if (n.equals(deviceId)) {
|
||||||
isShared = true;
|
isShared = true;
|
||||||
break outerloop;
|
break outerloop;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isShared) {
|
if (isShared) {
|
||||||
|
@ -704,7 +619,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
* @param eventType Name of the event. (See Syncthing documentation)
|
* @param eventType Name of the event. (See Syncthing documentation)
|
||||||
* @param data Contains the data fields of the event.
|
* @param data Contains the data fields of the event.
|
||||||
*/
|
*/
|
||||||
void onEvent(String eventType, JSONObject data) throws JSONException;
|
void onEvent(String eventType, JsonObject data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after all available events have been processed.
|
* Called after all available events have been processed.
|
||||||
|
@ -723,27 +638,9 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
Model m = new Gson().fromJson(s, Model.class);
|
||||||
JSONObject json = new JSONObject(s);
|
mCachedModelInfo.put(folderId, m);
|
||||||
Model m = new Model();
|
listener.onReceiveModel(folderId, m);
|
||||||
m.globalBytes = json.getLong("globalBytes");
|
|
||||||
m.globalDeleted = json.getLong("globalDeleted");
|
|
||||||
m.globalFiles = json.getLong("globalFiles");
|
|
||||||
m.localBytes = json.getLong("localBytes");
|
|
||||||
m.localDeleted = json.getLong("localDeleted");
|
|
||||||
m.localFiles = json.getLong("localFiles");
|
|
||||||
m.inSyncBytes = json.getLong("inSyncBytes");
|
|
||||||
m.inSyncFiles = json.getLong("inSyncFiles");
|
|
||||||
m.needBytes = json.getLong("needBytes");
|
|
||||||
m.needFiles = json.getLong("needFiles");
|
|
||||||
m.needDeletes = json.getLong("needDeletes");
|
|
||||||
m.state = json.getString("state");
|
|
||||||
m.invalid = json.optString("invalid");
|
|
||||||
mCachedModelInfo.put(folderId, m);
|
|
||||||
listener.onReceiveModel(folderId, m);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.w(TAG, "Failed to read folder info", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.execute("folder", folderId);
|
}.execute("folder", folderId);
|
||||||
}
|
}
|
||||||
|
@ -782,35 +679,32 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
JsonArray jsonEvents = new JsonParser().parse(s).getAsJsonArray();
|
||||||
JSONArray jsonEvents = new JSONArray(s);
|
long lastId = 0;
|
||||||
long lastId = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < jsonEvents.length(); i++) {
|
for (int i = 0; i < jsonEvents.size(); i++) {
|
||||||
JSONObject json = jsonEvents.getJSONObject(i);
|
JsonObject json = jsonEvents.get(i).getAsJsonObject();
|
||||||
String type = json.getString("type");
|
String type = json.get("type").getAsString();
|
||||||
long id = json.getLong("id");
|
long id = json.get("id").getAsLong();
|
||||||
|
|
||||||
if (lastId < id)
|
if (lastId < id)
|
||||||
lastId = id;
|
lastId = id;
|
||||||
|
|
||||||
JSONObject data = json.optJSONObject("data");
|
JsonObject data = null;
|
||||||
|
if (json.has("data"))
|
||||||
|
data = json.get("data").getAsJsonObject();
|
||||||
|
|
||||||
// Add folder path to data.
|
// Add folder path to data.
|
||||||
if (data != null && data.has("folder")) {
|
if (data != null && data.has("folder")) {
|
||||||
String folder = data.getString("folder");
|
String folder = data.get("folder").getAsString();
|
||||||
String folderPath = getPathForFolder(folder);
|
String folderPath = getPathForFolder(folder);
|
||||||
data.put("folderpath", folderPath);
|
data.addProperty("folderpath", folderPath);
|
||||||
}
|
|
||||||
|
|
||||||
listener.onEvent(type, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
listener.onDone(lastId);
|
listener.onEvent(type, data);
|
||||||
}
|
|
||||||
catch (JSONException e) {
|
|
||||||
Log.w(TAG, "Failed to read events", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listener.onDone(lastId);
|
||||||
}
|
}
|
||||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
|
||||||
"since", String.valueOf(sinceId), "limit", String.valueOf(limit));
|
"since", String.valueOf(sinceId), "limit", String.valueOf(limit));
|
||||||
|
@ -913,21 +807,21 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
r.put("label", folder.label);
|
r.put("label", folder.label);
|
||||||
r.put("id", folder.id);
|
r.put("id", folder.id);
|
||||||
r.put("ignorePerms", true);
|
r.put("ignorePerms", true);
|
||||||
r.put("type", (folder.readOnly) ? "readonly" : "readwrite");
|
r.put("type", folder.type);
|
||||||
|
|
||||||
JSONArray devices = new JSONArray();
|
JSONArray devices = new JSONArray();
|
||||||
for (String n : folder.deviceIds) {
|
for (String n : folder.getDevices()) {
|
||||||
JSONObject element = new JSONObject();
|
JSONObject element = new JSONObject();
|
||||||
element.put("deviceID", n);
|
element.put("deviceID", n);
|
||||||
devices.put(element);
|
devices.put(element);
|
||||||
}
|
}
|
||||||
r.put("devices", devices);
|
r.put("devices", devices);
|
||||||
JSONObject versioning = new JSONObject();
|
JSONObject versioning = new JSONObject();
|
||||||
versioning.put("type", folder.versioning.getType());
|
versioning.put("type", folder.versioning.type);
|
||||||
JSONObject params = new JSONObject();
|
JSONObject params = new JSONObject();
|
||||||
versioning.put("params", params);
|
versioning.put("params", params);
|
||||||
for (String key : folder.versioning.getParams().keySet()) {
|
for (String key : folder.versioning.params.keySet()) {
|
||||||
params.put(key, folder.versioning.getParams().get(key));
|
params.put(key, folder.versioning.params.get(key));
|
||||||
}
|
}
|
||||||
r.put("rescanIntervalS", folder.rescanIntervalS);
|
r.put("rescanIntervalS", folder.rescanIntervalS);
|
||||||
r.put("versioning", versioning);
|
r.put("versioning", versioning);
|
||||||
|
@ -1002,16 +896,13 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
String normalized = null;
|
JsonObject json = new JsonParser().parse(s).getAsJsonObject();
|
||||||
String error = null;
|
JsonElement id = json.get("id");
|
||||||
try {
|
JsonElement error = json.get("error");
|
||||||
JSONObject json = new JSONObject(s);
|
if (id != null)
|
||||||
normalized = json.optString("id", null);
|
listener.onDeviceIdNormalized(id.getAsString(), null);
|
||||||
error = json.optString("error", null);
|
if (error != null)
|
||||||
} catch (JSONException e) {
|
listener.onDeviceIdNormalized(null, error.getAsString());
|
||||||
Log.w(TAG, "Failed to parse normalized device ID JSON", e);
|
|
||||||
}
|
|
||||||
listener.onDeviceIdNormalized(normalized, error);
|
|
||||||
}
|
}
|
||||||
}.execute("id", id);
|
}.execute("id", id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import android.widget.Toast;
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
import com.nutomic.syncthingandroid.activities.MainActivity;
|
import com.nutomic.syncthingandroid.activities.MainActivity;
|
||||||
import com.nutomic.syncthingandroid.http.PollWebGuiAvailableTask;
|
import com.nutomic.syncthingandroid.http.PollWebGuiAvailableTask;
|
||||||
|
import com.nutomic.syncthingandroid.model.Folder;
|
||||||
import com.nutomic.syncthingandroid.util.ConfigXml;
|
import com.nutomic.syncthingandroid.util.ConfigXml;
|
||||||
import com.nutomic.syncthingandroid.util.FolderObserver;
|
import com.nutomic.syncthingandroid.util.FolderObserver;
|
||||||
import com.android.PRNGFixes;
|
import com.android.PRNGFixes;
|
||||||
|
@ -350,7 +351,7 @@ public class SyncthingService extends Service implements
|
||||||
mCurrentState = State.ACTIVE;
|
mCurrentState = State.ACTIVE;
|
||||||
onApiChange();
|
onApiChange();
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
for (RestApi.Folder r : mApi.getFolders()) {
|
for (Folder r : mApi.getFolders()) {
|
||||||
try {
|
try {
|
||||||
mObservers.add(new FolderObserver(mApi, r));
|
mObservers.add(new FolderObserver(mApi, r));
|
||||||
} catch (FolderObserver.FolderNotExistingException e) {
|
} catch (FolderObserver.FolderNotExistingException e) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.nutomic.syncthingandroid.util;
|
||||||
import android.os.FileObserver;
|
import android.os.FileObserver;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.nutomic.syncthingandroid.model.Folder;
|
||||||
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -17,7 +18,7 @@ public class FolderObserver extends FileObserver {
|
||||||
|
|
||||||
private final OnFolderFileChangeListener mListener;
|
private final OnFolderFileChangeListener mListener;
|
||||||
|
|
||||||
private final RestApi.Folder mFolder;
|
private final Folder mFolder;
|
||||||
|
|
||||||
private final String mPath;
|
private final String mPath;
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ public class FolderObserver extends FileObserver {
|
||||||
public void onFolderFileChange(String folderId, String relativePath);
|
public void onFolderFileChange(String folderId, String relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FolderObserver(OnFolderFileChangeListener listener, RestApi.Folder folder)
|
public FolderObserver(OnFolderFileChangeListener listener, Folder folder)
|
||||||
throws FolderNotExistingException {
|
throws FolderNotExistingException {
|
||||||
this(listener, folder, "");
|
this(listener, folder, "");
|
||||||
}
|
}
|
||||||
|
@ -53,7 +54,7 @@ public class FolderObserver extends FileObserver {
|
||||||
* @param folder The folder where this folder belongs to.
|
* @param folder The folder where this folder belongs to.
|
||||||
* @param path path to the monitored folder, relative to folder root.
|
* @param path path to the monitored folder, relative to folder root.
|
||||||
*/
|
*/
|
||||||
private FolderObserver(OnFolderFileChangeListener listener, RestApi.Folder folder, String path)
|
private FolderObserver(OnFolderFileChangeListener listener, Folder folder, String path)
|
||||||
throws FolderNotExistingException {
|
throws FolderNotExistingException {
|
||||||
super(folder.path + "/" + path,
|
super(folder.path + "/" + path,
|
||||||
ATTRIB | CLOSE_WRITE | CREATE | DELETE | DELETE_SELF | MOVED_FROM |
|
ATTRIB | CLOSE_WRITE | CREATE | DELETE | DELETE_SELF | MOVED_FROM |
|
||||||
|
|
|
@ -12,6 +12,7 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import com.nutomic.syncthingandroid.BuildConfig;
|
import com.nutomic.syncthingandroid.BuildConfig;
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
|
import com.nutomic.syncthingandroid.model.Folder;
|
||||||
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -23,7 +24,7 @@ import static com.nutomic.syncthingandroid.syncthing.RestApi.readableFileSize;
|
||||||
/**
|
/**
|
||||||
* Generates item views for folder items.
|
* Generates item views for folder items.
|
||||||
*/
|
*/
|
||||||
public class FoldersAdapter extends ArrayAdapter<RestApi.Folder>
|
public class FoldersAdapter extends ArrayAdapter<Folder>
|
||||||
implements RestApi.OnReceiveModelListener {
|
implements RestApi.OnReceiveModelListener {
|
||||||
|
|
||||||
private final HashMap<String, RestApi.Model> mModels = new HashMap<>();
|
private final HashMap<String, RestApi.Model> mModels = new HashMap<>();
|
||||||
|
@ -47,7 +48,7 @@ public class FoldersAdapter extends ArrayAdapter<RestApi.Folder>
|
||||||
TextView size = (TextView) convertView.findViewById(R.id.size);
|
TextView size = (TextView) convertView.findViewById(R.id.size);
|
||||||
TextView invalid = (TextView) convertView.findViewById(R.id.invalid);
|
TextView invalid = (TextView) convertView.findViewById(R.id.invalid);
|
||||||
|
|
||||||
RestApi.Folder folder = getItem(position);
|
Folder folder = getItem(position);
|
||||||
RestApi.Model model = mModels.get(folder.id);
|
RestApi.Model model = mModels.get(folder.id);
|
||||||
label.setText(TextUtils.isEmpty(folder.label) ? folder.id : folder.label);
|
label.setText(TextUtils.isEmpty(folder.label) ? folder.id : folder.label);
|
||||||
state.setTextColor(ContextCompat.getColor(getContext(), R.color.text_green));
|
state.setTextColor(ContextCompat.getColor(getContext(), R.color.text_green));
|
||||||
|
|
Loading…
Reference in a new issue