diff --git a/android/src/main/java/com/wix/RNCameraKit/GalleryAdapter.java b/android/src/main/java/com/wix/RNCameraKit/GalleryAdapter.java new file mode 100644 index 0000000..57131b0 --- /dev/null +++ b/android/src/main/java/com/wix/RNCameraKit/GalleryAdapter.java @@ -0,0 +1,100 @@ +package com.wix.RNCameraKit; + +import android.content.Context; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.provider.MediaStore; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import java.util.ArrayList; + +/** + * Created by yedidyak on 30/06/2016. + */ +public class GalleryAdapter extends RecyclerView.Adapter { + + + public static final String[] PROJECTION = new String[]{ + MediaStore.Images.Media.DATA + }; + + private ArrayList images = new ArrayList<>(); + + public class StupidHolder extends RecyclerView.ViewHolder { + public StupidHolder(View itemView) { + super(itemView); + } + } + + private Context context; + + public GalleryAdapter(Context context) { + this.context = context; + } + + public void setAlbum(String albumName) { + images.clear(); + + String selection = null; + if(albumName != null || !albumName.equals("All Photos")) { + selection = MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " = ?"; + } + + Cursor cursor = context.getContentResolver().query( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + PROJECTION, + selection, + new String[]{albumName}, + null + ); + + if (cursor.moveToFirst()) { + int dataIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA); + do { + images.add(cursor.getString(dataIndex)); + } while(cursor.moveToNext()); + } + + cursor.close(); + } + + @Override + public StupidHolder onCreateViewHolder(ViewGroup parent, int viewType) { + ImageView v = new ImageView(context) { + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, widthMeasureSpec); + } + }; + v.setScaleType(ImageView.ScaleType.CENTER_CROP); + return new StupidHolder(v); + } + + @Override + public void onBindViewHolder(final StupidHolder holder, final int position) { + + new AsyncTask() { + @Override + protected Bitmap doInBackground(Void... params) { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inSampleSize = 2; + return BitmapFactory.decodeFile(images.get(position), options); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + ((ImageView)holder.itemView).setImageBitmap(bitmap); + } + }.execute(); + } + + @Override + public int getItemCount() { + return images.size(); + } +} diff --git a/android/src/main/java/com/wix/RNCameraKit/GalleryView.java b/android/src/main/java/com/wix/RNCameraKit/GalleryView.java new file mode 100644 index 0000000..4f74a2d --- /dev/null +++ b/android/src/main/java/com/wix/RNCameraKit/GalleryView.java @@ -0,0 +1,61 @@ +package com.wix.RNCameraKit; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.Rect; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.Toast; + +/** + * Created by yedidyak on 30/06/2016. + */ +public class GalleryView extends RecyclerView { + + private String albumName; + private GalleryAdapter adapter; + private int itemSpacing; + private int lineSpacing; + + public GalleryView(Context context) { + super(context); + setHasFixedSize(true); + GridLayoutManager layoutManager = new GridLayoutManager(context, 3); + layoutManager.setOrientation(GridLayoutManager.VERTICAL); + setLayoutManager(layoutManager); + adapter = new GalleryAdapter(context); + setAdapter(adapter); + } + + private void updateDecorator() { + addItemDecoration(new ItemDecoration() { + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) { + outRect.top = lineSpacing; + outRect.left = itemSpacing; + outRect.right = itemSpacing; + outRect.bottom = lineSpacing; + } + }); + } + + public void setAlbumName(String albumName) { + this.albumName = albumName; + Toast.makeText(this.getContext(), albumName, Toast.LENGTH_SHORT).show(); + + adapter.setAlbum(albumName); + } + + public void setItemSpacing(int itemSpacing) { + this.itemSpacing = itemSpacing; + updateDecorator(); + } + + public void setLineSpacing(int lineSpacing) { + this.lineSpacing = lineSpacing; + updateDecorator(); + } +} diff --git a/android/src/main/java/com/wix/RNCameraKit/GalleryViewManager.java b/android/src/main/java/com/wix/RNCameraKit/GalleryViewManager.java new file mode 100644 index 0000000..c66d7dd --- /dev/null +++ b/android/src/main/java/com/wix/RNCameraKit/GalleryViewManager.java @@ -0,0 +1,39 @@ +package com.wix.RNCameraKit; + +import com.facebook.react.uimanager.SimpleViewManager; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.annotations.ReactProp; + +/** + * Created by yedidyak on 30/06/2016. + */ +public class GalleryViewManager extends SimpleViewManager { + + @Override + public String getName() { + return "GalleryView"; + } + + @Override + protected GalleryView createViewInstance(ThemedReactContext reactContext) { + return new GalleryView(reactContext.getBaseContext()); + } + + @ReactProp(name = "albumName") + public void setAlbumName(GalleryView view, String albumName) { + view.setAlbumName(albumName); + } + + + + @ReactProp(name = "minimumInteritemSpacing") + public void setItemSpacing(GalleryView view, int itemSpacing) { + view.setItemSpacing(itemSpacing/2); + } + + @ReactProp(name = "minimumLineSpacing") + public void setLineSpacing(GalleryView view, int lineSpacing) { + view.setLineSpacing(lineSpacing/2); + } + +} diff --git a/android/src/main/java/com/wix/RNCameraKit/NativeGalleryManager.java b/android/src/main/java/com/wix/RNCameraKit/NativeGalleryModule.java similarity index 59% rename from android/src/main/java/com/wix/RNCameraKit/NativeGalleryManager.java rename to android/src/main/java/com/wix/RNCameraKit/NativeGalleryModule.java index d062f13..207a977 100644 --- a/android/src/main/java/com/wix/RNCameraKit/NativeGalleryManager.java +++ b/android/src/main/java/com/wix/RNCameraKit/NativeGalleryModule.java @@ -2,9 +2,8 @@ package com.wix.RNCameraKit; import android.database.Cursor; import android.graphics.Bitmap; -import android.net.Uri; import android.provider.MediaStore; -import android.util.Base64; +import android.support.annotation.NonNull; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Promise; @@ -14,14 +13,18 @@ import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; -import java.io.ByteArrayOutputStream; import java.util.Collection; import java.util.HashMap; /** * Created by yedidyak on 29/06/2016. */ -public class NativeGalleryManager extends ReactContextBaseJavaModule { +public class NativeGalleryModule extends ReactContextBaseJavaModule { + + public static final String[] ALBUMS_PROJECTION = new String[]{ + MediaStore.Images.Media._ID, + MediaStore.Images.Media.BUCKET_DISPLAY_NAME + }; private class Album { String name; @@ -46,13 +49,7 @@ public class NativeGalleryManager extends ReactContextBaseJavaModule { } public void setThumbnail(String name, Bitmap thumbnail) { - - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); - byte[] byteArray = byteArrayOutputStream .toByteArray(); - String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT); - - albums.get(name).imageData = encoded; + albums.get(name).imageData = Utils.getBase64FromBitmap(thumbnail); } public boolean hasThumbnail(String name) { @@ -64,27 +61,26 @@ public class NativeGalleryManager extends ReactContextBaseJavaModule { } } - public NativeGalleryManager(ReactApplicationContext reactContext) { + public NativeGalleryModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { - return "NativeGalleryManager"; + return "NativeGalleryModule"; } - @ReactMethod - public void getAlbumsWithThumbnails(Promise promise) { - - String[] projection = new String[]{ - MediaStore.Images.Media._ID, - MediaStore.Images.Media.BUCKET_DISPLAY_NAME, - MediaStore.Images.Media._ID - }; - - Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; - Cursor imagesCursor = getCurrentActivity().getContentResolver().query(images, projection, null, null, null); + @NonNull + private WritableMap albumToMap(Album album) { + WritableMap map = Arguments.createMap(); + map.putInt("imagesCount", album.count); + map.putString("albumName", album.name); + map.putString("image", album.imageData); + return map; + } + @NonNull + private AlbumList getAlbumListFromCursor(Cursor imagesCursor) { AlbumList albums = new AlbumList(); if (imagesCursor.moveToFirst()) { @@ -93,27 +89,32 @@ public class NativeGalleryManager extends ReactContextBaseJavaModule { do { String name = imagesCursor.getString(bucketColumn); albums.addAlbum(name); - if(!albums.hasThumbnail(name)) { - int thumbId = imagesCursor.getInt(thumbIdColumn); - Bitmap thumb = MediaStore.Images.Thumbnails.getThumbnail( - getCurrentActivity().getContentResolver(), - thumbId, - MediaStore.Images.Thumbnails.MINI_KIND, - null); - albums.setThumbnail(name, thumb); + albums.setThumbnail(name, getThumbnail(imagesCursor.getInt(thumbIdColumn))); } } while (imagesCursor.moveToNext()); } + return albums; + } + private Bitmap getThumbnail(int thumbId) { + return MediaStore.Images.Thumbnails.getThumbnail( + getCurrentActivity().getContentResolver(), + thumbId, + MediaStore.Images.Thumbnails.MINI_KIND, + null); + } + + @ReactMethod + public void getAlbumsWithThumbnails(Promise promise) { + + Cursor imagesCursor = getCurrentActivity().getContentResolver().query( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ALBUMS_PROJECTION, null, null, null); + AlbumList albums = getAlbumListFromCursor(imagesCursor); WritableArray arr = Arguments.createArray(); for (Album album : albums.getAlbums()) { - WritableMap map = Arguments.createMap(); - map.putInt("imagesCount", album.count); - map.putString("albumName", album.name); - map.putString("image", album.imageData); - arr.pushMap(map); + arr.pushMap(albumToMap(album)); } WritableMap ret = Arguments.createMap(); @@ -121,9 +122,4 @@ public class NativeGalleryManager extends ReactContextBaseJavaModule { promise.resolve(ret); } - - @ReactMethod - public void getPhotosForAlbum(String albumName, int numberOfPhotos, Promise promise) { - - } } diff --git a/android/src/main/java/com/wix/RNCameraKit/RNCameraKitPackage.java b/android/src/main/java/com/wix/RNCameraKit/RNCameraKitPackage.java index 1786d2e..59a1e6c 100644 --- a/android/src/main/java/com/wix/RNCameraKit/RNCameraKitPackage.java +++ b/android/src/main/java/com/wix/RNCameraKit/RNCameraKitPackage.java @@ -14,19 +14,21 @@ public class RNCameraKitPackage implements ReactPackage { @Override public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new NativeGalleryManager(reactContext)); - return modules; + List modules = new ArrayList<>(); + modules.add(new NativeGalleryModule(reactContext)); + return modules; } @Override public List> createJSModules() { - return Collections.emptyList(); + return Collections.emptyList(); } @Override public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); + List viewManagers = new ArrayList<>(); + viewManagers.add(new GalleryViewManager()); + return viewManagers; } } \ No newline at end of file diff --git a/android/src/main/java/com/wix/RNCameraKit/Utils.java b/android/src/main/java/com/wix/RNCameraKit/Utils.java new file mode 100644 index 0000000..d24b97d --- /dev/null +++ b/android/src/main/java/com/wix/RNCameraKit/Utils.java @@ -0,0 +1,21 @@ +package com.wix.RNCameraKit; + +import android.graphics.Bitmap; +import android.util.Base64; + +import java.io.ByteArrayOutputStream; + +/** + * Created by yedidyak on 30/06/2016. + */ +public class Utils { + + public static String getBase64FromBitmap(Bitmap bitmap) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); + byte[] byteArray = byteArrayOutputStream .toByteArray(); + return Base64.encodeToString(byteArray, Base64.DEFAULT); + } +} + + diff --git a/index.android.js b/index.android.js index 4d2fdd0..ad11f39 100644 --- a/index.android.js +++ b/index.android.js @@ -1,11 +1,11 @@ import CameraKitGallery from './src/CameraKitGallery'; //import CameraKitCamera from './src/CameraKitCamera'; -//import CameraKitGalleryView from './src/CameraKitGalleryView'; +import CameraKitGalleryView from './src/CameraKitGalleryView'; export { CameraKitGallery, //CameraKitCamera, - //CameraKitGalleryView + CameraKitGalleryView }; diff --git a/src/CameraKitGallery.android.js b/src/CameraKitGallery.android.js index d891143..185986a 100644 --- a/src/CameraKitGallery.android.js +++ b/src/CameraKitGallery.android.js @@ -1,9 +1,9 @@ import {NativeModules} from 'react-native'; -const NativeGalleryManager = NativeModules.NativeGalleryManager; +const NativeGalleryModule = NativeModules.NativeGalleryModule; import _ from 'lodash'; async function getAlbumsWithThumbnails() { - const albums = await NativeGalleryManager.getAlbumsWithThumbnails(); + const albums = await NativeGalleryModule.getAlbumsWithThumbnails(); return albums; } diff --git a/src/CameraKitGalleryView.android.js b/src/CameraKitGalleryView.android.js new file mode 100644 index 0000000..c002d8f --- /dev/null +++ b/src/CameraKitGalleryView.android.js @@ -0,0 +1,27 @@ +import React, {Component} from 'react'; +import { + requireNativeComponent, + //NativeModules +} from 'react-native'; + +const GalleryView = requireNativeComponent('GalleryView', null); +//const GalleryViewManager = NativeModules.GalleryViewManager; +const ALL_PHOTOS = 'All Photos'; + +export default class CameraKitGalleryView extends Component { + + render() { + const transformedProps = {...this.props}; + transformedProps.albumName = this.props.albumName ? this.props.albumName : ALL_PHOTOS; + + return + } + + //async getSelectedImages() { + // + // const selectedImages = await GalleryViewManager.getSelectedImages(); + // return selectedImages; + //} + + +}