instagram

This commit is contained in:
Mateusz Hinc 2020-01-11 18:18:34 +01:00
parent 066400f700
commit 61f2af2cb9
22 changed files with 2000 additions and 194 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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'
])
}

View File

@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pl.edu.amu.wmi.socialaggregator">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
@ -68,6 +69,24 @@
android:name="com.facebook.FacebookContentProvider"
android:exported="true"/>
<meta-data android:name="com.snapchat.kit.sdk.clientId" android:value="240836fb-b762-4be8-a42f-5472a22f2114" />
<!-- <meta-data android:name="com.snapchat.kit.sdk.clientId" android:value="your apps client id" />-->
<!-- <meta-data android:name="com.snapchat.kit.sdk.redirectUrl" android:value="the url that will handle login completion" />-->
<!-- <meta-data android:name="com.snapchat.kit.sdk.scopes" android:resource="@array/snap_connect_scopes" />-->
<provider
android:authorities="${applicationId}.fileprovider,pl.edu.amu.wmi.socialaggregator.activity.NewPostActivity"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"
/>
</provider>
</application>
<uses-permission android:name="android.permission.INTERNET"/>

View File

@ -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()
})
)
}
}

View File

@ -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<Any>()
val resumedSubject = PublishSubject.create<Any>()
@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<Any, SocialPlatform, SocialPlatform> { _, 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)

View File

@ -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<Bitmap>) : PublishSubject<Any> {
override fun addPost(
publishSubject: PublishSubject<Any>,
context: Context,
text: String,
images: List<Bitmap>,
imagePaths: List<String>
) {
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<Any>()
val shareDialog = ShareDialog(context as Activity)
shareDialog.registerCallback(callbackManager, object : FacebookCallback<Sharer.Result?> {
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<List<Post>> {
return Single.just(AccessToken.getCurrentAccessToken())
.observeOn(Schedulers.io())
.map { token ->
if (token.isExpired) {
return@map emptyList<Post>()
} 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<String>()
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<LoginResult> {
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() {

View File

@ -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<Bitmap>): PublishSubject<Any> {
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<List<Post>> {
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())
}
}

View File

@ -0,0 +1,5 @@
package pl.edu.amu.wmi.socialaggregator.socialplatforms
import java.lang.Exception
class NotApplicableException(val socialPlatform: SocialPlatform) : Exception()

View File

@ -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<Any>,
context: Context,
text: String,
images: List<Bitmap>,
imagePaths: List<String>
) {
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<List<Post>> {
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()
}
}

View File

@ -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<Bitmap>): PublishSubject<Any>
fun addPost(publishSubject: PublishSubject<Any>,
context: Context, text: String, images: List<Bitmap>,
imagePaths: List<String>)
fun getPosts(context: Context): Single<List<Post>>
fun getLogo(): Int
fun handleButtonView(context: Context): (SocialWithButtonRecycler.ViewHolder) -> Unit = {}

View File

@ -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<SocialPlatform>(
private val IMPLEMENTED_PLATFORMS = listOf(
// FacebookMock()
Facebook()
Facebook(),
Snapchat()
)
fun getAll() = IMPLEMENTED_PLATFORMS

View File

@ -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<List<Post>>
) : RecyclerView.Adapter<PostDetailsRecycler.ViewHolder>() {
@ -20,10 +24,11 @@ class PostDetailsRecycler(
val posts = emptyList<Post>().toMutableList()
init {
postsObservable.subscribe {
posts.addAll(it)
notifyDataSetChanged()
}
postsObservable
.subscribe {
posts.addAll(it)
notifyDataSetChanged()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

View File

@ -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<Pair<SocialPlatform, List<Post>>>
socialsObservable: Observable<Pair<SocialPlatform, List<Post>?>>
) : RecyclerView.Adapter<PostSummaryRecycler.ViewHolder>() {
init {
socialsObservable.subscribe {
socials.add(it)
notifyDataSetChanged()
}
}
private val socials = mutableListOf<Pair<SocialPlatform, List<Post>?>>()
val socials = emptyList<Pair<SocialPlatform, List<Post>>>().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())
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -6,4 +6,10 @@
<string name="facebook_app_id">2437098899888167</string>
<string name="fb_login_protocol_scheme">fb2437098899888167</string>
<!-- <key>SCSDKScopes</key>-->
<!-- <array name="snap_connect_scopes">-->
<!-- <string>https://auth.snapchat.com/oauth2/api/user.bitmoji.avatar</string>-->
<!-- &lt;!&ndash; other scopes you might have... &ndash;&gt;-->
<!-- </array>-->
</resources>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<root-path name="root" path="." />
<external-cache-path name="external_files" path="."/>
<external-path name="external_files" path="."/>
</paths>

View File

@ -19,7 +19,10 @@ allprojects {
repositories {
google()
jcenter()
maven {
url "https://storage.googleapis.com/snap-kit-build/maven"
}
}
}