owncloud / android

:phone: The ownCloud Android App
GNU General Public License v2.0
3.8k stars 3.05k forks source link

Search feature for the Android App #695

Open supportreq opened 9 years ago

supportreq commented 9 years ago

Adding a search above the file listing


Edited by @davigonz from here on


We are going to face this in different stages:

1. Local search [DONE]

Here you have a gif showing how the local search looks like

2. Search using API: https://github.com/owncloud/core/issues/25373#issuecomment-400967608

https://github.com/owncloud/core/pull/31873

CC @michaelstingl @jesmrec

tobiasKaminsky commented 9 years ago

Do you mean a filter function for one folder: Current folder contains 500 files, you type "abc" in filter and it shows only 2 files? (this should be easy, though the right UX should be discussed a bit more).

Or do you want a real search: Searching for "abc" on the server across all folders? Then the results have to be shown with the folder where the file lies... (much more complex)

supportreq commented 9 years ago

we can start with the first filter.. something which apps like dropbox offers

tobiasKaminsky commented 9 years ago

I have splitted "filter function" to #696, so this issue is all about real search.

tobiasKaminsky commented 9 years ago

e0f31070-643d-11e4-8a07-d28b3a47ae44

@davivel @jancborchardt

Searching is usually done from a "magnifying glass" button in the action bar; the input field is then put in the action bar, replacing the title.

Your proposal is the same like dropbox does it? But I think it would be good to have the folder structure shown. For example on the screenshot no one can distinguish the "test" folder or say where they are located.

jancborchardt commented 9 years ago

@tobiasKaminsky then in case of two exactly same folder names in the results we can show the path in parentheses behind it. If the names are all unique, no need to show the path. (This is similar how Sublime Text does it for open files.)

tobiasKaminsky commented 9 years ago

@jancborchardt Hmm. My intension to display the path is that the user can navigate next time to the desired file without searching again. Or how would he know, that file "test.jpg" is in /images/wedding/ ? The navigation bar on the top of the display is only displayed when you browse in a folder. But if you would open an image directly you will never know where this file is located in owncloud.

davivel commented 9 years ago

@jancborchardt Parentheses? May be "heavy". What about path in smaller text under the name?

@tobiasKaminsky , we can reconsider the preview layout to show the current path in some place.

jancborchardt commented 9 years ago

@davivel good call, path in smaller text under the name. Then we can also show it always @tobiasKaminsky

supportreq commented 9 years ago

Hey guys, any update for this?

mahermeg17 commented 9 years ago

hi, any update for local or remote search feature ?

mahermeg17 commented 9 years ago

Hi, Following the sort feature, I added a filter to the FileListListAdapter.java like this :

public void filterByName(String keyName) {
mFilteredFiles=new Vector<OCFile>();
for(OCFile f :mFiles){
if(f.getFileName().contains(keyName)){
mFilteredFiles.add(f);
}
}
mFiles=mFilteredFiles;
Log.d("FileListListAdapter", ">>>notifyDataSetChanged");
notifyDataSetChanged();
Log.d("FileListListAdapter", ">>>notifyDataSetChanged.. OK");
}

and into the FileDisplayActivity.java :

@Override
public boolean onOptionsItemSelected(MenuItem item) {
.....
case R.id.action_search: {
SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Read sorting order, default to sort by name ascending
Integer sortOrder = appPreferences.getInt("sortOrder", FileListListAdapter.SORT_NAME);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title");
builder.setMessage("Message");
// Set an EditText view to get user input 
final EditText input = new EditText(this);
builder.setView(input);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString().trim();
filterByName(value);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
builder.show();
break;
}
....
}   

this works and return the filtred list. But at the first sync thread launched after the search, the listview is refreched as it is in the server (not filtred). Shoud I use a new listview result and show in the AlertDialog ? or are there an other easier way ?

mahermeg17 commented 9 years ago

Ok, some news.. I added the result of search into a new listview in the same alertbuilder. I use cloned adpater from the FileListListAdapter and delete unused methodes. still now to open selected file/folder into the main app activity ; FileDisplayActivity or FileActivity !! I am confused on this point, any help plz!

mahermeg17 commented 9 years ago

OK. it's done. It was more simpler than expected:

