diff --git a/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt b/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt index 2e212b8ab4..bb71d1309d 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt @@ -18,17 +18,13 @@ package com.keylesspalace.tusky import android.graphics.Color import android.os.Bundle import android.view.View -import android.view.WindowManager import androidx.activity.OnBackPressedCallback -import androidx.appcompat.app.AlertDialog -import androidx.core.widget.doOnTextChanged import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.transition.TransitionManager -import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.transition.MaterialArcMotion import com.google.android.material.transition.MaterialContainerTransform import com.keylesspalace.tusky.adapter.ItemInteractionListener @@ -37,13 +33,13 @@ import com.keylesspalace.tusky.appstore.EventHub import com.keylesspalace.tusky.appstore.MainTabsChangedEvent import com.keylesspalace.tusky.components.account.list.ListSelectionFragment import com.keylesspalace.tusky.databinding.ActivityTabPreferenceBinding -import com.keylesspalace.tusky.databinding.DialogAddHashtagBinding import com.keylesspalace.tusky.entity.MastoList import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.hashtagPattern import com.keylesspalace.tusky.util.unsafeLazy import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible +import com.keylesspalace.tusky.view.showHashtagPickerDialog import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.Dispatchers @@ -224,39 +220,21 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener, ListSelec } private fun showAddHashtagDialog(tab: TabData? = null, tabPosition: Int = 0) { - val dialogBinding = DialogAddHashtagBinding.inflate(layoutInflater) - val editText = dialogBinding.addHashtagEditText - - val dialog = MaterialAlertDialogBuilder(this) - .setTitle(R.string.add_hashtag_title) - .setView(dialogBinding.root) - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton(R.string.action_save) { _, _ -> - val input = editText.text.toString().trim() - if (tab == null) { - val newTab = createTabDataFromId(HASHTAG, listOf(input)) - currentTabs.add(newTab) - currentTabsAdapter.notifyItemInserted(currentTabs.size - 1) - } else { - val newTab = tab.copy(arguments = tab.arguments + input) - currentTabs[tabPosition] = newTab - - currentTabsAdapter.notifyItemChanged(tabPosition) - } - - updateAvailableTabs() - saveTabs() + showHashtagPickerDialog(mastodonApi, R.string.add_hashtag_title) { hashtag -> + if (tab == null) { + val newTab = createTabDataFromId(HASHTAG, listOf(hashtag)) + currentTabs.add(newTab) + currentTabsAdapter.notifyItemInserted(currentTabs.size - 1) + } else { + val newTab = tab.copy(arguments = tab.arguments + hashtag) + currentTabs[tabPosition] = newTab + + currentTabsAdapter.notifyItemChanged(tabPosition) } - .create() - editText.doOnTextChanged { s, _, _, _ -> - dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = validateHashtag(s) + updateAvailableTabs() + saveTabs() } - - dialog.show() - dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = validateHashtag(editText.text) - dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) - editText.requestFocus() } private var listSelectDialog: ListSelectionFragment? = null diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt index 80db564672..2b288aeb4e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeActivity.kt @@ -464,9 +464,9 @@ class ComposeActivity : binding.composeEditField.setAdapter( ComposeAutoCompleteAdapter( this, - preferences.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false), - preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false), - preferences.getBoolean(PrefKeys.SHOW_BOT_OVERLAY, true) + animateAvatar = preferences.getBoolean(PrefKeys.ANIMATE_GIF_AVATARS, false), + animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false), + showBotBadge = preferences.getBoolean(PrefKeys.SHOW_BOT_OVERLAY, true) ) ) binding.composeEditField.setTokenizer(ComposeTokenizer()) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeAutoCompleteAdapter.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeAutoCompleteAdapter.kt index 4b608d3b92..a7b2d8a165 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeAutoCompleteAdapter.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeAutoCompleteAdapter.kt @@ -37,7 +37,9 @@ class ComposeAutoCompleteAdapter( private val autocompletionProvider: AutocompletionProvider, private val animateAvatar: Boolean, private val animateEmojis: Boolean, - private val showBotBadge: Boolean + private val showBotBadge: Boolean, + // if true, @ # : are returned in the result, otherwise only the raw value + private val withDecoration: Boolean = true, ) : BaseAdapter(), Filterable { private var resultList: List = emptyList() @@ -52,37 +54,35 @@ class ComposeAutoCompleteAdapter( return position.toLong() } - override fun getFilter(): Filter { - return object : Filter() { + override fun getFilter() = object : Filter() { - override fun convertResultToString(resultValue: Any): CharSequence { - return when (resultValue) { - is AutocompleteResult.AccountResult -> "@${resultValue.account.username}" - is AutocompleteResult.HashtagResult -> "#${resultValue.hashtag}" - is AutocompleteResult.EmojiResult -> ":${resultValue.emoji.shortcode}:" - else -> "" - } + override fun convertResultToString(resultValue: Any): CharSequence { + return when (resultValue) { + is AutocompleteResult.AccountResult -> if (withDecoration) "@${resultValue.account.username}" else resultValue.account.username + is AutocompleteResult.HashtagResult -> if (withDecoration) "#${resultValue.hashtag}" else resultValue.hashtag + is AutocompleteResult.EmojiResult -> if (withDecoration) ":${resultValue.emoji.shortcode}:" else resultValue.emoji.shortcode + else -> "" } + } - @WorkerThread - override fun performFiltering(constraint: CharSequence?): FilterResults { - val filterResults = FilterResults() - if (constraint != null) { - val results = autocompletionProvider.search(constraint.toString()) - filterResults.values = results - filterResults.count = results.size - } - return filterResults + @WorkerThread + override fun performFiltering(constraint: CharSequence?): FilterResults { + val filterResults = FilterResults() + if (constraint != null) { + val results = autocompletionProvider.search(constraint.toString()) + filterResults.values = results + filterResults.count = results.size } + return filterResults + } - @Suppress("UNCHECKED_CAST") - override fun publishResults(constraint: CharSequence?, results: FilterResults) { - if (results.count > 0) { - resultList = results.values as List - notifyDataSetChanged() - } else { - notifyDataSetInvalidated() - } + @Suppress("UNCHECKED_CAST") + override fun publishResults(constraint: CharSequence?, results: FilterResults) { + if (results.count > 0) { + resultList = results.values as List + notifyDataSetChanged() + } else { + notifyDataSetInvalidated() } } } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt index ba0d327aeb..3c6fe5d47f 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt @@ -3,7 +3,6 @@ package com.keylesspalace.tusky.components.followedtags import android.content.SharedPreferences import android.os.Bundle import android.util.Log -import android.view.WindowManager import androidx.activity.viewModels import androidx.lifecycle.lifecycleScope import androidx.paging.LoadState @@ -11,14 +10,11 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.SimpleItemAnimator import at.connyduck.calladapter.networkresult.fold -import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import com.keylesspalace.tusky.BaseActivity import com.keylesspalace.tusky.R import com.keylesspalace.tusky.StatusListActivity -import com.keylesspalace.tusky.components.compose.ComposeAutoCompleteAdapter import com.keylesspalace.tusky.databinding.ActivityFollowedTagsBinding -import com.keylesspalace.tusky.databinding.DialogFollowHashtagBinding import com.keylesspalace.tusky.interfaces.HashtagActionListener import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.copyToClipboard @@ -26,6 +22,7 @@ import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible +import com.keylesspalace.tusky.view.showHashtagPickerDialog import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.collectLatest @@ -34,8 +31,8 @@ import kotlinx.coroutines.launch @AndroidEntryPoint class FollowedTagsActivity : BaseActivity(), - HashtagActionListener, - ComposeAutoCompleteAdapter.AutocompletionProvider { + HashtagActionListener { + @Inject lateinit var api: MastodonApi @@ -105,7 +102,7 @@ class FollowedTagsActivity : private fun follow(tagName: String, position: Int = -1) { lifecycleScope.launch { - api.followTag(tagName).fold( + val snackbarText = api.followTag(tagName).fold( { if (position == -1) { viewModel.tags.add(it) @@ -113,17 +110,20 @@ class FollowedTagsActivity : viewModel.tags.add(position, it) } viewModel.currentSource?.invalidate() + getString(R.string.follow_hashtag_success, tagName) }, - { - Snackbar.make( - this@FollowedTagsActivity, - binding.followedTagsView, - getString(R.string.error_following_hashtag_format, tagName), - Snackbar.LENGTH_SHORT - ) - .show() + { t -> + Log.w(TAG, "failed to follow hashtag $tagName", t) + getString(R.string.error_following_hashtag_format, tagName) } ) + Snackbar.make( + this@FollowedTagsActivity, + binding.followedTagsView, + snackbarText, + Snackbar.LENGTH_SHORT + ) + .show() } } @@ -160,10 +160,6 @@ class FollowedTagsActivity : } } - override fun search(token: String): List { - return viewModel.searchAutocompleteSuggestions(token) - } - override fun viewTag(tagName: String) { startActivity(StatusListActivity.newHashtagIntent(this, tagName)) } @@ -176,30 +172,9 @@ class FollowedTagsActivity : } private fun showDialog() { - val dialogBinding = DialogFollowHashtagBinding.inflate(layoutInflater) - dialogBinding.hashtagAutoCompleteTextView.setAdapter( - ComposeAutoCompleteAdapter( - this, - animateAvatar = false, - animateEmojis = false, - showBotBadge = false - ) - ) - dialogBinding.hashtagAutoCompleteTextView.requestFocus() - dialogBinding.hashtagAutoCompleteTextView.setSelection(dialogBinding.hashtagAutoCompleteTextView.length()) - - val dialog = MaterialAlertDialogBuilder(this) - .setTitle(R.string.dialog_follow_hashtag_title) - .setView(dialogBinding.root) - .setPositiveButton(android.R.string.ok) { _, _ -> - follow( - dialogBinding.hashtagAutoCompleteTextView.text.toString().removePrefix("#") - ) - } - .setNegativeButton(android.R.string.cancel, null) - .create() - dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) - dialog.show() + showHashtagPickerDialog(api, R.string.dialog_follow_hashtag_title) { hashtag -> + follow(hashtag) + } } companion object { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsViewModel.kt index bebc4ff9fe..590036cb0f 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsViewModel.kt @@ -1,24 +1,19 @@ package com.keylesspalace.tusky.components.followedtags -import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.paging.ExperimentalPagingApi import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.cachedIn -import at.connyduck.calladapter.networkresult.fold -import com.keylesspalace.tusky.components.compose.ComposeAutoCompleteAdapter -import com.keylesspalace.tusky.components.search.SearchType import com.keylesspalace.tusky.entity.HashTag import com.keylesspalace.tusky.network.MastodonApi import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject -import kotlinx.coroutines.runBlocking @HiltViewModel class FollowedTagsViewModel @Inject constructor( - private val api: MastodonApi + val api: MastodonApi ) : ViewModel() { val tags: MutableList = mutableListOf() var nextKey: String? = null @@ -39,24 +34,6 @@ class FollowedTagsViewModel @Inject constructor( } ).flow.cachedIn(viewModelScope) - fun searchAutocompleteSuggestions( - token: String - ): List { - return runBlocking { - api.search(query = token, type = SearchType.Hashtag.apiParameter, limit = 10) - .fold({ searchResult -> - searchResult.hashtags.map { - ComposeAutoCompleteAdapter.AutocompleteResult.HashtagResult( - it.name - ) - } - }, { e -> - Log.e(TAG, "Autocomplete search for $token failed.", e) - emptyList() - }) - } - } - companion object { private const val TAG = "FollowedTagsViewModel" } diff --git a/app/src/main/java/com/keylesspalace/tusky/view/HashtagPickerDialog.kt b/app/src/main/java/com/keylesspalace/tusky/view/HashtagPickerDialog.kt new file mode 100644 index 0000000000..2e3ccf9187 --- /dev/null +++ b/app/src/main/java/com/keylesspalace/tusky/view/HashtagPickerDialog.kt @@ -0,0 +1,118 @@ +/* Copyright 2025 Tusky Contributors + * + * This file is a part of Tusky. + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Tusky; if not, + * see . */ + +@file:JvmName("HashTagPickerDialog") + +package com.keylesspalace.tusky.view + +import android.content.Context +import android.util.Log +import android.view.KeyEvent +import android.view.LayoutInflater +import android.view.WindowManager +import android.view.inputmethod.EditorInfo +import android.widget.TextView +import android.widget.TextView.OnEditorActionListener +import androidx.annotation.StringRes +import androidx.appcompat.app.AlertDialog +import androidx.core.widget.doOnTextChanged +import at.connyduck.calladapter.networkresult.fold +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.keylesspalace.tusky.components.compose.ComposeAutoCompleteAdapter +import com.keylesspalace.tusky.components.search.SearchType +import com.keylesspalace.tusky.databinding.DialogPickHashtagBinding +import com.keylesspalace.tusky.network.MastodonApi +import com.keylesspalace.tusky.util.hashtagPattern +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.runBlocking + +fun Context.showHashtagPickerDialog( + api: MastodonApi, + @StringRes title: Int, + onHashtagSelected: (String) -> Unit +) { + val dialogScope = CoroutineScope(Dispatchers.Main) + val dialogBinding = DialogPickHashtagBinding.inflate(LayoutInflater.from(this)) + val autocompleteTextView = dialogBinding.pickHashtagEditText + + val autoCompleteProvider = object : ComposeAutoCompleteAdapter.AutocompletionProvider { + override fun search(token: String): List { + return runBlocking { + api.search(query = token, type = SearchType.Hashtag.apiParameter, limit = 5) + .fold({ searchResult -> + searchResult.hashtags.map { + ComposeAutoCompleteAdapter.AutocompleteResult.HashtagResult( + it.name + ) + } + }, { e -> + Log.e("HashtagPickerDialog", "Autocomplete search for $token failed", e) + emptyList() + }) + } + } + } + + autocompleteTextView.setAdapter( + ComposeAutoCompleteAdapter( + autoCompleteProvider, + animateAvatar = false, + animateEmojis = false, + showBotBadge = false, + withDecoration = false + ) + ) + + autocompleteTextView.setSelection(autocompleteTextView.length()) + + val dialog = MaterialAlertDialogBuilder(this) + .setTitle(title) + .setView(dialogBinding.root) + .setPositiveButton(android.R.string.ok) { _, _ -> + onHashtagSelected(autocompleteTextView.text.toString()) + } + .setNegativeButton(android.R.string.cancel, null) + .setOnDismissListener { + dialogScope.cancel() + } + .create() + + autocompleteTextView.doOnTextChanged { s, _, _, _ -> + dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = validateHashtag(s) + } + + autocompleteTextView.setOnEditorActionListener(object : OnEditorActionListener { + override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean { + if (actionId == EditorInfo.IME_ACTION_DONE && validateHashtag(autocompleteTextView.text)) { + onHashtagSelected(autocompleteTextView.text.toString()) + dialog.dismiss() + return true + } + return false + } + }) + + dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) + dialog.show() + dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = validateHashtag(autocompleteTextView.text) + autocompleteTextView.requestFocus() +} + +private fun validateHashtag(input: CharSequence?): Boolean { + val trimmedInput = input?.trim() ?: "" + return trimmedInput.isNotEmpty() && hashtagPattern.matcher(trimmedInput).matches() +} diff --git a/app/src/main/res/layout/dialog_add_hashtag.xml b/app/src/main/res/layout/dialog_add_hashtag.xml deleted file mode 100644 index 799a1fb26b..0000000000 --- a/app/src/main/res/layout/dialog_add_hashtag.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_follow_hashtag.xml b/app/src/main/res/layout/dialog_pick_hashtag.xml similarity index 74% rename from app/src/main/res/layout/dialog_follow_hashtag.xml rename to app/src/main/res/layout/dialog_pick_hashtag.xml index dca465eaf5..3fb413f054 100644 --- a/app/src/main/res/layout/dialog_follow_hashtag.xml +++ b/app/src/main/res/layout/dialog_pick_hashtag.xml @@ -1,5 +1,5 @@ - - + diff --git a/app/src/main/res/layout/item_autocomplete_hashtag.xml b/app/src/main/res/layout/item_autocomplete_hashtag.xml index fdb3625397..6d5ec5aafc 100644 --- a/app/src/main/res/layout/item_autocomplete_hashtag.xml +++ b/app/src/main/res/layout/item_autocomplete_hashtag.xml @@ -2,7 +2,7 @@ جارٍ تنزيل الوسائط هل تريد حذف وإعادة صياغة هذا التبويق؟ تم تفضيله - وسم بدون # + وسم بدون # مسح عامل تصفية طَبِّق diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 85e12bb8e0..8d94b4b975 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -453,7 +453,7 @@ Дадаць хэштэг Пашырана Апытанне з варыянтамі: %1$s, %2$s, %3$s, %4$s; %5$s - Хэштэг без # + Хэштэг без # Зменена Дададзена ў закладкі Упадабана diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 5915e0d4f4..1df4f3c8a6 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -61,7 +61,7 @@ Списък Избиране на списък Хаштагове - Хаштаг без # + Хаштаг без # Добавяне на хаштаг Име на списък Анкета с избори: %1$s, %2$s, %3$s, %4$s; %5$s diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index 01f69ef46b..4537e29b5e 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -383,7 +383,7 @@ প্রয়োগ ফিল্টার পরিষ্কার - # ছাড়া হ্যাশট্যাগ + # ছাড়া হ্যাশট্যাগ নামের তালিকা প্রিয়গুলো অনুগামিবৃন্দ diff --git a/app/src/main/res/values-bn-rIN/strings.xml b/app/src/main/res/values-bn-rIN/strings.xml index 492bff1902..7e950ed21c 100644 --- a/app/src/main/res/values-bn-rIN/strings.xml +++ b/app/src/main/res/values-bn-rIN/strings.xml @@ -351,7 +351,7 @@ সরাসরি পছন্দগুলি সহ নর্বাচন: %1$s, %2$s, %3$s, %4$s; %5$s নামের তালিকা - # ছাড়া হ্যাশট্যাগ + # ছাড়া হ্যাশট্যাগ পরিষ্কার ফিল্টার প্রয়োগ diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 4dc238329e..b737e3664b 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -347,7 +347,7 @@ Seguidors Directe Nom de la llista - Hashtag sense # + Hashtag sense # Netejar Filtrar Aplicar diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml index 791a7b3860..42c486a070 100644 --- a/app/src/main/res/values-ckb/strings.xml +++ b/app/src/main/res/values-ckb/strings.xml @@ -306,7 +306,7 @@ لیست دیاریکردنی لیست هاشتاگی - هاشتاگی بێ # + هاشتاگی بێ # هاشتاگی زیاد بکە ناوی لیست ڕاپرسی لەگەڵ هەڵبژاردنەکان: %1$s, %2$s, %3$s, %4$s; %5$s diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 195a25b66d..fd7c0f3685 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -351,7 +351,7 @@ Pro sledující Přímý Název seznamu - Hashtag bez # + Hashtag bez # Napsat příspěvek Napsat Vyčistit diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index 7299cd4c39..1955e96007 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -379,7 +379,7 @@ Dileu\'r neges wedi\'u hamserlennu hon\? Dim disgrifiad Enw\'r rhestr - Hashnod heb # + Hashnod heb # Anfon ymlaen at %1$s Daw\'r cyfrif o weinydd arall. Ydych chi am anfon copi dienw o\'r adroddiad i\'r gweinydd hwnnw hefyd\? Awr diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9411a6e0f3..ce67b2183c 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -319,7 +319,7 @@ Liste konnte nicht gelöscht werden Suche nach Leuten, denen du folgst Konto aus der Liste entfernen - Hashtag ohne # + Hashtag ohne # Autor*in des geteilten Beitrags öffnen Öffentliche Timelines diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 45cb0c73e0..b1ff36ed4f 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -360,7 +360,7 @@ Ebligi GIF-profilbildojn Enketoj Sciigoj pri enketoj, kiuj finiĝis - Kradvorto sen # + Kradvorto sen # Viŝi Filtri Apliki diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 151f13d5da..f44f7e8b1b 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -382,7 +382,7 @@ Sin listar Directo Nombre de la lista - Etiqueta sin # + Etiqueta sin # Limpiar Filtro Escribir publicación diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index a28a43b7b5..c4669222ec 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -367,7 +367,7 @@ Zuzena Inkesta aukerekin: %1$s, %2$s, %3$s, %4$s; %5$s Zerrendaren izena - Traola # gabe + Traola # gabe Garbitu Iragazi Aplikatu diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 6d68367bce..28c9c016e3 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -357,7 +357,7 @@ مستقیم نظرسنجی با گزینه‌ها: %1$s، %2$s، %3$s، %4$s؛ %5$s نام سیاهه - برچسب بدون # + برچسب بدون # حذف پالایش اعمال diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 75842f0c9a..0d63065356 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -217,7 +217,7 @@ \n(enintään %1$d merkkiä) - Aihetunniste ilman #-merkkiä + Aihetunniste ilman #-merkkiä Piilotetus verkkonimet Jaa… Verkkoselainta ei löytynyt. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 437f38a064..39a5bd1cc8 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -350,7 +350,7 @@ Direct Nom de la liste - Hashtag sans # + Hashtag sans # Supprimer Filtrer Appliquer diff --git a/app/src/main/res/values-ga/strings.xml b/app/src/main/res/values-ga/strings.xml index e9af2b1b0c..34c61f86ec 100644 --- a/app/src/main/res/values-ga/strings.xml +++ b/app/src/main/res/values-ga/strings.xml @@ -376,7 +376,7 @@ Díreach Ainm liosta Cuir hashtag leis - Hashtag gan # + Hashtag gan # Roghnaigh liosta Glan Scagaire diff --git a/app/src/main/res/values-gd/strings.xml b/app/src/main/res/values-gd/strings.xml index 79991be882..a4b5bb1fad 100644 --- a/app/src/main/res/values-gd/strings.xml +++ b/app/src/main/res/values-gd/strings.xml @@ -171,7 +171,7 @@ Sguab às Liosta Tagh liosta - Taga hais gun # + Taga hais gun # Cuir taga hais ris Ainm na liosta Cunntas-bheachd le roghainnean: %1$s, %2$s, %3$s, %4$s; %5$s diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 5d7e5a7f07..181ec1d0ff 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -180,7 +180,7 @@ Lista Escoller lista Cancelos - Cancelo sen # + Cancelo sen # Engadir cancelo Nome da lista Enquisa con opcións: %1$s, %2$s, %3$s, %4$s; %5$s diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index e6b06eebf8..50b1ec33ea 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -359,7 +359,7 @@ Közvetlen Szavazás válaszokkal: %1$s, %2$s, %3$s, %4$s; %5$s Lista neve - Hashtag # nélkül + Hashtag # nélkül Törlés Szűrés Alkalmaz diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index bb95a9afc0..0fb82aa5e8 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -356,7 +356,7 @@ Beint Könnun með valkostunum: %1$s, %2$s, %3$s, %4$s; %5$s Heiti á lista - Myllumerki án # + Myllumerki án # Veldu lista Listi Eyða diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 4946d94b7b..4ef040b22a 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -351,7 +351,7 @@ Scarica media Scaricando media Componi post - Hashtag senza # + Hashtag senza # Componi Cancella Filtra diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 4ed098d168..2134750c26 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -432,7 +432,7 @@ タブ間の切り替えにスワイプのジェスチャーを有効化 リンクのプレビューをタイムラインに表示 ブーストする前に確認を表示 - ハッシュタグ (#をつけない) + ハッシュタグ (#をつけない) リストを選択 %1$s • %2$s %1$sに終了 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 428e831a8c..ac78351410 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -356,7 +356,7 @@ 다이렉트 투표 선택지: %1$s, %2$s, %3$s, %4$s, %5$s 리스트 이름 - #를 제외한 해시태그 + #를 제외한 해시태그 알림 지우기 필터 적용 diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index ce049e4c9e..2edfce74f4 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -531,7 +531,7 @@ Augšupielāde neizdevās Rādīt melnrakstus Aizvākt - Tēmturis bez # + Tēmturis bez # %1$s laboja Pieslēgties ar pārlūku Strādā vairumā gadījumu. Dati netiek nopludināti uz citām lietotnēm. diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index a65c9090b3..1b050d7b4b 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -325,7 +325,7 @@ Følgere Direkte Listenavn - Emneord uten # + Emneord uten # Fjern Filter Bruk diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 565e3ad7d7..0492b6d9f8 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -342,7 +342,7 @@ Account aan de lijst toevoegen Account uit de lijst verwijderen Naam van lijst - Hashtag zonder # + Hashtag zonder # Verwijderen en herschrijven Dit bericht verwijderen en herschrijven\? Verwijderen diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index bc8b460cfc..eefa5baffa 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -342,7 +342,7 @@ Seguidors Dirècte Nom de la lista - Etiquetas sens # + Etiquetas sens # Escriure una publicacion Redactar Suprimir e reformular diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 048575f9c3..cf3a95a4a4 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -375,7 +375,7 @@ Bezpośrednio Głosowanie z opcjami: %1$s, %2$s, %3$s, %4$s; %5$s Nazwa listy - Hashtag bez # + Hashtag bez # Wyczyść Filtr Zastosuj diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index cd08f227e3..c8b4796dd6 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -351,7 +351,7 @@ Não-listado Direto Nome da lista - Hashtag sem # + Hashtag sem # Excluir notificações Filtrar notificações Salvar diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 7597a604ac..66d0dcc1b4 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -396,7 +396,7 @@ Votação com as opções: %1$s, %2$s, %3$s, %4$s; %5$s Nome da lista Adicionar hashtag - Hashtag sem # + Hashtag sem # Hashtags Selecionar lista Lista diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ba844de119..3ad564ccb9 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -374,7 +374,7 @@ Подписчики Личное упоминание Название списка - Хэштег без # + Хэштег без # Очистить Фильтр Применить diff --git a/app/src/main/res/values-sa/strings.xml b/app/src/main/res/values-sa/strings.xml index cbe93fb835..3402ebf1cd 100644 --- a/app/src/main/res/values-sa/strings.xml +++ b/app/src/main/res/values-sa/strings.xml @@ -427,7 +427,7 @@ सूचिः सूचिरवचीयताम् निश्रेणिचिह्नशीर्षकाः - # चिह्नं विना प्रचलितम् + # चिह्नं विना प्रचलितम् प्रचलितं युज्यताम् सूचिनाम मतदाने मतानि- %1$s, %2$s, %3$s, %4$s; %5$s diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index b2f1a34453..db33d5b292 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -319,7 +319,7 @@ Sledilci Neposredno Ime seznama - Ključnik brez # + Ključnik brez # Počisti Filter Uporabi diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 12a4f36670..e8c40fb58a 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -348,7 +348,7 @@ Listnamn Ladda ned media Laddar ned media - Hashtag utan # + Hashtag utan # Skriv inlägg Skriv Radera diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 5e2d48a376..6cc51c4913 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -56,7 +56,7 @@ รายการ เลือกรายการ แฮชแท็ก - แฮชแท็กโดยไม่มี # + แฮชแท็กโดยไม่มี # เพิ่มแฮชแท็ก ชื่อรายการ โพลกับตัวเลือก: %1$s, %2$s, %3$s, %4$s; %5$s diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index e760ec2305..ed5544f888 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -346,7 +346,7 @@ Doğrudan Seçenekli anket: %1$s, %2$s, %3$s, %4$s; %5$s Liste adı - # Etiket olmadan + # Etiket olmadan Sil Süzgeçle Uygula diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 7197bfe00f..3c6fec96ec 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -483,7 +483,7 @@ Видалити Список Вибрати список - Хештег без # + Хештег без # Додати хештег Назва списку Опитування з варіантами: %1$s, %2$s, %3$s, %4$s; %5$s diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 4d94540376..ccb140d6ce 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -363,7 +363,7 @@ Danh sách Chọn danh sách Hashtag - Không cần dấu # + Không cần dấu # Thêm hashtag Tên danh sách Lượt bình chọn: %1$s, %2$s, %3$s, %4$s; %5$s diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index ca66dd5947..2cb59d7c65 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -350,7 +350,7 @@ 私信 列表名 - 话题名(不含前面的 # 号) + 话题名(不含前面的 # 号) 删除 筛选 应用 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 02293ec059..e930ea99f3 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -366,7 +366,7 @@ 私信 列表名 - 話題名(不含前面的 # 號) + 話題名(不含前面的 # 號) 清空 分類 應用 diff --git a/app/src/main/res/values-zh-rMO/strings.xml b/app/src/main/res/values-zh-rMO/strings.xml index a0a64dc6e0..01f7b226ef 100644 --- a/app/src/main/res/values-zh-rMO/strings.xml +++ b/app/src/main/res/values-zh-rMO/strings.xml @@ -358,7 +358,7 @@ 私信 列表名 - 話題名(不含前面的 # 號) + 話題名(不含前面的 # 號) 清空 分類 應用 diff --git a/app/src/main/res/values-zh-rSG/strings.xml b/app/src/main/res/values-zh-rSG/strings.xml index 3b5ee2ae7d..f62e08b179 100644 --- a/app/src/main/res/values-zh-rSG/strings.xml +++ b/app/src/main/res/values-zh-rSG/strings.xml @@ -361,7 +361,7 @@ 私信 列表名 - 话题名(不含前面的 # 号) + 话题名(不含前面的 # 号) 清空 分类 应用 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 3a792b7816..96773ce87d 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -365,7 +365,7 @@ 私信 列表名 - 話題名(不含前面的 # 號) + 話題名(不含前面的 # 號) 清空 分類 應用 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 42ce93c84e..0e731a9e2d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -82,7 +82,7 @@ Edits Follow hashtag - #hashtag + Followed hashtag %1$s \@%1$s %1$s boosted @@ -616,7 +616,7 @@ List name Add hashtag - Hashtag without # + Hashtag without # Hashtags Select list Manage lists