amake / orgro

An Org Mode file viewer for iOS and Android
https://orgro.org
GNU General Public License v3.0
452 stars 21 forks source link

Support opening relative links #5

Closed amake closed 3 years ago

amake commented 4 years ago

It would be nice to support opening relative file links like [[./other_file.org][related text]].

Issues:

alexeyre commented 4 years ago

I know apps like Syncthing use the new scoped-storage API on android to request access to a whole folder, so that's an option for addressing issue 1, for android at least, I don't know anything about iOS development... imho the file should close the current file and open the new one in it's place, rather than trying to implement some kind of slide-over system, but that's just my two-cents.

fgilbert68 commented 3 years ago

I would really like this. I heavily rely on links like [[other_file.org::*Some outline][related text]] to switch between ideas and the Org file where they are written. For me, the natural way would be to close the current file and open the new one; displaying a "narrow" view if the link includes an outline. It would be a bonus if we can navigate back to where the link was, as we can do using "C-c &" in Emacs.

I'm not sure I understand the URI issue (but I don't know anything about the apparently very complex world of Android permissions). All my org files are in the same directory on the SD card (copied there using rsync through a davfs mount...), and if this is the case (as you suggested by writing [[./other_file.org]]), no extra permission should be needed?

amake commented 3 years ago

All my org files are in the same directory on the SD card (copied there using rsync through a davfs mount...), and if this is the case (as you suggested by writing [[./other_file.org]]), no extra permission should be needed?

Right now Orgro can only obtain permissions to individual files. So to access a separate file I would need to make you choose it from a picker. If I can preselect the file that might not be so bad. If I cache the access ID then you'd only have to choose it once.

But then you're still choosing each new file.

I'm not sure if obtaining permission to a directory would let me access all of its children. It might. But then there is a new concept of "choosing a directory" to somehow include in the UI and make it clear how/why you need to do that. That might require redoing all of the file-opening workflow code.

So this ticket is stuck waiting for me to have time to investigate all of this.

mcubrilo commented 3 years ago

bump

alensiljak commented 3 years ago

Very briefly, I can confirm that Flutter on Android can obtain permissions for a folder on external storage. Just recently I worked on the related code in GitJournal. This allows opening any file within the hierarchy below the selected location.

I'd agree that a more-encompassing strategy regarding file-opening would be worthwhile. I'm using Orgro as the viewer for the files edited by Orgzly, located in a local repository (folder). The folder tree is synchronized via rclone or syncthing.

Perhaps an option to "add a folder" could simply display all the .org files within? The issue with the current file-based permission from the content provider is that the permission is void as soon as the file/content is edited. After each edit, I need to re-select the file to preview it. Hopefully I still remember where exactly it is located. Going further, iterating through a folder tree and displaying notes (hopefully in a tree structure) would solve that issue for me completely. Probably would never have to select another file in Orgro again. This would, naturally, require refreshing the list occasionally (automatically).

amake commented 3 years ago

For #37 I've hit upon what I consider a plausible UI for requesting document-specific access permissions, so this is partially unblocked.

My idea is to detect at open time whether there are relative links, and to compute the common root directory.

Support for #22 falls out of this scheme plus #37.

Remaining issues

Getting permissions

I use file_picker_writable to get persistent access to files, but this plugin doesn't allow selecting directories. So I either need to add the functionality to that plugin, or write my own (see https://github.com/hpoul/file_picker_writable/issues/16).

Resolving relative path

Resolving a relative path against a security-scoped directory URL might not be super hard, but it at least seems like it will require a round-trip to the native layer so it is non-trivial.

Handling permissions

Directory permissions should be persisted so that the user doesn't get asked every time.

Given a set of existing permissions and a set of URLs, it might be non-trivial to compute whether we need to ask for additional permissions.

Permissions may expire or otherwise become temporarily or permanently unusable (switching users in Google Drive); figuring out how to cull them might be important.

Error handling

Rejected ideas

I don't want to change the topmost file-picking UI to introduce the concept of directories, or implement some sort of generalized directory tree browser.

alensiljak commented 3 years ago

I don't want to change the topmost file-picking UI to introduce the concept of directories, or implement some sort of generalized directory tree browser.

Interesting, since you mentioned you want to stick to the original OrgMode features yet here you reject the most basic one? OrgMode is defacto a file-based, therefore directory-based, system of notes. Why the disconnect?

I'm asking because it seems that most of the open issues would be resolved by implementing a folder-based structure.

amake commented 3 years ago

OrgMode is defacto a file-based, therefore directory-based, system of notes. Why the disconnect?

I disagree with this premise. Org Mode is buffer-based. Buffers are often backed by files, but don't have to be. Links (relative and otherwise) can point to files, but don't have to. You could have Org Mode function exactly as-is but have all the data come out of a database, or be fetched over the network, or really anything, as long as the links resolve by some mechanism.

There is nothing fundamental to Org Mode about either files or directories.

I'm asking because it seems that most of the open issues would be resolved by implementing a folder-based structure.

amake commented 3 years ago

I have this implemented locally to some degree, but there are large limitations.

Android-specific

It appears to be a fundamental limitation of the Android Storage Access Framework that you can't resolve up the tree from a known content URI.

If you open a file /a/b/foo.org that has a relative link to ../c/bar.org, the app must prompt for access permissions to /a, but given the content URI for foo.org (obtained from a file picker) and the relative path to bar.org (obtained from the content of foo.org), there seems to be no way to get a content URI for /a or even discover the name a. This means that prompting for access has very poor UX: I can't pre-select /a for the user or even tell them to select /a; I can only say "select the directory corresponding to .. from the file foo.org.

Either that, or I have to ask for permission to manage the entire provider document tree. That doesn't seem reasonable, and even then it's not clear that all paths are readily resolvable.

While Android is particularly restrictive in this regard, and iOS is less so, by virtue of being a Flutter app I can only reasonably target the least common denominator. So iOS suffers as well.

iOS and Android

Very few content providers implement support for picking a directory (ACTION_OPEN_DOCUMENT_TREE on Android; kUTTypeFolder on iOS). The only ones I've managed to find so far are:

(Providers that definitely don't support it include Google Drive and Dropbox.)

So opening relative links will be limited to supported providers, but I don't know of a way to programmatically determine if a provider supports it, so there will be some annoyances.

amake commented 3 years ago

This will be implemented in v1.18.0, which will be available for testing soon:

See here for details and caveats.

amake commented 3 years ago

v1.18.0 is now available for testing on Test Flight and Google Play.

amake commented 3 years ago

This is implemented in v1.18.1, which is out for all platforms.