WIP: Translatable text (#164)

* Extracted all visible texts

* Unit test import

* Removed conflicting import

* Removed unit tests that are no longer valid

* Added tests

* Renamed string

* Fixed string

* Added strings descriptions

* Converted string to templates
This commit is contained in:
mjaillot 2020-05-21 15:22:57 +02:00 committed by GitHub
parent 4e874b6f2f
commit 5b0a344236
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 224 additions and 110 deletions

View File

@ -4,34 +4,32 @@ import android.content.Context
import android.content.Intent
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.longClick
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.matcher.IntentMatchers
import androidx.test.espresso.intent.rule.IntentsTestRule
import androidx.test.espresso.matcher.RootMatchers
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.objects.Application
import com.h.pixeldroid.objects.Attachment
import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.objects.Tag
import com.h.pixeldroid.testUtility.MockServer
import com.h.pixeldroid.utils.DBUtils
import org.hamcrest.CoreMatchers
import org.hamcrest.Matcher
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.*
import org.junit.rules.Timeout
import org.junit.runner.RunWith
@ -187,6 +185,62 @@ class PostTest {
Intents.intended(expectedIntent)
}
@Test
fun getNLikesReturnsCorrectFormat() {
val status = Status(id="140364967936397312", uri="https://pixelfed.de/p/Miike/140364967936397312",
created_at="2020-03-03T08:00:16.000000Z",
account= Account(id="115114166443970560", username="Miike", acct="Miike",
url="https://pixelfed.de/Miike", display_name="Miike Duart", note="",
avatar="https://pixelfed.de/storage/avatars/011/511/416/644/397/056/0/ZhaopLJWTWJ3hsVCS5pS_avatar.png?v=d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
avatar_static="https://pixelfed.de/storage/avatars/011/511/416/644/397/056/0/ZhaopLJWTWJ3hsVCS5pS_avatar.png?v=d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
header="", header_static="", locked=false, emojis= emptyList(), discoverable=false,
created_at="2019-12-24T15:42:35.000000Z", statuses_count=71, followers_count=14,
following_count=0, moved=null, fields=null, bot=false, source=null),
content="""Day 8 <a href="https://pixelfed.de/discover/tags/rotavicentina?src=hash" title="#rotavicentina" class="u-url hashtag" rel="external nofollow noopener">#rotavicentina</a> <a href="https://pixelfed.de/discover/tags/hiking?src=hash" title="#hiking" class="u-url hashtag" rel="external nofollow noopener">#hiking</a> <a href="https://pixelfed.de/discover/tags/nature?src=hash" title="#nature" class="u-url hashtag" rel="external nofollow noopener">#nature</a>""",
visibility=Status.Visibility.public, sensitive=false, spoiler_text="",
media_attachments= listOf(
Attachment(id="15888", type= Attachment.AttachmentType.image, url="https://pixelfed.de/storage/m/113a3e2124a33b1f5511e531953f5ee48456e0c7/34dd6d9fb1762dac8c7ddeeaf789d2d8fa083c9f/JtjO0eAbELpgO1UZqF5ydrKbCKRVyJUM1WAaqIeB.jpeg",
preview_url="https://pixelfed.de/storage/m/113a3e2124a33b1f5511e531953f5ee48456e0c7/34dd6d9fb1762dac8c7ddeeaf789d2d8fa083c9f/JtjO0eAbELpgO1UZqF5ydrKbCKRVyJUM1WAaqIeB_thumb.jpeg",
remote_url=null, text_url=null, description=null, blurhash=null)
),
application= Application(name="web", website=null, vapid_key=null), mentions=emptyList(),
tags= listOf(Tag(name="hiking", url="https://pixelfed.de/discover/tags/hiking", history=null), Tag(name="nature", url="https://pixelfed.de/discover/tags/nature", history=null), Tag(name="rotavicentina", url="https://pixelfed.de/discover/tags/rotavicentina", history=null)),
emojis= emptyList(), reblogs_count=0, favourites_count=0, replies_count=0, url="https://pixelfed.de/p/Miike/140364967936397312",
in_reply_to_id=null, in_reply_to_account=null, reblog=null, poll=null, card=null, language=null, text=null, favourited=false, reblogged=false, muted=false, bookmarked=false, pinned=false)
Assert.assertEquals("${status.favourites_count} Likes",
status.getNLikes(getInstrumentation().targetContext))
}
@Test
fun getNSharesReturnsCorrectFormat() {
val status = Status(id="140364967936397312", uri="https://pixelfed.de/p/Miike/140364967936397312",
created_at="2020-03-03T08:00:16.000000Z",
account= Account(id="115114166443970560", username="Miike", acct="Miike",
url="https://pixelfed.de/Miike", display_name="Miike Duart", note="",
avatar="https://pixelfed.de/storage/avatars/011/511/416/644/397/056/0/ZhaopLJWTWJ3hsVCS5pS_avatar.png?v=d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
avatar_static="https://pixelfed.de/storage/avatars/011/511/416/644/397/056/0/ZhaopLJWTWJ3hsVCS5pS_avatar.png?v=d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
header="", header_static="", locked=false, emojis= emptyList(), discoverable=false,
created_at="2019-12-24T15:42:35.000000Z", statuses_count=71, followers_count=14,
following_count=0, moved=null, fields=null, bot=false, source=null),
content="""Day 8 <a href="https://pixelfed.de/discover/tags/rotavicentina?src=hash" title="#rotavicentina" class="u-url hashtag" rel="external nofollow noopener">#rotavicentina</a> <a href="https://pixelfed.de/discover/tags/hiking?src=hash" title="#hiking" class="u-url hashtag" rel="external nofollow noopener">#hiking</a> <a href="https://pixelfed.de/discover/tags/nature?src=hash" title="#nature" class="u-url hashtag" rel="external nofollow noopener">#nature</a>""",
visibility=Status.Visibility.public, sensitive=false, spoiler_text="",
media_attachments= listOf(
Attachment(id="15888", type= Attachment.AttachmentType.image, url="https://pixelfed.de/storage/m/113a3e2124a33b1f5511e531953f5ee48456e0c7/34dd6d9fb1762dac8c7ddeeaf789d2d8fa083c9f/JtjO0eAbELpgO1UZqF5ydrKbCKRVyJUM1WAaqIeB.jpeg",
preview_url="https://pixelfed.de/storage/m/113a3e2124a33b1f5511e531953f5ee48456e0c7/34dd6d9fb1762dac8c7ddeeaf789d2d8fa083c9f/JtjO0eAbELpgO1UZqF5ydrKbCKRVyJUM1WAaqIeB_thumb.jpeg",
remote_url=null, text_url=null, description=null, blurhash=null)
),
application= Application(name="web", website=null, vapid_key=null), mentions=emptyList(),
tags= listOf(Tag(name="hiking", url="https://pixelfed.de/discover/tags/hiking", history=null), Tag(name="nature", url="https://pixelfed.de/discover/tags/nature", history=null), Tag(name="rotavicentina", url="https://pixelfed.de/discover/tags/rotavicentina", history=null)),
emojis= emptyList(), reblogs_count=0, favourites_count=0, replies_count=0, url="https://pixelfed.de/p/Miike/140364967936397312",
in_reply_to_id=null, in_reply_to_account=null, reblog=null, poll=null, card=null, language=null, text=null, favourited=false, reblogged=false, muted=false, bookmarked=false, pinned=false)
Assert.assertEquals("${status.reblogs_count} Shares",
status.getNShares(getInstrumentation().targetContext))
}
@After
fun after() {
Intents.release()

View File

@ -324,7 +324,8 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
REQUEST_CODE_PERMISSIONS_SEND_PHOTO -> permissionsGrantedToSave(false)
}
} else {
Snackbar.make(coordinator_edit, "Permission denied", Snackbar.LENGTH_LONG).show()
Snackbar.make(coordinator_edit, getString(R.string.permission_denied),
Snackbar.LENGTH_LONG).show()
}
}
@ -393,13 +394,15 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
applyFinalFilters(originalImage)
file.writeBitmap(finalImage)
} catch (e: IOException) {
Snackbar.make(coordinator_edit, "Unable to save image", Snackbar.LENGTH_LONG).show()
Snackbar.make(coordinator_edit, getString(R.string.save_image_failed),
Snackbar.LENGTH_LONG).show()
}
if (!save) {
uploadImage(file)
} else {
Snackbar.make(coordinator_edit, "Image succesfully saved", Snackbar.LENGTH_LONG).show()
Snackbar.make(coordinator_edit, getString(R.string.save_image_success),
Snackbar.LENGTH_LONG).show()
}
}
//</editor-fold>

