Skip to content

Commit a9aee9d

Browse files
committed
Fix root display name not refreshed in SAF provider.
This is a major rework of how remote names are handled.
1 parent 42f9f0c commit a9aee9d

18 files changed

+106
-105
lines changed

app/build.gradle

+6-4
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,11 @@ android {
7171
}
7272

7373
project.ext.versionCodes = [
74-
'armeabi-v7a': 6,
75-
'arm64-v8a': 7,
76-
'x86': 8,
77-
'x86_64': 9]
74+
'armeabi-v7a': 6,
75+
'arm64-v8a': 7,
76+
'x86': 8,
77+
'x86_64': 9
78+
]
7879

7980
android.applicationVariants.all { variant ->
8081
variant.outputs.each { output ->
@@ -111,6 +112,7 @@ dependencies {
111112
implementation 'org.markdownj:markdownj-core:0.4'
112113
implementation 'jp.wasabeef:recyclerview-animators:2.3.0'
113114
implementation 'com.github.GrenderG:Toasty:1.3.0'
115+
implementation 'commons-io:commons-io:2.7'
114116
// Firebase & Crashlytics
115117
rcxImplementation 'com.google.firebase:firebase-analytics:17.3.0'
116118
rcxImplementation 'com.google.firebase:firebase-crashlytics:17.0.0-beta03'

app/src/main/java/ca/pkay/rcloneexplorer/AppShortcutsHelper.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public static void populateAppShortcuts(Context context, List<RemoteItem> remote
4242
Set<String> shortcutSet = new HashSet<>();
4343
List<ShortcutInfo> shortcutInfoList = new ArrayList<>();
4444

45-
RemoteItem.prepareDisplay(context, remotes);
4645
for (RemoteItem remoteItem : remotes) {
4746
String id = getUniqueIdFromString(remoteItem.getName());
4847

@@ -51,7 +50,7 @@ public static void populateAppShortcuts(Context context, List<RemoteItem> remote
5150
intent.putExtra(APP_SHORTCUT_REMOTE_NAME, remoteItem.getName());
5251

5352
ShortcutInfo shortcut = new ShortcutInfo.Builder(context, id)
54-
.setShortLabel(remoteItem.getDisplayName())
53+
.setShortLabel(remoteItem.getName())
5554
.setIcon(Icon.createWithResource(context, AppShortcutsHelper.getRemoteIcon(remoteItem.getType(), remoteItem.isCrypt())))
5655
.setIntent(intent)
5756
.build();
@@ -164,7 +163,7 @@ public static void addRemoteToAppShortcuts(Context context, RemoteItem remoteIte
164163
intent.putExtra(APP_SHORTCUT_REMOTE_NAME, remoteItem.getName());
165164

166165
ShortcutInfo shortcut = new ShortcutInfo.Builder(context, id)
167-
.setShortLabel(remoteItem.getDisplayName())
166+
.setShortLabel(remoteItem.getName())
168167
.setIcon(Icon.createWithResource(context, AppShortcutsHelper.getRemoteIcon(remoteItem.getType(), remoteItem.isCrypt())))
169168
.setIntent(intent)
170169
.build();
@@ -184,7 +183,7 @@ public static void addRemoteToHomeScreen(Context context, RemoteItem remoteItem)
184183
intent.putExtra(APP_SHORTCUT_REMOTE_NAME, remoteItem.getName());
185184

186185
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(context, id)
187-
.setShortLabel(remoteItem.getDisplayName())
186+
.setShortLabel(remoteItem.getName())
188187
.setIcon(IconCompat.createWithResource(context, AppShortcutsHelper.getRemoteIcon(remoteItem.getType(), remoteItem.isCrypt())))
189188
.setIntent(intent)
190189
.build();

app/src/main/java/ca/pkay/rcloneexplorer/Dialogs/RemotePropertiesDialog.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
9090
LayoutInflater inflater = ((FragmentActivity) context).getLayoutInflater();
9191
view = inflater.inflate(R.layout.dialog_remote_properties, null);
9292

93-
((TextView) view.findViewById(R.id.remote_name)).setText(remote.getDisplayName());
93+
((TextView) view.findViewById(R.id.remote_name)).setText(remote.getName());
9494

9595
View storageContainer = view.findViewById(R.id.remote_storage_container);
9696
remoteStorageStats = view.findViewById(R.id.remote_storage_stats);

app/src/main/java/ca/pkay/rcloneexplorer/Fragments/FileExplorerFragment.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
303303
breadcrumbView = ((FragmentActivity) context).findViewById(R.id.breadcrumb_view);
304304
breadcrumbView.setOnClickListener(this);
305305
breadcrumbView.setVisibility(View.VISIBLE);
306-
breadcrumbView.addCrumb(remote.getDisplayName(), "//" + remoteName);
306+
breadcrumbView.addCrumb(remote.getName(), "//" + remoteName);
307307
if (savedInstanceState != null) {
308308
if (!directoryObject.getCurrentPath().equals("//" + remoteName)) {
309309
breadcrumbView.buildBreadCrumbsFromPath(directoryObject.getCurrentPath());
@@ -935,7 +935,7 @@ private void cancelMoveClicked() {
935935
if (!moveStartPath.equals("//" + remoteName)) {
936936
breadcrumbView.buildBreadCrumbsFromPath(directoryObject.getCurrentPath());
937937
}
938-
breadcrumbView.addCrumb(remote.getDisplayName(), "//" + remoteName);
938+
breadcrumbView.addCrumb(remote.getName(), "//" + remoteName);
939939
moveStartPath = null;
940940
}
941941
}

app/src/main/java/ca/pkay/rcloneexplorer/Fragments/RemotesFragment.java

+4-19
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,6 @@ private void refreshRemotes() {
302302
private List<RemoteItem> filterRemotes() {
303303
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
304304
Set<String> hiddenRemotes = sharedPreferences.getStringSet(getString(R.string.shared_preferences_hidden_remotes), new HashSet<>());
305-
Set<String> renamedRemotes = sharedPreferences.getStringSet(getString(R.string.pref_key_renamed_remotes), new HashSet<>());
306305
remotes = rclone.getRemotes();
307306
if (hiddenRemotes != null && !hiddenRemotes.isEmpty()) {
308307
ArrayList<RemoteItem> toBeHidden = new ArrayList<>();
@@ -314,13 +313,6 @@ private List<RemoteItem> filterRemotes() {
314313
remotes.removeAll(toBeHidden);
315314
}
316315
Collections.sort(remotes);
317-
for(RemoteItem item : remotes) {
318-
if(renamedRemotes.contains(item.getName())) {
319-
String displayName = sharedPreferences.getString(
320-
getString(R.string.pref_key_renamed_remote_prefix, item.getName()), item.getName());
321-
item.setDisplayName(displayName);
322-
}
323-
}
324316
return remotes;
325317
}
326318

@@ -469,21 +461,14 @@ private void renameRemote(final RemoteItem remoteItem) {
469461
builder = new AlertDialog.Builder(context);
470462
}
471463

472-
final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
473464
final EditText remoteNameEdit = new EditText(context);
474-
String initialText = remoteItem.getDisplayName();
465+
String initialText = remoteItem.getName();
475466
remoteNameEdit.setText(initialText);
476467
builder.setView(remoteNameEdit);
477468
builder.setNegativeButton(R.string.cancel, null);
478469
builder.setPositiveButton(R.string.select, (dialog, which) -> {
479-
String displayName = remoteNameEdit.getText().toString();
480-
Set<String> renamedRemotes = pref.getStringSet(getString(R.string.pref_key_renamed_remotes), new HashSet<>());
481-
renamedRemotes.add(remoteItem.getName());
482-
pref.edit()
483-
.putString(getString(R.string.pref_key_renamed_remote_prefix, remoteItem.getName()), displayName)
484-
.putStringSet(getString(R.string.pref_key_renamed_remotes), renamedRemotes)
485-
.apply();
486-
remoteItem.setDisplayName(displayName);
470+
String newName = remoteNameEdit.getText().toString();
471+
rclone.renameRemote(remoteItem.getName(), newName);
487472
refreshRemotes();
488473
});
489474
builder.setTitle(R.string.rename_remote);
@@ -498,7 +483,7 @@ private void deleteRemote(final RemoteItem remoteItem) {
498483
builder = new AlertDialog.Builder(context);
499484
}
500485
builder.setTitle(R.string.delete_remote_title);
501-
builder.setMessage(remoteItem.getDisplayName());
486+
builder.setMessage(remoteItem.getName());
502487
builder.setNegativeButton(R.string.cancel, null);
503488
builder.setPositiveButton(R.string.delete, (dialog, which) -> new DeleteRemote(context, remoteItem).execute());
504489
builder.show();

app/src/main/java/ca/pkay/rcloneexplorer/Fragments/ShareRemotesFragment.java

-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
5353
((FragmentActivity) context).setTitle(getString(R.string.remotes_toolbar_title));
5454
Rclone rclone = new Rclone(getContext());
5555
remotes = rclone.getRemotes();
56-
RemoteItem.prepareDisplay(getContext(), remotes);
5756
Collections.sort(remotes);
5857
}
5958

app/src/main/java/ca/pkay/rcloneexplorer/Items/RemoteItem.java

+4-22
Original file line numberDiff line numberDiff line change
@@ -249,27 +249,6 @@ public boolean isRemoteType(int ...remotes) {
249249
return isSameType;
250250
}
251251

252-
public String getDisplayName() {
253-
return displayName != null ? displayName : name;
254-
}
255-
256-
public void setDisplayName(String displayName) {
257-
this.displayName = displayName;
258-
}
259-
260-
public static List<RemoteItem> prepareDisplay(Context context, List<RemoteItem> items) {
261-
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
262-
Set<String> renamedRemotes = pref.getStringSet(context.getString(R.string.pref_key_renamed_remotes), new HashSet<>());
263-
for(RemoteItem item : items) {
264-
if(renamedRemotes.contains(item.name)) {
265-
String displayName = pref.getString(
266-
context.getString(R.string.pref_key_renamed_remote_prefix, item.name), item.name);
267-
item.displayName = displayName;
268-
}
269-
}
270-
return items;
271-
}
272-
273252
private int getTypeFromString(String type) {
274253
switch (type) {
275254
case SafConstants.SAF_REMOTE_NAME:
@@ -407,7 +386,10 @@ public int compareTo(@NonNull RemoteItem remoteItem) {
407386
} else if (!this.isPinned && remoteItem.isPinned) {
408387
return 1;
409388
}
410-
return getDisplayName().toLowerCase().compareTo(remoteItem.getDisplayName().toLowerCase());
389+
390+
String self = getName().toLowerCase();
391+
String other = remoteItem.getName().toLowerCase();
392+
return self.compareTo(other);
411393
}
412394

413395
@Override

app/src/main/java/ca/pkay/rcloneexplorer/MainActivity.java

+8-29
Original file line numberDiff line numberDiff line change
@@ -366,18 +366,9 @@ private void pinRemotesToDrawer() {
366366

367367
List<RemoteItem> remoteItems = rclone.getRemotes();
368368
Collections.sort(remoteItems);
369-
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
370-
Set<String> renamedRemotes = sharedPreferences.getStringSet(getString(R.string.pref_key_renamed_remotes), new HashSet<>());
371-
for(RemoteItem item : remoteItems) {
372-
if(renamedRemotes.contains(item.getName())) {
373-
String displayName = sharedPreferences.getString(
374-
getString(R.string.pref_key_renamed_remote_prefix, item.getName()), item.getName());
375-
item.setDisplayName(displayName);
376-
}
377-
}
378369
for (RemoteItem remoteItem : remoteItems) {
379370
if (remoteItem.isDrawerPinned()) {
380-
MenuItem menuItem = subMenu.add(R.id.nav_pinned, availableDrawerPinnedRemoteId, Menu.NONE, remoteItem.getDisplayName());
371+
MenuItem menuItem = subMenu.add(R.id.nav_pinned, availableDrawerPinnedRemoteId, Menu.NONE, remoteItem.getName());
381372
drawerPinnedRemoteIds.put(availableDrawerPinnedRemoteId, remoteItem);
382373
availableDrawerPinnedRemoteId++;
383374
menuItem.setIcon(remoteItem.getRemoteIcon());
@@ -735,9 +726,6 @@ protected void onPostExecute(Boolean success) {
735726
}
736727

737728
private class RefreshLocalAliases extends AsyncTask<Void, Void, Boolean> {
738-
739-
private String EMULATED = "5d44cd8d-397c-4107-b79b-17f2b6a071e8";
740-
741729
private LoadingDialog loadingDialog;
742730

743731
protected boolean isRequired() {
@@ -790,14 +778,10 @@ protected Boolean doInBackground(Void... aVoid) {
790778
}
791779
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
792780
Set<String> generated = pref.getStringSet(getString(R.string.pref_key_local_alias_remotes), new HashSet<>());
793-
Set<String> renamed = pref.getStringSet(getString(R.string.pref_key_renamed_remotes), new HashSet<>());
794781
SharedPreferences.Editor editor = pref.edit();
795782
for(String remote : generated) {
796783
rclone.deleteRemote(remote);
797-
renamed.remove(remote);
798-
editor.remove(getString(R.string.pref_key_renamed_remote_prefix, remote));
799784
}
800-
editor.putStringSet(getString(R.string.pref_key_renamed_remotes), renamed);
801785
editor.apply();
802786
File[] dirs = context.getExternalFilesDirs(null);
803787
for(File file : dirs) {
@@ -833,23 +817,22 @@ private File getVolumeRoot(File file) {
833817
private void addLocalRemote(File root) throws IOException {
834818
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
835819
String name = root.getCanonicalPath();
836-
String id = Environment.isExternalStorageEmulated(root) ? EMULATED : UUID.randomUUID().toString();
837820
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
838821
StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
839822
StorageVolume storageVolume = storageManager.getStorageVolume(root);
840-
name = storageVolume.getDescription(context);
841-
if (null != storageVolume.getUuid()) {
842-
id = storageVolume.getUuid();
823+
String description = storageVolume != null ? storageVolume.getDescription(context) : null;
824+
if (description != null) {
825+
name = rclone.getUniqueRemoteName(description);
843826
}
844827
}
845828

846829
String path = root.getAbsolutePath();
847830
ArrayList<String> options = new ArrayList<>();
848-
options.add(id);
831+
options.add(name);
849832
options.add("alias");
850833
options.add("remote");
851834
options.add(path);
852-
FLog.d(TAG, "Adding local remote [%s] remote = %s", id, path);
835+
FLog.d(TAG, "Adding local remote [%s] remote = %s", name, path);
853836
Process process = rclone.configCreate(options);
854837
try {
855838
process.waitFor();
@@ -861,15 +844,11 @@ private void addLocalRemote(File root) throws IOException {
861844
FLog.e(TAG, "addLocalRemote: process error", e);
862845
return;
863846
}
864-
Set<String> renamedRemotes = pref.getStringSet(getString(R.string.pref_key_renamed_remotes), new HashSet<>());
865847
Set<String> pinnedRemotes = pref.getStringSet(getString(R.string.shared_preferences_drawer_pinned_remotes), new HashSet<>());
866848
Set<String> generatedRemotes = pref.getStringSet(getString(R.string.pref_key_local_alias_remotes), new HashSet<>());
867-
renamedRemotes.add(id);
868-
pinnedRemotes.add(id);
869-
generatedRemotes.add(id);
849+
pinnedRemotes.add(name);
850+
generatedRemotes.add(name);
870851
pref.edit()
871-
.putStringSet(getString(R.string.pref_key_renamed_remotes), renamedRemotes)
872-
.putString(getString(R.string.pref_key_renamed_remote_prefix, id), name)
873852
.putStringSet(getString(R.string.shared_preferences_drawer_pinned_remotes), pinnedRemotes)
874853
.putStringSet(getString(R.string.pref_key_local_alias_remotes), generatedRemotes)
875854
.apply();

app/src/main/java/ca/pkay/rcloneexplorer/Rclone.java

+63-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import io.github.x0b.safdav.SafAccessProvider;
1919
import io.github.x0b.safdav.SafDAVServer;
2020
import io.github.x0b.safdav.file.SafConstants;
21+
22+
import org.apache.commons.io.FileUtils;
2123
import org.json.JSONArray;
2224
import org.json.JSONException;
2325
import org.json.JSONObject;
@@ -407,7 +409,6 @@ public Process configCreate(List<String> options) {
407409

408410
System.arraycopy(opt, 0, commandWithOptions, command.length, opt.length);
409411

410-
411412
try {
412413
return Runtime.getRuntime().exec(commandWithOptions);
413414
} catch (IOException e) {
@@ -1148,6 +1149,67 @@ public void exportConfigFile(Uri uri) throws IOException {
11481149
outputStream.close();
11491150
}
11501151

1152+
public boolean renameRemote(String remoteName, String newName) {
1153+
// RClone uses this library to parse its config file: https://github.com/unknwon/goconfig
1154+
// It's very similar to the INI syntax, where section corresponds to a
1155+
// remote. Sections can contain any unicode character except for line
1156+
// breaks and are completely unescaped.
1157+
1158+
boolean found = false;
1159+
String searchedLine = "[" + remoteName + "]";
1160+
File file = new File(rcloneConf);
1161+
List<String> configContent;
1162+
List<String> newConfigContent;
1163+
1164+
try {
1165+
configContent = FileUtils.readLines(file, "UTF-8");
1166+
} catch (IOException e) {
1167+
Log.e(TAG, "Couldn't parse RClone config.", e);
1168+
return false;
1169+
}
1170+
1171+
newConfigContent = new ArrayList<>(configContent.size());
1172+
for (String line : configContent) {
1173+
if (line.trim().equals(searchedLine)) {
1174+
newConfigContent.add("[" + newName + "]");
1175+
found = true;
1176+
}
1177+
else {
1178+
newConfigContent.add(line);
1179+
}
1180+
}
1181+
1182+
if (!found) {
1183+
return false;
1184+
}
1185+
1186+
try {
1187+
FileUtils.writeLines(file, newConfigContent);
1188+
} catch (IOException e) {
1189+
Log.e(TAG, "Couldn't write RClone config.", e);
1190+
return false;
1191+
}
1192+
1193+
return true;
1194+
}
1195+
1196+
public String getUniqueRemoteName(String desiredName) {
1197+
List<RemoteItem> remotes = getRemotes();
1198+
Set<String> remoteNames = new HashSet<>(remotes.size());
1199+
for (RemoteItem remoteItem : remotes) {
1200+
remoteNames.add(remoteItem.getName());
1201+
}
1202+
if (!remoteNames.contains(desiredName)) {
1203+
return desiredName;
1204+
}
1205+
for (int i = 1;;++i) {
1206+
String remoteName = desiredName + " " + i;
1207+
if (!remoteNames.contains(remoteName)) {
1208+
return remoteName;
1209+
}
1210+
}
1211+
}
1212+
11511213
/**
11521214
* Prefixes local remotes with a base path on the primary external storage.
11531215
* @param item

app/src/main/java/ca/pkay/rcloneexplorer/RecyclerViewAdapters/RemotesRecyclerViewAdapter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public void onBindViewHolder(@NonNull final ViewHolder holder, final int positio
4848
RemoteItem item = remotes.get(position);
4949
boolean isPinned = item.isPinned();
5050
holder.remoteName = item.getName();
51-
holder.tvName.setText(item.getDisplayName());
51+
holder.tvName.setText(item.getName());
5252

5353
int icon = item.getRemoteIcon();
5454
holder.ivIcon.setImageDrawable(view.getResources().getDrawable(icon));

app/src/main/java/ca/pkay/rcloneexplorer/RecyclerViewAdapters/ShareRemotesRecyclerViewAdapter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public void onBindViewHolder(@NonNull final ViewHolder holder, final int positio
4040
String remoteName = remotes.get(position).getName();
4141
boolean isPinned = remotes.get(position).isPinned();
4242
holder.remoteName = remoteName;
43-
holder.tvName.setText(remotes.get(position).getDisplayName());
43+
holder.tvName.setText(remotes.get(position).getName());
4444

4545
int icon = remotes.get(position).getRemoteIcon();
4646
holder.ivIcon.setImageDrawable(view.getResources().getDrawable(icon));

app/src/main/java/ca/pkay/rcloneexplorer/RemoteConfig/AliasConfig.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,11 @@ private void setRemote() {
131131
return;
132132
}
133133

134-
RemoteItem.prepareDisplay(context, remotes);
135-
Collections.sort(remotes, (a, b) -> a.getDisplayName().compareTo(b.getDisplayName()));
134+
Collections.sort(remotes, (a, b) -> a.getName().compareTo(b.getName()));
136135
String[] options = new String[remotes.size()];
137136
int i = 0;
138137
for (RemoteItem remote : remotes) {
139-
options[i++] = remote.getDisplayName();
138+
options[i++] = remote.getName();
140139
}
141140

142141
AlertDialog.Builder builder;

0 commit comments

Comments
 (0)