resultList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
                // TODO Auto-generated method stub
                OCFile f= (OCFile) ((FileListFilterAdapter) resultList.getAdapter()).getItem(position);

                Intent showDetailsIntent = new Intent(FileDisplayActivity.this, FileDisplayActivity.class);
                showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, f);
                showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, mAccount);
                showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(showDetailsIntent);
            }
        });

please clean up the code and ad it to the next release. And here the search method using a recursive algo :

@SuppressLint("DefaultLocale")
public void filterByName(String keyName) {
    mFilteredFiles = new Vector<OCFile>();
    keyName = keyName.toLowerCase().trim();
    deepFilter(keyName, mFiles);
}

@SuppressLint("DefaultLocale")
public void deepFilter(String keyName, Vector<OCFile> level) {
    for (OCFile f : level) {
        if (f.getFileName().toLowerCase().contains(keyName)) {
            mFilteredFiles.add(f);
            Log.i("deepFilter", ">>find >>> " + f.getFileName());
        } else if (f!=null && f.isFolder()) {
            level = mStorageManager.getFolderContent(f);
            if (!level.isEmpty() && level != null) {
                Log.d("FileListListAdapter", ">>>level=" + level.get(0).getFileId());
                deepFilter(keyName, level);
            }
        }
    }
}
mahermeg17 commented 9 years ago

Hi again, I have a little bug when acceding to the file details from my listview containing the results : it's not auto downloaded and opened like the usual main functionality.

mahermeg17 commented 9 years ago

Hi, Now I know it's about this code in my FileListFilterAdapter: FileDownloaderBinder downloaderBinder = mTransferServiceGetter.getFileDownloaderBinder(); FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder(); if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) { localStateView.setImageResource(R.drawable.downloading_file_indicator); localStateView.setVisibility(View.VISIBLE); } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) { localStateView.setImageResource(R.drawable.uploading_file_indicator); localStateView.setVisibility(View.VISIBLE); } else if (file.isDown()) { localStateView.setImageResource(R.drawable.local_file_indicator); localStateView.setVisibility(View.VISIBLE); } else { localStateView.setVisibility(View.INVISIBLE); }

so I change the initialisation of the adapter int the OCFileListFragment mFilterAdapter = new FileListFilterAdapter( getSherlockActivity(), mContainerActivity );