View File

@ -117,7 +117,8 @@ class PostCreationActivity : AppCompatActivity() {
val content = textField.text.toString()
if (content.length > maxLength) {
// error, too much characters
textField.error = "Description must contain $maxLength characters at most."
textField.error = getString(R.string.description_max_characters).format(maxLength)
return false
}
// store the description
@ -132,7 +133,8 @@ class PostCreationActivity : AppCompatActivity() {
Callback<Attachment> {
override fun onFailure(call: Call<Attachment>, t: Throwable) {
Log.e(TAG, t.toString() + call.request())
Toast.makeText(applicationContext,"Picture upload error!",Toast.LENGTH_SHORT).show()
Toast.makeText(applicationContext,getString(R.string.upload_picture_failed),
Toast.LENGTH_SHORT).show()
}
override fun onResponse(call: Call<Attachment>, response: Response<Attachment>) {
@ -141,10 +143,14 @@ class PostCreationActivity : AppCompatActivity() {
if (body.type.name == "image") {
post(body.id)
} else
Toast.makeText(applicationContext, "Upload error: wrong picture format.", Toast.LENGTH_SHORT).show()
Toast.makeText(applicationContext, getString(R.string.picture_format_error),
Toast.LENGTH_SHORT).show()
} else {
Log.e(TAG, "Server responded: $response" + call.request() + call.request().body)
Toast.makeText(applicationContext,"Upload error: bad request format",Toast.LENGTH_SHORT).show()
Log.e(TAG,
"Server responded: $response${call.request()}${call.request().body}"
)
Toast.makeText(applicationContext,getString(R.string.request_format_error),
Toast.LENGTH_SHORT).show()
}
}
})
@ -158,16 +164,19 @@ class PostCreationActivity : AppCompatActivity() {
media_ids = listOf(id)
).enqueue(object: Callback<Status> {
override fun onFailure(call: Call<Status>, t: Throwable) {
Toast.makeText(applicationContext,"Post upload failed",Toast.LENGTH_SHORT).show()
Toast.makeText(applicationContext,getString(R.string.upload_post_failed),
Toast.LENGTH_SHORT).show()
Log.e(TAG, t.message + call.request())
}
override fun onResponse(call: Call<Status>, response: Response<Status>) {
if (response.code() == 200) {
Toast.makeText(applicationContext,"Post upload success",Toast.LENGTH_SHORT).show()
Toast.makeText(applicationContext,getString(R.string.upload_post_success),
Toast.LENGTH_SHORT).show()
startActivity(Intent(applicationContext, MainActivity::class.java))
} else {
Toast.makeText(applicationContext,"Post upload failed : not 200",Toast.LENGTH_SHORT).show()
Toast.makeText(applicationContext,getString(R.string.upload_post_error),
Toast.LENGTH_SHORT).show()
Log.e(TAG, call.request().toString() + response.raw().toString())
}
}

View File

@ -109,15 +109,18 @@ class ProfileActivity : AppCompatActivity() {
accountName.setTypeface(null, Typeface.BOLD)
val nbPosts = findViewById<TextView>(R.id.nbPostsTextView)
nbPosts.text = "${account!!.statuses_count}\nPosts"
nbPosts.text = applicationContext.getString(R.string.nb_posts)
.format(account!!.statuses_count.toString())
nbPosts.setTypeface(null, Typeface.BOLD)
val nbFollowers = findViewById<TextView>(R.id.nbFollowersTextView)
nbFollowers.text = "${account!!.followers_count}\nFollowers"
nbFollowers.text = applicationContext.getString(R.string.nb_followers)
.format(account!!.followers_count.toString())
nbFollowers.setTypeface(null, Typeface.BOLD)
val nbFollowing = findViewById<TextView>(R.id.nbFollowingTextView)
nbFollowing.text = "${account!!.following_count}\nFollowing"
nbFollowing.text = applicationContext.getString(R.string.nb_following)
.format(account!!.following_count.toString())
nbFollowing.setTypeface(null, Typeface.BOLD)
}
@ -148,8 +151,7 @@ class ProfileActivity : AppCompatActivity() {
if(browserIntent.resolveActivity(packageManager) != null) {
startActivity(browserIntent)
} else {
val text = "Cannot open this link"
Log.e("ProfileActivity", text)
Log.e("ProfileActivity", "Cannot open this link")
}
}
@ -179,7 +181,8 @@ class ProfileActivity : AppCompatActivity() {
override fun onFailure(call: Call<List<Relationship>>, t: Throwable) {
Log.e("FOLLOW ERROR", t.toString())
Toast.makeText(applicationContext,"Could not get follow status", Toast.LENGTH_SHORT).show()
Toast.makeText(applicationContext,getString(R.string.follow_status_failed),
Toast.LENGTH_SHORT).show()
}
override fun onResponse(call: Call<List<Relationship>>, response: Response<List<Relationship>>) {
@ -197,8 +200,8 @@ class ProfileActivity : AppCompatActivity() {
followButton.visibility = View.VISIBLE
}
} else {
Toast.makeText(applicationContext, "Could not display follow button", Toast.LENGTH_SHORT)
.show()
Toast.makeText(applicationContext, getString(R.string.follow_button_failed),
Toast.LENGTH_SHORT).show()
}
}
})
@ -213,8 +216,8 @@ class ProfileActivity : AppCompatActivity() {
override fun onFailure(call: Call<Relationship>, t: Throwable) {
Log.e("FOLLOW ERROR", t.toString())
Toast.makeText(applicationContext, "Could not follow", Toast.LENGTH_SHORT)
.show()
Toast.makeText(applicationContext, getString(R.string.follow_error),
Toast.LENGTH_SHORT).show()
}
override fun onResponse(
@ -225,8 +228,8 @@ class ProfileActivity : AppCompatActivity() {
followButton.text = "Unfollow"
setOnClickUnfollow()
} else if (response.code() == 403) {
Toast.makeText(applicationContext, "This action is not allowed", Toast.LENGTH_SHORT)
.show()
Toast.makeText(applicationContext, getString(R.string.action_not_allowed),
Toast.LENGTH_SHORT).show()
}
}
})
@ -242,8 +245,8 @@ class ProfileActivity : AppCompatActivity() {
override fun onFailure(call: Call<Relationship>, t: Throwable) {
Log.e("UNFOLLOW ERROR", t.toString())
Toast.makeText(applicationContext, "Could not unfollow", Toast.LENGTH_SHORT)
.show()
Toast.makeText(applicationContext, getString(R.string.unfollow_error),
Toast.LENGTH_SHORT).show()
}
override fun onResponse(call: Call<Relationship>, response: Response<Relationship>) {
@ -251,8 +254,8 @@ class ProfileActivity : AppCompatActivity() {
followButton.text = "Follow"
setOnClickFollow()
} else if (response.code() == 401) {
Toast.makeText(applicationContext, "The access token is invalid", Toast.LENGTH_SHORT)
.show()
Toast.makeText(applicationContext, getString(R.string.access_token_invalid),
Toast.LENGTH_SHORT).show()
}
}
})

View File

@ -77,9 +77,9 @@ class SearchActivity : AppCompatActivity() {
val tabLayout = findViewById<TabLayout>(R.id.search_tabs)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
when(position){
0 -> tab.text = "POSTS"
1 -> tab.text = "ACCOUNTS"
2 -> tab.text = "HASHTAGS"
0 -> tab.text = getString(R.string.posts)
1 -> tab.text = getString(R.string.accounts)
2 -> tab.text = getString(R.string.hashtags)
}
}.attach()
when(searchType){

View File

@ -75,7 +75,7 @@ class FilterListFragment : Fragment(), FilterListFragmentListener {
val tbItem = ThumbnailItem()
tbItem.image = tbImage
tbItem.filterName = "Normal"
tbItem.filterName = getString(R.string.normal_filter)
ThumbnailsManager.addThumb(tbItem)
val filters = FilterPack.getFilterPack(requireActivity())

View File

@ -53,7 +53,9 @@ class ImageFragment : Fragment() {
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(object: BasePermissionListener() {
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
Toast.makeText(view.context, "You need to grant write permission to download pictures!", Toast.LENGTH_SHORT).show()
Toast.makeText(view.context,
view.context.getString(R.string.write_permission_download_pic),
Toast.LENGTH_SHORT).show()
}
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {
@ -67,7 +69,9 @@ class ImageFragment : Fragment() {
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(object: BasePermissionListener() {
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
Toast.makeText(view.context, "You need to grant write permission to share pictures!", Toast.LENGTH_SHORT).show()
Toast.makeText(view.context,
view.context.getString(R.string.write_permission_share_pic),
Toast.LENGTH_SHORT).show()
}
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {

View File

@ -116,14 +116,14 @@ open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment(
callback.onResult(notifications as List<T>)
} else{
Toast.makeText(context,"Something went wrong while loading", Toast.LENGTH_SHORT).show()
Toast.makeText(context, getString(R.string.loading_toast), Toast.LENGTH_SHORT).show()
}
swipeRefreshLayout.isRefreshing = false
loadingIndicator.visibility = View.GONE
}
override fun onFailure(call: Call<List<T>>, t: Throwable) {
Toast.makeText(context,"Could not get feed", Toast.LENGTH_SHORT).show()
Toast.makeText(context, getString(R.string.feed_failed), Toast.LENGTH_SHORT).show()
Log.e("FeedFragment", t.toString())
}
})

View File

@ -9,6 +9,7 @@ import android.widget.Toast
import androidx.lifecycle.LiveData
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import com.h.pixeldroid.R
import com.h.pixeldroid.fragments.feeds.AccountListFragment
import com.h.pixeldroid.fragments.feeds.FeedFragment
import com.h.pixeldroid.objects.Account
@ -72,14 +73,14 @@ class SearchAccountFragment: AccountListFragment(){
callback.onResult(notifications as List<Account>)
} else{
Toast.makeText(context,"Something went wrong while loading", Toast.LENGTH_SHORT).show()
Toast.makeText(context, getString(R.string.loading_toast), Toast.LENGTH_SHORT).show()
}
swipeRefreshLayout.isRefreshing = false
loadingIndicator.visibility = View.GONE
}
override fun onFailure(call: Call<Results>, t: Throwable) {
Toast.makeText(context,"Could not get feed", Toast.LENGTH_SHORT).show()
Toast.makeText(context,getString(R.string.feed_failed), Toast.LENGTH_SHORT).show()
Log.e("FeedFragment", t.toString())
}
})

View File

@ -99,14 +99,14 @@ class SearchHashtagFragment: FeedFragment<Tag, SearchHashtagFragment.TagsRecycle
callback.onResult(notifications as List<Tag>)
} else{
Toast.makeText(context,"Something went wrong while loading", Toast.LENGTH_SHORT).show()
Toast.makeText(context,getString(R.string.loading_toast), Toast.LENGTH_SHORT).show()
}
swipeRefreshLayout.isRefreshing = false
loadingIndicator.visibility = View.GONE
}
override fun onFailure(call: Call<Results>, t: Throwable) {
Toast.makeText(context,"Could not get feed", Toast.LENGTH_SHORT).show()
Toast.makeText(context,getString(R.string.feed_failed), Toast.LENGTH_SHORT).show()
Log.e("FeedFragment", t.toString())
}
})

