Giter Club home page Giter Club logo

ark-navigator's Introduction

ARK Navigator example workflow

ARK Navigator is the next-generation file browser built on the idea of tags.

If you never can find your files on your phone — this app is for you.

Development APK

The app is in active development phase, but you can already try it out.

Just visit GitHub Actions section of this repo and select the latest main build

Information for contributors

All information for contributors can be found at CONTRIBUTING.md

What is ARK Navigator?

ARK Navigator is an Android app that is being designed to help you navigate seamlessly through your data (images, videos, documents, etc.) located in your phone. In short, it is a file browser with an innovative tag-based labeling and search system. The app focuses on privacy and security since you are not relying on third-party cloud services and everything is done locally and offline.

What would be an ideal use case for this app?

Phones have turned out to be an integral part of our day-to-day lives even though they were initially used for just sending messages and placing calls. They are far more advanced these days, allowing you to save all kinds of personal and non-personal information. For example, you might capture your favorite moments from that one-day trip to the nearby waterfalls, a picture of a restaurant that you want to try out another time, some important official documents, your resume, the research papers you have been reading, your must-read list of ebooks, the list goes on! Before you know it, your phone is flooded with images, videos, screenshots, documents, etc. and you are struggling to find something in particular. It’s like searching for a needle in a haystack. ARK Navigator helps you in this situation by allowing you to browse your files through an easy-to-use interface designed particularly to tackle situations like this. It allows you to add tags to your files and retrieve them easily using the tags. You can be as creative as you want with the tagging system. For example, you could mark your ebooks as read/unread, fiction/non-fiction, based on the author's name, etc. You could mark videos as watched/unwatched, short film/movie/documentary/etc., personal/public, etc.

How does it work?

In short, the app works this way - Bookmark the relevant folders, view contents of folder, add tags to the items and filter the items using the added tags. It's also worth mentioning that one of key features of our app is the "aggregated mode". That's what happening when you just press "navigate data" button in the bottom bar. It takes resources from all folders and presents the single resource space to the user, allowing the user to navigate this space using power of tags. Although, we are still working on performance and UX of course, selecting individual folders is faster sometimes.

Bookmark folders: To bookmark a folder, press the plus (+) button located on the right side of the app, navigate to the folder you wish to bookmark, and press the “Add root” button. Folders added this way will be listed in the “Manage Folders'' view as Root folders. Subfolders in the root folders can be bookmarked/favorited again for easier access. To do that, open “Manage Folders”, press the plus (+) button next to the relevant root folder, navigate to a subfolder, and press the “Favorite” button. Subfolders favorited like this are listed when you expand the Root folders.

View the contents of root/favorite folder: To view the contents of a root/favorite button, press the compass button located next to it under the “Manage Folders” section.

Add tags to an item: To add tags to an item, open the item by tapping on it, press the pen icon, and jot down the tags that you find relevant to the item.

Filter items based on tags: If you have successfully completed Steps 1 to 3, then you have successfully managed to add tags to at least some of the images, videos, and documents that you have in your root/favorite folders. Some tags might even be shared by multiple items. To filter items based on tags, simply open the root/favorite folder (step 2), and tap on the tags that you are interested in. All the files that are irrelevant to the selected tags will be filtered out.

What to expect going forward?

This app is under development right now, with more and more features being added gradually. After the initial phase of development, the ARK Navigator should work with all kinds of files, allowing you to preview the files and manipulate them. In the future as well, you should expect advanced bookmarking that would allow you save a link to an online media resource such as Youtube, SoundCloud or Spotify.

ark-navigator's People

Contributors

amoweolubusayo avatar cloudlevi avatar dependabot[bot] avatar hhio618 avatar hieuwu avatar j4w3ny avatar kashif2016 avatar kirillt avatar mdrlzy avatar melvin4u445 avatar pgpathan22 avatar saxihuangxing avatar sdex avatar shubertm avatar sisco0 avatar tuancoltech avatar vishal2376 avatar zannis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ark-navigator's Issues

"Share" button in gallery mode

There should be "share" button displayed on top of preview in GalleryFragment. Similar to "edit" and "delete" buttons.

The action to trigger by this button is sharing the resource via external app like messengers.

Incremental sorting

Right now, sorting of resources causes small delays on huge collections (e.g. 5000 of pictures). After addition of persistence of sorting preferences, this delay is imposed after frequent actions: opening a folder and going back from gallery mode to resources grid.

It may be possible to perform sorting in a smarter way:

  1. find top T resources and put K of them into visible frame;
  2. spawn sorting of the rest of resources in background;
  3. allow the user to do his stuff.

Implementation can be non-trivial, but performance would be better:
blocking phase: T * N operations to find top T resources (where N is number of all resources)
background phase: normal sorting of N - T elements

"Pick" button stucks in "favorite" state

  1. Open folder picker.
  2. Walk into some known root — "add root" button grays out.
  3. Descend further into some folder — "add root" becomes "favorite".
  4. Go back with "back" button — "favorite" must change back to grayed-out "add root".
  5. Go back again — the button must change to active "add root".

During steps 4 and 5 the "pick" button still has label "favorite".
During step 4 the "pick" button is still active.

Full-Screen mode in GalleryFragment

In current state, when a user lists resources' previews in GalleryFragment, he can tap on a free space and this will hide controls.
It would be great to also switch picture into full-screen mode, hiding titlebar, bottom tabs switch and system topbar.

"Reset preferences" button

Such button would be useful for testing (quickly reset sorting or chosen apps to open certain types of resources).

ResourcesFragment: "tags off" gets stucked

How to reproduce:

  1. open a folder
  2. click "tags off" button (picture of crossed-out cloud)
  3. undo by clicking "tags on"
  4. open any resource
  5. go back (using system navigation button)

Expected:

  • all resources in the folder displayed

Actual:

  • only resources without tags displayed (the same as after step 2)

Filesystem monitoring and reactive updates

Ideally, we should react to changes in filesystem.

E.g. if some path P maps to id A, after an external app modified P it needs to be updated to id B.
This change also must be propagated to the tags storage since id changed.

But there are some unclear moments like if an external app, in fact, moved original file untouched to another path S and put new content to the original path P. In this case, id A is still in our collection, it just was moved from P to S, so we shouldn't change tags storage regarding A but only bind A to new path S in the resources index and bind P to new resource B.

There might be other corner cases. This feature requires to be discussed before approaching.

"Edit resource" button

In gallery screen, a resource must be capable of edition. The "edit tags" button should be moved into tags list so its place could be used by new "edit resource" button.

Global resources counter and occupied disk space info

This feature is conceptually simple, but requires some smart structure in fact.
Architecturally, we should modify the counter every time we index a resource.

Visually, these counters should be placed on the folders screen.

Resources grid details widget

Another improvement. It would be great if the user had the option to see the full path to the opened folder. There isn't enough space to display the full path on the header, so maybe we could show it somewhere in the white section? The header could just show the name of the current folder or something?

image

Access denied in SD card

How to reproduce:
add a tag to the resource on the SD card

It looks like this bug does not affect Android 11

Log:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: space.taran.arknavigator, PID: 8596
    java.nio.file.AccessDeniedException: /storage/1B0C-2304/DCIM/.ark-tags
        at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
        at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:434)
        at java.nio.file.Files.newOutputStream(Files.java:216)
        at java.nio.file.Files.write(Files.java:3351)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage$writeStorage$2.invokeSuspend(PlainTagsStorage.kt:174)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage$writeStorage$2.invoke(Unknown Source:8)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage$writeStorage$2.invoke(Unknown Source:4)
        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:161)
        at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage.writeStorage(PlainTagsStorage.kt:165)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage.access$writeStorage(PlainTagsStorage.kt:22)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage$persist$2.invokeSuspend(PlainTagsStorage.kt:136)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage$persist$2.invoke(Unknown Source:8)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage$persist$2.invoke(Unknown Source:4)
        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:161)
        at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage.persist(PlainTagsStorage.kt:90)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage.access$persist(PlainTagsStorage.kt:22)
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage$setTags$2.invokeSuspend(PlainTagsStorage.kt:68)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

"Focus on tag" capability in tags selector

Right now, the following actions can be applied to a chip (tag) in tags selector:

  1. Tap for selecting the tag. Tap again for unselecting.
  2. Long-tap for negating the tag. This means that all resources marked with the tag, will be filtered out of current selection.

