Merge branch 'develop' into weblate-tusky-tusky
This commit is contained in:
commit
d70b389160
31 changed files with 729 additions and 133 deletions
|
|
@ -40,9 +40,7 @@
|
|||
<activity android:name=".components.login.LoginWebViewActivity" />
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden|screenLayout|smallestScreenSize"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/SplashTheme">
|
||||
|
||||
<intent-filter>
|
||||
|
|
@ -115,9 +113,7 @@
|
|||
android:name=".ViewMediaActivity"
|
||||
android:theme="@style/TuskyBaseTheme"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden|screenLayout|smallestScreenSize" />
|
||||
<activity
|
||||
android:name=".components.account.AccountActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden|screenLayout|smallestScreenSize" />
|
||||
<activity android:name=".components.account.AccountActivity" />
|
||||
<activity android:name=".EditProfileActivity" />
|
||||
<activity android:name=".components.preference.PreferencesActivity" />
|
||||
<activity android:name=".StatusListActivity" />
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import android.view.View;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
|
|
|
|||
|
|
@ -576,6 +576,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
|
|||
}
|
||||
}
|
||||
startActivity(composeIntent)
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun setupDrawer(
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class StatusListActivity : BottomSheetActivity() {
|
|||
val title = when (kind) {
|
||||
Kind.FAVOURITES -> getString(R.string.title_favourites)
|
||||
Kind.BOOKMARKS -> getString(R.string.title_bookmarks)
|
||||
Kind.TAG -> getString(R.string.title_tag).format(hashtag)
|
||||
Kind.TAG -> getString(R.string.hashtag_format, hashtag)
|
||||
Kind.PUBLIC_TRENDING_STATUSES -> getString(R.string.title_public_trending_statuses)
|
||||
else -> intent.getStringExtra(EXTRA_LIST_TITLE)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ fun createTabDataFromId(id: String, arguments: List<String> = emptyList()): TabD
|
|||
arguments = arguments,
|
||||
title = { context ->
|
||||
arguments.joinToString(separator = " ") {
|
||||
context.getString(R.string.title_tag, it)
|
||||
context.getString(R.string.hashtag_format, it)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.keylesspalace.tusky.databinding.ItemStatusPlaceholderBinding
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener
|
||||
import com.keylesspalace.tusky.util.hide
|
||||
import com.keylesspalace.tusky.util.show
|
||||
import com.keylesspalace.tusky.util.visible
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ class ComposeAutoCompleteAdapter(
|
|||
|
||||
override fun convertResultToString(resultValue: Any): CharSequence {
|
||||
return when (resultValue) {
|
||||
is AutocompleteResult.AccountResult -> formatUsername(resultValue)
|
||||
is AutocompleteResult.HashtagResult -> formatHashtag(resultValue)
|
||||
is AutocompleteResult.EmojiResult -> formatEmoji(resultValue)
|
||||
is AutocompleteResult.AccountResult -> "@${resultValue.account.username}"
|
||||
is AutocompleteResult.HashtagResult -> "#${resultValue.hashtag}"
|
||||
is AutocompleteResult.EmojiResult -> ":${resultValue.emoji.shortcode}:"
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ class ComposeAutoCompleteAdapter(
|
|||
}
|
||||
is ItemAutocompleteHashtagBinding -> {
|
||||
val result = getItem(position) as AutocompleteResult.HashtagResult
|
||||
binding.root.text = formatHashtag(result)
|
||||
binding.root.text = context.getString(R.string.hashtag_format, result.hashtag)
|
||||
}
|
||||
is ItemAutocompleteEmojiBinding -> {
|
||||
val emojiResult = getItem(position) as AutocompleteResult.EmojiResult
|
||||
|
|
@ -162,17 +162,5 @@ class ComposeAutoCompleteAdapter(
|
|||
private const val ACCOUNT_VIEW_TYPE = 0
|
||||
private const val HASHTAG_VIEW_TYPE = 1
|
||||
private const val EMOJI_VIEW_TYPE = 2
|
||||
|
||||
private fun formatUsername(result: AutocompleteResult.AccountResult): String {
|
||||
return String.format("@%s", result.account.username)
|
||||
}
|
||||
|
||||
private fun formatHashtag(result: AutocompleteResult.HashtagResult): String {
|
||||
return String.format("#%s", result.hashtag)
|
||||
}
|
||||
|
||||
private fun formatEmoji(result: AutocompleteResult.EmojiResult): String {
|
||||
return String.format(":%s:", result.emoji.shortcode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -265,12 +265,8 @@ class MediaUploader @Inject constructor(
|
|||
}
|
||||
val map = MimeTypeMap.getSingleton()
|
||||
val fileExtension = map.getExtensionFromMimeType(mimeType)
|
||||
val filename = "%s_%d_%s.%s".format(
|
||||
context.getString(R.string.app_name),
|
||||
System.currentTimeMillis(),
|
||||
randomAlphanumericString(10),
|
||||
fileExtension
|
||||
)
|
||||
val filename =
|
||||
"${context.getString(R.string.app_name)}_${System.currentTimeMillis()}_${randomAlphanumericString(10)}.$fileExtension"
|
||||
|
||||
if (mimeType == null) mimeType = "multipart/form-data"
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
package com.keylesspalace.tusky.components.compose.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
|
|
@ -80,11 +81,8 @@ class ComposeScheduleView
|
|||
}
|
||||
|
||||
val scheduled = scheduleDateTimeUtc!!.time
|
||||
binding.scheduledDateTime.text = String.format(
|
||||
"%s %s",
|
||||
dateFormat.format(scheduled),
|
||||
timeFormat.format(scheduled)
|
||||
)
|
||||
@SuppressLint("SetTextI18n")
|
||||
binding.scheduledDateTime.text = "${dateFormat.format(scheduled)} ${timeFormat.format(scheduled)}"
|
||||
verifyScheduledTime(scheduled)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ class DraftHelper @Inject constructor(
|
|||
map.getExtensionFromMimeType(mimeType)
|
||||
}
|
||||
|
||||
val filename = String.format("Tusky_Draft_Media_%s_%d.%s", timeStamp, index, fileExtension)
|
||||
val filename = "Tusky_Draft_Media_${timeStamp}_$index.$fileExtension"
|
||||
val file = File(folder, filename)
|
||||
|
||||
if (scheme == "https") {
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ class LoginActivity : BaseActivity() {
|
|||
getString(R.string.error_authorization_unknown)
|
||||
} else {
|
||||
// Use error returned by the server or fall back to the generic message
|
||||
Log.e(TAG, "%s %s".format(getString(R.string.error_authorization_denied), error))
|
||||
Log.e(TAG, getString(R.string.error_authorization_denied) + " " + error)
|
||||
error.ifBlank { getString(R.string.error_authorization_denied) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import android.view.LayoutInflater
|
|||
import android.view.ViewGroup
|
||||
import androidx.paging.PagingDataAdapter
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.databinding.ItemHashtagBinding
|
||||
import com.keylesspalace.tusky.entity.HashTag
|
||||
import com.keylesspalace.tusky.interfaces.LinkListener
|
||||
|
|
@ -37,7 +38,7 @@ class SearchHashtagsAdapter(private val linkListener: LinkListener) :
|
|||
|
||||
override fun onBindViewHolder(holder: BindingHolder<ItemHashtagBinding>, position: Int) {
|
||||
getItem(position)?.let { (name) ->
|
||||
holder.binding.root.text = String.format("#%s", name)
|
||||
holder.binding.root.text = holder.binding.root.context.getString(R.string.hashtag_format, name)
|
||||
holder.binding.root.setOnClickListener { linkListener.onViewTag(name) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ class NotificationFetcher @Inject constructor(
|
|||
* than the marker.
|
||||
*/
|
||||
private suspend fun fetchNewNotifications(account: AccountEntity): List<Notification> {
|
||||
val authHeader = String.format("Bearer %s", account.accessToken)
|
||||
val authHeader = "Bearer ${account.accessToken}"
|
||||
|
||||
// Figure out where to read from. Choose the most recent notification ID from:
|
||||
//
|
||||
|
|
|
|||
|
|
@ -604,13 +604,6 @@ class TimelineFragment :
|
|||
viewModel.removeStatusWithId(status.id)
|
||||
}
|
||||
|
||||
private fun actionButtonPresent(): Boolean {
|
||||
return viewModel.kind != TimelineViewModel.Kind.TAG &&
|
||||
viewModel.kind != TimelineViewModel.Kind.FAVOURITES &&
|
||||
viewModel.kind != TimelineViewModel.Kind.BOOKMARKS &&
|
||||
activity is ActionButtonActivity
|
||||
}
|
||||
|
||||
private var talkBackWasEnabled = false
|
||||
|
||||
override fun onPause() {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ class CachedTimelineViewModel @Inject constructor(
|
|||
private val db: AppDatabase
|
||||
) : TimelineViewModel(
|
||||
timelineCases,
|
||||
api,
|
||||
eventHub,
|
||||
accountManager,
|
||||
sharedPreferences,
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ class NetworkTimelineViewModel @Inject constructor(
|
|||
filterModel: FilterModel
|
||||
) : TimelineViewModel(
|
||||
timelineCases,
|
||||
api,
|
||||
eventHub,
|
||||
accountManager,
|
||||
sharedPreferences,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import com.keylesspalace.tusky.db.AccountManager
|
|||
import com.keylesspalace.tusky.entity.Filter
|
||||
import com.keylesspalace.tusky.entity.Poll
|
||||
import com.keylesspalace.tusky.network.FilterModel
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.usecase.TimelineCases
|
||||
import com.keylesspalace.tusky.viewdata.StatusViewData
|
||||
|
|
@ -41,7 +40,6 @@ import kotlinx.coroutines.launch
|
|||
|
||||
abstract class TimelineViewModel(
|
||||
protected val timelineCases: TimelineCases,
|
||||
private val api: MastodonApi,
|
||||
private val eventHub: EventHub,
|
||||
protected val accountManager: AccountManager,
|
||||
private val sharedPreferences: SharedPreferences,
|
||||
|
|
|
|||
|
|
@ -20,13 +20,16 @@ import com.keylesspalace.tusky.R
|
|||
import com.keylesspalace.tusky.databinding.ItemTrendingCellBinding
|
||||
import com.keylesspalace.tusky.util.formatNumber
|
||||
import com.keylesspalace.tusky.viewdata.TrendingViewData
|
||||
import java.text.NumberFormat
|
||||
|
||||
class TrendingTagViewHolder(
|
||||
private val binding: ItemTrendingCellBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
private val numberFormat: NumberFormat = NumberFormat.getNumberInstance()
|
||||
|
||||
fun setup(tagViewData: TrendingViewData.Tag, onViewTag: (String) -> Unit) {
|
||||
binding.tag.text = binding.root.context.getString(R.string.title_tag, tagViewData.name)
|
||||
binding.tag.text = binding.root.context.getString(R.string.hashtag_format, tagViewData.name)
|
||||
|
||||
binding.graph.maxTrendingValue = tagViewData.maxTrendingValue
|
||||
binding.graph.primaryLineData = tagViewData.usage
|
||||
|
|
@ -37,8 +40,8 @@ class TrendingTagViewHolder(
|
|||
val totalAccounts = tagViewData.accounts.sum()
|
||||
binding.totalAccounts.text = formatNumber(totalAccounts, 1000)
|
||||
|
||||
binding.currentUsage.text = tagViewData.usage.last().toString()
|
||||
binding.currentAccounts.text = tagViewData.usage.last().toString()
|
||||
binding.currentUsage.text = numberFormat.format(tagViewData.usage.last())
|
||||
binding.currentAccounts.text = numberFormat.format(tagViewData.usage.last())
|
||||
|
||||
itemView.setOnClickListener {
|
||||
onViewTag(tagViewData.name)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ data class Announcement(
|
|||
@Json(name = "updated_at") val updatedAt: Date,
|
||||
val read: Boolean = false,
|
||||
val mentions: List<Status.Mention>,
|
||||
val statuses: List<Status>,
|
||||
val tags: List<HashTag>,
|
||||
val emojis: List<Emoji>,
|
||||
val reactions: List<Reaction>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ import com.keylesspalace.tusky.R
|
|||
import com.keylesspalace.tusky.databinding.FragmentViewImageBinding
|
||||
import com.keylesspalace.tusky.entity.Attachment
|
||||
import com.keylesspalace.tusky.util.getParcelableCompat
|
||||
import com.keylesspalace.tusky.util.hide
|
||||
import com.keylesspalace.tusky.util.viewBinding
|
||||
import com.keylesspalace.tusky.util.visible
|
||||
import com.ortiz.touchview.OnTouchCoordinatesListener
|
||||
|
|
@ -113,7 +112,9 @@ class ViewImageFragment : ViewMediaFragment() {
|
|||
object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onDown(e: MotionEvent) = true
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
photoActionsListener.onPhotoTap()
|
||||
if (isAdded) {
|
||||
photoActionsListener.onPhotoTap()
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ import com.keylesspalace.tusky.ViewMediaActivity
|
|||
import com.keylesspalace.tusky.databinding.FragmentViewVideoBinding
|
||||
import com.keylesspalace.tusky.entity.Attachment
|
||||
import com.keylesspalace.tusky.util.getParcelableCompat
|
||||
import com.keylesspalace.tusky.util.hide
|
||||
import com.keylesspalace.tusky.util.unsafeLazy
|
||||
import com.keylesspalace.tusky.util.viewBinding
|
||||
import com.keylesspalace.tusky.util.visible
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class FilterModel @Inject constructor(
|
|||
val phrase = filter.phrase
|
||||
val quotedPhrase = Pattern.quote(phrase)
|
||||
return if (filter.wholeWord && ALPHANUMERIC.matcher(phrase).matches()) {
|
||||
String.format("(^|\\W)%s($|\\W)", quotedPhrase)
|
||||
"(^|\\W)$quotedPhrase($|\\W)"
|
||||
} else {
|
||||
quotedPhrase
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
package com.keylesspalace.tusky.util
|
||||
|
||||
import java.text.NumberFormat
|
||||
import java.util.Locale
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.ln
|
||||
import kotlin.math.pow
|
||||
|
|
@ -24,5 +25,10 @@ fun formatNumber(num: Long, min: Int = 100000): String {
|
|||
val exp = (ln(absNum.toDouble()) / ln_1k).toInt()
|
||||
|
||||
// Suffixes here are locale-agnostic
|
||||
return String.format("%.1f%c", num / 1000.0.pow(exp.toDouble()), "KMGTPE"[exp - 1])
|
||||
return String.format(
|
||||
Locale.getDefault(),
|
||||
"%.1f%c",
|
||||
num / 1000.0.pow(exp.toDouble()),
|
||||
"KMGTPE"[exp - 1]
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ class StatusViewHelper(private val itemView: View) {
|
|||
var labelText = getLabelTypeText(context, attachments[0].type)
|
||||
if (sensitive) {
|
||||
val sensitiveText = context.getString(R.string.post_sensitive_media_title)
|
||||
labelText += String.format(" (%s)", sensitiveText)
|
||||
labelText += " ($sensitiveText)"
|
||||
}
|
||||
mediaLabel.text = labelText
|
||||
|
||||
|
|
|
|||
|
|
@ -710,6 +710,7 @@
|
|||
<string name="pref_title_show_self_boosts">Önmegtolások megjelenítése</string>
|
||||
<string name="pref_title_show_self_boosts_description">Valaki a saját bejegyzését tolja meg</string>
|
||||
<string name="pref_title_show_notifications_filter">Értesítésszűrő megjelenítése</string>
|
||||
|
||||
<string name="action_follow_hashtag">Új hashtag követése</string>
|
||||
<string name="url_copied">Webcím másolva</string>
|
||||
<string name="dialog_follow_warning">Követed ezt a fiókot?</string>
|
||||
|
|
@ -724,4 +725,4 @@
|
|||
<string name="error_deleting_filter">Hiba a(z) „%1$s” szűrő törlésekor</string>
|
||||
<string name="error_saving_filter">Hiba a(z) „%1$s” szűrő mentésekor</string>
|
||||
<string name="confirmation_hashtag_copied">„#%1$s” másolva</string>
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<string name="at_symbol" translatable="false">\@</string>
|
||||
<string name="hash_symbol" translatable="false">#</string>
|
||||
<string name="title_tag" translatable="false">#%1$s</string>
|
||||
<string name="hashtag_format" translatable="false">#%1$s</string>
|
||||
|
||||
<string name="emoji_shortcode_format" translatable="false">:%1$s:</string>
|
||||
<string name="post_timestamp_with_edited_indicator" translatable="false">%1$s *</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue