mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-12-22 19:01:30 +00:00
greatly improve override_changes ux/ui
This commit is contained in:
parent
d415716256
commit
7a6ec4c883
9 changed files with 150 additions and 39 deletions
|
@ -57,7 +57,7 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
|||
private static final String TAG = "DeviceSettingsFragment";
|
||||
private static final String IS_SHOWING_DISCARD_DIALOG = "DISCARD_FOLDER_DIALOG_STATE";
|
||||
private static final String IS_SHOWING_COMPRESSION_DIALOG = "COMPRESSION_FOLDER_DIALOG_STATE";
|
||||
private static final String IS_SHOWING_DELETE_DIALOG = "DELETE_FOLDER_DIALOG_STATE";
|
||||
private static final String IS_SHOW_DELETE_DIALOG = "DELETE_FOLDER_DIALOG_STATE";
|
||||
private static final int QR_SCAN_REQUEST_CODE = 777;
|
||||
|
||||
private static final List<String> DYNAMIC_ADDRESS = Collections.singletonList("dynamic");
|
||||
|
@ -170,7 +170,7 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
|||
showCompressionDialog();
|
||||
}
|
||||
|
||||
if (savedInstanceState.getBoolean(IS_SHOWING_DELETE_DIALOG)){
|
||||
if (savedInstanceState.getBoolean(IS_SHOW_DELETE_DIALOG)){
|
||||
showDeleteDialog();
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,7 @@ public class DeviceActivity extends SyncthingActivity implements View.OnClickLis
|
|||
outState.putBoolean(IS_SHOWING_COMPRESSION_DIALOG, mCompressionDialog != null && mCompressionDialog.isShowing());
|
||||
Util.dismissDialogSafe(mCompressionDialog, this);
|
||||
|
||||
outState.putBoolean(IS_SHOWING_DELETE_DIALOG, mDeleteDialog != null && mDeleteDialog.isShowing());
|
||||
outState.putBoolean(IS_SHOW_DELETE_DIALOG, mDeleteDialog != null && mDeleteDialog.isShowing());
|
||||
Util.dismissDialogSafe(mDeleteDialog, this);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.nutomic.syncthingandroid.R;
|
|||
import com.nutomic.syncthingandroid.databinding.FragmentFolderBinding;
|
||||
import com.nutomic.syncthingandroid.model.Device;
|
||||
import com.nutomic.syncthingandroid.model.Folder;
|
||||
import com.nutomic.syncthingandroid.model.FolderStatus;
|
||||
import com.nutomic.syncthingandroid.service.Constants;
|
||||
import com.nutomic.syncthingandroid.service.RestApi;
|
||||
import com.nutomic.syncthingandroid.service.SyncthingService;
|
||||
|
@ -65,13 +66,16 @@ public class FolderActivity extends SyncthingActivity
|
|||
"com.nutomic.syncthingandroid.activities.FolderActivity.FOLDER_ID";
|
||||
public static final String EXTRA_FOLDER_LABEL =
|
||||
"com.nutomic.syncthingandroid.activities.FolderActivity.FOLDER_LABEL";
|
||||
public static final String EXTRA_FOLDER_OVERRIDABLE_CHANGES =
|
||||
"com.nutomic.syncthingandroid.activities.FolderActivity.FOLDER_OVERRIDABLE_CHANGES";
|
||||
public static final String EXTRA_DEVICE_ID =
|
||||
"com.nutomic.syncthingandroid.activities.FolderActivity.DEVICE_ID";
|
||||
|
||||
private static final String TAG = "FolderActivity";
|
||||
|
||||
private static final String IS_SHOWING_DELETE_DIALOG = "DELETE_FOLDER_DIALOG_STATE";
|
||||
private static final String IS_SHOW_DELETE_DIALOG = "DELETE_FOLDER_DIALOG_STATE";
|
||||
private static final String IS_SHOW_DISCARD_DIALOG = "DISCARD_FOLDER_DIALOG_STATE";
|
||||
private static final String IS_SHOW_OVERRIDE_CHANGES_DIALOG = "OVERRIDE_REMOTES_DIALOG_STATE";
|
||||
|
||||
private static final int FILE_VERSIONING_DIALOG_REQUEST = 3454;
|
||||
private static final int PULL_ORDER_DIALOG_REQUEST = 3455;
|
||||
|
@ -93,6 +97,7 @@ public class FolderActivity extends SyncthingActivity
|
|||
|
||||
private Dialog mDeleteDialog;
|
||||
private Dialog mDiscardDialog;
|
||||
private Dialog mOverrideChangesDialog;
|
||||
|
||||
private Folder.Versioning mVersioning;
|
||||
|
||||
|
@ -148,6 +153,7 @@ public class FolderActivity extends SyncthingActivity
|
|||
findViewById(R.id.pullOrderContainer).setOnClickListener(v -> showPullOrderDialog());
|
||||
findViewById(R.id.versioningContainer).setOnClickListener(v -> showVersioningDialog());
|
||||
binding.editIgnores.setOnClickListener(v -> editIgnores());
|
||||
binding.overrideChangesContainer.setOnClickListener(v -> showOverrideChangesDialog());
|
||||
|
||||
if (mIsCreateMode) {
|
||||
if (savedInstanceState != null) {
|
||||
|
@ -162,6 +168,7 @@ public class FolderActivity extends SyncthingActivity
|
|||
// Open keyboard on label view in edit mode.
|
||||
binding.label.requestFocus();
|
||||
binding.editIgnores.setEnabled(false);
|
||||
setOverrideChangesContainerEnabled(false);
|
||||
}
|
||||
else {
|
||||
// Prepare edit mode.
|
||||
|
@ -169,19 +176,31 @@ public class FolderActivity extends SyncthingActivity
|
|||
binding.id.setFocusable(false);
|
||||
binding.id.setEnabled(false);
|
||||
binding.directoryTextView.setEnabled(false);
|
||||
|
||||
// overridable remotes button
|
||||
setOverrideChangesContainerEnabled(
|
||||
getIntent().getBooleanExtra(EXTRA_FOLDER_OVERRIDABLE_CHANGES, false)
|
||||
);
|
||||
}
|
||||
|
||||
if (savedInstanceState != null){
|
||||
if (savedInstanceState.getBoolean(IS_SHOWING_DELETE_DIALOG)){
|
||||
if (savedInstanceState.getBoolean(IS_SHOW_DELETE_DIALOG)){
|
||||
showDeleteDialog();
|
||||
}
|
||||
}
|
||||
|
||||
if (savedInstanceState != null){
|
||||
if (savedInstanceState.getBoolean(IS_SHOWING_DELETE_DIALOG)){
|
||||
if (savedInstanceState.getBoolean(IS_SHOW_DELETE_DIALOG)){
|
||||
showDeleteDialog();
|
||||
}
|
||||
}
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
if (savedInstanceState.getBoolean(IS_SHOW_OVERRIDE_CHANGES_DIALOG)){
|
||||
showOverrideChangesDialog();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -304,12 +323,18 @@ public class FolderActivity extends SyncthingActivity
|
|||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBoolean(IS_SHOWING_DELETE_DIALOG, mDeleteDialog != null && mDeleteDialog.isShowing());
|
||||
outState.putBoolean(IS_SHOW_DELETE_DIALOG, mDeleteDialog != null && mDeleteDialog.isShowing());
|
||||
Util.dismissDialogSafe(mDeleteDialog, this);
|
||||
|
||||
outState.putBoolean(IS_SHOW_OVERRIDE_CHANGES_DIALOG, mOverrideChangesDialog != null && mOverrideChangesDialog.isShowing());
|
||||
Util.dismissDialogSafe(mOverrideChangesDialog, this);
|
||||
|
||||
if (mIsCreateMode){
|
||||
outState.putBoolean(IS_SHOW_DISCARD_DIALOG, mDiscardDialog != null && mDiscardDialog.isShowing());
|
||||
Util.dismissDialogSafe(mDiscardDialog, this);
|
||||
|
||||
outState.putBoolean(IS_SHOW_OVERRIDE_CHANGES_DIALOG, mOverrideChangesDialog != null && mOverrideChangesDialog.isShowing());
|
||||
Util.dismissDialogSafe(mOverrideChangesDialog, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -778,4 +803,33 @@ public class FolderActivity extends SyncthingActivity
|
|||
binding.versioningType.setText(type);
|
||||
binding.versioningDescription.setText(description);
|
||||
}
|
||||
|
||||
private void setOverrideChangesContainerEnabled(boolean state) {
|
||||
binding.overrideChangesContainer.setEnabled(state);
|
||||
for ( int i = 0; i < binding.overrideChangesContainer.getChildCount(); i++ ) {
|
||||
binding.overrideChangesContainer.getChildAt(i).setEnabled(state);
|
||||
}
|
||||
}
|
||||
|
||||
private void showOverrideChangesDialog(){
|
||||
mOverrideChangesDialog = createOverrideChangesDialog();
|
||||
mOverrideChangesDialog.show();
|
||||
}
|
||||
|
||||
private Dialog createOverrideChangesDialog(){
|
||||
return Util.getAlertDialogBuilder(this)
|
||||
.setIcon(R.drawable.outline_arrow_circle_up_24)
|
||||
.setTitle(R.string.override_changes)
|
||||
.setMessage(R.string.override_changes_are_you_sure)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.yes, (dialogInterface, i) -> {
|
||||
RestApi restApi = getApi();
|
||||
if (restApi != null) {
|
||||
restApi.overrideChanges(mFolder.id);
|
||||
mFolderNeedsToUpdate = true;
|
||||
}
|
||||
finish();
|
||||
})
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.nutomic.syncthingandroid.R;
|
|||
import com.nutomic.syncthingandroid.activities.FolderActivity;
|
||||
import com.nutomic.syncthingandroid.activities.SyncthingActivity;
|
||||
import com.nutomic.syncthingandroid.model.Folder;
|
||||
import com.nutomic.syncthingandroid.model.FolderStatus;
|
||||
import com.nutomic.syncthingandroid.service.Constants;
|
||||
import com.nutomic.syncthingandroid.service.RestApi;
|
||||
import com.nutomic.syncthingandroid.service.SyncthingService;
|
||||
|
@ -101,9 +102,14 @@ public class FolderListFragment extends ListFragment implements SyncthingService
|
|||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
Folder folder = mAdapter.getItem(i);
|
||||
FolderStatus folderStatus = mAdapter.getLocalFolderStatus(folder.id);
|
||||
boolean overridableChanges = folder.type.equals(Constants.FOLDER_TYPE_SEND_ONLY)
|
||||
&& folderStatus.isOutOfSync();
|
||||
Intent intent = new Intent(getActivity(), FolderActivity.class)
|
||||
.putExtra(FolderActivity.EXTRA_IS_CREATE, false)
|
||||
.putExtra(FolderActivity.EXTRA_FOLDER_ID, mAdapter.getItem(i).id);
|
||||
.putExtra(FolderActivity.EXTRA_FOLDER_ID, mAdapter.getItem(i).id)
|
||||
.putExtra(FolderActivity.EXTRA_FOLDER_OVERRIDABLE_CHANGES, overridableChanges);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,4 +27,12 @@ public class FolderStatus {
|
|||
public long version;
|
||||
public String error;
|
||||
public String watchError;
|
||||
|
||||
public boolean isNeedsItems() {
|
||||
return needFiles + needDirectories + needSymlinks + needDeletes > 0;
|
||||
}
|
||||
|
||||
public boolean isOutOfSync() {
|
||||
return state.equals("idle") && isNeedsItems();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,13 +59,6 @@ public class FoldersAdapter extends ArrayAdapter<Folder> {
|
|||
Folder folder = getItem(position);
|
||||
binding.label.setText(TextUtils.isEmpty(folder.label) ? folder.id : folder.label);
|
||||
binding.directory.setText(folder.path);
|
||||
binding.override.setOnClickListener(v -> {
|
||||
// Send "Override changes" through our service to the REST API.
|
||||
Intent intent = new Intent(mContext, SyncthingService.class)
|
||||
.putExtra(SyncthingService.EXTRA_FOLDER_ID, folder.id);
|
||||
intent.setAction(SyncthingService.ACTION_OVERRIDE_CHANGES);
|
||||
mContext.startService(intent);
|
||||
});
|
||||
binding.openFolder.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.fromFile(new File(folder.path)), "resource/folder");
|
||||
|
@ -94,17 +87,12 @@ public class FoldersAdapter extends ArrayAdapter<Folder> {
|
|||
FolderStatus folderStatus = mLocalFolderStatuses.get(folder.id);
|
||||
if (folderStatus == null) {
|
||||
binding.items.setVisibility(GONE);
|
||||
binding.override.setVisibility(GONE);
|
||||
binding.size.setVisibility(GONE);
|
||||
setTextOrHide(binding.invalid, folder.invalid);
|
||||
return;
|
||||
}
|
||||
|
||||
long neededItems = folderStatus.needFiles + folderStatus.needDirectories + folderStatus.needSymlinks + folderStatus.needDeletes;
|
||||
boolean outOfSync = folderStatus.state.equals("idle") && neededItems > 0;
|
||||
boolean overrideButtonVisible = folder.type.equals(Constants.FOLDER_TYPE_SEND_ONLY) && outOfSync;
|
||||
binding.override.setVisibility(overrideButtonVisible ? VISIBLE : GONE);
|
||||
if (outOfSync) {
|
||||
if (folderStatus.isOutOfSync()) {
|
||||
binding.state.setText(mContext.getString(R.string.status_outofsync));
|
||||
binding.state.setTextColor(ContextCompat.getColor(mContext, R.color.text_red));
|
||||
} else {
|
||||
|
@ -172,6 +160,10 @@ public class FoldersAdapter extends ArrayAdapter<Folder> {
|
|||
}
|
||||
}
|
||||
|
||||
public FolderStatus getLocalFolderStatus(String folderId) {
|
||||
return mLocalFolderStatuses.get(folderId);
|
||||
}
|
||||
|
||||
private void onReceiveFolderStatus(String folderId, FolderStatus folderStatus) {
|
||||
mLocalFolderStatuses.put(folderId, folderStatus);
|
||||
notifyDataSetChanged();
|
||||
|
@ -185,5 +177,4 @@ public class FoldersAdapter extends ArrayAdapter<Folder> {
|
|||
view.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
10
app/src/main/res/drawable/outline_arrow_circle_up_24.xml
Normal file
10
app/src/main/res/drawable/outline_arrow_circle_up_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20M12,22c5.52,0 10,-4.48 10,-10c0,-5.52 -4.48,-10 -10,-10C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22L12,22zM11,12l0,4h2l0,-4h3l-4,-4l-4,4H11z"/>
|
||||
</vector>
|
|
@ -217,6 +217,16 @@
|
|||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
android:layout_marginBottom="10dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ignoresContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/edit_ignores"
|
||||
style="@style/Widget.Syncthing.TextView.Label.Details"
|
||||
|
@ -229,6 +239,51 @@
|
|||
android:text="@string/ignore_patterns"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/actionsContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/overrideChangesContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:enabled="false">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/overrideChanges"
|
||||
style="@style/Widget.Syncthing.TextView.Label.Details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:checked="false"
|
||||
android:drawableLeft="@drawable/outline_arrow_circle_up_24"
|
||||
android:drawableStart="@drawable/outline_arrow_circle_up_24"
|
||||
android:text="@string/override_changes"
|
||||
android:enabled="false"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/overrideChangesDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="72dp"
|
||||
android:layout_marginTop="-10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
android:text="@string/override_changes_description"
|
||||
android:enabled="false"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
|
|
|
@ -44,26 +44,11 @@
|
|||
android:ellipsize="end"
|
||||
android:textAppearance="?textAppearanceListItemSecondary" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/override"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/directory"
|
||||
android:contentDescription="@string/override_changes"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:paddingStart="20dp"
|
||||
android:text="@string/override_changes"
|
||||
android:drawableLeft="@android:drawable/ic_menu_upload"
|
||||
android:drawableStart="@android:drawable/ic_menu_upload"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/items"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/override"
|
||||
android:layout_below="@id/directory"
|
||||
android:textAppearance="?textAppearanceListItemSecondary" />
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -116,7 +116,9 @@
|
|||
<item quantity="other">%1$d / %2$d Files</item>
|
||||
</plurals>
|
||||
|
||||
<string name="override_changes">Override changes</string>
|
||||
<string name="override_changes">Override Changes</string>
|
||||
<string name="override_changes_description">When configured as \"Send Only\" and changes have been made remotely, you may click here to overwrite the folder content on other devices.</string>
|
||||
<string name="override_changes_are_you_sure"><b>Warning!</b>\n\nThe folder content on other devices will be overwritten to become identical with this device. Files not present here will be deleted on other devices.\n\nAre you sure you want to continue?</string>
|
||||
|
||||
<string name="open_file_manager">Open file manager</string>
|
||||
|
||||
|
|
Loading…
Reference in a new issue