The desired feature is third possible action:
3. Double-tap for "focus on" the tag. After this, the tag becomes selected. Then, all tags from available set become negated. Previously selected or negated tags must not be affected.

Huge images loading

When we load preview for an image, we should create hint for a user about size of it. Spinner animation also would not hurt. We should also verify later that even 100mb images load successfully.

Removal from resources index fails on huge collections

This SQL query

    @Query("DELETE FROM Resource where path in (:paths)")
    suspend fun deletePaths(paths: List<StringPath>)

fails when there are too much elements in paths:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: space.taran.arknavigator, PID: 27089
E/AndroidRuntime: android.database.sqlite.SQLiteException: too many SQL variables (Sqlite code 1 SQLITE_ERROR): , while compiling: DELETE FROM Resource where path in (?,?,...,?), (OS error - 0:Success)
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:948)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:559)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:603)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:63)
        at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
        at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1166)
        at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.compileStatement(FrameworkSQLiteDatabase.java:64)
        at androidx.room.RoomDatabase.compileStatement(RoomDatabase.java:459)
        at space.taran.arknavigator.mvp.model.dao.ResourceDao_Impl$4.call(ResourceDao_Impl.java:138)
        at space.taran.arknavigator.mvp.model.dao.ResourceDao_Impl$4.call(ResourceDao_Impl.java:129)
        at androidx.room.CoroutinesRoom$Companion$execute$2.invokeSuspend(CoroutinesRoom.kt:61)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at androidx.room.TransactionExecutor$1.run(TransactionExecutor.java:47)
        at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:784)

Tags storage access in coroutine

D/item-container: item 8 clicked
D/gallery-screen: preview at 8 clicked, switching controls on/off
E/: [ZeroHung]zrhung_get_config: Get config failed for wp[0x0102]
D/gallery-screen: tag todo on resource 1771473116 long-clicked
D/gallery-screen: closing dialog in GalleryFragment
D/gallery-screen: displaying tags of resource 1771473116 for preview
D/gallery-screen: displaying tags resource 1771473116 for edit
D/OpenGLRenderer:   HWUI Binary is  enabled
E/: [ZeroHung]zrhung_get_config: Get config failed for wp[0x0102]
D/gallery-screen: tags [ark] added to 1771473116
D/mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000
D/OpenGLRenderer:   HWUI Binary is  enabled
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: space.taran.arknavigator, PID: 13324
    java.lang.AssertionError: Storage isn't aware about this resource id
        at space.taran.arknavigator.mvp.model.repo.PlainTagsStorage$setTags$2.invokeSuspend(PlainTagsStorage.kt:62)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

Resource versions tracking

Related to #27

Every time a resource has changed, we can represent this change as a transition from id1 to id2. This transition we can store in replicated state (or send to another app instance, but it will complicate implementation and should be avoided if possible). Afterwards, it should ease conflicts resolution.

Fix warnings

This issue will be updated with various debt about warnings.

MainActivity.kt: (55, 27): 'setOnNavigationItemSelectedListener(BottomNavigationView.OnNavigationItemSelectedListener?): Unit' is deprecated. Deprecated in Java

MainActivity.kt: (168, 15): 'onActivityResult(Int, Int, Intent?): Unit' is deprecated. Overrides deprecated member in 'androidx.activity.ComponentActivity'. Deprecated in Java

Boosting priority of folders in indexing queue, basing on type and access frequency

When a user opens the app, she sees folders screen. Indexing of resources should start immediately in background. All "favorites" should be placed first in the queue, "roots" follow after. Every folder must have score which is incremented every time the user opens the folder. If types of 2 folders are the same, their scores are used to order them in the queue.

Remember expanded and collapsed folders

This is more of an improvement than a bug.
It is a few extra steps each time to open the root folders again after pressing the compass button and returning back to the Manage Folders tab.

Ideally, the app remembers the expanded and collapsed folders and displays it when the user returns back to the view

collapsing_folders.mp4

Tags editing and bulk operations

It must be possible to edit tags, i.e. rename or delete them.

Renaming a tag from A to B walks through all resources labeled with A, removes A from them and sets B instead. Deletion of a tag X just removes it from all resources labeled with X.

