Merge branch 'token_consistency' into 'master'
Better token refresh, refactor auth token with interceptor See merge request pixeldroid/PixelDroid!326
This commit is contained in:
commit
bccf57f918
@ -185,16 +185,17 @@ class MainActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
private fun getUpdatedAccount() {
|
private fun getUpdatedAccount() {
|
||||||
if (hasInternet(applicationContext)) {
|
if (hasInternet(applicationContext)) {
|
||||||
val domain = user?.instance_uri.orEmpty()
|
|
||||||
val accessToken = user?.accessToken.orEmpty()
|
|
||||||
val refreshToken = user?.refreshToken
|
|
||||||
val clientId = user?.clientId.orEmpty()
|
|
||||||
val clientSecret = user?.clientSecret.orEmpty()
|
|
||||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
|
||||||
|
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
try {
|
try {
|
||||||
val account = api.verifyCredentials("Bearer $accessToken")
|
val domain = user?.instance_uri.orEmpty()
|
||||||
|
val accessToken = user?.accessToken.orEmpty()
|
||||||
|
val refreshToken = user?.refreshToken
|
||||||
|
val clientId = user?.clientId.orEmpty()
|
||||||
|
val clientSecret = user?.clientSecret.orEmpty()
|
||||||
|
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
|
||||||
|
val account = api.verifyCredentials()
|
||||||
addUser(db, account, domain, accessToken = accessToken, refreshToken = refreshToken, clientId = clientId, clientSecret = clientSecret)
|
addUser(db, account, domain, accessToken = accessToken, refreshToken = refreshToken, clientId = clientId, clientSecret = clientSecret)
|
||||||
fillDrawerAccountInfo(account.id!!)
|
fillDrawerAccountInfo(account.id!!)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
|
@ -29,7 +29,6 @@ import com.h.pixeldroid.postCreation.carousel.CarouselItem
|
|||||||
import com.h.pixeldroid.postCreation.carousel.ImageCarousel
|
import com.h.pixeldroid.postCreation.carousel.ImageCarousel
|
||||||
import com.h.pixeldroid.postCreation.photoEdit.PhotoEditActivity
|
import com.h.pixeldroid.postCreation.photoEdit.PhotoEditActivity
|
||||||
import com.h.pixeldroid.utils.BaseActivity
|
import com.h.pixeldroid.utils.BaseActivity
|
||||||
import com.h.pixeldroid.utils.api.PixelfedAPI
|
|
||||||
import com.h.pixeldroid.utils.api.objects.Attachment
|
import com.h.pixeldroid.utils.api.objects.Attachment
|
||||||
import com.h.pixeldroid.utils.db.entities.InstanceDatabaseEntity
|
import com.h.pixeldroid.utils.db.entities.InstanceDatabaseEntity
|
||||||
import com.h.pixeldroid.utils.db.entities.UserDatabaseEntity
|
import com.h.pixeldroid.utils.db.entities.UserDatabaseEntity
|
||||||
@ -58,8 +57,6 @@ data class PhotoData(
|
|||||||
|
|
||||||
class PostCreationActivity : BaseActivity() {
|
class PostCreationActivity : BaseActivity() {
|
||||||
|
|
||||||
private lateinit var accessToken: String
|
|
||||||
|
|
||||||
private var user: UserDatabaseEntity? = null
|
private var user: UserDatabaseEntity? = null
|
||||||
private lateinit var instance: InstanceDatabaseEntity
|
private lateinit var instance: InstanceDatabaseEntity
|
||||||
|
|
||||||
@ -85,8 +82,6 @@ class PostCreationActivity : BaseActivity() {
|
|||||||
// get image URIs
|
// get image URIs
|
||||||
intent.clipData?.let { addPossibleImages(it) }
|
intent.clipData?.let { addPossibleImages(it) }
|
||||||
|
|
||||||
accessToken = user?.accessToken.orEmpty()
|
|
||||||
|
|
||||||
val carousel: ImageCarousel = binding.carousel
|
val carousel: ImageCarousel = binding.carousel
|
||||||
carousel.addData(photoData.map { CarouselItem(it.imageUri) })
|
carousel.addData(photoData.map { CarouselItem(it.imageUri) })
|
||||||
carousel.layoutCarouselCallback = {
|
carousel.layoutCarouselCallback = {
|
||||||
@ -338,7 +333,7 @@ class PostCreationActivity : BaseActivity() {
|
|||||||
val description = data.imageDescription?.let { MultipartBody.Part.createFormData("description", it) }
|
val description = data.imageDescription?.let { MultipartBody.Part.createFormData("description", it) }
|
||||||
|
|
||||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
val inter = api.mediaUpload("Bearer $accessToken", description, requestBody.parts[0])
|
val inter = api.mediaUpload(description, requestBody.parts[0])
|
||||||
|
|
||||||
postSub = inter
|
postSub = inter
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
@ -383,7 +378,6 @@ class PostCreationActivity : BaseActivity() {
|
|||||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
|
||||||
api.postStatus(
|
api.postStatus(
|
||||||
authorization = "Bearer $accessToken",
|
|
||||||
statusText = description,
|
statusText = description,
|
||||||
media_ids = photoData.mapNotNull { it.uploadId }.toList()
|
media_ids = photoData.mapNotNull { it.uploadId }.toList()
|
||||||
)
|
)
|
||||||
|
@ -12,13 +12,13 @@ import android.view.View
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.text.toSpanned
|
import androidx.core.text.toSpanned
|
||||||
import androidx.lifecycle.Lifecycle
|
|
||||||
import androidx.lifecycle.LifecycleCoroutineScope
|
import androidx.lifecycle.LifecycleCoroutineScope
|
||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
import com.h.pixeldroid.utils.api.PixelfedAPI
|
import com.h.pixeldroid.utils.api.PixelfedAPI
|
||||||
import com.h.pixeldroid.utils.api.objects.Account.Companion.openAccountFromId
|
import com.h.pixeldroid.utils.api.objects.Account.Companion.openAccountFromId
|
||||||
import com.h.pixeldroid.utils.api.objects.Mention
|
import com.h.pixeldroid.utils.api.objects.Mention
|
||||||
import kotlinx.coroutines.coroutineScope
|
import com.h.pixeldroid.utils.db.AppDatabase
|
||||||
|
import com.h.pixeldroid.utils.di.PixelfedAPIHolder
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.URISyntaxException
|
import java.net.URISyntaxException
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
@ -50,12 +50,12 @@ fun getDomain(urlString: String?): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun parseHTMLText(
|
fun parseHTMLText(
|
||||||
text : String,
|
text: String,
|
||||||
mentions: List<Mention>?,
|
mentions: List<Mention>?,
|
||||||
api : PixelfedAPI,
|
apiHolder: PixelfedAPIHolder,
|
||||||
context: Context,
|
context: Context,
|
||||||
credential: String,
|
lifecycleScope: LifecycleCoroutineScope,
|
||||||
lifecycleScope: LifecycleCoroutineScope
|
db: AppDatabase
|
||||||
) : Spanned {
|
) : Spanned {
|
||||||
//Convert text to spannable
|
//Convert text to spannable
|
||||||
val content = fromHtml(text)
|
val content = fromHtml(text)
|
||||||
@ -108,7 +108,8 @@ fun parseHTMLText(
|
|||||||
Log.e("MENTION", "CLICKED")
|
Log.e("MENTION", "CLICKED")
|
||||||
//Retrieve the account for the given profile
|
//Retrieve the account for the given profile
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
openAccountFromId(accountId, api, context, credential)
|
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
openAccountFromId(accountId, api, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ import java.io.IOException
|
|||||||
|
|
||||||
class PostActivity : BaseActivity() {
|
class PostActivity : BaseActivity() {
|
||||||
lateinit var domain : String
|
lateinit var domain : String
|
||||||
private lateinit var accessToken : String
|
|
||||||
|
|
||||||
private lateinit var binding: ActivityPostBinding
|
private lateinit var binding: ActivityPostBinding
|
||||||
|
|
||||||
@ -45,17 +44,15 @@ class PostActivity : BaseActivity() {
|
|||||||
val user = db.userDao().getActiveUser()
|
val user = db.userDao().getActiveUser()
|
||||||
|
|
||||||
domain = user?.instance_uri.orEmpty()
|
domain = user?.instance_uri.orEmpty()
|
||||||
accessToken = user?.accessToken.orEmpty()
|
|
||||||
|
|
||||||
|
|
||||||
supportActionBar?.title = getString(R.string.post_title).format(status.account?.getDisplayName())
|
supportActionBar?.title = getString(R.string.post_title).format(status.account?.getDisplayName())
|
||||||
|
|
||||||
val holder = StatusViewHolder(binding.postFragmentSingle)
|
val holder = StatusViewHolder(binding.postFragmentSingle)
|
||||||
|
|
||||||
holder.bind(status, apiHolder.api!!, db, lifecycleScope, displayDimensionsInPx(), isActivity = true)
|
holder.bind(status, apiHolder, db, lifecycleScope, displayDimensionsInPx(), isActivity = true)
|
||||||
|
|
||||||
val credential = "Bearer $accessToken"
|
activateCommenter()
|
||||||
activateCommenter(credential)
|
|
||||||
|
|
||||||
if(viewComments || postComment){
|
if(viewComments || postComment){
|
||||||
//Scroll already down as much as possible (since comments are not loaded yet)
|
//Scroll already down as much as possible (since comments are not loaded yet)
|
||||||
@ -68,10 +65,10 @@ class PostActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// also retrieve comments if we're not posting the comment
|
// also retrieve comments if we're not posting the comment
|
||||||
if(!postComment) retrieveComments(apiHolder.api!!, credential)
|
if(!postComment) retrieveComments(apiHolder.api!!)
|
||||||
}
|
}
|
||||||
binding.postFragmentSingle.viewComments.setOnClickListener {
|
binding.postFragmentSingle.viewComments.setOnClickListener {
|
||||||
retrieveComments(apiHolder.api!!, credential)
|
retrieveComments(apiHolder.api!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +77,7 @@ class PostActivity : BaseActivity() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun activateCommenter(credential: String) {
|
private fun activateCommenter() {
|
||||||
//Activate commenter
|
//Activate commenter
|
||||||
binding.submitComment.setOnClickListener {
|
binding.submitComment.setOnClickListener {
|
||||||
val textIn = binding.editComment.text
|
val textIn = binding.editComment.text
|
||||||
@ -94,15 +91,14 @@ class PostActivity : BaseActivity() {
|
|||||||
} else {
|
} else {
|
||||||
//Post the comment
|
//Post the comment
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
apiHolder.api?.let { it1 -> postComment(it1, credential) }
|
apiHolder.api?.let { it1 -> postComment(it1) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addComment(context: Context, commentContainer: LinearLayout,
|
private fun addComment(context: Context, commentContainer: LinearLayout,
|
||||||
commentUsername: String, commentContent: String, mentions: List<Mention>,
|
commentUsername: String, commentContent: String, mentions: List<Mention>) {
|
||||||
credential: String) {
|
|
||||||
|
|
||||||
|
|
||||||
val itemBinding = CommentBinding.inflate(
|
val itemBinding = CommentBinding.inflate(
|
||||||
@ -113,25 +109,29 @@ class PostActivity : BaseActivity() {
|
|||||||
itemBinding.commentText.text = parseHTMLText(
|
itemBinding.commentText.text = parseHTMLText(
|
||||||
commentContent,
|
commentContent,
|
||||||
mentions,
|
mentions,
|
||||||
apiHolder.api!!,
|
apiHolder,
|
||||||
context,
|
context,
|
||||||
credential,
|
lifecycleScope,
|
||||||
lifecycleScope
|
db
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun retrieveComments(api: PixelfedAPI, credential: String) {
|
private fun retrieveComments(api: PixelfedAPI) {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
status.id.let {
|
status.id.let {
|
||||||
try {
|
try {
|
||||||
val statuses = api.statusComments(it, credential).descendants
|
val statuses = api.statusComments(it).descendants
|
||||||
|
|
||||||
binding.commentContainer.removeAllViews()
|
binding.commentContainer.removeAllViews()
|
||||||
|
|
||||||
//Create the new views for each comment
|
//Create the new views for each comment
|
||||||
for (status in statuses) {
|
for (status in statuses) {
|
||||||
addComment(binding.root.context, binding.commentContainer, status.account!!.username!!,
|
addComment(
|
||||||
status.content!!, status.mentions.orEmpty(), credential
|
binding.root.context,
|
||||||
|
binding.commentContainer,
|
||||||
|
status.account!!.username!!,
|
||||||
|
status.content!!,
|
||||||
|
status.mentions.orEmpty()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
binding.commentContainer.visibility = View.VISIBLE
|
binding.commentContainer.visibility = View.VISIBLE
|
||||||
@ -149,19 +149,18 @@ class PostActivity : BaseActivity() {
|
|||||||
|
|
||||||
private suspend fun postComment(
|
private suspend fun postComment(
|
||||||
api: PixelfedAPI,
|
api: PixelfedAPI,
|
||||||
credential: String,
|
|
||||||
) {
|
) {
|
||||||
val textIn = binding.editComment.text
|
val textIn = binding.editComment.text
|
||||||
val nonNullText = textIn.toString()
|
val nonNullText = textIn.toString()
|
||||||
status.id.let {
|
status.id.let {
|
||||||
try {
|
try {
|
||||||
val response = api.postStatus(credential, nonNullText, it)
|
val response = api.postStatus(nonNullText, it)
|
||||||
binding.commentIn.visibility = View.GONE
|
binding.commentIn.visibility = View.GONE
|
||||||
|
|
||||||
//Add the comment to the comment section
|
//Add the comment to the comment section
|
||||||
addComment(
|
addComment(
|
||||||
binding.root.context, binding.commentContainer, response.account!!.username!!,
|
binding.root.context, binding.commentContainer, response.account!!.username!!,
|
||||||
response.content!!, response.mentions.orEmpty(), credential
|
response.content!!, response.mentions.orEmpty()
|
||||||
)
|
)
|
||||||
|
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
|
@ -24,10 +24,6 @@ class ReportActivity : BaseActivity() {
|
|||||||
|
|
||||||
val status = intent.getSerializableExtra(Status.POST_TAG) as Status?
|
val status = intent.getSerializableExtra(Status.POST_TAG) as Status?
|
||||||
|
|
||||||
//get the currently active user
|
|
||||||
val user = db.userDao().getActiveUser()
|
|
||||||
|
|
||||||
|
|
||||||
binding.reportTargetTextview.text = getString(R.string.report_target).format(status?.account?.acct)
|
binding.reportTargetTextview.text = getString(R.string.report_target).format(status?.account?.acct)
|
||||||
|
|
||||||
|
|
||||||
@ -37,12 +33,15 @@ class ReportActivity : BaseActivity() {
|
|||||||
|
|
||||||
binding.textInputLayout.editText?.isEnabled = false
|
binding.textInputLayout.editText?.isEnabled = false
|
||||||
|
|
||||||
val accessToken = user?.accessToken.orEmpty()
|
|
||||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
try {
|
try {
|
||||||
api.report("Bearer $accessToken", status?.account?.id!!, listOf(status), binding.textInputLayout.editText?.text.toString())
|
api.report(
|
||||||
|
status?.account?.id!!,
|
||||||
|
listOf(status),
|
||||||
|
binding.textInputLayout.editText?.text.toString()
|
||||||
|
)
|
||||||
|
|
||||||
reportStatus(true)
|
reportStatus(true)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
|
@ -29,6 +29,7 @@ import com.h.pixeldroid.utils.api.objects.Status.Companion.POST_COMMENT_TAG
|
|||||||
import com.h.pixeldroid.utils.api.objects.Status.Companion.POST_TAG
|
import com.h.pixeldroid.utils.api.objects.Status.Companion.POST_TAG
|
||||||
import com.h.pixeldroid.utils.api.objects.Status.Companion.VIEW_COMMENTS_TAG
|
import com.h.pixeldroid.utils.api.objects.Status.Companion.VIEW_COMMENTS_TAG
|
||||||
import com.h.pixeldroid.utils.db.AppDatabase
|
import com.h.pixeldroid.utils.db.AppDatabase
|
||||||
|
import com.h.pixeldroid.utils.di.PixelfedAPIHolder
|
||||||
import com.karumi.dexter.Dexter
|
import com.karumi.dexter.Dexter
|
||||||
import com.karumi.dexter.listener.PermissionDeniedResponse
|
import com.karumi.dexter.listener.PermissionDeniedResponse
|
||||||
import com.karumi.dexter.listener.PermissionGrantedResponse
|
import com.karumi.dexter.listener.PermissionGrantedResponse
|
||||||
@ -46,7 +47,7 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
|
|
||||||
private var status: Status? = null
|
private var status: Status? = null
|
||||||
|
|
||||||
fun bind(status: Status?, pixelfedAPI: PixelfedAPI, db: AppDatabase, lifecycleScope: LifecycleCoroutineScope, displayDimensionsInPx: Pair<Int, Int>, isActivity: Boolean = false) {
|
fun bind(status: Status?, pixelfedAPI: PixelfedAPIHolder, db: AppDatabase, lifecycleScope: LifecycleCoroutineScope, displayDimensionsInPx: Pair<Int, Int>, isActivity: Boolean = false) {
|
||||||
|
|
||||||
this.itemView.visibility = View.VISIBLE
|
this.itemView.visibility = View.VISIBLE
|
||||||
this.status = status
|
this.status = status
|
||||||
@ -177,9 +178,9 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setDescription(
|
private fun setDescription(
|
||||||
api: PixelfedAPI,
|
apiHolder: PixelfedAPIHolder,
|
||||||
credential: String,
|
lifecycleScope: LifecycleCoroutineScope,
|
||||||
lifecycleScope: LifecycleCoroutineScope
|
db: AppDatabase
|
||||||
) {
|
) {
|
||||||
binding.description.apply {
|
binding.description.apply {
|
||||||
if (status?.content.isNullOrBlank()) {
|
if (status?.content.isNullOrBlank()) {
|
||||||
@ -188,10 +189,10 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
text = parseHTMLText(
|
text = parseHTMLText(
|
||||||
status?.content.orEmpty(),
|
status?.content.orEmpty(),
|
||||||
status?.mentions,
|
status?.mentions,
|
||||||
api,
|
apiHolder,
|
||||||
binding.root.context,
|
binding.root.context,
|
||||||
credential,
|
lifecycleScope,
|
||||||
lifecycleScope
|
db
|
||||||
)
|
)
|
||||||
movementMethod = LinkMovementMethod.getInstance()
|
movementMethod = LinkMovementMethod.getInstance()
|
||||||
}
|
}
|
||||||
@ -199,25 +200,20 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
}
|
}
|
||||||
//region buttons
|
//region buttons
|
||||||
private fun activateButtons(
|
private fun activateButtons(
|
||||||
api: PixelfedAPI,
|
apiHolder: PixelfedAPIHolder,
|
||||||
db: AppDatabase,
|
db: AppDatabase,
|
||||||
lifecycleScope: LifecycleCoroutineScope,
|
lifecycleScope: LifecycleCoroutineScope,
|
||||||
isActivity: Boolean
|
isActivity: Boolean
|
||||||
){
|
){
|
||||||
val user = db.userDao().getActiveUser()!!
|
|
||||||
|
|
||||||
val credential = "Bearer ${user.accessToken}"
|
|
||||||
//Set the special HTML text
|
//Set the special HTML text
|
||||||
setDescription(api, credential, lifecycleScope)
|
setDescription(apiHolder, lifecycleScope, db)
|
||||||
|
|
||||||
//Activate onclickListeners
|
//Activate onclickListeners
|
||||||
activateLiker(
|
activateLiker(
|
||||||
api, credential, status?.favourited ?: false,
|
apiHolder, status?.favourited ?: false, lifecycleScope, db
|
||||||
lifecycleScope
|
|
||||||
)
|
)
|
||||||
activateReblogger(
|
activateReblogger(
|
||||||
api, credential, status?.reblogged ?: false,
|
apiHolder, status?.reblogged ?: false, lifecycleScope, db
|
||||||
lifecycleScope
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if(isActivity){
|
if(isActivity){
|
||||||
@ -237,14 +233,14 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
|
|
||||||
showComments(lifecycleScope, isActivity)
|
showComments(lifecycleScope, isActivity)
|
||||||
|
|
||||||
activateMoreButton(api, db, lifecycleScope)
|
activateMoreButton(apiHolder, db, lifecycleScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun activateReblogger(
|
private fun activateReblogger(
|
||||||
api: PixelfedAPI,
|
apiHolder: PixelfedAPIHolder,
|
||||||
credential: String,
|
isReblogged: Boolean,
|
||||||
isReblogged: Boolean,
|
lifecycleScope: LifecycleCoroutineScope,
|
||||||
lifecycleScope: LifecycleCoroutineScope
|
db: AppDatabase
|
||||||
) {
|
) {
|
||||||
binding.reblogger.apply {
|
binding.reblogger.apply {
|
||||||
//Set initial button state
|
//Set initial button state
|
||||||
@ -253,12 +249,13 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
//Activate the button
|
//Activate the button
|
||||||
setEventListener { _, buttonState ->
|
setEventListener { _, buttonState ->
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
|
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
if (buttonState) {
|
if (buttonState) {
|
||||||
// Button is active
|
// Button is active
|
||||||
undoReblogPost(api, credential)
|
undoReblogPost(api)
|
||||||
} else {
|
} else {
|
||||||
// Button is inactive
|
// Button is inactive
|
||||||
reblogPost(api, credential)
|
reblogPost(api)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//show animation or not?
|
//show animation or not?
|
||||||
@ -267,15 +264,12 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun reblogPost(
|
private suspend fun reblogPost(api: PixelfedAPI) {
|
||||||
api: PixelfedAPI,
|
|
||||||
credential: String
|
|
||||||
) {
|
|
||||||
//Call the api function
|
//Call the api function
|
||||||
status?.id?.let {
|
status?.id?.let {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val resp = api.reblogStatus(credential, it)
|
val resp = api.reblogStatus(it)
|
||||||
|
|
||||||
//Update shown share count
|
//Update shown share count
|
||||||
binding.nshares.text = resp.getNShares(binding.root.context)
|
binding.nshares.text = resp.getNShares(binding.root.context)
|
||||||
@ -290,14 +284,11 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun undoReblogPost(
|
private suspend fun undoReblogPost(api: PixelfedAPI) {
|
||||||
api: PixelfedAPI,
|
|
||||||
credential: String,
|
|
||||||
) {
|
|
||||||
//Call the api function
|
//Call the api function
|
||||||
status?.id?.let {
|
status?.id?.let {
|
||||||
try {
|
try {
|
||||||
val resp = api.undoReblogStatus(credential, it)
|
val resp = api.undoReblogStatus(it)
|
||||||
|
|
||||||
//Update shown share count
|
//Update shown share count
|
||||||
binding.nshares.text = resp.getNShares(binding.root.context)
|
binding.nshares.text = resp.getNShares(binding.root.context)
|
||||||
@ -312,7 +303,7 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun activateMoreButton(api: PixelfedAPI, db: AppDatabase, lifecycleScope: LifecycleCoroutineScope){
|
private fun activateMoreButton(apiHolder: PixelfedAPIHolder, db: AppDatabase, lifecycleScope: LifecycleCoroutineScope){
|
||||||
binding.statusMore.setOnClickListener {
|
binding.statusMore.setOnClickListener {
|
||||||
PopupMenu(it.context, it).apply {
|
PopupMenu(it.context, it).apply {
|
||||||
setOnMenuItemClickListener { item ->
|
setOnMenuItemClickListener { item ->
|
||||||
@ -395,7 +386,8 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
db.homePostDao().delete(id, user.user_id, user.instance_uri)
|
db.homePostDao().delete(id, user.user_id, user.instance_uri)
|
||||||
db.publicPostDao().delete(id, user.user_id, user.instance_uri)
|
db.publicPostDao().delete(id, user.user_id, user.instance_uri)
|
||||||
try {
|
try {
|
||||||
api.deleteStatus("Bearer ${user.accessToken}", id)
|
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
api.deleteStatus(id)
|
||||||
binding.root.visibility = View.GONE
|
binding.root.visibility = View.GONE
|
||||||
} catch (exception: HttpException) {
|
} catch (exception: HttpException) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
@ -439,10 +431,10 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun activateLiker(
|
private fun activateLiker(
|
||||||
api: PixelfedAPI,
|
apiHolder: PixelfedAPIHolder,
|
||||||
credential: String,
|
isLiked: Boolean,
|
||||||
isLiked: Boolean,
|
lifecycleScope: LifecycleCoroutineScope,
|
||||||
lifecycleScope: LifecycleCoroutineScope
|
db: AppDatabase
|
||||||
) {
|
) {
|
||||||
|
|
||||||
binding.liker.apply {
|
binding.liker.apply {
|
||||||
@ -452,12 +444,13 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
//Activate the liker
|
//Activate the liker
|
||||||
setEventListener { _, buttonState ->
|
setEventListener { _, buttonState ->
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
|
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
if (buttonState) {
|
if (buttonState) {
|
||||||
// Button is active, unlike
|
// Button is active, unlike
|
||||||
unLikePostCall(api, credential)
|
unLikePostCall(api)
|
||||||
} else {
|
} else {
|
||||||
// Button is inactive, like
|
// Button is inactive, like
|
||||||
likePostCall(api, credential)
|
likePostCall(api)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//show animation or not?
|
//show animation or not?
|
||||||
@ -473,15 +466,16 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
if(binding.sensitiveWarning.visibility == View.GONE) {
|
if(binding.sensitiveWarning.visibility == View.GONE) {
|
||||||
//Check for double click
|
//Check for double click
|
||||||
if(clicked) {
|
if(clicked) {
|
||||||
|
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
if (binding.liker.isChecked) {
|
if (binding.liker.isChecked) {
|
||||||
// Button is active, unlike
|
// Button is active, unlike
|
||||||
binding.liker.isChecked = false
|
binding.liker.isChecked = false
|
||||||
unLikePostCall(api, credential)
|
unLikePostCall(api)
|
||||||
} else {
|
} else {
|
||||||
// Button is inactive, like
|
// Button is inactive, like
|
||||||
binding.liker.playAnimation()
|
binding.liker.playAnimation()
|
||||||
binding.liker.isChecked = true
|
binding.liker.isChecked = true
|
||||||
likePostCall(api, credential)
|
likePostCall(api)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clicked = true
|
clicked = true
|
||||||
@ -495,15 +489,12 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun likePostCall(
|
private suspend fun likePostCall(api: PixelfedAPI) {
|
||||||
api: PixelfedAPI,
|
|
||||||
credential: String,
|
|
||||||
) {
|
|
||||||
//Call the api function
|
//Call the api function
|
||||||
status?.id?.let {
|
status?.id?.let {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val resp = api.likePost(credential, it)
|
val resp = api.likePost(it)
|
||||||
|
|
||||||
//Update shown like count and internal like toggle
|
//Update shown like count and internal like toggle
|
||||||
binding.nlikes.text = resp.getNLikes(binding.root.context)
|
binding.nlikes.text = resp.getNLikes(binding.root.context)
|
||||||
@ -518,15 +509,12 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun unLikePostCall(
|
private suspend fun unLikePostCall(api: PixelfedAPI) {
|
||||||
api: PixelfedAPI,
|
|
||||||
credential: String,
|
|
||||||
) {
|
|
||||||
//Call the api function
|
//Call the api function
|
||||||
status?.id?.let {
|
status?.id?.let {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val resp = api.unlikePost(credential, it)
|
val resp = api.unlikePost(it)
|
||||||
|
|
||||||
//Update shown like count and internal like toggle
|
//Update shown like count and internal like toggle
|
||||||
binding.nlikes.text = resp.getNLikes(binding.root.context)
|
binding.nlikes.text = resp.getNLikes(binding.root.context)
|
||||||
|
@ -27,7 +27,6 @@ import com.h.pixeldroid.posts.feeds.cachedFeeds.ViewModelFactory
|
|||||||
import com.h.pixeldroid.posts.parseHTMLText
|
import com.h.pixeldroid.posts.parseHTMLText
|
||||||
import com.h.pixeldroid.posts.setTextViewFromISO8601
|
import com.h.pixeldroid.posts.setTextViewFromISO8601
|
||||||
import com.h.pixeldroid.profile.ProfileActivity
|
import com.h.pixeldroid.profile.ProfileActivity
|
||||||
import com.h.pixeldroid.utils.api.PixelfedAPI
|
|
||||||
import com.h.pixeldroid.utils.api.objects.Account
|
import com.h.pixeldroid.utils.api.objects.Account
|
||||||
import com.h.pixeldroid.utils.api.objects.Notification
|
import com.h.pixeldroid.utils.api.objects.Notification
|
||||||
import com.h.pixeldroid.utils.api.objects.Status
|
import com.h.pixeldroid.utils.api.objects.Status
|
||||||
@ -165,9 +164,9 @@ class NotificationsFragment : CachedFeedFragment<Notification>() {
|
|||||||
|
|
||||||
fun bind(
|
fun bind(
|
||||||
notification: Notification?,
|
notification: Notification?,
|
||||||
api: PixelfedAPI,
|
api: PixelfedAPIHolder,
|
||||||
accessToken: String,
|
lifecycleScope: LifecycleCoroutineScope,
|
||||||
lifecycleScope: LifecycleCoroutineScope
|
db: AppDatabase
|
||||||
) {
|
) {
|
||||||
|
|
||||||
this.notification = notification
|
this.notification = notification
|
||||||
@ -208,8 +207,8 @@ class NotificationsFragment : CachedFeedFragment<Notification>() {
|
|||||||
notification?.status?.mentions,
|
notification?.status?.mentions,
|
||||||
api,
|
api,
|
||||||
itemView.context,
|
itemView.context,
|
||||||
"Bearer $accessToken",
|
lifecycleScope,
|
||||||
lifecycleScope
|
db
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,9 +256,9 @@ class NotificationsFragment : CachedFeedFragment<Notification>() {
|
|||||||
uiModel.let {
|
uiModel.let {
|
||||||
(holder as NotificationViewHolder).bind(
|
(holder as NotificationViewHolder).bind(
|
||||||
it,
|
it,
|
||||||
apiHolder.setDomainToCurrentUser(db),
|
apiHolder,
|
||||||
db.userDao().getActiveUser()!!.accessToken,
|
lifecycleScope,
|
||||||
lifecycleScope
|
db
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,12 +59,11 @@ class NotificationsRemoteMediator @Inject constructor(
|
|||||||
val user = db.userDao().getActiveUser()
|
val user = db.userDao().getActiveUser()
|
||||||
?: return MediatorResult.Error(NullPointerException("No active user exists"))
|
?: return MediatorResult.Error(NullPointerException("No active user exists"))
|
||||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
val accessToken = user.accessToken
|
|
||||||
|
|
||||||
val apiResponse = api.notifications("Bearer $accessToken",
|
val apiResponse = api.notifications(
|
||||||
max_id = max_id,
|
max_id = max_id,
|
||||||
min_id = min_id,
|
min_id = min_id,
|
||||||
limit = state.config.pageSize.toString(),
|
limit = state.config.pageSize.toString(),
|
||||||
)
|
)
|
||||||
|
|
||||||
apiResponse.forEach{it.user_id = user.user_id; it.instance_uri = user.instance_uri}
|
apiResponse.forEach{it.user_id = user.user_id; it.instance_uri = user.instance_uri}
|
||||||
|
@ -44,11 +44,11 @@ class HomeFeedRemoteMediator @Inject constructor(
|
|||||||
val user = db.userDao().getActiveUser()
|
val user = db.userDao().getActiveUser()
|
||||||
?: return MediatorResult.Error(NullPointerException("No active user exists"))
|
?: return MediatorResult.Error(NullPointerException("No active user exists"))
|
||||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
val accessToken = user.accessToken
|
|
||||||
|
|
||||||
val apiResponse = api.timelineHome( "Bearer $accessToken",
|
val apiResponse = api.timelineHome(
|
||||||
max_id= max_id, min_id = min_id,
|
max_id= max_id,
|
||||||
limit = state.config.pageSize.toString())
|
min_id = min_id, limit = state.config.pageSize.toString()
|
||||||
|
)
|
||||||
|
|
||||||
val dbObjects = apiResponse.map{
|
val dbObjects = apiResponse.map{
|
||||||
HomeStatusDatabaseEntity(user.user_id, user.instance_uri, it)
|
HomeStatusDatabaseEntity(user.user_id, user.instance_uri, it)
|
||||||
|
@ -90,7 +90,7 @@ class PostFeedFragment<T: FeedContentDatabase>: CachedFeedFragment<T>() {
|
|||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
val uiModel = getItem(position) as Status
|
val uiModel = getItem(position) as Status
|
||||||
uiModel.let {
|
uiModel.let {
|
||||||
(holder as StatusViewHolder).bind(it, apiHolder.setDomainToCurrentUser(db), db, lifecycleScope, displayDimensionsInPx)
|
(holder as StatusViewHolder).bind(it, apiHolder, db, lifecycleScope, displayDimensionsInPx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,6 @@ class AccountListFragment : UncachedFeedFragment<Account>() {
|
|||||||
viewModel = ViewModelProvider(this, ViewModelFactory(
|
viewModel = ViewModelProvider(this, ViewModelFactory(
|
||||||
FollowersContentRepository(
|
FollowersContentRepository(
|
||||||
apiHolder.setDomainToCurrentUser(db),
|
apiHolder.setDomainToCurrentUser(db),
|
||||||
db.userDao().getActiveUser()!!.accessToken,
|
|
||||||
id,
|
id,
|
||||||
following
|
following
|
||||||
)
|
)
|
||||||
|
@ -14,7 +14,6 @@ import javax.inject.Inject
|
|||||||
class FollowersContentRepository @ExperimentalPagingApi
|
class FollowersContentRepository @ExperimentalPagingApi
|
||||||
@Inject constructor(
|
@Inject constructor(
|
||||||
private val api: PixelfedAPI,
|
private val api: PixelfedAPI,
|
||||||
private val accessToken: String,
|
|
||||||
private val accountId: String,
|
private val accountId: String,
|
||||||
private val following: Boolean,
|
private val following: Boolean,
|
||||||
): UncachedContentRepository<Account> {
|
): UncachedContentRepository<Account> {
|
||||||
@ -25,7 +24,7 @@ class FollowersContentRepository @ExperimentalPagingApi
|
|||||||
pageSize = NETWORK_PAGE_SIZE,
|
pageSize = NETWORK_PAGE_SIZE,
|
||||||
enablePlaceholders = false),
|
enablePlaceholders = false),
|
||||||
pagingSourceFactory = {
|
pagingSourceFactory = {
|
||||||
FollowersPagingSource(api, accessToken, accountId, following)
|
FollowersPagingSource(api, accountId, following)
|
||||||
}
|
}
|
||||||
).flow
|
).flow
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,9 @@ import com.h.pixeldroid.utils.api.PixelfedAPI
|
|||||||
import com.h.pixeldroid.utils.api.objects.Account
|
import com.h.pixeldroid.utils.api.objects.Account
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.math.BigInteger
|
|
||||||
|
|
||||||
class FollowersPagingSource(
|
class FollowersPagingSource(
|
||||||
private val api: PixelfedAPI,
|
private val api: PixelfedAPI,
|
||||||
private val accessToken: String,
|
|
||||||
private val accountId: String,
|
private val accountId: String,
|
||||||
private val following: Boolean
|
private val following: Boolean
|
||||||
) : PagingSource<String, Account>() {
|
) : PagingSource<String, Account>() {
|
||||||
@ -22,17 +20,19 @@ class FollowersPagingSource(
|
|||||||
// Laravel's paging mechanism, while Mastodon uses the Link header for pagination.
|
// Laravel's paging mechanism, while Mastodon uses the Link header for pagination.
|
||||||
// No need to know which is which, they should ignore the non-relevant argument
|
// No need to know which is which, they should ignore the non-relevant argument
|
||||||
if(following) {
|
if(following) {
|
||||||
api.followers(account_id = accountId,
|
api.followers(
|
||||||
authorization = "Bearer $accessToken",
|
account_id = accountId,
|
||||||
|
max_id = position,
|
||||||
limit = params.loadSize,
|
limit = params.loadSize,
|
||||||
page = position,
|
page = position
|
||||||
max_id = position)
|
)
|
||||||
} else {
|
} else {
|
||||||
api.following(account_id = accountId,
|
api.following(
|
||||||
authorization = "Bearer $accessToken",
|
account_id = accountId,
|
||||||
|
max_id = position,
|
||||||
limit = params.loadSize,
|
limit = params.loadSize,
|
||||||
page = position,
|
page = position
|
||||||
max_id = position)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val accounts = if(response.isSuccessful){
|
val accounts = if(response.isSuccessful){
|
||||||
|
@ -13,7 +13,6 @@ import javax.inject.Inject
|
|||||||
class ProfileContentRepository @ExperimentalPagingApi
|
class ProfileContentRepository @ExperimentalPagingApi
|
||||||
@Inject constructor(
|
@Inject constructor(
|
||||||
private val api: PixelfedAPI,
|
private val api: PixelfedAPI,
|
||||||
private val accessToken: String,
|
|
||||||
private val accountId: String
|
private val accountId: String
|
||||||
) : UncachedContentRepository<Status> {
|
) : UncachedContentRepository<Status> {
|
||||||
override fun getStream(): Flow<PagingData<Status>> {
|
override fun getStream(): Flow<PagingData<Status>> {
|
||||||
@ -23,7 +22,7 @@ class ProfileContentRepository @ExperimentalPagingApi
|
|||||||
pageSize = NETWORK_PAGE_SIZE,
|
pageSize = NETWORK_PAGE_SIZE,
|
||||||
enablePlaceholders = false),
|
enablePlaceholders = false),
|
||||||
pagingSourceFactory = {
|
pagingSourceFactory = {
|
||||||
ProfilePagingSource(api, accessToken, accountId)
|
ProfilePagingSource(api, accountId)
|
||||||
}
|
}
|
||||||
).flow
|
).flow
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,15 @@ import java.io.IOException
|
|||||||
|
|
||||||
class ProfilePagingSource(
|
class ProfilePagingSource(
|
||||||
private val api: PixelfedAPI,
|
private val api: PixelfedAPI,
|
||||||
private val accessToken: String,
|
|
||||||
private val accountId: String
|
private val accountId: String
|
||||||
) : PagingSource<String, Status>() {
|
) : PagingSource<String, Status>() {
|
||||||
override suspend fun load(params: LoadParams<String>): LoadResult<String, Status> {
|
override suspend fun load(params: LoadParams<String>): LoadResult<String, Status> {
|
||||||
val position = params.key
|
val position = params.key
|
||||||
return try {
|
return try {
|
||||||
val posts = api.accountPosts("Bearer $accessToken",
|
val posts = api.accountPosts(
|
||||||
account_id = accountId,
|
account_id = accountId,
|
||||||
max_id = position,
|
max_id = position,
|
||||||
limit = params.loadSize
|
limit = params.loadSize
|
||||||
)
|
)
|
||||||
|
|
||||||
LoadResult.Page(
|
LoadResult.Page(
|
||||||
|
@ -41,7 +41,6 @@ class SearchAccountFragment : UncachedFeedFragment<Account>() {
|
|||||||
SearchContentRepository<Account>(
|
SearchContentRepository<Account>(
|
||||||
apiHolder.setDomainToCurrentUser(db),
|
apiHolder.setDomainToCurrentUser(db),
|
||||||
Results.SearchType.accounts,
|
Results.SearchType.accounts,
|
||||||
db.userDao().getActiveUser()!!.accessToken,
|
|
||||||
query
|
query
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -22,7 +22,6 @@ class SearchContentRepository<T: FeedContent> @ExperimentalPagingApi
|
|||||||
@Inject constructor(
|
@Inject constructor(
|
||||||
private val api: PixelfedAPI,
|
private val api: PixelfedAPI,
|
||||||
private val type: Results.SearchType,
|
private val type: Results.SearchType,
|
||||||
private val accessToken: String,
|
|
||||||
private val query: String,
|
private val query: String,
|
||||||
): UncachedContentRepository<T> {
|
): UncachedContentRepository<T> {
|
||||||
override fun getStream(): Flow<PagingData<T>> {
|
override fun getStream(): Flow<PagingData<T>> {
|
||||||
@ -32,7 +31,7 @@ class SearchContentRepository<T: FeedContent> @ExperimentalPagingApi
|
|||||||
pageSize = NETWORK_PAGE_SIZE,
|
pageSize = NETWORK_PAGE_SIZE,
|
||||||
enablePlaceholders = false),
|
enablePlaceholders = false),
|
||||||
pagingSourceFactory = {
|
pagingSourceFactory = {
|
||||||
SearchPagingSource<T>(api, query, type, accessToken)
|
SearchPagingSource<T>(api, query, type)
|
||||||
}
|
}
|
||||||
).flow
|
).flow
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@ class SearchHashtagFragment : UncachedFeedFragment<Tag>() {
|
|||||||
SearchContentRepository<Tag>(
|
SearchContentRepository<Tag>(
|
||||||
apiHolder.setDomainToCurrentUser(db),
|
apiHolder.setDomainToCurrentUser(db),
|
||||||
Results.SearchType.hashtags,
|
Results.SearchType.hashtags,
|
||||||
db.userDao().getActiveUser()!!.accessToken,
|
|
||||||
query
|
query
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -15,16 +15,16 @@ class SearchPagingSource<T: FeedContent>(
|
|||||||
private val api: PixelfedAPI,
|
private val api: PixelfedAPI,
|
||||||
private val query: String,
|
private val query: String,
|
||||||
private val type: Results.SearchType,
|
private val type: Results.SearchType,
|
||||||
private val accessToken: String,
|
|
||||||
) : PagingSource<Int, T>() {
|
) : PagingSource<Int, T>() {
|
||||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, T> {
|
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, T> {
|
||||||
val position = params.key
|
val position = params.key
|
||||||
return try {
|
return try {
|
||||||
val response = api.search(authorization = "Bearer $accessToken",
|
val response = api.search(
|
||||||
offset = position?.toString(),
|
|
||||||
q = query,
|
|
||||||
type = type,
|
type = type,
|
||||||
limit = params.loadSize.toString())
|
q = query,
|
||||||
|
limit = params.loadSize.toString(),
|
||||||
|
offset = position?.toString()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
@ -45,7 +45,6 @@ class SearchPostsFragment : UncachedFeedFragment<Status>() {
|
|||||||
SearchContentRepository<Status>(
|
SearchContentRepository<Status>(
|
||||||
apiHolder.setDomainToCurrentUser(db),
|
apiHolder.setDomainToCurrentUser(db),
|
||||||
Results.SearchType.statuses,
|
Results.SearchType.statuses,
|
||||||
db.userDao().getActiveUser()!!.accessToken,
|
|
||||||
query
|
query
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -80,7 +79,7 @@ class SearchPostsFragment : UncachedFeedFragment<Status>() {
|
|||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
val uiModel = getItem(position) as Status
|
val uiModel = getItem(position) as Status
|
||||||
uiModel.let {
|
uiModel.let {
|
||||||
(holder as StatusViewHolder).bind(it, apiHolder.setDomainToCurrentUser(db), db, lifecycleScope, displayDimensionsInPx)
|
(holder as StatusViewHolder).bind(it, apiHolder, db, lifecycleScope, displayDimensionsInPx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,6 @@ import java.io.IOException
|
|||||||
|
|
||||||
class ProfileActivity : BaseActivity() {
|
class ProfileActivity : BaseActivity() {
|
||||||
|
|
||||||
private lateinit var pixelfedAPI : PixelfedAPI
|
|
||||||
private lateinit var accessToken : String
|
|
||||||
private lateinit var domain : String
|
private lateinit var domain : String
|
||||||
private lateinit var accountId : String
|
private lateinit var accountId : String
|
||||||
private lateinit var binding: ActivityProfileBinding
|
private lateinit var binding: ActivityProfileBinding
|
||||||
@ -66,8 +64,6 @@ class ProfileActivity : BaseActivity() {
|
|||||||
user = db.userDao().getActiveUser()
|
user = db.userDao().getActiveUser()
|
||||||
|
|
||||||
domain = user?.instance_uri.orEmpty()
|
domain = user?.instance_uri.orEmpty()
|
||||||
pixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
|
||||||
accessToken = user?.accessToken.orEmpty()
|
|
||||||
|
|
||||||
// Set profile according to given account
|
// Set profile according to given account
|
||||||
val account = intent.getSerializableExtra(Account.ACCOUNT_TAG) as Account?
|
val account = intent.getSerializableExtra(Account.ACCOUNT_TAG) as Account?
|
||||||
@ -77,9 +73,8 @@ class ProfileActivity : BaseActivity() {
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
viewModel = ViewModelProvider(this, ProfileViewModelFactory(
|
viewModel = ViewModelProvider(this, ProfileViewModelFactory(
|
||||||
ProfileContentRepository(
|
ProfileContentRepository(
|
||||||
apiHolder.setDomainToCurrentUser(db),
|
apiHolder.setDomainToCurrentUser(db),
|
||||||
db.userDao().getActiveUser()!!.accessToken,
|
accountId
|
||||||
accountId
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
).get(FeedViewModel::class.java) as FeedViewModel<Status>
|
).get(FeedViewModel::class.java) as FeedViewModel<Status>
|
||||||
@ -124,8 +119,9 @@ class ProfileActivity : BaseActivity() {
|
|||||||
setViews(account)
|
setViews(account)
|
||||||
} else {
|
} else {
|
||||||
lifecycleScope.launchWhenResumed {
|
lifecycleScope.launchWhenResumed {
|
||||||
|
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
val myAccount: Account = try {
|
val myAccount: Account = try {
|
||||||
pixelfedAPI.verifyCredentials("Bearer $accessToken")
|
api.verifyCredentials()
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
Log.e("ProfileActivity:", exception.toString())
|
Log.e("ProfileActivity:", exception.toString())
|
||||||
return@launchWhenResumed showError()
|
return@launchWhenResumed showError()
|
||||||
@ -162,9 +158,10 @@ class ProfileActivity : BaseActivity() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
binding.descriptionTextView.text = parseHTMLText(
|
binding.descriptionTextView.text = parseHTMLText(
|
||||||
account.note ?: "", emptyList(), pixelfedAPI,
|
account.note ?: "", emptyList(), apiHolder,
|
||||||
applicationContext, "Bearer $accessToken",
|
applicationContext,
|
||||||
lifecycleScope
|
lifecycleScope,
|
||||||
|
db
|
||||||
)
|
)
|
||||||
|
|
||||||
val displayName = account.getDisplayName()
|
val displayName = account.getDisplayName()
|
||||||
@ -235,8 +232,9 @@ class ProfileActivity : BaseActivity() {
|
|||||||
// Get relationship between the two users (credential and this) and set followButton accordingly
|
// Get relationship between the two users (credential and this) and set followButton accordingly
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
try {
|
try {
|
||||||
val relationship = pixelfedAPI.checkRelationships(
|
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
"Bearer $accessToken", listOf(account.id.orEmpty())
|
val relationship = api.checkRelationships(
|
||||||
|
listOf(account.id.orEmpty())
|
||||||
).firstOrNull()
|
).firstOrNull()
|
||||||
|
|
||||||
if(relationship != null){
|
if(relationship != null){
|
||||||
@ -268,7 +266,8 @@ class ProfileActivity : BaseActivity() {
|
|||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
lifecycleScope.launchWhenResumed {
|
lifecycleScope.launchWhenResumed {
|
||||||
try {
|
try {
|
||||||
val rel = pixelfedAPI.follow(account.id.orEmpty(), "Bearer $accessToken")
|
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
val rel = api.follow(account.id.orEmpty())
|
||||||
if(rel.following == true) setOnClickUnfollow(account, rel.requested == true)
|
if(rel.following == true) setOnClickUnfollow(account, rel.requested == true)
|
||||||
else setOnClickFollow(account)
|
else setOnClickFollow(account)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
@ -298,7 +297,8 @@ class ProfileActivity : BaseActivity() {
|
|||||||
fun unfollow() {
|
fun unfollow() {
|
||||||
lifecycleScope.launchWhenResumed {
|
lifecycleScope.launchWhenResumed {
|
||||||
try {
|
try {
|
||||||
val rel = pixelfedAPI.unfollow(account.id.orEmpty(), "Bearer $accessToken")
|
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
val rel = api.unfollow(account.id.orEmpty())
|
||||||
if(rel.following == false && rel.requested == false) setOnClickFollow(account)
|
if(rel.following == false && rel.requested == false) setOnClickFollow(account)
|
||||||
else setOnClickUnfollow(account, rel.requested == true)
|
else setOnClickUnfollow(account, rel.requested == true)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
|
@ -20,12 +20,6 @@ import com.h.pixeldroid.posts.PostActivity
|
|||||||
import com.h.pixeldroid.utils.BaseFragment
|
import com.h.pixeldroid.utils.BaseFragment
|
||||||
import com.h.pixeldroid.utils.ImageConverter
|
import com.h.pixeldroid.utils.ImageConverter
|
||||||
import com.h.pixeldroid.utils.bindingLifecycleAware
|
import com.h.pixeldroid.utils.bindingLifecycleAware
|
||||||
import com.mikepenz.iconics.IconicsColor
|
|
||||||
import com.mikepenz.iconics.IconicsDrawable
|
|
||||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
|
||||||
import com.mikepenz.iconics.utils.color
|
|
||||||
import com.mikepenz.iconics.utils.paddingDp
|
|
||||||
import com.mikepenz.iconics.utils.sizeDp
|
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
@ -37,7 +31,6 @@ class SearchDiscoverFragment : BaseFragment() {
|
|||||||
private lateinit var api: PixelfedAPI
|
private lateinit var api: PixelfedAPI
|
||||||
private lateinit var recycler : RecyclerView
|
private lateinit var recycler : RecyclerView
|
||||||
private lateinit var adapter : DiscoverRecyclerViewAdapter
|
private lateinit var adapter : DiscoverRecyclerViewAdapter
|
||||||
private lateinit var accessToken: String
|
|
||||||
|
|
||||||
var binding: FragmentSearchBinding by bindingLifecycleAware()
|
var binding: FragmentSearchBinding by bindingLifecycleAware()
|
||||||
|
|
||||||
@ -68,8 +61,6 @@ class SearchDiscoverFragment : BaseFragment() {
|
|||||||
|
|
||||||
api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
|
||||||
accessToken = db.userDao().getActiveUser()?.accessToken.orEmpty()
|
|
||||||
|
|
||||||
getDiscover()
|
getDiscover()
|
||||||
|
|
||||||
binding.discoverRefreshLayout.setOnRefreshListener {
|
binding.discoverRefreshLayout.setOnRefreshListener {
|
||||||
@ -93,7 +84,7 @@ class SearchDiscoverFragment : BaseFragment() {
|
|||||||
private fun getDiscover() {
|
private fun getDiscover() {
|
||||||
lifecycleScope.launchWhenCreated {
|
lifecycleScope.launchWhenCreated {
|
||||||
try {
|
try {
|
||||||
val discoverPosts = api.discover("Bearer $accessToken")
|
val discoverPosts = api.discover()
|
||||||
adapter.addPosts(discoverPosts.posts)
|
adapter.addPosts(discoverPosts.posts)
|
||||||
showError(show = false)
|
showError(show = false)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
|
@ -74,31 +74,23 @@ interface PixelfedAPI {
|
|||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("/api/v1/accounts/{id}/follow")
|
@POST("/api/v1/accounts/{id}/follow")
|
||||||
suspend fun follow(
|
suspend fun follow(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
|
||||||
@Path("id") statusId: String,
|
@Path("id") statusId: String,
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Field("reblogs") reblogs : Boolean = true
|
@Field("reblogs") reblogs : Boolean = true
|
||||||
) : Relationship
|
) : Relationship
|
||||||
|
|
||||||
@POST("/api/v1/accounts/{id}/unfollow")
|
@POST("/api/v1/accounts/{id}/unfollow")
|
||||||
suspend fun unfollow(
|
suspend fun unfollow(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
|
||||||
@Path("id") statusId: String,
|
@Path("id") statusId: String,
|
||||||
@Header("Authorization") authorization: String
|
|
||||||
) : Relationship
|
) : Relationship
|
||||||
|
|
||||||
@POST("api/v1/statuses/{id}/favourite")
|
@POST("api/v1/statuses/{id}/favourite")
|
||||||
suspend fun likePost(
|
suspend fun likePost(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Path("id") statusId: String
|
@Path("id") statusId: String
|
||||||
|
|
||||||
) : Status
|
) : Status
|
||||||
|
|
||||||
@POST("/api/v1/statuses/{id}/unfavourite")
|
@POST("/api/v1/statuses/{id}/unfavourite")
|
||||||
suspend fun unlikePost(
|
suspend fun unlikePost(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Path("id") statusId: String
|
@Path("id") statusId: String
|
||||||
) : Status
|
) : Status
|
||||||
|
|
||||||
@ -106,8 +98,6 @@ interface PixelfedAPI {
|
|||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("/api/v1/statuses")
|
@POST("/api/v1/statuses")
|
||||||
suspend fun postStatus(
|
suspend fun postStatus(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Field("status") statusText : String,
|
@Field("status") statusText : String,
|
||||||
@Field("in_reply_to_id") in_reply_to_id : String? = null,
|
@Field("in_reply_to_id") in_reply_to_id : String? = null,
|
||||||
@Field("media_ids[]") media_ids : List<String> = emptyList(),
|
@Field("media_ids[]") media_ids : List<String> = emptyList(),
|
||||||
@ -124,14 +114,12 @@ interface PixelfedAPI {
|
|||||||
|
|
||||||
@DELETE("/api/v1/statuses/{id}")
|
@DELETE("/api/v1/statuses/{id}")
|
||||||
suspend fun deleteStatus(
|
suspend fun deleteStatus(
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Path("id") statusId: String
|
@Path("id") statusId: String
|
||||||
)
|
)
|
||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("/api/v1/statuses/{id}/reblog")
|
@POST("/api/v1/statuses/{id}/reblog")
|
||||||
suspend fun reblogStatus(
|
suspend fun reblogStatus(
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Path("id") statusId: String,
|
@Path("id") statusId: String,
|
||||||
@Field("visibility") visibility: String? = null
|
@Field("visibility") visibility: String? = null
|
||||||
) : Status
|
) : Status
|
||||||
@ -139,14 +127,12 @@ interface PixelfedAPI {
|
|||||||
@POST("/api/v1/statuses/{id}/unreblog")
|
@POST("/api/v1/statuses/{id}/unreblog")
|
||||||
suspend fun undoReblogStatus(
|
suspend fun undoReblogStatus(
|
||||||
@Path("id") statusId: String,
|
@Path("id") statusId: String,
|
||||||
@Header("Authorization") authorization: String
|
|
||||||
) : Status
|
) : Status
|
||||||
|
|
||||||
//Used in our case to retrieve comments for a given status
|
//Used in our case to retrieve comments for a given status
|
||||||
@GET("/api/v1/statuses/{id}/context")
|
@GET("/api/v1/statuses/{id}/context")
|
||||||
suspend fun statusComments(
|
suspend fun statusComments(
|
||||||
@Path("id") statusId: String,
|
@Path("id") statusId: String,
|
||||||
@Header("Authorization") authorization: String? = null
|
|
||||||
) : Context
|
) : Context
|
||||||
|
|
||||||
@GET("/api/v1/timelines/public")
|
@GET("/api/v1/timelines/public")
|
||||||
@ -160,8 +146,6 @@ interface PixelfedAPI {
|
|||||||
|
|
||||||
@GET("/api/v1/timelines/home")
|
@GET("/api/v1/timelines/home")
|
||||||
suspend fun timelineHome(
|
suspend fun timelineHome(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Query("max_id") max_id: String? = null,
|
@Query("max_id") max_id: String? = null,
|
||||||
@Query("since_id") since_id: String? = null,
|
@Query("since_id") since_id: String? = null,
|
||||||
@Query("min_id") min_id: String? = null,
|
@Query("min_id") min_id: String? = null,
|
||||||
@ -171,8 +155,6 @@ interface PixelfedAPI {
|
|||||||
|
|
||||||
@GET("/api/v2/search")
|
@GET("/api/v2/search")
|
||||||
suspend fun search(
|
suspend fun search(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Query("account_id") account_id: String? = null,
|
@Query("account_id") account_id: String? = null,
|
||||||
@Query("max_id") max_id: String? = null,
|
@Query("max_id") max_id: String? = null,
|
||||||
@Query("min_id") min_id: String? = null,
|
@Query("min_id") min_id: String? = null,
|
||||||
@ -187,8 +169,6 @@ interface PixelfedAPI {
|
|||||||
|
|
||||||
@GET("/api/v1/notifications")
|
@GET("/api/v1/notifications")
|
||||||
suspend fun notifications(
|
suspend fun notifications(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Query("max_id") max_id: String? = null,
|
@Query("max_id") max_id: String? = null,
|
||||||
@Query("since_id") since_id: String? = null,
|
@Query("since_id") since_id: String? = null,
|
||||||
@Query("min_id") min_id: String? = null,
|
@Query("min_id") min_id: String? = null,
|
||||||
@ -200,13 +180,12 @@ interface PixelfedAPI {
|
|||||||
@GET("/api/v1/accounts/verify_credentials")
|
@GET("/api/v1/accounts/verify_credentials")
|
||||||
suspend fun verifyCredentials(
|
suspend fun verifyCredentials(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
//The authorization header needs to be of the form "Bearer <token>"
|
||||||
@Header("Authorization") authorization: String
|
@Header("Authorization") authorization: String? = null
|
||||||
): Account
|
): Account
|
||||||
|
|
||||||
|
|
||||||
@GET("/api/v1/accounts/{id}/statuses")
|
@GET("/api/v1/accounts/{id}/statuses")
|
||||||
suspend fun accountPosts(
|
suspend fun accountPosts(
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Path("id") account_id: String,
|
@Path("id") account_id: String,
|
||||||
@Query("min_id") min_id: String? = null,
|
@Query("min_id") min_id: String? = null,
|
||||||
@Query("max_id") max_id: String?,
|
@Query("max_id") max_id: String?,
|
||||||
@ -215,14 +194,12 @@ interface PixelfedAPI {
|
|||||||
|
|
||||||
@GET("/api/v1/accounts/relationships")
|
@GET("/api/v1/accounts/relationships")
|
||||||
suspend fun checkRelationships(
|
suspend fun checkRelationships(
|
||||||
@Header("Authorization") authorization : String,
|
|
||||||
@Query("id[]") account_ids : List<String>
|
@Query("id[]") account_ids : List<String>
|
||||||
) : List<Relationship>
|
) : List<Relationship>
|
||||||
|
|
||||||
@GET("/api/v1/accounts/{id}/followers")
|
@GET("/api/v1/accounts/{id}/followers")
|
||||||
suspend fun followers(
|
suspend fun followers(
|
||||||
@Path("id") account_id: String,
|
@Path("id") account_id: String,
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Query("max_id") max_id: String? = null,
|
@Query("max_id") max_id: String? = null,
|
||||||
@Query("since_id") since_id: String? = null,
|
@Query("since_id") since_id: String? = null,
|
||||||
@Query("limit") limit: Number? = null,
|
@Query("limit") limit: Number? = null,
|
||||||
@ -232,7 +209,6 @@ interface PixelfedAPI {
|
|||||||
@GET("/api/v1/accounts/{id}/following")
|
@GET("/api/v1/accounts/{id}/following")
|
||||||
suspend fun following(
|
suspend fun following(
|
||||||
@Path("id") account_id: String,
|
@Path("id") account_id: String,
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Query("max_id") max_id: String? = null,
|
@Query("max_id") max_id: String? = null,
|
||||||
@Query("since_id") since_id: String? = null,
|
@Query("since_id") since_id: String? = null,
|
||||||
@Query("limit") limit: Number? = 40,
|
@Query("limit") limit: Number? = 40,
|
||||||
@ -241,36 +217,29 @@ interface PixelfedAPI {
|
|||||||
|
|
||||||
@GET("/api/v1/accounts/{id}")
|
@GET("/api/v1/accounts/{id}")
|
||||||
suspend fun getAccount(
|
suspend fun getAccount(
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Path("id") accountId : String
|
@Path("id") accountId : String
|
||||||
): Account
|
): Account
|
||||||
|
|
||||||
@GET("/api/v1/statuses/{id}")
|
@GET("/api/v1/statuses/{id}")
|
||||||
suspend fun getStatus(
|
suspend fun getStatus(
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Path("id") accountId : String
|
@Path("id") accountId : String
|
||||||
): Status
|
): Status
|
||||||
|
|
||||||
@Multipart
|
@Multipart
|
||||||
@POST("/api/v1/media")
|
@POST("/api/v1/media")
|
||||||
fun mediaUpload(
|
fun mediaUpload(
|
||||||
//The authorization header needs to be of the form "Bearer <token>"
|
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Part description: MultipartBody.Part? = null,
|
@Part description: MultipartBody.Part? = null,
|
||||||
@Part file: MultipartBody.Part
|
@Part file: MultipartBody.Part
|
||||||
): Observable<Attachment>
|
): Observable<Attachment>
|
||||||
|
|
||||||
// get discover
|
// get discover
|
||||||
@GET("/api/v2/discover/posts")
|
@GET("/api/v2/discover/posts")
|
||||||
suspend fun discover(
|
suspend fun discover() : DiscoverPosts
|
||||||
@Header("Authorization") authorization: String
|
|
||||||
) : DiscoverPosts
|
|
||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("/api/v1/reports")
|
@POST("/api/v1/reports")
|
||||||
@JvmSuppressWildcards
|
@JvmSuppressWildcards
|
||||||
suspend fun report(
|
suspend fun report(
|
||||||
@Header("Authorization") authorization: String,
|
|
||||||
@Field("account_id") account_id: String,
|
@Field("account_id") account_id: String,
|
||||||
@Field("status_ids") status_ids: List<Status>,
|
@Field("status_ids") status_ids: List<Status>,
|
||||||
@Field("comment") comment: String,
|
@Field("comment") comment: String,
|
||||||
|
@ -6,13 +6,7 @@ import android.util.Log
|
|||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import com.h.pixeldroid.profile.ProfileActivity
|
import com.h.pixeldroid.profile.ProfileActivity
|
||||||
import com.h.pixeldroid.utils.api.PixelfedAPI
|
import com.h.pixeldroid.utils.api.PixelfedAPI
|
||||||
import kotlinx.coroutines.coroutineScope
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.coroutines.supervisorScope
|
|
||||||
import retrofit2.Call
|
|
||||||
import retrofit2.Callback
|
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import retrofit2.Response
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
@ -57,9 +51,9 @@ data class Account(
|
|||||||
/**
|
/**
|
||||||
* @brief Opens an activity of the profile with the given id
|
* @brief Opens an activity of the profile with the given id
|
||||||
*/
|
*/
|
||||||
suspend fun openAccountFromId(id: String, api : PixelfedAPI, context: Context, credential: String) {
|
suspend fun openAccountFromId(id: String, api : PixelfedAPI, context: Context) {
|
||||||
val account = try {
|
val account = try {
|
||||||
api.getAccount(credential, id)
|
api.getAccount(id)
|
||||||
} catch (exception: IOException) {
|
} catch (exception: IOException) {
|
||||||
Log.e("GET ACCOUNT ERROR", exception.toString())
|
Log.e("GET ACCOUNT ERROR", exception.toString())
|
||||||
return
|
return
|
||||||
|
@ -8,8 +8,8 @@ interface UserDao {
|
|||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
fun insertUser(user: UserDatabaseEntity)
|
fun insertUser(user: UserDatabaseEntity)
|
||||||
|
|
||||||
@Query("UPDATE users SET accessToken = :accessToken WHERE user_id = :id and instance_uri = :instance_uri")
|
@Query("UPDATE users SET accessToken = :accessToken, refreshToken = :refreshToken WHERE user_id = :id and instance_uri = :instance_uri")
|
||||||
fun updateAccessToken(accessToken: String, id: String, instance_uri: String)
|
fun updateAccessToken(accessToken: String, refreshToken: String, id: String, instance_uri: String)
|
||||||
|
|
||||||
@Query("SELECT * FROM users")
|
@Query("SELECT * FROM users")
|
||||||
fun getAll(): List<UserDatabaseEntity>
|
fun getAll(): List<UserDatabaseEntity>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.h.pixeldroid.utils.di
|
package com.h.pixeldroid.utils.di
|
||||||
|
|
||||||
import com.h.pixeldroid.utils.api.PixelfedAPI
|
import com.h.pixeldroid.utils.api.PixelfedAPI
|
||||||
|
import com.h.pixeldroid.utils.api.objects.Token
|
||||||
import com.h.pixeldroid.utils.db.AppDatabase
|
import com.h.pixeldroid.utils.db.AppDatabase
|
||||||
import com.h.pixeldroid.utils.db.entities.UserDatabaseEntity
|
import com.h.pixeldroid.utils.db.entities.UserDatabaseEntity
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
@ -22,17 +23,30 @@ class APIModule{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TokenAuthenticator(val user: UserDatabaseEntity, val db: AppDatabase) : Authenticator {
|
class TokenAuthenticator(val user: UserDatabaseEntity, val db: AppDatabase, val apiHolder: PixelfedAPIHolder) : Authenticator {
|
||||||
|
|
||||||
private val pixelfedAPI = PixelfedAPI.createFromUrl(user.instance_uri)
|
private val pixelfedAPI = PixelfedAPI.createFromUrl(user.instance_uri)
|
||||||
|
|
||||||
|
// Returns the number of tries for this response by walking through the priorResponses
|
||||||
|
private fun Response.responseCount(): Int {
|
||||||
|
var result = 1
|
||||||
|
var response: Response? = priorResponse
|
||||||
|
|
||||||
|
while (response != null) {
|
||||||
|
result++
|
||||||
|
response = response.priorResponse
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun authenticate(route: Route?, response: Response): Request? {
|
override fun authenticate(route: Route?, response: Response): Request? {
|
||||||
|
|
||||||
if (response.request.header("Authorization") != null) {
|
if (response.responseCount() > 3) {
|
||||||
return null // Give up, we've already failed to authenticate.
|
return null // Give up, we've already failed to authenticate a couple times
|
||||||
}
|
}
|
||||||
// Refresh the access_token using a synchronous api request
|
// Refresh the access_token using a synchronous api request
|
||||||
val newAccessToken: String? = try {
|
val newAccessToken: Token = try {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
pixelfedAPI.obtainToken(
|
pixelfedAPI.obtainToken(
|
||||||
scope = "",
|
scope = "",
|
||||||
@ -40,19 +54,25 @@ class TokenAuthenticator(val user: UserDatabaseEntity, val db: AppDatabase) : Au
|
|||||||
refresh_token = user.refreshToken,
|
refresh_token = user.refreshToken,
|
||||||
client_id = user.clientId,
|
client_id = user.clientId,
|
||||||
client_secret = user.clientSecret
|
client_secret = user.clientSecret
|
||||||
).access_token
|
)
|
||||||
}
|
}
|
||||||
}catch (e: Exception){
|
}catch (e: Exception){
|
||||||
null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newAccessToken != null) {
|
// Save the new access token and refresh token
|
||||||
db.userDao().updateAccessToken(newAccessToken, user.user_id, user.instance_uri)
|
if (newAccessToken.access_token != null && newAccessToken.refresh_token != null) {
|
||||||
|
db.userDao().updateAccessToken(
|
||||||
|
newAccessToken.access_token,
|
||||||
|
newAccessToken.refresh_token,
|
||||||
|
user.user_id, user.instance_uri
|
||||||
|
)
|
||||||
|
apiHolder.setDomainToCurrentUser(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new header to rejected request and retry it
|
// Add new header to rejected request and retry it
|
||||||
return response.request.newBuilder()
|
return response.request.newBuilder()
|
||||||
.header("Authorization", "Bearer ${newAccessToken.orEmpty()}")
|
.header("Authorization", "Bearer ${newAccessToken.access_token.orEmpty()}")
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,6 +81,7 @@ class PixelfedAPIHolder(db: AppDatabase?){
|
|||||||
private val intermediate: Retrofit.Builder = Retrofit.Builder()
|
private val intermediate: Retrofit.Builder = Retrofit.Builder()
|
||||||
.addConverterFactory(GsonConverterFactory.create())
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
|
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
|
||||||
|
|
||||||
var api: PixelfedAPI? =
|
var api: PixelfedAPI? =
|
||||||
db?.userDao()?.getActiveUser()?.let {
|
db?.userDao()?.getActiveUser()?.let {
|
||||||
setDomainToCurrentUser(db, it)
|
setDomainToCurrentUser(db, it)
|
||||||
@ -73,10 +94,11 @@ class PixelfedAPIHolder(db: AppDatabase?){
|
|||||||
val newAPI = intermediate
|
val newAPI = intermediate
|
||||||
.baseUrl(user.instance_uri)
|
.baseUrl(user.instance_uri)
|
||||||
.client(
|
.client(
|
||||||
OkHttpClient().newBuilder().authenticator(TokenAuthenticator(user, db))
|
OkHttpClient().newBuilder().authenticator(TokenAuthenticator(user, db, this))
|
||||||
.addInterceptor {
|
.addInterceptor {
|
||||||
it.request().newBuilder().run {
|
it.request().newBuilder().run {
|
||||||
header("Accept", "application/json")
|
header("Accept", "application/json")
|
||||||
|
header("Authorization", "Bearer ${user.accessToken}")
|
||||||
it.proceed(build())
|
it.proceed(build())
|
||||||
}
|
}
|
||||||
}.build()
|
}.build()
|
||||||
|
@ -4,7 +4,6 @@ import com.github.tomakehurst.wiremock.client.WireMock.*
|
|||||||
import com.github.tomakehurst.wiremock.junit.WireMockRule
|
import com.github.tomakehurst.wiremock.junit.WireMockRule
|
||||||
import com.h.pixeldroid.utils.api.PixelfedAPI
|
import com.h.pixeldroid.utils.api.PixelfedAPI
|
||||||
import com.h.pixeldroid.utils.api.objects.*
|
import com.h.pixeldroid.utils.api.objects.*
|
||||||
import io.reactivex.Single
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
@ -91,7 +90,7 @@ class APIUnitTest {
|
|||||||
statuses = PixelfedAPI.createFromUrl("http://localhost:8089")
|
statuses = PixelfedAPI.createFromUrl("http://localhost:8089")
|
||||||
.timelinePublic(null, null, null, null, null)
|
.timelinePublic(null, null, null, null, null)
|
||||||
statusesHome = PixelfedAPI.createFromUrl("http://localhost:8089")
|
statusesHome = PixelfedAPI.createFromUrl("http://localhost:8089")
|
||||||
.timelineHome("abc", null, null, null,null, null)
|
.timelineHome(null, null, null, null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user