Merge master

This commit is contained in:
Matthieu 2021-09-06 15:59:16 +02:00
commit 5115e3f428
22 changed files with 241 additions and 102 deletions

View File

@ -28,8 +28,8 @@ android {
applicationId "org.pixeldroid.app"
minSdkVersion 23
targetSdkVersion 30
versionCode 2
versionName "1.0.beta2"
versionCode 3
versionName "1.0.beta3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
@ -65,12 +65,12 @@ android {
localProperties.load(new FileInputStream(rootProject.file("local.properties")))
}
buildConfigField "String", "USER_ID", System.getenv("USER_ID") ?: localProperties['USER_ID'] ?: ""
buildConfigField "String", "INSTANCE_URI", System.getenv("INSTANCE_URI") ?: localProperties['INSTANCE_URI'] ?: ""
buildConfigField "String", "ACCESS_TOKEN", System.getenv("ACCESS_TOKEN") ?: localProperties['ACCESS_TOKEN'] ?: ""
buildConfigField "String", "REFRESH_TOKEN", System.getenv("REFRESH_TOKEN") ?: localProperties['REFRESH_TOKEN'] ?: ""
buildConfigField "String", "CLIENT_ID", System.getenv("CLIENT_ID") ?: localProperties['CLIENT_ID'] ?: ""
buildConfigField "String", "CLIENT_SECRET", System.getenv("CLIENT_SECRET") ?: localProperties['CLIENT_SECRET'] ?: ""
buildConfigField "String", "USER_ID", System.getenv("USER_ID") ?: localProperties['USER_ID'] ?: '""'
buildConfigField "String", "INSTANCE_URI", System.getenv("INSTANCE_URI") ?: localProperties['INSTANCE_URI'] ?: '""'
buildConfigField "String", "ACCESS_TOKEN", System.getenv("ACCESS_TOKEN") ?: localProperties['ACCESS_TOKEN'] ?: '""'
buildConfigField "String", "REFRESH_TOKEN", System.getenv("REFRESH_TOKEN") ?: localProperties['REFRESH_TOKEN'] ?: '""'
buildConfigField "String", "CLIENT_ID", System.getenv("CLIENT_ID") ?: localProperties['CLIENT_ID'] ?: '""'
buildConfigField "String", "CLIENT_SECRET", System.getenv("CLIENT_SECRET") ?: localProperties['CLIENT_SECRET'] ?: '""'
}
release {
minifyEnabled true
@ -126,8 +126,8 @@ dependencies {
implementation 'androidx.gridlayout:gridlayout:1.0.0'
implementation "androidx.activity:activity-ktx:1.3.1"
implementation 'androidx.fragment:fragment-ktx:1.3.6'
implementation "androidx.work:work-runtime-ktx:2.5.0"
implementation 'androidx.work:work-testing:2.5.0'
implementation "androidx.work:work-runtime-ktx:2.6.0"
implementation 'androidx.work:work-testing:2.6.0'
// Use the most recent version of CameraX
def cameraX_version = '1.0.1'
@ -137,7 +137,7 @@ dependencies {
implementation "androidx.camera:camera-lifecycle:$cameraX_version"
// CameraX View class
implementation 'androidx.camera:camera-view:1.0.0-alpha27'
implementation 'androidx.camera:camera-view:1.0.0-alpha28'
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
@ -189,10 +189,10 @@ dependencies {
implementation 'com.mikepenz:materialdrawer-nav:8.4.2'
//iconics
implementation 'com.mikepenz:iconics-core:5.3.0'
implementation "com.mikepenz:iconics-core:5.3.0"
implementation 'com.mikepenz:materialdrawer-iconics:8.4.2'
implementation 'com.mikepenz:iconics-views:5.3.0'
implementation 'com.mikepenz:google-material-typeface:4.0.0.1-kotlin@aar'
implementation "com.mikepenz:iconics-views:5.3.0"
implementation 'com.mikepenz:google-material-typeface:3.0.1.4.original-kotlin@aar'
implementation 'com.karumi:dexter:6.2.3'
@ -257,4 +257,4 @@ task jacocoTestReport(type: JacocoReport, dependsOn: ['connectedStagingAndroidTe
'jacoco/testStagingUnitTest.exec'
]))
}
}

View File

@ -13,12 +13,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice
import org.hamcrest.Matchers.allOf
import org.junit.*
import org.pixeldroid.app.testUtility.*
import org.pixeldroid.app.utils.db.AppDatabase
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.Timeout
import org.junit.runner.RunWith
@ -88,6 +85,7 @@ class DrawerMenuTest {
}
@Test
@Ignore
fun testDrawerLogoutButton() {
// Start the screen of your activity.
onView(withText(R.string.logout)).perform(click())
@ -130,7 +128,7 @@ class DrawerMenuTest {
onView(withText(followingText)).perform(click())
waitForView(R.id.account_entry_avatar)
onView(withText("@User 1")).check(matches(isDisplayed()))
onView(withText("User 2")).check(matches(isDisplayed()))
}
/*@Test

View File

@ -18,6 +18,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import androidx.activity.result.contract.ActivityResultContracts
import androidx.camera.core.*
import androidx.camera.core.ImageCapture.Metadata
import androidx.camera.lifecycle.ProcessCameraProvider
@ -47,9 +48,15 @@ import kotlin.properties.Delegates
// request. Where an app has multiple context for requesting permission,
// this can help differentiate the different contexts.
private const val REQUEST_CODE_PERMISSIONS = 10
private const val ANIMATION_FAST_MILLIS = 50L
private const val ANIMATION_SLOW_MILLIS = 100L
private val REQUIRED_PERMISSIONS = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE
)
/**
* Camera fragment
*/
@ -57,12 +64,8 @@ class CameraFragment : Fragment() {
private lateinit var container: ConstraintLayout
private lateinit var viewFinder: PreviewView
private val REQUIRED_PERMISSIONS = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE
)
private val PICK_IMAGE_REQUEST = 1
private val CAPTURE_IMAGE_REQUEST = 2
private val cameraLifecycleOwner = CameraLifecycleOwner()
private var displayId: Int = -1
private var lensFacing: Int = CameraSelector.LENS_FACING_BACK
@ -86,12 +89,10 @@ class CameraFragment : Fragment() {
REQUEST_CODE_PERMISSIONS
)
} else {
//Bind the viewfinder here, since when leaving the fragment it gets unbound
bindCameraUseCases()
// Build UI controls
updateCameraUi()
}
cameraLifecycleOwner.resume()
}
/**
* Check if all permission specified in the manifest have been granted
@ -145,6 +146,8 @@ class CameraFragment : Fragment() {
// Initialize our background executor
cameraExecutor = Executors.newSingleThreadExecutor()
bindCameraUseCases()
// Every time the orientation of device changes, update rotation for use cases
// Wait for the views to be properly laid out
@ -169,14 +172,12 @@ class CameraFragment : Fragment() {
}
/** Declare and bind preview, capture and analysis use cases */
private fun bindCameraUseCases(forceRebind: Boolean = false) {
private fun bindCameraUseCases() {
// Get screen metrics used to setup camera for full screen resolution
val metrics = DisplayMetrics().also { viewFinder.display?.getRealMetrics(it) }
Log.d(TAG, "Screen metrics: ${metrics.widthPixels} x ${metrics.heightPixels}")
val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
Log.d(TAG, "Preview aspect ratio: $screenAspectRatio")
val rotation = viewFinder.display?.rotation ?: 0
@ -188,48 +189,65 @@ class CameraFragment : Fragment() {
// CameraProvider
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
if (forceRebind || camera == null || preview == null || imageCapture == null || !cameraProvider.isBound(preview!!) || !cameraProvider.isBound(imageCapture!!)) {
// Preview
preview = Preview.Builder()
// We request aspect ratio but no resolution
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation
.setTargetRotation(rotation)
.build()
// Preview
preview = Preview.Builder()
// We request aspect ratio but no resolution
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation
.setTargetRotation(rotation)
.build()
// ImageCapture
imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
// We request aspect ratio but no resolution to match preview config, but letting
// CameraX optimize for whatever specific resolution best fits our use cases
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation, we will have to call this again if rotation changes
// during the lifecycle of this use case
.setTargetRotation(rotation)
.build()
// ImageCapture
imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
// We request aspect ratio but no resolution to match preview config, but letting
// CameraX optimize for whatever specific resolution best fits our use cases
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation, we will have to call this again if rotation changes
// during the lifecycle of this use case
.setTargetRotation(rotation)
.build()
// Must unbind the use-cases before rebinding them
cameraProvider.unbindAll()
// Must unbind the use-cases before rebinding them
cameraProvider.unbindAll()
try {
// A variable number of use-cases can be passed here -
// camera provides access to CameraControl & CameraInfo
camera = cameraProvider.bindToLifecycle(
cameraLifecycleOwner, cameraSelector, preview, imageCapture
)
try {
// A variable number of use-cases can be passed here -
// camera provides access to CameraControl & CameraInfo
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture
)
// Attach the viewfinder's surface provider to preview use case
preview?.setSurfaceProvider(viewFinder.surfaceProvider)
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
// Attach the viewfinder's surface provider to preview use case
preview?.setSurfaceProvider(viewFinder.surfaceProvider)
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
}, ContextCompat.getMainExecutor(requireContext()))
}
override fun onPause() {
super.onPause()
cameraLifecycleOwner.pause()
}
override fun onDestroy() {
super.onDestroy()
cameraLifecycleOwner.destroy()
}
override fun onStop() {
super.onStop()
cameraLifecycleOwner.stop()
}
override fun onStart() {
super.onStart()
cameraLifecycleOwner.start()
}
/**
* setTargetAspectRatio requires enum value of
* [androidx.camera.core.AspectRatio]. Currently it has values of 4:3 & 16:9.
@ -292,6 +310,25 @@ class CameraFragment : Fragment() {
setupUploadImage(controls)
}
private val uploadImageResultContract = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val data: Intent? = result.data
if (result.resultCode == Activity.RESULT_OK && data != null) {
val images: ArrayList<String> = ArrayList()
val clipData = data.clipData
if (clipData != null) {
val count = clipData.itemCount
for (i in 0 until count) {
val imageUri: String = clipData.getItemAt(i).uri.toString()
images.add(imageUri)
}
startAlbumCreation(images)
} else if (data.data != null) {
images.add(data.data!!.toString())
startAlbumCreation(images)
}
}
}
private fun setupUploadImage(controls: View) {
// Listener for button used to view the most recent photo
controls.findViewById<ImageButton>(R.id.photo_view_button)?.setOnClickListener {
@ -301,8 +338,8 @@ class CameraFragment : Fragment() {
addCategory(Intent.CATEGORY_OPENABLE)
putExtra(Intent.EXTRA_LOCAL_ONLY, true)
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
startActivityForResult(
Intent.createChooser(this, "Select a Picture"), PICK_IMAGE_REQUEST
uploadImageResultContract.launch(
Intent.createChooser(this, null)
)
}
}
@ -324,7 +361,7 @@ class CameraFragment : Fragment() {
REQUEST_CODE_PERMISSIONS
)
} else {
bindCameraUseCases(forceRebind = true)
bindCameraUseCases()
}
}
}
@ -379,25 +416,6 @@ class CameraFragment : Fragment() {
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && data != null
&& (requestCode == PICK_IMAGE_REQUEST || requestCode == CAPTURE_IMAGE_REQUEST)) {
val images: ArrayList<String> = ArrayList()
if (data.clipData != null) {
val count = data.clipData!!.itemCount
for (i in 0 until count) {
val imageUri: String = data.clipData!!.getItemAt(i).uri.toString()
images.add(imageUri)
}
startAlbumCreation(images)
} else if (data.data != null) {
images.add(data.data!!.toString())
startAlbumCreation(images)
}
}
}
private fun startAlbumCreation(uris: ArrayList<String>) {

View File

@ -0,0 +1,38 @@
package org.pixeldroid.app.postCreation.camera
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
class CameraLifecycleOwner : LifecycleOwner {
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
init {
lifecycleRegistry.currentState = Lifecycle.State.INITIALIZED
lifecycleRegistry.currentState = Lifecycle.State.CREATED
}
fun resume() {
lifecycleRegistry.currentState = Lifecycle.State.RESUMED
}
fun pause() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
lifecycleRegistry.currentState = Lifecycle.State.CREATED
}
fun destroy() {
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
}
fun start() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
}
fun stop() {
lifecycleRegistry.currentState = Lifecycle.State.CREATED
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
}

View File

@ -169,7 +169,7 @@ class NotificationsFragment : CachedFeedFragment<Notification>() {
this.notification = notification
Glide.with(itemView).load(notification?.account?.avatar_static).circleCrop()
Glide.with(itemView).load(notification?.account?.anyAvatar()).circleCrop()
.into(avatar)
val previewUrl = notification?.status?.media_attachments?.getOrNull(0)?.preview_url

View File

@ -92,7 +92,7 @@ class AccountViewHolder(binding: AccountListEntryBinding) : RecyclerView.ViewHol
this.account = account
Glide.with(itemView)
.load(account?.avatar_static ?: account?.avatar)
.load(account?.anyAvatar())
.circleCrop().placeholder(R.drawable.ic_default_user)
.into(avatar)

View File

@ -3,8 +3,6 @@ package org.pixeldroid.app.posts.feeds.uncachedFeeds.hashtags
import androidx.paging.PagingSource
import androidx.paging.PagingState
import org.pixeldroid.app.utils.api.PixelfedAPI
import org.pixeldroid.app.utils.api.objects.FeedContent
import org.pixeldroid.app.utils.api.objects.Results
import org.pixeldroid.app.utils.api.objects.Status
import retrofit2.HttpException
import java.io.IOException

View File

@ -33,7 +33,6 @@ import org.pixeldroid.app.utils.BaseActivity
import org.pixeldroid.app.utils.ImageConverter
import org.pixeldroid.app.utils.api.PixelfedAPI
import org.pixeldroid.app.utils.api.objects.Account
import org.pixeldroid.app.utils.api.objects.FeedContent
import org.pixeldroid.app.utils.api.objects.Status
import org.pixeldroid.app.utils.db.entities.UserDatabaseEntity
import org.pixeldroid.app.utils.openUrl
@ -146,7 +145,7 @@ class ProfileActivity : BaseActivity() {
val profilePicture = binding.profilePictureImageView
ImageConverter.setRoundImageFromURL(
View(applicationContext),
account.avatar,
account.anyAvatar(),
profilePicture
)

View File

@ -25,8 +25,8 @@ data class Account(
//Display attributes
val display_name: String? = "",
val note: String? = "", //HTML
val avatar: String? = "", //URL
val avatar_static: String? = "", //URL
private val avatar: String? = "", //URL
private val avatar_static: String? = "", //URL
val header: String? = "", //URL
val header_static: String? = "", //URL
val locked: Boolean? = false,
@ -74,6 +74,7 @@ data class Account(
else -> display_name.orEmpty()
}
fun anyAvatar(): String? = avatar_static ?: avatar
/**
* @brief Open profile activity with given account
*/

View File

@ -64,7 +64,7 @@ open class Status(
}
fun getPostUrl() : String? = media_attachments?.firstOrNull()?.url
fun getProfilePicUrl() : String? = account?.avatar
fun getProfilePicUrl() : String? = account?.anyAvatar()
fun getPostPreviewURL() : String? = media_attachments?.firstOrNull()?.preview_url

View File

@ -20,7 +20,7 @@ fun addUser(db: AppDatabase, account: Account, instance_uri: String, activeUser:
instance_uri = normalizeDomain(instance_uri),
username = account.username!!,
display_name = account.getDisplayName(),
avatar_static = account.avatar_static.orEmpty(),
avatar_static = account.anyAvatar().orEmpty(),
isActive = activeUser,
accessToken = accessToken,
refreshToken = refreshToken,

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="help_translate">Pomozte přeložit PixelDroid do vašeho jazyka:</string>
<string name="language">Jazyk</string>
<string name="delete_dialog">Smazat tento příspěvek\?</string>
<string name="delete">Smazat</string>
<string name="something_went_wrong">Něco se pokazilo…</string>
<string name="profile_picture">Profilový obrázek</string>
<string name="toolbar_title_edit">Upravit</string>
<string name="report_error">Hlášení nelze odeslat</string>
<string name="reported">Nahlášeno {gmd_check_circle}</string>
<string name="report_target">Nahlásit příspěvek uživatele @%1$s</string>
<string name="optional_report_comment">Volitelná zpráva pro moderátory/správce</string>
<string name="share_link">Sdílet odkaz</string>
<string name="report">Nahlásit</string>
<string name="status_more_options">Více možností</string>
<string name="search_empty_error">Vyhledávací dotaz nemůže být prázdný</string>
<string name="follows_title">%1$s sleduje</string>
<string name="hashtag_title">#%1$s</string>
<string name="followers_title">Sledují uživatele %1$s</string>
<string name="post_title">Příspěvek od %1$s</string>
<string name="license_info">PixelDroid je svobodný software s otevřeným zdrojovým kódem, licencovaný pod GNU General Public License (verze 3 nebo vyšší)</string>
<string name="project_website">Webové stránky projektu: https://pixeldroid.org</string>
<string name="dependencies_licenses">Závislosti a licence</string>
<string name="about_pixeldroid">O aplikaci PixelDroid</string>
<string name="about">O aplikaci</string>
<string name="app_name">PixelDroid</string>
<string name="whats_an_instance">Co je to instance\?</string>
<string name="liked_notification">%1$s se líbí váš příspěvek</string>
<string name="theme_title">Motiv aplikace</string>
<string name="title_activity_settings2">Nastavení</string>
<string name="light_theme">Světlý</string>
<string name="mention_notification">%1$s se o vás zmínil/a</string>
<string name="shared_notification">%1$s sdílel/a váš příspěvek</string>
<string name="followed_notification">%1$s vás sleduje</string>
<string name="dark_theme">Tmavý</string>
<string name="add_account_description">Přidat další účet Pixelfed</string>
<string name="add_account_name">Přidat účet</string>
<string name="default_system">Výchozí (dle systému)</string>
<string name="theme_header">Motiv</string>
<string name="token_error">Chyba při získávání tokenu</string>
<string name="browser_launch_failed">Nelze spustit prohlížeč. Je některý instalovaný\?</string>
<string name="registration_failed">Na tomto serveru nelze aplikaci zaregistrovat</string>
<string name="invalid_domain">Neplatná doména</string>
<string name="menu_settings">Nastavení</string>
<string name="menu_account">Můj profil</string>
</resources>

View File

@ -187,4 +187,5 @@
</plurals>
<string name="delete_post_failed_error">Impossible de supprimer la publication, erreur %1$d</string>
<string name="empty_feed">Rien à voir par ici :(</string>
<string name="delete_post_failed_io_except">Impossible de supprimer le message, vérifiez votre connexion \?</string>
</resources>

View File

@ -103,4 +103,22 @@
<string name="hashtag_title">#%1$s</string>
<string name="default_system">സ്ഥിരസ്ഥിതി (സിസ്റ്റം പിന്തുടരുന്നു)</string>
<string name="login_connection_required_once">PixelDroid ഉപയോഗിക്കാനും ഒരു അക്കൗണ്ട് ചേർക്കാനും നിങ്ങൾ ഓൺലൈനിൽ ആയിരിക്കണം :(</string>
</resources>
<string name="browser_launch_failed">ബ്രൗസർ തുറക്കാനായില്ല, നിങ്ങൾക്ക് ബ്രൗസർ ഉണ്ടോ\?</string>
<string name="auth_failed">ഉറപ്പാക്കാൻ സാധിച്ചില്ലാ</string>
<string name="theme_title">ആപ്ലിക്കേഷന്റെ തീം</string>
<string name="light_theme">ലൈറ്റ്</string>
<string name="dark_theme">ഡാർക്ക്</string>
<string name="api_not_enabled_dialog">എപിഐ ഈ ഇൻസ്റ്റൻസിൽ സജീവമല്ലാ.ഇത് സജീവമാക്കാൻ നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്ററെ ബന്ധപ്പെടുക.</string>
<string name="feed_failed">ഫീഡ് ലഭ്യമാക്കാൻ സാധിച്ചില്ല</string>
<string name="write_permission_download_pic">ചിത്രങ്ങൾ ഡൗൺലോഡ് ചെയ്യാൻ നിങ്ങൾ എഴുത്ത് അനുമതി നൽകണം!</string>
<string name="write_permission_share_pic">ചിത്രങ്ങൾ പങ്കിടാൻ നിങ്ങൾ എഴുത്ത് അനുമതി നൽകണം!</string>
<plurals name="number_comments">
<item quantity="one">%d</item>
<item quantity="other"></item>
</plurals>
<string name="registration_failed">ഈ സെർവറിൽ ആപ്ലിക്കേഷൻ രജിസ്റ്റർ ചെയ്യാനായില്ല</string>
<plurals name="description_max_characters">
<item quantity="one">വിവരണത്തിൽ പരമാവധി %d പ്രതീകം അടങ്ങിയിരിക്കണം.</item>
<item quantity="other">വിവരണത്തിൽ പരമാവധി %d പ്രതീകങ്ങൾ അടങ്ങിയിരിക്കണം.</item>
</plurals>
</resources>

View File

@ -193,4 +193,5 @@
<string name="open_drawer_menu">Abrir o menu lateral</string>
<string name="follows_title">%1$s está seguindo</string>
<string name="media_upload_failed">Envio de mídia falhou. Tente novamente ou verifique as condições de conectividade</string>
<string name="hashtag_title">#%1$s</string>
</resources>

View File

@ -166,8 +166,8 @@ fun assertStatusEqualsToReference(actual: Status){
&& actual.created_at == OffsetDateTime.parse("2020-03-03T08:00:16.+00:00")
&& actual.account!!.id=="115114166443970560"&& actual.account!!.username=="Miike"&& actual.account!!.acct=="Miike" &&
actual.account!!.url=="https://pixelfed.de/Miike"&& actual.account!!.display_name=="Miike Duart"&& actual.account!!.note==""&&
actual.account!!.avatar=="https://pixelfed.de/storage/avatars/011/511/416/644/397/056/0/ZhaopLJWTWJ3hsVCS5pS_avatar.png?v=d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35"&&
actual.account!!.avatar_static=="https://pixelfed.de/storage/avatars/011/511/416/644/397/056/0/ZhaopLJWTWJ3hsVCS5pS_avatar.png?v=d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35"&&
//actual.account!!.avatar=="https://pixelfed.de/storage/avatars/011/511/416/644/397/056/0/ZhaopLJWTWJ3hsVCS5pS_avatar.png?v=d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35"&&
//actual.account!!.avatar_static=="https://pixelfed.de/storage/avatars/011/511/416/644/397/056/0/ZhaopLJWTWJ3hsVCS5pS_avatar.png?v=d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35"&&
actual.account!!.header==""&& actual.account!!.header_static=="") && !actual.account!!.locked!! && actual.account!!.emojis== emptyList<Emoji>() && actual.account!!.discoverable == null && actual.account!!.created_at=="2019-12-24T15:42:35.000000Z" && actual.account!!.statuses_count==71 && actual.account!!.followers_count==14 && actual.account!!.following_count==0 && actual.account!!.moved==null && actual.account!!.fields==null && !actual.account!!.bot!! && actual.account!!.source==null && actual.content == """Day 8 <a href="https://pixelfed.de/discover/tags/rotavicentina?src=hash" title="#rotavicentina" class="u-url hashtag" rel="external nofollow noopener">#rotavicentina</a> <a href="https://pixelfed.de/discover/tags/hiking?src=hash" title="#hiking" class="u-url hashtag" rel="external nofollow noopener">#hiking</a> <a href="https://pixelfed.de/discover/tags/nature?src=hash" title="#nature" class="u-url hashtag" rel="external nofollow noopener">#nature</a>""" && actual.visibility==Status.Visibility.public) && !actual.sensitive!! && actual.spoiler_text==""
)
val attchmnt = actual.media_attachments!![0]

View File

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.5.21'
ext.kotlin_version = '1.5.30'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.1'
classpath 'com.android.tools.build:gradle:7.0.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong

View File

@ -0,0 +1,7 @@
* Add language (Malayalam)
* Bug fix for some bad API responses
* Update dependencies
* Update translations

View File

@ -0,0 +1,7 @@
* افزودن زبان (مالایالم)
* رفع مشکل پاسخ بد API
* به‌روزرسانی وابستگی‌ها
* به‌روزرسانی ترجمه‌ها

View File

@ -0,0 +1 @@
Cliente Pixelfed, a plataforma de compartilhamento de imagens federada

View File

@ -0,0 +1 @@
PixelDroid

View File

@ -4,4 +4,8 @@ distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
<<<<<<< HEAD
distributionSha256Sum=13bf8d3cf8eeeb5770d19741a59bde9bd966dd78d17f1bbad787a05ef19d1c2d
=======
distributionSha256Sum=81003f83b0056d20eedf48cddd4f52a9813163d4ba185bcf8abd34b8eeea4cbd
>>>>>>> master