diff --git a/Test Results - MainActivityTest.html b/Test Results - MainActivityTest.html new file mode 100644 index 0000000..2fc5a54 --- /dev/null +++ b/Test Results - MainActivityTest.html @@ -0,0 +1,687 @@ + + + + +Test Results — MainActivityTest + + + + + + + + + +
+ +
+ +
+
+ + + diff --git a/Test Results - Tests_in_'pl_edu_amu_wmi_socialaggregator'.html b/Test Results - Tests_in_'pl_edu_amu_wmi_socialaggregator'.html new file mode 100644 index 0000000..bbfa19d --- /dev/null +++ b/Test Results - Tests_in_'pl_edu_amu_wmi_socialaggregator'.html @@ -0,0 +1,1010 @@ + + + + +Test Results — Tests in 'pl.edu.amu.wmi.socialaggregator' + + + + + + + + + +
+ +
+ +
+
+ + + diff --git a/app/build.gradle b/app/build.gradle index eb976f4..558768f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,4 +76,9 @@ dependencies { implementation 'com.facebook.android:facebook-share:[5,6)' implementation 'com.squareup.picasso:picasso:2.5.2' + + implementation([ + 'com.snapchat.kit.sdk:creative:1.1.4', + 'com.snapchat.kit.sdk:core:1.1.4' + ]) } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 53b7386..07a5330 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ + + + + + + + + + + + + diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/activity/MainActivity.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/activity/MainActivity.kt index 29e4680..838e856 100644 --- a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/activity/MainActivity.kt +++ b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/activity/MainActivity.kt @@ -2,24 +2,16 @@ package pl.edu.amu.wmi.socialaggregator.activity import android.content.Intent import android.os.Bundle -import android.util.Log import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager -import com.facebook.CallbackManager -import com.facebook.FacebookCallback -import com.facebook.FacebookException -import com.facebook.login.LoginResult import com.jakewharton.rxbinding2.view.RxView +import io.reactivex.Observable import io.reactivex.disposables.CompositeDisposable import kotlinx.android.synthetic.main.activity_main.* import pl.edu.amu.wmi.socialaggregator.R import pl.edu.amu.wmi.socialaggregator.utils.SocialPlatformsManager import pl.edu.amu.wmi.socialaggregator.viewholders.PostSummaryRecycler import pl.edu.amu.wmi.socialaggregator.viewholders.SocialWithButtonRecycler -import com.facebook.AccessToken -import com.facebook.login.LoginManager -import com.facebook.share.widget.ShareDialog -import io.reactivex.Observable class MainActivity : AppCompatActivity() { @@ -38,30 +30,6 @@ class MainActivity : AppCompatActivity() { val intent = Intent(this, NewPostActivity::class.java) startActivity(intent) }, -// RxView.clicks(connectedSocialsButton) -// .subscribe { -// val accessToken = AccessToken.getCurrentAccessToken() -// val isLoggedIn = accessToken != null && !accessToken.isExpired -// -// Log.i(TAG, isLoggedIn.toString()) -// -// LoginManager.getInstance().logInWithReadPermissions(this, listOf("public_profile")) -// -//// val request = GraphRequest.newMeRequest( -//// accessToken -//// ) { `object`, response -> -//// Log.v("LoginActivity", response.toString()) -//// -//// // Application code -//// } -//// val parameters = Bundle() -//// parameters.putString("fields", "id,name,email,gender,birthday") -//// request.parameters = parameters -//// request.executeAsync() -// ShareDialog(this).show() -//// val intent = Intent(this, AddSocialActivity::class.java) -//// startActivity(intent) -// }, RxView.clicks(previousPostsButton) .subscribe { val intent = Intent(this, PostHistoryActivity::class.java) @@ -72,7 +40,7 @@ class MainActivity : AppCompatActivity() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { SocialPlatformsManager.getAll() - .forEach { it.onActivityResult(requestCode, resultCode, data)} + .forEach { it.onActivityResult(requestCode, resultCode, data) } super.onActivityResult(requestCode, resultCode, data) } @@ -88,12 +56,13 @@ class MainActivity : AppCompatActivity() { previousPostsRecyclerView.apply { layoutManager = LinearLayoutManager(this@MainActivity) adapter = PostSummaryRecycler( - Observable.fromIterable(SocialPlatformsManager.getLoggedIn(this@MainActivity)) - .flatMap { social -> - return@flatMap social.getPosts(this@MainActivity) - .map { social to it } - .toObservable() - }) + Observable.merge(SocialPlatformsManager.getLoggedIn(this@MainActivity) + .map { social -> + social.getPosts(this@MainActivity) + .map { social to it } + .toObservable() + }) + ) } } diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/activity/NewPostActivity.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/activity/NewPostActivity.kt index a32fd3c..c5c85ca 100644 --- a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/activity/NewPostActivity.kt +++ b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/activity/NewPostActivity.kt @@ -2,12 +2,13 @@ package pl.edu.amu.wmi.socialaggregator.activity import android.Manifest import android.annotation.SuppressLint +import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.graphics.BitmapFactory +import android.net.Uri import android.os.Bundle import android.provider.MediaStore -import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat @@ -15,16 +16,25 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar import com.jakewharton.rxbinding2.view.RxView import io.reactivex.Observable +import io.reactivex.functions.BiFunction +import io.reactivex.schedulers.Schedulers +import io.reactivex.subjects.PublishSubject import kotlinx.android.synthetic.main.activity_new_post.* import kotlinx.android.synthetic.main.content_new_post.* import pl.edu.amu.wmi.socialaggregator.R +import pl.edu.amu.wmi.socialaggregator.socialplatforms.SocialPlatform import pl.edu.amu.wmi.socialaggregator.utils.SocialPlatformsManager import pl.edu.amu.wmi.socialaggregator.viewholders.SocialWithToggleRecycler + class NewPostActivity : AppCompatActivity() { var file: String? = null + val postedSubject = PublishSubject.create() + + val resumedSubject = PublishSubject.create() + @SuppressLint("CheckResult") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -47,16 +57,48 @@ class NewPostActivity : AppCompatActivity() { RxView.clicks(publishPost) .filter { file != null } - .subscribe { - availablesRecycler.chips.entries - .filter { (_, chip) -> chip.isChecked } - .forEach { (social, _) -> + .doOnNext { + val sdk = android.os.Build.VERSION.SDK_INT + if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) { + val clipboard = + getSystemService(Context.CLIPBOARD_SERVICE) as android.text.ClipboardManager + clipboard.text = postText.text?.toString() ?: "" + } else { + val clipboard = + getSystemService(Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager + val clip = android.content.ClipData.newPlainText( + "text label", + postText.text?.toString() ?: "" + ) + clipboard.primaryClip = clip + } + } + .observeOn(Schedulers.io()) + .doOnNext { + resumedSubject.zipWith( + Observable.fromIterable(availablesRecycler.chips.entries + .filter { (_, chip) -> chip.isChecked } + .map { it.key }), + BiFunction { _, t2 -> t2 } + ) + .doOnNext { val bitmap = BitmapFactory.decodeFile(file!!) - social.addPost(this, postText.text?.toString() ?: "test", listOf(bitmap)) - .blockingSubscribe() - Toast.makeText(this, "Posted to ${social.getName()}!", Toast.LENGTH_SHORT) - .show() + it.addPost( + postedSubject, this, + postText.text?.toString() ?: "", + listOf(bitmap), + listOf(file!!) + ) } + .take(availablesRecycler.chips.count { it.value.isChecked }.toLong()) + .toList() + .subscribe { _ -> + finish() + } + + } + .subscribe { + resumedSubject.onNext(Any()) } RxView.clicks(imageView2) @@ -86,18 +128,33 @@ class NewPostActivity : AppCompatActivity() { } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + SocialPlatformsManager.getAll() + .forEach { it.onActivityResult(requestCode, resultCode, data) } super.onActivityResult(requestCode, resultCode, data) if (requestCode == PICK_IMAGE_REQUEST_CODE) { data?.data?.let { uri -> - uri.pathSegments?.last()?.let { - file = it - } + file = getPath(uri) imageView2.setImageURI(uri) + } } } + fun getPath(uri: Uri): String? { + val projection = arrayOf(MediaStore.Images.Media.DATA) + val cursor = contentResolver.query(uri, projection, null, null, null) ?: return null + val column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) + cursor.moveToFirst() + val s = cursor.getString(column_index) + cursor.close() + return s + } + + override fun onResume() { + super.onResume() + resumedSubject.onNext(Any()) + } private fun canAccessGallery() = (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/Facebook.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/Facebook.kt index 3683861..d1f4b64 100644 --- a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/Facebook.kt +++ b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/Facebook.kt @@ -4,7 +4,6 @@ import android.app.Activity import android.content.Context import android.content.Intent import android.graphics.Bitmap -import android.icu.text.SimpleDateFormat import android.os.Bundle import android.util.Log import android.view.View @@ -12,11 +11,9 @@ import android.view.ViewGroup import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import com.facebook.* +import com.facebook.login.LoginManager import com.facebook.login.LoginResult import com.facebook.login.widget.LoginButton -import pl.edu.amu.wmi.socialaggregator.utils.Utils -import pl.edu.amu.wmi.socialaggregator.viewholders.SocialWithButtonRecycler -import com.facebook.login.LoginManager import com.facebook.share.Sharer import com.facebook.share.model.ShareMediaContent import com.facebook.share.model.SharePhoto @@ -28,7 +25,8 @@ import io.reactivex.subjects.PublishSubject import org.json.JSONArray import org.json.JSONObject import pl.edu.amu.wmi.socialaggregator.R -import java.lang.Exception +import pl.edu.amu.wmi.socialaggregator.utils.Utils +import pl.edu.amu.wmi.socialaggregator.viewholders.SocialWithButtonRecycler class Facebook : SocialPlatform { @@ -52,15 +50,21 @@ class Facebook : SocialPlatform { return accessToken != null && !accessToken.isExpired } - override fun addPost(context: Context, text: String, images: List) : PublishSubject { + override fun addPost( + publishSubject: PublishSubject, + context: Context, + text: String, + images: List, + imagePaths: List + ) { val content = ShareMediaContent.Builder().apply { - images.forEach {addMedium( - SharePhoto.Builder().setBitmap(it).build() - )} + images.forEach { + addMedium( + SharePhoto.Builder().setBitmap(it).build() + ) + } }.build() - val publishSubject = PublishSubject.create() - val shareDialog = ShareDialog(context as Activity) shareDialog.registerCallback(callbackManager, object : FacebookCallback { override fun onSuccess(result: Sharer.Result?) { @@ -68,7 +72,7 @@ class Facebook : SocialPlatform { } override fun onCancel() { - publishSubject.onError(Exception("Cancelled")) + publishSubject.onNext(Any()) } override fun onError(error: FacebookException?) { @@ -76,23 +80,26 @@ class Facebook : SocialPlatform { } }) shareDialog.show(content, ShareDialog.Mode.AUTOMATIC) - - return publishSubject } override fun getPosts(context: Context): Single> { return Single.just(AccessToken.getCurrentAccessToken()) + .observeOn(Schedulers.io()) .map { token -> if (token.isExpired) { return@map emptyList() } else { val request = GraphRequest.newGraphPathRequest( AccessToken.getCurrentAccessToken(), - "/me/posts") { + "/me/posts" + ) { Log.i(getName(), it.toString()) } val parameters = Bundle() - parameters.putString("fields", "likes.summary(true),created_time,message,attachments{url,unshimmed_url,media,subattachments}") + parameters.putString( + "fields", + "likes.summary(true),created_time,message,attachments{url,unshimmed_url,media,subattachments}" + ) request.parameters = parameters val res = request.executeAndWait() @@ -100,14 +107,14 @@ class Facebook : SocialPlatform { val size = data.length() return@map (0 until size).map { val obj = data[it] as JSONObject - val msg = if(obj.has("message")) obj.getString("message") else "" - val date = if(obj.has("created_time")) obj.getString("created_time") else "" + val msg = if (obj.has("message")) obj.getString("message") else "" + val date = + if (obj.has("created_time")) obj.getString("created_time") else "" // SimpleDateFormat("YYYY-MM-DD\'T\'hh:mm:ssZ").parse(date) Post(this, msg, date, getImages(obj)) } } } - .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) } @@ -122,12 +129,15 @@ class Facebook : SocialPlatform { .flatMap { val urls = mutableListOf() if (it.has("media")) { - urls.add(it.getJSONObject("media") - .getJSONObject("image") - .getString("src")) + urls.add( + it.getJSONObject("media") + .getJSONObject("image") + .getString("src") + ) } if (it.has("subattachments")) { - val subattachments = it.getJSONObject("subattachments").getJSONArray("data") + val subattachments = + it.getJSONObject("subattachments").getJSONArray("data") urls.addAll((0 until subattachments.length()) .map { subattachments[it] as JSONObject } .map { @@ -158,21 +168,35 @@ class Facebook : SocialPlatform { parent.addView(button) constraintSet.clone(parent as ConstraintLayout) - constraintSet.connect(button.id, ConstraintSet.TOP, - parent.id, ConstraintSet.TOP, 8.toPx(context)) - constraintSet.connect(button.id, ConstraintSet.END, - parent.id, ConstraintSet.END) - constraintSet.connect(button.id, ConstraintSet.BOTTOM, - parent.id, ConstraintSet.BOTTOM, 8.toPx(context)) + constraintSet.connect( + button.id, ConstraintSet.TOP, + parent.id, ConstraintSet.TOP, 8.toPx(context) + ) + constraintSet.connect( + button.id, ConstraintSet.END, + parent.id, ConstraintSet.END + ) + constraintSet.connect( + button.id, ConstraintSet.BOTTOM, + parent.id, ConstraintSet.BOTTOM, 8.toPx(context) + ) - constraintSet.connect(viewHolder.textView.id, ConstraintSet.BOTTOM, - button.id, ConstraintSet.BOTTOM) - constraintSet.connect(viewHolder.textView.id, ConstraintSet.END, - button.id, ConstraintSet.START, 8.toPx(context)) - constraintSet.connect(viewHolder.textView.id, ConstraintSet.START, - parent.id, ConstraintSet.START) - constraintSet.connect(viewHolder.textView.id, ConstraintSet.TOP, - button.id, ConstraintSet.TOP) + constraintSet.connect( + viewHolder.textView.id, ConstraintSet.BOTTOM, + button.id, ConstraintSet.BOTTOM + ) + constraintSet.connect( + viewHolder.textView.id, ConstraintSet.END, + button.id, ConstraintSet.START, 8.toPx(context) + ) + constraintSet.connect( + viewHolder.textView.id, ConstraintSet.START, + parent.id, ConstraintSet.START + ) + constraintSet.connect( + viewHolder.textView.id, ConstraintSet.TOP, + button.id, ConstraintSet.TOP + ) constraintSet.setHorizontalBias(viewHolder.textView.id, 0.toFloat()) constraintSet.applyTo(parent) @@ -180,8 +204,10 @@ class Facebook : SocialPlatform { val callback = object : FacebookCallback { override fun onSuccess(result: LoginResult?) { Log.i(getName(), "SUCCESS!") - LoginManager.getInstance().logInWithReadPermissions(context as Activity, - listOf("email")) + LoginManager.getInstance().logInWithReadPermissions( + context as Activity, + listOf("email") + ) } override fun onCancel() { diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/FacebookMock.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/FacebookMock.kt deleted file mode 100644 index 6988a1c..0000000 --- a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/FacebookMock.kt +++ /dev/null @@ -1,84 +0,0 @@ -package pl.edu.amu.wmi.socialaggregator.socialplatforms - -import android.content.Context -import android.graphics.Bitmap -import android.util.Log -import io.reactivex.Single -import io.reactivex.subjects.PublishSubject -import pl.edu.amu.wmi.socialaggregator.R -import pl.edu.amu.wmi.socialaggregator.utils.InternalStorage -import java.io.ByteArrayOutputStream -import java.io.File -import java.text.DateFormat -import java.util.* - -abstract class FacebookMock : SocialPlatform { - - companion object { - val TAG = FacebookMock::class.java.canonicalName - } - - override fun getName(): String = "Facebook Mock" - - override fun getLogo(): Int = R.mipmap.ic_logo_facebook - - override fun login(context: Context) { - val loginsDir = InternalStorage.getFileOrDir(context, "logins") - loginsDir?.mkdir() - if (loginsDir != null) { - val loginFile = File(loginsDir, "facebook") - loginFile.createNewFile() - } else { - Log.e(TAG, "Could not create logins directory") - } - } - - override fun logout(context: Context) { - InternalStorage.getFileOrDir(context, "logins/facebook")?.delete() - } - - override fun isLoggedIn(context: Context): Boolean { - return InternalStorage.getFileOrDir(context, "logins/facebook")?.exists() ?: false - } - - override fun addPost(context: Context, text: String, images: List): PublishSubject { - val postsDir = InternalStorage.getFileOrDir(context, "posts/facebook") - if (postsDir != null) { - val postDir = File(postsDir, System.currentTimeMillis().toString()) - postDir.mkdirs() - - val textFile = File(postDir, "content") - textFile.createNewFile() - textFile.writeText(text) - - images.forEachIndexed { index, image -> - val imageFile = File(postDir, "image$index") - imageFile.createNewFile() - - ByteArrayOutputStream().use { stream -> - image.compress(Bitmap.CompressFormat.JPEG, 100, stream) - imageFile.writeBytes(stream.toByteArray()) - } - } - - } else { - Log.e(TAG, "Could not create posts directory") - } - return PublishSubject.create() - } - - override fun getPosts(context: Context): Single> { - val postsDir = InternalStorage.getFileOrDir(context, "posts/facebook") - return Single.just(postsDir?.listFiles()?.flatMap { - it.listFiles().map { - val dt = Date(it.lastModified()) - Post( - this, - it.readText(), - DateFormat.getDateTimeInstance().format(dt), - emptyList() - ) - } - }?.toList() ?: emptyList()) - } -} \ No newline at end of file diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/NotApplicableException.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/NotApplicableException.kt new file mode 100644 index 0000000..c4a0eb7 --- /dev/null +++ b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/NotApplicableException.kt @@ -0,0 +1,5 @@ +package pl.edu.amu.wmi.socialaggregator.socialplatforms + +import java.lang.Exception + +class NotApplicableException(val socialPlatform: SocialPlatform) : Exception() \ No newline at end of file diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/Snapchat.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/Snapchat.kt new file mode 100644 index 0000000..8d22a9c --- /dev/null +++ b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/Snapchat.kt @@ -0,0 +1,79 @@ +package pl.edu.amu.wmi.socialaggregator.socialplatforms + +import android.content.Context +import android.content.Intent +import android.graphics.Bitmap +import android.util.Log +import com.snapchat.kit.sdk.SnapCreative +import com.snapchat.kit.sdk.creative.api.SnapCreativeKitCompletionCallback +import com.snapchat.kit.sdk.creative.api.SnapCreativeKitSendError +import com.snapchat.kit.sdk.creative.exceptions.SnapMediaSizeException +import com.snapchat.kit.sdk.creative.models.SnapPhotoContent +import io.reactivex.Single +import io.reactivex.subjects.PublishSubject +import pl.edu.amu.wmi.socialaggregator.R +import pl.edu.amu.wmi.socialaggregator.viewholders.SocialWithButtonRecycler +import java.io.File +import java.lang.Exception + +class Snapchat : SocialPlatform { + override fun getName(): String = "Snapchat" + + override fun login(context: Context) { + } + + override fun logout(context: Context) { + } + + override fun isLoggedIn(context: Context): Boolean = true + + override fun addPost( + publishSubject: PublishSubject, + context: Context, + text: String, + images: List, + imagePaths: List + ) { + val snapCreativeKitApi = SnapCreative.getApi(context) + + val content = imagePaths.map { + val snapMediaFactory = SnapCreative.getMediaFactory(context) + val photoFile = try { + snapMediaFactory.getSnapPhotoFromFile(File(it)) + } catch (e: SnapMediaSizeException) { + Log.e(getName(), e.toString()) + null + } + SnapPhotoContent(photoFile!!) + }.first() + + snapCreativeKitApi.sendWithCompletionHandler( + content, + object : SnapCreativeKitCompletionCallback { + override fun onSendSuccess() { + publishSubject.onNext(Any()) + } + + override fun onSendFailed(p0: SnapCreativeKitSendError?) { + publishSubject.onError(Exception("Snapchat error")) + } + + }) + } + + override fun getPosts(context: Context): Single> { + return Single.just(emptyList()) + } + + override fun getLogo(): Int = R.drawable.ic_icon_snapchat + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + } + + override fun handleButtonView(context: Context): (SocialWithButtonRecycler.ViewHolder) -> Unit = + { + it.image.setImageResource(getLogo()) + it.textView.text = getName() + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/SocialPlatform.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/SocialPlatform.kt index 3214dbe..8ee41a7 100644 --- a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/SocialPlatform.kt +++ b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/socialplatforms/SocialPlatform.kt @@ -13,7 +13,10 @@ interface SocialPlatform { fun login(context: Context) fun logout(context: Context) fun isLoggedIn(context: Context): Boolean - fun addPost(context: Context, text: String, images: List): PublishSubject + fun addPost(publishSubject: PublishSubject, + context: Context, text: String, images: List, + imagePaths: List) + fun getPosts(context: Context): Single> fun getLogo(): Int fun handleButtonView(context: Context): (SocialWithButtonRecycler.ViewHolder) -> Unit = {} diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/utils/SocialPlatformsManager.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/utils/SocialPlatformsManager.kt index b7cf0e2..5a42626 100644 --- a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/utils/SocialPlatformsManager.kt +++ b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/utils/SocialPlatformsManager.kt @@ -2,13 +2,14 @@ package pl.edu.amu.wmi.socialaggregator.utils import android.content.Context import pl.edu.amu.wmi.socialaggregator.socialplatforms.Facebook -import pl.edu.amu.wmi.socialaggregator.socialplatforms.FacebookMock +import pl.edu.amu.wmi.socialaggregator.socialplatforms.Snapchat import pl.edu.amu.wmi.socialaggregator.socialplatforms.SocialPlatform object SocialPlatformsManager { - private val IMPLEMENTED_PLATFORMS = listOf( + private val IMPLEMENTED_PLATFORMS = listOf( // FacebookMock() - Facebook() + Facebook(), + Snapchat() ) fun getAll() = IMPLEMENTED_PLATFORMS diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/viewholders/PostDetailsRecycler.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/viewholders/PostDetailsRecycler.kt index 3dedaf0..ce42649 100644 --- a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/viewholders/PostDetailsRecycler.kt +++ b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/viewholders/PostDetailsRecycler.kt @@ -1,5 +1,6 @@ package pl.edu.amu.wmi.socialaggregator.viewholders +import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -11,8 +12,11 @@ import androidx.recyclerview.widget.RecyclerView import com.squareup.picasso.Picasso import io.reactivex.Observable import pl.edu.amu.wmi.socialaggregator.R +import pl.edu.amu.wmi.socialaggregator.socialplatforms.NotApplicableException import pl.edu.amu.wmi.socialaggregator.socialplatforms.Post +import pl.edu.amu.wmi.socialaggregator.socialplatforms.SocialPlatform +@SuppressLint("CheckResult") class PostDetailsRecycler( postsObservable: Observable> ) : RecyclerView.Adapter() { @@ -20,10 +24,11 @@ class PostDetailsRecycler( val posts = emptyList().toMutableList() init { - postsObservable.subscribe { - posts.addAll(it) - notifyDataSetChanged() - } + postsObservable + .subscribe { + posts.addAll(it) + notifyDataSetChanged() + } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { diff --git a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/viewholders/PostSummaryRecycler.kt b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/viewholders/PostSummaryRecycler.kt index 66165a8..c16f0ad 100644 --- a/app/src/main/java/pl/edu/amu/wmi/socialaggregator/viewholders/PostSummaryRecycler.kt +++ b/app/src/main/java/pl/edu/amu/wmi/socialaggregator/viewholders/PostSummaryRecycler.kt @@ -1,5 +1,6 @@ package pl.edu.amu.wmi.socialaggregator.viewholders +import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.ViewGroup import android.widget.ImageView @@ -7,22 +8,27 @@ import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView import io.reactivex.Observable +import io.reactivex.Single import pl.edu.amu.wmi.socialaggregator.R +import pl.edu.amu.wmi.socialaggregator.socialplatforms.NotApplicableException import pl.edu.amu.wmi.socialaggregator.socialplatforms.Post import pl.edu.amu.wmi.socialaggregator.socialplatforms.SocialPlatform +@SuppressLint("CheckResult") class PostSummaryRecycler( - socialsObservable: Observable>> + socialsObservable: Observable?>> ) : RecyclerView.Adapter() { - init { - socialsObservable.subscribe { - socials.add(it) - notifyDataSetChanged() - } - } + private val socials = mutableListOf?>>() - val socials = emptyList>>().toMutableList() + init { + socialsObservable + .doOnNext { + socials.add(it) + notifyDataSetChanged() + } + .subscribe() + } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val layout = LayoutInflater.from(parent.context) @@ -41,9 +47,11 @@ class PostSummaryRecycler( override fun onBindViewHolder(holder: ViewHolder, position: Int) { val (social, posts) = socials[position] - val count = posts.size + val count = posts?.size holder.socialName.text = social.getName() - holder.postCount.text = count.toString() + if (count > 1) " posts" else " post" + holder.postCount.text = count?.let { + count.toString() + if (count > 1) " posts" else " post" + } ?: "Not applicable" holder.imageView.setImageResource(social.getLogo()) } diff --git a/app/src/main/res/drawable-hdpi/ic_icon_snapchat.png b/app/src/main/res/drawable-hdpi/ic_icon_snapchat.png new file mode 100644 index 0000000..fce2549 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_icon_snapchat.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_icon_snapchat.png b/app/src/main/res/drawable-mdpi/ic_icon_snapchat.png new file mode 100644 index 0000000..68ebedf Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_icon_snapchat.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_icon_snapchat.png b/app/src/main/res/drawable-xhdpi/ic_icon_snapchat.png new file mode 100644 index 0000000..2a0157b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_icon_snapchat.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_icon_snapchat.png b/app/src/main/res/drawable-xxhdpi/ic_icon_snapchat.png new file mode 100644 index 0000000..b67b08a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_icon_snapchat.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_icon_snapchat.png b/app/src/main/res/drawable-xxxhdpi/ic_icon_snapchat.png new file mode 100644 index 0000000..f7e3609 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_icon_snapchat.png differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0ad99b7..cd531cb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,4 +6,10 @@ 2437098899888167 fb2437098899888167 + + + + + + diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml new file mode 100644 index 0000000..995db17 --- /dev/null +++ b/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index e882ab2..29dd1d1 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,10 @@ allprojects { repositories { google() jcenter() - + + maven { + url "https://storage.googleapis.com/snap-kit-build/maven" + } } }