and in the FileDisplayActivity case R.id.action_search: { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Recherche"); final Account mAccount = getAccount(); final FileDataStorageManager mStorageManager = new FileDataStorageManager(mAccount, getContentResolver()); LayoutInflater inflater = this.getLayoutInflater(); View dialogView = inflater.inflate(R.layout.list_search_result, null); builder.setView(dialogView); final EditText input = (EditText) dialogView.findViewById(R.id.search_key); final ListView resultList = (ListView) dialogView.findViewById(R.id.search_result_list); final Button search = (Button) dialogView.findViewById(R.id.search_button); resultList.setAdapter(getmFilterAdapter()); resultList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) { // TODO Auto-generated method stub OCFile f= (OCFile) ((FileListFilterAdapter) resultList.getAdapter()).getItem(position); Intent showDetailsIntent = null; if (PreviewImageFragment.canBePreviewed(f)) { showDetailsIntent = new Intent(FileDisplayActivity.this, PreviewImageActivity.class); } else { showDetailsIntent = new Intent(FileDisplayActivity.this, FileDisplayActivity.class); } showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, f); showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, mAccount); showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); showDetailsIntent.setAction(null); startActivity(showDetailsIntent); } }); search.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { String value = input.getText().toString().trim(); if (!value.isEmpty()) { try { Vector files = getSpacemFiles(); ((FileListFilterAdapter) resultList.getAdapter()).setmAccount(mAccount); ((FileListFilterAdapter) resultList.getAdapter()).setmStorageManager(mStorageManager); ((FileListFilterAdapter) resultList.getAdapter()).setmFiles(files); ((FileListFilterAdapter) resultList.getAdapter()).filterByName(value); ((FileListFilterAdapter) resultList.getAdapter()).notifyDataSetChanged(); } catch (Exception e) { e.printStackTrace(); } } } }); builder.setNegativeButton("Retour", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // Canceled. } }); builder.show(); break; }

but finaly the file is not auto downloaded and shown ...!!?

tobiasKaminsky commented 8 years ago

@DeepDiver1975 Is there a search api in /core? (Sorry, if you are not the right contact person in /core, but you are roughly the only one I know)

DeepDiver1975 commented 8 years ago

@DeepDiver1975 Is there a search api in /core? (Sorry, if you are not the right contact person in /core, but you are roughly the only one I know)

Nothing which is usable by the clients (in terms of public api or ready to be used)

tobiasKaminsky commented 8 years ago

@DeepDiver1975 Thank you for your reply. Is there a related issue in /core, which I can subscribe to? Or should I open one? Then I could also link it to this one.

DeepDiver1975 commented 8 years ago

Is there a related issue in /core, which I can subscribe to? Or should I open one?

I'm not aware of one right away - maybe searching github can reveal something. At least there should be an issue about webdav search by @butonic

butonic commented 8 years ago

There is a research issue where I had a look at hew we could expose our search via webdaf, since there is RFC5323 for it: https://github.com/owncloud/core/pull/12884. See also comment in https://github.com/owncloud/core/issues/12543#issuecomment-67628949

The bottom line is that we should implement a query language that can express RFC5323 DAV:basicsearch parts:

That at least is my personal opinion.

tobiasKaminsky commented 8 years ago

Thank you both for your feedback. Then we will wait until the server part is finished.

whisere commented 8 years ago

When will this search feature be released in the latest Android version, will this be included into the iOS version too?

tobiasKaminsky commented 8 years ago

As the previous devs said, there is no functionality in the server that will allow searching for now. So this will have to wait. The same is true for the iOS app.

whisere commented 8 years ago

Thank you.

tobiasKaminsky commented 8 years ago

As /core needs some time to get the search api, I would like to add the search in the current folder. This could look like https://github.com/owncloud/android/issues/695#issuecomment-61665708. @jancborchardt @davivel is this ok?

jancborchardt commented 8 years ago

Yeah, we can have a filter of the current folder first, and then search of the rest later. Kind of like in the web interface where the current folder is filtered and other results show below.

supportreq commented 8 years ago

@tobiasKaminsky is this in beta?

tobiasKaminsky commented 8 years ago

No... There is no pull request so far. But when there is one, I will include it into beta.

davigonz commented 6 years ago

Some core efforts are needed before:

owncloud/core#13915

harshitbansal05 commented 6 years ago

@davigonz i think we should add the feature to search locally for documents of a certain type example pdf, images, videos and files. Also, is the feature of local search being implemented?

jesmrec commented 6 years ago

this should be a work in different stages, but for the current one we can put the focus on filtering in the current folder using the file name.

@michaelstingl is it worthy to put effort in this issue?

michaelstingl commented 6 years ago

From my understanding, on the device is only a small number of files present. Local search don't really solve a problem.

Folder filtering in big folders with a long list of files might already solve a small problem for some users, and the UI should be reusable for server-based search via API. 👍

jesmrec commented 6 years ago

then, this can be a good start point @harshitbansal05 .

Some tips related:

harshitbansal05 commented 6 years ago

@jesmrec, imo a progress bar can be shown when user performs any search and can be placed on the top of the screen. But I could'nt undertand the third point.. do you mean returning back to the normal list of files? could you please explain? Also the search needs to be done for files in a folder, right?

jesmrec commented 6 years ago

With the third point i mean to set something that clears the text area where the user inputs the filter (An (x) or similar).

Also the search needs to be done for files in a folder, right?

do you mean in the current folder? i meant that searching in the current folder is filtering.

michaelstingl commented 6 years ago

Search API has been implemented on oC server and is planned to be included in oC 10.0.10: https://github.com/owncloud/core/issues/25373#issuecomment-400967608

davigonz commented 5 years ago

Local search merged, to be included in 2.9

davigonz commented 5 years ago

Reopening this, since searching using the API is still pending.

madchap commented 5 years ago

Hi,

Not sure this fits in there, yet it would be great to be able to filter/search on collaborative tags as well.

Thanks.

michaelstingl commented 5 years ago

There's another issue for tags (https://github.com/owncloud/android/issues/1587), but I could also imagine to extend the future search feature with filter/search for collaborative tags.

shashvat-kedia commented 5 years ago

@jesmrec Is this required?

jesmrec commented 5 years ago

The search feature using the core API is required of course, but i would think about the requirements before starting to develop. Let me have a look about what we expect for this.

piotrekzielony commented 2 years ago

any chance to get recursive search within folders?

jesmrec commented 2 years ago

not implemented yet, but in our roadmap.