Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 35fa9765 authored by alperozturk's avatar alperozturk
Browse files

add share api

parent 1e120483
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import it.niedermann.owncloud.notes.persistence.sync.CapabilitiesDeserializer;
import it.niedermann.owncloud.notes.persistence.sync.FilesAPI;
import it.niedermann.owncloud.notes.persistence.sync.NotesAPI;
import it.niedermann.owncloud.notes.persistence.sync.OcsAPI;
import it.niedermann.owncloud.notes.persistence.sync.ShareAPI;
import it.niedermann.owncloud.notes.shared.model.ApiVersion;
import it.niedermann.owncloud.notes.shared.model.Capabilities;
import retrofit2.NextcloudRetrofitApiBuilder;
@@ -47,12 +48,14 @@ public class ApiProvider {

    private static final String API_ENDPOINT_OCS = "/ocs/v2.php/cloud/";
    private static final String API_ENDPOINT_FILES ="/ocs/v2.php/apps/files/api/v1/";
    private static final String API_ENDPOINT_FILES_SHARING ="/ocs/v2.php/apps/files_sharing/api/v1/";

    private static final Map<String, NextcloudAPI> API_CACHE = new ConcurrentHashMap<>();

    private static final Map<String, OcsAPI> API_CACHE_OCS = new ConcurrentHashMap<>();
    private static final Map<String, NotesAPI> API_CACHE_NOTES = new ConcurrentHashMap<>();
    private static final Map<String, FilesAPI> API_CACHE_FILES = new ConcurrentHashMap<>();
    private static final Map<String, ShareAPI> API_CACHE_FILES_SHARING = new ConcurrentHashMap<>();


    public static ApiProvider getInstance() {
@@ -96,6 +99,15 @@ public class ApiProvider {
        return filesAPI;
    }

    public synchronized ShareAPI getShareAPI(@NonNull Context context, @NonNull SingleSignOnAccount ssoAccount) {
        if (API_CACHE_FILES_SHARING.containsKey(ssoAccount.name)) {
            return API_CACHE_FILES_SHARING.get(ssoAccount.name);
        }
        final var shareAPI = new NextcloudRetrofitApiBuilder(getNextcloudAPI(context, ssoAccount), API_ENDPOINT_FILES_SHARING).create(ShareAPI.class);
        API_CACHE_FILES_SHARING.put(ssoAccount.name, shareAPI);
        return shareAPI;
    }

    private synchronized NextcloudAPI getNextcloudAPI(@NonNull Context context, @NonNull SingleSignOnAccount ssoAccount) {
        if (API_CACHE.containsKey(ssoAccount.name)) {
            return API_CACHE.get(ssoAccount.name);
+131 −0
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.persistence

import android.app.Application
import android.content.Context
import com.nextcloud.android.sso.api.EmptyResponse
import com.nextcloud.android.sso.model.SingleSignOnAccount
import com.owncloud.android.lib.resources.shares.OCShare
import com.owncloud.android.lib.resources.shares.ShareType
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
import it.niedermann.owncloud.notes.persistence.entity.Note
import it.niedermann.owncloud.notes.shared.model.ApiVersion

class ShareRepository private constructor(private val applicationContext: Context) {

    private val apiProvider: ApiProvider by lazy { ApiProvider.getInstance() }
    private val notesRepository: NotesRepository by lazy {
        NotesRepository.getInstance(
            applicationContext,
        )
    }

    private fun getNotesPath(account: SingleSignOnAccount): Single<String> {
        return Single.fromCallable {
            val call = notesRepository.getServerSettings(account, ApiVersion.API_VERSION_1_0)
            val response = call.execute()
            response.body()?.notesPath ?: throw RuntimeException("No notes path available")
        }.subscribeOn(Schedulers.io())
    }

    fun getShares(
        account: SingleSignOnAccount,
        remoteId: Long
    ): Single<List<OCShare>> {
        return Single.fromCallable {
            val shareAPI = apiProvider.getShareAPI(applicationContext, account)
            val call = shareAPI.getShares(remoteId)
            val response = call.execute()
            response.body()?.ocs?.data ?: throw RuntimeException("No shares available")
        }.subscribeOn(Schedulers.io())
    }

    fun getSharesForFile(
        account: SingleSignOnAccount,
        note: Note,
        reshares: Boolean = false,
        subfiles: Boolean = false
    ): Single<List<OCShare>> {
        return getNotesPath(account)
            .flatMap { notesPath ->
                Single.fromCallable {
                    val shareAPI = apiProvider.getShareAPI(applicationContext, account)
                    val call = shareAPI.getSharesForFile(
                        remoteFilePath = notesPath + "/" + note.remoteId,
                        reshares = reshares,
                        subfiles = subfiles
                    )
                    val response = call.execute()
                    response.body()?.ocs?.data ?: throw RuntimeException("No shares available")
                }.subscribeOn(Schedulers.io())
            }
    }

    fun deleteShare(
        account: SingleSignOnAccount,
        remoteShareId: Long
    ): Single<EmptyResponse> {
        return Single.fromCallable {
            val shareAPI = apiProvider.getShareAPI(applicationContext, account)
            val call = shareAPI.deleteShare(remoteShareId)
            val response = call.execute()
            response.body() ?: throw RuntimeException("No shares available")
        }.subscribeOn(Schedulers.io())
    }

    fun updateShare(
        account: SingleSignOnAccount,
        remoteShareId: Long
    ): Single<List<OCShare>> {
        return Single.fromCallable {
            val shareAPI = apiProvider.getShareAPI(applicationContext, account)
            val call = shareAPI.updateShare(remoteShareId)
            val response = call.execute()
            response.body()?.ocs?.data ?: throw RuntimeException("Share update failed")
        }.subscribeOn(Schedulers.io())
    }

    fun addShare(
        account: SingleSignOnAccount,
        note: Note,
        shareType: ShareType,
        shareWith: String,
        publicUpload: Boolean = false,
        password: String = "",
        permissions: Int = 0,
        getShareDetails: Boolean = true,
        shareNote: String = ""
    ): Single<List<OCShare>> {
        return getNotesPath(account)
            .flatMap { notesPath ->
                Single.fromCallable {
                    val shareAPI = apiProvider.getShareAPI(applicationContext, account)
                    val call = shareAPI.addShare(
                        remoteFilePath = notesPath + "/" + note.remoteId,
                        shareType = shareType,
                        shareWith = shareWith,
                        publicUpload = publicUpload,
                        password = password,
                        permissions = permissions,
                        getShareDetails = getShareDetails,
                        note = shareNote
                    )
                    val response = call.execute()
                    response.body()?.ocs?.data ?: throw RuntimeException("Share creation failed")
                }.subscribeOn(Schedulers.io())
            }
    }

    companion object {
        private var instance: ShareRepository? = null

        @JvmStatic
        fun getInstance(applicationContext: Context): ShareRepository {
            require(applicationContext is Application)
            if (instance == null) {
                instance = ShareRepository(applicationContext)
            }
            return instance!!
        }
    }
}
+41 −0
Original line number Diff line number Diff line
package it.niedermann.owncloud.notes.persistence.sync

import com.nextcloud.android.sso.api.EmptyResponse
import com.owncloud.android.lib.resources.shares.OCShare
import com.owncloud.android.lib.resources.shares.ShareType
import it.niedermann.owncloud.notes.shared.model.OcsResponse
import retrofit2.Call
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.PATCH
import retrofit2.http.POST

interface ShareAPI {
    @GET("shares")
    fun getShares(remoteId: Long): Call<OcsResponse<List<OCShare>>>

    @GET("shares")
    fun getSharesForFile(
        remoteFilePath: String,
        reshares: Boolean,
        subfiles: Boolean
    ): Call<OcsResponse<MutableList<OCShare>>>

    @DELETE("shares")
    fun deleteShare(remoteShareId: Long): Call<EmptyResponse>

    @PATCH("shares")
    fun updateShare(remoteShareId: Long): Call<OcsResponse<List<OCShare>>>

    @POST("shares")
    fun addShare(
        remoteFilePath: String,
        shareType: ShareType,
        shareWith: String,
        publicUpload: Boolean,
        password: String,
        permissions: Int,
        getShareDetails: Boolean,
        note: String
    ): Call<OcsResponse<List<OCShare>>>
}
+17 −10
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment;
@@ -54,6 +53,7 @@ import it.niedermann.owncloud.notes.share.dialog.FileDetailSharingMenuBottomShee
import it.niedermann.owncloud.notes.share.dialog.QuickSharingPermissionsBottomSheetDialog;
import it.niedermann.owncloud.notes.share.dialog.ShareLinkToDialog;
import it.niedermann.owncloud.notes.share.dialog.SharePasswordDialogFragment;
import it.niedermann.owncloud.notes.share.helper.UsersAndGroupsSearchProvider;
import it.niedermann.owncloud.notes.share.listener.FileDetailsSharingMenuBottomSheetActions;
import it.niedermann.owncloud.notes.share.listener.ShareeListAdapterListener;
import it.niedermann.owncloud.notes.share.model.UsersAndGroupsSearchConfig;
@@ -124,12 +124,14 @@ public class NoteShareActivity extends BrandedActivity implements ShareeListAdap

        // OCFile parentFile = fileDataStorageManager.getFileById(file.getParentId());

        setupSearchView((SearchManager) getSystemService(Context.SEARCH_SERVICE), binding.searchView, getComponentName());
        setupSearchView((SearchManager) getSystemService(Context.SEARCH_SERVICE), getComponentName());

        binding.searchView.setQueryHint(getResources().getString(R.string.note_share_fragment_resharing_not_allowed));
        binding.searchView.setInputType(InputType.TYPE_NULL);
        binding.pickContactEmailBtn.setVisibility(View.GONE);
        disableSearchView(binding.searchView);

        // TODO: When to disable?
        // binding.pickContactEmailBtn.setVisibility(View.GONE);
        // disableSearchView(binding.searchView);

        /*
        if (file.canReshare()) {
@@ -144,31 +146,36 @@ public class NoteShareActivity extends BrandedActivity implements ShareeListAdap

    }

    private void setupSearchView(@Nullable SearchManager searchManager, SearchView searchView,
    private void setupSearchView(@Nullable SearchManager searchManager,
                                       ComponentName componentName) {
        if (searchManager == null) {
            searchView.setVisibility(View.GONE);
            binding.searchView.setVisibility(View.GONE);
            return;
        }

        // assumes parent activity is the searchable activity
        searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName));
        binding.searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName));

        // do not iconify the widget; expand it by default
        searchView.setIconifiedByDefault(false);
        binding.searchView.setIconifiedByDefault(false);

        // avoid fullscreen with softkeyboard
        searchView.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
        binding.searchView.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        UsersAndGroupsSearchProvider provider = new UsersAndGroupsSearchProvider(account, clientFactory.create());

        binding.searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {

                // return true to prevent the query from being processed;
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                Log_OC.e(NoteShareActivity.class.getSimpleName(), "Failed to pick email address as Cursor is null." + newText);

                // leave it for the parent listener in the hierarchy / default behaviour
                return false;
            }
+433 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading