diff --git a/src/androidTest/java/com/nutomic/syncthingandroid/test/activities/MainActivityTest.java b/src/androidTest/java/com/nutomic/syncthingandroid/test/activities/MainActivityTest.java
index 18b075ff..5d29ed43 100644
--- a/src/androidTest/java/com/nutomic/syncthingandroid/test/activities/MainActivityTest.java
+++ b/src/androidTest/java/com/nutomic/syncthingandroid/test/activities/MainActivityTest.java
@@ -3,7 +3,7 @@ package com.nutomic.syncthingandroid.test.activities;
import android.test.ActivityInstrumentationTestCase2;
import com.nutomic.syncthingandroid.activities.MainActivity;
-import com.nutomic.syncthingandroid.fragments.DevicesFragment;
+import com.nutomic.syncthingandroid.fragments.DeviceListFragment;
import com.nutomic.syncthingandroid.fragments.FolderListFragment;
import com.nutomic.syncthingandroid.syncthing.SyncthingServiceBinder;
import com.nutomic.syncthingandroid.test.MockSyncthingService;
@@ -20,7 +20,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2
+ android:theme="@style/Theme.Syncthing.Translucent"
+ android:launchMode="singleTop"/>
diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/MainActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/MainActivity.java
index d725b289..37b37689 100644
--- a/src/main/java/com/nutomic/syncthingandroid/activities/MainActivity.java
+++ b/src/main/java/com/nutomic/syncthingandroid/activities/MainActivity.java
@@ -33,7 +33,7 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.nutomic.syncthingandroid.R;
-import com.nutomic.syncthingandroid.fragments.DevicesFragment;
+import com.nutomic.syncthingandroid.fragments.DeviceListFragment;
import com.nutomic.syncthingandroid.fragments.DrawerFragment;
import com.nutomic.syncthingandroid.fragments.FolderListFragment;
import com.nutomic.syncthingandroid.syncthing.RestApi;
@@ -45,8 +45,8 @@ import static java.lang.Math.min;
/**
* Shows {@link FolderListFragment} and
- * {@link com.nutomic.syncthingandroid.fragments.DevicesFragment} in different tabs, and
- * {@link com.nutomic.syncthingandroid.fragments.DrawerFragment} in the navigation drawer.
+ * {@link DeviceListFragment} in different tabs, and
+ * {@link DrawerFragment} in the navigation drawer.
*/
public class MainActivity extends SyncthingActivity
implements SyncthingService.OnApiChangeListener {
@@ -161,9 +161,9 @@ public class MainActivity extends SyncthingActivity
public Fragment getItem(int position) {
switch (position) {
case 0:
- return mFolderFragment;
+ return mFolderListFragment;
case 1:
- return mDevicesFragment;
+ return mDeviceListFragment;
default:
return null;
}
@@ -187,9 +187,9 @@ public class MainActivity extends SyncthingActivity
}
};
- private FolderListFragment mFolderFragment;
+ private FolderListFragment mFolderListFragment;
- private DevicesFragment mDevicesFragment;
+ private DeviceListFragment mDeviceListFragment;
private DrawerFragment mDrawerFragment;
@@ -216,16 +216,16 @@ public class MainActivity extends SyncthingActivity
if (savedInstanceState != null) {
FragmentManager fm = getSupportFragmentManager();
- mFolderFragment = (FolderListFragment) fm.getFragment(
+ mFolderListFragment = (FolderListFragment) fm.getFragment(
savedInstanceState, FolderListFragment.class.getName());
- mDevicesFragment = (DevicesFragment) fm.getFragment(
- savedInstanceState, DevicesFragment.class.getName());
+ mDeviceListFragment = (DeviceListFragment) fm.getFragment(
+ savedInstanceState, DeviceListFragment.class.getName());
mDrawerFragment = (DrawerFragment) fm.getFragment(
savedInstanceState, DrawerFragment.class.getName());
mViewPager.setCurrentItem(savedInstanceState.getInt("currentTab"));
} else {
- mFolderFragment = new FolderListFragment();
- mDevicesFragment = new DevicesFragment();
+ mFolderListFragment = new FolderListFragment();
+ mDeviceListFragment = new DeviceListFragment();
mDrawerFragment = new DrawerFragment();
}
@@ -247,8 +247,8 @@ public class MainActivity extends SyncthingActivity
}
if (getService() != null) {
getService().unregisterOnApiChangeListener(this);
- getService().unregisterOnApiChangeListener(mFolderFragment);
- getService().unregisterOnApiChangeListener(mDevicesFragment);
+ getService().unregisterOnApiChangeListener(mFolderListFragment);
+ getService().unregisterOnApiChangeListener(mDeviceListFragment);
}
}
@@ -256,8 +256,8 @@ public class MainActivity extends SyncthingActivity
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
super.onServiceConnected(componentName, iBinder);
getService().registerOnApiChangeListener(this);
- getService().registerOnApiChangeListener(mFolderFragment);
- getService().registerOnApiChangeListener(mDevicesFragment);
+ getService().registerOnApiChangeListener(mFolderListFragment);
+ getService().registerOnApiChangeListener(mDeviceListFragment);
}
/**
@@ -267,10 +267,10 @@ public class MainActivity extends SyncthingActivity
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Avoid crash if called during startup.
- if (mFolderFragment != null && mDevicesFragment != null && mDrawerFragment != null) {
+ if (mFolderListFragment != null && mDeviceListFragment != null && mDrawerFragment != null) {
FragmentManager fm = getSupportFragmentManager();
- fm.putFragment(outState, FolderListFragment.class.getName(), mFolderFragment);
- fm.putFragment(outState, DevicesFragment.class.getName(), mDevicesFragment);
+ fm.putFragment(outState, FolderListFragment.class.getName(), mFolderListFragment);
+ fm.putFragment(outState, DeviceListFragment.class.getName(), mDeviceListFragment);
fm.putFragment(outState, DrawerFragment.class.getName(), mDrawerFragment);
outState.putInt("currentTab", mViewPager.getCurrentItem());
}
diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java
index 17892e81..a1129f6f 100644
--- a/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java
+++ b/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java
@@ -3,10 +3,9 @@ package com.nutomic.syncthingandroid.activities;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
-import android.view.View;
import com.nutomic.syncthingandroid.R;
-import com.nutomic.syncthingandroid.fragments.DeviceSettingsFragment;
+import com.nutomic.syncthingandroid.fragments.DeviceFragment;
import com.nutomic.syncthingandroid.fragments.FolderFragment;
import com.nutomic.syncthingandroid.fragments.SettingsFragment;
@@ -27,7 +26,7 @@ public class SettingsActivity extends SyncthingActivity {
* edited or a new one created.
*
* If this is false, {@link FolderFragment#EXTRA_REPO_ID} or
- * {@link com.nutomic.syncthingandroid.fragments.DeviceSettingsFragment#EXTRA_NODE_ID} must be set (according to the selected fragment).
+ * {@link DeviceFragment#EXTRA_NODE_ID} must be set (according to the selected fragment).
*/
public static final String EXTRA_IS_CREATE = "create";
@@ -50,7 +49,7 @@ public class SettingsActivity extends SyncthingActivity {
mFragment = new SettingsFragment();
break;
case ACTION_NODE_SETTINGS_FRAGMENT:
- mFragment = new DeviceSettingsFragment();
+ mFragment = new DeviceFragment();
if (!getIntent().hasExtra(EXTRA_IS_CREATE)) {
throw new IllegalArgumentException("EXTRA_IS_CREATE must be set");
}
@@ -87,16 +86,4 @@ public class SettingsActivity extends SyncthingActivity {
public boolean getIsCreate() {
return getIntent().getBooleanExtra(EXTRA_IS_CREATE, false);
}
-
- /**
- * Used for the QR code scanner in DeviceSettingsFragment.
- *
- * Instead of the cast, an interface could be used (if there are multiple fragments using this).
- */
- public void onClick(View view) {
- if (mFragment instanceof DeviceSettingsFragment) {
- ((DeviceSettingsFragment) mFragment).onClick(view);
- }
- }
-
}
diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceFragment.java
new file mode 100644
index 00000000..b4e64483
--- /dev/null
+++ b/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceFragment.java
@@ -0,0 +1,425 @@
+package com.nutomic.syncthingandroid.fragments;
+
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.widget.SwitchCompat;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.LayoutInflater;
+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.TextView;
+import android.widget.Toast;
+
+import com.nutomic.syncthingandroid.R;
+import com.nutomic.syncthingandroid.activities.SettingsActivity;
+import com.nutomic.syncthingandroid.activities.SyncthingActivity;
+import com.nutomic.syncthingandroid.syncthing.RestApi;
+import com.nutomic.syncthingandroid.syncthing.SyncthingService;
+import com.nutomic.syncthingandroid.util.BarcodeIntentIntegrator;
+import com.nutomic.syncthingandroid.util.BarcodeIntentResult;
+import com.nutomic.syncthingandroid.util.Compression;
+import com.nutomic.syncthingandroid.util.TextWatcherAdapter;
+
+import java.util.List;
+import java.util.Map;
+
+import static android.text.TextUtils.isEmpty;
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;
+import static com.nutomic.syncthingandroid.syncthing.SyncthingService.State.ACTIVE;
+import static com.nutomic.syncthingandroid.util.Compression.METADATA;
+
+/**
+ * Shows device details and allows changing them.
+ */
+public class DeviceFragment extends Fragment implements
+ SyncthingActivity.OnServiceConnectedListener, RestApi.OnReceiveConnectionsListener,
+ SyncthingService.OnApiChangeListener, RestApi.OnDeviceIdNormalizedListener,
+ View.OnClickListener {
+
+ public static final String EXTRA_NODE_ID = "device_id";
+
+ private static final String TAG = "DeviceSettingsFragment";
+
+ private static final String DYNAMIC_ADDRESSES = "dynamic";
+
+ private SyncthingService mSyncthingService;
+
+ private RestApi.Device mDevice;
+
+ private View mIdContainer;
+
+ private EditText mIdView;
+
+ private View mQrButton;
+
+ private EditText mNameView;
+
+ private EditText mAddressesView;
+
+ private TextView mCurrentAddressView;
+
+ private TextView mCompressionValueView;
+
+ private SwitchCompat mIntroducerView;
+
+ private TextView mSyncthingVersionView;
+
+ private View mCompressionContainer;
+
+ private boolean mIsCreateMode;
+
+ private boolean mDeviceNeedsToUpdate;
+
+ private DialogInterface.OnClickListener mCompressionEntrySelectedListener = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+
+ Compression compression = Compression.fromIndex(which);
+ // Don't pop the restart dialog unless the value is actually different.
+ if (compression != Compression.fromValue(getActivity(), mDevice.compression)) {
+ mDeviceNeedsToUpdate = true;
+
+ mDevice.compression = compression.getValue(getActivity());
+ mCompressionValueView.setText(compression.getTitle(getActivity()));
+ }
+ }
+ };
+
+ private TextWatcher mIdTextWatcher = new TextWatcherAdapter() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (!s.toString().equals(mDevice.deviceID)) {
+ mDeviceNeedsToUpdate = true;
+
+ mDevice.deviceID = s.toString();
+ }
+ }
+ };
+
+ private TextWatcher mNameTextWatcher = new TextWatcherAdapter() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (!s.toString().equals(mDevice.name)) {
+ mDeviceNeedsToUpdate = true;
+
+ mDevice.name = s.toString();
+ }
+ }
+ };
+
+ private TextWatcher mAddressesTextWatcher = new TextWatcherAdapter() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (!s.toString().equals(mDevice.addresses)) {
+ mDeviceNeedsToUpdate = true;
+
+ mDevice.addresses = persistableAddresses(s);
+ }
+ }
+ };
+
+ private CompoundButton.OnCheckedChangeListener mIntroducerCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (mDevice.introducer != isChecked) {
+ mDeviceNeedsToUpdate = true;
+
+ mDevice.introducer = isChecked;
+ }
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ SettingsActivity activity = (SettingsActivity) getActivity();
+ mIsCreateMode = activity.getIsCreate();
+ activity.registerOnServiceConnectedListener(this);
+ activity.setTitle(mIsCreateMode ? R.string.add_device : R.string.edit_device);
+ setHasOptionsMenu(true);
+
+ if (mIsCreateMode) {
+ if (savedInstanceState != null) {
+ mDevice = (RestApi.Device) savedInstanceState.getSerializable("device");
+ }
+ if (mDevice == null) {
+ initDevice();
+ }
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mSyncthingService != null) {
+ mSyncthingService.unregisterOnApiChangeListener(this);
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ // We don't want to update every time a TextView's character changes,
+ // so we hold off until the view stops being visible to the user.
+ if (mDeviceNeedsToUpdate) {
+ updateDevice();
+ }
+ }
+
+ /**
+ * Save current settings in case we are in create mode and they aren't yet stored in the config.
+ */
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putSerializable("device", mDevice);
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_device, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mIdContainer = view.findViewById(R.id.idContainer);
+ mIdView = (EditText) view.findViewById(R.id.id);
+ mQrButton = view.findViewById(R.id.qrButton);
+ mNameView = (EditText) view.findViewById(R.id.name);
+ mAddressesView = (EditText) view.findViewById(R.id.addresses);
+ mCurrentAddressView = (TextView) view.findViewById(R.id.currentAddress);
+ mCompressionContainer = view.findViewById(R.id.compressionContainer);
+ mCompressionValueView = (TextView) view.findViewById(R.id.compressionValue);
+ mIntroducerView = (SwitchCompat) view.findViewById(R.id.introducer);
+ mSyncthingVersionView = (TextView) view.findViewById(R.id.syncthingVersion);
+
+ mQrButton.setOnClickListener(this);
+ mCompressionContainer.setOnClickListener(this);
+
+ if (!mIsCreateMode) {
+ prepareEditMode();
+ }
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+
+ mIdView.removeTextChangedListener(mIdTextWatcher);
+ mNameView.removeTextChangedListener(mNameTextWatcher);
+ mAddressesView.removeTextChangedListener(mAddressesTextWatcher);
+ }
+
+ @Override
+ public void onServiceConnected() {
+ mSyncthingService = ((SyncthingActivity) getActivity()).getService();
+ mSyncthingService.registerOnApiChangeListener(this);
+ }
+
+ /**
+ * Sets version and current address of the device.
+ *
+ * NOTE: This is only called once on startup, should be called more often to properly display
+ * version/address changes.
+ */
+ @Override
+ public void onReceiveConnections(Map connections) {
+ boolean viewsExist = mSyncthingVersionView != null && mCurrentAddressView != null;
+ if (viewsExist && connections.containsKey(mDevice.deviceID)) {
+ mCurrentAddressView.setVisibility(VISIBLE);
+ mSyncthingVersionView.setVisibility(VISIBLE);
+ mCurrentAddressView.setText(connections.get(mDevice.deviceID).address);
+ mSyncthingVersionView.setText(connections.get(mDevice.deviceID).clientVersion);
+ }
+ }
+
+ @Override
+ public void onApiChange(SyncthingService.State currentState) {
+ if (currentState != ACTIVE) {
+ getActivity().finish();
+ return;
+ }
+
+ if (!mIsCreateMode) {
+ List devices = mSyncthingService.getApi().getDevices(false);
+ for (int i = 0; i < devices.size(); i++) {
+ if (devices.get(i).deviceID.equals(
+ getActivity().getIntent().getStringExtra(EXTRA_NODE_ID))) {
+ mDevice = devices.get(i);
+ break;
+ }
+ }
+ if (mDevice == null) {
+ Log.w(TAG, "Device not found in API update");
+ getActivity().finish();
+ return;
+ }
+ }
+
+ mSyncthingService.getApi().getConnections(this);
+
+ updateViewsAndSetListeners();
+ }
+
+ private void updateViewsAndSetListeners() {
+ // Update views
+ mIdView.setText(mDevice.deviceID);
+ mNameView.setText((mDevice.name));
+ mAddressesView.setText(displayableAddresses());
+ mCompressionValueView.setText(Compression.fromValue(getActivity(), mDevice.compression).getTitle(getActivity()));
+ mIntroducerView.setChecked(mDevice.introducer);
+
+ // Keep state updated
+ mIdView.addTextChangedListener(mIdTextWatcher);
+ mNameView.addTextChangedListener(mNameTextWatcher);
+ mAddressesView.addTextChangedListener(mAddressesTextWatcher);
+ mIntroducerView.setOnCheckedChangeListener(mIntroducerCheckedChangeListener);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ inflater.inflate(R.menu.device_settings, menu);
+ }
+
+ @Override
+ public void onPrepareOptionsMenu(Menu menu) {
+ menu.findItem(R.id.create).setVisible(mIsCreateMode);
+ menu.findItem(R.id.share_device_id).setVisible(!mIsCreateMode);
+ menu.findItem(R.id.delete).setVisible(!mIsCreateMode);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.create:
+ if (isEmpty(mDevice.deviceID)) {
+ Toast.makeText(getActivity(), R.string.device_id_required, Toast.LENGTH_LONG)
+ .show();
+ return true;
+ }
+ if (isEmpty(mDevice.name)) {
+ Toast.makeText(getActivity(), R.string.device_name_required, Toast.LENGTH_LONG)
+ .show();
+ return true;
+ }
+ mSyncthingService.getApi().editDevice(mDevice, getActivity(), this);
+ getActivity().finish();
+ return true;
+ case R.id.share_device_id:
+ RestApi.shareDeviceId(getActivity(), mDevice.deviceID);
+ return true;
+ case R.id.delete:
+ new AlertDialog.Builder(getActivity())
+ .setMessage(R.string.delete_device_confirm)
+ .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ mSyncthingService.getApi().deleteDevice(mDevice, getActivity());
+ }
+ })
+ .setNegativeButton(android.R.string.no, null)
+ .show();
+ return true;
+ case android.R.id.home:
+ getActivity().finish();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ /**
+ * Receives value of scanned QR code and sets it as device ID.
+ */
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ BarcodeIntentResult scanResult = BarcodeIntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
+ if (scanResult != null) {
+ mDevice.deviceID = scanResult.getContents();
+ mIdView.setText(mDevice.deviceID);
+ }
+ }
+
+ /**
+ * Callback for {@link RestApi#editDevice}.
+ * Displays an error toast if error message present.
+ */
+ @Override
+ public void onDeviceIdNormalized(String normalizedId, String error) {
+ if (error != null) {
+ Toast.makeText(getActivity(), error, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ private void initDevice() {
+ mDevice = new RestApi.Device();
+ mDevice.name = "";
+ mDevice.deviceID = "";
+ mDevice.addresses = "dynamic";
+ mDevice.compression = METADATA.getValue(getActivity());
+ mDevice.introducer = false;
+ }
+
+ private void prepareEditMode() {
+ getActivity().getWindow().setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_HIDDEN);
+
+ mIdView.setEnabled(false);
+ mQrButton.setVisibility(GONE);
+
+ mIdContainer.setOnClickListener(this);
+ }
+
+ /**
+ * Sends the updated device info if in edit mode.
+ */
+ private void updateDevice() {
+ if (!mIsCreateMode && mDeviceNeedsToUpdate) {
+ mSyncthingService.getApi().editDevice(mDevice, getActivity(), this);
+ }
+ }
+
+ private String persistableAddresses(CharSequence userInput) {
+ return isEmpty(userInput) ? DYNAMIC_ADDRESSES : userInput.toString();
+ }
+
+ private String displayableAddresses() {
+ return DYNAMIC_ADDRESSES.equals(mDevice.addresses) ? "" : mDevice.addresses;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.equals(mCompressionContainer)) {
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.compression)
+ .setSingleChoiceItems(R.array.compress_entries,
+ Compression.fromValue(getActivity(), mDevice.compression).getIndex(),
+ mCompressionEntrySelectedListener)
+ .show();
+ } else if (v.equals(mQrButton)){
+ BarcodeIntentIntegrator integrator = new BarcodeIntentIntegrator(DeviceFragment.this);
+ integrator.initiateScan();
+ } else if (v.equals(mIdContainer)) {
+ mSyncthingService.getApi().copyDeviceId(mDevice.deviceID);
+ }
+ }
+}
diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/DevicesFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceListFragment.java
similarity index 95%
rename from src/main/java/com/nutomic/syncthingandroid/fragments/DevicesFragment.java
rename to src/main/java/com/nutomic/syncthingandroid/fragments/DeviceListFragment.java
index ba24e923..a6f3be63 100644
--- a/src/main/java/com/nutomic/syncthingandroid/fragments/DevicesFragment.java
+++ b/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceListFragment.java
@@ -23,7 +23,7 @@ import java.util.TimerTask;
/**
* Displays a list of all existing devices.
*/
-public class DevicesFragment extends ListFragment implements SyncthingService.OnApiChangeListener,
+public class DeviceListFragment extends ListFragment implements SyncthingService.OnApiChangeListener,
ListView.OnItemClickListener {
private DevicesAdapter mAdapter;
@@ -96,7 +96,7 @@ public class DevicesFragment extends ListFragment implements SyncthingService.On
Intent intent = new Intent(getActivity(), SettingsActivity.class);
intent.setAction(SettingsActivity.ACTION_NODE_SETTINGS_FRAGMENT);
intent.putExtra(SettingsActivity.EXTRA_IS_CREATE, false);
- intent.putExtra(DeviceSettingsFragment.EXTRA_NODE_ID, mAdapter.getItem(i).deviceID);
+ intent.putExtra(DeviceFragment.EXTRA_NODE_ID, mAdapter.getItem(i).deviceID);
startActivity(intent);
}
diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceSettingsFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceSettingsFragment.java
deleted file mode 100644
index eed7f7f7..00000000
--- a/src/main/java/com/nutomic/syncthingandroid/fragments/DeviceSettingsFragment.java
+++ /dev/null
@@ -1,330 +0,0 @@
-package com.nutomic.syncthingandroid.fragments;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.EditTextPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.support.v4.app.Fragment;
-import android.support.v4.preference.PreferenceFragment;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.Toast;
-
-import com.nutomic.syncthingandroid.R;
-import com.nutomic.syncthingandroid.activities.SettingsActivity;
-import com.nutomic.syncthingandroid.activities.SyncthingActivity;
-import com.nutomic.syncthingandroid.syncthing.RestApi;
-import com.nutomic.syncthingandroid.syncthing.SyncthingService;
-import com.nutomic.syncthingandroid.util.BarcodeIntentIntegrator;
-import com.nutomic.syncthingandroid.util.BarcodeIntentResult;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Shows device details and allows changing them.
- */
-public class DeviceSettingsFragment extends PreferenceFragment implements
- SyncthingActivity.OnServiceConnectedListener, Preference.OnPreferenceChangeListener,
- Preference.OnPreferenceClickListener, RestApi.OnReceiveConnectionsListener,
- SyncthingService.OnApiChangeListener, RestApi.OnDeviceIdNormalizedListener {
-
- public static final String EXTRA_NODE_ID = "device_id";
-
- private static final String TAG = "DeviceSettingsFragment";
-
- private static final int SCAN_QR_REQUEST_CODE = 235;
-
- private SyncthingService mSyncthingService;
-
- private RestApi.Device mDevice;
-
- private Preference mDeviceId;
-
- private EditTextPreference mName;
-
- private EditTextPreference mAddresses;
-
- private ListPreference mCompression;
-
- private CheckBoxPreference mIntroducer;
-
- private Preference mVersion;
-
- private Preference mCurrentAddress;
-
- private boolean mIsCreate;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- ((SyncthingActivity) getActivity()).registerOnServiceConnectedListener(this);
-
- mIsCreate = ((SettingsActivity) getActivity()).getIsCreate();
- setHasOptionsMenu(true);
-
- if (mIsCreate) {
- addPreferencesFromResource(R.xml.device_settings_create);
- } else {
- addPreferencesFromResource(R.xml.device_settings_edit);
- }
-
- mDeviceId = findPreference("device_id");
- mDeviceId.setOnPreferenceChangeListener(this);
- mName = (EditTextPreference) findPreference("name");
- mName.setOnPreferenceChangeListener(this);
- mAddresses = (EditTextPreference) findPreference("addresses");
- mAddresses.setOnPreferenceChangeListener(this);
- mCompression = (ListPreference) findPreference("compression");
- mCompression.setOnPreferenceChangeListener(this);
- mIntroducer = (CheckBoxPreference) findPreference("introducer");
- mIntroducer.setOnPreferenceChangeListener(this);
- if (!mIsCreate) {
- mVersion = findPreference("version");
- mVersion.setSummary("?");
- mCurrentAddress = findPreference("current_address");
- mCurrentAddress.setSummary("?");
- }
-
- if (mIsCreate) {
- if (savedInstanceState != null) {
- mDevice = (RestApi.Device) savedInstanceState.getSerializable("device");
- }
- if (mDevice == null) {
- mDevice = new RestApi.Device();
- mDevice.name = "";
- mDevice.deviceID = "";
- mDevice.addresses = "dynamic";
- mDevice.compression = "metadata";
- mDevice.introducer = false;
- ((EditTextPreference) mDeviceId).setText(mDevice.deviceID);
- }
- }
- }
-
- /**
- * Save current settings in case we are in create mode and they aren't yet stored in the config.
- */
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putSerializable("device", mDevice);
- }
-
- @Override
- public void onServiceConnected() {
- mSyncthingService = ((SyncthingActivity) getActivity()).getService();
- mSyncthingService.registerOnApiChangeListener(this);
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mSyncthingService.unregisterOnApiChangeListener(this);
- }
-
- @Override
- public void onApiChange(SyncthingService.State currentState) {
- if (currentState != SyncthingService.State.ACTIVE) {
- getActivity().finish();
- return;
- }
-
- if (mIsCreate)
- getActivity().setTitle(R.string.add_device);
- else {
- RestApi.Device device = null;
- getActivity().setTitle(R.string.edit_device);
- List devices = mSyncthingService.getApi().getDevices(false);
- for (int i = 0; i < devices.size(); i++) {
- if (devices.get(i).deviceID.equals(
- getActivity().getIntent().getStringExtra(EXTRA_NODE_ID))) {
- device = devices.get(i);
- break;
- }
- }
- if (device == null) {
- Log.w(TAG, "Device not found in API update");
- getActivity().finish();
- return;
- }
- mDevice = device;
- mDeviceId.setOnPreferenceClickListener(this);
- }
-
- mSyncthingService.getApi().getConnections(DeviceSettingsFragment.this);
-
- mDeviceId.setSummary(mDevice.deviceID);
- mName.setText((mDevice.name));
- mName.setSummary(mDevice.name);
- mAddresses.setText(mDevice.addresses);
- mAddresses.setSummary(mDevice.addresses);
- mCompression.setValue(mDevice.compression);
- mCompression.setSummary(mDevice.compression);
- mIntroducer.setChecked(mDevice.introducer);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.device_settings, menu);
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- menu.findItem(R.id.create).setVisible(mIsCreate);
- menu.findItem(R.id.share_device_id).setVisible(!mIsCreate);
- menu.findItem(R.id.delete).setVisible(!mIsCreate);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.create:
- if (mDevice.deviceID.equals("")) {
- Toast.makeText(getActivity(), R.string.device_id_required, Toast.LENGTH_LONG)
- .show();
- return true;
- }
- if (mDevice.name.equals("")) {
- Toast.makeText(getActivity(), R.string.device_name_required, Toast.LENGTH_LONG)
- .show();
- return true;
- }
- mSyncthingService.getApi().editDevice(mDevice, getActivity(), this);
- getActivity().finish();
- return true;
- case R.id.share_device_id:
- RestApi.shareDeviceId(getActivity(), mDevice.deviceID);
- return true;
- case R.id.delete:
- new AlertDialog.Builder(getActivity())
- .setMessage(R.string.delete_device_confirm)
- .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- mSyncthingService.getApi().deleteDevice(mDevice, getActivity());
- }
- })
- .setNegativeButton(android.R.string.no, null)
- .show();
- return true;
- case android.R.id.home:
- getActivity().finish();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object o) {
- if (preference instanceof EditTextPreference) {
- EditTextPreference pref = (EditTextPreference) preference;
- pref.setSummary((String) o);
- }
- if (preference instanceof ListPreference) {
- ListPreference pref = (ListPreference) preference;
- pref.setSummary((String) o);
- }
- if (preference.equals(mDeviceId)) {
- mDevice.deviceID = (String) o;
- deviceUpdated();
- return true;
- } else if (preference.equals(mName)) {
- mDevice.name = (String) o;
- deviceUpdated();
- return true;
- } else if (preference.equals(mAddresses)) {
- mDevice.addresses = (String) o;
- deviceUpdated();
- return true;
- } else if (preference.equals(mCompression)) {
- mDevice.compression = (String) o;
- deviceUpdated();
- return true;
- } else if (preference.equals(mIntroducer)) {
- mDevice.introducer = (Boolean) o;
- deviceUpdated();
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- if (preference.equals(mDeviceId)) {
- mSyncthingService.getApi().copyDeviceId(mDevice.deviceID);
- return true;
- }
- return false;
- }
-
- /**
- * Sets version and current address of the device.
- *
- * NOTE: This is only called once on startup, should be called more often to properly display
- * version/address changes.
- */
- @Override
- public void onReceiveConnections(Map connections) {
- if (mVersion == null || mCurrentAddress == null)
- return;
- if (connections.containsKey(mDevice.deviceID)) {
- mVersion.setSummary(connections.get(mDevice.deviceID).clientVersion);
- mCurrentAddress.setSummary(connections.get(mDevice.deviceID).address);
- }
- }
-
- /**
- * Sends the updated device info if in edit mode.
- */
- private void deviceUpdated() {
- if (!mIsCreate) {
- mSyncthingService.getApi().editDevice(mDevice, getActivity(), this);
- }
- }
-
- /**
- * Sends QR code scanning intent when clicking the QR code icon.
- */
- public void onClick(View view) {
- BarcodeIntentIntegrator integrator = new BarcodeIntentIntegrator(this);
- integrator.initiateScan();
- }
-
- /**
- * Receives value of scanned QR code and sets it as device ID.
- */
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent intent) {
- BarcodeIntentResult scanResult = BarcodeIntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
- if (scanResult != null) {
- mDevice.deviceID = scanResult.getContents();
- ((EditTextPreference) mDeviceId).setText(mDevice.deviceID);
- mDeviceId.setSummary(mDevice.deviceID);
- }
- }
-
- /**
- * Callback for {@link RestApi#editDevice}.
- * Displays an error toast if error message present.
- */
- @Override
- public void onDeviceIdNormalized(String normalizedId, String error) {
- if (error != null) {
- Toast.makeText(getActivity(), error, Toast.LENGTH_LONG).show();
- }
- }
-
-}
diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/FolderFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/FolderFragment.java
index afce907e..e9ce9b98 100644
--- a/src/main/java/com/nutomic/syncthingandroid/fragments/FolderFragment.java
+++ b/src/main/java/com/nutomic/syncthingandroid/fragments/FolderFragment.java
@@ -32,6 +32,7 @@ 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.util.TextWatcherAdapter;
import java.util.ArrayList;
import java.util.List;
@@ -76,7 +77,7 @@ public class FolderFragment extends Fragment
private TextView mVersioningKeepView;
- private boolean mIsCreate;
+ private boolean mIsCreateMode;
private KeepVersionsDialogFragment mKeepVersionsDialogFragment = new KeepVersionsDialogFragment();
@@ -154,12 +155,12 @@ public class FolderFragment extends Fragment
super.onCreate(savedInstanceState);
SettingsActivity activity = (SettingsActivity) getActivity();
- mIsCreate = activity.getIsCreate();
- activity.setTitle(isCreatingFolder() ? R.string.create_folder : R.string.edit_folder);
+ mIsCreateMode = activity.getIsCreate();
+ activity.setTitle(mIsCreateMode ? R.string.create_folder : R.string.edit_folder);
activity.registerOnServiceConnectedListener(this);
setHasOptionsMenu(true);
- if (isCreatingFolder()) {
+ if (mIsCreateMode) {
if (savedInstanceState != null) {
mFolder = (RestApi.Folder) savedInstanceState.getSerializable("folder");
}
@@ -169,6 +170,14 @@ public class FolderFragment extends Fragment
}
}
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mSyncthingService != null) {
+ mSyncthingService.unregisterOnApiChangeListener(this);
+ }
+ }
+
/**
* Save current settings in case we are in create mode and they aren't yet stored in the config.
*/
@@ -196,11 +205,50 @@ public class FolderFragment extends Fragment
mPathView.setOnClickListener(mPathViewClickListener);
view.findViewById(R.id.versioningContainer).setOnClickListener(mVersioningContainerClickListener);
- if (isEditingFolder()) {
+ if (!mIsCreateMode) {
prepareEditMode();
}
}
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ mIdView.removeTextChangedListener(mIdTextWatcher);
+ mPathView.removeTextChangedListener(mPathTextWatcher);
+ }
+
+ @Override
+ public void onServiceConnected() {
+ mSyncthingService = ((SyncthingActivity) getActivity()).getService();
+ mSyncthingService.registerOnApiChangeListener(this);
+ }
+
+ @Override
+ public void onApiChange(SyncthingService.State currentState) {
+ if (currentState != ACTIVE) {
+ getActivity().finish();
+ return;
+ }
+
+ if (!mIsCreateMode) {
+ List folders = mSyncthingService.getApi().getFolders();
+ String passedId = getActivity().getIntent().getStringExtra(EXTRA_REPO_ID);
+ for (RestApi.Folder currentFolder : folders) {
+ if (currentFolder.id.equals(passedId)) {
+ mFolder = currentFolder;
+ break;
+ }
+ }
+ if (mFolder == null) {
+ Log.w(TAG, "Folder not found in API update");
+ getActivity().finish();
+ return;
+ }
+ }
+
+ updateViewsAndSetListeners();
+ }
+
private void updateViewsAndSetListeners() {
// Update views
mIdView.setText(mFolder.id);
@@ -233,53 +281,6 @@ public class FolderFragment extends Fragment
mKeepVersionsDialogFragment.setOnValueChangeListener(mOnValueChangeListener);
}
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- mIdView.removeTextChangedListener(mIdTextWatcher);
- mPathView.removeTextChangedListener(mPathTextWatcher);
- }
-
- @Override
- public void onApiChange(SyncthingService.State currentState) {
- if (currentState != ACTIVE) {
- getActivity().finish();
- return;
- }
-
- if (isEditingFolder()) {
- List folders = mSyncthingService.getApi().getFolders();
- String passedId = getActivity().getIntent().getStringExtra(EXTRA_REPO_ID);
- for (RestApi.Folder currentFolder : folders) {
- if (currentFolder.id.equals(passedId)) {
- mFolder = currentFolder;
- break;
- }
- }
- if (mFolder == null) {
- Log.w(TAG, "Folder not found in API update");
- getActivity().finish();
- return;
- }
- }
-
- updateViewsAndSetListeners();
- }
-
- @Override
- public void onServiceConnected() {
- mSyncthingService = ((SyncthingActivity) getActivity()).getService();
- mSyncthingService.registerOnApiChangeListener(this);
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- if (mSyncthingService != null) {
- mSyncthingService.unregisterOnApiChangeListener(this);
- }
- }
-
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
@@ -288,8 +289,8 @@ public class FolderFragment extends Fragment
@Override
public void onPrepareOptionsMenu(Menu menu) {
- menu.findItem(R.id.create).setVisible(isCreatingFolder());
- menu.findItem(R.id.delete).setVisible(isEditingFolder());
+ menu.findItem(R.id.create).setVisible(mIsCreateMode);
+ menu.findItem(R.id.delete).setVisible(!mIsCreateMode);
}
@Override
@@ -324,8 +325,9 @@ public class FolderFragment extends Fragment
case android.R.id.home:
getActivity().finish();
return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
- return super.onOptionsItemSelected(item);
}
@Override
@@ -355,7 +357,6 @@ public class FolderFragment extends Fragment
private void addEmptyDeviceListView() {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(WRAP_CONTENT, dp(48, getActivity()));
- // 72dp margin to align with dividers
int dividerInset = getResources().getDimensionPixelOffset(R.dimen.material_divider_inset);
int contentInset = getResources().getDimensionPixelOffset(R.dimen.abc_action_bar_content_inset_material);
setMarginStart(params, dividerInset);
@@ -376,28 +377,8 @@ public class FolderFragment extends Fragment
}
private void updateRepo() {
- if (isEditingFolder()) {
+ if (!mIsCreateMode) {
mSyncthingService.getApi().editFolder(mFolder, false, getActivity());
}
}
-
- private boolean isEditingFolder() {
- return !mIsCreate;
- }
-
- private boolean isCreatingFolder() {
- return mIsCreate;
- }
-
- private class TextWatcherAdapter implements TextWatcher {
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {}
-
- @Override
- public void afterTextChanged(Editable s) {}
- }
}
diff --git a/src/main/java/com/nutomic/syncthingandroid/util/Compression.java b/src/main/java/com/nutomic/syncthingandroid/util/Compression.java
new file mode 100644
index 00000000..28063ecb
--- /dev/null
+++ b/src/main/java/com/nutomic/syncthingandroid/util/Compression.java
@@ -0,0 +1,57 @@
+package com.nutomic.syncthingandroid.util;
+
+import android.content.Context;
+
+import com.nutomic.syncthingandroid.R;
+
+/**
+ * Device compression attribute helper. This unifies operations between string values as expected by
+ * Syncthing with string values as displayed to the user and int ordinals as expected by the dialog
+ * click interface.
+ */
+public enum Compression {
+ NONE(0),
+ METADATA(1),
+ ALWAYS(2);
+
+ private final int index;
+
+ Compression(int index) {
+ this.index = index;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public String getValue(Context context) {
+ return context.getResources().getStringArray(R.array.compress_values)[index];
+ }
+
+ public String getTitle(Context context) {
+ return context.getResources().getStringArray(R.array.compress_entries)[index];
+ }
+
+ public static Compression fromIndex(int index) {
+ switch (index) {
+ case 0:
+ return NONE;
+ case 2:
+ return ALWAYS;
+ default:
+ return METADATA;
+ }
+ }
+
+ public static Compression fromValue(Context context, String value) {
+ int index = 0;
+ String[] values = context.getResources().getStringArray(R.array.compress_values);
+ for (int i = 0; i < values.length; i++) {
+ if (values[i].equals(value)) {
+ index = i;
+ }
+ }
+
+ return fromIndex(index);
+ }
+}
diff --git a/src/main/java/com/nutomic/syncthingandroid/util/TextWatcherAdapter.java b/src/main/java/com/nutomic/syncthingandroid/util/TextWatcherAdapter.java
new file mode 100644
index 00000000..ee9f2888
--- /dev/null
+++ b/src/main/java/com/nutomic/syncthingandroid/util/TextWatcherAdapter.java
@@ -0,0 +1,16 @@
+package com.nutomic.syncthingandroid.util;
+
+import android.text.Editable;
+import android.text.TextWatcher;
+
+public class TextWatcherAdapter implements TextWatcher {
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {}
+}
diff --git a/src/main/java/com/nutomic/syncthingandroid/widget/EnhancedEditText.java b/src/main/java/com/nutomic/syncthingandroid/widget/EnhancedEditText.java
new file mode 100644
index 00000000..5df51557
--- /dev/null
+++ b/src/main/java/com/nutomic/syncthingandroid/widget/EnhancedEditText.java
@@ -0,0 +1,50 @@
+package com.nutomic.syncthingandroid.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.EditText;
+
+import static android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
+
+/**
+ * Apparently EditText blocks touch event propagation to the parent even
+ * when disabled/not clickable/not focusable. Therefore we have to manually
+ * check whether we are enabled and either ignore the event or process it normally.
+ *
+ * This class also blocks the default EditText behaviour of textMultiLine flag enforcing replacement
+ * of the IME action button with the new line character. This allows rendering soft wraps on single
+ * line input.
+ */
+public class EnhancedEditText extends EditText {
+
+ public EnhancedEditText(Context context) {
+ super(context);
+ }
+
+ public EnhancedEditText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public EnhancedEditText(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (isEnabled()) {
+ return super.onTouchEvent(event);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ InputConnection conn = super.onCreateInputConnection(outAttrs);
+ outAttrs.imeOptions &= ~IME_FLAG_NO_ENTER_ACTION;
+ return conn;
+ }
+}
diff --git a/src/main/res/drawable-hdpi/ic_cellphone_black_24dp_active.png b/src/main/res/drawable-hdpi/ic_cellphone_black_24dp_active.png
new file mode 100644
index 00000000..23f0c445
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_cellphone_black_24dp_active.png differ
diff --git a/src/main/res/drawable-hdpi/ic_cellphone_black_24dp_inactive.png b/src/main/res/drawable-hdpi/ic_cellphone_black_24dp_inactive.png
new file mode 100644
index 00000000..95aa9c1f
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_cellphone_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-hdpi/ic_info_black_24dp_active.png b/src/main/res/drawable-hdpi/ic_info_black_24dp_active.png
new file mode 100644
index 00000000..e724f48f
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_info_black_24dp_active.png differ
diff --git a/src/main/res/drawable-hdpi/ic_info_black_24dp_inactive.png b/src/main/res/drawable-hdpi/ic_info_black_24dp_inactive.png
new file mode 100644
index 00000000..6cc170e6
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_info_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-hdpi/ic_link_black_24dp_active.png b/src/main/res/drawable-hdpi/ic_link_black_24dp_active.png
new file mode 100644
index 00000000..2cc6a5a3
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_link_black_24dp_active.png differ
diff --git a/src/main/res/drawable-hdpi/ic_link_black_24dp_inactive.png b/src/main/res/drawable-hdpi/ic_link_black_24dp_inactive.png
new file mode 100644
index 00000000..b0effd93
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_link_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-hdpi/ic_phonelink_black_24dp_active.png b/src/main/res/drawable-hdpi/ic_phonelink_black_24dp_active.png
new file mode 100644
index 00000000..935686e8
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_phonelink_black_24dp_active.png differ
diff --git a/src/main/res/drawable-hdpi/ic_phonelink_black_24dp_inactive.png b/src/main/res/drawable-hdpi/ic_phonelink_black_24dp_inactive.png
new file mode 100644
index 00000000..3d0ab6e4
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_phonelink_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-hdpi/ic_qrcode.png b/src/main/res/drawable-hdpi/ic_qrcode.png
deleted file mode 100644
index 3f7475ec..00000000
Binary files a/src/main/res/drawable-hdpi/ic_qrcode.png and /dev/null differ
diff --git a/src/main/res/drawable-hdpi/ic_qrcode_black_24dp_active.png b/src/main/res/drawable-hdpi/ic_qrcode_black_24dp_active.png
new file mode 100644
index 00000000..49eb0bbe
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_qrcode_black_24dp_active.png differ
diff --git a/src/main/res/drawable-hdpi/ic_qrcode_black_24dp_inactive.png b/src/main/res/drawable-hdpi/ic_qrcode_black_24dp_inactive.png
new file mode 100644
index 00000000..1f79549c
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_qrcode_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-hdpi/ic_tag_text_outline_black_24dp_active.png b/src/main/res/drawable-hdpi/ic_tag_text_outline_black_24dp_active.png
new file mode 100644
index 00000000..3da65a17
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_tag_text_outline_black_24dp_active.png differ
diff --git a/src/main/res/drawable-hdpi/ic_tag_text_outline_black_24dp_inactive.png b/src/main/res/drawable-hdpi/ic_tag_text_outline_black_24dp_inactive.png
new file mode 100644
index 00000000..94ff9526
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_tag_text_outline_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-hdpi/ic_zip_box_black_24dp_active.png b/src/main/res/drawable-hdpi/ic_zip_box_black_24dp_active.png
new file mode 100644
index 00000000..77961be8
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_zip_box_black_24dp_active.png differ
diff --git a/src/main/res/drawable-hdpi/ic_zip_box_black_24dp_inactive.png b/src/main/res/drawable-hdpi/ic_zip_box_black_24dp_inactive.png
new file mode 100644
index 00000000..f64ae589
Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_zip_box_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-mdpi/ic_qrcode.png b/src/main/res/drawable-mdpi/ic_qrcode.png
deleted file mode 100644
index c20e21bf..00000000
Binary files a/src/main/res/drawable-mdpi/ic_qrcode.png and /dev/null differ
diff --git a/src/main/res/drawable-xhdpi/ic_cellphone_black_24dp_active.png b/src/main/res/drawable-xhdpi/ic_cellphone_black_24dp_active.png
new file mode 100644
index 00000000..aaaa44af
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_cellphone_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_cellphone_black_24dp_inactive.png b/src/main/res/drawable-xhdpi/ic_cellphone_black_24dp_inactive.png
new file mode 100644
index 00000000..fb786521
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_cellphone_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_info_black_24dp_active.png b/src/main/res/drawable-xhdpi/ic_info_black_24dp_active.png
new file mode 100644
index 00000000..c4b44188
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_info_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_info_black_24dp_inactive.png b/src/main/res/drawable-xhdpi/ic_info_black_24dp_inactive.png
new file mode 100644
index 00000000..138e36b0
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_info_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_link_black_24dp_active.png b/src/main/res/drawable-xhdpi/ic_link_black_24dp_active.png
new file mode 100644
index 00000000..b1499f36
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_link_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_link_black_24dp_inactive.png b/src/main/res/drawable-xhdpi/ic_link_black_24dp_inactive.png
new file mode 100644
index 00000000..97aaef54
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_link_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_phonelink_black_24dp_active.png b/src/main/res/drawable-xhdpi/ic_phonelink_black_24dp_active.png
new file mode 100644
index 00000000..5575e46d
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_phonelink_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_phonelink_black_24dp_inactive.png b/src/main/res/drawable-xhdpi/ic_phonelink_black_24dp_inactive.png
new file mode 100644
index 00000000..008a58ce
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_phonelink_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_qrcode.png b/src/main/res/drawable-xhdpi/ic_qrcode.png
deleted file mode 100644
index 34fe1032..00000000
Binary files a/src/main/res/drawable-xhdpi/ic_qrcode.png and /dev/null differ
diff --git a/src/main/res/drawable-xhdpi/ic_qrcode_black_24dp_active.png b/src/main/res/drawable-xhdpi/ic_qrcode_black_24dp_active.png
new file mode 100644
index 00000000..f4547714
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_qrcode_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_qrcode_black_24dp_inactive.png b/src/main/res/drawable-xhdpi/ic_qrcode_black_24dp_inactive.png
new file mode 100644
index 00000000..529c0700
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_qrcode_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_tag_text_outline_black_24dp_active.png b/src/main/res/drawable-xhdpi/ic_tag_text_outline_black_24dp_active.png
new file mode 100644
index 00000000..3fede434
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_tag_text_outline_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_tag_text_outline_black_24dp_inactive.png b/src/main/res/drawable-xhdpi/ic_tag_text_outline_black_24dp_inactive.png
new file mode 100644
index 00000000..a7bb5637
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_tag_text_outline_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_zip_box_black_24dp_active.png b/src/main/res/drawable-xhdpi/ic_zip_box_black_24dp_active.png
new file mode 100644
index 00000000..240f40a6
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_zip_box_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xhdpi/ic_zip_box_black_24dp_inactive.png b/src/main/res/drawable-xhdpi/ic_zip_box_black_24dp_inactive.png
new file mode 100644
index 00000000..ec5db18a
Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_zip_box_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_cellphone_black_24dp_active.png b/src/main/res/drawable-xxhdpi/ic_cellphone_black_24dp_active.png
new file mode 100644
index 00000000..1a03caba
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_cellphone_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_cellphone_black_24dp_inactive.png b/src/main/res/drawable-xxhdpi/ic_cellphone_black_24dp_inactive.png
new file mode 100644
index 00000000..2dc0ef75
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_cellphone_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_info_black_24dp_active.png b/src/main/res/drawable-xxhdpi/ic_info_black_24dp_active.png
new file mode 100644
index 00000000..459b0d4a
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_info_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_info_black_24dp_inactive.png b/src/main/res/drawable-xxhdpi/ic_info_black_24dp_inactive.png
new file mode 100644
index 00000000..3fd178db
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_info_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_link_black_24dp_active.png b/src/main/res/drawable-xxhdpi/ic_link_black_24dp_active.png
new file mode 100644
index 00000000..213d4d52
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_link_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_link_black_24dp_inactive.png b/src/main/res/drawable-xxhdpi/ic_link_black_24dp_inactive.png
new file mode 100644
index 00000000..daa211f9
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_link_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_phonelink_black_24dp_active.png b/src/main/res/drawable-xxhdpi/ic_phonelink_black_24dp_active.png
new file mode 100644
index 00000000..132fe37e
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_phonelink_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_phonelink_black_24dp_inactive.png b/src/main/res/drawable-xxhdpi/ic_phonelink_black_24dp_inactive.png
new file mode 100644
index 00000000..854c4256
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_phonelink_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_qrcode.png b/src/main/res/drawable-xxhdpi/ic_qrcode.png
deleted file mode 100644
index 5ead1fb9..00000000
Binary files a/src/main/res/drawable-xxhdpi/ic_qrcode.png and /dev/null differ
diff --git a/src/main/res/drawable-xxhdpi/ic_qrcode_black_24dp_active.png b/src/main/res/drawable-xxhdpi/ic_qrcode_black_24dp_active.png
new file mode 100644
index 00000000..5b2884d3
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_qrcode_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_qrcode_black_24dp_inactive.png b/src/main/res/drawable-xxhdpi/ic_qrcode_black_24dp_inactive.png
new file mode 100644
index 00000000..e0c9df0c
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_qrcode_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_tag_text_outline_black_24dp_active.png b/src/main/res/drawable-xxhdpi/ic_tag_text_outline_black_24dp_active.png
new file mode 100644
index 00000000..f70f65ed
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_tag_text_outline_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_tag_text_outline_black_24dp_inactive.png b/src/main/res/drawable-xxhdpi/ic_tag_text_outline_black_24dp_inactive.png
new file mode 100644
index 00000000..77572b06
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_tag_text_outline_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_zip_box_black_24dp_active.png b/src/main/res/drawable-xxhdpi/ic_zip_box_black_24dp_active.png
new file mode 100644
index 00000000..43dc2405
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_zip_box_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxhdpi/ic_zip_box_black_24dp_inactive.png b/src/main/res/drawable-xxhdpi/ic_zip_box_black_24dp_inactive.png
new file mode 100644
index 00000000..61e2f21f
Binary files /dev/null and b/src/main/res/drawable-xxhdpi/ic_zip_box_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_cellphone_black_24dp_active.png b/src/main/res/drawable-xxxhdpi/ic_cellphone_black_24dp_active.png
new file mode 100644
index 00000000..0533b7be
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_cellphone_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_cellphone_black_24dp_inactive.png b/src/main/res/drawable-xxxhdpi/ic_cellphone_black_24dp_inactive.png
new file mode 100644
index 00000000..8b9000fb
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_cellphone_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_info_black_24dp_active.png b/src/main/res/drawable-xxxhdpi/ic_info_black_24dp_active.png
new file mode 100644
index 00000000..090f8258
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_info_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_info_black_24dp_inactive.png b/src/main/res/drawable-xxxhdpi/ic_info_black_24dp_inactive.png
new file mode 100644
index 00000000..35f85460
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_info_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_link_black_24dp_active.png b/src/main/res/drawable-xxxhdpi/ic_link_black_24dp_active.png
new file mode 100644
index 00000000..18ba9a5d
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_link_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_link_black_24dp_inactive.png b/src/main/res/drawable-xxxhdpi/ic_link_black_24dp_inactive.png
new file mode 100644
index 00000000..1971c1ed
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_link_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_phonelink_black_24dp_active.png b/src/main/res/drawable-xxxhdpi/ic_phonelink_black_24dp_active.png
new file mode 100644
index 00000000..10f29d47
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_phonelink_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_phonelink_black_24dp_inactive.png b/src/main/res/drawable-xxxhdpi/ic_phonelink_black_24dp_inactive.png
new file mode 100644
index 00000000..b2f04b03
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_phonelink_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_qrcode_black_24dp_active.png b/src/main/res/drawable-xxxhdpi/ic_qrcode_black_24dp_active.png
new file mode 100644
index 00000000..a5f05770
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_qrcode_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_qrcode_black_24dp_inactive.png b/src/main/res/drawable-xxxhdpi/ic_qrcode_black_24dp_inactive.png
new file mode 100644
index 00000000..e85a4c25
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_qrcode_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_tag_text_outline_black_24dp_active.png b/src/main/res/drawable-xxxhdpi/ic_tag_text_outline_black_24dp_active.png
new file mode 100644
index 00000000..bd2545fa
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_tag_text_outline_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_tag_text_outline_black_24dp_inactive.png b/src/main/res/drawable-xxxhdpi/ic_tag_text_outline_black_24dp_inactive.png
new file mode 100644
index 00000000..fef8eff9
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_tag_text_outline_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_zip_box_black_24dp_active.png b/src/main/res/drawable-xxxhdpi/ic_zip_box_black_24dp_active.png
new file mode 100644
index 00000000..c3359f74
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_zip_box_black_24dp_active.png differ
diff --git a/src/main/res/drawable-xxxhdpi/ic_zip_box_black_24dp_inactive.png b/src/main/res/drawable-xxxhdpi/ic_zip_box_black_24dp_inactive.png
new file mode 100644
index 00000000..b861d2d7
Binary files /dev/null and b/src/main/res/drawable-xxxhdpi/ic_zip_box_black_24dp_inactive.png differ
diff --git a/src/main/res/drawable/ic_cellphone_black_24dp.xml b/src/main/res/drawable/ic_cellphone_black_24dp.xml
new file mode 100644
index 00000000..52c7da3c
--- /dev/null
+++ b/src/main/res/drawable/ic_cellphone_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_info_black_24dp.xml b/src/main/res/drawable/ic_info_black_24dp.xml
new file mode 100644
index 00000000..81edf070
--- /dev/null
+++ b/src/main/res/drawable/ic_info_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_link_black_24dp.xml b/src/main/res/drawable/ic_link_black_24dp.xml
new file mode 100644
index 00000000..9bd770ba
--- /dev/null
+++ b/src/main/res/drawable/ic_link_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_phonelink_black_24dp.xml b/src/main/res/drawable/ic_phonelink_black_24dp.xml
new file mode 100644
index 00000000..87c6109a
--- /dev/null
+++ b/src/main/res/drawable/ic_phonelink_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_qrcode_black_24dp.xml b/src/main/res/drawable/ic_qrcode_black_24dp.xml
new file mode 100644
index 00000000..bdf21d93
--- /dev/null
+++ b/src/main/res/drawable/ic_qrcode_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_tag_text_outline_black_24dp.xml b/src/main/res/drawable/ic_tag_text_outline_black_24dp.xml
new file mode 100644
index 00000000..fdc74823
--- /dev/null
+++ b/src/main/res/drawable/ic_tag_text_outline_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_transparent_24dp.xml b/src/main/res/drawable/ic_transparent_24dp.xml
new file mode 100644
index 00000000..c4043eb2
--- /dev/null
+++ b/src/main/res/drawable/ic_transparent_24dp.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_zip_box_black_24dp.xml b/src/main/res/drawable/ic_zip_box_black_24dp.xml
new file mode 100644
index 00000000..7fce39a7
--- /dev/null
+++ b/src/main/res/drawable/ic_zip_box_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/res/layout/fragment_device.xml b/src/main/res/layout/fragment_device.xml
new file mode 100644
index 00000000..8afb2561
--- /dev/null
+++ b/src/main/res/layout/fragment_device.xml
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/fragment_folder.xml b/src/main/res/layout/fragment_folder.xml
index c883375a..2f1d8fe4 100644
--- a/src/main/res/layout/fragment_folder.xml
+++ b/src/main/res/layout/fragment_folder.xml
@@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".fragments.FoldersFragment">
+ tools:context=".fragments.FolderFragment">
+ android:showDividers="middle">
+ android:hint="@string/folder_id"
+ android:imeOptions="actionDone"
+ android:inputType="textCapWords" />
@@ -40,9 +41,9 @@
android:orientation="vertical">
@@ -50,9 +51,9 @@
\ No newline at end of file
+ tools:ignore="RtlHardcoded,RtlSymmetry" />
diff --git a/src/main/res/layout/pref_widget_scan_qr_code.xml b/src/main/res/layout/pref_widget_scan_qr_code.xml
index 5412c17a..8b06f59d 100644
--- a/src/main/res/layout/pref_widget_scan_qr_code.xml
+++ b/src/main/res/layout/pref_widget_scan_qr_code.xml
@@ -1,8 +1,8 @@
diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml
index 47455f7f..c546bc97 100644
--- a/src/main/res/values/styles.xml
+++ b/src/main/res/values/styles.xml
@@ -25,18 +25,20 @@
- @dimen/abc_action_bar_content_inset_material
-
-
-