Add reporting and link sharing functionality, polish UI
This commit is contained in:
parent
a769d404a6
commit
50dd0bad51
|
@ -65,7 +65,7 @@ dependencies {
|
||||||
* AndroidX dependencies:
|
* AndroidX dependencies:
|
||||||
*/
|
*/
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation 'androidx.core:core-ktx:1.3.1'
|
implementation 'androidx.core:core-ktx:1.3.2'
|
||||||
implementation 'androidx.preference:preference:1.1.1'
|
implementation 'androidx.preference:preference:1.1.1'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
||||||
implementation 'androidx.navigation:navigation-fragment:2.3.0'
|
implementation 'androidx.navigation:navigation-fragment:2.3.0'
|
||||||
|
@ -80,6 +80,7 @@ dependencies {
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
|
||||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
|
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
|
||||||
implementation "androidx.annotation:annotation:1.1.0"
|
implementation "androidx.annotation:annotation:1.1.0"
|
||||||
|
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||||
|
|
||||||
// Use the most recent version of CameraX
|
// Use the most recent version of CameraX
|
||||||
def camerax_version = '1.0.0-beta08'
|
def camerax_version = '1.0.0-beta08'
|
||||||
|
@ -104,8 +105,6 @@ dependencies {
|
||||||
|
|
||||||
implementation 'com.google.android.material:material:1.2.1'
|
implementation 'com.google.android.material:material:1.2.1'
|
||||||
|
|
||||||
implementation 'com.google.android:flexbox:2.0.1'
|
|
||||||
|
|
||||||
//Dagger (dependency injection)
|
//Dagger (dependency injection)
|
||||||
implementation 'com.google.dagger:dagger-android:2.28.3'
|
implementation 'com.google.dagger:dagger-android:2.28.3'
|
||||||
implementation 'com.google.dagger:dagger-android-support:2.28.3'
|
implementation 'com.google.dagger:dagger-android-support:2.28.3'
|
||||||
|
@ -138,13 +137,14 @@ dependencies {
|
||||||
|
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
|
|
||||||
implementation "com.mikepenz:materialdrawer:8.1.4"
|
implementation "com.mikepenz:materialdrawer:8.1.5"
|
||||||
// Add for NavController support
|
// Add for NavController support
|
||||||
implementation "com.mikepenz:materialdrawer-nav:8.0.3"
|
implementation "com.mikepenz:materialdrawer-nav:8.1.5"
|
||||||
|
|
||||||
//iconics
|
//iconics
|
||||||
implementation "com.mikepenz:materialdrawer-iconics:8.1.4"
|
implementation "com.mikepenz:iconics-core:5.0.3"
|
||||||
implementation "com.mikepenz:iconics-views:5.0.2"
|
implementation "com.mikepenz:materialdrawer-iconics:8.1.5"
|
||||||
|
implementation "com.mikepenz:iconics-views:5.0.3"
|
||||||
implementation 'com.mikepenz:google-material-typeface:3.0.1.4.original-kotlin@aar'
|
implementation 'com.mikepenz:google-material-typeface:3.0.1.4.original-kotlin@aar'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,12 @@
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
tools:replace="android:allowBackup">
|
tools:replace="android:allowBackup">
|
||||||
|
<activity android:name=".CameraActivity"></activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".PhotoEditActivity"
|
android:name=".ReportActivity"
|
||||||
android:theme="@style/AppTheme.NoActionBar" />
|
android:screenOrientation="sensorPortrait"
|
||||||
|
tools:ignore="LockedOrientationActivity" />
|
||||||
|
<activity android:name=".PhotoEditActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".PostCreationActivity"
|
android:name=".PostCreationActivity"
|
||||||
android:screenOrientation="sensorPortrait"
|
android:screenOrientation="sensorPortrait"
|
||||||
|
@ -47,19 +50,24 @@
|
||||||
<activity
|
<activity
|
||||||
android:name=".SettingsActivity"
|
android:name=".SettingsActivity"
|
||||||
android:label="@string/title_activity_settings2"
|
android:label="@string/title_activity_settings2"
|
||||||
|
android:parentActivityName=".MainActivity"
|
||||||
android:screenOrientation="sensorPortrait"
|
android:screenOrientation="sensorPortrait"
|
||||||
tools:ignore="LockedOrientationActivity"
|
tools:ignore="LockedOrientationActivity" />
|
||||||
android:parentActivityName=".MainActivity" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:screenOrientation="sensorPortrait"
|
android:screenOrientation="sensorPortrait"
|
||||||
android:theme="@style/AppTheme.Launcher"
|
android:theme="@style/AppTheme.Launcher"
|
||||||
|
android:windowSoftInputMode="adjustPan"
|
||||||
tools:ignore="LockedOrientationActivity">
|
tools:ignore="LockedOrientationActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.app.default_searchable"
|
||||||
|
android:value=".SearchActivity" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".LoginActivity"
|
android:name=".LoginActivity"
|
||||||
|
@ -89,28 +97,23 @@
|
||||||
android:screenOrientation="sensorPortrait"
|
android:screenOrientation="sensorPortrait"
|
||||||
tools:ignore="LockedOrientationActivity">
|
tools:ignore="LockedOrientationActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action
|
<action android:name="android.intent.action.SEARCH" />
|
||||||
android:name="android.intent.action.SEARCH"
|
|
||||||
android:screenOrientation="sensorPortrait"
|
|
||||||
tools:ignore="LockedOrientationActivity" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.app.searchable"
|
android:name="android.app.searchable"
|
||||||
android:resource="@xml/searchable" />
|
android:resource="@xml/searchable" />
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".AboutActivity"
|
android:name=".AboutActivity"
|
||||||
|
android:parentActivityName=".SettingsActivity"
|
||||||
android:screenOrientation="sensorPortrait"
|
android:screenOrientation="sensorPortrait"
|
||||||
tools:ignore="LockedOrientationActivity"
|
tools:ignore="LockedOrientationActivity" />
|
||||||
android:parentActivityName=".SettingsActivity" />
|
<activity
|
||||||
|
android:name=".LicenseActivity"
|
||||||
<activity android:name=".LicenseActivity"
|
android:parentActivityName=".AboutActivity"
|
||||||
android:screenOrientation="sensorPortrait"
|
android:screenOrientation="sensorPortrait"
|
||||||
tools:ignore="LockedOrientationActivity"
|
tools:ignore="LockedOrientationActivity" />
|
||||||
android:parentActivityName=".AboutActivity" />
|
|
||||||
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.h.pixeldroid
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.h.pixeldroid.fragments.CameraFragment
|
||||||
|
|
||||||
|
class CameraActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_camera)
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
supportActionBar?.setTitle(R.string.add_photo)
|
||||||
|
|
||||||
|
val cameraFragment = CameraFragment()
|
||||||
|
|
||||||
|
val arguments = Bundle()
|
||||||
|
arguments.putBoolean("CameraActivity", true)
|
||||||
|
cameraFragment.arguments = arguments
|
||||||
|
|
||||||
|
supportFragmentManager.beginTransaction()
|
||||||
|
.add(R.id.camera_activity_fragment, cameraFragment).commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSupportNavigateUp(): Boolean {
|
||||||
|
onBackPressed()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -88,7 +88,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupDrawer() {
|
private fun setupDrawer() {
|
||||||
main_toolbar.setNavigationOnClickListener {
|
main_drawer_button.setOnClickListener{
|
||||||
drawer_layout.open()
|
drawer_layout.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,11 +103,9 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_photo_edit)
|
setContentView(R.layout.activity_photo_edit)
|
||||||
|
|
||||||
//TODO move to xml:
|
supportActionBar?.setTitle(R.string.toolbar_title_edit)
|
||||||
setSupportActionBar(toolbar)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
supportActionBar!!.title = "Edit"
|
supportActionBar?.setHomeButtonEnabled(true)
|
||||||
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
|
||||||
supportActionBar!!.setHomeButtonEnabled(true)
|
|
||||||
|
|
||||||
val cropButton: FloatingActionButton = findViewById(R.id.cropImageButton)
|
val cropButton: FloatingActionButton = findViewById(R.id.cropImageButton)
|
||||||
|
|
||||||
|
@ -267,7 +265,11 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||||
private fun startCrop() {
|
private fun startCrop() {
|
||||||
val file = File.createTempFile("temp_crop_img", ".png", cacheDir)
|
val file = File.createTempFile("temp_crop_img", ".png", cacheDir)
|
||||||
|
|
||||||
val uCrop: UCrop = UCrop.of(initialUri!!, Uri.fromFile(file))
|
val options: UCrop.Options = UCrop.Options().apply {
|
||||||
|
setStatusBarColor(resources.getColor(R.color.colorPrimaryDark, theme))
|
||||||
|
setActiveControlsWidgetColor(resources.getColor(R.color.colorButtonBg, theme))
|
||||||
|
}
|
||||||
|
val uCrop: UCrop = UCrop.of(initialUri!!, Uri.fromFile(file)).withOptions(options)
|
||||||
uCrop.start(this)
|
uCrop.start(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,14 +472,19 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
|
||||||
if(!save) {
|
if(!save) {
|
||||||
sendBackImage(path)
|
sendBackImage(path)
|
||||||
} else {
|
} else {
|
||||||
MediaScannerConnection.scanFile(
|
if(path.startsWith("file")) {
|
||||||
this,
|
MediaScannerConnection.scanFile(
|
||||||
arrayOf(path.toUri().toFile().absolutePath),
|
this,
|
||||||
null
|
arrayOf(path.toUri().toFile().absolutePath),
|
||||||
|
null
|
||||||
|
|
||||||
) { path, uri ->
|
) { path, uri ->
|
||||||
if(uri == null) {
|
if (uri == null) {
|
||||||
Log.e("NEW IMAGE SCAN FAILED", "Tried to scan $path, but it failed")
|
Log.e(
|
||||||
|
"NEW IMAGE SCAN FAILED",
|
||||||
|
"Tried to scan $path, but it failed"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Application
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.h.pixeldroid.di.*
|
import com.h.pixeldroid.di.*
|
||||||
import com.h.pixeldroid.utils.ThemeUtils
|
import com.h.pixeldroid.utils.ThemeUtils
|
||||||
|
import com.mikepenz.iconics.Iconics
|
||||||
import org.ligi.tracedroid.TraceDroid
|
import org.ligi.tracedroid.TraceDroid
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +24,9 @@ class Pixeldroid: Application() {
|
||||||
.databaseModule(DatabaseModule(applicationContext))
|
.databaseModule(DatabaseModule(applicationContext))
|
||||||
.aPIModule(APIModule())
|
.aPIModule(APIModule())
|
||||||
.build()
|
.build()
|
||||||
mApplicationComponent.inject(this);
|
mApplicationComponent.inject(this)
|
||||||
|
|
||||||
|
Iconics.init(applicationContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAppComponent(): ApplicationComponent {
|
fun getAppComponent(): ApplicationComponent {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.h.pixeldroid
|
package com.h.pixeldroid
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -26,7 +25,6 @@ import com.h.pixeldroid.interfaces.PostCreationListener
|
||||||
import com.h.pixeldroid.objects.Attachment
|
import com.h.pixeldroid.objects.Attachment
|
||||||
import com.h.pixeldroid.objects.Instance
|
import com.h.pixeldroid.objects.Instance
|
||||||
import com.h.pixeldroid.objects.Status
|
import com.h.pixeldroid.objects.Status
|
||||||
import com.h.pixeldroid.utils.DBUtils
|
|
||||||
import com.h.pixeldroid.utils.ProgressRequestBody
|
import com.h.pixeldroid.utils.ProgressRequestBody
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
|
@ -39,9 +37,11 @@ import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
private val TAG = "Post Creation Activity"
|
||||||
|
private val MORE_PICTURES_REQUEST_CODE = 0xffff
|
||||||
|
|
||||||
private val TAG = "Post Creation Activity"
|
|
||||||
|
class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
||||||
|
|
||||||
private lateinit var recycler : RecyclerView
|
private lateinit var recycler : RecyclerView
|
||||||
private lateinit var adapter : PostCreationAdapter
|
private lateinit var adapter : PostCreationAdapter
|
||||||
|
@ -74,16 +74,19 @@ class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
||||||
|
|
||||||
(this.application as Pixeldroid).getAppComponent().inject(this)
|
(this.application as Pixeldroid).getAppComponent().inject(this)
|
||||||
|
|
||||||
// load images
|
// get image URIs
|
||||||
posts = intent.getStringArrayListExtra("pictures_uri")!!
|
if(intent.clipData != null) {
|
||||||
|
val count = intent.clipData!!.itemCount
|
||||||
progressList = posts.map { 0 } as ArrayList<Int>
|
for (i in 0 until count) {
|
||||||
muListOfIds = posts.map { "" }.toMutableList()
|
val imageUri: String = intent.clipData!!.getItemAt(i).uri.toString()
|
||||||
|
posts.add(imageUri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
user = db.userDao().getActiveUser()
|
user = db.userDao().getActiveUser()
|
||||||
|
|
||||||
val instances = db.instanceDao().getAll()
|
val instances = db.instanceDao().getAll()
|
||||||
maxLength = if (user!=null){
|
maxLength = if (user != null){
|
||||||
val thisInstances =
|
val thisInstances =
|
||||||
instances.filter { instanceDatabaseEntity ->
|
instances.filter { instanceDatabaseEntity ->
|
||||||
instanceDatabaseEntity.uri.contains(user!!.instance_uri)
|
instanceDatabaseEntity.uri.contains(user!!.instance_uri)
|
||||||
|
@ -100,12 +103,14 @@ class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
//upload the picture and display progress while doing so
|
//upload the picture and display progress while doing so
|
||||||
|
muListOfIds = posts.map { "" }.toMutableList()
|
||||||
|
progressList = posts.map { 0 } as ArrayList<Int>
|
||||||
upload()
|
upload()
|
||||||
|
|
||||||
adapter = PostCreationAdapter(posts)
|
adapter = PostCreationAdapter(posts)
|
||||||
adapter.listener = this
|
adapter.listener = this
|
||||||
recycler = findViewById(R.id.image_grid)
|
recycler = findViewById(R.id.image_grid)
|
||||||
recycler.layoutManager = GridLayoutManager(this, if (posts.size > 2) 2 else 1)
|
recycler.layoutManager = GridLayoutManager(this, 3)
|
||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
|
|
||||||
// get the description and send the post
|
// get the description and send the post
|
||||||
|
@ -126,8 +131,8 @@ class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
||||||
val textField = findViewById<TextInputEditText>(R.id.new_post_description_input_field)
|
val textField = findViewById<TextInputEditText>(R.id.new_post_description_input_field)
|
||||||
val content = textField.text.toString()
|
val content = textField.text.toString()
|
||||||
if (content.length > maxLength) {
|
if (content.length > maxLength) {
|
||||||
// error, too much characters
|
// error, too many characters
|
||||||
textField.error = "Description must contain $maxLength characters at most."
|
textField.error = getString(R.string.description_max_characters).format(maxLength)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// store the description
|
// store the description
|
||||||
|
@ -135,9 +140,26 @@ class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun upload() {
|
/**
|
||||||
for ((index, post) in posts.withIndex()) {
|
* Uploads the images that are in the [posts] array.
|
||||||
val imageUri = Uri.parse(post)
|
* Keeps track of them in the [progressList] (for the upload progress), and the [muListOfIds]
|
||||||
|
* (for the list of ids of the uploads).
|
||||||
|
* @param newImagesStartingIndex is the index in the [posts] array we want to start uploading at.
|
||||||
|
* Indices before this are already uploading, or done uploading, from before.
|
||||||
|
* @param editedImage contains the index of the image that was edited. If set, other images are
|
||||||
|
* not uploaded again: they should already be uploading, or be done uploading, from before.
|
||||||
|
*/
|
||||||
|
private fun upload(newImagesStartingIndex: Int = 0, editedImage: Int? = null) {
|
||||||
|
enableButton(false)
|
||||||
|
uploadProgressBar.visibility = View.VISIBLE
|
||||||
|
upload_completed_textview.visibility = View.INVISIBLE
|
||||||
|
|
||||||
|
val range: IntRange = if(editedImage == null){
|
||||||
|
newImagesStartingIndex until posts.size
|
||||||
|
} else IntRange(editedImage, editedImage)
|
||||||
|
|
||||||
|
for (index in range) {
|
||||||
|
val imageUri = Uri.parse(posts[index])
|
||||||
val imageInputStream = contentResolver.openInputStream(imageUri)!!
|
val imageInputStream = contentResolver.openInputStream(imageUri)!!
|
||||||
|
|
||||||
val size =
|
val size =
|
||||||
|
@ -237,7 +259,7 @@ class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
||||||
if(enable){
|
if(enable){
|
||||||
posting_progress_bar.visibility = View.GONE
|
posting_progress_bar.visibility = View.GONE
|
||||||
post_creation_send_button.visibility = View.VISIBLE
|
post_creation_send_button.visibility = View.VISIBLE
|
||||||
} else{
|
} else {
|
||||||
posting_progress_bar.visibility = View.VISIBLE
|
posting_progress_bar.visibility = View.VISIBLE
|
||||||
post_creation_send_button.visibility = View.GONE
|
post_creation_send_button.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
@ -259,51 +281,85 @@ class PostCreationActivity : AppCompatActivity(), PostCreationListener {
|
||||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||||
posts[positionResult] = data.getStringExtra("result")!!
|
posts[positionResult] = data.getStringExtra("result")!!
|
||||||
adapter.notifyItemChanged(positionResult)
|
adapter.notifyItemChanged(positionResult)
|
||||||
muListOfIds.clear()
|
muListOfIds[positionResult] = ""
|
||||||
upload()
|
progressList[positionResult] = 0
|
||||||
}
|
upload(editedImage = positionResult)
|
||||||
else if(resultCode == Activity.RESULT_CANCELED){
|
} else if(resultCode == Activity.RESULT_CANCELED){
|
||||||
Toast.makeText(applicationContext, "Edition cancelled", Toast.LENGTH_SHORT).show()
|
Toast.makeText(applicationContext, "Editing cancelled", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(applicationContext, "Error while editing", Toast.LENGTH_SHORT).show()
|
Toast.makeText(applicationContext, "Error while editing", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
} else if (requestCode == MORE_PICTURES_REQUEST_CODE) {
|
||||||
|
if (resultCode == Activity.RESULT_OK && data?.clipData != null) {
|
||||||
|
|
||||||
|
val count = data.clipData!!.itemCount
|
||||||
|
for (i in 0 until count) {
|
||||||
|
val imageUri: String = data.clipData!!.getItemAt(i).uri.toString()
|
||||||
|
posts.add(imageUri)
|
||||||
|
progressList.add(0)
|
||||||
|
muListOfIds.add(i, "")
|
||||||
|
}
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
upload(newImagesStartingIndex = posts.size - count)
|
||||||
|
} else if(resultCode == Activity.RESULT_CANCELED){
|
||||||
|
Toast.makeText(applicationContext, "Adding images", Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(applicationContext, "Error while adding images", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PostCreationAdapter(private val posts: ArrayList<String>): RecyclerView.Adapter<PostCreationAdapter.ViewHolder>() {
|
inner class PostCreationAdapter(private val posts: ArrayList<String>): RecyclerView.Adapter<PostCreationAdapter.ViewHolder>() {
|
||||||
private var context: Context? = null
|
|
||||||
var listener: PostCreationListener? = null
|
var listener: PostCreationListener? = null
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
context = parent.context
|
val view =
|
||||||
val view = LayoutInflater.from(parent.context)
|
if(viewType == 0) LayoutInflater.from(parent.context)
|
||||||
.inflate(R.layout.image_album_creation, parent, false)
|
.inflate(R.layout.image_album_creation, parent, false)
|
||||||
|
else LayoutInflater.from(parent.context)
|
||||||
|
.inflate(R.layout.add_more_album_creation, parent, false)
|
||||||
return ViewHolder(view)
|
return ViewHolder(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun getItemViewType(position: Int): Int {
|
||||||
Log.d("test", "binded")
|
if(position == posts.size) return 1
|
||||||
holder.bind()
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = posts.size
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
if(position != posts.size) {
|
||||||
|
holder.bindImage()
|
||||||
|
} else{
|
||||||
|
holder.bindPlusButton()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = posts.size + 1
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
|
||||||
fun bind() {
|
fun bindImage() {
|
||||||
val image = Uri.parse(posts[adapterPosition])
|
val image = Uri.parse(
|
||||||
|
posts[adapterPosition]
|
||||||
|
)
|
||||||
// load image
|
// load image
|
||||||
Glide.with(context!!)
|
Glide.with(itemView.context)
|
||||||
.load(image)
|
.load(image)
|
||||||
.centerCrop()
|
.centerCrop()
|
||||||
.into(itemView.galleryImage)
|
.into(itemView.galleryImage)
|
||||||
|
|
||||||
// adding click or tap handler for the image layout
|
// adding click or tap handler for the image layout
|
||||||
itemView.galleryImage.setOnClickListener {
|
itemView.setOnClickListener {
|
||||||
Log.d("test", "clicked")
|
|
||||||
listener?.onClick(adapterPosition)
|
listener?.onClick(adapterPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bindPlusButton() {
|
||||||
|
itemView.setOnClickListener {
|
||||||
|
val intent = Intent(itemView.context, CameraActivity::class.java)
|
||||||
|
this@PostCreationActivity.startActivityForResult(intent, MORE_PICTURES_REQUEST_CODE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.h.pixeldroid
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import com.h.pixeldroid.db.AppDatabase
|
||||||
|
import com.h.pixeldroid.di.PixelfedAPIHolder
|
||||||
|
import com.h.pixeldroid.objects.Report
|
||||||
|
import com.h.pixeldroid.objects.Status
|
||||||
|
import kotlinx.android.synthetic.main.activity_report.*
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.Callback
|
||||||
|
import retrofit2.Response
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ReportActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var db: AppDatabase
|
||||||
|
@Inject
|
||||||
|
lateinit var apiHolder: PixelfedAPIHolder
|
||||||
|
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_report)
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
supportActionBar?.setTitle(R.string.report)
|
||||||
|
|
||||||
|
val status = intent.getSerializableExtra(Status.POST_TAG) as Status?
|
||||||
|
|
||||||
|
(this.application as Pixeldroid).getAppComponent().inject(this)
|
||||||
|
//get the currently active user
|
||||||
|
val user = db.userDao().getActiveUser()
|
||||||
|
|
||||||
|
|
||||||
|
report_target_textview.text = getString(R.string.report_target).format(status?.account?.acct)
|
||||||
|
|
||||||
|
|
||||||
|
reportButton.setOnClickListener{
|
||||||
|
reportButton.visibility = View.INVISIBLE
|
||||||
|
reportProgressBar.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
textInputLayout.editText?.isEnabled = false
|
||||||
|
|
||||||
|
val accessToken = user?.accessToken.orEmpty()
|
||||||
|
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
api.report("Bearer $accessToken", status?.account?.id!!, listOf(status), textInputLayout.editText?.text.toString())
|
||||||
|
.enqueue(object : Callback<Report> {
|
||||||
|
override fun onResponse(
|
||||||
|
call: Call<Report>,
|
||||||
|
response: Response<Report>
|
||||||
|
) {
|
||||||
|
if (response.body() == null || !response.isSuccessful) {
|
||||||
|
textInputLayout.error = getString(R.string.report_error)
|
||||||
|
reportButton.visibility = View.VISIBLE
|
||||||
|
textInputLayout.editText?.isEnabled = true
|
||||||
|
reportProgressBar.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
reportProgressBar.visibility = View.GONE
|
||||||
|
reportButton.isEnabled = false
|
||||||
|
reportButton.text = getString(R.string.reported)
|
||||||
|
reportButton.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<Report>, t: Throwable) {
|
||||||
|
Log.e("REPORT:", t.toString())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onSupportNavigateUp(): Boolean {
|
||||||
|
onBackPressed()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,9 +20,15 @@ class SearchActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_search)
|
setContentView(R.layout.activity_search)
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
|
var query = ""
|
||||||
|
if (Intent.ACTION_SEARCH == intent.action) {
|
||||||
|
query = intent.getStringExtra(SearchManager.QUERY).orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
var query = intent.getSerializableExtra("searchFeed") as String
|
|
||||||
query = query.trim()
|
query = query.trim()
|
||||||
|
supportActionBar?.title = query
|
||||||
|
|
||||||
val searchType = when {
|
val searchType = when {
|
||||||
query.startsWith("#") -> {
|
query.startsWith("#") -> {
|
||||||
|
@ -41,6 +47,11 @@ class SearchActivity : AppCompatActivity() {
|
||||||
setupTabs(tabs, searchType)
|
setupTabs(tabs, searchType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onSupportNavigateUp(): Boolean {
|
||||||
|
onBackPressed()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
private fun createSearchTabs(query: String): Array<Fragment>{
|
private fun createSearchTabs(query: String): Array<Fragment>{
|
||||||
|
|
||||||
val searchFeedFragment =
|
val searchFeedFragment =
|
||||||
|
|
|
@ -54,13 +54,6 @@ class SettingsActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferen
|
||||||
class SettingsFragment : PreferenceFragmentCompat() {
|
class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
setPreferencesFromResource(R.xml.root_preferences, rootKey)
|
setPreferencesFromResource(R.xml.root_preferences, rootKey)
|
||||||
val button: Preference? = findPreference("about")
|
|
||||||
button?.onPreferenceClickListener =
|
|
||||||
Preference.OnPreferenceClickListener {
|
|
||||||
val intent = Intent(context, AboutActivity::class.java)
|
|
||||||
startActivity(intent)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -266,4 +266,15 @@ interface PixelfedAPI {
|
||||||
fun discover(
|
fun discover(
|
||||||
@Header("Authorization") authorization: String
|
@Header("Authorization") authorization: String
|
||||||
) : Call<DiscoverPosts>
|
) : Call<DiscoverPosts>
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST("/api/v1/reports")
|
||||||
|
fun report(
|
||||||
|
@Header("Authorization") authorization: String,
|
||||||
|
@Field("account_id") account_id: String,
|
||||||
|
@Field("status_ids") status_ids: List<Status>,
|
||||||
|
@Field("comment") comment: String,
|
||||||
|
@Field("forward") forward: Boolean = true
|
||||||
|
) : Call<Report>
|
||||||
|
|
||||||
}
|
}
|
|
@ -24,6 +24,7 @@ interface ApplicationComponent {
|
||||||
fun inject(activity: PostCreationActivity?)
|
fun inject(activity: PostCreationActivity?)
|
||||||
fun inject(activity: ProfileActivity?)
|
fun inject(activity: ProfileActivity?)
|
||||||
fun inject(mainActivity: MainActivity?)
|
fun inject(mainActivity: MainActivity?)
|
||||||
|
fun inject(activity: ReportActivity?)
|
||||||
fun inject(fragment: PostFragment)
|
fun inject(fragment: PostFragment)
|
||||||
fun inject(fragment: SearchDiscoverFragment)
|
fun inject(fragment: SearchDiscoverFragment)
|
||||||
fun inject(fragment: OfflineFeedFragment)
|
fun inject(fragment: OfflineFeedFragment)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.h.pixeldroid.fragments
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.ClipData
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
@ -23,13 +24,14 @@ import androidx.camera.view.PreviewView
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.net.toUri
|
||||||
import androidx.core.view.setPadding
|
import androidx.core.view.setPadding
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import com.h.pixeldroid.PhotoEditActivity
|
|
||||||
import com.h.pixeldroid.PostCreationActivity
|
import com.h.pixeldroid.PostCreationActivity
|
||||||
|
import com.h.pixeldroid.CameraActivity
|
||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -39,6 +41,7 @@ import java.util.concurrent.Executors
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
// This is an arbitrary number we are using to keep track of the permission
|
// This is an arbitrary number we are using to keep track of the permission
|
||||||
// request. Where an app has multiple context for requesting permission,
|
// request. Where an app has multiple context for requesting permission,
|
||||||
|
@ -54,7 +57,10 @@ class CameraFragment : Fragment() {
|
||||||
|
|
||||||
private lateinit var container: ConstraintLayout
|
private lateinit var container: ConstraintLayout
|
||||||
private lateinit var viewFinder: PreviewView
|
private lateinit var viewFinder: PreviewView
|
||||||
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE)
|
private val REQUIRED_PERMISSIONS = arrayOf(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||||
|
)
|
||||||
private val PICK_IMAGE_REQUEST = 1
|
private val PICK_IMAGE_REQUEST = 1
|
||||||
private val CAPTURE_IMAGE_REQUEST = 2
|
private val CAPTURE_IMAGE_REQUEST = 2
|
||||||
|
|
||||||
|
@ -64,6 +70,8 @@ class CameraFragment : Fragment() {
|
||||||
private var imageCapture: ImageCapture? = null
|
private var imageCapture: ImageCapture? = null
|
||||||
private var camera: Camera? = null
|
private var camera: Camera? = null
|
||||||
|
|
||||||
|
private var inActivity by Delegates.notNull<Boolean>()
|
||||||
|
|
||||||
/** Blocking camera operations are performed using this executor */
|
/** Blocking camera operations are performed using this executor */
|
||||||
private lateinit var cameraExecutor: ExecutorService
|
private lateinit var cameraExecutor: ExecutorService
|
||||||
|
|
||||||
|
@ -90,7 +98,8 @@ class CameraFragment : Fragment() {
|
||||||
*/
|
*/
|
||||||
private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
|
private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
|
||||||
ContextCompat.checkSelfPermission(
|
ContextCompat.checkSelfPermission(
|
||||||
requireContext(), it) == PackageManager.PERMISSION_GRANTED
|
requireContext(), it
|
||||||
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -105,8 +114,12 @@ class CameraFragment : Fragment() {
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?): View? =
|
savedInstanceState: Bundle?
|
||||||
inflater.inflate(R.layout.fragment_camera, container, false)
|
): View? {
|
||||||
|
inActivity = arguments?.getBoolean("CameraActivity") ?: false
|
||||||
|
|
||||||
|
return inflater.inflate(R.layout.fragment_camera, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setGalleryThumbnail(uri: String) {
|
private fun setGalleryThumbnail(uri: String) {
|
||||||
// Reference of the view that holds the gallery thumbnail
|
// Reference of the view that holds the gallery thumbnail
|
||||||
|
@ -203,11 +216,12 @@ class CameraFragment : Fragment() {
|
||||||
// A variable number of use-cases can be passed here -
|
// A variable number of use-cases can be passed here -
|
||||||
// camera provides access to CameraControl & CameraInfo
|
// camera provides access to CameraControl & CameraInfo
|
||||||
camera = cameraProvider.bindToLifecycle(
|
camera = cameraProvider.bindToLifecycle(
|
||||||
this, cameraSelector, preview, imageCapture)
|
this, cameraSelector, preview, imageCapture
|
||||||
|
)
|
||||||
|
|
||||||
// Attach the viewfinder's surface provider to preview use case
|
// Attach the viewfinder's surface provider to preview use case
|
||||||
preview?.setSurfaceProvider(viewFinder.createSurfaceProvider())
|
preview?.setSurfaceProvider(viewFinder.createSurfaceProvider())
|
||||||
} catch(exc: Exception) {
|
} catch (exc: Exception) {
|
||||||
Log.e(TAG, "Use case binding failed", exc)
|
Log.e(TAG, "Use case binding failed", exc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +260,6 @@ class CameraFragment : Fragment() {
|
||||||
|
|
||||||
// In the background, load latest photo taken (if any) for gallery thumbnail
|
// In the background, load latest photo taken (if any) for gallery thumbnail
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
// Find the last picture
|
|
||||||
// Find the last picture
|
// Find the last picture
|
||||||
val projection = arrayOf(
|
val projection = arrayOf(
|
||||||
MediaStore.Images.ImageColumns._ID,
|
MediaStore.Images.ImageColumns._ID,
|
||||||
|
@ -382,10 +395,29 @@ class CameraFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startAlbumCreation(uris: ArrayList<String>) {
|
private fun startAlbumCreation(uris: ArrayList<String>) {
|
||||||
startActivity(
|
|
||||||
Intent(activity, PostCreationActivity::class.java)
|
val intent = Intent(requireActivity(), PostCreationActivity::class.java)
|
||||||
.putExtra("pictures_uri", uris)
|
.apply {
|
||||||
)
|
uris.forEach{
|
||||||
|
//Why are we using ClipData here? Because the FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
//needs to be applied to the URIs, and this flag flag only applies to the
|
||||||
|
//Intent's data and any URIs specified in its ClipData.
|
||||||
|
if(clipData == null){
|
||||||
|
clipData = ClipData("", emptyArray(), ClipData.Item(it.toUri()))
|
||||||
|
} else {
|
||||||
|
clipData!!.addItem(ClipData.Item(it.toUri()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
|
||||||
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inActivity){
|
||||||
|
requireActivity().setResult(Activity.RESULT_OK, intent)
|
||||||
|
requireActivity().finish()
|
||||||
|
} else {
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -50,11 +50,14 @@ class FilterListFragment : Fragment(), FilterListFragmentListener {
|
||||||
recyclerView.addItemDecoration(SpaceItemDecoration(space))
|
recyclerView.addItemDecoration(SpaceItemDecoration(space))
|
||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
|
|
||||||
displayImage(null)
|
|
||||||
|
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
displayImage(null)
|
||||||
|
}
|
||||||
|
|
||||||
private fun displayImage(bitmap: Bitmap?) {
|
private fun displayImage(bitmap: Bitmap?) {
|
||||||
val r = Runnable {
|
val r = Runnable {
|
||||||
val tbImage: Bitmap = (if (bitmap == null) {
|
val tbImage: Bitmap = (if (bitmap == null) {
|
||||||
|
@ -74,10 +77,10 @@ class FilterListFragment : Fragment(), FilterListFragmentListener {
|
||||||
})
|
})
|
||||||
?: return@Runnable
|
?: return@Runnable
|
||||||
|
|
||||||
setupFilter(tbImage)
|
if(activity != null) setupFilter(tbImage)
|
||||||
|
|
||||||
tbItemList.addAll(ThumbnailsManager.processThumbs(activity))
|
if(context != null) tbItemList.addAll(ThumbnailsManager.processThumbs(context))
|
||||||
requireActivity().runOnUiThread{ adapter.notifyDataSetChanged() }
|
activity?.runOnUiThread{ adapter.notifyDataSetChanged() }
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread(r).start()
|
Thread(r).start()
|
||||||
|
@ -93,7 +96,7 @@ class FilterListFragment : Fragment(), FilterListFragmentListener {
|
||||||
tbItem.filterName = tbItem.filter.name
|
tbItem.filterName = tbItem.filter.name
|
||||||
ThumbnailsManager.addThumb(tbItem)
|
ThumbnailsManager.addThumb(tbItem)
|
||||||
|
|
||||||
val filters = FilterPack.getFilterPack(requireActivity())
|
val filters = FilterPack.getFilterPack(context)
|
||||||
|
|
||||||
for (filter in filters) {
|
for (filter in filters) {
|
||||||
val item = ThumbnailItem()
|
val item = ThumbnailItem()
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.h.pixeldroid.fragments
|
package com.h.pixeldroid.fragments
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -9,18 +8,14 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.PopupMenu
|
|
||||||
import android.widget.Toast
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
import com.h.pixeldroid.utils.ImageUtils
|
import kotlinx.android.synthetic.main.fragment_image.*
|
||||||
import com.karumi.dexter.Dexter
|
|
||||||
import com.karumi.dexter.listener.PermissionDeniedResponse
|
|
||||||
import com.karumi.dexter.listener.PermissionGrantedResponse
|
|
||||||
import com.karumi.dexter.listener.single.BasePermissionListener
|
|
||||||
|
|
||||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||||
private const val IMG_URL = "imgurl"
|
private const val IMG_URL = "imgurl"
|
||||||
|
private const val IMG_DESCRIPTION = "imgdescription"
|
||||||
private const val RQST_BLDR = "rqstbldr"
|
private const val RQST_BLDR = "rqstbldr"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,11 +25,13 @@ private const val RQST_BLDR = "rqstbldr"
|
||||||
*/
|
*/
|
||||||
class ImageFragment : Fragment() {
|
class ImageFragment : Fragment() {
|
||||||
private lateinit var imgUrl: String
|
private lateinit var imgUrl: String
|
||||||
|
private lateinit var imgDescription: String
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
arguments?.let {
|
arguments?.let {
|
||||||
imgUrl = it.getString(IMG_URL)!!
|
imgUrl = it.getString(IMG_URL)!!
|
||||||
|
imgDescription = it.getString(IMG_DESCRIPTION)!!.ifEmpty { getString(R.string.no_description) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,49 +42,10 @@ class ImageFragment : Fragment() {
|
||||||
val view = inflater.inflate(R.layout.fragment_image, container, false)
|
val view = inflater.inflate(R.layout.fragment_image, container, false)
|
||||||
|
|
||||||
view.findViewById<ImageView>(R.id.imageImageView).setOnLongClickListener {
|
view.findViewById<ImageView>(R.id.imageImageView).setOnLongClickListener {
|
||||||
PopupMenu(view.context, it).apply {
|
Snackbar.make(it, imgDescription, Snackbar.LENGTH_SHORT).show()
|
||||||
setOnMenuItemClickListener { item ->
|
|
||||||
when (item.itemId) {
|
|
||||||
R.id.image_popup_menu_save_to_gallery -> {
|
|
||||||
Dexter.withContext(view.context)
|
|
||||||
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
.withListener(object: BasePermissionListener() {
|
|
||||||
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
|
|
||||||
Toast.makeText(view.context,
|
|
||||||
view.context.getString(R.string.write_permission_download_pic),
|
|
||||||
Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {
|
|
||||||
ImageUtils.downloadImage(requireActivity(), imgUrl)
|
|
||||||
}
|
|
||||||
}).check()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
R.id.image_popup_menu_share_picture -> {
|
|
||||||
Dexter.withContext(view.context)
|
|
||||||
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
.withListener(object: BasePermissionListener() {
|
|
||||||
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
|
|
||||||
Toast.makeText(view.context,
|
|
||||||
view.context.getString(R.string.write_permission_share_pic),
|
|
||||||
Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {
|
|
||||||
ImageUtils.downloadImage(requireActivity(), imgUrl, share = true)
|
|
||||||
}
|
|
||||||
}).check()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inflate(R.menu.image_popup_menu)
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
@ -100,6 +58,7 @@ class ImageFragment : Fragment() {
|
||||||
.placeholder(ColorDrawable(Color.GRAY))
|
.placeholder(ColorDrawable(Color.GRAY))
|
||||||
.load(imgUrl)
|
.load(imgUrl)
|
||||||
.into(view.findViewById(R.id.imageImageView)!!)
|
.into(view.findViewById(R.id.imageImageView)!!)
|
||||||
|
imageImageView.contentDescription = imgDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -111,10 +70,11 @@ class ImageFragment : Fragment() {
|
||||||
* @return A new instance of fragment ImageFragment.
|
* @return A new instance of fragment ImageFragment.
|
||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun newInstance(imageUrl: String) =
|
fun newInstance(imageUrl: String, imageDescription: String) =
|
||||||
ImageFragment().apply {
|
ImageFragment().apply {
|
||||||
arguments = Bundle().apply {
|
arguments = Bundle().apply {
|
||||||
putString(IMG_URL, imageUrl)
|
putString(IMG_URL, imageUrl)
|
||||||
|
putString(IMG_DESCRIPTION, imageDescription)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,6 @@ class PostFragment : Fragment() {
|
||||||
.asDrawable().fitCenter()
|
.asDrawable().fitCenter()
|
||||||
.placeholder(ColorDrawable(Color.GRAY))
|
.placeholder(ColorDrawable(Color.GRAY))
|
||||||
|
|
||||||
currentStatus?.setupPost(root, picRequest, this, statusDomain, true)
|
|
||||||
|
|
||||||
//Setup arguments needed for the onclicklisteners
|
|
||||||
val holder = PostViewHolder(
|
|
||||||
root,
|
|
||||||
requireContext()
|
|
||||||
)
|
|
||||||
|
|
||||||
(requireActivity().application as Pixeldroid).getAppComponent().inject(this)
|
(requireActivity().application as Pixeldroid).getAppComponent().inject(this)
|
||||||
|
|
||||||
val user = db.userDao().getActiveUser()
|
val user = db.userDao().getActiveUser()
|
||||||
|
@ -54,21 +46,17 @@ class PostFragment : Fragment() {
|
||||||
val accessToken = user?.accessToken.orEmpty()
|
val accessToken = user?.accessToken.orEmpty()
|
||||||
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
val api = apiHolder.api ?: apiHolder.setDomainToCurrentUser(db)
|
||||||
|
|
||||||
currentStatus?.setDescription(root, api, "Bearer $accessToken")
|
currentStatus?.setupPost(root, picRequest, this, statusDomain, true)
|
||||||
|
|
||||||
//Activate onclickListeners
|
val holder = PostViewHolder(
|
||||||
currentStatus?.activateLiker(holder, api, "Bearer $accessToken",
|
root,
|
||||||
currentStatus.favourited ?: false
|
root.context
|
||||||
)
|
)
|
||||||
currentStatus?.activateReblogger(holder, api, "Bearer $accessToken",
|
|
||||||
currentStatus.reblogged ?: false
|
|
||||||
)
|
|
||||||
currentStatus?.activateCommenter(holder, api, "Bearer $accessToken")
|
|
||||||
currentStatus?.showComments(holder, api, "Bearer $accessToken")
|
|
||||||
|
|
||||||
//Activate double tap liking
|
currentStatus?.activateButtons(holder, api, "Bearer $accessToken")
|
||||||
currentStatus?.activateDoubleTapLiker(holder, api, "Bearer $accessToken")
|
|
||||||
return root
|
return root
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
package com.h.pixeldroid.fragments
|
package com.h.pixeldroid.fragments
|
||||||
|
|
||||||
|
import android.app.SearchManager
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Button
|
import android.widget.*
|
||||||
import android.widget.EditText
|
import androidx.appcompat.widget.SearchView
|
||||||
import android.widget.ImageView
|
import androidx.core.content.ContextCompat.getSystemService
|
||||||
import android.widget.ProgressBar
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
import com.google.android.material.textview.MaterialTextView
|
||||||
import com.h.pixeldroid.Pixeldroid
|
import com.h.pixeldroid.Pixeldroid
|
||||||
import com.h.pixeldroid.PostActivity
|
import com.h.pixeldroid.PostActivity
|
||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
|
@ -26,6 +28,12 @@ import com.h.pixeldroid.objects.DiscoverPosts
|
||||||
import com.h.pixeldroid.objects.Status
|
import com.h.pixeldroid.objects.Status
|
||||||
import com.h.pixeldroid.utils.DBUtils
|
import com.h.pixeldroid.utils.DBUtils
|
||||||
import com.h.pixeldroid.utils.ImageConverter
|
import com.h.pixeldroid.utils.ImageConverter
|
||||||
|
import com.mikepenz.iconics.IconicsDrawable
|
||||||
|
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||||
|
import com.mikepenz.iconics.utils.padding
|
||||||
|
import com.mikepenz.iconics.utils.paddingDp
|
||||||
|
import com.mikepenz.iconics.utils.sizeDp
|
||||||
|
import kotlinx.android.synthetic.main.fragment_search.*
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
@ -55,22 +63,30 @@ class SearchDiscoverFragment : Fragment() {
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
val view = inflater.inflate(R.layout.fragment_search, container, false)
|
val view = inflater.inflate(R.layout.fragment_search, container, false)
|
||||||
val button = view.findViewById<Button>(R.id.searchButton)
|
val search = view.findViewById<SearchView>(R.id.search)
|
||||||
val search = view.findViewById<EditText>(R.id.searchEditText)
|
|
||||||
|
|
||||||
(requireActivity().application as Pixeldroid).getAppComponent().inject(this)
|
(requireActivity().application as Pixeldroid).getAppComponent().inject(this)
|
||||||
|
|
||||||
button.setOnClickListener {
|
|
||||||
val intent = Intent(context, SearchActivity::class.java)
|
//Configure the search widget (see https://developer.android.com/guide/topics/search/search-dialog#ConfiguringWidget)
|
||||||
intent.putExtra("searchFeed", search.text.toString())
|
val searchManager = requireActivity().getSystemService(Context.SEARCH_SERVICE) as SearchManager
|
||||||
startActivity(intent)
|
search.setSearchableInfo(searchManager.getSearchableInfo(requireActivity().componentName))
|
||||||
}
|
|
||||||
|
search.isSubmitButtonEnabled = true
|
||||||
|
|
||||||
// Set posts RecyclerView as a grid with 3 columns
|
// Set posts RecyclerView as a grid with 3 columns
|
||||||
recycler = view.findViewById(R.id.discoverList)
|
recycler = view.findViewById(R.id.discoverList)
|
||||||
recycler.layoutManager = GridLayoutManager(requireContext(), 3)
|
recycler.layoutManager = GridLayoutManager(requireContext(), 3)
|
||||||
adapter = DiscoverRecyclerViewAdapter()
|
adapter = DiscoverRecyclerViewAdapter()
|
||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
|
|
||||||
|
val discoverText = view.findViewById<TextView>(R.id.discoverText)
|
||||||
|
|
||||||
|
discoverText.setCompoundDrawables(IconicsDrawable(requireContext(), GoogleMaterial.Icon.gmd_explore).apply {
|
||||||
|
sizeDp = 24
|
||||||
|
paddingDp = 20
|
||||||
|
}, null, null, null)
|
||||||
|
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.h.pixeldroid.fragments.feeds
|
package com.h.pixeldroid.fragments.feeds
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
@ -43,7 +44,7 @@ open class AccountListFragment : FeedFragment() {
|
||||||
|
|
||||||
//RequestBuilder that is re-used for every image
|
//RequestBuilder that is re-used for every image
|
||||||
profilePicRequest = Glide.with(this)
|
profilePicRequest = Glide.with(this)
|
||||||
.asDrawable().apply(RequestOptions().circleCrop())
|
.asDrawable().dontAnimate().apply(RequestOptions().circleCrop())
|
||||||
.placeholder(R.drawable.ic_default_user)
|
.placeholder(R.drawable.ic_default_user)
|
||||||
|
|
||||||
adapter = AccountsRecyclerViewAdapter()
|
adapter = AccountsRecyclerViewAdapter()
|
||||||
|
@ -160,9 +161,11 @@ open class AccountListFragment : FeedFragment() {
|
||||||
|
|
||||||
override fun onBindViewHolder(holder : ViewHolder, position : Int) {
|
override fun onBindViewHolder(holder : ViewHolder, position : Int) {
|
||||||
val account = getItem(position) ?: return
|
val account = getItem(position) ?: return
|
||||||
profilePicRequest.load(account.avatar_static).into(holder.avatar)
|
profilePicRequest.load(account.avatar).into(holder.avatar)
|
||||||
|
|
||||||
holder.username.text = account.username
|
holder.username.text = account.username
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
holder.acct.text = "@${account.acct}"
|
||||||
|
|
||||||
holder.mView.setOnClickListener { account.openProfile(context) }
|
holder.mView.setOnClickListener { account.openProfile(context) }
|
||||||
}
|
}
|
||||||
|
@ -170,6 +173,7 @@ open class AccountListFragment : FeedFragment() {
|
||||||
inner class ViewHolder(val mView : View) : RecyclerView.ViewHolder(mView) {
|
inner class ViewHolder(val mView : View) : RecyclerView.ViewHolder(mView) {
|
||||||
val avatar : ImageView = mView.account_entry_avatar
|
val avatar : ImageView = mView.account_entry_avatar
|
||||||
val username : TextView = mView.account_entry_username
|
val username : TextView = mView.account_entry_username
|
||||||
|
val acct: TextView = mView.account_entry_acct
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPreloadItems(position : Int) : MutableList<Account> {
|
override fun getPreloadItems(position : Int) : MutableList<Account> {
|
||||||
|
|
|
@ -117,7 +117,7 @@ open class FeedFragment: Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do nothing here, it is expected to pull to refresh to load newer notifications
|
* Do nothing here, it is expected to pull to refresh to load newer items
|
||||||
*/
|
*/
|
||||||
override fun loadBefore(params: LoadParams<ObjectId>, callback: LoadCallback<APIObject>) {}
|
override fun loadBefore(params: LoadParams<ObjectId>, callback: LoadCallback<APIObject>) {}
|
||||||
|
|
||||||
|
|
|
@ -172,8 +172,8 @@ class OfflineFeedFragment: Fragment() {
|
||||||
holder.itemView.postTabs.visibility = View.VISIBLE
|
holder.itemView.postTabs.visibility = View.VISIBLE
|
||||||
val tabs : ArrayList<ImageFragment> = ArrayList()
|
val tabs : ArrayList<ImageFragment> = ArrayList()
|
||||||
//Fill the tabs with each mediaAttachment
|
//Fill the tabs with each mediaAttachment
|
||||||
for(media in post.media_urls) {
|
for((index, media) in post.media_urls.withIndex()) {
|
||||||
tabs.add(ImageFragment.newInstance(media))
|
tabs.add(ImageFragment.newInstance(media, "Photo $index"))
|
||||||
}
|
}
|
||||||
holder.itemView.postPager.adapter = object : FragmentStateAdapter(this@OfflineFeedFragment) {
|
holder.itemView.postPager.adapter = object : FragmentStateAdapter(this@OfflineFeedFragment) {
|
||||||
override fun createFragment(position: Int): Fragment {
|
override fun createFragment(position: Int): Fragment {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.paging.PagedList
|
import androidx.paging.PagedList
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import at.connyduck.sparkbutton.SparkButton
|
import at.connyduck.sparkbutton.SparkButton
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.ListPreloader
|
import com.bumptech.glide.ListPreloader
|
||||||
|
@ -60,7 +61,7 @@ abstract class PostsFeedFragment : FeedFragment() {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
val content = makeContent()
|
val content = makeContent()
|
||||||
content.observe(viewLifecycleOwner,
|
content.observe(viewLifecycleOwner,
|
||||||
Observer { c ->
|
{ c ->
|
||||||
adapter.submitList(c)
|
adapter.submitList(c)
|
||||||
//after a refresh is done we need to stop the pull to refresh spinner
|
//after a refresh is done we need to stop the pull to refresh spinner
|
||||||
swipeRefreshLayout.isRefreshing = false
|
swipeRefreshLayout.isRefreshing = false
|
||||||
|
@ -99,29 +100,12 @@ abstract class PostsFeedFragment : FeedFragment() {
|
||||||
val post = getItem(position) ?: return
|
val post = getItem(position) ?: return
|
||||||
val metrics = context.resources.displayMetrics
|
val metrics = context.resources.displayMetrics
|
||||||
//Limit the height of the different images
|
//Limit the height of the different images
|
||||||
holder.profilePic.maxHeight = metrics.heightPixels
|
holder.postPic.maxHeight = metrics.heightPixels * 3/4
|
||||||
holder.postPic.maxHeight = metrics.heightPixels
|
|
||||||
|
|
||||||
//Setup the post layout
|
//Setup the post layout
|
||||||
post.setupPost(holder.postView, picRequest, this@PostsFeedFragment, domain, false)
|
post.setupPost(holder.postView, picRequest, this@PostsFeedFragment, domain, false)
|
||||||
|
|
||||||
//Set the special HTML text
|
post.activateButtons(holder, api, credential)
|
||||||
post.setDescription(holder.postView, api, credential)
|
|
||||||
|
|
||||||
//Activate liker
|
|
||||||
post.activateLiker(holder, api, credential, post.favourited ?: false)
|
|
||||||
|
|
||||||
//Activate double tap liking
|
|
||||||
post.activateDoubleTapLiker(holder, api, credential)
|
|
||||||
|
|
||||||
//Show comments
|
|
||||||
post.showComments(holder, api, credential)
|
|
||||||
|
|
||||||
//Activate Commenter
|
|
||||||
post.activateCommenter(holder, api, credential)
|
|
||||||
|
|
||||||
//Activate Reblogger
|
|
||||||
post.activateReblogger(holder, api ,credential, post.reblogged ?: false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPreloadItems(position: Int): MutableList<Status> {
|
override fun getPreloadItems(position: Int): MutableList<Status> {
|
||||||
|
@ -160,4 +144,7 @@ class PostViewHolder(val postView: View, val context: android.content.Context) :
|
||||||
val postDate : TextView = postView.findViewById(R.id.postDate)
|
val postDate : TextView = postView.findViewById(R.id.postDate)
|
||||||
val postDomain : TextView = postView.findViewById(R.id.postDomain)
|
val postDomain : TextView = postView.findViewById(R.id.postDomain)
|
||||||
val sensitiveW : TextView = postView.findViewById(R.id.sensitiveWarning)
|
val sensitiveW : TextView = postView.findViewById(R.id.sensitiveWarning)
|
||||||
|
val postPager : ViewPager2 = postView.findViewById(R.id.postPager)
|
||||||
|
|
||||||
|
val more : ImageButton = postView.findViewById(R.id.status_more)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.h.pixeldroid.objects
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
data class Report(
|
||||||
|
val id: String
|
||||||
|
): Serializable
|
|
@ -1,29 +1,36 @@
|
||||||
package com.h.pixeldroid.objects
|
package com.h.pixeldroid.objects
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.app.DownloadManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.database.Cursor
|
||||||
import android.graphics.ColorMatrixColorFilter
|
import android.graphics.ColorMatrixColorFilter
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Environment
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
|
import androidx.core.net.toUri
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
import com.bumptech.glide.RequestBuilder
|
import com.bumptech.glide.RequestBuilder
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
|
import com.h.pixeldroid.ReportActivity
|
||||||
import com.h.pixeldroid.api.PixelfedAPI
|
import com.h.pixeldroid.api.PixelfedAPI
|
||||||
import com.h.pixeldroid.fragments.ImageFragment
|
import com.h.pixeldroid.fragments.ImageFragment
|
||||||
import com.h.pixeldroid.fragments.feeds.postFeeds.PostViewHolder
|
import com.h.pixeldroid.fragments.feeds.postFeeds.PostViewHolder
|
||||||
import com.h.pixeldroid.utils.HtmlUtils.Companion.getDomain
|
import com.h.pixeldroid.utils.HtmlUtils.Companion.getDomain
|
||||||
import com.h.pixeldroid.utils.HtmlUtils.Companion.parseHTMLText
|
import com.h.pixeldroid.utils.HtmlUtils.Companion.parseHTMLText
|
||||||
import com.h.pixeldroid.utils.ImageConverter
|
import com.h.pixeldroid.utils.ImageConverter
|
||||||
import com.h.pixeldroid.utils.ImageUtils.Companion.downloadImage
|
|
||||||
import com.h.pixeldroid.utils.PostUtils.Companion.censorColorMatrix
|
import com.h.pixeldroid.utils.PostUtils.Companion.censorColorMatrix
|
||||||
import com.h.pixeldroid.utils.PostUtils.Companion.likePostCall
|
import com.h.pixeldroid.utils.PostUtils.Companion.likePostCall
|
||||||
import com.h.pixeldroid.utils.PostUtils.Companion.postComment
|
import com.h.pixeldroid.utils.PostUtils.Companion.postComment
|
||||||
|
@ -39,8 +46,9 @@ import com.karumi.dexter.listener.PermissionDeniedResponse
|
||||||
import com.karumi.dexter.listener.PermissionGrantedResponse
|
import com.karumi.dexter.listener.PermissionGrantedResponse
|
||||||
import com.karumi.dexter.listener.single.BasePermissionListener
|
import com.karumi.dexter.listener.single.BasePermissionListener
|
||||||
import kotlinx.android.synthetic.main.post_fragment.view.*
|
import kotlinx.android.synthetic.main.post_fragment.view.*
|
||||||
|
import java.io.File
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.util.Date
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -115,39 +123,70 @@ data class Status(
|
||||||
return context.getString(R.string.shares).format(reblogs_count.toString())
|
return context.getString(R.string.shares).format(reblogs_count.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getStatusDomain(domain : String) : String {
|
private fun getStatusDomain(domain: String) : String {
|
||||||
val accountDomain = getDomain(account!!.url)
|
val accountDomain = getDomain(account!!.url)
|
||||||
return if(getDomain(domain) == accountDomain) ""
|
return if(getDomain(domain) == accountDomain) ""
|
||||||
else " from $accountDomain"
|
else " from $accountDomain"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupPostPics(rootView: View, request: RequestBuilder<Drawable>, homeFragment: Fragment) {
|
private fun setupPostPics(
|
||||||
|
rootView: View,
|
||||||
|
request: RequestBuilder<Drawable>,
|
||||||
|
homeFragment: Fragment
|
||||||
|
) {
|
||||||
|
|
||||||
// Standard layout
|
// Standard layout
|
||||||
rootView.postPicture.visibility = VISIBLE
|
rootView.postPicture.visibility = VISIBLE
|
||||||
rootView.postPager.visibility = GONE
|
rootView.postPager.visibility = GONE
|
||||||
rootView.postTabs.visibility = GONE
|
rootView.postTabs.visibility = GONE
|
||||||
|
|
||||||
if (sensitive!!) {
|
|
||||||
setupSensitiveLayout(rootView, request, homeFragment)
|
if(media_attachments?.size == 1) {
|
||||||
request.load(this.getPostUrl()).into(rootView.postPicture)
|
request.load(this.getPostUrl()).into(rootView.postPicture)
|
||||||
|
val imgDescription = media_attachments[0].description.orEmpty().ifEmpty { rootView.context.getString(R.string.no_description) }
|
||||||
|
rootView.postPicture.contentDescription = imgDescription
|
||||||
|
|
||||||
} else {
|
rootView.postPicture.setOnLongClickListener {
|
||||||
rootView.sensitiveWarning.visibility = GONE
|
Snackbar.make(it, imgDescription, Snackbar.LENGTH_SHORT).show()
|
||||||
|
true
|
||||||
if(media_attachments?.size == 1) {
|
|
||||||
request.load(this.getPostUrl()).into(rootView.postPicture)
|
|
||||||
|
|
||||||
} else if(media_attachments?.size!! > 1) {
|
|
||||||
setupTabsLayout(rootView, request, homeFragment)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imagePopUpMenu(rootView, homeFragment.requireActivity())
|
} else if(media_attachments?.size!! > 1) {
|
||||||
|
setupTabsLayout(rootView, request, homeFragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sensitive!!) {
|
||||||
|
setupSensitiveLayout(rootView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupTabsLayout(rootView: View, request: RequestBuilder<Drawable>, homeFragment: Fragment) {
|
private fun setupSensitiveLayout(view: View) {
|
||||||
|
|
||||||
|
// Set dark layout and warning message
|
||||||
|
view.sensitiveWarning.visibility = VISIBLE
|
||||||
|
view.postPicture.colorFilter = ColorMatrixColorFilter(censorColorMatrix())
|
||||||
|
|
||||||
|
fun uncensorPicture(view: View) {
|
||||||
|
view.sensitiveWarning.visibility = GONE
|
||||||
|
view.postPicture.colorFilter = ColorMatrixColorFilter(uncensorColorMatrix())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
view.findViewById<TextView>(R.id.sensitiveWarning).setOnClickListener {
|
||||||
|
uncensorPicture(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
view.findViewById<ImageView>(R.id.postPicture).setOnClickListener {
|
||||||
|
uncensorPicture(view)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupTabsLayout(
|
||||||
|
rootView: View,
|
||||||
|
request: RequestBuilder<Drawable>,
|
||||||
|
homeFragment: Fragment
|
||||||
|
) {
|
||||||
//Only show the viewPager and tabs
|
//Only show the viewPager and tabs
|
||||||
rootView.postPicture.visibility = GONE
|
rootView.postPicture.visibility = GONE
|
||||||
rootView.postPager.visibility = VISIBLE
|
rootView.postPager.visibility = VISIBLE
|
||||||
|
@ -157,7 +196,7 @@ data class Status(
|
||||||
|
|
||||||
//Fill the tabs with each mediaAttachment
|
//Fill the tabs with each mediaAttachment
|
||||||
for(media in media_attachments!!) {
|
for(media in media_attachments!!) {
|
||||||
tabs.add(ImageFragment.newInstance(media.url!!))
|
tabs.add(ImageFragment.newInstance(media.url!!, media.description.orEmpty()))
|
||||||
}
|
}
|
||||||
|
|
||||||
setupTabs(tabs, rootView, homeFragment)
|
setupTabs(tabs, rootView, homeFragment)
|
||||||
|
@ -185,8 +224,8 @@ data class Status(
|
||||||
rootView: View,
|
rootView: View,
|
||||||
request: RequestBuilder<Drawable>,
|
request: RequestBuilder<Drawable>,
|
||||||
homeFragment: Fragment,
|
homeFragment: Fragment,
|
||||||
domain : String,
|
domain: String,
|
||||||
isActivity : Boolean
|
isActivity: Boolean
|
||||||
) {
|
) {
|
||||||
//Setup username as a button that opens the profile
|
//Setup username as a button that opens the profile
|
||||||
rootView.findViewById<TextView>(R.id.username).apply {
|
rootView.findViewById<TextView>(R.id.username).apply {
|
||||||
|
@ -233,10 +272,8 @@ data class Status(
|
||||||
rootView.findViewById<LinearLayout>(R.id.commentIn).visibility = GONE
|
rootView.findViewById<LinearLayout>(R.id.commentIn).visibility = GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setDescription(rootView: View, api : PixelfedAPI, credential: String) {
|
fun setDescription(rootView: View, api: PixelfedAPI, credential: String) {
|
||||||
val desc = rootView.findViewById<TextView>(R.id.description)
|
rootView.findViewById<TextView>(R.id.description).apply {
|
||||||
|
|
||||||
desc.apply {
|
|
||||||
if (content.isNullOrBlank()) {
|
if (content.isNullOrBlank()) {
|
||||||
visibility = GONE
|
visibility = GONE
|
||||||
} else {
|
} else {
|
||||||
|
@ -246,11 +283,35 @@ data class Status(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun activateButtons(holder: PostViewHolder, api: PixelfedAPI, credential: String){
|
||||||
|
|
||||||
|
//Set the special HTML text
|
||||||
|
setDescription(holder.postView, api, credential)
|
||||||
|
|
||||||
|
//Activate onclickListeners
|
||||||
|
activateLiker(
|
||||||
|
holder, api, credential,
|
||||||
|
this.favourited ?: false
|
||||||
|
)
|
||||||
|
activateReblogger(
|
||||||
|
holder, api, credential,
|
||||||
|
this.reblogged ?: false
|
||||||
|
)
|
||||||
|
activateCommenter(holder, api, credential)
|
||||||
|
|
||||||
|
showComments(holder, api, credential)
|
||||||
|
|
||||||
|
//Activate double tap liking
|
||||||
|
activateDoubleTapLiker(holder, api, credential)
|
||||||
|
|
||||||
|
activateMoreButton(holder)
|
||||||
|
}
|
||||||
|
|
||||||
fun activateReblogger(
|
fun activateReblogger(
|
||||||
holder : PostViewHolder,
|
holder: PostViewHolder,
|
||||||
api : PixelfedAPI,
|
api: PixelfedAPI,
|
||||||
credential: String,
|
credential: String,
|
||||||
isReblogged : Boolean
|
isReblogged: Boolean
|
||||||
) {
|
) {
|
||||||
holder.reblogger.apply {
|
holder.reblogger.apply {
|
||||||
//Set initial button state
|
//Set initial button state
|
||||||
|
@ -271,8 +332,165 @@ data class Status(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun downloadImage(context: Context, url: String, view: View, share: Boolean = false) {
|
||||||
|
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
|
||||||
|
|
||||||
|
val downloadUri = Uri.parse(url)
|
||||||
|
|
||||||
|
val title = url.substringAfterLast("/")
|
||||||
|
val request = DownloadManager.Request(downloadUri).apply {
|
||||||
|
setTitle(title)
|
||||||
|
if(!share) {
|
||||||
|
val directory = File(Environment.DIRECTORY_PICTURES)
|
||||||
|
if (!directory.exists()) {
|
||||||
|
directory.mkdirs()
|
||||||
|
}
|
||||||
|
setDestinationInExternalPublicDir(directory.toString(), title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val downloadId = downloadManager.enqueue(request)
|
||||||
|
val query = DownloadManager.Query().setFilterById(downloadId)
|
||||||
|
|
||||||
|
Thread {
|
||||||
|
|
||||||
|
var msg = ""
|
||||||
|
var lastMsg = ""
|
||||||
|
var downloading = true
|
||||||
|
|
||||||
|
while (downloading) {
|
||||||
|
val cursor: Cursor = downloadManager.query(query)
|
||||||
|
cursor.moveToFirst()
|
||||||
|
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
|
||||||
|
== DownloadManager.STATUS_SUCCESSFUL
|
||||||
|
) {
|
||||||
|
downloading = false
|
||||||
|
}
|
||||||
|
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
|
||||||
|
if (!share) {
|
||||||
|
msg = when (status) {
|
||||||
|
DownloadManager.STATUS_FAILED ->
|
||||||
|
context.getString(R.string.image_download_failed)
|
||||||
|
DownloadManager.STATUS_RUNNING ->
|
||||||
|
context.getString(R.string.image_download_downloading)
|
||||||
|
DownloadManager.STATUS_SUCCESSFUL ->
|
||||||
|
context.getString(R.string.image_download_success)
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
if (msg != lastMsg && msg != "") {
|
||||||
|
Snackbar.make(view, msg, Snackbar.LENGTH_SHORT).show()
|
||||||
|
lastMsg = msg
|
||||||
|
}
|
||||||
|
} else if (status == DownloadManager.STATUS_SUCCESSFUL) {
|
||||||
|
|
||||||
|
val ext = url.substringAfterLast(".", "*")
|
||||||
|
|
||||||
|
val path = cursor.getString(
|
||||||
|
cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)
|
||||||
|
)
|
||||||
|
val file = path.toUri()
|
||||||
|
|
||||||
|
val shareIntent: Intent = Intent.createChooser(Intent().apply {
|
||||||
|
action = Intent.ACTION_SEND
|
||||||
|
putExtra(Intent.EXTRA_STREAM, file)
|
||||||
|
data = file
|
||||||
|
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
type = "image/$ext"
|
||||||
|
}, null)
|
||||||
|
|
||||||
|
context.startActivity(shareIntent)
|
||||||
|
}
|
||||||
|
cursor.close()
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun activateMoreButton(holder: PostViewHolder){
|
||||||
|
holder.more.setOnClickListener {
|
||||||
|
PopupMenu(it.context, it).apply {
|
||||||
|
setOnMenuItemClickListener { item ->
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.post_more_menu_report -> {
|
||||||
|
val intent = Intent(it.context, ReportActivity::class.java)
|
||||||
|
intent.putExtra(POST_TAG, this@Status)
|
||||||
|
startActivity(it.context, intent, null)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
R.id.post_more_menu_share_link -> {
|
||||||
|
val share = Intent.createChooser(Intent().apply {
|
||||||
|
action = Intent.ACTION_SEND
|
||||||
|
putExtra(Intent.EXTRA_TEXT, uri)
|
||||||
|
|
||||||
|
type = "text/plain"
|
||||||
|
|
||||||
|
putExtra(Intent.EXTRA_TITLE, content)
|
||||||
|
}, null)
|
||||||
|
startActivity(it.context, share, null)
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
R.id.post_more_menu_save_to_gallery -> {
|
||||||
|
Dexter.withContext(holder.context)
|
||||||
|
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
.withListener(object : BasePermissionListener() {
|
||||||
|
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
|
||||||
|
Toast.makeText(
|
||||||
|
holder.context,
|
||||||
|
holder.context.getString(R.string.write_permission_download_pic),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {
|
||||||
|
downloadImage(
|
||||||
|
holder.context,
|
||||||
|
media_attachments?.get(holder.postPager.currentItem)?.url
|
||||||
|
?: "",
|
||||||
|
holder.postView
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}).check()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
R.id.post_more_menu_share_picture -> {
|
||||||
|
Dexter.withContext(holder.context)
|
||||||
|
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
.withListener(object : BasePermissionListener() {
|
||||||
|
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
|
||||||
|
Toast.makeText(
|
||||||
|
holder.context,
|
||||||
|
holder.context.getString(R.string.write_permission_share_pic),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {
|
||||||
|
downloadImage(
|
||||||
|
holder.context,
|
||||||
|
media_attachments?.get(holder.postPager.currentItem)?.url
|
||||||
|
?: "",
|
||||||
|
holder.postView,
|
||||||
|
share = true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}).check()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inflate(R.menu.post_more_menu)
|
||||||
|
if(media_attachments.isNullOrEmpty()) {
|
||||||
|
//make sure to disable image-related things if there aren't any
|
||||||
|
menu.setGroupVisible(R.id.post_more_group_picture, false)
|
||||||
|
}
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun activateDoubleTapLiker(
|
fun activateDoubleTapLiker(
|
||||||
holder : PostViewHolder,
|
holder: PostViewHolder,
|
||||||
api: PixelfedAPI,
|
api: PixelfedAPI,
|
||||||
credential: String
|
credential: String
|
||||||
) {
|
) {
|
||||||
|
@ -305,7 +523,7 @@ data class Status(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun activateLiker(
|
fun activateLiker(
|
||||||
holder : PostViewHolder,
|
holder: PostViewHolder,
|
||||||
api: PixelfedAPI,
|
api: PixelfedAPI,
|
||||||
credential: String,
|
credential: String,
|
||||||
isLiked: Boolean
|
isLiked: Boolean
|
||||||
|
@ -332,7 +550,7 @@ data class Status(
|
||||||
|
|
||||||
|
|
||||||
fun showComments(
|
fun showComments(
|
||||||
holder : PostViewHolder,
|
holder: PostViewHolder,
|
||||||
api: PixelfedAPI,
|
api: PixelfedAPI,
|
||||||
credential: String
|
credential: String
|
||||||
) {
|
) {
|
||||||
|
@ -353,19 +571,23 @@ data class Status(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun activateCommenter(
|
fun activateCommenter(
|
||||||
holder : PostViewHolder,
|
holder: PostViewHolder,
|
||||||
api: PixelfedAPI,
|
api: PixelfedAPI,
|
||||||
credential: String
|
credential: String
|
||||||
) {
|
) {
|
||||||
//Toggle comment button
|
//Toggle comment button
|
||||||
toggleCommentInput(holder)
|
toggleCommentInput(holder)
|
||||||
|
|
||||||
//Activate commenter
|
//Activate commenterpostPicture
|
||||||
holder.submitCmnt.setOnClickListener {
|
holder.submitCmnt.setOnClickListener {
|
||||||
val textIn = holder.comment.text
|
val textIn = holder.comment.text
|
||||||
//Open text input
|
//Open text input
|
||||||
if(textIn.isNullOrEmpty()) {
|
if(textIn.isNullOrEmpty()) {
|
||||||
Toast.makeText(holder.context, holder.context.getString(R.string.empty_comment), Toast.LENGTH_SHORT).show()
|
Toast.makeText(
|
||||||
|
holder.context,
|
||||||
|
holder.context.getString(R.string.empty_comment),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
//Post the comment
|
//Post the comment
|
||||||
|
@ -377,78 +599,4 @@ data class Status(
|
||||||
enum class Visibility : Serializable {
|
enum class Visibility : Serializable {
|
||||||
public, unlisted, private, direct
|
public, unlisted, private, direct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun imagePopUpMenu(view: View, activity: FragmentActivity) {
|
|
||||||
val anchor = view.findViewById<FrameLayout>(R.id.post_fragment_image_popup_menu_anchor)
|
|
||||||
if (!media_attachments.isNullOrEmpty() && media_attachments.size == 1) {
|
|
||||||
view.findViewById<ImageView>(R.id.postPicture).setOnLongClickListener {
|
|
||||||
PopupMenu(view.context, anchor).apply {
|
|
||||||
setOnMenuItemClickListener { item ->
|
|
||||||
when (item.itemId) {
|
|
||||||
R.id.image_popup_menu_save_to_gallery -> {
|
|
||||||
Dexter.withContext(view.context)
|
|
||||||
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
.withListener(object: BasePermissionListener() {
|
|
||||||
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
|
|
||||||
Toast.makeText(view.context, view.context.getString(R.string.write_permission_download_pic), Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {
|
|
||||||
downloadImage(activity, getPostUrl()!!)
|
|
||||||
}
|
|
||||||
}).check()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
R.id.image_popup_menu_share_picture -> {
|
|
||||||
Dexter.withContext(view.context)
|
|
||||||
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
.withListener(object: BasePermissionListener() {
|
|
||||||
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
|
|
||||||
Toast.makeText(view.context, view.context.getString(R.string.write_permission_share_pic), Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {
|
|
||||||
downloadImage(activity, getPostUrl()!!, share = true)
|
|
||||||
}
|
|
||||||
}).check()
|
|
||||||
true
|
|
||||||
}
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inflate(R.menu.image_popup_menu)
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupSensitiveLayout(view: View, request: RequestBuilder<Drawable>, homeFragment: Fragment) {
|
|
||||||
|
|
||||||
// Set dark layout and warning message
|
|
||||||
view.sensitiveWarning.visibility = VISIBLE
|
|
||||||
view.postPicture.colorFilter = ColorMatrixColorFilter(censorColorMatrix())
|
|
||||||
|
|
||||||
fun uncensorPicture(view: View) {
|
|
||||||
if (!media_attachments.isNullOrEmpty()) {
|
|
||||||
view.sensitiveWarning.visibility = GONE
|
|
||||||
view.postPicture.colorFilter = ColorMatrixColorFilter(uncensorColorMatrix())
|
|
||||||
|
|
||||||
if (media_attachments.size > 1)
|
|
||||||
setupTabsLayout(view, request, homeFragment)
|
|
||||||
}
|
|
||||||
imagePopUpMenu(view, homeFragment.requireActivity())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
view.findViewById<TextView>(R.id.sensitiveWarning).setOnClickListener {
|
|
||||||
uncensorPicture(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
view.findViewById<ImageView>(R.id.postPicture).setOnClickListener {
|
|
||||||
uncensorPicture(view)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,99 +0,0 @@
|
||||||
package com.h.pixeldroid.utils
|
|
||||||
|
|
||||||
import android.app.DownloadManager
|
|
||||||
import android.content.ContentValues
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.database.Cursor
|
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Environment
|
|
||||||
import android.provider.MediaStore.Images
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
|
||||||
import com.h.pixeldroid.R
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
|
|
||||||
class ImageUtils {
|
|
||||||
companion object {
|
|
||||||
fun downloadImage(activity: FragmentActivity, url: String, share: Boolean = false) {
|
|
||||||
val context = activity.applicationContext
|
|
||||||
var msg = ""
|
|
||||||
var lastMsg = ""
|
|
||||||
val directory = File(Environment.DIRECTORY_PICTURES)
|
|
||||||
if (!directory.exists()) {
|
|
||||||
directory.mkdirs()
|
|
||||||
}
|
|
||||||
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE)
|
|
||||||
as DownloadManager
|
|
||||||
val downloadUri = Uri.parse(url)
|
|
||||||
val title = url.substring(url.lastIndexOf("/") + 1)
|
|
||||||
val ext = url.substring(url.lastIndexOf("."))
|
|
||||||
val request = DownloadManager.Request(downloadUri).apply {
|
|
||||||
setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI
|
|
||||||
or DownloadManager.Request.NETWORK_MOBILE)
|
|
||||||
setTitle(title)
|
|
||||||
setDestinationInExternalPublicDir(directory.toString(), title)
|
|
||||||
}
|
|
||||||
val downloadId = downloadManager.enqueue(request)
|
|
||||||
val query = DownloadManager.Query().setFilterById(downloadId)
|
|
||||||
|
|
||||||
Thread(Runnable {
|
|
||||||
var downloading = true
|
|
||||||
while (downloading) {
|
|
||||||
val cursor: Cursor = downloadManager.query(query)
|
|
||||||
cursor.moveToFirst()
|
|
||||||
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
|
|
||||||
== DownloadManager.STATUS_SUCCESSFUL) {
|
|
||||||
downloading = false
|
|
||||||
}
|
|
||||||
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
|
|
||||||
if(!share) {
|
|
||||||
msg = when (status) {
|
|
||||||
DownloadManager.STATUS_FAILED ->
|
|
||||||
context.getString(R.string.image_download_failed)
|
|
||||||
DownloadManager.STATUS_RUNNING ->
|
|
||||||
context.getString(R.string.image_download_downloading)
|
|
||||||
DownloadManager.STATUS_SUCCESSFUL ->
|
|
||||||
context.getString(R.string.image_download_success)
|
|
||||||
else -> ""
|
|
||||||
}
|
|
||||||
if (msg != lastMsg && msg != "") {
|
|
||||||
activity.runOnUiThread {
|
|
||||||
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
lastMsg = msg
|
|
||||||
}
|
|
||||||
} else if (status == DownloadManager.STATUS_SUCCESSFUL) {
|
|
||||||
val icon: Bitmap = BitmapFactory.decodeFile(
|
|
||||||
Uri.parse(cursor.getString(
|
|
||||||
cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)
|
|
||||||
)).path
|
|
||||||
)
|
|
||||||
val intentShare = Intent(Intent.ACTION_SEND)
|
|
||||||
intentShare.type = "image/$ext"
|
|
||||||
val values = ContentValues()
|
|
||||||
values.put(Images.Media.TITLE, title)
|
|
||||||
values.put(Images.Media.MIME_TYPE, "image/$ext")
|
|
||||||
val uri: Uri = context.contentResolver.insert(
|
|
||||||
Images.Media.EXTERNAL_CONTENT_URI,
|
|
||||||
values
|
|
||||||
)!!
|
|
||||||
try {
|
|
||||||
val outstream = context.contentResolver.openOutputStream(uri)!!
|
|
||||||
icon.compress(Bitmap.CompressFormat.JPEG, 100, outstream)
|
|
||||||
outstream.close()
|
|
||||||
} catch(e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
intentShare.putExtra(Intent.EXTRA_STREAM, uri)
|
|
||||||
activity.startActivity(Intent.createChooser(intentShare, context.getString(R.string.share_image)))
|
|
||||||
}
|
|
||||||
cursor.close()
|
|
||||||
}
|
|
||||||
}).start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M19,7v2.99s-1.99,0.01 -2,0L17,7h-3s0.01,-1.99 0,-2h3L17,2h2v3h3v2h-3zM16,11L16,8h-3L13,5L5,5c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2v-8h-3zM5,19l3,-4 2,3 3,-4 4,5L5,19z"
|
||||||
|
android:fillColor="#FFFFFF"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M19,7v2.99s-1.99,0.01 -2,0L17,7h-3s0.01,-1.99 0,-2h3L17,2h2v3h3v2h-3zM16,11L16,8h-3L13,5L5,5c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2v-8h-3zM5,19l3,-4 2,3 3,-4 4,5L5,19z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/account_entry_avatar"
|
android:id="@+id/account_entry_avatar"
|
||||||
|
@ -11,20 +11,31 @@
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
|
android:contentDescription="TODO"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:src="@drawable/ic_default_user"
|
tools:src="@drawable/ic_default_user" />
|
||||||
android:contentDescription="TODO" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/account_entry_username"
|
android:id="@+id/account_entry_username"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="28dp"
|
android:textStyle="bold"
|
||||||
android:text="TextView"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/account_entry_avatar"
|
app:layout_constraintStart_toEndOf="@+id/account_entry_avatar"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="@+id/account_entry_avatar"
|
||||||
|
tools:text="Username" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/account_entry_acct"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/account_entry_avatar"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/account_entry_username"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/account_entry_username"
|
||||||
|
tools:text="\@username@domain.tld" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".CameraActivity">
|
||||||
|
|
||||||
|
<androidx.fragment.app.FragmentContainerView
|
||||||
|
android:id="@+id/camera_activity_fragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -10,22 +10,27 @@
|
||||||
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/main_activity_main_linear_layout"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
<androidx.appcompat.widget.Toolbar
|
android:id="@+id/main_activity_main_linear_layout"
|
||||||
android:id="@+id/main_toolbar"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/colorPrimaryTab"
|
android:orientation="horizontal"
|
||||||
app:contentInsetStartWithNavigation="0dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
app:navigationContentDescription="Open drawer menu"
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
app:navigationIcon="@drawable/ic_baseline_menu_24">
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/main_drawer_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/colorPrimaryTab"
|
||||||
|
android:contentDescription="@string/open_drawer_menu"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:src="@drawable/ic_baseline_menu_24" />
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
android:id="@+id/tabs"
|
android:id="@+id/tabs"
|
||||||
|
@ -36,19 +41,17 @@
|
||||||
app:tabMaxWidth="0dp"
|
app:tabMaxWidth="0dp"
|
||||||
app:tabMode="fixed"
|
app:tabMode="fixed"
|
||||||
app:tabUnboundedRipple="false" />
|
app:tabUnboundedRipple="false" />
|
||||||
|
</LinearLayout>
|
||||||
</androidx.appcompat.widget.Toolbar>
|
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/view_pager"
|
android:id="@+id/view_pager"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/main_toolbar"
|
app:layout_constraintBottom_toTopOf="@+id/main_activity_main_linear_layout"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/toolbar" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
<androidx.constraintlayout.widget.Guideline
|
<androidx.constraintlayout.widget.Guideline
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -84,14 +84,4 @@
|
||||||
app:layout_constraintRight_toRightOf="@+id/right_guideline"
|
app:layout_constraintRight_toRightOf="@+id/right_guideline"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline" />
|
app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@color/colorPrimaryActionBar"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -17,15 +17,19 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<ScrollView
|
||||||
android:id="@+id/postFragmentSingle"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="0dp"
|
android:layout_height="match_parent">
|
||||||
android:layout_height="0dp"
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:visibility="gone"
|
android:id="@+id/postFragmentSingle"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_width="match_parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:visibility="gone"
|
||||||
app:layout_constraintTop_toTopOf="parent" >
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" >
|
||||||
|
</androidx.fragment.app.FragmentContainerView>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
</androidx.fragment.app.FragmentContainerView>
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -42,17 +42,29 @@
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<com.mikepenz.iconics.view.IconicsTextView
|
||||||
|
android:id="@+id/upload_completed_textview"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="@string/media_upload_completed"
|
||||||
|
android:textColor="@android:color/holo_green_light"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:visibility="invisible"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/image_grid"
|
android:id="@+id/image_grid"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:padding="16dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/postTextInputLayout"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toBottomOf="@id/upload_completed_textview" />
|
||||||
>
|
|
||||||
|
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/buttonConstraints"
|
android:id="@+id/buttonConstraints"
|
||||||
|
@ -61,7 +73,7 @@
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/textInputLayout2">
|
app:layout_constraintTop_toTopOf="@id/postTextInputLayout">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/post_creation_send_button"
|
android:id="@+id/post_creation_send_button"
|
||||||
|
@ -70,7 +82,7 @@
|
||||||
android:backgroundTint="@color/colorButtonBg"
|
android:backgroundTint="@color/colorButtonBg"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:text="@string/send"
|
android:text="@string/post"
|
||||||
android:textColor="@color/colorButtonText"
|
android:textColor="@color/colorButtonText"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -93,12 +105,12 @@
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toTopOf="@id/textInputLayout2"
|
app:layout_constraintBottom_toTopOf="@id/postTextInputLayout"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/textInputLayout2"
|
android:id="@+id/postTextInputLayout"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/description"
|
android:hint="@string/description"
|
||||||
|
@ -121,16 +133,4 @@
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<com.mikepenz.iconics.view.IconicsTextView
|
|
||||||
android:id="@+id/upload_completed_textview"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:text="@string/media_upload_completed"
|
|
||||||
android:textColor="@android:color/holo_green_light"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -6,7 +6,7 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ProfileActivity">
|
tools:context=".ProfileActivity">
|
||||||
|
|
||||||
<ScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
@ -165,10 +165,11 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_margin="5dp"
|
android:layout_margin="5dp"
|
||||||
|
android:nestedScrollingEnabled="false"
|
||||||
app:layoutManager="LinearLayoutManager"
|
app:layoutManager="LinearLayoutManager"
|
||||||
tools:context=".fragments.ProfileFragment"
|
tools:context=".fragments.ProfileFragment"
|
||||||
tools:listitem="@layout/fragment_profile_posts" />
|
tools:listitem="@layout/fragment_profile_posts" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".ReportActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/report_target_textview"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/textInputLayout"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Reporting @user's post:" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/textInputLayout"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
app:counterEnabled="true"
|
||||||
|
app:counterMaxLength="1000"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/reportButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:hint="@string/optional_report_comment"
|
||||||
|
android:inputType="text|textCapSentences|textMultiLine"
|
||||||
|
android:lines="8" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<com.mikepenz.iconics.view.IconicsButton
|
||||||
|
android:id="@+id/reportButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/report"
|
||||||
|
android:textColor="@color/colorText"
|
||||||
|
android:backgroundTint="@color/colorPrimary"
|
||||||
|
app:iconGravity="end"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.75" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/reportProgressBar"
|
||||||
|
style="?android:attr/progressBarStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/reportButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/reportButton"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/reportButton"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/reportButton" />
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.h.pixeldroid.utils.SquareLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:foreground="?selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:background="@drawable/add_photo_alternate_black_24dp" />
|
||||||
|
</com.h.pixeldroid.utils.SquareLayout>
|
|
@ -11,7 +11,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:contentDescription="TODO" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
|
@ -1,24 +1,28 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.gridlayout.widget.GridLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:flexWrap="wrap"
|
app:columnCount="3">
|
||||||
app:justifyContent="center">
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="5dp">
|
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/postPreview"
|
android:id="@+id/postPreview"
|
||||||
android:layout_width="100dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="100dp"
|
android:layout_height="0dp"
|
||||||
android:contentDescription="TODO" />
|
app:layout_constraintDimensionRatio="H,1:1"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:contentDescription="TODO"
|
||||||
|
android:padding="1dp"
|
||||||
|
app:layout_gravity="fill"
|
||||||
|
app:layout_rowWeight="1"
|
||||||
|
app:layout_columnWeight="1"/>
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.gridlayout.widget.GridLayout>
|
||||||
|
|
||||||
|
|
||||||
</com.google.android.flexbox.FlexboxLayout>
|
|
||||||
|
|
|
@ -1,50 +1,28 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal">
|
android:layout_gravity="center_horizontal">
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<androidx.appcompat.widget.SearchView
|
||||||
android:id="@+id/search"
|
android:id="@+id/search"
|
||||||
android:layout_width="250dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:hint="@string/search"
|
|
||||||
app:errorEnabled="true"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/searchButton"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/searchEditText"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:imeOptions="actionDone"
|
|
||||||
android:inputType="textUri" />
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/searchButton"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="20dp"
|
app:iconifiedByDefault="false"
|
||||||
android:backgroundTint="@color/colorButtonBg"
|
|
||||||
android:text="@string/search"
|
|
||||||
android:textColor="@color/colorButtonText"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/search"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/search" />
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:queryHint="@string/search" />
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/discoverProgressBar"
|
android:id="@+id/discoverProgressBar"
|
||||||
style="?android:attr/progressBarStyle"
|
style="?android:attr/progressBarStyle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
@ -54,21 +32,33 @@
|
||||||
android:id="@+id/discoverRefreshLayout"
|
android:id="@+id/discoverRefreshLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
android:layout_marginTop="10dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/search">
|
app:layout_constraintTop_toBottomOf="@+id/search">
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/discoverList"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent">
|
||||||
android:layout_marginLeft="16dp"
|
<LinearLayout
|
||||||
android:layout_marginRight="16dp"
|
android:layout_width="match_parent"
|
||||||
app:layoutManager="com.google.android.flexbox.FlexboxLayoutManager"
|
android:layout_height="match_parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/search" />
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/discoverText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:text="@string/discover"
|
||||||
|
android:layout_gravity="center_horizontal"/>
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/discoverList"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:nestedScrollingEnabled="false"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,23 +1,34 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<com.h.pixeldroid.utils.SquareLayout
|
<com.h.pixeldroid.utils.SquareLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/container"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:foreground="?selectableItemBackground"
|
android:foreground="?selectableItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true">
|
android:focusable="true">
|
||||||
<RelativeLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/galleryImage"
|
android:id="@+id/galleryImage"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scaleType="centerCrop"/>
|
android:padding="8dp"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="30dp"
|
android:layout_width="30dp"
|
||||||
android:layout_height="30dp"
|
android:layout_height="30dp"
|
||||||
android:src="@drawable/ic_baseline_edit_24"/>
|
android:layout_marginStart="16dp"
|
||||||
</RelativeLayout>
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@drawable/circle_black_24dp"
|
||||||
|
android:backgroundTint="#7A3E3C3C"
|
||||||
|
android:foreground="@drawable/ic_baseline_edit_24"
|
||||||
|
android:foregroundGravity="center"
|
||||||
|
android:foregroundTint="#FFFFFF"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</com.h.pixeldroid.utils.SquareLayout>
|
</com.h.pixeldroid.utils.SquareLayout>
|
|
@ -4,17 +4,10 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
xmlns:sparkbutton="http://schemas.android.com/apk/res-auto"
|
xmlns:sparkbutton="http://schemas.android.com/apk/res-auto"
|
||||||
tools:context=".fragments.PostFragment">
|
tools:context=".fragments.PostFragment">
|
||||||
<androidx.cardview.widget.CardView
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -33,16 +26,18 @@
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:src="@drawable/ic_default_user"
|
android:src="@drawable/ic_default_user"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:contentDescription="@string/profile_picture" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/username"
|
android:id="@+id/username"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="12dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/profilePic"
|
app:layout_constraintBottom_toBottomOf="@+id/profilePic"
|
||||||
app:layout_constraintStart_toEndOf="@+id/profilePic"
|
app:layout_constraintStart_toEndOf="@+id/profilePic"
|
||||||
app:layout_constraintTop_toTopOf="@+id/profilePic"/>
|
app:layout_constraintTop_toTopOf="@+id/profilePic"
|
||||||
|
tools:text="username" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/postDomain"
|
android:id="@+id/postDomain"
|
||||||
|
@ -51,14 +46,14 @@
|
||||||
android:textColor="#b3b3b3"
|
android:textColor="#b3b3b3"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/profilePic"
|
app:layout_constraintBottom_toBottomOf="@+id/profilePic"
|
||||||
app:layout_constraintStart_toEndOf="@+id/username"
|
app:layout_constraintStart_toEndOf="@+id/username"
|
||||||
app:layout_constraintTop_toTopOf="@+id/profilePic"/>
|
app:layout_constraintTop_toTopOf="@+id/profilePic"
|
||||||
|
tools:text=" from domain.tld" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/postConstraint"
|
android:id="@+id/postConstraint"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginTop="10dp"
|
||||||
android:adjustViewBounds="true"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/profilePic">
|
app:layout_constraintTop_toBottomOf="@+id/profilePic">
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
|
@ -87,7 +82,7 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:src="@color/browser_actions_bg_grey"
|
tools:src="@color/browser_actions_bg_grey"
|
||||||
android:longClickable="true" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/post_fragment_image_popup_menu_anchor"
|
android:id="@+id/post_fragment_image_popup_menu_anchor"
|
||||||
|
@ -106,11 +101,13 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:gravity="center|center_horizontal|center_vertical"
|
android:gravity="center|center_horizontal|center_vertical"
|
||||||
android:longClickable="true"
|
|
||||||
android:text="@string/cw_nsfw_hidden_media_n_click_to_show"
|
android:text="@string/cw_nsfw_hidden_media_n_click_to_show"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||||
android:textColor="@color/ic_launcher_background"
|
android:textColor="@color/ic_launcher_background"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/postPicture"
|
app:layout_constraintBottom_toBottomOf="@+id/postPicture"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/postTabs"
|
app:layout_constraintTop_toBottomOf="@+id/postTabs"
|
||||||
tools:src="@color/browser_actions_bg_grey" />
|
tools:src="@color/browser_actions_bg_grey" />
|
||||||
|
|
||||||
|
@ -121,7 +118,6 @@
|
||||||
android:id="@+id/commenter"
|
android:id="@+id/commenter"
|
||||||
android:layout_width="30dp"
|
android:layout_width="30dp"
|
||||||
android:layout_height="30dp"
|
android:layout_height="30dp"
|
||||||
android:importantForAccessibility="no"
|
|
||||||
android:padding="4dp"
|
android:padding="4dp"
|
||||||
android:src="@drawable/ic_comment_empty"
|
android:src="@drawable/ic_comment_empty"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/liker"
|
app:layout_constraintBottom_toBottomOf="@+id/liker"
|
||||||
|
@ -137,7 +133,6 @@
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:layout_marginBottom="4dp"
|
android:layout_marginBottom="4dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:importantForAccessibility="no"
|
|
||||||
android:padding="4dp"
|
android:padding="4dp"
|
||||||
sparkbutton:activeImage="@drawable/ic_like_full"
|
sparkbutton:activeImage="@drawable/ic_like_full"
|
||||||
sparkbutton:iconSize="28dp"
|
sparkbutton:iconSize="28dp"
|
||||||
|
@ -154,7 +149,6 @@
|
||||||
android:layout_width="30dp"
|
android:layout_width="30dp"
|
||||||
android:layout_height="30dp"
|
android:layout_height="30dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:importantForAccessibility="no"
|
|
||||||
android:padding="4dp"
|
android:padding="4dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/commenter"
|
app:layout_constraintBottom_toBottomOf="@+id/commenter"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -166,6 +160,17 @@
|
||||||
sparkbutton:primaryColor="@color/share_blue"
|
sparkbutton:primaryColor="@color/share_blue"
|
||||||
sparkbutton:secondaryColor="@color/black"/>
|
sparkbutton:secondaryColor="@color/black"/>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/status_more"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:contentDescription="@string/status_more_options"
|
||||||
|
android:padding="4dp"
|
||||||
|
style="?android:attr/actionOverflowButtonStyle"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/postDomain"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/postDomain" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/nlikes"
|
android:id="@+id/nlikes"
|
||||||
|
@ -182,7 +187,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="50"
|
android:layout_weight="50"
|
||||||
android:gravity="right"
|
android:gravity="end"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/reblogger"
|
app:layout_constraintEnd_toEndOf="@+id/reblogger"
|
||||||
app:layout_constraintStart_toStartOf="@+id/reblogger"
|
app:layout_constraintStart_toStartOf="@+id/reblogger"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/reblogger"
|
app:layout_constraintTop_toBottomOf="@+id/reblogger"
|
||||||
|
@ -214,7 +219,7 @@
|
||||||
android:textColor="#b3b3b3"
|
android:textColor="#b3b3b3"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/description"
|
app:layout_constraintTop_toBottomOf="@+id/description"
|
||||||
tools:text="time" />
|
tools:text="Yesterday" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/commentIn"
|
android:id="@+id/commentIn"
|
||||||
|
@ -234,7 +239,6 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:hint="@string/comment"
|
android:hint="@string/comment"
|
||||||
android:importantForAutofill="no"
|
|
||||||
android:inputType="text" />
|
android:inputType="text" />
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
@ -262,15 +266,10 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
tools:text="TextView"/>
|
tools:text="3 comments"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
|
@ -1,18 +1,19 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/filter_name"
|
android:id="@+id/filter_name"
|
||||||
android:text="FILTER_NAME"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
tools:text="FILTER_NAME" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/thumbnail"
|
android:id="@+id/thumbnail"
|
||||||
|
@ -20,5 +21,5 @@
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:layout_width="80dp"
|
android:layout_width="80dp"
|
||||||
android:layout_height="80dp"
|
android:layout_height="80dp"
|
||||||
android:contentDescription="thumbnail of filter" />
|
android:contentDescription="Thumbnail of filter" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<item android:id="@+id/image_popup_menu_save_to_gallery"
|
|
||||||
android:title="@string/save_to_gallery"/>
|
|
||||||
<item android:id="@+id/image_popup_menu_share_picture"
|
|
||||||
android:title="@string/share_picture"/>
|
|
||||||
</menu>
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:id="@+id/post_more_menu_report"
|
||||||
|
android:title="@string/report" />
|
||||||
|
<item android:id="@+id/post_more_menu_share_link"
|
||||||
|
android:title="@string/share_link" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Group that should only be shown if there are pictures in the post -->
|
||||||
|
<group android:id="@+id/post_more_group_picture">
|
||||||
|
<item android:id="@+id/post_more_menu_share_picture"
|
||||||
|
android:title="@string/share_picture"/>
|
||||||
|
<item android:id="@+id/post_more_menu_save_to_gallery"
|
||||||
|
android:title="@string/save_to_gallery"/>
|
||||||
|
</group>
|
||||||
|
</menu>
|
|
@ -15,7 +15,7 @@
|
||||||
<string name="auth_failed">فشلت المصادقة</string>
|
<string name="auth_failed">فشلت المصادقة</string>
|
||||||
<string name="followed_notification">يتابعك %1$s</string>
|
<string name="followed_notification">يتابعك %1$s</string>
|
||||||
<string name="description">الوصف…</string>
|
<string name="description">الوصف…</string>
|
||||||
<string name="send">ارسل</string>
|
<string name="post">ارسل</string>
|
||||||
<string name="whats_an_instance">ماذا نعني بمثيل الخادم؟</string>
|
<string name="whats_an_instance">ماذا نعني بمثيل الخادم؟</string>
|
||||||
<string name="logout">الخروج</string>
|
<string name="logout">الخروج</string>
|
||||||
<string name="tab_filters">الفلاتر</string>
|
<string name="tab_filters">الفلاتر</string>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<string name="save_to_gallery">Desar a la galeria…</string>
|
<string name="save_to_gallery">Desar a la galeria…</string>
|
||||||
<string name="logout">Tancar sessió</string>
|
<string name="logout">Tancar sessió</string>
|
||||||
<string name="whats_an_instance">Què és una instància\?</string>
|
<string name="whats_an_instance">Què és una instància\?</string>
|
||||||
<string name="send">enviar</string>
|
<string name="post">enviar</string>
|
||||||
<string name="description">Descripció…</string>
|
<string name="description">Descripció…</string>
|
||||||
<string name="liked_notification">%1$s ha dona\'t m\'agrada a la teva publicació</string>
|
<string name="liked_notification">%1$s ha dona\'t m\'agrada a la teva publicació</string>
|
||||||
<string name="theme_title">Tema de l\'aplicació</string>
|
<string name="theme_title">Tema de l\'aplicació</string>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<string name="mention_notification">%1$s hat dich erwähnt</string>
|
<string name="mention_notification">%1$s hat dich erwähnt</string>
|
||||||
<string name="shared_notification">%1$s hat deinen Beitrag geteilt</string>
|
<string name="shared_notification">%1$s hat deinen Beitrag geteilt</string>
|
||||||
<string name="liked_notification">%1$s hat deinen Beitrag favorisiert</string>
|
<string name="liked_notification">%1$s hat deinen Beitrag favorisiert</string>
|
||||||
<string name="send">senden</string>
|
<string name="post">senden</string>
|
||||||
<string name="whats_an_instance">Was ist eine Instanz\?</string>
|
<string name="whats_an_instance">Was ist eine Instanz\?</string>
|
||||||
<string name="theme_title">Erscheinungsbild</string>
|
<string name="theme_title">Erscheinungsbild</string>
|
||||||
<string name="description">Beschreibung…</string>
|
<string name="description">Beschreibung…</string>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<string name="shared_notification">%1$s compartió tu publicación</string>
|
<string name="shared_notification">%1$s compartió tu publicación</string>
|
||||||
<string name="liked_notification">%1$s le gustó tu publicación</string>
|
<string name="liked_notification">%1$s le gustó tu publicación</string>
|
||||||
<string name="description">Descripción…</string>
|
<string name="description">Descripción…</string>
|
||||||
<string name="send">enviar</string>
|
<string name="post">enviar</string>
|
||||||
<string name="whats_an_instance">¿Qué es una instancia\?</string>
|
<string name="whats_an_instance">¿Qué es una instancia\?</string>
|
||||||
<string name="logout">Cerrar sesión</string>
|
<string name="logout">Cerrar sesión</string>
|
||||||
<string name="save_to_gallery">Guardar en la galería…</string>
|
<string name="save_to_gallery">Guardar en la galería…</string>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<string name="save_to_gallery">Gorde galerian…</string>
|
<string name="save_to_gallery">Gorde galerian…</string>
|
||||||
<string name="logout">Saioa Itxi</string>
|
<string name="logout">Saioa Itxi</string>
|
||||||
<string name="whats_an_instance">Zer da instantzia bat\?</string>
|
<string name="whats_an_instance">Zer da instantzia bat\?</string>
|
||||||
<string name="send">bidali</string>
|
<string name="post">bidali</string>
|
||||||
<string name="description">Deskribapena…</string>
|
<string name="description">Deskribapena…</string>
|
||||||
<string name="mention_notification">%1$s erabiltzaileak aipatu zaitu</string>
|
<string name="mention_notification">%1$s erabiltzaileak aipatu zaitu</string>
|
||||||
<string name="followed_notification">%1$s jarraitzen hasi zaizu</string>
|
<string name="followed_notification">%1$s jarraitzen hasi zaizu</string>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<string name="shared_notification">%1$s مطلب شما را همرسانی کرد</string>
|
<string name="shared_notification">%1$s مطلب شما را همرسانی کرد</string>
|
||||||
<string name="liked_notification">%1$s مطلب شما را پسندید</string>
|
<string name="liked_notification">%1$s مطلب شما را پسندید</string>
|
||||||
<string name="description">توضیحات…</string>
|
<string name="description">توضیحات…</string>
|
||||||
<string name="send">بفرست</string>
|
<string name="post">بفرست</string>
|
||||||
<string name="whats_an_instance">یک نمونه چیست؟</string>
|
<string name="whats_an_instance">یک نمونه چیست؟</string>
|
||||||
<string name="logout">خروج</string>
|
<string name="logout">خروج</string>
|
||||||
<string name="lbl_brightness">روشنایی</string>
|
<string name="lbl_brightness">روشنایی</string>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<string name="shared_notification">%1$s a partagé votre publication</string>
|
<string name="shared_notification">%1$s a partagé votre publication</string>
|
||||||
<string name="liked_notification">%1$s a aimé votre publication</string>
|
<string name="liked_notification">%1$s a aimé votre publication</string>
|
||||||
<string name="description">Description…</string>
|
<string name="description">Description…</string>
|
||||||
<string name="send">envoyer</string>
|
<string name="post">envoyer</string>
|
||||||
<string name="whats_an_instance">Qu\'est-ce qu\'une instance \?</string>
|
<string name="whats_an_instance">Qu\'est-ce qu\'une instance \?</string>
|
||||||
<string name="logout">Se déconnecter</string>
|
<string name="logout">Se déconnecter</string>
|
||||||
<string name="save_to_gallery">Sauvegarder dans la galerie…</string>
|
<string name="save_to_gallery">Sauvegarder dans la galerie…</string>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<string name="liked_notification">a %1$s gustoulle a publicación</string>
|
<string name="liked_notification">a %1$s gustoulle a publicación</string>
|
||||||
<string name="shared_notification">%1$s comparteu a publicación</string>
|
<string name="shared_notification">%1$s comparteu a publicación</string>
|
||||||
<string name="description">Descrición…</string>
|
<string name="description">Descrición…</string>
|
||||||
<string name="send">enviar</string>
|
<string name="post">enviar</string>
|
||||||
<string name="whats_an_instance">Que é unha instancia\?</string>
|
<string name="whats_an_instance">Que é unha instancia\?</string>
|
||||||
<string name="logout">Saír</string>
|
<string name="logout">Saír</string>
|
||||||
<string name="lbl_brightness">BRILLO</string>
|
<string name="lbl_brightness">BRILLO</string>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<string name="mention_notification">%1$s ti ha menzionato</string>
|
<string name="mention_notification">%1$s ti ha menzionato</string>
|
||||||
<string name="liked_notification">%1$s è piaciuto il tuo post</string>
|
<string name="liked_notification">%1$s è piaciuto il tuo post</string>
|
||||||
<string name="tab_filters">FILTRI</string>
|
<string name="tab_filters">FILTRI</string>
|
||||||
<string name="send">invia</string>
|
<string name="post">invia</string>
|
||||||
<string name="lbl_brightness">LUMINOSITÀ</string>
|
<string name="lbl_brightness">LUMINOSITÀ</string>
|
||||||
<string name="description">Descrizione…</string>
|
<string name="description">Descrizione…</string>
|
||||||
<string name="whats_an_instance">Cos\'è un\'istanza\?</string>
|
<string name="whats_an_instance">Cos\'è un\'istanza\?</string>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<string name="followed_notification">%1$s さんにフォローされました</string>
|
<string name="followed_notification">%1$s さんにフォローされました</string>
|
||||||
<string name="liked_notification">%1$s さんがあなたの投稿をお気に入りに登録しました</string>
|
<string name="liked_notification">%1$s さんがあなたの投稿をお気に入りに登録しました</string>
|
||||||
<string name="description">説明…</string>
|
<string name="description">説明…</string>
|
||||||
<string name="send">送信</string>
|
<string name="post">送信</string>
|
||||||
<string name="whats_an_instance">インスタンスとは?</string>
|
<string name="whats_an_instance">インスタンスとは?</string>
|
||||||
<string name="logout">ログアウト</string>
|
<string name="logout">ログアウト</string>
|
||||||
<string name="lbl_brightness">輝度</string>
|
<string name="lbl_brightness">輝度</string>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<string name="menu_account">Mijn profiel</string>
|
<string name="menu_account">Mijn profiel</string>
|
||||||
<string name="logout">Log uit</string>
|
<string name="logout">Log uit</string>
|
||||||
<string name="whats_an_instance">Wat is een instance\?</string>
|
<string name="whats_an_instance">Wat is een instance\?</string>
|
||||||
<string name="send">stuur</string>
|
<string name="post">stuur</string>
|
||||||
<string name="description">Beschrijving…</string>
|
<string name="description">Beschrijving…</string>
|
||||||
<string name="liked_notification">%1$s vond je bericht leuk</string>
|
<string name="liked_notification">%1$s vond je bericht leuk</string>
|
||||||
<string name="shared_notification">%1$s heeft je bericht gedeeld</string>
|
<string name="shared_notification">%1$s heeft je bericht gedeeld</string>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<string name="lbl_brightness">BRILHO</string>
|
<string name="lbl_brightness">BRILHO</string>
|
||||||
<string name="logout">Sair</string>
|
<string name="logout">Sair</string>
|
||||||
<string name="whats_an_instance">O que é uma instância\?</string>
|
<string name="whats_an_instance">O que é uma instância\?</string>
|
||||||
<string name="send">enviar</string>
|
<string name="post">enviar</string>
|
||||||
<string name="description">Descrição…</string>
|
<string name="description">Descrição…</string>
|
||||||
<string name="liked_notification">%1$s curtiu o seu post</string>
|
<string name="liked_notification">%1$s curtiu o seu post</string>
|
||||||
<string name="shared_notification">%1$s compartilhou o seu post</string>
|
<string name="shared_notification">%1$s compartilhou o seu post</string>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<string name="followed_notification">%1$s подписался(-лась) на вас</string>
|
<string name="followed_notification">%1$s подписался(-лась) на вас</string>
|
||||||
<string name="mention_notification">%1$s упомянул(а) вас</string>
|
<string name="mention_notification">%1$s упомянул(а) вас</string>
|
||||||
<string name="shared_notification">%1$s поделился(-лась) вашим постом</string>
|
<string name="shared_notification">%1$s поделился(-лась) вашим постом</string>
|
||||||
<string name="send">отправить</string>
|
<string name="post">отправить</string>
|
||||||
<string name="logout">Выйти</string>
|
<string name="logout">Выйти</string>
|
||||||
<string name="lbl_brightness">ЯРКОСТЬ</string>
|
<string name="lbl_brightness">ЯРКОСТЬ</string>
|
||||||
<string name="whats_an_instance">Что такое инстанс\?</string>
|
<string name="whats_an_instance">Что такое инстанс\?</string>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<string name="shared_notification">%1$s delande ditt inlägg</string>
|
<string name="shared_notification">%1$s delande ditt inlägg</string>
|
||||||
<string name="liked_notification">%1$s gillar ditt inlägg</string>
|
<string name="liked_notification">%1$s gillar ditt inlägg</string>
|
||||||
<string name="description">Beskrivning…</string>
|
<string name="description">Beskrivning…</string>
|
||||||
<string name="send">skicka</string>
|
<string name="post">skicka</string>
|
||||||
<string name="whats_an_instance">Vad är en instans\?</string>
|
<string name="whats_an_instance">Vad är en instans\?</string>
|
||||||
<string name="logout">Logga ut</string>
|
<string name="logout">Logga ut</string>
|
||||||
<string name="lbl_brightness">LJUSSTYRKA</string>
|
<string name="lbl_brightness">LJUSSTYRKA</string>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<string name="theme_header">Тема</string>
|
<string name="theme_header">Тема</string>
|
||||||
<string name="mention_notification">%1$s згадав(-ла) вас</string>
|
<string name="mention_notification">%1$s згадав(-ла) вас</string>
|
||||||
<string name="description">Опис…</string>
|
<string name="description">Опис…</string>
|
||||||
<string name="send">відправити</string>
|
<string name="post">відправити</string>
|
||||||
<string name="lbl_brightness">Яскравість</string>
|
<string name="lbl_brightness">Яскравість</string>
|
||||||
<string name="lbl_contrast">Контраст</string>
|
<string name="lbl_contrast">Контраст</string>
|
||||||
<string name="lbl_saturation">Насичення</string>
|
<string name="lbl_saturation">Насичення</string>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<string name="auth_failed">无法验证</string>
|
<string name="auth_failed">无法验证</string>
|
||||||
<string name="token_error">获取验证令牌时出错</string>
|
<string name="token_error">获取验证令牌时出错</string>
|
||||||
<string name="theme_header">主题</string>
|
<string name="theme_header">主题</string>
|
||||||
<string name="send">发送</string>
|
<string name="post">发送</string>
|
||||||
<string name="logout">注销</string>
|
<string name="logout">注销</string>
|
||||||
<string name="app_name">PixelDroid</string>
|
<string name="app_name">PixelDroid</string>
|
||||||
<string name="title_activity_settings2">配置</string>
|
<string name="title_activity_settings2">配置</string>
|
||||||
|
|
|
@ -44,8 +44,9 @@
|
||||||
<string name="upload_post_success">Post uploaded successfully</string>
|
<string name="upload_post_success">Post uploaded successfully</string>
|
||||||
<string name="upload_post_error">Post upload failed</string>
|
<string name="upload_post_error">Post upload failed</string>
|
||||||
<string name="description">Description…</string>
|
<string name="description">Description…</string>
|
||||||
<string name="send">send</string>
|
<string name="post">post</string>
|
||||||
<!-- Post edition -->
|
<string name="add_photo">Add a photo</string>
|
||||||
|
<!-- Post editing -->
|
||||||
<string name="lbl_brightness">BRIGHTNESS</string>
|
<string name="lbl_brightness">BRIGHTNESS</string>
|
||||||
<string name="lbl_contrast">CONTRAST</string>
|
<string name="lbl_contrast">CONTRAST</string>
|
||||||
<string name="lbl_saturation">SATURATION</string>
|
<string name="lbl_saturation">SATURATION</string>
|
||||||
|
@ -121,6 +122,19 @@
|
||||||
<string name="post_title">%1$s\'s post</string>
|
<string name="post_title">%1$s\'s post</string>
|
||||||
<string name="followers_title">%1$s\'s followers</string>
|
<string name="followers_title">%1$s\'s followers</string>
|
||||||
<string name="follows_title">%1$s\'s follows</string>
|
<string name="follows_title">%1$s\'s follows</string>
|
||||||
|
<string name="search_empty_error">Search query can\'t be empty</string>
|
||||||
|
<string name="status_more_options">More options</string>
|
||||||
|
<string name="report">Report</string>
|
||||||
|
<string name="share_link">Share Link</string>
|
||||||
|
<string name="optional_report_comment">Optional message for mods/admins</string>
|
||||||
|
<string name="report_target">Report @%1$s\'s post</string>
|
||||||
|
<!-- Text on button, shown when report was successful. {gmd_check_circle} is an icon, position it as is appropriate in target language -->
|
||||||
|
<string name="reported">Reported {gmd_check_circle}</string>
|
||||||
|
<string name="report_error">Could not send report</string>
|
||||||
|
<string name="toolbar_title_edit">Edit</string>
|
||||||
|
<string name="profile_picture">Profile picture</string>
|
||||||
|
<string name="open_drawer_menu">Open drawer menu</string>
|
||||||
|
<string name="discover">DISCOVER</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -24,6 +24,5 @@
|
||||||
<style name="AppTheme.NoActionBar">
|
<style name="AppTheme.NoActionBar">
|
||||||
<item name="windowActionBar">false</item>
|
<item name="windowActionBar">false</item>
|
||||||
<item name="windowNoTitle">true</item>
|
<item name="windowNoTitle">true</item>
|
||||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<PreferenceCategory app:title="@string/theme_header">
|
<PreferenceCategory app:title="@string/theme_header">
|
||||||
<ListPreference
|
<ListPreference
|
||||||
app:defaultValue="@string/default_theme"
|
app:defaultValue="default"
|
||||||
app:entries="@array/theme_entries"
|
app:entries="@array/theme_entries"
|
||||||
app:entryValues="@array/theme_values"
|
app:entryValues="@array/theme_values"
|
||||||
app:key="theme"
|
app:key="theme"
|
||||||
|
@ -13,5 +13,9 @@
|
||||||
|
|
||||||
<Preference android:title="@string/about"
|
<Preference android:title="@string/about"
|
||||||
android:key="about"
|
android:key="about"
|
||||||
android:summary="@string/about_pixeldroid"/>
|
android:summary="@string/about_pixeldroid">
|
||||||
|
<intent
|
||||||
|
android:targetPackage="com.h.pixeldroid"
|
||||||
|
android:targetClass="com.h.pixeldroid.AboutActivity"/>
|
||||||
|
</Preference>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
|
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:hint="Search" >
|
android:hint="@string/search" >
|
||||||
</searchable>
|
</searchable>
|
||||||
|
|
Loading…
Reference in New Issue