diff options
author | stefan-niedermann <info@niedermann.it> | 2020-02-10 15:16:43 +0300 |
---|---|---|
committer | stefan-niedermann <info@niedermann.it> | 2020-02-10 15:16:43 +0300 |
commit | cde1fd39e23ae3a3187dc105d8b80eadd0d68565 (patch) | |
tree | d7ef9214d602b28134e8b0ec10b66cbaaa3e61bb | |
parent | 41d867d88d06cdcdbb0128c8f28d0d31828967bc (diff) |
#211 Attachments 📎
Glide Module
4 files changed, 208 insertions, 6 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java index b1ae31989..162e267f0 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java @@ -14,6 +14,9 @@ import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatImageView; import androidx.recyclerview.widget.RecyclerView; +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; + import java.util.List; import butterknife.BindView; @@ -57,12 +60,12 @@ public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.At holder.notSyncedYet.setVisibility(attachment.getStatusEnum() == DBStatus.UP_TO_DATE ? View.GONE : View.VISIBLE); if (attachment.getMimetype().startsWith("image")) { // TODO Glide is currently not yet able to use SSO and fails on authentication -// String uri = account.getUrl() + "/index.php/apps/deck/cards/" + cardRemoteId + "/attachment/" + attachment.getId(); -// Glide.with(context) -// .load(uri) -// .error(R.drawable.ic_image_grey600_24dp) -// .apply(RequestOptions.circleCropTransform()) -// .into(holder.filetype); + String uri = account.getUrl() + "/index.php/apps/deck/cards/" + cardRemoteId + "/attachment/" + attachment.getId(); + Glide.with(context) + .load(uri) + .error(R.drawable.ic_image_grey600_24dp) + .apply(RequestOptions.circleCropTransform()) + .into(holder.filetype); holder.filetype.setImageResource(R.drawable.ic_image_grey600_24dp); } else if (attachment.getMimetype().startsWith("audio")) { holder.filetype.setImageResource(R.drawable.ic_music_note_grey600_24dp); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/util/glide/SingleSignOnLibraryGlideModule.java b/app/src/main/java/it/niedermann/nextcloud/deck/util/glide/SingleSignOnLibraryGlideModule.java new file mode 100644 index 000000000..bea488eef --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/util/glide/SingleSignOnLibraryGlideModule.java @@ -0,0 +1,29 @@ +package it.niedermann.nextcloud.deck.util.glide; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.Registry; +import com.bumptech.glide.annotation.GlideModule; +import com.bumptech.glide.load.model.GlideUrl; +import com.bumptech.glide.module.AppGlideModule; +import com.bumptech.glide.module.LibraryGlideModule; + +import java.io.InputStream; + +/** + * Registers OkHttp related classes via Glide's annotation processor. + * + * <p>For Applications that depend on this library and include an {@link AppGlideModule} and Glide's + * annotation processor, this class will be automatically included. + */ +@GlideModule +public final class SingleSignOnLibraryGlideModule extends LibraryGlideModule { + @Override + public void registerComponents( + @NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) { + registry.replace(GlideUrl.class, InputStream.class, new SingleSignOnUrlLoader.Factory(context)); + } +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/util/glide/SingleSignOnStreamFetcher.java b/app/src/main/java/it/niedermann/nextcloud/deck/util/glide/SingleSignOnStreamFetcher.java new file mode 100644 index 000000000..80a3e5392 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/util/glide/SingleSignOnStreamFetcher.java @@ -0,0 +1,80 @@ +package it.niedermann.nextcloud.deck.util.glide; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Priority; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.data.DataFetcher; +import com.bumptech.glide.load.model.GlideUrl; +import com.nextcloud.android.sso.aidl.NextcloudRequest; +import com.nextcloud.android.sso.api.NextcloudAPI; +import com.nextcloud.android.sso.api.Response; + +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import it.niedermann.nextcloud.deck.DeckLog; + + +/** + * Fetches an {@link InputStream} using the okhttp library. + */ +public class SingleSignOnStreamFetcher implements DataFetcher<InputStream> { + private static final String TAG = SingleSignOnStreamFetcher.class.getCanonicalName(); + + private final NextcloudAPI client; + private final GlideUrl url; + + // Public API. + @SuppressWarnings("WeakerAccess") + public SingleSignOnStreamFetcher(NextcloudAPI client, GlideUrl url) { + this.client = client; + this.url = url; + } + + @Override + public void loadData(@NonNull Priority priority, @NonNull final DataCallback<? super InputStream> callback) { + NextcloudRequest.Builder requestBuilder = new NextcloudRequest.Builder() + .setMethod("GET") + .setUrl(url.toStringUrl()); + Map<String, List<String>> header = new HashMap<>(); + for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) { + header.put(headerEntry.getKey(), Collections.singletonList(headerEntry.getValue())); + } + requestBuilder.setHeader(header); + NextcloudRequest nextcloudRequest = requestBuilder.build(); + DeckLog.log(nextcloudRequest.toString()); + try { + Response response = client.performNetworkRequestV2(nextcloudRequest); + callback.onDataReady(response.getBody()); + } catch (Exception e) { + callback.onLoadFailed(e); + } + + } + + @Override + public void cleanup() { + + } + + @Override + public void cancel() { + + } + + @NonNull + @Override + public Class<InputStream> getDataClass() { + return InputStream.class; + } + + @NonNull + @Override + public DataSource getDataSource() { + return DataSource.REMOTE; + } +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/util/glide/SingleSignOnUrlLoader.java b/app/src/main/java/it/niedermann/nextcloud/deck/util/glide/SingleSignOnUrlLoader.java new file mode 100644 index 000000000..ae1fc4aa7 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/util/glide/SingleSignOnUrlLoader.java @@ -0,0 +1,90 @@ +package it.niedermann.nextcloud.deck.util.glide; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.load.Options; +import com.bumptech.glide.load.model.GlideUrl; +import com.bumptech.glide.load.model.ModelLoader; +import com.bumptech.glide.load.model.ModelLoaderFactory; +import com.bumptech.glide.load.model.MultiModelLoaderFactory; +import com.nextcloud.android.sso.api.NextcloudAPI; +import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; +import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; +import com.nextcloud.android.sso.helper.SingleAccountHelper; + +import java.io.InputStream; + +import it.niedermann.nextcloud.deck.DeckLog; +import it.niedermann.nextcloud.deck.api.GsonConfig; + +/** + * A simple model loader for fetching media over http/https using OkHttp. + */ +public class SingleSignOnUrlLoader implements ModelLoader<GlideUrl, InputStream> { + + private final NextcloudAPI client; + + // Public API. + @SuppressWarnings("WeakerAccess") + public SingleSignOnUrlLoader(@NonNull NextcloudAPI client) { + this.client = client; + } + + @Override + public boolean handles(@NonNull GlideUrl url) { + return true; + } + + @Override + public LoadData<InputStream> buildLoadData( + @NonNull GlideUrl model, int width, int height, @NonNull Options options) { + return new LoadData<>(model, new SingleSignOnStreamFetcher(client, model)); + } + + /** + * The default factory for {@link SingleSignOnUrlLoader}s. + */ + // Public API. + @SuppressWarnings("WeakerAccess") + public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> { + private boolean isConnected = false; + private SingleSignOnUrlLoader loader; + + /** + * Constructor for a new Factory that runs requests using given client. + */ + public Factory(@NonNull Context context) { + try { + loader = new SingleSignOnUrlLoader(new NextcloudAPI(context, SingleAccountHelper.getCurrentSingleSignOnAccount(context), GsonConfig.getGson(), new NextcloudAPI.ApiConnectedListener() { + @Override + public void onConnected() { + isConnected = true; + DeckLog.log("success: init SSO-Api"); + } + + @Override + public void onError(Exception ex) { + DeckLog.logError(ex); + } + })); + } catch (NextcloudFilesAppAccountNotFoundException e) { + e.printStackTrace(); + } catch (NoCurrentAccountSelectedException e) { + e.printStackTrace(); + } + } + + @NonNull + @Override + public ModelLoader<GlideUrl, InputStream> build(MultiModelLoaderFactory multiFactory) { + return loader; + } + + @Override + public void teardown() { + // Do nothing, this instance doesn't own the client. + } + } +} |