Skip to content

Commit

Permalink
Add setting for enabling subfolders
Browse files Browse the repository at this point in the history
The feature is disabled by default. In the long run, we want to enable
it by default, and finally remove it. But I'm not sure how to best do
that without disrupting the UX.
  • Loading branch information
amberin committed Oct 4, 2024
1 parent f0cccf2 commit c91953c
Show file tree
Hide file tree
Showing 14 changed files with 257 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,13 @@ class DocumentRepoTest : SyncRepoTest, OrgzlyTest() {
}

@Test
override fun testGetBooks_singleFileInSubfolder() {
SyncRepoTest.testGetBooks_singleFileInSubfolder(repoDirectory, syncRepo)
override fun testGetBooks_singleFileInSubfolderWhenEnabled() {
SyncRepoTest.testGetBooks_singleFileInSubfolderWhenEnabled(repoDirectory, syncRepo)
}

@Test
override fun testGetBooks_singleFileInSubfolderWhenDisabled() {
SyncRepoTest.testGetBooks_singleFileInSubfolderWhenDisabled(repoDirectory, syncRepo)
}

@Test
Expand Down Expand Up @@ -81,8 +86,13 @@ class DocumentRepoTest : SyncRepoTest, OrgzlyTest() {
}

@Test
override fun testStoreBook_producesSameUriAsRetrieveBook() {
SyncRepoTest.testStoreBook_producesSameUriAsRetrieveBook(syncRepo)
override fun testStoreBook_producesSameUriAsRetrieveBookWithSubfolder() {
SyncRepoTest.testStoreBook_producesSameUriAsRetrieveBookWithSubfolder(syncRepo)
}

@Test
override fun testStoreBook_producesSameUriAsRetrieveBookWithoutSubfolder() {
SyncRepoTest.testStoreBook_producesSameUriAsRetrieveBookWithoutSubfolder(syncRepo)
}

@Test
Expand All @@ -95,6 +105,11 @@ class DocumentRepoTest : SyncRepoTest, OrgzlyTest() {
SyncRepoTest.testStoreBook_inSubfolder(repoDirectory, syncRepo)
}

@Test(expected = IOException::class)
override fun testStoreBook_inSubfolderWhenDisabled() {
SyncRepoTest.testStoreBook_inSubfolderWhenDisabled(syncRepo)
}

@Test
override fun testRenameBook_expectedUri() {
SyncRepoTest.testRenameBook_expectedUri(syncRepo)
Expand All @@ -106,8 +121,13 @@ class DocumentRepoTest : SyncRepoTest, OrgzlyTest() {
}

@Test
override fun testRenameBook_fromRootToSubfolder() {
SyncRepoTest.testRenameBook_fromRootToSubfolder(syncRepo)
override fun testRenameBook_fromRootToSubfolderWhenEnabled() {
SyncRepoTest.testRenameBook_fromRootToSubfolderWhenEnabled(syncRepo)
}

@Test(expected = IOException::class)
override fun testRenameBook_fromRootToSubfolderWhenDisabled() {
SyncRepoTest.testRenameBook_fromRootToSubfolderWhenDisabled(syncRepo)
}

@Test
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/java/com/orgzly/android/prefs/AppPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,19 @@ public static void refileLastLocation(Context context, String value) {
getStateSharedPreferences(context).edit().putString(key, value).apply();
}

/*
* Subfolder support
*/
public static boolean subfolderSupport(Context context) {
String key = context.getResources().getString(R.string.pref_key_enable_repo_subfolders);
return getStateSharedPreferences(context).getBoolean(key, false);
}

public static void subfolderSupport(Context context, boolean value) {
String key = context.getResources().getString(R.string.pref_key_enable_repo_subfolders);
getStateSharedPreferences(context).edit().putBoolean(key, value).apply();
}

/*
* Repository properties map
*/
Expand Down
21 changes: 16 additions & 5 deletions app/src/main/java/com/orgzly/android/repos/DocumentRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.orgzly.R;
import com.orgzly.android.BookName;
import com.orgzly.android.db.entity.Repo;
import com.orgzly.android.prefs.AppPreferences;
import com.orgzly.android.util.LogUtils;
import com.orgzly.android.util.MiscUtils;

Expand Down Expand Up @@ -117,6 +118,8 @@ private List<DocumentFile> walkFileTree() {
for (DocumentFile node : currentDir.listFiles()) {
String repoRelativePath = BookName.getRepoRelativePath(repoUri, node.getUri());
if (node.isDirectory()) {
if (!AppPreferences.subfolderSupport(context))
continue;
if (Build.VERSION.SDK_INT >= 26) {
if (ignores.isPathIgnored(repoRelativePath, true)) {
continue;
Expand Down Expand Up @@ -176,10 +179,14 @@ public VersionedRook storeBook(File file, String repoRelativePath) throws IOExce
}
DocumentFile destinationFile = getDocumentFileFromPath(repoRelativePath);
if (repoRelativePath.contains("/")) {
DocumentFile destinationDir = ensureDirectoryHierarchy(repoRelativePath);
String fileName = Uri.parse(repoRelativePath).getLastPathSegment();
if (destinationDir.findFile(fileName) == null) {
destinationFile = destinationDir.createFile("text/*", fileName);
if (AppPreferences.subfolderSupport(context)) {
DocumentFile destinationDir = ensureDirectoryHierarchy(repoRelativePath);
String fileName = Uri.parse(repoRelativePath).getLastPathSegment();
if (destinationDir.findFile(fileName) == null) {
destinationFile = destinationDir.createFile("text/*", fileName);
}
} else {
throw new IOException("Subfolder support has not been enabled");
}
} else {
if (!destinationFile.exists()) {
Expand Down Expand Up @@ -246,7 +253,11 @@ public VersionedRook renameBook(Uri oldFullUri, String newName) throws IOExcepti
Uri newUri = oldFullUri;

if (newName.contains("/")) {
newDir = ensureDirectoryHierarchy(newName);
if (AppPreferences.subfolderSupport(context)) {
newDir = ensureDirectoryHierarchy(newName);
} else {
throw new IOException("Subfolder support has not been enabled");
}
} else {
newDir = repoDocumentFile;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public List<VersionedRook> getBooks(Uri repoUri, RepoIgnoreNode ignores) throws
list.add(book);
}
}
if (metadata instanceof FolderMetadata) {
if (metadata instanceof FolderMetadata && AppPreferences.subfolderSupport(mContext)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (ignores.isPathIgnored(pathRelativeToRepoRoot, true)) {
continue;
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/orgzly/android/repos/DropboxRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

import androidx.annotation.NonNull;

import com.orgzly.android.App;
import com.orgzly.android.BookName;
import com.orgzly.android.prefs.AppPreferences;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -61,6 +63,8 @@ public VersionedRook storeBook(File file, String repoRelativePath) throws IOExce

@Override
public VersionedRook renameBook(Uri oldFullUri, String newName) throws IOException {
if (newName.contains("/") && !AppPreferences.subfolderSupport(App.getAppContext()))
throw new IOException("Subfolder support has not been enabled");
BookName oldBookName = BookName.fromRepoRelativePath(BookName.getRepoRelativePath(repoUri, oldFullUri));
String newRelativePath = BookName.repoRelativePath(newName, oldBookName.getFormat());
String newEncodedRelativePath = Uri.encode(newRelativePath, "/");
Expand Down
8 changes: 7 additions & 1 deletion app/src/main/java/com/orgzly/android/repos/GitRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
import android.util.Log;

import com.orgzly.BuildConfig;
import com.orgzly.android.App;
import com.orgzly.android.BookFormat;
import com.orgzly.android.BookName;
import com.orgzly.android.db.entity.Repo;
import com.orgzly.android.git.GitFileSynchronizer;
import com.orgzly.android.git.GitPreferences;
import com.orgzly.android.git.GitPreferencesFromRepoPrefs;
import com.orgzly.android.git.GitTransportSetter;
import com.orgzly.android.prefs.AppPreferences;
import com.orgzly.android.prefs.RepoPreferences;
import com.orgzly.android.util.LogUtils;

Expand Down Expand Up @@ -260,6 +262,7 @@ public List<VersionedRook> getBooks() throws IOException {
walk.setRecursive(true);
walk.addTree(synchronizer.currentHead().getTree());
final RepoIgnoreNode ignores = new RepoIgnoreNode(this);
boolean supportsSubFolders = AppPreferences.subfolderSupport(App.getAppContext());
walk.setFilter(new TreeFilter() {
@Override
public boolean include(TreeWalk walker) {
Expand All @@ -269,7 +272,7 @@ public boolean include(TreeWalk walker) {
if (ignores.isIgnored(repoRelativePath, isDirectory) == IgnoreNode.MatchResult.IGNORED)
return false;
if (isDirectory)
return true;
return supportsSubFolders;
return BookName.isSupportedFormatFileName(repoRelativePath);
}

Expand Down Expand Up @@ -298,6 +301,9 @@ public void delete(Uri uri) throws IOException {
}

public VersionedRook renameBook(Uri oldFullUri, String newName) throws IOException {
if (newName.contains("/") && !AppPreferences.subfolderSupport(App.getAppContext())) {
throw new IOException("Subfolder support has not been enabled");
}
String oldPath = oldFullUri.toString().replaceFirst("^/", "");
String newPath = BookName.repoRelativePath(newName, BookFormat.ORG);
if (synchronizer.renameFileInRepo(oldPath, newPath)) {
Expand Down
16 changes: 14 additions & 2 deletions app/src/main/java/com/orgzly/android/repos/WebdavRepo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import com.burgstaller.okhttp.basic.BasicAuthenticator
import com.burgstaller.okhttp.digest.CachingAuthenticator
import com.burgstaller.okhttp.digest.Credentials
import com.burgstaller.okhttp.digest.DigestAuthenticator
import com.orgzly.android.App
import com.orgzly.android.BookName
import com.orgzly.android.prefs.AppPreferences
import com.thegrizzlylabs.sardineandroid.DavResource
import com.thegrizzlylabs.sardineandroid.impl.OkHttpSardine
import okhttp3.OkHttpClient
Expand Down Expand Up @@ -166,8 +168,14 @@ class WebdavRepo(

val ignores = RepoIgnoreNode(this)

val listDepth = if (AppPreferences.subfolderSupport(App.getAppContext())) {
-1
} else {
1
}

return sardine
.list(url, -1)
.list(url, listDepth)
.mapNotNull {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!BookName.isSupportedFormatFileName(it.name) || ignores.isPathIgnored(it.getRelativePath(), it.isDirectory)) {
Expand Down Expand Up @@ -244,7 +252,11 @@ class WebdavRepo(
}

if (newName.contains("/")) {
ensureDirectoryHierarchy(newEncodedRelativePath)
if (AppPreferences.subfolderSupport(App.getAppContext())) {
ensureDirectoryHierarchy(newEncodedRelativePath)
} else {
throw IOException("Subfolder support has not been enabled")
}
}

sardine.move(oldFullUri.toUrl(), newFullUrl)
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/values/prefs_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,10 @@
<string name="pref_key_highlight_edited_rich_text" translatable="false">pref_key_highlight_edited_rich_text</string>
<bool name="pref_default_highlight_edited_rich_text" translatable="false">false</bool>

<!-- Subfolder support -->
<string name="pref_key_enable_repo_subfolders" translatable="false">pref_key_enable_repo_subfolders</string>
<bool name="pref_default_enable_repo_subfolders" translatable="false">false</bool>

<!-- Git preferences -->
<string name="pref_key_git_ssh_key_type" translatable="false">pref_key_git_ssh_key_type</string>
<string name="pref_key_git_author" traslatable="false">pref_key_git_author</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@
<!-- Preferences (Settings). -->
<string name="repos_preference_title">Repositories</string>
<string name="repos_preference_summary">Location to synchronize your notebooks with</string>
<string name="enable_repo_subfolders_preferences_title">Support repository subfolders</string>
<string name="enable_repo_subfolders_preferences_summary">Load from and write to subfolders</string>
<string name="ssh_keygen_preference_title">SSH key generation</string>
<string name="ssh_keygen_preference_summary">Generate key pair for Git repo sync</string>
<string name="ssh_show_public_key_preference_title">View generated SSH public key</string>
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/xml/prefs_screen_sync.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
android:targetClass="com.orgzly.android.ui.repos.ReposActivity"/>
</Preference>

<SwitchPreference
android:key="@string/pref_key_enable_repo_subfolders"
android:title="@string/enable_repo_subfolders_preferences_title"
android:summary="@string/enable_repo_subfolders_preferences_summary"
android:defaultValue="@bool/pref_default_enable_repo_subfolders"/>

<androidx.preference.PreferenceScreen
android:key="prefs_screen_auto_sync"
android:title="@string/auto_sync"
Expand Down
32 changes: 26 additions & 6 deletions app/src/test/java/com/orgzly/android/repos/DropboxRepoTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,13 @@ class DropboxRepoTest : SyncRepoTest {
}

@Test
override fun testGetBooks_singleFileInSubfolder() {
SyncRepoTest.testGetBooks_singleFileInSubfolder(client, syncRepo)
override fun testGetBooks_singleFileInSubfolderWhenEnabled() {
SyncRepoTest.testGetBooks_singleFileInSubfolderWhenEnabled(client, syncRepo)
}

@Test
override fun testGetBooks_singleFileInSubfolderWhenDisabled() {
SyncRepoTest.testGetBooks_singleFileInSubfolderWhenDisabled(client, syncRepo)
}

@Test
Expand Down Expand Up @@ -84,8 +89,13 @@ class DropboxRepoTest : SyncRepoTest {
}

@Test
override fun testStoreBook_producesSameUriAsRetrieveBook() {
SyncRepoTest.testStoreBook_producesSameUriAsRetrieveBook(syncRepo)
override fun testStoreBook_producesSameUriAsRetrieveBookWithSubfolder() {
SyncRepoTest.testStoreBook_producesSameUriAsRetrieveBookWithSubfolder(syncRepo)
}

@Test
override fun testStoreBook_producesSameUriAsRetrieveBookWithoutSubfolder() {
SyncRepoTest.testStoreBook_producesSameUriAsRetrieveBookWithoutSubfolder(syncRepo)
}

@Test
Expand All @@ -98,6 +108,11 @@ class DropboxRepoTest : SyncRepoTest {
SyncRepoTest.testStoreBook_inSubfolder(client, syncRepo)
}

@Test
override fun testStoreBook_inSubfolderWhenDisabled() {
SyncRepoTest.testStoreBook_inSubfolderWhenDisabled(syncRepo)
}

@Test
override fun testRenameBook_expectedUri() {
SyncRepoTest.testRenameBook_expectedUri(syncRepo)
Expand All @@ -109,8 +124,13 @@ class DropboxRepoTest : SyncRepoTest {
}

@Test
override fun testRenameBook_fromRootToSubfolder() {
SyncRepoTest.testRenameBook_fromRootToSubfolder(syncRepo)
override fun testRenameBook_fromRootToSubfolderWhenEnabled() {
SyncRepoTest.testRenameBook_fromRootToSubfolderWhenEnabled(syncRepo)
}

@Test(expected = IOException::class)
override fun testRenameBook_fromRootToSubfolderWhenDisabled() {
SyncRepoTest.testRenameBook_fromRootToSubfolderWhenDisabled(syncRepo)
}

@Test
Expand Down
32 changes: 26 additions & 6 deletions app/src/test/java/com/orgzly/android/repos/GitRepoTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,13 @@ class GitRepoTest : SyncRepoTest {
}

@Test
override fun testGetBooks_singleFileInSubfolder() {
SyncRepoTest.testGetBooks_singleFileInSubfolder(gitWorkingTree, syncRepo)
override fun testGetBooks_singleFileInSubfolderWhenEnabled() {
SyncRepoTest.testGetBooks_singleFileInSubfolderWhenEnabled(gitWorkingTree, syncRepo)
}

@Test
override fun testGetBooks_singleFileInSubfolderWhenDisabled() {
SyncRepoTest.testGetBooks_singleFileInSubfolderWhenDisabled(gitWorkingTree, syncRepo)
}

@Test
Expand Down Expand Up @@ -86,8 +91,13 @@ class GitRepoTest : SyncRepoTest {
}

@Test
override fun testStoreBook_producesSameUriAsRetrieveBook() {
SyncRepoTest.testStoreBook_producesSameUriAsRetrieveBook(syncRepo)
override fun testStoreBook_producesSameUriAsRetrieveBookWithSubfolder() {
SyncRepoTest.testStoreBook_producesSameUriAsRetrieveBookWithSubfolder(syncRepo)
}

@Test
override fun testStoreBook_producesSameUriAsRetrieveBookWithoutSubfolder() {
SyncRepoTest.testStoreBook_producesSameUriAsRetrieveBookWithoutSubfolder(syncRepo)
}

@Test
Expand All @@ -100,6 +110,11 @@ class GitRepoTest : SyncRepoTest {
SyncRepoTest.testStoreBook_inSubfolder(gitWorkingTree, syncRepo)
}

@Test
override fun testStoreBook_inSubfolderWhenDisabled() {
SyncRepoTest.testStoreBook_inSubfolderWhenDisabled(syncRepo)
}

@Test
override fun testRenameBook_expectedUri() {
SyncRepoTest.testRenameBook_expectedUri(syncRepo)
Expand All @@ -111,8 +126,13 @@ class GitRepoTest : SyncRepoTest {
}

@Test
override fun testRenameBook_fromRootToSubfolder() {
SyncRepoTest.testRenameBook_fromRootToSubfolder(syncRepo)
override fun testRenameBook_fromRootToSubfolderWhenEnabled() {
SyncRepoTest.testRenameBook_fromRootToSubfolderWhenEnabled(syncRepo)
}

@Test(expected = IOException::class)
override fun testRenameBook_fromRootToSubfolderWhenDisabled() {
SyncRepoTest.testRenameBook_fromRootToSubfolderWhenDisabled(syncRepo)
}

@Test
Expand Down
Loading

0 comments on commit c91953c

Please sign in to comment.