From ce5ec15ff13ba0b36b486edd192dbb6c103a2f6c Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Sun, 1 May 2022 17:16:22 +0200 Subject: [PATCH 01/31] increase timeout for media uploads (#2489) --- .../tusky/components/compose/MediaUploader.kt | 6 +++--- .../keylesspalace/tusky/di/NetworkModule.kt | 15 +++++++++++++++ .../tusky/network/MastodonApi.kt | 7 ------- .../tusky/network/MediaUploadApi.kt | 19 +++++++++++++++++++ 4 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/com/keylesspalace/tusky/network/MediaUploadApi.kt diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/MediaUploader.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/MediaUploader.kt index 85be146c1..f1debc98b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/MediaUploader.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/MediaUploader.kt @@ -26,7 +26,7 @@ import androidx.core.net.toUri import com.keylesspalace.tusky.BuildConfig import com.keylesspalace.tusky.R import com.keylesspalace.tusky.components.compose.ComposeActivity.QueuedMedia -import com.keylesspalace.tusky.network.MastodonApi +import com.keylesspalace.tusky.network.MediaUploadApi import com.keylesspalace.tusky.network.ProgressRequestBody import com.keylesspalace.tusky.util.MEDIA_SIZE_UNKNOWN import com.keylesspalace.tusky.util.getImageSquarePixels @@ -75,7 +75,7 @@ class CouldNotOpenFileException : Exception() class MediaUploader @Inject constructor( private val context: Context, - private val mastodonApi: MastodonApi + private val mediaUploadApi: MediaUploadApi ) { @OptIn(ExperimentalCoroutinesApi::class) @@ -222,7 +222,7 @@ class MediaUploader @Inject constructor( null } - val result = mastodonApi.uploadMedia(body, description).getOrThrow() + val result = mediaUploadApi.uploadMedia(body, description).getOrThrow() send(UploadEvent.FinishedEvent(result.id)) awaitClose() } diff --git a/app/src/main/java/com/keylesspalace/tusky/di/NetworkModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/NetworkModule.kt index d8b52ca38..90dd30263 100644 --- a/app/src/main/java/com/keylesspalace/tusky/di/NetworkModule.kt +++ b/app/src/main/java/com/keylesspalace/tusky/di/NetworkModule.kt @@ -24,6 +24,7 @@ import com.keylesspalace.tusky.BuildConfig import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.network.InstanceSwitchAuthInterceptor import com.keylesspalace.tusky.network.MastodonApi +import com.keylesspalace.tusky.network.MediaUploadApi import com.keylesspalace.tusky.util.getNonNullString import dagger.Module import dagger.Provides @@ -112,4 +113,18 @@ class NetworkModule { @Provides @Singleton fun providesApi(retrofit: Retrofit): MastodonApi = retrofit.create() + + @Provides + @Singleton + fun providesMediaUploadApi(retrofit: Retrofit, okHttpClient: OkHttpClient): MediaUploadApi { + val longTimeOutOkHttpClient = okHttpClient.newBuilder() + .readTimeout(100, TimeUnit.SECONDS) + .writeTimeout(100, TimeUnit.SECONDS) + .build() + + return retrofit.newBuilder() + .client(longTimeOutOkHttpClient) + .build() + .create() + } } diff --git a/app/src/main/java/com/keylesspalace/tusky/network/MastodonApi.kt b/app/src/main/java/com/keylesspalace/tusky/network/MastodonApi.kt index 25fe03d4d..7357293b5 100644 --- a/app/src/main/java/com/keylesspalace/tusky/network/MastodonApi.kt +++ b/app/src/main/java/com/keylesspalace/tusky/network/MastodonApi.kt @@ -142,13 +142,6 @@ interface MastodonApi { @POST("api/v1/notifications/clear") fun clearNotifications(): Single - @Multipart - @POST("api/v2/media") - suspend fun uploadMedia( - @Part file: MultipartBody.Part, - @Part description: MultipartBody.Part? = null - ): Result - @FormUrlEncoded @PUT("api/v1/media/{mediaId}") suspend fun updateMedia( diff --git a/app/src/main/java/com/keylesspalace/tusky/network/MediaUploadApi.kt b/app/src/main/java/com/keylesspalace/tusky/network/MediaUploadApi.kt new file mode 100644 index 000000000..c7e9633f6 --- /dev/null +++ b/app/src/main/java/com/keylesspalace/tusky/network/MediaUploadApi.kt @@ -0,0 +1,19 @@ +package com.keylesspalace.tusky.network + +import com.keylesspalace.tusky.entity.MediaUploadResult +import okhttp3.MultipartBody +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part + +/** endpoints defined in this interface will be called with a higher timeout than usual + * which is necessary for media uploads to succeed on some servers + */ +interface MediaUploadApi { + @Multipart + @POST("api/v2/media") + suspend fun uploadMedia( + @Part file: MultipartBody.Part, + @Part description: MultipartBody.Part? = null + ): Result +} From 444e7365c972d79f54553b841d4a212a52f44a4e Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Tue, 3 May 2022 19:12:35 +0200 Subject: [PATCH 02/31] fix race condition where multiple uploaded media can get same internal id (#2479) * fix race condition where multiple uploaded media can get same internal id * atomically update media stateflow * atomically update media stateflow --- .../components/compose/ComposeActivity.kt | 24 +++-- .../components/compose/ComposeViewModel.kt | 99 +++++++++++-------- 2 files changed, 72 insertions(+), 51 deletions(-) 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 48e14def5..321626147 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 @@ -51,6 +51,7 @@ import androidx.core.view.ContentInfoCompat import androidx.core.view.OnReceiveContentListener import androidx.core.view.isGone import androidx.core.view.isVisible +import androidx.lifecycle.asLiveData import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager import androidx.recyclerview.widget.LinearLayoutManager @@ -344,14 +345,17 @@ class ComposeActivity : viewModel.statusVisibility.observe { visibility -> setStatusVisibility(visibility) } - viewModel.media.observe { media -> - mediaAdapter.submitList(media) - if (media.size != mediaCount) { - mediaCount = media.size - binding.composeMediaPreviewBar.visible(media.isNotEmpty()) - updateSensitiveMediaToggle(viewModel.markMediaAsSensitive.value != false, viewModel.showContentWarning.value != false) + lifecycleScope.launch { + viewModel.media.collect { media -> + mediaAdapter.submitList(media) + if (media.size != mediaCount) { + mediaCount = media.size + binding.composeMediaPreviewBar.visible(media.isNotEmpty()) + updateSensitiveMediaToggle(viewModel.markMediaAsSensitive.value != false, viewModel.showContentWarning.value != false) + } } } + viewModel.poll.observe { poll -> binding.pollPreview.visible(poll != null) poll?.let(binding.pollPreview::setPoll) @@ -364,7 +368,7 @@ class ComposeActivity : } updateScheduleButton() } - combineOptionalLiveData(viewModel.media, viewModel.poll) { media, poll -> + combineOptionalLiveData(viewModel.media.asLiveData(), viewModel.poll) { media, poll -> val active = poll == null && media!!.size != 4 && (media.isEmpty() || media.first().type == QueuedMedia.Type.IMAGE) @@ -781,11 +785,11 @@ class ComposeActivity : spoilerText = binding.composeContentWarningField.text.toString() } val characterCount = calculateTextLength() - if ((characterCount <= 0 || contentText.isBlank()) && viewModel.media.value!!.isEmpty()) { + if ((characterCount <= 0 || contentText.isBlank()) && viewModel.media.value.isEmpty()) { binding.composeEditField.error = getString(R.string.error_empty) enableButtons(true) } else if (characterCount <= maximumTootCharacters) { - if (viewModel.media.value!!.isNotEmpty()) { + if (viewModel.media.value.isNotEmpty()) { finishingUploadDialog = ProgressDialog.show( this, getString(R.string.dialog_title_finishing_media_upload), getString(R.string.dialog_message_uploading_media), true, true @@ -983,7 +987,7 @@ class ComposeActivity : } data class QueuedMedia( - val localId: Long, + val localId: Int, val uri: Uri, val type: Type, val mediaSize: Long, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt index 81500ee49..7b1805327 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt @@ -21,6 +21,7 @@ import androidx.core.net.toUri import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope import com.keylesspalace.tusky.components.compose.ComposeActivity.QueuedMedia import com.keylesspalace.tusky.components.drafts.DraftHelper @@ -36,15 +37,17 @@ import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.service.ServiceClient import com.keylesspalace.tusky.service.StatusToSend import com.keylesspalace.tusky.util.combineLiveData -import com.keylesspalace.tusky.util.filter -import com.keylesspalace.tusky.util.map import com.keylesspalace.tusky.util.randomAlphanumericString import com.keylesspalace.tusky.util.toLiveData -import com.keylesspalace.tusky.util.withoutFirstWhich import io.reactivex.rxjava3.core.Observable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch import kotlinx.coroutines.rx3.rxSingle import kotlinx.coroutines.withContext @@ -84,10 +87,10 @@ class ComposeViewModel @Inject constructor( val poll: MutableLiveData = mutableLiveData(null) val scheduledAt: MutableLiveData = mutableLiveData(null) - val media = mutableLiveData>(listOf()) + val media: MutableStateFlow> = MutableStateFlow(emptyList()) val uploadError = MutableLiveData() - private val mediaToJob = mutableMapOf() + private val mediaToJob = mutableMapOf() private val isEditingScheduledToot get() = !scheduledTootId.isNullOrEmpty() @@ -103,7 +106,7 @@ class ComposeViewModel @Inject constructor( suspend fun pickMedia(mediaUri: Uri, description: String? = null): Result = withContext(Dispatchers.IO) { try { val (type, uri, size) = mediaUploader.prepareMedia(mediaUri) - val mediaItems = media.value!! + val mediaItems = media.value if (type != QueuedMedia.Type.IMAGE && mediaItems.isNotEmpty() && mediaItems[0].type == QueuedMedia.Type.IMAGE @@ -118,29 +121,31 @@ class ComposeViewModel @Inject constructor( } } - private fun addMediaToQueue( + private suspend fun addMediaToQueue( type: QueuedMedia.Type, uri: Uri, mediaSize: Long, description: String? = null ): QueuedMedia { - val mediaItem = QueuedMedia( - localId = System.currentTimeMillis(), - uri = uri, - type = type, - mediaSize = mediaSize, - description = description - ) - media.postValue(media.value!! + mediaItem) + val mediaItem = media.updateAndGet { mediaValue -> + val mediaItem = QueuedMedia( + localId = (mediaValue.maxOfOrNull { it.localId } ?: 0) + 1, + uri = uri, + type = type, + mediaSize = mediaSize, + description = description + ) + mediaValue + mediaItem + }.last() mediaToJob[mediaItem.localId] = viewModelScope.launch { mediaUploader .uploadMedia(mediaItem) .catch { error -> - media.postValue(media.value?.filter { it.localId != mediaItem.localId } ?: emptyList()) + media.update { mediaValue -> mediaValue.filter { it.localId != mediaItem.localId } } uploadError.postValue(error) } .collect { event -> - val item = media.value?.find { it.localId == mediaItem.localId } + val item = media.value.find { it.localId == mediaItem.localId } ?: return@collect val newMediaItem = when (event) { is UploadEvent.ProgressEvent -> @@ -148,16 +153,14 @@ class ComposeViewModel @Inject constructor( is UploadEvent.FinishedEvent -> item.copy(id = event.mediaId, uploadPercent = -1) } - synchronized(media) { - val mediaValue = media.value!! - val index = mediaValue.indexOfFirst { it.localId == newMediaItem.localId } - media.postValue( - if (index == -1) { - mediaValue + newMediaItem + media.update { mediaValue -> + mediaValue.map { mediaItem -> + if (mediaItem.localId == newMediaItem.localId) { + newMediaItem } else { - mediaValue.toMutableList().also { it[index] = newMediaItem } + mediaItem } - ) + } } } } @@ -165,13 +168,23 @@ class ComposeViewModel @Inject constructor( } private fun addUploadedMedia(id: String, type: QueuedMedia.Type, uri: Uri, description: String?) { - val mediaItem = QueuedMedia(System.currentTimeMillis(), uri, type, 0, -1, id, description) - media.value = media.value!! + mediaItem + media.update { mediaValue -> + val mediaItem = QueuedMedia( + localId = (mediaValue.maxOfOrNull { it.localId } ?: 0) + 1, + uri = uri, + type = type, + mediaSize = 0, + uploadPercent = -1, + id = id, + description = description + ) + mediaValue + mediaItem + } } fun removeMediaFromQueue(item: QueuedMedia) { mediaToJob[item.localId]?.cancel() - media.value = media.value!!.withoutFirstWhich { it.localId == item.localId } + media.update { mediaValue -> mediaValue.filter { it.localId == item.localId } } } fun toggleMarkSensitive() { @@ -211,7 +224,7 @@ class ComposeViewModel @Inject constructor( viewModelScope.launch { val mediaUris: MutableList = mutableListOf() val mediaDescriptions: MutableList = mutableListOf() - media.value?.forEach { item -> + media.value.forEach { item -> mediaUris.add(item.uri.toString()) mediaDescriptions.add(item.description) } @@ -248,14 +261,14 @@ class ComposeViewModel @Inject constructor( Observable.just(Unit) }.toLiveData() - val sendObservable = media + val sendFlow = media .filter { items -> items.all { it.uploadPercent == -1 } } .map { val mediaIds: MutableList = mutableListOf() val mediaUris: MutableList = mutableListOf() val mediaDescriptions: MutableList = mutableListOf() val mediaProcessed: MutableList = mutableListOf() - for (item in media.value!!) { + for (item in media.value) { mediaIds.add(item.id!!) mediaUris.add(item.uri) mediaDescriptions.add(item.description ?: "") @@ -285,17 +298,21 @@ class ComposeViewModel @Inject constructor( serviceClient.sendToot(tootToSend) } - return combineLiveData(deletionObservable, sendObservable) { _, _ -> } + return combineLiveData(deletionObservable, sendFlow.asLiveData()) { _, _ -> } } - suspend fun updateDescription(localId: Long, description: String): Boolean { - val newList = media.value!!.toMutableList() - val index = newList.indexOfFirst { it.localId == localId } - if (index != -1) { - newList[index] = newList[index].copy(description = description) + suspend fun updateDescription(localId: Int, description: String): Boolean { + val newMediaList = media.updateAndGet { mediaValue -> + mediaValue.map { mediaItem -> + if (mediaItem.localId == localId) { + mediaItem.copy(description = description) + } else { + mediaItem + } + } } - media.value = newList - val updatedItem = newList.find { it.localId == localId } + + val updatedItem = newMediaList.find { it.localId == localId } if (updatedItem?.id != null) { return api.updateMedia(updatedItem.id, description) .fold({ @@ -387,8 +404,8 @@ class ComposeViewModel @Inject constructor( val draftAttachments = composeOptions?.draftAttachments if (draftAttachments != null) { // when coming from DraftActivity - draftAttachments.forEach { attachment -> - viewModelScope.launch { + viewModelScope.launch { + draftAttachments.forEach { attachment -> pickMedia(attachment.uri, attachment.description) } } From 1eed0e1cc2fc8c1f5dae8c7e75fc00de118e2b7c Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Tue, 3 May 2022 19:13:13 +0200 Subject: [PATCH 03/31] fix unparsed html when sharing status content (#2491) --- .../main/java/com/keylesspalace/tusky/fragment/SFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.java b/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.java index bb02807dd..ad81abe33 100644 --- a/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.java @@ -58,6 +58,7 @@ import com.keylesspalace.tusky.entity.Status; import com.keylesspalace.tusky.network.MastodonApi; import com.keylesspalace.tusky.network.TimelineCases; import com.keylesspalace.tusky.util.LinkHelper; +import com.keylesspalace.tusky.util.StatusParsingHelper; import com.keylesspalace.tusky.view.MuteAccountDialog; import com.keylesspalace.tusky.viewdata.AttachmentViewData; @@ -228,7 +229,7 @@ public abstract class SFragment extends Fragment implements Injectable { String stringToShare = statusToShare.getAccount().getUsername() + " - " + - statusToShare.getContent().toString(); + StatusParsingHelper.parseAsMastodonHtml(statusToShare.getContent()).toString(); sendIntent.putExtra(Intent.EXTRA_TEXT, stringToShare); sendIntent.putExtra(Intent.EXTRA_SUBJECT, statusUrl); sendIntent.setType("text/plain"); From f3d79238034586d2fb81cff21d8ecdeb3a15ad54 Mon Sep 17 00:00:00 2001 From: Ivan Kupalov Date: Tue, 3 May 2022 19:14:55 +0200 Subject: [PATCH 04/31] Improve UX when Login WebView fails to load the page (#2492) Previously we simply closed the screen with the login WebView which could cause confusion. Now we specify that page could not be loaded. As a side effect it will also show the error message which the server returns (if any). --- .../com/keylesspalace/tusky/components/login/LoginActivity.kt | 4 +++- .../tusky/components/login/LoginWebViewActivity.kt | 2 +- app/src/main/res/values/strings.xml | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt index 4df7abc1d..bcbb4abf8 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginActivity.kt @@ -68,7 +68,9 @@ class LoginActivity : BaseActivity(), Injectable { // Authorization failed. Put the error response where the user can read it and they // can try again. setLoading(false) - binding.domainTextInputLayout.error = getString(R.string.error_authorization_denied) + // Use error returned by the server or fall back to the generic message + binding.domainTextInputLayout.error = + result.errorMessage.ifBlank { getString(R.string.error_authorization_denied) } Log.e( TAG, "%s %s".format( diff --git a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt index 58f745e79..a32a164c4 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt @@ -117,7 +117,7 @@ class LoginWebViewActivity : BaseActivity(), Injectable { error: WebResourceError ) { Log.d("LoginWeb", "Failed to load ${data.url}: $error") - finishWithoutSlideOutAnimation() + sendResult(LoginResult.Err(getString(R.string.error_could_not_load_login_page))) } override fun shouldOverrideUrlLoading( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2a209d9a7..fc1ed743c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,6 +9,7 @@ An unidentified authorization error occurred. Authorization was denied. Failed getting a login token. + Could not load the login page. The post is too long! The file must be less than 8MB. Video files must be less than 40MB. From a2cc622683073862f8842ceb9ed764d32ccf2a47 Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Tue, 3 May 2022 19:15:59 +0200 Subject: [PATCH 05/31] fix EmojiCompat.get().process crash in polls (#2494) --- .../com/keylesspalace/tusky/adapter/PollAdapter.kt | 10 +++------- .../tusky/components/account/AccountActivity.kt | 10 +--------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/PollAdapter.kt b/app/src/main/java/com/keylesspalace/tusky/adapter/PollAdapter.kt index 9ffeca9ea..ef366795f 100644 --- a/app/src/main/java/com/keylesspalace/tusky/adapter/PollAdapter.kt +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/PollAdapter.kt @@ -19,7 +19,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat -import androidx.emoji2.text.EmojiCompat import androidx.recyclerview.widget.RecyclerView import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.ItemPollBinding @@ -87,9 +86,8 @@ class PollAdapter : RecyclerView.Adapter>() { when (mode) { RESULT -> { val percent = calculatePercent(option.votesCount, votersCount, voteCount) - val emojifiedPollOptionText = buildDescription(option.title, percent, option.voted, resultTextView.context) + resultTextView.text = buildDescription(option.title, percent, option.voted, resultTextView.context) .emojify(emojis, resultTextView, animateEmojis) - resultTextView.text = EmojiCompat.get().process(emojifiedPollOptionText) val level = percent * 100 val optionColor = if (option.voted) { @@ -103,8 +101,7 @@ class PollAdapter : RecyclerView.Adapter>() { resultTextView.setOnClickListener(resultClickListener) } SINGLE -> { - val emojifiedPollOptionText = option.title.emojify(emojis, radioButton, animateEmojis) - radioButton.text = EmojiCompat.get().process(emojifiedPollOptionText) + radioButton.text = option.title.emojify(emojis, radioButton, animateEmojis) radioButton.isChecked = option.selected radioButton.setOnClickListener { pollOptions.forEachIndexed { index, pollOption -> @@ -114,8 +111,7 @@ class PollAdapter : RecyclerView.Adapter>() { } } MULTIPLE -> { - val emojifiedPollOptionText = option.title.emojify(emojis, checkBox, animateEmojis) - checkBox.text = EmojiCompat.get().process(emojifiedPollOptionText) + checkBox.text = option.title.emojify(emojis, checkBox, animateEmojis) checkBox.isChecked = option.selected checkBox.setOnCheckedChangeListener { _, isChecked -> pollOptions[holder.bindingAdapterPosition].selected = isChecked diff --git a/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt index cc8719bb6..6a8bc7dc6 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt @@ -37,7 +37,6 @@ import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat.Type.systemBars import androidx.core.view.updatePadding -import androidx.emoji2.text.EmojiCompat import androidx.preference.PreferenceManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.viewpager2.widget.MarginPageTransformer @@ -459,14 +458,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI */ private fun updateToolbar() { loadedAccount?.let { account -> - - val emojifiedName = account.name.emojify(account.emojis, binding.accountToolbar, animateEmojis) - - try { - supportActionBar?.title = EmojiCompat.get().process(emojifiedName) - } catch (e: IllegalStateException) { - supportActionBar?.title = emojifiedName - } + supportActionBar?.title = account.name.emojify(account.emojis, binding.accountToolbar, animateEmojis) supportActionBar?.subtitle = String.format(getString(R.string.post_username_format), account.username) } } From f693c5ea210d0e3b774ccc3627a6668cda9e4029 Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 1 May 2022 17:40:32 +0000 Subject: [PATCH 06/31] Translated using Weblate (Polish) Currently translated at 100.0% (16 of 16 strings) Translation: Tusky/Tusky description Translate-URL: https://weblate.tusky.app/projects/tusky/tusky-app/pl/ --- fastlane/metadata/android/pl/changelogs/89.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 fastlane/metadata/android/pl/changelogs/89.txt diff --git a/fastlane/metadata/android/pl/changelogs/89.txt b/fastlane/metadata/android/pl/changelogs/89.txt new file mode 100644 index 000000000..edfc6f0ab --- /dev/null +++ b/fastlane/metadata/android/pl/changelogs/89.txt @@ -0,0 +1,7 @@ +Tusky v17.0 + +- "Otwórz jako..." teraz jest także dostępne w menu na profilach kont gdy używane jest kilka kont +- Login teraz jest obsługiwany w WebView w aplikacji +- Wsparcie dla Androida 12 +- Wsparcie nowego API konfiguracji instancji Mastodon +- i wiele innych małych poprawek i ulepszeń From 90ff6544734bf49f00d89ea610346ef0bfc4672e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Sun, 1 May 2022 17:40:32 +0000 Subject: [PATCH 07/31] Translated using Weblate (Icelandic) Currently translated at 100.0% (16 of 16 strings) Translation: Tusky/Tusky description Translate-URL: https://weblate.tusky.app/projects/tusky/tusky-app/is/ --- fastlane/metadata/android/is/changelogs/89.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 fastlane/metadata/android/is/changelogs/89.txt diff --git a/fastlane/metadata/android/is/changelogs/89.txt b/fastlane/metadata/android/is/changelogs/89.txt new file mode 100644 index 000000000..e379fc723 --- /dev/null +++ b/fastlane/metadata/android/is/changelogs/89.txt @@ -0,0 +1,7 @@ +Tusky útg.17.0 + +- "Opna sem..." er núna líka á valmyndinni í notendasniðum þegar verið er að nota marga aðganga +- Innskráning er núna meðhöndluð í WebView innan forritsins +- Stuðningur við Android 12 +- Stuðningur við API-kerfisviðmót fyrir nýja uppsetningu Mastodon-tilvika +- og mökkur af smærri endurbótum og lagfæringum From a86391a7e928922ff726acb333de1212fd00c552 Mon Sep 17 00:00:00 2001 From: Bruno Miguel Date: Sun, 1 May 2022 17:40:32 +0000 Subject: [PATCH 08/31] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (16 of 16 strings) Translation: Tusky/Tusky description Translate-URL: https://weblate.tusky.app/projects/tusky/tusky-app/pt_PT/ --- fastlane/metadata/android/pt-PT/changelogs/58.txt | 12 ++++++++++++ fastlane/metadata/android/pt-PT/changelogs/61.txt | 7 +++++++ fastlane/metadata/android/pt-PT/changelogs/67.txt | 9 +++++++++ fastlane/metadata/android/pt-PT/changelogs/68.txt | 3 +++ fastlane/metadata/android/pt-PT/changelogs/70.txt | 8 ++++++++ fastlane/metadata/android/pt-PT/changelogs/72.txt | 11 +++++++++++ fastlane/metadata/android/pt-PT/changelogs/74.txt | 8 ++++++++ fastlane/metadata/android/pt-PT/changelogs/77.txt | 10 ++++++++++ fastlane/metadata/android/pt-PT/changelogs/80.txt | 7 +++++++ fastlane/metadata/android/pt-PT/changelogs/82.txt | 5 +++++ fastlane/metadata/android/pt-PT/changelogs/83.txt | 3 +++ fastlane/metadata/android/pt-PT/changelogs/87.txt | 8 ++++++++ fastlane/metadata/android/pt-PT/changelogs/89.txt | 7 +++++++ fastlane/metadata/android/pt-PT/full_description.txt | 12 ++++++++++++ .../metadata/android/pt-PT/short_description.txt | 1 + fastlane/metadata/android/pt-PT/title.txt | 1 + 16 files changed, 112 insertions(+) create mode 100644 fastlane/metadata/android/pt-PT/changelogs/58.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/61.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/67.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/68.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/70.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/72.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/74.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/77.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/80.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/82.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/83.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/87.txt create mode 100644 fastlane/metadata/android/pt-PT/changelogs/89.txt create mode 100644 fastlane/metadata/android/pt-PT/full_description.txt create mode 100644 fastlane/metadata/android/pt-PT/short_description.txt create mode 100644 fastlane/metadata/android/pt-PT/title.txt diff --git a/fastlane/metadata/android/pt-PT/changelogs/58.txt b/fastlane/metadata/android/pt-PT/changelogs/58.txt new file mode 100644 index 000000000..24aad2f26 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/58.txt @@ -0,0 +1,12 @@ +Tusky v6.0 + +- Os filtros de timeline passaram para "Preferências da Conta" e sincronizam com servidor +- Pode ter uma hashtag personalizada como separador +- Suporte a edição de listas +- O editor sugere emojis personalizados ao escrever +- Nova configuração: "seguir tema do sistema" +- Melhor acessibilidade da timeline +- O Tusky ignora notificações desconhecidas, deixando de crashar +- Nova opção: trocar o idioma do sistema por outro +- Novas traduções +- Muitas outras melhorias e correções diff --git a/fastlane/metadata/android/pt-PT/changelogs/61.txt b/fastlane/metadata/android/pt-PT/changelogs/61.txt new file mode 100644 index 000000000..3cc7097e1 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/61.txt @@ -0,0 +1,7 @@ +Tusky v7.0 + +- Suporte para mostragem de votações, para votação e notificação de votações +- Botões novos para filtrar notificações e excluí-las +- Exclua e rascunhe os seus toots +- Novo indicador que mostra, na foto de perfil, se uma conta é um bot (pode ser desativado nas preferências) +- Novas traduções: Norueguês, Bokmål e Esloveno. diff --git a/fastlane/metadata/android/pt-PT/changelogs/67.txt b/fastlane/metadata/android/pt-PT/changelogs/67.txt new file mode 100644 index 000000000..5d3d38494 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/67.txt @@ -0,0 +1,9 @@ +Tusky v9.0 + +- Agora pode criar votações no Tusky +- Pesquisa melhorada +- Nova opção em "Preferências da Conta": "Expandir sempre os toots com Aviso de Conteúdo" +- Avatars em formato quadrado com cantos arredondados +- Agora é possível denunciar utilizadores, mesmo que não tenham toots +- O Tusky vai recusar a ligação através de ligações simples (não encriptadas) em Android 6+ +- Muitas outras pequenas melhorias e correções de bugs diff --git a/fastlane/metadata/android/pt-PT/changelogs/68.txt b/fastlane/metadata/android/pt-PT/changelogs/68.txt new file mode 100644 index 000000000..917921132 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/68.txt @@ -0,0 +1,3 @@ +Tusky v9.1 + +Esta atualização garante compatibilidade com Mastodon 3 e melhora a performance e estabilidade. diff --git a/fastlane/metadata/android/pt-PT/changelogs/70.txt b/fastlane/metadata/android/pt-PT/changelogs/70.txt new file mode 100644 index 000000000..6ac528b12 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/70.txt @@ -0,0 +1,8 @@ +Tusky v10.0 + +- Agora é possível adicionar toots aos favoritos e ver a lista de favoritos no Tusky. +- Já pode agendar toots, no entanto é necessário agendá-los para pelo menos 5 minutos depois do momento da escrita. +- Já pode adicionar listas na barra lateral do Tusky! +- Já pode partilhar ficheiros de som nos teus toots! + +E muitas outras pequenas melhorias e correções de bugs! diff --git a/fastlane/metadata/android/pt-PT/changelogs/72.txt b/fastlane/metadata/android/pt-PT/changelogs/72.txt new file mode 100644 index 000000000..f42b0a8e2 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/72.txt @@ -0,0 +1,11 @@ +Tusky v11.0 + +- Notificações de seguidores pendentes quando a conta está trancada! +- Novas funcionalidades nas "Preferências": + * desativação do gesto que alterna entre separadores + * diálogo de confirmação antes de dar boost + * mostragem da pré-visualização de links nas timelines +- As conversas agora podem ser silenciadas +- As votações passam a ser calculadas pelo número de votantes e não pelo número de votos +- Várias correções relacionadas com a escrita de toots + - Traduções melhoradas diff --git a/fastlane/metadata/android/pt-PT/changelogs/74.txt b/fastlane/metadata/android/pt-PT/changelogs/74.txt new file mode 100644 index 000000000..9595cb1f3 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/74.txt @@ -0,0 +1,8 @@ +Tusky v.12.0 + +- Interface principal melhorada - passa a ser possível mover os separadores para baixo! +- Ao silenciar um utilizador, pode também escolher se também pretende silenciar as notificações +- Agora dá para seguir quantas hashtags quiser num único separador! +- A exibição da descrição dos conteúdos multimédia foi melhorada para suportar descrições super longas + +Registo completo de alterações: https://github.com/tuskyapp/Tusky/releases diff --git a/fastlane/metadata/android/pt-PT/changelogs/77.txt b/fastlane/metadata/android/pt-PT/changelogs/77.txt new file mode 100644 index 000000000..01c57b339 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/77.txt @@ -0,0 +1,10 @@ +Tusky v13.0 + +- Suporte para anotações em perfis (novidade do Mastodon 3.2.0) +- Suporte para anúncios do(s) administrador(es) de instâncias (novidade do Mastodon 3.1.0) + +- O avatar da sua conta selecionada passa a ficar visível na barra de ferramentas principal (canto superior esquerdo) +- Tocar no nome de utilizador na timeline abrirá o perfil em questão + +- Várias pequenas melhorias e correções +- Traduções melhoradas diff --git a/fastlane/metadata/android/pt-PT/changelogs/80.txt b/fastlane/metadata/android/pt-PT/changelogs/80.txt new file mode 100644 index 000000000..866dc8e53 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/80.txt @@ -0,0 +1,7 @@ +Tusky v14.0 + +- Receba notificações quando um utilizador que segue publicar um toot - basta clicar no ícone do sino (novidade do Mastodon 3.3.0) +- O suporte para rascunhos do Tusky foi reescrito para ser mais rápido, simples e menos propenso a erros. +- Foi adicionado uma funcionalidade de bem-estar, que permite limitar algumas funcionalidades no Tusky. +- O Tusky já consegue animar os emojis personalizados +Registo completo de alterações: https://github.com/tuskyapp/Tusky/releases diff --git a/fastlane/metadata/android/pt-PT/changelogs/82.txt b/fastlane/metadata/android/pt-PT/changelogs/82.txt new file mode 100644 index 000000000..0ee9e8760 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/82.txt @@ -0,0 +1,5 @@ +Tusky v15.0 + +- O menu principal passa a mostrar uma opção para ver os utilizadores que pediram para o seguir! +- O relógio para agendar toots ganhou um aspeto mais consistente com o resto do Tusky +Registo completo de alterações: https://github.com/tuskyapp/Tusky/releases diff --git a/fastlane/metadata/android/pt-PT/changelogs/83.txt b/fastlane/metadata/android/pt-PT/changelogs/83.txt new file mode 100644 index 000000000..4c71e64d8 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/83.txt @@ -0,0 +1,3 @@ +Tusky v15.1 + +O Tusky já não crasha ao adicionar descrição às imagens diff --git a/fastlane/metadata/android/pt-PT/changelogs/87.txt b/fastlane/metadata/android/pt-PT/changelogs/87.txt new file mode 100644 index 000000000..79a811570 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/87.txt @@ -0,0 +1,8 @@ +Tusky v16.0 + +- O algoritmo de carregamento da timeline foi completamente reescrito para ser mais rápida, mais estável e mais fácil de manter. +- O Tusky passa a poder animar emojis personalizados no formato APNG & WebP Animated. +- Muitas correções de bugs +- Suporte para Android 11 +- Novas traduções: gaélico escocês, galego, ucraniano +- Traduções melhoradas diff --git a/fastlane/metadata/android/pt-PT/changelogs/89.txt b/fastlane/metadata/android/pt-PT/changelogs/89.txt new file mode 100644 index 000000000..28cebc1b3 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/changelogs/89.txt @@ -0,0 +1,7 @@ +Tusky v17.0 + +- "Abrir como..." está disponível no menu de perfis de contas quando estão várias contas configuradas +- O login passa a ser feito numa WebView dentro da aplicação +- Suporte para Android 12 +- Suporte para a nova API de configuração de instâncias do Mastodon +- Várias pequenas melhorias e correções diff --git a/fastlane/metadata/android/pt-PT/full_description.txt b/fastlane/metadata/android/pt-PT/full_description.txt new file mode 100644 index 000000000..52d67d811 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/full_description.txt @@ -0,0 +1,12 @@ +Tusky é um cliente leve para Mastodon, um servidor de rede social de código aberto e livre. + +• Design Material +• Maioria das APIs do Mastodon implementadas +• Suporte para várias contas +• Temas diurno e noturno, com possibilidade de troca automática de acordo com o horário +• Rascunhos - Escreva os seus toots e guarde-os para mais tarde +• Escolha entre estilos diferentes de emoji +• Otimizado para todos os tamanhos de ecrã +• Código totalmente aberto, sem dependências não-livres como Google Play Services + +Para ler mais sobre o Mastodon, visite o endereço https://joinmastodon.org/ diff --git a/fastlane/metadata/android/pt-PT/short_description.txt b/fastlane/metadata/android/pt-PT/short_description.txt new file mode 100644 index 000000000..38a439d85 --- /dev/null +++ b/fastlane/metadata/android/pt-PT/short_description.txt @@ -0,0 +1 @@ +Um cliente multi-contas para a rede social Mastodon diff --git a/fastlane/metadata/android/pt-PT/title.txt b/fastlane/metadata/android/pt-PT/title.txt new file mode 100644 index 000000000..0238ffc0a --- /dev/null +++ b/fastlane/metadata/android/pt-PT/title.txt @@ -0,0 +1 @@ +Tusky From 76accf0d0df051c3e4e1925494b26e49ed553125 Mon Sep 17 00:00:00 2001 From: ButterflyOfFire Date: Tue, 3 May 2022 17:12:40 +0000 Subject: [PATCH 09/31] Translated using Weblate (French) Currently translated at 100.0% (477 of 477 strings) Translated using Weblate (Arabic) Currently translated at 98.3% (469 of 477 strings) Co-authored-by: ButterflyOfFire Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/ar/ Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/fr/ Translation: Tusky/Tusky --- app/src/main/res/values-ar/strings.xml | 6 ++++++ app/src/main/res/values-fr/strings.xml | 1 + 2 files changed, 7 insertions(+) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index cb6936700..d0160a600 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -551,4 +551,10 @@ 180 يومًا 365 يومًا تحرير منشور + حسابات جديدة + لِج + قام %s بإنشاء حساب + أحدهم أنشأ حسابا جديدا + منشورات تم تعديلها + قام %s بتعديل منشوره \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 37f8b9845..dc30483bd 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -547,4 +547,5 @@ un message avec lequel j\'ai interagi est modifié Messages modifiés Notifications quand un post avec lequel vous avez interagi est modifié + Se connecter \ No newline at end of file From 97e8a25a47aadd9da09d1bd22a6ae80dd7f424aa Mon Sep 17 00:00:00 2001 From: mondstern Date: Tue, 3 May 2022 17:12:41 +0000 Subject: [PATCH 10/31] Translated using Weblate (German) Currently translated at 99.1% (473 of 477 strings) Co-authored-by: mondstern Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/de/ Translation: Tusky/Tusky --- app/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 254a61160..b05ccc963 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -534,4 +534,5 @@ %s hat sich registriert Jemand hat sich registriert Benachrichtigungen, wenn Beiträge bearbeitet werden, mit denen du interagiert hast + Anmelden \ No newline at end of file From 95581fa0269b7872bc9fa23a9fe1ee2af814d04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=E1=BB=93=20Nh=E1=BA=A5t=20Duy?= Date: Tue, 3 May 2022 17:12:41 +0000 Subject: [PATCH 11/31] Translated using Weblate (Vietnamese) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Hồ Nhất Duy Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/vi/ Translation: Tusky/Tusky --- app/src/main/res/values-vi/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 1ec9ef803..5219775de 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -515,4 +515,5 @@ khi một tút mà tôi tương tác bị sửa Sửa tút Thông báo khi tút mà tôi tương tác bị sửa + Đăng nhập \ No newline at end of file From 58bd20edcae2c95c77755942d5aaf718271befa2 Mon Sep 17 00:00:00 2001 From: Makis Diakatos Date: Tue, 3 May 2022 17:12:41 +0000 Subject: [PATCH 12/31] Translated using Weblate (Greek) Currently translated at 22.0% (105 of 477 strings) Co-authored-by: Makis Diakatos Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/el/ Translation: Tusky/Tusky --- app/src/main/res/values-el/strings.xml | 102 +++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 4734fea97..85583a2b2 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -3,4 +3,106 @@ Αυτό δεν μπορεί να είναι κενό. Προέκυψε σφάλμα δικτύου! Παρακαλώ ελέγξτε τη σύνδεσή σας και προσπαθήστε ξανά! Προέκυψε ένα σφάλμα. + Αποκλεισμένοι χρήστες + Ακύρωση αιτήματος ακολούθησης; + Διαγραφή αυτής της συζήτησης; + Δεν υπάρχουν αποτελέσματα + Επεργασία προφίλ + Ακολουθεί + Επαναφορά + ο/η %s σας ακολούθησε + Χρήστες σε σίγαση + Αποσύνδεση + Μην ακολουθείτε + Άρση σίγασης του %s + Διαγραφή και αναδιατύπωση + Επεξεργασία προφίλ + Κοινοποίηση + Άδειες + Ανοίξτε σε browser + Αιτήματα ακολούθησης + Προσθήκη σελιδοδείκτη + Περισσότερα + Σελιδοδείκτες + Σελιδοδείκτες + Ακόλουθοι + Άρση αποκλεισμού + Αγαπημένα + Η δημοσίευση είναι πολύ μεγάλη! + Πληκτρολόγιο emoji + Είστε σίγουροι ότι θέλετε να αποσυνδεθείτε από τον λογαριασμό %1$s; + Προσχέδια + Αγαπημένα + Απάντηση… + Απόρριψη + Αποκλεισμένοι χρήστες + Αφαίρεση προώθησης + Επεξεργασία + Σίγαση του %s + Αποκλεισμός + Αναίρεση + ο/η %s ζήτησε να σας ακολουθήσει + Απάντηση + Καρτέλες + ο/η %s προώθησε τη δημοσίευσή σας + στον/στην %s άρεσε η δημοσίευσή σας + Ακολουθήστε + Αναφορά + Σίγαση + Τα μουσικά αρχεία πρέπει να είναι μικρότερα από 40MB. + Αφαίρεση αγαπημένου + Αναφορά του/της %s + Προτιμήσεις Λογαριασμού + Προσθήκη καρτέλας + Αντιγραφή συνδέσμου + Αναζήτηση… + Αποδοχή + Εμφάνιση προωθήσεων + Προφίλ + Αιτήματα ακολούθησης + Αναζήτηση + Διαγραφή συζήτησης + Διαγραφή + ο/η %s μόλις δημοσίευσε + Αποθήκευση + Γρήγορη Απάντηση + Χρήστες σε σίγαση + Το αρχείο πρέπει να είναι μικρότερο από 8MB. + Απόκρυψη προωθήσεων + Προτιμήσεις + Σύνδεση + Ανακοινώσεις + Προσχέδια + ο/η %s έκανε εγγραφή + Προσπαθήστε ξανά + Διαγραφή αυτής της δημοσίευσης; + Άρση σίγασης + Αγαπημένο + Σύνδεσμοι + Κλείσιμο + Ειδοποιήσεις + Γράψτε + Σύνδεση με Mastodon + Επεξεργασία + Προώθηση + Άρση ακολούθησης αυτού του λογαριασμού; + Απόκρυψη ειδοποιήσεων + Αφαίρεση σελιδοδείκτη + Προειδοποίηση περιεχομένου + Σύνδεσμοι + Σύνδεση… + Προγραμματισμένες δημοσιεύσεις + Προγραμματισμός δημοσίευσης + Προγραμματισμένες δημοσιεύσεις + Δημοσιεύσεις + Καρφιτσωμένο + Ευαίσθητο περιεχόμενο + Κρυμμένα μέσα + ο/η %s το προώθησε + Με απαντήσεις + Δείτε περισσότερα + Δείτε λιγότερα + Κλικ για να δείτε + ο/η %s επεξεργάστηκε τη δημοσίευσή του/της + Διαγραφή και αναδιατύπωση αυτής της δημοσίευσης; \ No newline at end of file From 7b98adf1eed0f1b939c0f33afc159993a261a76e Mon Sep 17 00:00:00 2001 From: Bruno Miguel Date: Tue, 3 May 2022 17:12:41 +0000 Subject: [PATCH 13/31] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (477 of 477 strings) Co-authored-by: Bruno Miguel Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/pt_PT/ Translation: Tusky/Tusky --- app/src/main/res/values-pt-rPT/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index e501ed2ac..aa81160b2 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -339,7 +339,7 @@ Descrição para deficientes visuais \n(até %d caracteres) - + Descrever Remover From cb1f4898ba0d8815f0406e0bec7954faba0ffa30 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 3 May 2022 17:12:41 +0000 Subject: [PATCH 14/31] Translated using Weblate (Italian) Currently translated at 100.0% (477 of 477 strings) Translated using Weblate (Italian) Currently translated at 96.6% (461 of 477 strings) Co-authored-by: Stefano Pigozzi Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/it/ Translation: Tusky/Tusky --- app/src/main/res/values-it/strings.xml | 297 +++++++++++++------------ 1 file changed, 152 insertions(+), 145 deletions(-) diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index b1a3e130d..1a15d152a 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -2,33 +2,33 @@ Si è verificato un errore. Si è verificato un errore di rete! Per favore controlla la tua connessione e riprova! - Questo non può esser vuoto. - Inserito un dominio non valido - Autenticazione fallita con quell\'istanza. - Non riesco a trovare un browser web da usare. + Questo non può essere vuoto. + Inserito dominio non valido + Autenticazione con quell\'istanza fallita. + Nessun browser web utilizzabile trovato. Si è verificato un errore di autenticazione non identificato. - L\'autorizzazione è stata negata. - Errore nell\'acquisizione del token di accesso. - Lo stato è troppo lungo! - La dimensione dei file immagine deve essere inferiore a 8 MB. - La dimensione dei file video deve essere inferiore a 40 MB. - Questo tipo di file non può essere caricato. - Questo file non può essere aperto. - Il permesso di lettura della scheda sd è richiesto. - È richiesta l\'autorizzazione di archiviazione. - Immagini e video non possono essere allegati allo stesso stato. - Il caricamento non è riuscito. - Errore nell\'invio del toot. + Autorizzazione negata. + Acquisizione token di accesso fallita. + Il post è troppo lungo! + Il file deve essere più piccolo di 8 MB. + I video devono essere più piccoli di 40 MB. + Quel tipo di file non può essere caricato. + Non è stato possibile aprire quel file. + È richiesto il permesso di leggere file. + È richiesto il permesso di salvare file. + Non è possibile allegare allo stesso post immagini e video. + Il caricamento è fallito. + Errore nell\'invio del post. Home Notifiche Locale Federata - Messaggi Diretti + Messaggi diretti Schede - Toot + Conversazione Post Con risposte - Fissati in alto + Fissati Seguiti Seguono Preferiti @@ -43,15 +43,15 @@ Contenuto sensibile Media nascosto Clicca per visualizzare - Mostra di Più - Mostra Meno + Mostra di più + Mostra di meno Espandi Riduci - Qui non c\'è niente. - Qui non c\'è niente. Trascina verso il basso per aggiornare! - %s ha boostato il tuo toot - %s ha messo il tuo toot nei preferiti - %s ti segue + Qui non c\'è nulla. + Qui non c\'è nulla. Trascina verso il basso per aggiornare! + %s ha boostato il tuo post + %s ha messo il tuo post nei preferiti + %s ti ha seguito Segnala @%s Commenti aggiuntivi? Risposta veloce @@ -79,7 +79,7 @@ Chiudi Profilo Preferenze - Preferenze Account + Preferenze account Preferiti Utenti silenziati Utenti bloccati @@ -102,14 +102,14 @@ Rifiuta Cerca Bozze - Visibilità dei toot - Avviso per il contenuto + Visibilità dei post + Avviso di contenuto sensibile Tastiera emoji - Aggiungi Scheda + Aggiungi scheda Collegamenti Menzioni Hashtag - Apri autore del boost + Vai all\'autore del boost Mostra boost Mostra preferiti Hashtag @@ -117,11 +117,11 @@ Collegamenti Apri media #%d Scaricando %1$s - Copia il link + Copia link Apri come %s Condividi come … - Condividi URL del toot su… - Condividi toot su… + Condividi URL del post su… + Condividi post su… Condividi media su… Inviato! Utente sbloccato @@ -132,7 +132,7 @@ Cosa succede? Avviso di contenuto sensibile Mostra nome - Bio + Biografia Cerca… Nessun risultato Rispondi… @@ -152,22 +152,22 @@ Scarica Revocare la richiesta di seguire? Smettere di seguire questo account? - Eliminare questo toot? + Eliminare questo post\? Pubblico: visibile sulla timeline pubblica - Non Elencato: non visibile sulla timeline pubblica e locale - Solo Follower: visibile solo dai tuoi follower + Non in elenco: non visibile sulla timeline pubblica e locale + Solo follower: visibile solo dai tuoi follower Diretto: visibile solo agli utenti menzionati - Modifica Notifiche + Notifiche Notifiche Allarmi Notifica con suoneria Notifica con vibrazione Notifica con luce Notificami quando - sono stato menzionato - sono stato seguito - i miei post sono boostati - i miei post sono messi nei preferiti + vengo menzionato + vengo seguito + i miei post vengono boostati + i miei post vengono messi nei preferiti Aspetto Tema dell\'app Timeline @@ -176,10 +176,10 @@ Chiaro Nero Automatico al tramonto - Usa Tema di Sistema + Usa tema di sistema Browser - Usa Tab Personalizzate di Chrome - Nascondi il pulsante componi mentre scorri + Usa Custom Tabs di Chrome + Nascondi il pulsante Componi mentre scorri Lingua Filtraggio della timeline Schede @@ -193,25 +193,25 @@ Porta proxy HTTP Privacy di default dei post Segna sempre media come contenuto sensibile - Pubblicando (sincronizzato con il server) + Pubblicazione (sincronizzato con il server) Sincronizzazione delle impostazioni fallita Pubblico - Non elencato - Solo per chi ti segue - Dimensione del testo degli stati + Non in elenco + Solo follower + Dimensione del testo dei post Piccolissimo Piccolo Normale Grande Grandissimo - Nuove Menzioni - Notifiche quando qualcuno ti menziona - Nuove persone che ti seguono - Notifiche su nuove persone che ti seguono + Nuove menzioni + Notifiche di quando vieni menzionato da qualcuno + Nuovi follower + Notifiche su nuovi follower Boost - Notifiche quando i tuoi toot vengono boostati + Notifiche sui tuoi post che vengono boostati Preferiti - Notifiche quando i tuoi toot vengono segnati come preferiti + Notifiche sui tuoi post che vengono segnati come preferiti %s ti ha menzionato %1$s, %2$s, %3$s e %4$d altri %1$s, %2$s e %3$s @@ -234,14 +234,14 @@ --> Sito web del progetto:\n https://tusky.app - Segnala problemi & richiedi funzionalità:\n - https://github.com/tuskyapp/Tusky/issues + Segnala problemi e richiedi funzionalità: +\n https://github.com/tuskyapp/Tusky/issues Profilo di Tusky - Condividi contenuto del toot - Condividi link al toot + Condividi contenuto del post + Condividi link al post Immagini Video - In attesa di approvazione + Richiesta inviata in %d a in %dg @@ -250,14 +250,14 @@ in %ds %da %dg - %d o - %d min - %d s - Seguono te - Mostra sempre tutto il contenuto sensibile + %do + %dmin + %ds + Ti segue + Mostra sempre tutti i contenuti sensibili Media Rispondendo a @%s - carica di più + carica altri Timeline pubbliche Conversazioni Aggiungi filtro @@ -265,7 +265,7 @@ Rimuovi Aggiorna Frase da filtrare - Aggiungi Account + Aggiungi account Aggiungi un nuovo Account Mastodon Liste Liste @@ -288,29 +288,29 @@ Inserisci descrizione Rimuovi Blocca account - Richiede la tua approvazione manuale di chi ti segue + Richiedi una tua approvazione manuale per seguirti Salvare bozza? - Inviando il Toot… + Inviando il post… Errore durante l\'invio - Invio Toot + Invio post Invio annullato - Una copia del toot è stata salvata nelle tue bozze + Una copia del post è stata salvata nelle tue bozze Componi La tua istanza %s non ha nessuna emoji personalizzata - Stile di emoji - Predefiniti del sistema + Stile delle emoji + Predefinite del sistema Dovrai prima scaricare questo pacchetto di emoji - Eseguendo una ricerca… - Espandi/Riduci tutti gli stati - Apri toot + Ricerca in corso… + Espandi/riduci tutti i post + Apri post Riavvio dell\'app richiesto Devi riavviare Tusky per applicare queste modifiche Più tardi Riavvia Le emoji predefinite del tuo dispositivo - Le emoji Blob conosciute da Android 4.4-7.1 + Le emoji Blob di Android 4.4-7.1 Le emoji standard di Mastodon - Scaricamento fallito + Download fallito Bot %1$s si è spostato su: Boost con la visibilità del post di origine @@ -323,63 +323,60 @@ aggiungi dati Etichetta Contenuto - Usa tempo assoluto + Usa ora assoluta Il profilo dell\'utente mostrato qui sotto potrebbe essere incompleto. Premi per aprire il profilo completo nel browser. - Non fissare + Smetti di fissare Fissa - %1$s Mi piace - %1$s Mi piace + %1$s Preferito + %1$s Preferiti <b>%s</b> Boost <b>%s</b> Boost Boostato da - Preferito da + Aggiunto ai preferiti da %1$s %1$s e %2$s %1$s, %2$s ed altri %3$d - limite massimo di %1$d tab raggiunto - limite massimo di %1$d tab raggiunto + limite massimo di %1$d scheda raggiunto + limite massimo di %1$d schede raggiunto - Media: %s - + Media: %s Contenuto sensibile: %s Nessuna descrizione Ribloggato - Apprezzato - + Messo nei preferiti Pubblico - Non elencato - - Seguaci + Non in elenco + Solo follower Diretti Nome della lista Scarica media Scaricando media - Componi Toot + Componi post Hashtag senza # Componi - Pulisci + Svuota Filtra Applica - Mostra indicatore per bot + Mostra indicatore bot Sei sicuro di voler permanentemente eliminare tutte le tue notifiche\? Cancella e riscrivi - Cancellare e riscrivere questo toot\? + Cancellare e riscrivere questo post\? %s voto %s voti - termina alle %s - terminato + si conclude alle %s + concluso Vota Domini nascosti Domini nascosti @@ -387,37 +384,37 @@ %s mostrati Sei sicuro di voler bloccare tutto %s\? Non vedrai nessun contenuto da quel dominio in nessuna timeline pubblica o nelle tue notifiche. I tuoi seguaci che stanno in quel dominio saranno rimossi. Nascondi l\'intero dominio - Le votazioni sono finite - Mostra le animazioni delle GIF negli avatar + dei sondaggi si sono conclusi + Riproduci animazioni avatar Votazioni - Notifiche sulle votazioni che sono concluse + Notifiche sulle votazioni che si sono concluse Parola intera Quando la parola chiave o la frase sono composte da soli caratteri alfanumerici, sarà applicata solo se corrisponde alla parola completa - Insieme di emoji di Google + Set di emoji di Google Segnalibri Segnalibro Modifica Segnalibri Aggiungi sondaggio - Fatto con Tusky - Espandi sempre i toot segnalati come contenuto sensibile - Messo nei segalibri + Fatto usando Tusky + Espandi sempre i post segnalati come contenuto sensibile + Messo nei segnalibri Sondaggio con scelte: %1$s, %2$s, %3$s, %4$s; %5$s Scegli lista Lista Azioni per l\'immagine %s - Un sondaggio che hai votato è terminato - Un sondaggio che hai creato è terminato + Un sondaggio che hai votato si è concluso + Un sondaggio che hai creato si è concluso - %d giorno rimasti + %d giorno rimasto %d giorni rimasti - %d ora rimasti + %d ora rimasta %d ore rimasti - %d minuto rimasti + %d minuto rimasto %d minuti rimasti @@ -427,12 +424,12 @@ Continua Indietro Fatto - Inviato con successo @%s + Segnalato @%s con successo Altri commenti Inoltra a %s - Errore durante l\'invio - Errore durante lo scaricamento degli aggiornamenti - La segnalazione sarà inviata al moderatore del tuo server. Puoi spiegare perchè vuoi segnalare questo utente qui sotto: + Segnalazione fallita + Scaricamento dei post fallito + La segnalazione sarà inviata al moderatore del tuo server. Puoi spiegare perchè stai segnalando questo utente qui sotto: L\'utente è su un altro server. Mandare una copia della segnalazione anche lì\? Utenti Errore durante la ricerca @@ -450,10 +447,10 @@ Scelta %d Modifica Errore nella ricerca del post %s - Toot programmati - Toot programmati - Programma un toot - RIpristina + Post programmati + Post programmati + Programma un post + Ripristina %1$s • %2$s Non hai bozze. @@ -464,66 +461,66 @@ Aggiungi hashtag Silenziare @%s\? Bloccare @%s\? - Non silenziare più %s - Smetti di silenziare conversazione + Smetti di silenziare %s + Smetti di silenziare la conversazione Silenzia conversazione %s ha chiesto di seguirti - La dimensione dei file audio deve essere inferiore a 40 MB. + I file audio devono essere più piccoli di 40 MB. Smetti di silenziare %s Richieste di seguirti Salvato! La tua nota privata su questo account Nascondi il titolo della barra degli strumenti in alto - Mostra la finestra di dialogo di conferma prima del boosting + Mostra la finestra di conferma prima di boostare Mostra le anteprime dei collegamenti nelle timelines - Mastodon ha un intervallo minimo di programmazione di 5 minuti. + Mastodon ha un intervallo di programmazione minimo di 5 minuti. Non ci sono annunci. - Non hai stati pianificati. + Non hai post pianificati. Abilita il gesto di scorrimento per passare da una scheda all\'altra Notifiche sulle richieste di essere seguiti - Parte inferiore + In fondo In cima - Posizione di navigazione principale - Mostra sfumature colorate per i media nascosti + Posizione barra di navigazione principale + Mostra gradienti colorati per i media nascosti Nascondi notifiche Disattiva le notifiche da %s Riattiva le notifiche da %s Annunci - Richieste di seguirti + mi viene richiesto di seguirmi Nascondi statistiche quantitative sui profili Nascondi le statistiche quantitative sui post - Limita le notifiche della timeline - Revisiona le notifiche + Limita le notifiche dalla timeline + Rivedi le notifiche Benessere - Notifiche di quando qualcuno a cui sei iscritto ha pubblicato un nuovo toot - Nuovi toots - qualcuno a cui sono iscritto ha pubblicato un nuovo toot - %s appena pubblicato + Notifiche di nuovi post di qualcuno a cui sei iscritto + Nuovi post + qualcuno che seguo ha pubblicato un nuovo post + %s ha appena pubblicato Non puoi caricare più di %1$d allegato multimediale. Non puoi caricare più di %1$d allegati multimediali. - Il toot a cui hai scritto una risposta è stato rimosso - Bozza cancellata - L\'invio di questo toot è fallito! + Il post a cui hai scritto una risposta è stato rimosso + Bozza eliminata + L\'invio di questo post è fallito! Sei sicuro di voler cancellare la lista %s\? Indefinita Durata Allegati Audio - Mostra le animazioni delle emojis personalizzate + Riproduci emoji animate Iscriviti Rimuovere questa conversazione\? - Errore nel recuperare le informazioni sulla risposta + Errore nel recupero delle informazioni sulla risposta Disiscriviti - Rimuovi conversazione + Elimina conversazione Alcune informazioni che potrebbero influenzare il tuo benessere mentale saranno nascoste. Questo include: \n \n - Notifiche riguardo a Preferiti/Boost/Following -\n - Conteggio dei Preferiti/Boost nei toot -\n - Statistiche riguardo a Preferiti e Post nei profili +\n - Conteggio dei Preferiti/Boost nei post +\n - Statistiche riguardo a Preferiti/Post nei profili \n -\n Le notifiche push non saranno influenzate, ma puoi rivedere le tue impostazioni delle notifiche manualmente. +\n Le notifiche push non saranno influenzate, ma puoi modificare le tue impostazioni delle notifiche manualmente. Rimuovi segnalibro Chiedi conferma prima di boostare 14 giorni @@ -532,5 +529,15 @@ 90 giorni 180 giorni 365 giorni - Anche se il tuo account non è bloccato, lo staff di %1$s ha pensato che potresti voler controllare queste richieste di following da parte questi account manualmente. + Anche se il tuo account non è bloccato, lo staff di %1$s ha pensato che potresti voler verificare le richieste di seguirti da parte questi account manualmente. + %s si è registrato + qualcuno si è registrato + Login + %s ha modificato il suo post + un post con cui ho interagito è stato modificato + Componi post + Registrazioni + Notifiche di quando qualcuno si è registrato + Modifiche ai post + Notifiche di quando i post con cui hai interagito vengono modificati \ No newline at end of file From db81ede04a7309962b1328119448612df6d34c2c Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Wed, 4 May 2022 18:40:29 +0200 Subject: [PATCH 15/31] fix login webview title color with light theme (#2497) --- .../tusky/components/login/LoginWebViewActivity.kt | 4 ++-- .../layout/{login_webview.xml => activity_login_webview.xml} | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) rename app/src/main/res/layout/{login_webview.xml => activity_login_webview.xml} (88%) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt index a32a164c4..2ed38720b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/login/LoginWebViewActivity.kt @@ -20,7 +20,7 @@ import androidx.core.net.toUri import com.keylesspalace.tusky.BaseActivity import com.keylesspalace.tusky.BuildConfig import com.keylesspalace.tusky.R -import com.keylesspalace.tusky.databinding.LoginWebviewBinding +import com.keylesspalace.tusky.databinding.ActivityLoginWebviewBinding import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.viewBinding @@ -78,7 +78,7 @@ sealed class LoginResult : Parcelable { /** Activity to do Oauth process using WebView. */ class LoginWebViewActivity : BaseActivity(), Injectable { - private val binding by viewBinding(LoginWebviewBinding::inflate) + private val binding by viewBinding(ActivityLoginWebviewBinding::inflate) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/res/layout/login_webview.xml b/app/src/main/res/layout/activity_login_webview.xml similarity index 88% rename from app/src/main/res/layout/login_webview.xml rename to app/src/main/res/layout/activity_login_webview.xml index 67d47d6f8..1630239ef 100644 --- a/app/src/main/res/layout/login_webview.xml +++ b/app/src/main/res/layout/activity_login_webview.xml @@ -11,8 +11,7 @@ + android:layout_height="wrap_content" /> From b4eda5ea65e71419233b6a350ade04baf4c95e1f Mon Sep 17 00:00:00 2001 From: Levi Bard Date: Thu, 5 May 2022 18:27:05 +0200 Subject: [PATCH 16/31] Unbreak link previews in timelines (#2506) --- .../timeline/TimelineTypeMappers.kt | 12 ++++--- .../keylesspalace/tusky/db/AppDatabase.java | 9 +++++- .../com/keylesspalace/tusky/db/TimelineDao.kt | 2 +- .../tusky/db/TimelineStatusEntity.kt | 3 +- .../com/keylesspalace/tusky/di/AppModule.kt | 2 +- .../keylesspalace/tusky/db/TimelineDaoTest.kt | 32 +++++++++++++++++-- 6 files changed, 50 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineTypeMappers.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineTypeMappers.kt index 6ec954239..12422a954 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineTypeMappers.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineTypeMappers.kt @@ -21,6 +21,7 @@ import com.keylesspalace.tusky.db.TimelineAccountEntity import com.keylesspalace.tusky.db.TimelineStatusEntity import com.keylesspalace.tusky.db.TimelineStatusWithAccount import com.keylesspalace.tusky.entity.Attachment +import com.keylesspalace.tusky.entity.Card import com.keylesspalace.tusky.entity.Emoji import com.keylesspalace.tusky.entity.HashTag import com.keylesspalace.tusky.entity.Poll @@ -96,7 +97,8 @@ fun Placeholder.toEntity(timelineUserId: Long): TimelineStatusEntity { expanded = loading, contentCollapsed = false, contentShowing = false, - pinned = false + pinned = false, + card = null, ) } @@ -136,7 +138,8 @@ fun Status.toEntity( expanded = expanded, contentShowing = contentShowing, contentCollapsed = contentCollapsed, - pinned = actionableStatus.pinned == true + pinned = actionableStatus.pinned == true, + card = actionableStatus.card?.let(gson::toJson), ) } @@ -151,6 +154,7 @@ fun TimelineStatusWithAccount.toViewData(gson: Gson): StatusViewData { val application = gson.fromJson(status.application, Status.Application::class.java) val emojis: List = gson.fromJson(status.emojis, emojisListType) ?: emptyList() val poll: Poll? = gson.fromJson(status.poll, Poll::class.java) + val card: Card? = gson.fromJson(status.card, Card::class.java) val reblog = status.reblogServerId?.let { id -> Status( @@ -178,7 +182,7 @@ fun TimelineStatusWithAccount.toViewData(gson: Gson): StatusViewData { pinned = false, muted = status.muted, poll = poll, - card = null + card = card, ) } val status = if (reblog != null) { @@ -235,7 +239,7 @@ fun TimelineStatusWithAccount.toViewData(gson: Gson): StatusViewData { pinned = status.pinned, muted = status.muted, poll = poll, - card = null + card = card, ) } return StatusViewData.Concrete( diff --git a/app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java b/app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java index 293db65e8..d5f023e58 100644 --- a/app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java +++ b/app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java @@ -31,7 +31,7 @@ import java.io.File; */ @Database(entities = { DraftEntity.class, AccountEntity.class, InstanceEntity.class, TimelineStatusEntity.class, TimelineAccountEntity.class, ConversationEntity.class - }, version = 34) + }, version = 35) public abstract class AppDatabase extends RoomDatabase { public abstract AccountDao accountDao(); @@ -534,4 +534,11 @@ public abstract class AppDatabase extends RoomDatabase { database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `notificationsUpdates` INTEGER NOT NULL DEFAULT 1"); } }; + + public static final Migration MIGRATION_34_35 = new Migration(34, 35) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL("ALTER TABLE `TimelineStatusEntity` ADD COLUMN `card` TEXT"); + } + }; } diff --git a/app/src/main/java/com/keylesspalace/tusky/db/TimelineDao.kt b/app/src/main/java/com/keylesspalace/tusky/db/TimelineDao.kt index dd59f2a3e..2c6ef1887 100644 --- a/app/src/main/java/com/keylesspalace/tusky/db/TimelineDao.kt +++ b/app/src/main/java/com/keylesspalace/tusky/db/TimelineDao.kt @@ -36,7 +36,7 @@ SELECT s.serverId, s.url, s.timelineUserId, s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt, s.emojis, s.reblogsCount, s.favouritesCount, s.reblogged, s.favourited, s.bookmarked, s.sensitive, s.spoilerText, s.visibility, s.mentions, s.tags, s.application, s.reblogServerId,s.reblogAccountId, -s.content, s.attachments, s.poll, s.muted, s.expanded, s.contentShowing, s.contentCollapsed, s.pinned, +s.content, s.attachments, s.poll, s.card, s.muted, s.expanded, s.contentShowing, s.contentCollapsed, s.pinned, a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId', a.localUsername as 'a_localUsername', a.username as 'a_username', a.displayName as 'a_displayName', a.url as 'a_url', a.avatar as 'a_avatar', diff --git a/app/src/main/java/com/keylesspalace/tusky/db/TimelineStatusEntity.kt b/app/src/main/java/com/keylesspalace/tusky/db/TimelineStatusEntity.kt index 41b122c36..2c4d45c32 100644 --- a/app/src/main/java/com/keylesspalace/tusky/db/TimelineStatusEntity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/db/TimelineStatusEntity.kt @@ -78,7 +78,8 @@ data class TimelineStatusEntity( val expanded: Boolean, // used as the "loading" attribute when this TimelineStatusEntity is a placeholder val contentCollapsed: Boolean, val contentShowing: Boolean, - val pinned: Boolean + val pinned: Boolean, + val card: String?, ) @Entity( diff --git a/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt index c92d52ef1..0861e9cf0 100644 --- a/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt +++ b/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt @@ -63,7 +63,7 @@ class AppModule { AppDatabase.Migration25_26(appContext.getExternalFilesDir("Tusky")), AppDatabase.MIGRATION_26_27, AppDatabase.MIGRATION_27_28, AppDatabase.MIGRATION_28_29, AppDatabase.MIGRATION_29_30, AppDatabase.MIGRATION_30_31, AppDatabase.MIGRATION_31_32, - AppDatabase.MIGRATION_32_33, AppDatabase.MIGRATION_33_34 + AppDatabase.MIGRATION_32_33, AppDatabase.MIGRATION_33_34, AppDatabase.MIGRATION_34_35, ) .build() } diff --git a/app/src/test/java/com/keylesspalace/tusky/db/TimelineDaoTest.kt b/app/src/test/java/com/keylesspalace/tusky/db/TimelineDaoTest.kt index 889e5f989..ed652418a 100644 --- a/app/src/test/java/com/keylesspalace/tusky/db/TimelineDaoTest.kt +++ b/app/src/test/java/com/keylesspalace/tusky/db/TimelineDaoTest.kt @@ -369,13 +369,36 @@ class TimelineDaoTest { assertEquals("99", timelineDao.getTopPlaceholderId(1)) } + @Test + fun `preview card survives roundtrip`() = runBlocking { + val setOne = makeStatus(statusId = 3, cardUrl = "https://foo.bar") + + for ((status, author, reblogger) in listOf(setOne)) { + timelineDao.insertAccount(author) + reblogger?.let { + timelineDao.insertAccount(it) + } + timelineDao.insertStatus(status) + } + + val pagingSource = timelineDao.getStatuses(setOne.first.timelineUserId) + + val loadResult = pagingSource.load(PagingSource.LoadParams.Refresh(null, 2, false)) + + val loadedStatuses = (loadResult as PagingSource.LoadResult.Page).data + + assertEquals(1, loadedStatuses.size) + assertStatuses(listOf(setOne), loadedStatuses) + } + private fun makeStatus( accountId: Long = 1, statusId: Long = 10, reblog: Boolean = false, createdAt: Long = statusId, authorServerId: String = "20", - domain: String = "mastodon.example" + domain: String = "mastodon.example", + cardUrl: String? = null, ): Triple { val author = TimelineAccountEntity( serverId = authorServerId, @@ -403,6 +426,10 @@ class TimelineDaoTest { ) } else null + val card = when (cardUrl) { + null -> null + else -> "{ url: \"$cardUrl\" }" + } val even = accountId % 2 == 0L val status = TimelineStatusEntity( serverId = statusId.toString(), @@ -433,7 +460,8 @@ class TimelineDaoTest { expanded = false, contentCollapsed = false, contentShowing = true, - pinned = false + pinned = false, + card = card, ) return Triple(status, author, reblogAuthor) } From beaed6b8751e547564e5e40c6cb8f93c7a7df88f Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Mon, 9 May 2022 19:39:43 +0200 Subject: [PATCH 17/31] Fix crash when saving redrafted media to drafts (#2502) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix crash when saving draft from redraft * fix crash when saving draft from redraft * replace ... with … --- .../components/compose/ComposeActivity.kt | 15 ++++- .../components/compose/ComposeViewModel.kt | 49 ++++++++------- .../tusky/components/drafts/DraftHelper.kt | 63 ++++++++++++++----- app/src/main/res/values/strings.xml | 1 + 4 files changed, 87 insertions(+), 41 deletions(-) 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 321626147..a6e8d6776 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 @@ -967,8 +967,19 @@ class ComposeActivity : } private fun saveDraftAndFinish(contentText: String, contentWarning: String) { - viewModel.saveDraft(contentText, contentWarning) - finishWithoutSlideOutAnimation() + lifecycleScope.launch { + val dialog = if (viewModel.shouldShowSaveDraftDialog()) { + ProgressDialog.show( + this@ComposeActivity, null, + getString(R.string.saving_draft), true, false + ) + } else { + null + } + viewModel.saveDraft(contentText, contentWarning) + dialog?.cancel() + finishWithoutSlideOutAnimation() + } } override fun search(token: String): List { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt index 7b1805327..abf2ff42c 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/ComposeViewModel.kt @@ -220,31 +220,36 @@ class ComposeViewModel @Inject constructor( } } - fun saveDraft(content: String, contentWarning: String) { - viewModelScope.launch { - val mediaUris: MutableList = mutableListOf() - val mediaDescriptions: MutableList = mutableListOf() - media.value.forEach { item -> - mediaUris.add(item.uri.toString()) - mediaDescriptions.add(item.description) - } - - draftHelper.saveDraft( - draftId = draftId, - accountId = accountManager.activeAccount?.id!!, - inReplyToId = inReplyToId, - content = content, - contentWarning = contentWarning, - sensitive = markMediaAsSensitive.value!!, - visibility = statusVisibility.value!!, - mediaUris = mediaUris, - mediaDescriptions = mediaDescriptions, - poll = poll.value, - failedToSend = false - ) + fun shouldShowSaveDraftDialog(): Boolean { + // if any of the media files need to be downloaded first it could take a while, so show a loading dialog + return media.value.any { mediaValue -> + mediaValue.uri.scheme == "https" } } + suspend fun saveDraft(content: String, contentWarning: String) { + val mediaUris: MutableList = mutableListOf() + val mediaDescriptions: MutableList = mutableListOf() + media.value.forEach { item -> + mediaUris.add(item.uri.toString()) + mediaDescriptions.add(item.description) + } + + draftHelper.saveDraft( + draftId = draftId, + accountId = accountManager.activeAccount?.id!!, + inReplyToId = inReplyToId, + content = content, + contentWarning = contentWarning, + sensitive = markMediaAsSensitive.value!!, + visibility = statusVisibility.value!!, + mediaUris = mediaUris, + mediaDescriptions = mediaDescriptions, + poll = poll.value, + failedToSend = false + ) + } + /** * Send status to the server. * Uses current state plus provided arguments. diff --git a/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftHelper.kt b/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftHelper.kt index 7511dc3c3..a6cd3fcd7 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftHelper.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/drafts/DraftHelper.kt @@ -30,7 +30,12 @@ import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.util.IOUtils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.Request +import okio.buffer +import okio.sink import java.io.File +import java.io.IOException import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -38,6 +43,7 @@ import javax.inject.Inject class DraftHelper @Inject constructor( val context: Context, + val okHttpClient: OkHttpClient, db: AppDatabase ) { @@ -71,11 +77,11 @@ class DraftHelper @Inject constructor( val uris = mediaUris.map { uriString -> uriString.toUri() - }.map { uri -> - if (uri.isNotInFolder(draftDirectory)) { - uri.copyToFolder(draftDirectory) - } else { + }.mapNotNull { uri -> + if (uri.isInFolder(draftDirectory)) { uri + } else { + uri.copyToFolder(draftDirectory) } } @@ -114,6 +120,7 @@ class DraftHelper @Inject constructor( ) draftDao.insertOrReplace(draft) + Log.d("DraftHelper", "saved draft to db") } suspend fun deleteDraftAndAttachments(draftId: Int) { @@ -133,33 +140,55 @@ class DraftHelper @Inject constructor( } } - suspend fun deleteAttachments(draft: DraftEntity) { - withContext(Dispatchers.IO) { - draft.attachments.forEach { attachment -> - if (context.contentResolver.delete(attachment.uri, null, null) == 0) { - Log.e("DraftHelper", "Did not delete file ${attachment.uriString}") - } + suspend fun deleteAttachments(draft: DraftEntity) = withContext(Dispatchers.IO) { + draft.attachments.forEach { attachment -> + if (context.contentResolver.delete(attachment.uri, null, null) == 0) { + Log.e("DraftHelper", "Did not delete file ${attachment.uriString}") } } } - private fun Uri.isNotInFolder(folder: File): Boolean { + private fun Uri.isInFolder(folder: File): Boolean { val filePath = path ?: return true return File(filePath).parentFile == folder } - private fun Uri.copyToFolder(folder: File): Uri { + private fun Uri.copyToFolder(folder: File): Uri? { val contentResolver = context.contentResolver - val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date()) - val mimeType = contentResolver.getType(this) - val map = MimeTypeMap.getSingleton() - val fileExtension = map.getExtensionFromMimeType(mimeType) + val fileExtension = if (scheme == "https") { + lastPathSegment?.substringAfterLast('.', "tmp") + } else { + val mimeType = contentResolver.getType(this) + val map = MimeTypeMap.getSingleton() + map.getExtensionFromMimeType(mimeType) + } val filename = String.format("Tusky_Draft_Media_%s.%s", timeStamp, fileExtension) val file = File(folder, filename) - IOUtils.copyToFile(contentResolver, this, file) + + if (scheme == "https") { + // saving redrafted media + try { + val request = Request.Builder().url(toString()).build() + + val response = okHttpClient.newCall(request).execute() + + val sink = file.sink().buffer() + + response.body?.source()?.use { input -> + sink.use { output -> + output.writeAll(input) + } + } + } catch (ex: IOException) { + Log.w("DraftHelper", "failed to save media", ex) + return null + } + } else { + IOUtils.copyToFile(contentResolver, this, file) + } return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileprovider", file) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fc1ed743c..d8ce83941 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -640,5 +640,6 @@ Unsubscribe Compose Post + Saving draft… From 45ac280db768cb9bc25a0551d3e0326f56ab317a Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Mon, 9 May 2022 19:40:32 +0200 Subject: [PATCH 18/31] Add Portuguese (Portugal) to the in-app language picker (#2507) --- app/src/main/res/values/donottranslate.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index e6f9f62a7..ed1e30cb6 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -57,6 +57,7 @@ Occitan Polski Português (Brasil) + Português (Portugal) Slovenščina Svenska Taqbaylit @@ -106,6 +107,7 @@ oc pl pt-BR + pt-PT sl sv kab From fc1e153cb3cfe2ede5e07c489ba7dadc7afd3b36 Mon Sep 17 00:00:00 2001 From: idontwanttohaveausername Date: Mon, 9 May 2022 17:39:49 +0000 Subject: [PATCH 19/31] Translated using Weblate (Ukrainian) Currently translated at 100.0% (478 of 478 strings) Co-authored-by: idontwanttohaveausername Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/uk/ Translation: Tusky/Tusky --- app/src/main/res/values-uk/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 7d4b806ec..67eb11cbd 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -100,7 +100,7 @@ %s надсилає запит на підписку %s підписується на вас Тут нічого немає. Потягніть вниз, щоб оновити! - Тут нічого немає. + Тут пусто. Згорнути Розгорнути Натисніть для перегляду From 8b840396fd2368dc69d660877127c525d759aaa4 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Mon, 9 May 2022 17:39:49 +0000 Subject: [PATCH 20/31] Translated using Weblate (Ukrainian) Currently translated at 100.0% (478 of 478 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (478 of 478 strings) Co-authored-by: Ihor Hordiichuk Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/uk/ Translation: Tusky/Tusky --- app/src/main/res/values-uk/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 67eb11cbd..6c5100970 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -100,7 +100,7 @@ %s надсилає запит на підписку %s підписується на вас Тут нічого немає. Потягніть вниз, щоб оновити! - Тут пусто. + Тут порожньо. Згорнути Розгорнути Натисніть для перегляду @@ -549,4 +549,5 @@ Сповіщення, коли редагується повідомлення, з яким ви взаємодіяли Редакції допису Вхід + Не вдалося завантажити сторінку входу. \ No newline at end of file From 078603819a2a86e557226bf929664b4f9f5832dc Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Mon, 9 May 2022 17:39:49 +0000 Subject: [PATCH 21/31] Translated using Weblate (Italian) Currently translated at 100.0% (478 of 478 strings) Co-authored-by: Stefano Pigozzi Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/it/ Translation: Tusky/Tusky --- app/src/main/res/values-it/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 1a15d152a..162846af5 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -540,4 +540,5 @@ Notifiche di quando qualcuno si è registrato Modifiche ai post Notifiche di quando i post con cui hai interagito vengono modificati + Non è stato possibile caricare la pagina di login. \ No newline at end of file From 010a4372f9af4b5b3e0e844bd154a98cce834dbd Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 9 May 2022 17:39:49 +0000 Subject: [PATCH 22/31] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (478 of 478 strings) Co-authored-by: Eric Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/zh_Hans/ Translation: Tusky/Tusky --- app/src/main/res/values-zh-rCN/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 5dd1975f2..f3d7b2aaf 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -535,4 +535,5 @@ 我进行过互动的嘟文被编辑了 嘟文编辑 当你进行过互动的嘟文被编辑时发出通知 + 无法加载登录页。 \ No newline at end of file From aa200404798ee66d3f578a097482b388849bd784 Mon Sep 17 00:00:00 2001 From: Vegard Skjefstad Date: Mon, 9 May 2022 17:39:49 +0000 Subject: [PATCH 23/31] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (478 of 478 strings) Co-authored-by: Vegard Skjefstad Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/nb_NO/ Translation: Tusky/Tusky --- app/src/main/res/values-no-rNB/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-no-rNB/strings.xml b/app/src/main/res/values-no-rNB/strings.xml index 3512b4808..80b744bb5 100644 --- a/app/src/main/res/values-no-rNB/strings.xml +++ b/app/src/main/res/values-no-rNB/strings.xml @@ -527,4 +527,5 @@ Redigerte innlegg Varslinger når et innlegg du har hatt en interaksjon med er redigert Innlogging + Klarte ikke å laste innloggingssiden. \ No newline at end of file From 9ec41903cfaeb52e0de38f3401fadfa11969066c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=E1=BB=93=20Nh=E1=BA=A5t=20Duy?= Date: Mon, 9 May 2022 17:39:49 +0000 Subject: [PATCH 24/31] Translated using Weblate (Vietnamese) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (478 of 478 strings) Co-authored-by: Hồ Nhất Duy Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/vi/ Translation: Tusky/Tusky --- app/src/main/res/values-vi/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 5219775de..0c8109db4 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -516,4 +516,5 @@ Sửa tút Thông báo khi tút mà tôi tương tác bị sửa Đăng nhập + Không thể tải trang đăng nhập. \ No newline at end of file From 529452c1937b3064d0e2c12fc7b29e3c40b3449a Mon Sep 17 00:00:00 2001 From: GunChleoc Date: Mon, 9 May 2022 17:39:49 +0000 Subject: [PATCH 25/31] Translated using Weblate (Gaelic) Currently translated at 100.0% (478 of 478 strings) Co-authored-by: GunChleoc Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/gd/ Translation: Tusky/Tusky --- app/src/main/res/values-gd/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-gd/strings.xml b/app/src/main/res/values-gd/strings.xml index 10d64e0c1..e27b677aa 100644 --- a/app/src/main/res/values-gd/strings.xml +++ b/app/src/main/res/values-gd/strings.xml @@ -555,4 +555,5 @@ Brathan nuair a thèid postaichean a rinn thu conaltradh leotha a dheasachadh chaidh post a rinn mi conaltradh leis a deasachadh Clàraich a-steach + Cha b’ urrainn dhuinn duilleag a’ chlàraidh a-steach fhosgladh. \ No newline at end of file From d421de6ba8626a0c721c7b9c35e5646bbda81386 Mon Sep 17 00:00:00 2001 From: ruben Date: Mon, 9 May 2022 17:39:49 +0000 Subject: [PATCH 26/31] Translated using Weblate (Catalan) Currently translated at 93.3% (446 of 478 strings) Co-authored-by: ruben Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/ca/ Translation: Tusky/Tusky --- app/src/main/res/values-ca/strings.xml | 76 +++++++++++++------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 8b9660611..65affe75e 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -20,8 +20,8 @@ Notificacions Local Federació - Toot - Posts + Fil + Publicacions Seguits Seguidors Preferits @@ -31,19 +31,19 @@ Edita el perfil Esborranys \@%s - %s tootejat + %s ha impulsat Contingut sensible Fes clic per a visualitzar-lo Mostra\'n més Mostra\'n menys No hi res aquí. Llisca avall per a actualitzar! - %s ha impulsat el teu toot - %s ha marcat com a preferit el teu toot + %s ha impulsat la teva publicació + %s ha marcat com a preferida la teva publicació %s et segueix Denuncia @%s Cap comentari addicional? Respon - Retooteja + Impulsa Preferit Més Escriure @@ -55,8 +55,8 @@ Deixa de blocar Denuncia Elimina - TOOT - TOOT! + PUBLICA + PUBLICA! Torna a intentar-ho Tanca Perfil @@ -83,8 +83,8 @@ Esborranys S\'està baixant %1$s Copia l\'enllaç - Comparteix l\'URL del toot a… - Comparteix el toot a… + Comparteix l\'URL de la publicació a… + Comparteix la publicació a… Enviat! Usuari desblocat Usuari sense silenciar @@ -132,10 +132,10 @@ Amaga el botó de redacció en desplaçament Filtre de la cronologia Pestanyes - Mostra els retoots + Mostra els impulsos Mostra les respostes Mostra les previsualitzacions - Privacitat predeterminada dels toots + Privacitat per defecte de les publicacions Publicació Pública Sense llistar @@ -145,7 +145,7 @@ Notificacions sobre mencions noves Seguidors nous Notificacions sobre nous seguidors - Retoots + Impulsos Notificacions si retootejents els teus toots Preferits Notificacions si marquen com a preferits els teus toots @@ -172,8 +172,8 @@ https://github.com/tuskyapp/Tusky/issues Perfil del Tusky - Comparteix el contingut del toot - Comparteix l\'enllaç al toot + Comparteix el contingut de la publicació + Comparteix l\'enllaç a la publicació Imatges Vídeo @@ -193,7 +193,7 @@ En resposta a @%s carrega\'n més Vota - S\'ha produït un error en enviar el tut. + S\'ha produït un error en publicar. Pestanyes Llicències Amplia @@ -209,11 +209,11 @@ Multimèdia amagada Amaga Estàs segur de tancar la sessió de %1$s\? - Amaga els retoots + Amaga els impulsos Mostra els impulsos Elimina i reecririu Obre el menú - Visibilitat del toot + Visibilitat de la publicació Contingut sensible Afegir una pestanya Enllaços @@ -227,17 +227,17 @@ Baixa el fitxer Compartir la imatge a … Enviat! - S\'ha enviat la petició de seguiment + Petició enviada Amb respostes Teclat d\'emojis Obrir el media #%d - Obrir com %s + Obre com a %s S\'està Descarregant media Resposta enviada correctament. Resposta … Revocar la petició de seguiment\? Vols eliminar aquest toot\? - Esborrar i reescriure aquest toot\? + Vols eliminar i reescriure aquesta publicació\? Finalització de les enquetes Tema Cronologia @@ -267,7 +267,7 @@ Eliminar Afegir un compte Obre l\'autor de l\'impuls - Mostra els retoots + Mostra els impulsos Notificacions d\'enquestes que han finalitzat Línia de temps públiques Actualització @@ -297,11 +297,11 @@ Protegir el compte S\'haurà d\'admetre els seguidors manualment Guardar l\'esborrany\? - Enviant toot… - Error enviant el toot - Enviant toots + S\'està publicant… + Error en publicar + S\'esatan enviant les publicacions Envio anul·lat - Una copia del toot s\'ha guardat a esborranys + S\'ha guardat una còpia de la publicació als esborranys Escriure La teva instància %s no te emojis personalitzats Estil dels emojis @@ -309,7 +309,7 @@ Hauràs de descarregar el joc d\'emojis Cercant… Expandir/ocultar tots els estats - Obrir toot + Obre la publicació Cal reiniciar l\'aplicació Has de reiniciar l\'aplicació per tal d\'aplicar aquests canvis Més tard @@ -360,7 +360,7 @@ Netejar Filtrar Aplicar - Escriure un toot + Escriure una publicació Escriure Mostra l\'indicador dels bots Vols netejar totes les notificacions permanentment\? @@ -374,8 +374,8 @@ L\'enquesta on has votat està tancada La enquesta que heu creat ha finalitzat Advertència: %s - Toot fixat - Toot no fixat + Fixat + No fixis Fixar Respost Accions per a la imatge %s @@ -385,7 +385,7 @@ Silenciar %s %s visible Amagar el domini sencer - Obrir sempre els toots marcats amb contingut sensible + Mostra sempre obertes les publicacions marcades amb avisos de contingut Paraula sencera Ventall actual d\'emojis de Google Enquesta amb opcions: %1$s, %2$s, %3$s, %4$s; %5$s @@ -418,12 +418,12 @@ Múltiples tries Tria %d Preferits - Toots programats + Publicacions programades Preferit Edita Preferits - Toots programats - Programar el toot + Publicacions programades + Programa la publicació Reiniciar Desenvolupat per Tusky S\'ha afegit a les adreces d\'interès @@ -449,7 +449,7 @@ Silenciar @%s\? Bloquejar @%s\? No silenciar la conversació - Conversació muda + Silencia la conversa %s ha sol·licitat seguir-te A baix A dalt @@ -487,15 +487,15 @@ Adjuncions Àudio Notificacions quan algú a qui esteu subscrit publica un tut nou - Tuts nous + Publicacions noves emojis personalitzats animats algú a qui estic subscrit acaba de publicar un tut nou %s acaba de fer una publicació Avisos - S\'ha esborrat el tut del qual en vau fer un esborrany de resposta + S\'ha eliminat la publicació a la qual vau fer un esborrany de resposta S\'ha eliminat l\'esborrany No s\'ha pogut carregar la informació de la resposta - No s\'ha pogut enviar aquest tut! + No s\'ha pogut publicar! Segur que voleu esborrar la llista %s\? No podeu pujar més de %1$d adjunts multimèdia. From 3d3287cc42dbeb5630c5bc037044fb3ef26abf53 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Mon, 9 May 2022 17:39:49 +0000 Subject: [PATCH 27/31] Translated using Weblate (German) Currently translated at 100.0% (478 of 478 strings) Co-authored-by: Christian Schmidt Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/de/ Translation: Tusky/Tusky --- app/src/main/res/values-de/strings.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index b05ccc963..c8d647500 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -25,7 +25,7 @@ Föderiert Direktnachrichten Tabs - Beitrag + Konversation Beiträge mit Antworten Angeheftet @@ -490,7 +490,7 @@ Für immer Anhänge Audio - Benachrichtigungen, wenn jemand, den ich abonniert habe, etwas Neues veröffentlicht + Benachrichtigungen, wenn jemand, den ich abonniert habe, eine neue Nachricht veröffentlicht Neue Beiträge GIF-Emojis animieren Jemand, den ich abonniert habe, hat etwas Neues veröffentlicht @@ -535,4 +535,6 @@ Jemand hat sich registriert Benachrichtigungen, wenn Beiträge bearbeitet werden, mit denen du interagiert hast Anmelden + Die Anmeldeseite konnte nicht geladen werden. + Beitragsbearbeitungen \ No newline at end of file From 23d6d04b399711cdb07a67028f96cd15c6efcedc Mon Sep 17 00:00:00 2001 From: Bruno Miguel Date: Mon, 9 May 2022 17:39:50 +0000 Subject: [PATCH 28/31] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (478 of 478 strings) Co-authored-by: Bruno Miguel Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/pt_PT/ Translation: Tusky/Tusky --- app/src/main/res/values-pt-rPT/strings.xml | 212 +++++++++++---------- 1 file changed, 107 insertions(+), 105 deletions(-) diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index aa81160b2..6be06b0c2 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -10,20 +10,20 @@ A responder a @%s Editar a lista - Exige a aprovação manual de seguidores + Necessita de aprovar manualmente os seguidores Guardar rascunho\? Depois Desafixar %1$s e %2$s Bem-estar Escrever Toot - Deseja excluir a lista %s\? - Apesar do seu perfil não ser trancado, %1$s exige que você revise a solicitação para te seguir destes perfis manualmente. - Notificar - Cancelar + Pretende remover a lista %s\? + Apesar do seu perfil não ser privado, %1$s exige que você reveja manualmente as solicitações para te seguir destes perfis. + Subscrever + Remover subscrição Autorização negada. Erro ao adquirir token de login. - O toot é muito longo! + O toot é muito extenso! O ficheiro deve ter menor de 8MB. Os ficheiros de vídeo devem ter menor de 40MB. Os ficheiros de áudio devem ter menor de 40MB. @@ -48,13 +48,13 @@ Seguidores Favoritos Itens guardados - Utilizadors silenciados - Utilizadors bloqueados + Utilizadores silenciados + Utilizadores bloqueados Instâncias bloqueadas Seguidores Pendentes Conteúdo sensível Editar perfil - Conteúdo ocultado + Conteúdo multimédia ocultado Rascunhos Toque para ver Mostrar Mais @@ -67,7 +67,7 @@ \@%s %s fez boost Nada aqui. - Nada aqui. Arraste para baixo para atualizar! + Nada para ver aqui. Arraste para baixo para atualizar! %s fez boost ao seu toot %s adicionou o seu toot aos favoritos %s está a seguir-te @@ -77,7 +77,7 @@ %s editou um toot Denunciar @%s Comentários adicionais\? - Resposta rápida + Resposta Rápida Responder Fazer boost Desfazer boost @@ -89,7 +89,7 @@ Escrever Entrar com Mastodon Sair - Tem certeza de que deseja sair da conta %1$s\? + Tem a certeza que deseja sair da conta %1$s\? Seguir Deixar de seguir Bloquear @@ -106,12 +106,12 @@ Tentar novamente Fechar Perfil - Preferências - Preferências da Conta + Configurações + Configurações da Conta Favoritos - Guardados - utilizadors silenciados - utilizadors bloqueados + Itens Guardados + Utilizadores silenciados + Utilizadores bloqueados Instâncias bloqueadas Seguidores Pendentes Conteúdo multimédia @@ -138,13 +138,13 @@ Privacidade do toot Aviso de conteúdo Teclado de emojis - Agendar toot + Agendar Toot Redefinir Adicionar Separador Hiperligações Menções Hashtags - Ver quem fez boost + Ver autor do boost Mostrar boosts Mostrar favoritos Hashtags @@ -152,7 +152,7 @@ Hiperligações Abrir conteúdo multimédia #%d A descarregar %1$s - Copiar hiperligação + Copiar a hiperligação Abrir como %s Partilhar como… Descarregar conteúdo multimédia @@ -178,22 +178,22 @@ Cabeçalho O que é uma instância\? A ligar… - O endereço IP ou domínio de qualquer instância pode ser inserido aqui, como por exemplo mastodon.social, masto.donte.com.br, colorid.es ou qualquer outro! + O endereço IP ou domínio de qualquer instância pode ser inserido aqui, como por exemplo mastodon.social, masto.pt, pleroma.pt ou qualquer outro! \n -\n Se ainda não tem uma conta, insira o nome da instância onde pretende participar e crie uma conta lá. +\nSe ainda não tem uma conta, insira o nome da instância onde pretende participar e crie uma conta lá. \n -\n Uma instância é um lugar onde sua conta é hospedada, mas pode facilmente seguir e comunicar com pessoas de outras instâncias como se todos estivessem no mesmo site. +\nUma instância é o local onde sua conta é criada, mas pode facilmente seguir e comunicar com pessoas de outras instâncias como se estivessem todos no mesmo site. \n \nMais informações disponíveis em joinmastodon.org. - Envio de Conteúdo Multimédia Terminando + A Terminar Envio de Conteúdo Multimédia A enviar… Descarregar - Cancelar pedido para seguir\? + Cancelar o pedido para seguir\? Deixar de seguir esta conta\? Apagar este toot\? - Apagar e criar novo rascunho\? + Apagar e rescrever este toot\? Apagar esta conversa\? - Tem certeza que pretende bloquear a instância %s\? Deixará de poder ver quaisquer conteúdos dessa instância em qualquer timeline pública ou nas suas notificações. Os seus seguidores dessa instância serão removidos. + Tem a certeza que pretende bloquear a instância %s\? Deixará de poder ver quaisquer conteúdos dessa instância em qualquer timeline pública ou nas suas notificações. Os seus seguidores dessa instância serão removidos. Bloquear instância Bloquear @%s\? Silenciar @%s\? @@ -202,7 +202,7 @@ Não listado: Não publicar em timelines públicas Privado: Publicar apenas para os seguidores Direto: Publicar apenas para os utilizadores mencionados - Editar notificações + Notificações Notificações Alertas Notificar com som @@ -213,17 +213,17 @@ for seguido alguém para quem ativei os alertas publicar um toot novo fizerem pedido para me seguir - derem boosts nos meus toots + fizerem boosts aos meus toots adicionarem os meus toots aos favoritos votações terminarem alguém criar conta um toot com o qual interagi for editado Aparência - Temas + Tema da Aplicação Timelines Filtros - Noturno - Diurno + Escuro + Claro AMOLED Automático ao pôr-do-sol Usar o Tema do Sistema @@ -232,11 +232,11 @@ Esconder o botão de criação de toots ao fazer scroll Idioma Mostrar indicador para bots - Reproduzir avatares em GIFs + Reproduzir avatars em GIF Mostrar desfocagem em conteúdo multimédia sensível Animar emojis personalizados Filtro da timeline - Separadors + Separadores Mostrar boosts Mostrar respostas Mostrar pré-visualização de conteúdo multimédia @@ -268,23 +268,23 @@ Notificações para seguidores pendentes Boosts Votações - Notificações para votações que terminaram - Notificações quando alguém para quem ativei os alertas publicar um toot novo + Notificações para votações terminadas + Notificações quando alguém para quem ativou os alertas publicar um toot novo Notificações para novos utilizadores - Edições a toots + Edições de toots Notificações para boosts recebidos Favoritos - Notificações quando os teus toots são adicionados aos favoritos - Notificações quando toots com os quais interagi foram editados + Notificações quando os seus toots são adicionados aos favoritos + Notificações quando toots com os quais interagiu forem editados %s mencionou-te %1$s, %2$s, %3$s e %4$d outros %1$s, %2$s e %3$s - Perfil Bloqueado + Perfil Privado Sobre Tusky %s A correr o Tusky Atualizar - Tusky é um software livre e de código aberto e é ljcenciado com a versão 3 da GNU General Public License. Leia a licença aqui: https://www.gnu.org/licenses/gpl-3.0.pt-br.html + Tusky é um software livre e de código aberto, licenciado com a versão 3 da GNU General Public License. Pode ler a licença aqui: https://www.gnu.org/licenses/gpl-3.0.pt-br.html Página do projeto: \n https://tusky.app Reporte de erros e pedidos de funcionalidades: @@ -296,13 +296,13 @@ Vídeo Áudio Anexos - Pedido enviado + Pedido para seguir enviado em %dy em %dd em %dh em %dm em %ds - %da + %dy %dd %dh %dm @@ -325,7 +325,7 @@ Listas Não foi possível renomear a lista Listas - Lista da timeline + Cronologia da timeline Não foi possível criar a lista Não foi possível apagar a lista Criar uma lista @@ -338,10 +338,11 @@ Erro ao incluir descrição Descrição para deficientes visuais +\n(até %d letra) + Descrição para deficientes visuais \n(até %d caracteres) - - Descrever + Escrever descrição Remover Bloquear perfil A enviar o toot… @@ -351,34 +352,34 @@ Uma cópia do toot foi guardada nos seus rascunhos Escrever A sua instância, %s, não tem emojis personalizados - Estilo de emoji + Estilo dos emojis Padrão do sistema É necessário descarregar estes pacotes de emojis primeiro A fazer pesquisa… Expandir/Contrair todos os toots Abrir toot É necessário reiniciar a aplicação - É necessário reiniciar o aplicativo para aplicar as alterações + É necessário reiniciar o Tusky para aplicar as alterações Reiniciar Pacote de emojis padrão do seu dispositivo - Emojis padrão do Android da versão 4.4 até 7.1 + Emojis padrão do Android 4.4 até ao 7.1 Pacote de emojis padrão do Mastodon - Pacote de emojis atual do Google - Erro ao baixar + Pacote de emojis atuais da Google + Erro ao descarregar Robô %1$s mudou-se para: - Dar boost para o mesmo público + Dar boost para o público inicial Desfazer boost O Tusky contém código e recursos dos seguintes projetos de código aberto: - Licenciado sob a licença Apache (cópia separadorixo) + Licenciado sob a licença Apache (cópia abaixo) CC-BY 4.0 CC-BY-SA 4.0 Metadados do perfil - Adicionar + adicionar dados Rótulo Conteúdo - Usar tempo absoluto - As informações separadorixo podem refletir incompletamente o perfil do utilizador. Toque aqui para abrir o perfil completo no navegador. + Usar data absoluta + As informações abaixo podem refletir, de forma incompleta, o perfil do utilizador. Toque aqui para abrir o perfil completo no navegador. Fixar %1$s Favorito @@ -388,25 +389,25 @@ %s Boost %s Boosts - Levou boost de - Favoritado por + Boost dado por + Adicionado aos favoritos por %1$s - %1$s, %2$s e %3$d outros + %1$s, %2$s e %3$d mais - excedeu o máximo de %1$d separador - excedeu o máximo de %1$d separadors + atingiu o máximo de %1$d separador + atingiu o máximo de %1$d separadores - conteúdo multimédia: %s + Conteúdo multimédia: %s Aviso de Conteúdo: %s Sem descrição - Você fez boost - Favoritado - Salvo + Replicado + Adicionado aos favoritos + Guardado Público Não-listado Privado Direto - Enquete com as opções: %1$s, %2$s, %3$s, %4$s; %5$s + Votação com as opções: %1$s, %2$s, %3$s, %4$s; %5$s Nome da lista Adicionar hashtag Hashtag sem # @@ -414,11 +415,11 @@ Selecionar lista Lista Limpar - Filtro - Salvar - Compor toot - Compor - Tem certeza de que deseja limpar permanentemente todas as suas notificações\? + Filtrar + Aplicar + Escrever toot + Escrever + Tem certeza que pretende limpar permanentemente todas as suas notificações\? Opções para imagem %s %1$s • %2$s @@ -430,10 +431,10 @@ %s pessoas termina em %s - Terminou + terminada Votar - Uma enquete que você votou terminou - Sua enquete terminou + Uma votação em que votou terminou + A sua votação terminou %d dia restante %d dias restantes @@ -451,20 +452,20 @@ %d segundos restantes Continuar - Voltar - Ok + Retroceder + Feito \@%s denunciado com sucesso Comentários adicionais Encaminhar para %s Erro ao denunciar Erro ao carregar toots - A denúncia será enviada aos moderadores da instância. Explique por que denunciou a conta: - A conta está em outra instância. Enviar uma cópia anônima da denúncia para lá\? + A denúncia será enviada aos moderadores da instância. Pode adicionar abaixo uma explicação para a sua denúncia: + A conta está noutra instância. Quer enviar uma cópia anónima da denúncia para lá\? Contas Erro ao pesquisar - Mostrar filtro de notificações - Ativar deslizar para alternar entre separadors - Enquete + Mostrar Filtro das Notificações + Ativar gesto de deslizar para alternar entre separadores + Votação Duração Indefinido 5 minutos @@ -481,46 +482,46 @@ 180 dias 365 dias Adicionar opção - Múltiplas opções + Escolha múltipla Opção %d Editar - Erro ao pesquisar %s - Sem rascunhos. - Sem toots agendados. - Salvo! + Erro ao pesquisar toot %s + Não tem rascunhos. + Não tem toots agendados. + Guardado! Algumas informações que podem afetar seu bem-estar serão ocultadas. Isso inclui: \n \n- Notificações de favoritos, boosts e seguidores \n- Número de favoritos e boosts nos toots \n- Status de toots e seguidores nos perfis \n -\nNotificações push não serão afetadas, mas é possível revisar sua preferência manualmente. - Revisar notificações +\nNotificações push não serão afetadas, mas é possível rever as configurações das notificações manualmente. + Rever Notificações Limitar notificações da timeline - Sem comunicados. - Mastodon possui um intervalo mínimo de 5 minutos para agendar. - Mostrar prévias de Hiperligações nas linhas - Solicitar confirmação antes de dar boost - Solicitar confirmação antes de favoritar - Esconder o título da barra superior de tarefas - Nota pessoal sobre este perfil aqui - Esconder status dos toots - Esconder status dos perfis + Sem anúncios. + O Mastodon tem um intervalo mínimo de agendamento de 5 minutos. + Mostrar pré-visualização de hiperligações nas timelines + Mostrar janela de confirmação antes de dar boost + Mostrar janela de confirmação antes de adicionar aos favoritos + Esconder o título da barra superior + Nota pessoal sobre este perfil + Esconder estatísticas quantitativas nos toots + Esconder estatísticas quantitativas nos perfis - Não é possível anexar mais de %1$d arquivo de conteúdo multimédia. - Não é possível anexar mais de %1$d arquivos de conteúdo multimédia. + Não é possível enviar mais de %1$d arquivo de conteúdo multimédia. + Não é possível enviar mais de %1$d arquivos de conteúdo multimédia. Erro ao enviar o toot! - Erro ao carregar toot para responder - Rascunho excluído - O toot em que se rascunhou uma resposta foi excluído + Erro ao carregar informação de resposta + Rascunho apagado + O toot para o qual escreveu um rascunho foi apagado Ocorreu um erro. Ocorreu um erro de conetividade! Por favor, verifique a sua ligação e tente novamente! Isto não pode estar vazio. - Instância inválida inserida + A instância inserida é inválida Erro ao autenticar com esta instância. - Nao foi possível encontrar um navegador. - Ocorreu um erro não identificado de autorização. + Não foi possível encontrar um navegador. + Ocorreu um erro de autorização não identificado. Entrar Guardar Editar perfil @@ -528,4 +529,5 @@ Desfazer Aceitar Rejeitar + Não foi possível carregar a página de login \ No newline at end of file From b353e67587355fc1dc07eb1db30a2643b2358684 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Mon, 9 May 2022 11:40:35 +0000 Subject: [PATCH 29/31] Translated using Weblate (German) Currently translated at 100.0% (16 of 16 strings) Translation: Tusky/Tusky description Translate-URL: https://weblate.tusky.app/projects/tusky/tusky-app/de/ --- fastlane/metadata/android/de/changelogs/89.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 fastlane/metadata/android/de/changelogs/89.txt diff --git a/fastlane/metadata/android/de/changelogs/89.txt b/fastlane/metadata/android/de/changelogs/89.txt new file mode 100644 index 000000000..cb92453b8 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/89.txt @@ -0,0 +1,7 @@ +Tusky v17.0 + +- "Öffnen als..." ist jetzt im Menü in Konto Profilen auch verfügbar, wenn mehrere Konten genutzt werden +- Die Anmeldung wird jetzt über die WebView innerhalb der App abgewickelt +- Unterstützung für Android 12 +- Unterstützung für die neue Mastodon instance configuration API +- und einige andere kleine Fehlerbehebungen und Verbesserungen From 7db504775c094c333f8e012ef797d4ece06f2d88 Mon Sep 17 00:00:00 2001 From: Conny Duck Date: Tue, 10 May 2022 20:00:53 +0200 Subject: [PATCH 30/31] Release 90 --- app/build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/91.txt | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/91.txt diff --git a/app/build.gradle b/app/build.gradle index 4484ff54e..c152805b4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ android { applicationId APP_ID minSdkVersion 21 targetSdkVersion 31 - versionCode 89 - versionName "17.0" + versionCode 90 + versionName "18.0 beta 1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true diff --git a/fastlane/metadata/android/en-US/changelogs/91.txt b/fastlane/metadata/android/en-US/changelogs/91.txt new file mode 100644 index 000000000..e1d983039 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/91.txt @@ -0,0 +1,6 @@ +Tusky v18.0 + +- Support for new Mastodon 3.5 notification types +- The bot badge now looks better and adjusts to the selected theme +- Text can now be selected on the post detail view +- Fixed a lot of bugs, including one that prevented logins on Android 6 and lower From 0f1e95d0ca81d0254f8d1ae6b60a3130d51b15cf Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Wed, 11 May 2022 07:43:30 +0200 Subject: [PATCH 31/31] add 35.json --- .../35.json | 821 ++++++++++++++++++ 1 file changed, 821 insertions(+) create mode 100644 app/schemas/com.keylesspalace.tusky.db.AppDatabase/35.json diff --git a/app/schemas/com.keylesspalace.tusky.db.AppDatabase/35.json b/app/schemas/com.keylesspalace.tusky.db.AppDatabase/35.json new file mode 100644 index 000000000..9b71adf21 --- /dev/null +++ b/app/schemas/com.keylesspalace.tusky.db.AppDatabase/35.json @@ -0,0 +1,821 @@ +{ + "formatVersion": 1, + "database": { + "version": 35, + "identityHash": "9e6c0bb60538683a16c30fa3e1cc24f2", + "entities": [ + { + "tableName": "DraftEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `accountId` INTEGER NOT NULL, `inReplyToId` TEXT, `content` TEXT, `contentWarning` TEXT, `sensitive` INTEGER NOT NULL, `visibility` INTEGER NOT NULL, `attachments` TEXT NOT NULL, `poll` TEXT, `failedToSend` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "accountId", + "columnName": "accountId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "inReplyToId", + "columnName": "inReplyToId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "contentWarning", + "columnName": "contentWarning", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sensitive", + "columnName": "sensitive", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "visibility", + "columnName": "visibility", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "attachments", + "columnName": "attachments", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "poll", + "columnName": "poll", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "failedToSend", + "columnName": "failedToSend", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "AccountEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `domain` TEXT NOT NULL, `accessToken` TEXT NOT NULL, `isActive` INTEGER NOT NULL, `accountId` TEXT NOT NULL, `username` TEXT NOT NULL, `displayName` TEXT NOT NULL, `profilePictureUrl` TEXT NOT NULL, `notificationsEnabled` INTEGER NOT NULL, `notificationsMentioned` INTEGER NOT NULL, `notificationsFollowed` INTEGER NOT NULL, `notificationsFollowRequested` INTEGER NOT NULL, `notificationsReblogged` INTEGER NOT NULL, `notificationsFavorited` INTEGER NOT NULL, `notificationsPolls` INTEGER NOT NULL, `notificationsSubscriptions` INTEGER NOT NULL, `notificationsSignUps` INTEGER NOT NULL, `notificationsUpdates` INTEGER NOT NULL, `notificationSound` INTEGER NOT NULL, `notificationVibration` INTEGER NOT NULL, `notificationLight` INTEGER NOT NULL, `defaultPostPrivacy` INTEGER NOT NULL, `defaultMediaSensitivity` INTEGER NOT NULL, `alwaysShowSensitiveMedia` INTEGER NOT NULL, `alwaysOpenSpoiler` INTEGER NOT NULL, `mediaPreviewEnabled` INTEGER NOT NULL, `lastNotificationId` TEXT NOT NULL, `activeNotifications` TEXT NOT NULL, `emojis` TEXT NOT NULL, `tabPreferences` TEXT NOT NULL, `notificationsFilter` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "domain", + "columnName": "domain", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accessToken", + "columnName": "accessToken", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isActive", + "columnName": "isActive", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "accountId", + "columnName": "accountId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "username", + "columnName": "username", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "profilePictureUrl", + "columnName": "profilePictureUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "notificationsEnabled", + "columnName": "notificationsEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationsMentioned", + "columnName": "notificationsMentioned", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationsFollowed", + "columnName": "notificationsFollowed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationsFollowRequested", + "columnName": "notificationsFollowRequested", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationsReblogged", + "columnName": "notificationsReblogged", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationsFavorited", + "columnName": "notificationsFavorited", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationsPolls", + "columnName": "notificationsPolls", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationsSubscriptions", + "columnName": "notificationsSubscriptions", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationsSignUps", + "columnName": "notificationsSignUps", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationsUpdates", + "columnName": "notificationsUpdates", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationSound", + "columnName": "notificationSound", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationVibration", + "columnName": "notificationVibration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationLight", + "columnName": "notificationLight", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "defaultPostPrivacy", + "columnName": "defaultPostPrivacy", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "defaultMediaSensitivity", + "columnName": "defaultMediaSensitivity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "alwaysShowSensitiveMedia", + "columnName": "alwaysShowSensitiveMedia", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "alwaysOpenSpoiler", + "columnName": "alwaysOpenSpoiler", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "mediaPreviewEnabled", + "columnName": "mediaPreviewEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastNotificationId", + "columnName": "lastNotificationId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "activeNotifications", + "columnName": "activeNotifications", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "emojis", + "columnName": "emojis", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "tabPreferences", + "columnName": "tabPreferences", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "notificationsFilter", + "columnName": "notificationsFilter", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_AccountEntity_domain_accountId", + "unique": true, + "columnNames": [ + "domain", + "accountId" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_AccountEntity_domain_accountId` ON `${TABLE_NAME}` (`domain`, `accountId`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "InstanceEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`instance` TEXT NOT NULL, `emojiList` TEXT, `maximumTootCharacters` INTEGER, `maxPollOptions` INTEGER, `maxPollOptionLength` INTEGER, `minPollDuration` INTEGER, `maxPollDuration` INTEGER, `charactersReservedPerUrl` INTEGER, `version` TEXT, PRIMARY KEY(`instance`))", + "fields": [ + { + "fieldPath": "instance", + "columnName": "instance", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "emojiList", + "columnName": "emojiList", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "maximumTootCharacters", + "columnName": "maximumTootCharacters", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "maxPollOptions", + "columnName": "maxPollOptions", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "maxPollOptionLength", + "columnName": "maxPollOptionLength", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "minPollDuration", + "columnName": "minPollDuration", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "maxPollDuration", + "columnName": "maxPollDuration", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "charactersReservedPerUrl", + "columnName": "charactersReservedPerUrl", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "version", + "columnName": "version", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "instance" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "TimelineStatusEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` TEXT NOT NULL, `url` TEXT, `timelineUserId` INTEGER NOT NULL, `authorServerId` TEXT, `inReplyToId` TEXT, `inReplyToAccountId` TEXT, `content` TEXT, `createdAt` INTEGER NOT NULL, `emojis` TEXT, `reblogsCount` INTEGER NOT NULL, `favouritesCount` INTEGER NOT NULL, `reblogged` INTEGER NOT NULL, `bookmarked` INTEGER NOT NULL, `favourited` INTEGER NOT NULL, `sensitive` INTEGER NOT NULL, `spoilerText` TEXT NOT NULL, `visibility` INTEGER NOT NULL, `attachments` TEXT, `mentions` TEXT, `tags` TEXT, `application` TEXT, `reblogServerId` TEXT, `reblogAccountId` TEXT, `poll` TEXT, `muted` INTEGER, `expanded` INTEGER NOT NULL, `contentCollapsed` INTEGER NOT NULL, `contentShowing` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `card` TEXT, PRIMARY KEY(`serverId`, `timelineUserId`), FOREIGN KEY(`authorServerId`, `timelineUserId`) REFERENCES `TimelineAccountEntity`(`serverId`, `timelineUserId`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "serverId", + "columnName": "serverId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "timelineUserId", + "columnName": "timelineUserId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "authorServerId", + "columnName": "authorServerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "inReplyToId", + "columnName": "inReplyToId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "inReplyToAccountId", + "columnName": "inReplyToAccountId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "emojis", + "columnName": "emojis", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "reblogsCount", + "columnName": "reblogsCount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "favouritesCount", + "columnName": "favouritesCount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "reblogged", + "columnName": "reblogged", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "bookmarked", + "columnName": "bookmarked", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "favourited", + "columnName": "favourited", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "sensitive", + "columnName": "sensitive", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "spoilerText", + "columnName": "spoilerText", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "visibility", + "columnName": "visibility", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "attachments", + "columnName": "attachments", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "mentions", + "columnName": "mentions", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tags", + "columnName": "tags", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "application", + "columnName": "application", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "reblogServerId", + "columnName": "reblogServerId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "reblogAccountId", + "columnName": "reblogAccountId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "poll", + "columnName": "poll", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "muted", + "columnName": "muted", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "expanded", + "columnName": "expanded", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "contentCollapsed", + "columnName": "contentCollapsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "contentShowing", + "columnName": "contentShowing", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "pinned", + "columnName": "pinned", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "card", + "columnName": "card", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "serverId", + "timelineUserId" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_TimelineStatusEntity_authorServerId_timelineUserId", + "unique": false, + "columnNames": [ + "authorServerId", + "timelineUserId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_TimelineStatusEntity_authorServerId_timelineUserId` ON `${TABLE_NAME}` (`authorServerId`, `timelineUserId`)" + } + ], + "foreignKeys": [ + { + "table": "TimelineAccountEntity", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "authorServerId", + "timelineUserId" + ], + "referencedColumns": [ + "serverId", + "timelineUserId" + ] + } + ] + }, + { + "tableName": "TimelineAccountEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` TEXT NOT NULL, `timelineUserId` INTEGER NOT NULL, `localUsername` TEXT NOT NULL, `username` TEXT NOT NULL, `displayName` TEXT NOT NULL, `url` TEXT NOT NULL, `avatar` TEXT NOT NULL, `emojis` TEXT NOT NULL, `bot` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `timelineUserId`))", + "fields": [ + { + "fieldPath": "serverId", + "columnName": "serverId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "timelineUserId", + "columnName": "timelineUserId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localUsername", + "columnName": "localUsername", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "username", + "columnName": "username", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "avatar", + "columnName": "avatar", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "emojis", + "columnName": "emojis", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bot", + "columnName": "bot", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "serverId", + "timelineUserId" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "ConversationEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accountId` INTEGER NOT NULL, `id` TEXT NOT NULL, `accounts` TEXT NOT NULL, `unread` INTEGER NOT NULL, `s_id` TEXT NOT NULL, `s_url` TEXT, `s_inReplyToId` TEXT, `s_inReplyToAccountId` TEXT, `s_account` TEXT NOT NULL, `s_content` TEXT NOT NULL, `s_createdAt` INTEGER NOT NULL, `s_emojis` TEXT NOT NULL, `s_favouritesCount` INTEGER NOT NULL, `s_favourited` INTEGER NOT NULL, `s_bookmarked` INTEGER NOT NULL, `s_sensitive` INTEGER NOT NULL, `s_spoilerText` TEXT NOT NULL, `s_attachments` TEXT NOT NULL, `s_mentions` TEXT NOT NULL, `s_tags` TEXT, `s_showingHiddenContent` INTEGER NOT NULL, `s_expanded` INTEGER NOT NULL, `s_collapsed` INTEGER NOT NULL, `s_muted` INTEGER NOT NULL, `s_poll` TEXT, PRIMARY KEY(`id`, `accountId`))", + "fields": [ + { + "fieldPath": "accountId", + "columnName": "accountId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accounts", + "columnName": "accounts", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "unread", + "columnName": "unread", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.id", + "columnName": "s_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastStatus.url", + "columnName": "s_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastStatus.inReplyToId", + "columnName": "s_inReplyToId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastStatus.inReplyToAccountId", + "columnName": "s_inReplyToAccountId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastStatus.account", + "columnName": "s_account", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastStatus.content", + "columnName": "s_content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastStatus.createdAt", + "columnName": "s_createdAt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.emojis", + "columnName": "s_emojis", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastStatus.favouritesCount", + "columnName": "s_favouritesCount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.favourited", + "columnName": "s_favourited", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.bookmarked", + "columnName": "s_bookmarked", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.sensitive", + "columnName": "s_sensitive", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.spoilerText", + "columnName": "s_spoilerText", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastStatus.attachments", + "columnName": "s_attachments", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastStatus.mentions", + "columnName": "s_mentions", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastStatus.tags", + "columnName": "s_tags", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastStatus.showingHiddenContent", + "columnName": "s_showingHiddenContent", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.expanded", + "columnName": "s_expanded", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.collapsed", + "columnName": "s_collapsed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.muted", + "columnName": "s_muted", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastStatus.poll", + "columnName": "s_poll", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id", + "accountId" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9e6c0bb60538683a16c30fa3e1cc24f2')" + ] + } +} \ No newline at end of file