"Open with" button in gallery mode

There should be "open with" button displayed on top of preview in GalleryFragment. Similar to "edit" and "delete" buttons.

The action to trigger by this button is opening the resource in an external app. E.g. video might be opened in video player or html file might be opened in web browser.

Storage file format upgrades

When the app reads a tags storage file, it checks the format version. If the version is lower than the current one, the file must be upgraded before using.

The app must contain code for upgrades between any two adjacent versions. Backup of the file should be done before upgrade.

Resources grid forgets sorting after tags changed in the selector

  1. Open a folder.
  2. [optionally] select some tags
  3. Choose sorting type. Now resources are sorted correctly.
  4. Select different tags so another resources are presented.

Expected: resources are sorted with ordering type specified before.
Actual: resources are not sorted. Sorting menu displays ordering type chosen before.

Tags editing dialog: focus on the input

When tags editing dialog is spawned, focus must be on the text input and keyboard must be displayed.
This reduces amount of time necessary to input a tag.

Faster id calculation

Right now, CRC-32 hash is used for resource identification.
Calculation of hash of some file's content can take the same time as reading the file from disk.

This should be improved. Maybe with native library.

Persisted sorting preferences

Sorting preferences must be saved between runs. E.g. if a user chooses "sort by size, descending", this choice must be still enabled even after the user left the app, or the app crashed and restarted.

Previews for PDF files

In gallery mode PDF files should be depicted by it's first page.
If possible, number of pages should be depicted on top of preview.

In resources grid PDF files should be depicted by special PDF icon.
If possible, number of pages should be overlayed on top the icon.

Remember tags on/off state

The tag on/off state is not remembered when returning back after viewing media

As you see in the video, tags were turned ON before viewing media. When returning back to the view, the button shows as OFF again

tag_button_state.mp4

Syncthing folder as a device

There is a software called Syncthing: https://syncthing.net/

Our app's focus is on easy replication of data — we don't involve our own syncing mechanism, but we assume that a user can replicate his files to other devices. That's why we store tags in files inside of user-chosen folders. These storage files will be automatically replicated (whether it is by USB drive, or by syncing software like Syncthing).

But Syncthing on Android versions allows writing only into folders inside of Synthing's folder.
This makes a user to choose long paths, so we can ease this by creating a virtual device for Syncthing in our app.

Fragments must be restorable

Right now, if a user leaves the app on, e.g. GalleryFragment, and switches to another app, and OS kills our app — after Android attempts to restore our app, it will crash. The reason is that Android can restore only fragments with empty constructors.

Fragments should be reworked to gain this capability, particularly GalleryFragment and ResourcesFragment.

Boosting priority of resources in indexing queue

Asynchronous indexing (#23) will allow a user to continue working while she has some resources in indexing queue. This means, that some of resources can have modified tags and unknown (yet) id. Such resources should gain priority of indexing.

"Shuffle" button in resources grid

The button must shuffle current selection every time (it isn't "as-is" ordering).

Lazy shuffling could be implemented for usage with big collections: select random N resources, where N is amount of visible items in the grid; select next ones only when a user scrolls the grid or the gallery. Similar to #73.

Background indexing

It would be great, if a user could switch to other activities with the app while huge folders are being indexed.
E.g. trigger indexing of other folders or tag resources. It can happen that the user tags a resource, which is still not indexed.
Then we need to postpone modification of the storage, since we don't know the resource's id.
This means, beside of indexing queue we also need to create tagging queue.

Bulk resources operations

It should be possible to apply some operations to selections, e.g. to move all selected resources to some folder (favorite or root) with all their tags.

Icons for various types of files

Right now, we only have predefined previews (icons) for "file" and "folder" types.
It is necessary to add icons for html, txt, doc and other types of files.

Display progress spinner when resources are being sorted

Huge folders can cause ResourcesFragment freeze during sorting — sorting of 5000 resources freezes for 5 seconds on my Huawei P10. We should inform user about operation in progress. Also would be great to attach short label to any spinner animation: like "indexing" and "sorting" to provide a user with clue about what exactly takes time (so she can disable sorting for instance).

Previews for video files

Some random frame from the video would be enough.
It can be useful to overlay also duration of the video and quality.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.