View File

@ -103,7 +103,7 @@ data class Status(
private fun getDescription(api: PixelfedAPI, context: Context, credential: String) : Spanned {
val description = content
if(description.isEmpty()) {
return "No description".toSpanned()
return context.getString(R.string.no_description).toSpanned()
}
return parseHTMLText(description, mentions, api, context, credential)
@ -112,17 +112,15 @@ data class Status(
fun getUsername() : CharSequence =
account.username.ifBlank{account.display_name.ifBlank{"NoName"}}
fun getNLikes() : CharSequence {
val nLikes = favourites_count
return "$nLikes Likes"
fun getNLikes(context: Context) : CharSequence {
return context.getString(R.string.likes).format(favourites_count.toString())
}
fun getNShares() : CharSequence {
val nShares = reblogs_count
return "$nShares Shares"
fun getNShares(context: Context) : CharSequence {
return context.getString(R.string.shares).format(reblogs_count.toString())
}
private fun ISO8601toDate(dateString : String, textView: TextView, isActivity: Boolean) {
private fun ISO8601toDate(dateString : String, textView: TextView, isActivity: Boolean, context: Context) {
var format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.hhmmss'Z'")
if(dateString.matches("[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}Z".toRegex())) {
format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.hhmmss'Z'")
@ -138,8 +136,10 @@ data class Status(
.getRelativeTimeSpanString(then, now,
android.text.format.DateUtils.SECOND_IN_MILLIS,
android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE)
textView.text = if(isActivity) "Posted on $date"
else "$formattedDate"
textView.text = if(isActivity) context.getString(R.string.posted_on).format(date)
else "$formattedDate"
} catch (e: ParseException) {
e.printStackTrace()
}
@ -231,17 +231,17 @@ data class Status(
}
rootView.findViewById<TextView>(R.id.nlikes).apply {
text = this@Status.getNLikes()
text = this@Status.getNLikes(rootView.context)
setTypeface(null, Typeface.BOLD)
}
rootView.findViewById<TextView>(R.id.nshares).apply {
text = this@Status.getNShares()
text = this@Status.getNShares(rootView.context)
setTypeface(null, Typeface.BOLD)
}
//Convert the date to a readable string
ISO8601toDate(created_at, rootView.postDate, isActivity)
ISO8601toDate(created_at, rootView.postDate, isActivity, rootView.context)
rootView.postDomain.text = getStatusDomain(domain)
@ -358,7 +358,7 @@ data class Status(
val textIn = holder.comment.text
//Open text input
if(textIn.isNullOrEmpty()) {
Toast.makeText(holder.context,"Comment must not be empty!", Toast.LENGTH_SHORT).show()
Toast.makeText(holder.context, holder.context.getString(R.string.empty_comment), Toast.LENGTH_SHORT).show()
} else {
//Post the comment
@ -384,7 +384,7 @@ data class Status(
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(object: BasePermissionListener() {
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
Toast.makeText(view.context, "You need to grant write permission to download pictures!", Toast.LENGTH_SHORT).show()
Toast.makeText(view.context, view.context.getString(R.string.write_permission_download_pic), Toast.LENGTH_SHORT).show()
}
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {
@ -398,7 +398,7 @@ data class Status(
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(object: BasePermissionListener() {
override fun onPermissionDenied(p0: PermissionDeniedResponse?) {
Toast.makeText(view.context, "You need to grant write permission to share pictures!", Toast.LENGTH_SHORT).show()
Toast.makeText(view.context, view.context.getString(R.string.write_permission_share_pic), Toast.LENGTH_SHORT).show()
}
override fun onPermissionGranted(p0: PermissionGrantedResponse?) {

View File

@ -89,7 +89,7 @@ class ImageUtils {
e.printStackTrace()
}
intentShare.putExtra(Intent.EXTRA_STREAM, uri)
activity.startActivity(Intent.createChooser(intentShare, "Share Image"))
activity.startActivity(Intent.createChooser(intentShare, context.getString(R.string.share_image)))
}
cursor.close()
}

View File

@ -55,7 +55,7 @@ abstract class PostUtils {
val resp = response.body()!!
//Update shown share count
holder.nshares.text = resp.getNShares()
holder.nshares.text = resp.getNShares(holder.context)
holder.reblogger.isChecked = resp.reblogged
} else {
Log.e("RESPONSE_CODE", response.code().toString())
@ -84,7 +84,7 @@ abstract class PostUtils {
val resp = response.body()!!
//Update shown share count
holder.nshares.text = resp.getNShares()
holder.nshares.text = resp.getNShares(holder.context)
holder.reblogger.isChecked = resp.reblogged
} else {
Log.e("RESPONSE_CODE", response.code().toString())
@ -113,7 +113,7 @@ abstract class PostUtils {
val resp = response.body()!!
//Update shown like count and internal like toggle
holder.nlikes.text = resp.getNLikes()
holder.nlikes.text = resp.getNLikes(holder.context)
holder.liker.isChecked = resp.favourited
} else {
Log.e("RESPONSE_CODE", response.code().toString())
@ -142,7 +142,7 @@ abstract class PostUtils {
val resp = response.body()!!
//Update shown like count and internal like toggle
holder.nlikes.text = resp.getNLikes()
holder.nlikes.text = resp.getNLikes(holder.context)
holder.liker.isChecked = resp.favourited
} else {
Log.e("RESPONSE_CODE", response.code().toString())
@ -166,7 +166,8 @@ abstract class PostUtils {
Callback<Status> {
override fun onFailure(call: Call<Status>, t: Throwable) {
Log.e("COMMENT ERROR", t.toString())
Toast.makeText(holder.context,"Comment error!", Toast.LENGTH_SHORT).show()
Toast.makeText(holder.context, holder.context.getString(R.string.comment_error),
Toast.LENGTH_SHORT).show()
}
override fun onResponse(call: Call<Status>, response: Response<Status>) {
@ -178,7 +179,9 @@ abstract class PostUtils {
//Add the comment to the comment section
addComment(holder.context, holder.commentCont, resp.account.username, resp.content)
Toast.makeText(holder.context,"Comment: \"$textIn\" posted!", Toast.LENGTH_SHORT).show()
Toast.makeText(holder.context,
holder.context.getString(R.string.comment_posted).format(textIn),
Toast.LENGTH_SHORT).show()
Log.e("COMMENT SUCCESS", "posted: $textIn")
} else {
Log.e("ERROR_CODE", response.code().toString())

View File

@ -31,8 +31,7 @@
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_weight="1"
tools:srcCompat="@tools:sample/avatars"
android:contentDescription="TODO" />
tools:srcCompat="@tools:sample/avatars" />
<LinearLayout
android:layout_width="match_parent"
@ -46,7 +45,7 @@
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="-\nPosts" />
android:text="@string/default_nposts" />
<TextView
android:id="@+id/nbFollowersTextView"
@ -54,7 +53,7 @@
android:layout_height="120dp"
android:layout_weight="1"
android:gravity="center"
android:text="-\nFollowers" />
android:text="@string/default_nfollowers" />
<TextView
android:id="@+id/nbFollowingTextView"
@ -62,7 +61,7 @@
android:layout_height="120dp"
android:layout_weight="1"
android:gravity="center"
android:text="-\nFollowing" />
android:text="@string/default_nfollowing" />
</LinearLayout>
</LinearLayout>
@ -79,7 +78,7 @@
android:id="@+id/accountNameTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="No Username"
android:text="@string/no_username"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
@ -111,7 +110,7 @@
android:id="@+id/followButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Follow"
android:text="@string/follow"
android:visibility="invisible"
android:textColor="@color/colorButtonText"
android:backgroundTint="@color/colorButtonBg"
@ -124,8 +123,8 @@
android:layout_height="wrap_content"
android:textColor="@color/colorButtonText"
android:backgroundTint="@color/colorButtonBg"
android:text="Edit profile"
android:visibility="gone"
android:text="@string/edit_profile"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -11,7 +11,7 @@
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:hint="Search"
android:hint="@string/search"
app:errorEnabled="true"
app:layout_constraintEnd_toStartOf="@+id/searchButton"
app:layout_constraintStart_toStartOf="parent"
@ -32,7 +32,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="Search"
android:text="@string/search"
android:backgroundTint="@color/colorButtonBg"
android:textColor="@color/colorButtonText"
app:layout_constraintBottom_toBottomOf="@+id/search"

View File

@ -33,8 +33,7 @@
android:layout_marginEnd="10dp"
android:src="@drawable/ic_default_user"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:contentDescription="TODO" />
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/username"
@ -88,8 +87,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@color/browser_actions_bg_grey"
android:longClickable="true"
android:contentDescription="TODO" />
android:longClickable="true" />
<FrameLayout
android:id="@+id/post_fragment_image_popup_menu_anchor"
@ -235,7 +233,7 @@
android:id="@+id/editComment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="Comment"
android:hint="@string/comment"
android:importantForAutofill="no"
android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout>

View File

@ -22,34 +22,84 @@
<string name="mention_notification">%1$s mentioned you</string>
<string name="shared_notification">%1$s shared your post</string>
<string name="liked_notification">%1$s liked your post</string>
<!-- Login page -->
<string name="whats_an_instance">"What's an instance?"</string>
<string name="domain_of_your_instance">Domain of your instance</string>
<string name="connect_to_pixelfed">Connect to Pixelfed</string>
<string name="login_connection_required_once">You need to be online to be able to add the first account and use PixelDroid :(</string>
<string name="add_account_name">Add Account</string>
<string name="add_account_description">Add another Pixelfed Account</string>
<!-- Drawer -->
<string name="logout">Log out</string>
<!-- Post creation -->
<string name="permission_denied">Permission denied</string>
<string name="save_image_failed">Unable to save image</string>
<string name="save_image_success">Image succesfully saved</string>
<string name="description_max_characters">"Description must contain %1$s characters at most."</string>
<string name="upload_picture_failed">Picture upload error!</string>
<string name="picture_format_error">Upload error: wrong picture format.</string>
<string name="request_format_error">Upload error: bad request format</string>
<string name="upload_post_failed">Post upload failed</string>
<string name="upload_post_success">Post upload success</string>
<string name="upload_post_error">Post upload failed : not 200</string>
<string name="description">Description…</string>
<string name="send">send</string>
<string name="whats_an_instance">"What's an instance?"</string>
<string name="logout">Log out</string>
<!-- Post edition -->
<string name="lbl_brightness">BRIGHTNESS</string>
<string name="lbl_contrast">CONTRAST</string>
<string name="lbl_saturation">SATURATION</string>
<string name="tab_filters">FILTERS</string>
<string name="tab_edit">EDIT</string>
<string name="save_to_gallery">Save to Gallery…</string>
<string name="image_download_failed">Download has been failed, please try again</string>
<string name="image_download_downloading">Downloading…</string>
<string name="image_download_success">Image downloaded successfully</string>
<string name="normal_filter">Normal</string>
<!-- Camera -->
<string name="capture_button_alt">Capture</string>
<string name="switch_camera_button_alt">Switch camera</string>
<string name="gallery_button_alt">Gallery</string>
<!-- Loading error messages -->
<string name="loading_toast">Something went wrong while loading</string>
<string name="feed_failed">Could not get feed</string>
<!-- Post pop-up options -->
<string name="share_picture">Share picture…</string>
<string name="save_to_gallery">Save to Gallery…</string>
<string name="image_download_failed">Download has failed, please try again</string>
<string name="image_download_downloading">Downloading…</string>
<string name="image_download_success">Image downloaded successfully</string>
<!-- Post attributes -->
<string name="no_description">No description</string>
<string name="likes">"%1$s Likes"</string>
<string name="shares">"%1$s Shares"</string>
<string name="posted_on">"Posted on %1$s"</string>
<string name="NoCommentsToShow">No comments on this post…</string>
<string name="empty_comment">Comment must not be empty!</string>
<string name="write_permission_download_pic">You need to grant write permission to download pictures!</string>
<string name="write_permission_share_pic">You need to grant write permission to share pictures!</string>
<string name="share_image">Share Image</string>
<string name="comment_error">Comment error!</string>
<string name="comment_posted">"Comment: %1$s posted!"</string>
<string name="comment">Comment</string>
<string name="CommentDisplay"> to show…</string>
<string name="domain_of_your_instance">Domain of your instance</string>
<string name="connect_to_pixelfed">Connect to Pixelfed</string>
<string name="login_connection_required_once">You need to be online to be able to add the first account and use PixelDroid :(</string>
<string name="you_are_in_offline_mode">You are in offline mode, but you can still view some content!</string>
<string name="add_account_name">Add Account</string>
<string name="add_account_description">Add another Pixelfed Account</string>
<!-- Profile page -->
<string name="nb_posts">"%1$s\nPosts"</string>
<string name="nb_followers">"%1$s\nFollowers"</string>
<string name="nb_following">"%1$s\nFollowing"</string>
<string name="follow_status_failed">Could not get follow status</string>
<string name="follow_button_failed">Could not display follow button</string>
<string name="follow_error">Could not follow</string>
<string name="action_not_allowed">This action is not allowed</string>
<string name="unfollow_error">Could not unfollow</string>
<string name="access_token_invalid">The access token is invalid</string>
<string name="default_nposts">-\nPosts</string>
<string name="default_nfollowers">-\nFollowers</string>
<string name="default_nfollowing">-\nFollowing</string>
<string name="no_username">No Username</string>
<string name="follow">Follow</string>
<string name="edit_profile">Edit profile</string>
<!-- Search page -->
<string name="search">Search</string>
<string name="posts">POSTS</string>
<string name="accounts">ACCOUNTS</string>
<string name="hashtags">HASHTAGS</string>
<!-- Sensitive media -->
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Hidden Media \n (click to show)</string>

View File

@ -41,14 +41,4 @@ class PostUnitTest {
Assert.assertEquals(status.account.display_name, emptyDescStatus.getUsername())
}
@Test
fun getNLikesReturnsCorrectFormat() {
Assert.assertEquals("${status.favourites_count} Likes", status.getNLikes())
}
@Test
fun getNSharesReturnsCorrectFormat() {
Assert.assertEquals("${status.reblogs_count} Shares", status.getNShares())
}
}