mirror of
https://github.com/syncthing/syncthing-android.git
synced 2025-02-08 01:54:42 +00:00
Added node and repo settings activities.
This commit is contained in:
parent
2ceca738ea
commit
3933740213
20 changed files with 893 additions and 13 deletions
|
@ -45,5 +45,21 @@
|
||||||
|
|
||||||
<service android:name=".syncthing.SyncthingService" />
|
<service android:name=".syncthing.SyncthingService" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".gui.RepoSettingsActivity"
|
||||||
|
android:theme="@style/DialogWhenLargeCompat" >
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
android:value=".gui.MainActivity" />
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".gui.NodeSettingsActivity"
|
||||||
|
android:theme="@style/DialogWhenLargeCompat" >
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
android:value=".gui.MainActivity" />
|
||||||
|
</activity>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.nutomic.syncthingandroid;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.preference.CheckBoxPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves an extra object on construction, which can be retrieved later.
|
||||||
|
*/
|
||||||
|
public class ExtendedCheckBoxPreference extends CheckBoxPreference {
|
||||||
|
|
||||||
|
private final Object mObject;
|
||||||
|
|
||||||
|
public ExtendedCheckBoxPreference(Context context, Object object) {
|
||||||
|
super(context);
|
||||||
|
mObject = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getObject() {
|
||||||
|
return mObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ import android.support.v4.app.ListFragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.ListAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -33,7 +34,7 @@ import com.nutomic.syncthingandroid.syncthing.SyncthingService;
|
||||||
/**
|
/**
|
||||||
* {@link android.support.v4.app.ListFragment} that shows a configurable loading text.
|
* {@link android.support.v4.app.ListFragment} that shows a configurable loading text.
|
||||||
*/
|
*/
|
||||||
public abstract class LoadingListFragment extends Fragment implements RestApi.OnApiAvailableListener {
|
public abstract class LoadingListFragment extends Fragment implements RestApi.OnApiAvailableListener, AdapterView.OnItemClickListener {
|
||||||
|
|
||||||
private boolean mInitialized = false;
|
private boolean mInitialized = false;
|
||||||
|
|
||||||
|
@ -111,6 +112,7 @@ public abstract class LoadingListFragment extends Fragment implements RestApi.On
|
||||||
if (!mInitialized && getActivity() != null &&
|
if (!mInitialized && getActivity() != null &&
|
||||||
activity.getApi() != null && mListFragment != null) {
|
activity.getApi() != null && mListFragment != null) {
|
||||||
onInitAdapter(activity);
|
onInitAdapter(activity);
|
||||||
|
getListView().setOnItemClickListener(this);
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ import com.nutomic.syncthingandroid.syncthing.SyncthingServiceBinder;
|
||||||
* {@link LocalNodeInfoFragment} in the navigation drawer.
|
* {@link LocalNodeInfoFragment} in the navigation drawer.
|
||||||
*/
|
*/
|
||||||
public class MainActivity extends ActionBarActivity
|
public class MainActivity extends ActionBarActivity
|
||||||
implements SyncthingService.OnWebGuiAvailableListener{
|
implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
|
|
||||||
private SyncthingService mSyncthingService;
|
private SyncthingService mSyncthingService;
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ public class MainActivity extends ActionBarActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.menu, menu);
|
getMenuInflater().inflate(R.menu.main_menu, menu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +220,16 @@ public class MainActivity extends ActionBarActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
|
case R.id.add_node:
|
||||||
|
Intent intent = new Intent(this, NodeSettingsActivity.class);
|
||||||
|
intent.setAction(NodeSettingsActivity.ACTION_CREATE);
|
||||||
|
startActivity(intent);
|
||||||
|
return true;
|
||||||
|
case R.id.add_repository:
|
||||||
|
intent = new Intent(this, RepoSettingsActivity.class);
|
||||||
|
intent.setAction(RepoSettingsActivity.ACTION_CREATE);
|
||||||
|
startActivity(intent);
|
||||||
|
return true;
|
||||||
case R.id.web_gui:
|
case R.id.web_gui:
|
||||||
startActivity(new Intent(this, WebGuiActivity.class));
|
startActivity(new Intent(this, WebGuiActivity.class));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,228 @@
|
||||||
|
package com.nutomic.syncthingandroid.gui;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.preference.EditTextPreference;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceActivity;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.nutomic.syncthingandroid.R;
|
||||||
|
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
||||||
|
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
|
||||||
|
import com.nutomic.syncthingandroid.syncthing.SyncthingServiceBinder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows node details and allows changing them.
|
||||||
|
*/
|
||||||
|
public class NodeSettingsActivity extends PreferenceActivity implements
|
||||||
|
Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
|
||||||
|
RestApi.OnReceiveConnectionsListener, RestApi.OnApiAvailableListener {
|
||||||
|
|
||||||
|
public static final String ACTION_CREATE = "create";
|
||||||
|
|
||||||
|
public static final String ACTION_EDIT = "edit";
|
||||||
|
|
||||||
|
public static final String KEY_NODE_ID = "node_id";
|
||||||
|
|
||||||
|
private SyncthingService mSyncthingService;
|
||||||
|
|
||||||
|
private final ServiceConnection mSyncthingServiceConnection = new ServiceConnection() {
|
||||||
|
|
||||||
|
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||||
|
SyncthingServiceBinder binder = (SyncthingServiceBinder) service;
|
||||||
|
mSyncthingService = binder.getService();
|
||||||
|
mSyncthingService.getApi()
|
||||||
|
.registerOnApiAvailableListener(NodeSettingsActivity.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onServiceDisconnected(ComponentName className) {
|
||||||
|
mSyncthingService = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private RestApi.Node mNode;
|
||||||
|
|
||||||
|
private EditTextPreference mNodeId;
|
||||||
|
|
||||||
|
private EditTextPreference mName;
|
||||||
|
|
||||||
|
private EditTextPreference mAddresses;
|
||||||
|
|
||||||
|
private Preference mVersion;
|
||||||
|
|
||||||
|
private Preference mCurrentAddress;
|
||||||
|
|
||||||
|
private Preference mDelete;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
addPreferencesFromResource(R.xml.node_settings);
|
||||||
|
|
||||||
|
mNodeId = (EditTextPreference) findPreference("node_id");
|
||||||
|
mNodeId.setOnPreferenceChangeListener(this);
|
||||||
|
mName = (EditTextPreference) findPreference("name");
|
||||||
|
mName.setOnPreferenceChangeListener(this);
|
||||||
|
mAddresses = (EditTextPreference) findPreference("addresses");
|
||||||
|
mAddresses.setOnPreferenceChangeListener(this);
|
||||||
|
mVersion = findPreference("version");
|
||||||
|
mVersion.setSummary("?");
|
||||||
|
mCurrentAddress = findPreference("current_address");
|
||||||
|
mCurrentAddress.setSummary("?");
|
||||||
|
mDelete = findPreference("delete");
|
||||||
|
mDelete.setOnPreferenceClickListener(this);
|
||||||
|
|
||||||
|
bindService(new Intent(this, SyncthingService.class),
|
||||||
|
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApiAvailable() {
|
||||||
|
if (getIntent().getAction().equals(ACTION_CREATE)) {
|
||||||
|
setTitle(R.string.create_node);
|
||||||
|
mNode = new RestApi.Node();
|
||||||
|
mNode.Name = "";
|
||||||
|
mNode.NodeID = "";
|
||||||
|
mNode.Addresses = "dynamic";
|
||||||
|
getPreferenceScreen().removePreference(mDelete);
|
||||||
|
}
|
||||||
|
else if (getIntent().getAction().equals(ACTION_EDIT)) {
|
||||||
|
setTitle(R.string.edit_node);
|
||||||
|
mNodeId.setEnabled(false);
|
||||||
|
List<RestApi.Node> nodes = mSyncthingService.getApi().getNodes();
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
if (nodes.get(i).NodeID.equals(getIntent().getStringExtra(KEY_NODE_ID))) {
|
||||||
|
mNode = nodes.get(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mSyncthingService.getApi().getConnections(NodeSettingsActivity.this);
|
||||||
|
|
||||||
|
mNodeId.setText(mNode.NodeID);
|
||||||
|
mNodeId.setSummary(mNode.NodeID);
|
||||||
|
mName.setText((mNode.Name));
|
||||||
|
mName.setSummary(mNode.Name);
|
||||||
|
mAddresses.setText(mNode.Addresses);
|
||||||
|
mAddresses.setSummary(mNode.Addresses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.node_settings_menu, menu);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
|
menu.findItem(R.id.create).setVisible(getIntent().getAction().equals(ACTION_CREATE));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.create:
|
||||||
|
if (mNode.NodeID.equals("")) {
|
||||||
|
Toast.makeText(this, R.string.node_id_required, Toast.LENGTH_LONG).show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (mNode.Name.equals("")) {
|
||||||
|
Toast.makeText(this, R.string.node_name_required, Toast.LENGTH_LONG).show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
mSyncthingService.getApi().editNode(mNode, true);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
unbindService(mSyncthingServiceConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||||
|
if (preference instanceof EditTextPreference) {
|
||||||
|
EditTextPreference pref = (EditTextPreference) preference;
|
||||||
|
pref.setSummary((String) o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preference.equals(mNodeId)) {
|
||||||
|
mNode.NodeID = (String) o;
|
||||||
|
nodeUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (preference.equals(mName)) {
|
||||||
|
mNode.Name = (String) o;
|
||||||
|
nodeUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (preference.equals(mAddresses)) {
|
||||||
|
mNode.Addresses = (String) o;
|
||||||
|
nodeUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
if (preference.equals(mDelete)) {
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setMessage(R.string.delete_node_confirm)
|
||||||
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
mSyncthingService.getApi().deleteNode(mNode);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.no, null)
|
||||||
|
.show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets version and current address of the node.
|
||||||
|
*
|
||||||
|
* NOTE: This is only called once on startup, should be called more often to properly display
|
||||||
|
* version/address changes.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onReceiveConnections(Map<String, RestApi.Connection> connections) {
|
||||||
|
if (connections.containsKey(mNode.NodeID)) {
|
||||||
|
mVersion.setSummary(connections.get(mNode.NodeID).ClientVersion);
|
||||||
|
mCurrentAddress.setSummary(connections.get(mNode.NodeID).Address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the updated node info if in edit mode.
|
||||||
|
*/
|
||||||
|
private void nodeUpdated() {
|
||||||
|
if (getIntent().getAction().equals(ACTION_EDIT)) {
|
||||||
|
mSyncthingService.getApi().editNode(mNode, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,11 @@
|
||||||
package com.nutomic.syncthingandroid.gui;
|
package com.nutomic.syncthingandroid.gui;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
import com.nutomic.syncthingandroid.NodeAdapter;
|
import com.nutomic.syncthingandroid.NodeAdapter;
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
||||||
|
@ -12,7 +18,7 @@ import java.util.TimerTask;
|
||||||
* Displays a list of all existing nodes.
|
* Displays a list of all existing nodes.
|
||||||
*/
|
*/
|
||||||
public class NodesFragment extends LoadingListFragment implements
|
public class NodesFragment extends LoadingListFragment implements
|
||||||
RestApi.OnApiAvailableListener {
|
RestApi.OnApiAvailableListener, ListView.OnItemClickListener {
|
||||||
|
|
||||||
private NodeAdapter mAdapter;
|
private NodeAdapter mAdapter;
|
||||||
|
|
||||||
|
@ -58,4 +64,12 @@ public class NodesFragment extends LoadingListFragment implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||||
|
Intent intent = new Intent(getActivity(), NodeSettingsActivity.class);
|
||||||
|
intent.setAction(NodeSettingsActivity.ACTION_EDIT);
|
||||||
|
intent.putExtra(NodeSettingsActivity.KEY_NODE_ID, mAdapter.getItem(i).NodeID);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,280 @@
|
||||||
|
package com.nutomic.syncthingandroid.gui;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.preference.CheckBoxPreference;
|
||||||
|
import android.preference.EditTextPreference;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceActivity;
|
||||||
|
import android.preference.PreferenceScreen;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.nutomic.syncthingandroid.ExtendedCheckBoxPreference;
|
||||||
|
import com.nutomic.syncthingandroid.R;
|
||||||
|
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
||||||
|
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
|
||||||
|
import com.nutomic.syncthingandroid.syncthing.SyncthingServiceBinder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows repo details and allows changing them.
|
||||||
|
*/
|
||||||
|
public class RepoSettingsActivity extends PreferenceActivity
|
||||||
|
implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
|
||||||
|
RestApi.OnApiAvailableListener {
|
||||||
|
|
||||||
|
public static final String ACTION_CREATE = "create";
|
||||||
|
|
||||||
|
public static final String ACTION_EDIT = "edit";
|
||||||
|
|
||||||
|
public static final String KEY_REPOSITORY_ID = "repository_id";
|
||||||
|
|
||||||
|
private static final String KEY_NODE_SHARED = "node_shared";
|
||||||
|
|
||||||
|
private SyncthingService mSyncthingService;
|
||||||
|
|
||||||
|
private final ServiceConnection mSyncthingServiceConnection = new ServiceConnection() {
|
||||||
|
|
||||||
|
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||||
|
SyncthingServiceBinder binder = (SyncthingServiceBinder) service;
|
||||||
|
mSyncthingService = binder.getService();
|
||||||
|
mSyncthingService.getApi()
|
||||||
|
.registerOnApiAvailableListener(RepoSettingsActivity.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onServiceDisconnected(ComponentName className) {
|
||||||
|
mSyncthingService = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private RestApi.Repository mRepository;
|
||||||
|
|
||||||
|
private EditTextPreference mRepositoryId;
|
||||||
|
|
||||||
|
private EditTextPreference mDirectory;
|
||||||
|
|
||||||
|
private CheckBoxPreference mRepositoryMaster;
|
||||||
|
|
||||||
|
private PreferenceScreen mNodes;
|
||||||
|
|
||||||
|
private CheckBoxPreference mVersioning;
|
||||||
|
|
||||||
|
private EditTextPreference mVersioningKeep;
|
||||||
|
|
||||||
|
private Preference mDelete;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
addPreferencesFromResource(R.xml.repo_settings);
|
||||||
|
|
||||||
|
mRepositoryId = (EditTextPreference) findPreference("repository_id");
|
||||||
|
mRepositoryId.setOnPreferenceChangeListener(this);
|
||||||
|
mDirectory = (EditTextPreference) findPreference("directory");
|
||||||
|
mDirectory.setOnPreferenceChangeListener(this);
|
||||||
|
mRepositoryMaster = (CheckBoxPreference) findPreference("repository_master");
|
||||||
|
mRepositoryMaster.setOnPreferenceChangeListener(this);
|
||||||
|
mNodes = (PreferenceScreen) findPreference("nodes");
|
||||||
|
mVersioning = (CheckBoxPreference) findPreference("versioning");
|
||||||
|
mVersioning.setOnPreferenceChangeListener(this);
|
||||||
|
mVersioningKeep = (EditTextPreference) findPreference("versioning_keep");
|
||||||
|
mVersioningKeep.setOnPreferenceChangeListener(this);
|
||||||
|
mDelete = findPreference("delete");
|
||||||
|
mDelete.setOnPreferenceClickListener(this);
|
||||||
|
|
||||||
|
bindService(new Intent(this, SyncthingService.class),
|
||||||
|
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApiAvailable() {
|
||||||
|
if (getIntent().getAction().equals(ACTION_CREATE)) {
|
||||||
|
setTitle(R.string.create_repo);
|
||||||
|
mRepository = new RestApi.Repository();
|
||||||
|
mRepository.ID = "";
|
||||||
|
mRepository.Directory = "";
|
||||||
|
mRepository.Nodes = new ArrayList<RestApi.Node>();
|
||||||
|
mRepository.Versioning = new RestApi.Versioning();
|
||||||
|
getPreferenceScreen().removePreference(mDelete);
|
||||||
|
}
|
||||||
|
else if (getIntent().getAction().equals(ACTION_EDIT)) {
|
||||||
|
setTitle(R.string.edit_repo);
|
||||||
|
mRepositoryId.setEnabled(false);
|
||||||
|
List<RestApi.Repository> repos = mSyncthingService.getApi().getRepositories();
|
||||||
|
for (int i = 0; i < repos.size(); i++) {
|
||||||
|
if (repos.get(i).ID.equals(getIntent().getStringExtra(KEY_REPOSITORY_ID))) {
|
||||||
|
mRepository = repos.get(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mRepositoryId.setText(mRepository.ID);
|
||||||
|
mRepositoryId.setSummary(mRepository.ID);
|
||||||
|
mDirectory.setText(mRepository.Directory);
|
||||||
|
mDirectory.setSummary(mRepository.Directory);
|
||||||
|
mRepositoryMaster.setChecked(mRepository.ReadOnly);
|
||||||
|
List<RestApi.Node> nodesList = mSyncthingService.getApi().getNodes();
|
||||||
|
for (RestApi.Node n : nodesList) {
|
||||||
|
ExtendedCheckBoxPreference cbp =
|
||||||
|
new ExtendedCheckBoxPreference(RepoSettingsActivity.this, n);
|
||||||
|
cbp.setTitle(n.Name);
|
||||||
|
cbp.setKey(KEY_NODE_SHARED);
|
||||||
|
cbp.setOnPreferenceChangeListener(RepoSettingsActivity.this);
|
||||||
|
cbp.setChecked(false);
|
||||||
|
for (RestApi.Node n2 : mRepository.Nodes) {
|
||||||
|
if (n2.NodeID.equals(n.NodeID)) {
|
||||||
|
cbp.setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mNodes.addPreference(cbp);
|
||||||
|
}
|
||||||
|
mVersioning.setChecked(mRepository.Versioning instanceof RestApi.SimpleVersioning);
|
||||||
|
if (mVersioning.isChecked()) {
|
||||||
|
mVersioningKeep.setText(mRepository.Versioning.getParams().get("keep"));
|
||||||
|
mVersioningKeep.setSummary(mRepository.Versioning.getParams().get("keep"));
|
||||||
|
mVersioningKeep.setEnabled(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mVersioningKeep.setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.repo_settings_menu, menu);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
|
menu.findItem(R.id.create).setVisible(getIntent().getAction().equals(ACTION_CREATE));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.create:
|
||||||
|
if (mRepository.ID.equals("")) {
|
||||||
|
Toast.makeText(this, R.string.repo_id_required, Toast.LENGTH_LONG).show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (mRepository.Directory.equals("")) {
|
||||||
|
Toast.makeText(this, R.string.repo_path_required, Toast.LENGTH_LONG).show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
mSyncthingService.getApi().editRepository(mRepository, true);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
unbindService(mSyncthingServiceConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||||
|
if (preference instanceof EditTextPreference) {
|
||||||
|
EditTextPreference pref = (EditTextPreference) preference;
|
||||||
|
pref.setSummary((String) o);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preference.equals(mRepositoryId)) {
|
||||||
|
mRepository.ID = (String) o;
|
||||||
|
repositoryUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (preference.equals(mDirectory)) {
|
||||||
|
mRepository.Directory = (String) o;
|
||||||
|
repositoryUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (preference.equals(mRepositoryMaster)) {
|
||||||
|
mRepository.ReadOnly = (Boolean) o;
|
||||||
|
repositoryUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (preference.getKey().equals(KEY_NODE_SHARED)) {
|
||||||
|
ExtendedCheckBoxPreference pref = (ExtendedCheckBoxPreference) preference;
|
||||||
|
RestApi.Node node = (RestApi.Node) pref.getObject();
|
||||||
|
if ((Boolean) o) {
|
||||||
|
mRepository.Nodes.add(node);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (RestApi.Node n : mRepository.Nodes) {
|
||||||
|
if (n.NodeID.equals(node.NodeID)) {
|
||||||
|
mRepository.Nodes.remove(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
repositoryUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (preference.equals(mVersioning)) {
|
||||||
|
mVersioningKeep.setEnabled((Boolean) o);
|
||||||
|
if ((Boolean) o) {
|
||||||
|
RestApi.SimpleVersioning v = new RestApi.SimpleVersioning();
|
||||||
|
mRepository.Versioning = v;
|
||||||
|
v.setParams(5);
|
||||||
|
mVersioningKeep.setText("5");
|
||||||
|
mVersioningKeep.setSummary("5");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mRepository.Versioning = new RestApi.Versioning();
|
||||||
|
}
|
||||||
|
repositoryUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (preference.equals(mVersioningKeep)) {
|
||||||
|
((RestApi.SimpleVersioning) mRepository.Versioning)
|
||||||
|
.setParams(Integer.parseInt((String) o));
|
||||||
|
repositoryUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
if (preference.equals(mDelete)) {
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setMessage(R.string.delete_repo_confirm)
|
||||||
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
mSyncthingService.getApi().deleteRepository(mRepository);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.no, null)
|
||||||
|
.show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void repositoryUpdated() {
|
||||||
|
if (getIntent().getAction().equals(ACTION_EDIT)) {
|
||||||
|
mSyncthingService.getApi().editRepository(mRepository, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,9 @@
|
||||||
package com.nutomic.syncthingandroid.gui;
|
package com.nutomic.syncthingandroid.gui;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
import com.nutomic.syncthingandroid.RepositoryAdapter;
|
import com.nutomic.syncthingandroid.RepositoryAdapter;
|
||||||
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
||||||
|
@ -12,7 +16,7 @@ import java.util.TimerTask;
|
||||||
* Displays a list of all existing repositories.
|
* Displays a list of all existing repositories.
|
||||||
*/
|
*/
|
||||||
public class RepositoriesFragment extends LoadingListFragment implements
|
public class RepositoriesFragment extends LoadingListFragment implements
|
||||||
RestApi.OnApiAvailableListener {
|
RestApi.OnApiAvailableListener, AdapterView.OnItemClickListener {
|
||||||
|
|
||||||
private RepositoryAdapter mAdapter;
|
private RepositoryAdapter mAdapter;
|
||||||
|
|
||||||
|
@ -58,4 +62,11 @@ public class RepositoriesFragment extends LoadingListFragment implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||||
|
Intent intent = new Intent(getActivity(), RepoSettingsActivity.class);
|
||||||
|
intent.setAction(RepoSettingsActivity.ACTION_EDIT);
|
||||||
|
intent.putExtra(RepoSettingsActivity.KEY_REPOSITORY_ID, mAdapter.getItem(i).ID);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.nutomic.syncthingandroid.gui;
|
package com.nutomic.syncthingandroid.gui;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -93,6 +94,7 @@ public class SettingsActivity extends PreferenceActivity
|
||||||
* Manual target API as we manually check if ActionBar is available (for ActionBar back button).
|
* Manual target API as we manually check if ActionBar is available (for ActionBar back button).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressLint("AppCompatMethod")
|
||||||
@TargetApi(11)
|
@TargetApi(11)
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -106,7 +108,7 @@ public class SettingsActivity extends PreferenceActivity
|
||||||
bindService(new Intent(this, SyncthingService.class),
|
bindService(new Intent(this, SyncthingService.class),
|
||||||
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
|
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.settings);
|
addPreferencesFromResource(R.xml.app_settings);
|
||||||
PreferenceScreen screen = getPreferenceScreen();
|
PreferenceScreen screen = getPreferenceScreen();
|
||||||
mVersion = screen.findPreference(SYNCTHING_VERSION_KEY);
|
mVersion = screen.findPreference(SYNCTHING_VERSION_KEY);
|
||||||
mOptionsScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_OPTIONS_KEY);
|
mOptionsScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_OPTIONS_KEY);
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class PostTask extends AsyncTask<String, Void, Void> {
|
||||||
post.addHeader(new BasicHeader("X-API-Key", params[2]));
|
post.addHeader(new BasicHeader("X-API-Key", params[2]));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (params.length > 2) {
|
if (params.length > 3) {
|
||||||
post.setEntity(new StringEntity(params[3]));
|
post.setEntity(new StringEntity(params[3]));
|
||||||
}
|
}
|
||||||
httpclient.execute(post);
|
httpclient.execute(post);
|
||||||
|
|
|
@ -5,9 +5,12 @@ import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.nutomic.syncthingandroid.BuildConfig;
|
||||||
import com.nutomic.syncthingandroid.R;
|
import com.nutomic.syncthingandroid.R;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
@ -63,7 +66,6 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
public static class Repository {
|
public static class Repository {
|
||||||
public String Directory;
|
public String Directory;
|
||||||
public String ID;
|
public String ID;
|
||||||
public final boolean IgnorePerms = true;
|
|
||||||
public String Invalid;
|
public String Invalid;
|
||||||
public List<Node> Nodes;
|
public List<Node> Nodes;
|
||||||
public boolean ReadOnly;
|
public boolean ReadOnly;
|
||||||
|
@ -236,14 +238,14 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
*/
|
*/
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
mNotificationManager.cancel(NOTIFICATION_RESTART);
|
mNotificationManager.cancel(NOTIFICATION_RESTART);
|
||||||
new PostTask().execute(mUrl, PostTask.URI_SHUTDOWN, mApiKey, "");
|
new PostTask().execute(mUrl, PostTask.URI_SHUTDOWN, mApiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restarts the syncthing binary.
|
* Restarts the syncthing binary.
|
||||||
*/
|
*/
|
||||||
public void restart() {
|
public void restart() {
|
||||||
new PostTask().execute(mUrl, PostTask.URI_RESTART);
|
new PostTask().execute(mUrl, PostTask.URI_RESTART, mApiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -307,7 +309,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
* Sends the updated mConfig via Rest API to syncthing and displays a "restart" notification.
|
* Sends the updated mConfig via Rest API to syncthing and displays a "restart" notification.
|
||||||
*/
|
*/
|
||||||
private void configUpdated() {
|
private void configUpdated() {
|
||||||
new PostTask().execute(mUrl, PostTask.URI_CONFIG, mConfig.toString());
|
new PostTask().execute(mUrl, PostTask.URI_CONFIG, mApiKey, mConfig.toString());
|
||||||
|
|
||||||
Intent i = new Intent(mContext, SyncthingService.class)
|
Intent i = new Intent(mContext, SyncthingService.class)
|
||||||
.setAction(SyncthingService.ACTION_RESTART);
|
.setAction(SyncthingService.ACTION_RESTART);
|
||||||
|
@ -352,6 +354,9 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
new GetTask() {
|
new GetTask() {
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(String s) {
|
protected void onPostExecute(String s) {
|
||||||
|
if (s == null)
|
||||||
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JSONObject system = new JSONObject(s);
|
JSONObject system = new JSONObject(s);
|
||||||
SystemInfo si = new SystemInfo();
|
SystemInfo si = new SystemInfo();
|
||||||
|
@ -395,6 +400,9 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
* Returns a list of all existing repositores.
|
* Returns a list of all existing repositores.
|
||||||
*/
|
*/
|
||||||
public List<Repository> getRepositories() {
|
public List<Repository> getRepositories() {
|
||||||
|
if (mConfig == null)
|
||||||
|
return new ArrayList<Repository>();
|
||||||
|
|
||||||
List<Repository> ret = null;
|
List<Repository> ret = null;
|
||||||
try {
|
try {
|
||||||
JSONArray repos = mConfig.getJSONArray("Repositories");
|
JSONArray repos = mConfig.getJSONArray("Repositories");
|
||||||
|
@ -404,16 +412,16 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
Repository r = new Repository();
|
Repository r = new Repository();
|
||||||
r.Directory = json.getString("Directory");
|
r.Directory = json.getString("Directory");
|
||||||
r.ID = json.getString("ID");
|
r.ID = json.getString("ID");
|
||||||
// Hardcoded to true because missing permissions support.
|
|
||||||
// r.IgnorePerms = json.getBoolean("IgnorePerms");
|
|
||||||
r.Invalid = json.getString("Invalid");
|
r.Invalid = json.getString("Invalid");
|
||||||
r.Nodes = getNodes(json.getJSONArray("Nodes"));
|
r.Nodes = getNodes(json.getJSONArray("Nodes"));
|
||||||
|
|
||||||
r.ReadOnly = json.getBoolean("ReadOnly");
|
r.ReadOnly = json.getBoolean("ReadOnly");
|
||||||
JSONObject versioning = json.getJSONObject("Versioning");
|
JSONObject versioning = json.getJSONObject("Versioning");
|
||||||
if (versioning.getString("Type").equals("simple")) {
|
if (versioning.getString("Type").equals("simple")) {
|
||||||
|
Log.d(TAG, mConfig.toString());
|
||||||
SimpleVersioning sv = new SimpleVersioning();
|
SimpleVersioning sv = new SimpleVersioning();
|
||||||
JSONObject params = versioning.getJSONObject("Params");
|
JSONObject params = versioning.getJSONObject("Params");
|
||||||
|
Log.d(TAG, params.toString());
|
||||||
sv.setParams(params.getInt("keep"));
|
sv.setParams(params.getInt("keep"));
|
||||||
r.Versioning = sv;
|
r.Versioning = sv;
|
||||||
}
|
}
|
||||||
|
@ -486,6 +494,9 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
new GetTask() {
|
new GetTask() {
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(String s) {
|
protected void onPostExecute(String s) {
|
||||||
|
if (s == null)
|
||||||
|
return;
|
||||||
|
|
||||||
Long now = System.currentTimeMillis();
|
Long now = System.currentTimeMillis();
|
||||||
Long difference = (now - mPreviousConnectionTime) / 1000;
|
Long difference = (now - mPreviousConnectionTime) / 1000;
|
||||||
if (difference < 1) {
|
if (difference < 1) {
|
||||||
|
@ -547,6 +558,9 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
new GetTask() {
|
new GetTask() {
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(String s) {
|
protected void onPostExecute(String s) {
|
||||||
|
if (s == null)
|
||||||
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JSONObject json = new JSONObject(s);
|
JSONObject json = new JSONObject(s);
|
||||||
Model m = new Model();
|
Model m = new Model();
|
||||||
|
@ -571,4 +585,128 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
||||||
}.execute(mUrl, GetTask.URI_MODEL, mApiKey, "repo", repoId);
|
}.execute(mUrl, GetTask.URI_MODEL, mApiKey, "repo", repoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates or creates the given node.
|
||||||
|
*/
|
||||||
|
public void editNode(Node node, boolean create) {
|
||||||
|
try {
|
||||||
|
JSONArray nodes = mConfig.getJSONArray("Nodes");
|
||||||
|
JSONObject n = null;
|
||||||
|
if (create) {
|
||||||
|
n = new JSONObject();
|
||||||
|
nodes.put(n);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int i = 0; i < nodes.length(); i++) {
|
||||||
|
JSONObject json = nodes.getJSONObject(i);
|
||||||
|
if (node.NodeID.equals(json.getString("NodeID"))) {
|
||||||
|
n = nodes.getJSONObject(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n.put("NodeID", node.NodeID);
|
||||||
|
n.put("Name", node.Name);
|
||||||
|
n.put("Addresses", listToJson(node.Addresses.split(" ")));
|
||||||
|
Log.d(TAG, n.toString());
|
||||||
|
Log.d(TAG, nodes.toString());
|
||||||
|
configUpdated();
|
||||||
|
}
|
||||||
|
catch (JSONException e) {
|
||||||
|
Log.w(TAG, "Failed to read nodes", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteNode(Node node) {
|
||||||
|
try {
|
||||||
|
JSONArray nodes = mConfig.getJSONArray("Nodes");
|
||||||
|
|
||||||
|
for (int i = 0; i < nodes.length(); i++) {
|
||||||
|
JSONObject json = nodes.getJSONObject(i);
|
||||||
|
if (node.NodeID.equals(json.getString("NodeID"))) {
|
||||||
|
mConfig.remove("Nodes");
|
||||||
|
mConfig.put("Nodes", delete(nodes, nodes.getJSONObject(i)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
configUpdated();
|
||||||
|
}
|
||||||
|
catch (JSONException e) {
|
||||||
|
Log.w(TAG, "Failed to edit repo", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void editRepository(Repository repository, boolean create) {
|
||||||
|
try {
|
||||||
|
JSONArray repos = mConfig.getJSONArray("Repositories");
|
||||||
|
JSONObject r = null;
|
||||||
|
if (create) {
|
||||||
|
r = new JSONObject();
|
||||||
|
repos.put(r);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int i = 0; i < repos.length(); i++) {
|
||||||
|
JSONObject json = repos.getJSONObject(i);
|
||||||
|
if (repository.ID.equals(json.getString("ID"))) {
|
||||||
|
r = repos.getJSONObject(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.put("Directory", repository.Directory);
|
||||||
|
r.put("ID", repository.ID);
|
||||||
|
r.put("ReadOnly", repository.ReadOnly);
|
||||||
|
JSONArray nodes = new JSONArray();
|
||||||
|
for (Node n : repository.Nodes) {
|
||||||
|
JSONObject element = new JSONObject();
|
||||||
|
element.put("Addresses", n.Addresses);
|
||||||
|
element.put("Name", n.Name);
|
||||||
|
element.put("NodeID", n.NodeID);
|
||||||
|
nodes.put(element);
|
||||||
|
}
|
||||||
|
r.put("Nodes", nodes);
|
||||||
|
JSONObject versioning = new JSONObject();
|
||||||
|
versioning.put("Type", repository.Versioning.getType());
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
versioning.put("Params", params);
|
||||||
|
for (String key : repository.Versioning.getParams().keySet()) {
|
||||||
|
params.put(key, repository.Versioning.getParams().get(key));
|
||||||
|
}
|
||||||
|
r.put("Versioning", versioning);
|
||||||
|
configUpdated();
|
||||||
|
}
|
||||||
|
catch (JSONException e) {
|
||||||
|
Log.w(TAG, "Failed to edit repo " + repository.ID + " at " + repository.Directory, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteRepository(Repository repository) {
|
||||||
|
try {
|
||||||
|
JSONArray repos = mConfig.getJSONArray("Repositories");
|
||||||
|
|
||||||
|
for (int i = 0; i < repos.length(); i++) {
|
||||||
|
JSONObject json = repos.getJSONObject(i);
|
||||||
|
if (repository.ID.equals(json.getString("ID"))) {
|
||||||
|
mConfig.remove("Repositories");
|
||||||
|
mConfig.put("Repositories", delete(repos, repos.getJSONObject(i)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
configUpdated();
|
||||||
|
}
|
||||||
|
catch (JSONException e) {
|
||||||
|
Log.w(TAG, "Failed to edit repo", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONArray delete(JSONArray array, JSONObject delete) throws JSONException {
|
||||||
|
JSONArray newArray = new JSONArray();
|
||||||
|
for (int i = 0; i < array.length(); i++) {
|
||||||
|
if (!array.getJSONObject(i).equals(delete)) {
|
||||||
|
newArray.put(array.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newArray;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,18 @@
|
||||||
android:icon="@android:drawable/ic_menu_share"
|
android:icon="@android:drawable/ic_menu_share"
|
||||||
android:title="@string/share_node_id"
|
android:title="@string/share_node_id"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/add_repository"
|
||||||
|
android:title="@string/add_repo"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/add_node"
|
||||||
|
android:title="@string/add_node"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/web_gui"
|
android:id="@+id/web_gui"
|
||||||
android:title="@string/web_gui_title" />
|
android:title="@string/web_gui_title" />
|
8
src/main/res/menu/node_settings_menu.xml
Normal file
8
src/main/res/menu/node_settings_menu.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/create"
|
||||||
|
android:title="@string/create" />
|
||||||
|
</menu>
|
8
src/main/res/menu/repo_settings_menu.xml
Normal file
8
src/main/res/menu/repo_settings_menu.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/create"
|
||||||
|
android:title="@string/create" />
|
||||||
|
</menu>
|
4
src/main/res/values-large/styles.xml
Normal file
4
src/main/res/values-large/styles.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="DialogWhenLargeCompat" parent="android:Theme.Holo.DialogWhenLarge" />
|
||||||
|
</resources>
|
|
@ -12,6 +12,14 @@
|
||||||
<!-- ActionBar title shown when the drawer is open -->
|
<!-- ActionBar title shown when the drawer is open -->
|
||||||
<string name="system_info">System Info</string>
|
<string name="system_info">System Info</string>
|
||||||
|
|
||||||
|
<!-- MainActivity -->
|
||||||
|
|
||||||
|
<!-- Title of the "add repo" menu action -->
|
||||||
|
<string name="add_repo">Add Repository</string>
|
||||||
|
|
||||||
|
<!-- Title of the "add node" menu action -->
|
||||||
|
<string name="add_node">Add Node</string>
|
||||||
|
|
||||||
<!-- Title of the "share node id" menu action -->
|
<!-- Title of the "share node id" menu action -->
|
||||||
<string name="share_node_id">Share Node ID</string>
|
<string name="share_node_id">Share Node ID</string>
|
||||||
|
|
||||||
|
@ -70,6 +78,43 @@
|
||||||
<!-- Title for announce server status -->
|
<!-- Title for announce server status -->
|
||||||
<string name="announce_server">Announce Server</string>
|
<string name="announce_server">Announce Server</string>
|
||||||
|
|
||||||
|
<!-- RepoSettingsActivity -->
|
||||||
|
|
||||||
|
<!-- Title for RepoSettingsActivity in create mode -->
|
||||||
|
<string name="create_repo">Create Repository</string>
|
||||||
|
|
||||||
|
<!-- Title for RepoSettingsActivity in edit mode -->
|
||||||
|
<string name="edit_repo">Edit Repository</string>
|
||||||
|
|
||||||
|
<!-- Used to confirm repo/node creation -->
|
||||||
|
<string name="create">Create</string>
|
||||||
|
|
||||||
|
<!-- Dialog shown when attempting to delete a repository -->
|
||||||
|
<string name="delete_repo_confirm">Do you really want to delete this repository?</string>
|
||||||
|
|
||||||
|
<!-- Toast shown when trying to create a repository with an empty ID -->
|
||||||
|
<string name="repo_id_required">The repository ID must not be empty</string>
|
||||||
|
|
||||||
|
<!-- Toast shown when trying to create a repository with an empty path -->
|
||||||
|
<string name="repo_path_required">The repository path must not be empty</string>
|
||||||
|
|
||||||
|
<!-- NodeSettingsActivity -->
|
||||||
|
|
||||||
|
<!-- Title for NodeSettingsActivity in create mode -->
|
||||||
|
<string name="create_node">Create Node</string>
|
||||||
|
|
||||||
|
<!-- Title for NodeSettingsActivity in edit mode -->
|
||||||
|
<string name="edit_node">Edit Node</string>
|
||||||
|
|
||||||
|
<!-- Dialog shown when attempting to delete a node -->
|
||||||
|
<string name="delete_node_confirm">Do you really want to delete this node?</string>
|
||||||
|
|
||||||
|
<!-- Toast shown when trying to create a node with an empty ID -->
|
||||||
|
<string name="node_id_required">The node ID must not be empty</string>
|
||||||
|
|
||||||
|
<!-- Toast shown when trying to create a node with an empty name -->
|
||||||
|
<string name="node_name_required">The node name must not be empty</string>
|
||||||
|
|
||||||
<!-- WebGuiActivity -->
|
<!-- WebGuiActivity -->
|
||||||
|
|
||||||
<!-- Title of the web gui activity -->
|
<!-- Title of the web gui activity -->
|
||||||
|
|
10
src/main/res/values/styles.xml
Normal file
10
src/main/res/values/styles.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="MyAppCompatDialogTheme" parent="DialogWhenLargeCompat">
|
||||||
|
<item name="android:windowIsFloating">false</item>
|
||||||
|
<item name="android:windowContentOverlay">@null</item>
|
||||||
|
<item name="android:windowSoftInputMode">stateAlwaysHidden</item>
|
||||||
|
<!--<item name="android:windowActionModeOverlay">true</item>-->
|
||||||
|
<item name="android:windowIsTranslucent">true</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
34
src/main/res/xml/node_settings.xml
Normal file
34
src/main/res/xml/node_settings.xml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:persistent="false" >
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="node_id"
|
||||||
|
android:title="Node ID"
|
||||||
|
android:text="7TGPF3-AYRIE6-YVAHJN-TYWH5D-KFDF6B-7JUHMI-LNIC2S-YE5QIV-FH2Q" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="name"
|
||||||
|
android:title="Name"
|
||||||
|
android:text="laptop" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="addresses"
|
||||||
|
android:title="Addresses"
|
||||||
|
android:text="dynamic" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="version"
|
||||||
|
android:title="@string/syncthing_version_title"
|
||||||
|
style="?android:preferenceInformationStyle" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="current_address"
|
||||||
|
android:title="Current Address"
|
||||||
|
style="?android:preferenceInformationStyle" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="delete"
|
||||||
|
android:title="Delete Node" />
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
36
src/main/res/xml/repo_settings.xml
Normal file
36
src/main/res/xml/repo_settings.xml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:persistent="false" >
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="repository_id"
|
||||||
|
android:title="Repository ID"
|
||||||
|
android:text="default" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="directory"
|
||||||
|
android:title="Directory"
|
||||||
|
android:text="/sdcard/syncthing/" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="repository_master"
|
||||||
|
android:title="Repository Master" />
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
android:key="nodes"
|
||||||
|
android:title="Nodes" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="versioning"
|
||||||
|
android:title="File Versioning" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="versioning_keep"
|
||||||
|
android:title="Keep Versions"
|
||||||
|
android:inputType="numberDecimal" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="delete"
|
||||||
|
android:title="Delete Repository" />
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
Loading…
Reference in a new issue